blob: 14e4b37224284976a1cb8890e5d13ae5337350cc [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 iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100489
David Woodhouseae853dd2015-09-09 11:58:59 +0100490#define IDENTMAP_ALL 1
491#define IDENTMAP_GFX 2
492#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100493
Lu Baoluab967462018-05-04 13:08:18 +0800494#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap))
495#define pasid_enabled(iommu) (ecs_enabled(iommu) && ecap_pasid(iommu->ecap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700496
David Woodhousec0771df2011-10-14 20:59:46 +0100497int intel_iommu_gfx_mapped;
498EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
499
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700500#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
501static DEFINE_SPINLOCK(device_domain_lock);
502static LIST_HEAD(device_domain_list);
503
Joerg Roedelb0119e82017-02-01 13:23:08 +0100504const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100505
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200506static bool translation_pre_enabled(struct intel_iommu *iommu)
507{
508 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
509}
510
Joerg Roedel091d42e2015-06-12 11:56:10 +0200511static void clear_translation_pre_enabled(struct intel_iommu *iommu)
512{
513 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
514}
515
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200516static void init_translation_status(struct intel_iommu *iommu)
517{
518 u32 gsts;
519
520 gsts = readl(iommu->reg + DMAR_GSTS_REG);
521 if (gsts & DMA_GSTS_TES)
522 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
523}
524
Joerg Roedel00a77de2015-03-26 13:43:08 +0100525/* Convert generic 'struct iommu_domain to private struct dmar_domain */
526static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
527{
528 return container_of(dom, struct dmar_domain, domain);
529}
530
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700531static int __init intel_iommu_setup(char *str)
532{
533 if (!str)
534 return -EINVAL;
535 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800536 if (!strncmp(str, "on", 2)) {
537 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200538 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800539 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700540 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200541 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700542 } else if (!strncmp(str, "igfx_off", 8)) {
543 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200544 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700545 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200546 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700547 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800548 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200549 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800550 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100551 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200552 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100553 intel_iommu_superpage = 0;
David Woodhousec83b2f22015-06-12 10:15:49 +0100554 } else if (!strncmp(str, "ecs_off", 7)) {
555 printk(KERN_INFO
556 "Intel-IOMMU: disable extended context table support\n");
557 intel_iommu_ecs = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700558 } else if (!strncmp(str, "tboot_noforce", 13)) {
559 printk(KERN_INFO
560 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
561 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700562 }
563
564 str += strcspn(str, ",");
565 while (*str == ',')
566 str++;
567 }
568 return 0;
569}
570__setup("intel_iommu=", intel_iommu_setup);
571
572static struct kmem_cache *iommu_domain_cache;
573static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700574
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200575static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
576{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200577 struct dmar_domain **domains;
578 int idx = did >> 8;
579
580 domains = iommu->domains[idx];
581 if (!domains)
582 return NULL;
583
584 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200585}
586
587static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
588 struct dmar_domain *domain)
589{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200590 struct dmar_domain **domains;
591 int idx = did >> 8;
592
593 if (!iommu->domains[idx]) {
594 size_t size = 256 * sizeof(struct dmar_domain *);
595 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
596 }
597
598 domains = iommu->domains[idx];
599 if (WARN_ON(!domains))
600 return;
601 else
602 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200603}
604
Suresh Siddha4c923d42009-10-02 11:01:24 -0700605static inline void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700606{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700607 struct page *page;
608 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700609
Suresh Siddha4c923d42009-10-02 11:01:24 -0700610 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
611 if (page)
612 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700613 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700614}
615
616static inline void free_pgtable_page(void *vaddr)
617{
618 free_page((unsigned long)vaddr);
619}
620
621static inline void *alloc_domain_mem(void)
622{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900623 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700624}
625
Kay, Allen M38717942008-09-09 18:37:29 +0300626static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700627{
628 kmem_cache_free(iommu_domain_cache, vaddr);
629}
630
631static inline void * alloc_devinfo_mem(void)
632{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900633 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700634}
635
636static inline void free_devinfo_mem(void *vaddr)
637{
638 kmem_cache_free(iommu_devinfo_cache, vaddr);
639}
640
Jiang Liuab8dfe22014-07-11 14:19:27 +0800641static inline int domain_type_is_vm(struct dmar_domain *domain)
642{
643 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
644}
645
Joerg Roedel28ccce02015-07-21 14:45:31 +0200646static inline int domain_type_is_si(struct dmar_domain *domain)
647{
648 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
649}
650
Jiang Liuab8dfe22014-07-11 14:19:27 +0800651static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
652{
653 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
654 DOMAIN_FLAG_STATIC_IDENTITY);
655}
Weidong Han1b573682008-12-08 15:34:06 +0800656
Jiang Liu162d1b12014-07-11 14:19:35 +0800657static inline int domain_pfn_supported(struct dmar_domain *domain,
658 unsigned long pfn)
659{
660 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
661
662 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
663}
664
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700665static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800666{
667 unsigned long sagaw;
668 int agaw = -1;
669
670 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700671 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800672 agaw >= 0; agaw--) {
673 if (test_bit(agaw, &sagaw))
674 break;
675 }
676
677 return agaw;
678}
679
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700680/*
681 * Calculate max SAGAW for each iommu.
682 */
683int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
684{
685 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
686}
687
688/*
689 * calculate agaw for each iommu.
690 * "SAGAW" may be different across iommus, use a default agaw, and
691 * get a supported less agaw for iommus that don't support the default agaw.
692 */
693int iommu_calculate_agaw(struct intel_iommu *iommu)
694{
695 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
696}
697
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700698/* This functionin only returns single iommu in a domain */
Weidong Han8c11e792008-12-08 15:29:22 +0800699static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
700{
701 int iommu_id;
702
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700703 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800704 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200705 for_each_domain_iommu(iommu_id, domain)
706 break;
707
Weidong Han8c11e792008-12-08 15:29:22 +0800708 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
709 return NULL;
710
711 return g_iommus[iommu_id];
712}
713
Weidong Han8e6040972008-12-08 15:49:06 +0800714static void domain_update_iommu_coherency(struct dmar_domain *domain)
715{
David Woodhoused0501962014-03-11 17:10:29 -0700716 struct dmar_drhd_unit *drhd;
717 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100718 bool found = false;
719 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800720
David Woodhoused0501962014-03-11 17:10:29 -0700721 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800722
Joerg Roedel29a27712015-07-21 17:17:12 +0200723 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100724 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800725 if (!ecap_coherent(g_iommus[i]->ecap)) {
726 domain->iommu_coherency = 0;
727 break;
728 }
Weidong Han8e6040972008-12-08 15:49:06 +0800729 }
David Woodhoused0501962014-03-11 17:10:29 -0700730 if (found)
731 return;
732
733 /* No hardware attached; use lowest common denominator */
734 rcu_read_lock();
735 for_each_active_iommu(iommu, drhd) {
736 if (!ecap_coherent(iommu->ecap)) {
737 domain->iommu_coherency = 0;
738 break;
739 }
740 }
741 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800742}
743
Jiang Liu161f6932014-07-11 14:19:37 +0800744static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100745{
Allen Kay8140a952011-10-14 12:32:17 -0700746 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800747 struct intel_iommu *iommu;
748 int ret = 1;
749
750 rcu_read_lock();
751 for_each_active_iommu(iommu, drhd) {
752 if (iommu != skip) {
753 if (!ecap_sc_support(iommu->ecap)) {
754 ret = 0;
755 break;
756 }
757 }
758 }
759 rcu_read_unlock();
760
761 return ret;
762}
763
764static int domain_update_iommu_superpage(struct intel_iommu *skip)
765{
766 struct dmar_drhd_unit *drhd;
767 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700768 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100769
770 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800771 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100772 }
773
Allen Kay8140a952011-10-14 12:32:17 -0700774 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800775 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700776 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800777 if (iommu != skip) {
778 mask &= cap_super_page_val(iommu->cap);
779 if (!mask)
780 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100781 }
782 }
Jiang Liu0e242612014-02-19 14:07:34 +0800783 rcu_read_unlock();
784
Jiang Liu161f6932014-07-11 14:19:37 +0800785 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100786}
787
Sheng Yang58c610b2009-03-18 15:33:05 +0800788/* Some capabilities may be different across iommus */
789static void domain_update_iommu_cap(struct dmar_domain *domain)
790{
791 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800792 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
793 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800794}
795
David Woodhouse03ecc322015-02-13 14:35:21 +0000796static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu,
797 u8 bus, u8 devfn, int alloc)
798{
799 struct root_entry *root = &iommu->root_entry[bus];
800 struct context_entry *context;
801 u64 *entry;
802
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200803 entry = &root->lo;
David Woodhousec83b2f22015-06-12 10:15:49 +0100804 if (ecs_enabled(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000805 if (devfn >= 0x80) {
806 devfn -= 0x80;
807 entry = &root->hi;
808 }
809 devfn *= 2;
810 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000811 if (*entry & 1)
812 context = phys_to_virt(*entry & VTD_PAGE_MASK);
813 else {
814 unsigned long phy_addr;
815 if (!alloc)
816 return NULL;
817
818 context = alloc_pgtable_page(iommu->node);
819 if (!context)
820 return NULL;
821
822 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
823 phy_addr = virt_to_phys((void *)context);
824 *entry = phy_addr | 1;
825 __iommu_flush_cache(iommu, entry, sizeof(*entry));
826 }
827 return &context[devfn];
828}
829
David Woodhouse4ed6a542015-05-11 14:59:20 +0100830static int iommu_dummy(struct device *dev)
831{
832 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
833}
834
David Woodhouse156baca2014-03-09 14:00:57 -0700835static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800836{
837 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800838 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700839 struct device *tmp;
840 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800841 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800842 int i;
843
David Woodhouse4ed6a542015-05-11 14:59:20 +0100844 if (iommu_dummy(dev))
845 return NULL;
846
David Woodhouse156baca2014-03-09 14:00:57 -0700847 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700848 struct pci_dev *pf_pdev;
849
David Woodhouse156baca2014-03-09 14:00:57 -0700850 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600851
852#ifdef CONFIG_X86
853 /* VMD child devices currently cannot be handled individually */
854 if (is_vmd(pdev->bus))
855 return NULL;
856#endif
857
Ashok Raj1c387182016-10-21 15:32:05 -0700858 /* VFs aren't listed in scope tables; we need to look up
859 * the PF instead to find the IOMMU. */
860 pf_pdev = pci_physfn(pdev);
861 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700862 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100863 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700864 dev = &ACPI_COMPANION(dev)->dev;
865
Jiang Liu0e242612014-02-19 14:07:34 +0800866 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800867 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700868 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100869 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800870
Jiang Liub683b232014-02-19 14:07:32 +0800871 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700872 drhd->devices_cnt, i, tmp) {
873 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700874 /* For a VF use its original BDF# not that of the PF
875 * which we used for the IOMMU lookup. Strictly speaking
876 * we could do this for all PCI devices; we only need to
877 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100878 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700879 goto got_pdev;
880
David Woodhouse156baca2014-03-09 14:00:57 -0700881 *bus = drhd->devices[i].bus;
882 *devfn = drhd->devices[i].devfn;
883 goto out;
884 }
885
886 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000887 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700888
889 ptmp = to_pci_dev(tmp);
890 if (ptmp->subordinate &&
891 ptmp->subordinate->number <= pdev->bus->number &&
892 ptmp->subordinate->busn_res.end >= pdev->bus->number)
893 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100894 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800895
David Woodhouse156baca2014-03-09 14:00:57 -0700896 if (pdev && drhd->include_all) {
897 got_pdev:
898 *bus = pdev->bus->number;
899 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800900 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700901 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800902 }
Jiang Liub683b232014-02-19 14:07:32 +0800903 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700904 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800905 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800906
Jiang Liub683b232014-02-19 14:07:32 +0800907 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800908}
909
Weidong Han5331fe62008-12-08 23:00:00 +0800910static void domain_flush_cache(struct dmar_domain *domain,
911 void *addr, int size)
912{
913 if (!domain->iommu_coherency)
914 clflush_cache_range(addr, size);
915}
916
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700917static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
918{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700919 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000920 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700921 unsigned long flags;
922
923 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000924 context = iommu_context_addr(iommu, bus, devfn, 0);
925 if (context)
926 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700927 spin_unlock_irqrestore(&iommu->lock, flags);
928 return ret;
929}
930
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700931static void free_context_table(struct intel_iommu *iommu)
932{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700933 int i;
934 unsigned long flags;
935 struct context_entry *context;
936
937 spin_lock_irqsave(&iommu->lock, flags);
938 if (!iommu->root_entry) {
939 goto out;
940 }
941 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000942 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700943 if (context)
944 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000945
David Woodhousec83b2f22015-06-12 10:15:49 +0100946 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000947 continue;
948
949 context = iommu_context_addr(iommu, i, 0x80, 0);
950 if (context)
951 free_pgtable_page(context);
952
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700953 }
954 free_pgtable_page(iommu->root_entry);
955 iommu->root_entry = NULL;
956out:
957 spin_unlock_irqrestore(&iommu->lock, flags);
958}
959
David Woodhouseb026fd22009-06-28 10:37:25 +0100960static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000961 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700962{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700963 struct dma_pte *parent, *pte = NULL;
964 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700965 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700966
967 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200968
Jiang Liu162d1b12014-07-11 14:19:35 +0800969 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200970 /* Address beyond IOMMU's addressing capabilities. */
971 return NULL;
972
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700973 parent = domain->pgd;
974
David Woodhouse5cf0a762014-03-19 16:07:49 +0000975 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700976 void *tmp_page;
977
David Woodhouseb026fd22009-06-28 10:37:25 +0100978 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700979 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000980 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100981 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000982 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700983 break;
984
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000985 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100986 uint64_t pteval;
987
Suresh Siddha4c923d42009-10-02 11:01:24 -0700988 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700989
David Woodhouse206a73c2009-07-01 19:30:28 +0100990 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700991 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100992
David Woodhousec85994e2009-07-01 19:21:24 +0100993 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400994 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 +0800995 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100996 /* Someone else set it while we were thinking; use theirs. */
997 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800998 else
David Woodhousec85994e2009-07-01 19:21:24 +0100999 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001000 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001001 if (level == 1)
1002 break;
1003
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001004 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001005 level--;
1006 }
1007
David Woodhouse5cf0a762014-03-19 16:07:49 +00001008 if (!*target_level)
1009 *target_level = level;
1010
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001011 return pte;
1012}
1013
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001014
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001015/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001016static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1017 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001018 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001019{
1020 struct dma_pte *parent, *pte = NULL;
1021 int total = agaw_to_level(domain->agaw);
1022 int offset;
1023
1024 parent = domain->pgd;
1025 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001026 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001027 pte = &parent[offset];
1028 if (level == total)
1029 return pte;
1030
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001031 if (!dma_pte_present(pte)) {
1032 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001033 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001034 }
1035
Yijing Wange16922a2014-05-20 20:37:51 +08001036 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001037 *large_page = total;
1038 return pte;
1039 }
1040
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001041 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001042 total--;
1043 }
1044 return NULL;
1045}
1046
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001047/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001048static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001049 unsigned long start_pfn,
1050 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001051{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001052 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001053 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001054
Jiang Liu162d1b12014-07-11 14:19:35 +08001055 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1056 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001057 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001058
David Woodhouse04b18e62009-06-27 19:15:01 +01001059 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001060 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001061 large_page = 1;
1062 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001063 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001064 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001065 continue;
1066 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001067 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001068 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001069 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001070 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001071 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1072
David Woodhouse310a5ab2009-06-28 18:52:20 +01001073 domain_flush_cache(domain, first_pte,
1074 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001075
1076 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001077}
1078
Alex Williamson3269ee02013-06-15 10:27:19 -06001079static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001080 int retain_level, struct dma_pte *pte,
1081 unsigned long pfn, unsigned long start_pfn,
1082 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001083{
1084 pfn = max(start_pfn, pfn);
1085 pte = &pte[pfn_level_offset(pfn, level)];
1086
1087 do {
1088 unsigned long level_pfn;
1089 struct dma_pte *level_pte;
1090
1091 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1092 goto next;
1093
David Dillowf7116e12017-01-30 19:11:11 -08001094 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001095 level_pte = phys_to_virt(dma_pte_addr(pte));
1096
David Dillowbc24c572017-06-28 19:42:23 -07001097 if (level > 2) {
1098 dma_pte_free_level(domain, level - 1, retain_level,
1099 level_pte, level_pfn, start_pfn,
1100 last_pfn);
1101 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001102
David Dillowbc24c572017-06-28 19:42:23 -07001103 /*
1104 * Free the page table if we're below the level we want to
1105 * retain and the range covers the entire table.
1106 */
1107 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001108 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001109 dma_clear_pte(pte);
1110 domain_flush_cache(domain, pte, sizeof(*pte));
1111 free_pgtable_page(level_pte);
1112 }
1113next:
1114 pfn += level_size(level);
1115 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1116}
1117
David Dillowbc24c572017-06-28 19:42:23 -07001118/*
1119 * clear last level (leaf) ptes and free page table pages below the
1120 * level we wish to keep intact.
1121 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001122static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001123 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001124 unsigned long last_pfn,
1125 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001126{
Jiang Liu162d1b12014-07-11 14:19:35 +08001127 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1128 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001129 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001130
Jiang Liud41a4ad2014-07-11 14:19:34 +08001131 dma_pte_clear_range(domain, start_pfn, last_pfn);
1132
David Woodhousef3a0a522009-06-30 03:40:07 +01001133 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001134 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001135 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001136
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001137 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001138 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001139 free_pgtable_page(domain->pgd);
1140 domain->pgd = NULL;
1141 }
1142}
1143
David Woodhouseea8ea462014-03-05 17:09:32 +00001144/* When a page at a given level is being unlinked from its parent, we don't
1145 need to *modify* it at all. All we need to do is make a list of all the
1146 pages which can be freed just as soon as we've flushed the IOTLB and we
1147 know the hardware page-walk will no longer touch them.
1148 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1149 be freed. */
1150static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1151 int level, struct dma_pte *pte,
1152 struct page *freelist)
1153{
1154 struct page *pg;
1155
1156 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1157 pg->freelist = freelist;
1158 freelist = pg;
1159
1160 if (level == 1)
1161 return freelist;
1162
Jiang Liuadeb2592014-04-09 10:20:39 +08001163 pte = page_address(pg);
1164 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001165 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1166 freelist = dma_pte_list_pagetables(domain, level - 1,
1167 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001168 pte++;
1169 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001170
1171 return freelist;
1172}
1173
1174static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1175 struct dma_pte *pte, unsigned long pfn,
1176 unsigned long start_pfn,
1177 unsigned long last_pfn,
1178 struct page *freelist)
1179{
1180 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1181
1182 pfn = max(start_pfn, pfn);
1183 pte = &pte[pfn_level_offset(pfn, level)];
1184
1185 do {
1186 unsigned long level_pfn;
1187
1188 if (!dma_pte_present(pte))
1189 goto next;
1190
1191 level_pfn = pfn & level_mask(level);
1192
1193 /* If range covers entire pagetable, free it */
1194 if (start_pfn <= level_pfn &&
1195 last_pfn >= level_pfn + level_size(level) - 1) {
1196 /* These suborbinate page tables are going away entirely. Don't
1197 bother to clear them; we're just going to *free* them. */
1198 if (level > 1 && !dma_pte_superpage(pte))
1199 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1200
1201 dma_clear_pte(pte);
1202 if (!first_pte)
1203 first_pte = pte;
1204 last_pte = pte;
1205 } else if (level > 1) {
1206 /* Recurse down into a level that isn't *entirely* obsolete */
1207 freelist = dma_pte_clear_level(domain, level - 1,
1208 phys_to_virt(dma_pte_addr(pte)),
1209 level_pfn, start_pfn, last_pfn,
1210 freelist);
1211 }
1212next:
1213 pfn += level_size(level);
1214 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1215
1216 if (first_pte)
1217 domain_flush_cache(domain, first_pte,
1218 (void *)++last_pte - (void *)first_pte);
1219
1220 return freelist;
1221}
1222
1223/* We can't just free the pages because the IOMMU may still be walking
1224 the page tables, and may have cached the intermediate levels. The
1225 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001226static struct page *domain_unmap(struct dmar_domain *domain,
1227 unsigned long start_pfn,
1228 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001229{
David Woodhouseea8ea462014-03-05 17:09:32 +00001230 struct page *freelist = NULL;
1231
Jiang Liu162d1b12014-07-11 14:19:35 +08001232 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1233 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001234 BUG_ON(start_pfn > last_pfn);
1235
1236 /* we don't need lock here; nobody else touches the iova range */
1237 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1238 domain->pgd, 0, start_pfn, last_pfn, NULL);
1239
1240 /* free pgd */
1241 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1242 struct page *pgd_page = virt_to_page(domain->pgd);
1243 pgd_page->freelist = freelist;
1244 freelist = pgd_page;
1245
1246 domain->pgd = NULL;
1247 }
1248
1249 return freelist;
1250}
1251
Joerg Roedelb6904202015-08-13 11:32:18 +02001252static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001253{
1254 struct page *pg;
1255
1256 while ((pg = freelist)) {
1257 freelist = pg->freelist;
1258 free_pgtable_page(page_address(pg));
1259 }
1260}
1261
Joerg Roedel13cf0172017-08-11 11:40:10 +02001262static void iova_entry_free(unsigned long data)
1263{
1264 struct page *freelist = (struct page *)data;
1265
1266 dma_free_pagelist(freelist);
1267}
1268
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001269/* iommu handling */
1270static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1271{
1272 struct root_entry *root;
1273 unsigned long flags;
1274
Suresh Siddha4c923d42009-10-02 11:01:24 -07001275 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001276 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001277 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001278 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001279 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001280 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001281
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001282 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001283
1284 spin_lock_irqsave(&iommu->lock, flags);
1285 iommu->root_entry = root;
1286 spin_unlock_irqrestore(&iommu->lock, flags);
1287
1288 return 0;
1289}
1290
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001291static void iommu_set_root_entry(struct intel_iommu *iommu)
1292{
David Woodhouse03ecc322015-02-13 14:35:21 +00001293 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001294 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001295 unsigned long flag;
1296
David Woodhouse03ecc322015-02-13 14:35:21 +00001297 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001298 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001299 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001300
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001301 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001302 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001303
David Woodhousec416daa2009-05-10 20:30:58 +01001304 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001305
1306 /* Make sure hardware complete it */
1307 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001308 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001309
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001310 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001311}
1312
1313static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1314{
1315 u32 val;
1316 unsigned long flag;
1317
David Woodhouse9af88142009-02-13 23:18:03 +00001318 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001319 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001320
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001321 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001322 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001323
1324 /* Make sure hardware complete it */
1325 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001326 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001327
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001328 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001329}
1330
1331/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001332static void __iommu_flush_context(struct intel_iommu *iommu,
1333 u16 did, u16 source_id, u8 function_mask,
1334 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001335{
1336 u64 val = 0;
1337 unsigned long flag;
1338
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001339 switch (type) {
1340 case DMA_CCMD_GLOBAL_INVL:
1341 val = DMA_CCMD_GLOBAL_INVL;
1342 break;
1343 case DMA_CCMD_DOMAIN_INVL:
1344 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1345 break;
1346 case DMA_CCMD_DEVICE_INVL:
1347 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1348 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1349 break;
1350 default:
1351 BUG();
1352 }
1353 val |= DMA_CCMD_ICC;
1354
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001355 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001356 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1357
1358 /* Make sure hardware complete it */
1359 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1360 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1361
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001362 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001363}
1364
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001365/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001366static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1367 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001368{
1369 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1370 u64 val = 0, val_iva = 0;
1371 unsigned long flag;
1372
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001373 switch (type) {
1374 case DMA_TLB_GLOBAL_FLUSH:
1375 /* global flush doesn't need set IVA_REG */
1376 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1377 break;
1378 case DMA_TLB_DSI_FLUSH:
1379 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1380 break;
1381 case DMA_TLB_PSI_FLUSH:
1382 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001383 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001384 val_iva = size_order | addr;
1385 break;
1386 default:
1387 BUG();
1388 }
1389 /* Note: set drain read/write */
1390#if 0
1391 /*
1392 * This is probably to be super secure.. Looks like we can
1393 * ignore it without any impact.
1394 */
1395 if (cap_read_drain(iommu->cap))
1396 val |= DMA_TLB_READ_DRAIN;
1397#endif
1398 if (cap_write_drain(iommu->cap))
1399 val |= DMA_TLB_WRITE_DRAIN;
1400
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001401 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001402 /* Note: Only uses first TLB reg currently */
1403 if (val_iva)
1404 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1405 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1406
1407 /* Make sure hardware complete it */
1408 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1409 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1410
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001411 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001412
1413 /* check IOTLB invalidation granularity */
1414 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001415 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001416 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001417 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001418 (unsigned long long)DMA_TLB_IIRG(type),
1419 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001420}
1421
David Woodhouse64ae8922014-03-09 12:52:30 -07001422static struct device_domain_info *
1423iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1424 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001425{
Yu Zhao93a23a72009-05-18 13:51:37 +08001426 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001427
Joerg Roedel55d94042015-07-22 16:50:40 +02001428 assert_spin_locked(&device_domain_lock);
1429
Yu Zhao93a23a72009-05-18 13:51:37 +08001430 if (!iommu->qi)
1431 return NULL;
1432
Yu Zhao93a23a72009-05-18 13:51:37 +08001433 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001434 if (info->iommu == iommu && info->bus == bus &&
1435 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001436 if (info->ats_supported && info->dev)
1437 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001438 break;
1439 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001440
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001441 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001442}
1443
Omer Peleg0824c592016-04-20 19:03:35 +03001444static void domain_update_iotlb(struct dmar_domain *domain)
1445{
1446 struct device_domain_info *info;
1447 bool has_iotlb_device = false;
1448
1449 assert_spin_locked(&device_domain_lock);
1450
1451 list_for_each_entry(info, &domain->devices, link) {
1452 struct pci_dev *pdev;
1453
1454 if (!info->dev || !dev_is_pci(info->dev))
1455 continue;
1456
1457 pdev = to_pci_dev(info->dev);
1458 if (pdev->ats_enabled) {
1459 has_iotlb_device = true;
1460 break;
1461 }
1462 }
1463
1464 domain->has_iotlb_device = has_iotlb_device;
1465}
1466
Yu Zhao93a23a72009-05-18 13:51:37 +08001467static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1468{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001469 struct pci_dev *pdev;
1470
Omer Peleg0824c592016-04-20 19:03:35 +03001471 assert_spin_locked(&device_domain_lock);
1472
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001473 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001474 return;
1475
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001476 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001477
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001478#ifdef CONFIG_INTEL_IOMMU_SVM
1479 /* The PCIe spec, in its wisdom, declares that the behaviour of
1480 the device if you enable PASID support after ATS support is
1481 undefined. So always enable PASID support on devices which
1482 have it, even if we can't yet know if we're ever going to
1483 use it. */
1484 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1485 info->pasid_enabled = 1;
1486
1487 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1488 info->pri_enabled = 1;
1489#endif
1490 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1491 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001492 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001493 info->ats_qdep = pci_ats_queue_depth(pdev);
1494 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001495}
1496
1497static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1498{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001499 struct pci_dev *pdev;
1500
Omer Peleg0824c592016-04-20 19:03:35 +03001501 assert_spin_locked(&device_domain_lock);
1502
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001503 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001504 return;
1505
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001506 pdev = to_pci_dev(info->dev);
1507
1508 if (info->ats_enabled) {
1509 pci_disable_ats(pdev);
1510 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001511 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001512 }
1513#ifdef CONFIG_INTEL_IOMMU_SVM
1514 if (info->pri_enabled) {
1515 pci_disable_pri(pdev);
1516 info->pri_enabled = 0;
1517 }
1518 if (info->pasid_enabled) {
1519 pci_disable_pasid(pdev);
1520 info->pasid_enabled = 0;
1521 }
1522#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001523}
1524
1525static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1526 u64 addr, unsigned mask)
1527{
1528 u16 sid, qdep;
1529 unsigned long flags;
1530 struct device_domain_info *info;
1531
Omer Peleg0824c592016-04-20 19:03:35 +03001532 if (!domain->has_iotlb_device)
1533 return;
1534
Yu Zhao93a23a72009-05-18 13:51:37 +08001535 spin_lock_irqsave(&device_domain_lock, flags);
1536 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001537 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001538 continue;
1539
1540 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001541 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001542 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1543 }
1544 spin_unlock_irqrestore(&device_domain_lock, flags);
1545}
1546
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001547static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1548 struct dmar_domain *domain,
1549 unsigned long pfn, unsigned int pages,
1550 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001551{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001552 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001553 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001554 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001555
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001556 BUG_ON(pages == 0);
1557
David Woodhouseea8ea462014-03-05 17:09:32 +00001558 if (ih)
1559 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001560 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001561 * Fallback to domain selective flush if no PSI support or the size is
1562 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001563 * PSI requires page size to be 2 ^ x, and the base address is naturally
1564 * aligned to the size
1565 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001566 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1567 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001568 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001569 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001570 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001571 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001572
1573 /*
Nadav Amit82653632010-04-01 13:24:40 +03001574 * In caching mode, changes of pages from non-present to present require
1575 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001576 */
Nadav Amit82653632010-04-01 13:24:40 +03001577 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001578 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001579}
1580
Peter Xueed91a02018-05-04 10:34:52 +08001581/* Notification for newly created mappings */
1582static inline void __mapping_notify_one(struct intel_iommu *iommu,
1583 struct dmar_domain *domain,
1584 unsigned long pfn, unsigned int pages)
1585{
1586 /* It's a non-present to present mapping. Only flush if caching mode */
1587 if (cap_caching_mode(iommu->cap))
1588 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1589 else
1590 iommu_flush_write_buffer(iommu);
1591}
1592
Joerg Roedel13cf0172017-08-11 11:40:10 +02001593static void iommu_flush_iova(struct iova_domain *iovad)
1594{
1595 struct dmar_domain *domain;
1596 int idx;
1597
1598 domain = container_of(iovad, struct dmar_domain, iovad);
1599
1600 for_each_domain_iommu(idx, domain) {
1601 struct intel_iommu *iommu = g_iommus[idx];
1602 u16 did = domain->iommu_did[iommu->seq_id];
1603
1604 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1605
1606 if (!cap_caching_mode(iommu->cap))
1607 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1608 0, MAX_AGAW_PFN_WIDTH);
1609 }
1610}
1611
mark grossf8bab732008-02-08 04:18:38 -08001612static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1613{
1614 u32 pmen;
1615 unsigned long flags;
1616
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001617 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001618 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1619 pmen &= ~DMA_PMEN_EPM;
1620 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1621
1622 /* wait for the protected region status bit to clear */
1623 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1624 readl, !(pmen & DMA_PMEN_PRS), pmen);
1625
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001626 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001627}
1628
Jiang Liu2a41cce2014-07-11 14:19:33 +08001629static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001630{
1631 u32 sts;
1632 unsigned long flags;
1633
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001634 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001635 iommu->gcmd |= DMA_GCMD_TE;
1636 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001637
1638 /* Make sure hardware complete it */
1639 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001640 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001641
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001642 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001643}
1644
Jiang Liu2a41cce2014-07-11 14:19:33 +08001645static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001646{
1647 u32 sts;
1648 unsigned long flag;
1649
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001650 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001651 iommu->gcmd &= ~DMA_GCMD_TE;
1652 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1653
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, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001659}
1660
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001661
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001662static int iommu_init_domains(struct intel_iommu *iommu)
1663{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001664 u32 ndomains, nlongs;
1665 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001666
1667 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001668 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001669 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001670 nlongs = BITS_TO_LONGS(ndomains);
1671
Donald Dutile94a91b52009-08-20 16:51:34 -04001672 spin_lock_init(&iommu->lock);
1673
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001674 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1675 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001676 pr_err("%s: Allocating domain id array failed\n",
1677 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678 return -ENOMEM;
1679 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001680
Wei Yang86f004c2016-05-21 02:41:51 +00001681 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001682 iommu->domains = kzalloc(size, GFP_KERNEL);
1683
1684 if (iommu->domains) {
1685 size = 256 * sizeof(struct dmar_domain *);
1686 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1687 }
1688
1689 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001690 pr_err("%s: Allocating domain array failed\n",
1691 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001692 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001693 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001694 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001695 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001696 return -ENOMEM;
1697 }
1698
Joerg Roedel8bf47812015-07-21 10:41:21 +02001699
1700
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001701 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001702 * If Caching mode is set, then invalid translations are tagged
1703 * with domain-id 0, hence we need to pre-allocate it. We also
1704 * use domain-id 0 as a marker for non-allocated domain-id, so
1705 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001706 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001707 set_bit(0, iommu->domain_ids);
1708
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001709 return 0;
1710}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001711
Jiang Liuffebeb42014-11-09 22:48:02 +08001712static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001713{
Joerg Roedel29a27712015-07-21 17:17:12 +02001714 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001715 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001716
Joerg Roedel29a27712015-07-21 17:17:12 +02001717 if (!iommu->domains || !iommu->domain_ids)
1718 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001719
Joerg Roedelbea64032016-11-08 15:08:26 +01001720again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001721 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001722 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1723 struct dmar_domain *domain;
1724
1725 if (info->iommu != iommu)
1726 continue;
1727
1728 if (!info->dev || !info->domain)
1729 continue;
1730
1731 domain = info->domain;
1732
Joerg Roedelbea64032016-11-08 15:08:26 +01001733 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001734
Joerg Roedelbea64032016-11-08 15:08:26 +01001735 if (!domain_type_is_vm_or_si(domain)) {
1736 /*
1737 * The domain_exit() function can't be called under
1738 * device_domain_lock, as it takes this lock itself.
1739 * So release the lock here and re-run the loop
1740 * afterwards.
1741 */
1742 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001743 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001744 goto again;
1745 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001746 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001747 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001748
1749 if (iommu->gcmd & DMA_GCMD_TE)
1750 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001751}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001752
Jiang Liuffebeb42014-11-09 22:48:02 +08001753static void free_dmar_iommu(struct intel_iommu *iommu)
1754{
1755 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001756 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001757 int i;
1758
1759 for (i = 0; i < elems; i++)
1760 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001761 kfree(iommu->domains);
1762 kfree(iommu->domain_ids);
1763 iommu->domains = NULL;
1764 iommu->domain_ids = NULL;
1765 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001766
Weidong Hand9630fe2008-12-08 11:06:32 +08001767 g_iommus[iommu->seq_id] = NULL;
1768
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001769 /* free context mapping */
1770 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001771
1772#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001773 if (pasid_enabled(iommu)) {
1774 if (ecap_prs(iommu->ecap))
1775 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001776 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001777 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001778#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001779}
1780
Jiang Liuab8dfe22014-07-11 14:19:27 +08001781static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001782{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001783 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001784
1785 domain = alloc_domain_mem();
1786 if (!domain)
1787 return NULL;
1788
Jiang Liuab8dfe22014-07-11 14:19:27 +08001789 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001790 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001791 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001792 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001793 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001794
1795 return domain;
1796}
1797
Joerg Roedeld160aca2015-07-22 11:52:53 +02001798/* Must be called with iommu->lock */
1799static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001800 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001801{
Jiang Liu44bde612014-07-11 14:19:29 +08001802 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001803 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001804
Joerg Roedel55d94042015-07-22 16:50:40 +02001805 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001806 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001807
Joerg Roedel29a27712015-07-21 17:17:12 +02001808 domain->iommu_refcnt[iommu->seq_id] += 1;
1809 domain->iommu_count += 1;
1810 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001811 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001812 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1813
1814 if (num >= ndomains) {
1815 pr_err("%s: No free domain ids\n", iommu->name);
1816 domain->iommu_refcnt[iommu->seq_id] -= 1;
1817 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001818 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001819 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001820
Joerg Roedeld160aca2015-07-22 11:52:53 +02001821 set_bit(num, iommu->domain_ids);
1822 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001823
Joerg Roedeld160aca2015-07-22 11:52:53 +02001824 domain->iommu_did[iommu->seq_id] = num;
1825 domain->nid = iommu->node;
1826
Jiang Liufb170fb2014-07-11 14:19:28 +08001827 domain_update_iommu_cap(domain);
1828 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001829
Joerg Roedel55d94042015-07-22 16:50:40 +02001830 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001831}
1832
1833static int domain_detach_iommu(struct dmar_domain *domain,
1834 struct intel_iommu *iommu)
1835{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001836 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001837
Joerg Roedel55d94042015-07-22 16:50:40 +02001838 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001839 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001840
Joerg Roedel29a27712015-07-21 17:17:12 +02001841 domain->iommu_refcnt[iommu->seq_id] -= 1;
1842 count = --domain->iommu_count;
1843 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001844 num = domain->iommu_did[iommu->seq_id];
1845 clear_bit(num, iommu->domain_ids);
1846 set_iommu_domain(iommu, num, NULL);
1847
Jiang Liufb170fb2014-07-11 14:19:28 +08001848 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001849 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001850 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001851
1852 return count;
1853}
1854
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001855static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001856static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001857
Joseph Cihula51a63e62011-03-21 11:04:24 -07001858static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001859{
1860 struct pci_dev *pdev = NULL;
1861 struct iova *iova;
1862 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001863
Zhen Leiaa3ac942017-09-21 16:52:45 +01001864 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001865
Mark Gross8a443df2008-03-04 14:59:31 -08001866 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1867 &reserved_rbtree_key);
1868
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001869 /* IOAPIC ranges shouldn't be accessed by DMA */
1870 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1871 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001872 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001873 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001874 return -ENODEV;
1875 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001876
1877 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1878 for_each_pci_dev(pdev) {
1879 struct resource *r;
1880
1881 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1882 r = &pdev->resource[i];
1883 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1884 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001885 iova = reserve_iova(&reserved_iova_list,
1886 IOVA_PFN(r->start),
1887 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001888 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001889 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001890 return -ENODEV;
1891 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001892 }
1893 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001894 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001895}
1896
1897static void domain_reserve_special_ranges(struct dmar_domain *domain)
1898{
1899 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1900}
1901
1902static inline int guestwidth_to_adjustwidth(int gaw)
1903{
1904 int agaw;
1905 int r = (gaw - 12) % 9;
1906
1907 if (r == 0)
1908 agaw = gaw;
1909 else
1910 agaw = gaw + 9 - r;
1911 if (agaw > 64)
1912 agaw = 64;
1913 return agaw;
1914}
1915
Joerg Roedeldc534b22015-07-22 12:44:02 +02001916static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1917 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001918{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001919 int adjust_width, agaw;
1920 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001921 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001922
Zhen Leiaa3ac942017-09-21 16:52:45 +01001923 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001924
1925 err = init_iova_flush_queue(&domain->iovad,
1926 iommu_flush_iova, iova_entry_free);
1927 if (err)
1928 return err;
1929
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001930 domain_reserve_special_ranges(domain);
1931
1932 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001933 if (guest_width > cap_mgaw(iommu->cap))
1934 guest_width = cap_mgaw(iommu->cap);
1935 domain->gaw = guest_width;
1936 adjust_width = guestwidth_to_adjustwidth(guest_width);
1937 agaw = width_to_agaw(adjust_width);
1938 sagaw = cap_sagaw(iommu->cap);
1939 if (!test_bit(agaw, &sagaw)) {
1940 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001941 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001942 agaw = find_next_bit(&sagaw, 5, agaw);
1943 if (agaw >= 5)
1944 return -ENODEV;
1945 }
1946 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001947
Weidong Han8e6040972008-12-08 15:49:06 +08001948 if (ecap_coherent(iommu->ecap))
1949 domain->iommu_coherency = 1;
1950 else
1951 domain->iommu_coherency = 0;
1952
Sheng Yang58c610b2009-03-18 15:33:05 +08001953 if (ecap_sc_support(iommu->ecap))
1954 domain->iommu_snooping = 1;
1955 else
1956 domain->iommu_snooping = 0;
1957
David Woodhouse214e39a2014-03-19 10:38:49 +00001958 if (intel_iommu_superpage)
1959 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1960 else
1961 domain->iommu_superpage = 0;
1962
Suresh Siddha4c923d42009-10-02 11:01:24 -07001963 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001964
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001965 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001966 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001967 if (!domain->pgd)
1968 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001969 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001970 return 0;
1971}
1972
1973static void domain_exit(struct dmar_domain *domain)
1974{
David Woodhouseea8ea462014-03-05 17:09:32 +00001975 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001976
1977 /* Domain 0 is reserved, so dont process it */
1978 if (!domain)
1979 return;
1980
Joerg Roedeld160aca2015-07-22 11:52:53 +02001981 /* Remove associated devices and clear attached or cached domains */
1982 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001983 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001984 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08001985
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 /* destroy iovas */
1987 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001988
David Woodhouseea8ea462014-03-05 17:09:32 +00001989 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001990
David Woodhouseea8ea462014-03-05 17:09:32 +00001991 dma_free_pagelist(freelist);
1992
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001993 free_domain_mem(domain);
1994}
1995
David Woodhouse64ae8922014-03-09 12:52:30 -07001996static int domain_context_mapping_one(struct dmar_domain *domain,
1997 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001998 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001999{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002000 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002001 int translation = CONTEXT_TT_MULTI_LEVEL;
2002 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002003 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002005 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002006 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002007
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002008 WARN_ON(did == 0);
2009
Joerg Roedel28ccce02015-07-21 14:45:31 +02002010 if (hw_pass_through && domain_type_is_si(domain))
2011 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002012
2013 pr_debug("Set context mapping for %02x:%02x.%d\n",
2014 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002015
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002016 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002017
Joerg Roedel55d94042015-07-22 16:50:40 +02002018 spin_lock_irqsave(&device_domain_lock, flags);
2019 spin_lock(&iommu->lock);
2020
2021 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002022 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002023 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002024 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002025
Joerg Roedel55d94042015-07-22 16:50:40 +02002026 ret = 0;
2027 if (context_present(context))
2028 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002029
Xunlei Pangaec0e862016-12-05 20:09:07 +08002030 /*
2031 * For kdump cases, old valid entries may be cached due to the
2032 * in-flight DMA and copied pgtable, but there is no unmapping
2033 * behaviour for them, thus we need an explicit cache flush for
2034 * the newly-mapped device. For kdump, at this point, the device
2035 * is supposed to finish reset at its driver probe stage, so no
2036 * in-flight DMA will exist, and we don't need to worry anymore
2037 * hereafter.
2038 */
2039 if (context_copied(context)) {
2040 u16 did_old = context_domain_id(context);
2041
Christos Gkekasb117e032017-10-08 23:33:31 +01002042 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002043 iommu->flush.flush_context(iommu, did_old,
2044 (((u16)bus) << 8) | devfn,
2045 DMA_CCMD_MASK_NOBIT,
2046 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002047 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2048 DMA_TLB_DSI_FLUSH);
2049 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002050 }
2051
Weidong Hanea6606b2008-12-08 23:08:15 +08002052 pgd = domain->pgd;
2053
Joerg Roedelde24e552015-07-21 14:53:04 +02002054 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002055 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002056
Joerg Roedelde24e552015-07-21 14:53:04 +02002057 /*
2058 * Skip top levels of page tables for iommu which has less agaw
2059 * than default. Unnecessary for PT mode.
2060 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002061 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002062 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002063 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002064 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002065 if (!dma_pte_present(pgd))
2066 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002067 }
2068
David Woodhouse64ae8922014-03-09 12:52:30 -07002069 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002070 if (info && info->ats_supported)
2071 translation = CONTEXT_TT_DEV_IOTLB;
2072 else
2073 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002074
Yu Zhao93a23a72009-05-18 13:51:37 +08002075 context_set_address_root(context, virt_to_phys(pgd));
2076 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002077 } else {
2078 /*
2079 * In pass through mode, AW must be programmed to
2080 * indicate the largest AGAW value supported by
2081 * hardware. And ASR is ignored by hardware.
2082 */
2083 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002084 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002085
2086 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002087 context_set_fault_enable(context);
2088 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002089 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002090
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002091 /*
2092 * It's a non-present to present mapping. If hardware doesn't cache
2093 * non-present entry we only need to flush the write-buffer. If the
2094 * _does_ cache non-present entries, then it does so in the special
2095 * domain #0, which we have to flush:
2096 */
2097 if (cap_caching_mode(iommu->cap)) {
2098 iommu->flush.flush_context(iommu, 0,
2099 (((u16)bus) << 8) | devfn,
2100 DMA_CCMD_MASK_NOBIT,
2101 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002102 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002103 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002104 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002105 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002106 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002107
Joerg Roedel55d94042015-07-22 16:50:40 +02002108 ret = 0;
2109
2110out_unlock:
2111 spin_unlock(&iommu->lock);
2112 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002113
Wei Yang5c365d12016-07-13 13:53:21 +00002114 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002115}
2116
Alex Williamson579305f2014-07-03 09:51:43 -06002117struct domain_context_mapping_data {
2118 struct dmar_domain *domain;
2119 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002120};
2121
2122static int domain_context_mapping_cb(struct pci_dev *pdev,
2123 u16 alias, void *opaque)
2124{
2125 struct domain_context_mapping_data *data = opaque;
2126
2127 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002128 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002129}
2130
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002131static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002132domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002133{
David Woodhouse64ae8922014-03-09 12:52:30 -07002134 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002135 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002136 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002137
David Woodhousee1f167f2014-03-09 15:24:46 -07002138 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002139 if (!iommu)
2140 return -ENODEV;
2141
Alex Williamson579305f2014-07-03 09:51:43 -06002142 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002143 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002144
2145 data.domain = domain;
2146 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002147
2148 return pci_for_each_dma_alias(to_pci_dev(dev),
2149 &domain_context_mapping_cb, &data);
2150}
2151
2152static int domain_context_mapped_cb(struct pci_dev *pdev,
2153 u16 alias, void *opaque)
2154{
2155 struct intel_iommu *iommu = opaque;
2156
2157 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002158}
2159
David Woodhousee1f167f2014-03-09 15:24:46 -07002160static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002161{
Weidong Han5331fe62008-12-08 23:00:00 +08002162 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002163 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002164
David Woodhousee1f167f2014-03-09 15:24:46 -07002165 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002166 if (!iommu)
2167 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002168
Alex Williamson579305f2014-07-03 09:51:43 -06002169 if (!dev_is_pci(dev))
2170 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002171
Alex Williamson579305f2014-07-03 09:51:43 -06002172 return !pci_for_each_dma_alias(to_pci_dev(dev),
2173 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002174}
2175
Fenghua Yuf5329592009-08-04 15:09:37 -07002176/* Returns a number of VTD pages, but aligned to MM page size */
2177static inline unsigned long aligned_nrpages(unsigned long host_addr,
2178 size_t size)
2179{
2180 host_addr &= ~PAGE_MASK;
2181 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2182}
2183
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002184/* Return largest possible superpage level for a given mapping */
2185static inline int hardware_largepage_caps(struct dmar_domain *domain,
2186 unsigned long iov_pfn,
2187 unsigned long phy_pfn,
2188 unsigned long pages)
2189{
2190 int support, level = 1;
2191 unsigned long pfnmerge;
2192
2193 support = domain->iommu_superpage;
2194
2195 /* To use a large page, the virtual *and* physical addresses
2196 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2197 of them will mean we have to use smaller pages. So just
2198 merge them and check both at once. */
2199 pfnmerge = iov_pfn | phy_pfn;
2200
2201 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2202 pages >>= VTD_STRIDE_SHIFT;
2203 if (!pages)
2204 break;
2205 pfnmerge >>= VTD_STRIDE_SHIFT;
2206 level++;
2207 support--;
2208 }
2209 return level;
2210}
2211
David Woodhouse9051aa02009-06-29 12:30:54 +01002212static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2213 struct scatterlist *sg, unsigned long phys_pfn,
2214 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002215{
2216 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002217 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002218 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002219 unsigned int largepage_lvl = 0;
2220 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002221
Jiang Liu162d1b12014-07-11 14:19:35 +08002222 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002223
2224 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2225 return -EINVAL;
2226
2227 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2228
Jiang Liucc4f14a2014-11-26 09:42:10 +08002229 if (!sg) {
2230 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002231 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2232 }
2233
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002234 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002235 uint64_t tmp;
2236
David Woodhousee1605492009-06-29 11:17:38 +01002237 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002238 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2239
Fenghua Yuf5329592009-08-04 15:09:37 -07002240 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002241 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002242 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002243 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002244 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002245 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002246
David Woodhousee1605492009-06-29 11:17:38 +01002247 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002248 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2249
David Woodhouse5cf0a762014-03-19 16:07:49 +00002250 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002251 if (!pte)
2252 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002253 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002254 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002255 unsigned long nr_superpages, end_pfn;
2256
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002257 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002258 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002259
2260 nr_superpages = sg_res / lvl_pages;
2261 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2262
Jiang Liud41a4ad2014-07-11 14:19:34 +08002263 /*
2264 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002265 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002266 * We're adding new large pages, so make sure
2267 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002268 */
David Dillowbc24c572017-06-28 19:42:23 -07002269 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2270 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002271 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002272 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002273 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002274
David Woodhousee1605492009-06-29 11:17:38 +01002275 }
2276 /* We don't need lock here, nobody else
2277 * touches the iova range
2278 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002279 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002280 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002281 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002282 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2283 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002284 if (dumps) {
2285 dumps--;
2286 debug_dma_dump_mappings(NULL);
2287 }
2288 WARN_ON(1);
2289 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002290
2291 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2292
2293 BUG_ON(nr_pages < lvl_pages);
2294 BUG_ON(sg_res < lvl_pages);
2295
2296 nr_pages -= lvl_pages;
2297 iov_pfn += lvl_pages;
2298 phys_pfn += lvl_pages;
2299 pteval += lvl_pages * VTD_PAGE_SIZE;
2300 sg_res -= lvl_pages;
2301
2302 /* If the next PTE would be the first in a new page, then we
2303 need to flush the cache on the entries we've just written.
2304 And then we'll need to recalculate 'pte', so clear it and
2305 let it get set again in the if (!pte) block above.
2306
2307 If we're done (!nr_pages) we need to flush the cache too.
2308
2309 Also if we've been setting superpages, we may need to
2310 recalculate 'pte' and switch back to smaller pages for the
2311 end of the mapping, if the trailing size is not enough to
2312 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002313 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002314 if (!nr_pages || first_pte_in_page(pte) ||
2315 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002316 domain_flush_cache(domain, first_pte,
2317 (void *)pte - (void *)first_pte);
2318 pte = NULL;
2319 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002320
2321 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002322 sg = sg_next(sg);
2323 }
2324 return 0;
2325}
2326
Peter Xu87684fd2018-05-04 10:34:53 +08002327static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2328 struct scatterlist *sg, unsigned long phys_pfn,
2329 unsigned long nr_pages, int prot)
2330{
2331 int ret;
2332 struct intel_iommu *iommu;
2333
2334 /* Do the real mapping first */
2335 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2336 if (ret)
2337 return ret;
2338
2339 /* Notify about the new mapping */
2340 if (domain_type_is_vm(domain)) {
2341 /* VM typed domains can have more than one IOMMUs */
2342 int iommu_id;
2343 for_each_domain_iommu(iommu_id, domain) {
2344 iommu = g_iommus[iommu_id];
2345 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2346 }
2347 } else {
2348 /* General domains only have one IOMMU */
2349 iommu = domain_get_iommu(domain);
2350 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2351 }
2352
2353 return 0;
2354}
2355
David Woodhouse9051aa02009-06-29 12:30:54 +01002356static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2357 struct scatterlist *sg, unsigned long nr_pages,
2358 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002359{
Peter Xu87684fd2018-05-04 10:34:53 +08002360 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002361}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002362
David Woodhouse9051aa02009-06-29 12:30:54 +01002363static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2364 unsigned long phys_pfn, unsigned long nr_pages,
2365 int prot)
2366{
Peter Xu87684fd2018-05-04 10:34:53 +08002367 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002368}
2369
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002370static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002371{
Filippo Sironi50822192017-08-31 10:58:11 +02002372 unsigned long flags;
2373 struct context_entry *context;
2374 u16 did_old;
2375
Weidong Hanc7151a82008-12-08 22:51:37 +08002376 if (!iommu)
2377 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002378
Filippo Sironi50822192017-08-31 10:58:11 +02002379 spin_lock_irqsave(&iommu->lock, flags);
2380 context = iommu_context_addr(iommu, bus, devfn, 0);
2381 if (!context) {
2382 spin_unlock_irqrestore(&iommu->lock, flags);
2383 return;
2384 }
2385 did_old = context_domain_id(context);
2386 context_clear_entry(context);
2387 __iommu_flush_cache(iommu, context, sizeof(*context));
2388 spin_unlock_irqrestore(&iommu->lock, flags);
2389 iommu->flush.flush_context(iommu,
2390 did_old,
2391 (((u16)bus) << 8) | devfn,
2392 DMA_CCMD_MASK_NOBIT,
2393 DMA_CCMD_DEVICE_INVL);
2394 iommu->flush.flush_iotlb(iommu,
2395 did_old,
2396 0,
2397 0,
2398 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002399}
2400
David Woodhouse109b9b02012-05-25 17:43:02 +01002401static inline void unlink_domain_info(struct device_domain_info *info)
2402{
2403 assert_spin_locked(&device_domain_lock);
2404 list_del(&info->link);
2405 list_del(&info->global);
2406 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002407 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002408}
2409
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002410static void domain_remove_dev_info(struct dmar_domain *domain)
2411{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002412 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002413 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002414
2415 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002416 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002417 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002418 spin_unlock_irqrestore(&device_domain_lock, flags);
2419}
2420
2421/*
2422 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002423 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002424 */
David Woodhouse1525a292014-03-06 16:19:30 +00002425static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002426{
2427 struct device_domain_info *info;
2428
2429 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002430 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002431 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002432 return info->domain;
2433 return NULL;
2434}
2435
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002436static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002437dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2438{
2439 struct device_domain_info *info;
2440
2441 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002442 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002443 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002444 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002445
2446 return NULL;
2447}
2448
Joerg Roedel5db31562015-07-22 12:40:43 +02002449static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2450 int bus, int devfn,
2451 struct device *dev,
2452 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002453{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002454 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002455 struct device_domain_info *info;
2456 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002457 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002458
2459 info = alloc_devinfo_mem();
2460 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002461 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002462
Jiang Liu745f2582014-02-19 14:07:26 +08002463 info->bus = bus;
2464 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002465 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2466 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2467 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002468 info->dev = dev;
2469 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002470 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002471
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002472 if (dev && dev_is_pci(dev)) {
2473 struct pci_dev *pdev = to_pci_dev(info->dev);
2474
Gil Kupfercef74402018-05-10 17:56:02 -05002475 if (!pci_ats_disabled() &&
2476 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002477 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2478 dmar_find_matched_atsr_unit(pdev))
2479 info->ats_supported = 1;
2480
2481 if (ecs_enabled(iommu)) {
2482 if (pasid_enabled(iommu)) {
2483 int features = pci_pasid_features(pdev);
2484 if (features >= 0)
2485 info->pasid_supported = features | 1;
2486 }
2487
2488 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2489 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2490 info->pri_supported = 1;
2491 }
2492 }
2493
Jiang Liu745f2582014-02-19 14:07:26 +08002494 spin_lock_irqsave(&device_domain_lock, flags);
2495 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002496 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002497
2498 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002499 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002500 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002501 if (info2) {
2502 found = info2->domain;
2503 info2->dev = dev;
2504 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002505 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002506
Jiang Liu745f2582014-02-19 14:07:26 +08002507 if (found) {
2508 spin_unlock_irqrestore(&device_domain_lock, flags);
2509 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002510 /* Caller must free the original domain */
2511 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002512 }
2513
Joerg Roedeld160aca2015-07-22 11:52:53 +02002514 spin_lock(&iommu->lock);
2515 ret = domain_attach_iommu(domain, iommu);
2516 spin_unlock(&iommu->lock);
2517
2518 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002519 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302520 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002521 return NULL;
2522 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002523
David Woodhouseb718cd32014-03-09 13:11:33 -07002524 list_add(&info->link, &domain->devices);
2525 list_add(&info->global, &device_domain_list);
2526 if (dev)
2527 dev->archdata.iommu = info;
2528 spin_unlock_irqrestore(&device_domain_lock, flags);
2529
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002530 if (dev && domain_context_mapping(domain, dev)) {
2531 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002532 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002533 return NULL;
2534 }
2535
David Woodhouseb718cd32014-03-09 13:11:33 -07002536 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002537}
2538
Alex Williamson579305f2014-07-03 09:51:43 -06002539static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2540{
2541 *(u16 *)opaque = alias;
2542 return 0;
2543}
2544
Joerg Roedel76208352016-08-25 14:25:12 +02002545static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002546{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002547 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002548 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002549 struct intel_iommu *iommu;
Lu Baolufcc35c62018-05-04 13:08:17 +08002550 u16 dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002551 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002552 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002553
David Woodhouse146922e2014-03-09 15:44:17 -07002554 iommu = device_to_iommu(dev, &bus, &devfn);
2555 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002556 return NULL;
2557
2558 if (dev_is_pci(dev)) {
2559 struct pci_dev *pdev = to_pci_dev(dev);
2560
2561 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2562
2563 spin_lock_irqsave(&device_domain_lock, flags);
2564 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2565 PCI_BUS_NUM(dma_alias),
2566 dma_alias & 0xff);
2567 if (info) {
2568 iommu = info->iommu;
2569 domain = info->domain;
2570 }
2571 spin_unlock_irqrestore(&device_domain_lock, flags);
2572
Joerg Roedel76208352016-08-25 14:25:12 +02002573 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002574 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002575 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002576 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002577
David Woodhouse146922e2014-03-09 15:44:17 -07002578 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002579 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002580 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002581 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002582 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002583 domain_exit(domain);
2584 return NULL;
2585 }
2586
Joerg Roedel76208352016-08-25 14:25:12 +02002587out:
Alex Williamson579305f2014-07-03 09:51:43 -06002588
Joerg Roedel76208352016-08-25 14:25:12 +02002589 return domain;
2590}
2591
2592static struct dmar_domain *set_domain_for_dev(struct device *dev,
2593 struct dmar_domain *domain)
2594{
2595 struct intel_iommu *iommu;
2596 struct dmar_domain *tmp;
2597 u16 req_id, dma_alias;
2598 u8 bus, devfn;
2599
2600 iommu = device_to_iommu(dev, &bus, &devfn);
2601 if (!iommu)
2602 return NULL;
2603
2604 req_id = ((u16)bus << 8) | devfn;
2605
2606 if (dev_is_pci(dev)) {
2607 struct pci_dev *pdev = to_pci_dev(dev);
2608
2609 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2610
2611 /* register PCI DMA alias device */
2612 if (req_id != dma_alias) {
2613 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2614 dma_alias & 0xff, NULL, domain);
2615
2616 if (!tmp || tmp != domain)
2617 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002618 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002619 }
2620
Joerg Roedel5db31562015-07-22 12:40:43 +02002621 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002622 if (!tmp || tmp != domain)
2623 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002624
Joerg Roedel76208352016-08-25 14:25:12 +02002625 return domain;
2626}
2627
2628static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2629{
2630 struct dmar_domain *domain, *tmp;
2631
2632 domain = find_domain(dev);
2633 if (domain)
2634 goto out;
2635
2636 domain = find_or_alloc_domain(dev, gaw);
2637 if (!domain)
2638 goto out;
2639
2640 tmp = set_domain_for_dev(dev, domain);
2641 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002642 domain_exit(domain);
2643 domain = tmp;
2644 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002645
Joerg Roedel76208352016-08-25 14:25:12 +02002646out:
2647
David Woodhouseb718cd32014-03-09 13:11:33 -07002648 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002649}
2650
David Woodhouseb2132032009-06-26 18:50:28 +01002651static int iommu_domain_identity_map(struct dmar_domain *domain,
2652 unsigned long long start,
2653 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002654{
David Woodhousec5395d52009-06-28 16:35:56 +01002655 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2656 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002657
David Woodhousec5395d52009-06-28 16:35:56 +01002658 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2659 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002660 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002661 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002662 }
2663
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002664 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002665 /*
2666 * RMRR range might have overlap with physical memory range,
2667 * clear it first
2668 */
David Woodhousec5395d52009-06-28 16:35:56 +01002669 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002670
Peter Xu87684fd2018-05-04 10:34:53 +08002671 return __domain_mapping(domain, first_vpfn, NULL,
2672 first_vpfn, last_vpfn - first_vpfn + 1,
2673 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002674}
2675
Joerg Roedeld66ce542015-09-23 19:00:10 +02002676static int domain_prepare_identity_map(struct device *dev,
2677 struct dmar_domain *domain,
2678 unsigned long long start,
2679 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002680{
David Woodhouse19943b02009-08-04 16:19:20 +01002681 /* For _hardware_ passthrough, don't bother. But for software
2682 passthrough, we do it anyway -- it may indicate a memory
2683 range which is reserved in E820, so which didn't get set
2684 up to start with in si_domain */
2685 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002686 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2687 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002688 return 0;
2689 }
2690
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002691 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2692 dev_name(dev), start, end);
2693
David Woodhouse5595b522009-12-02 09:21:55 +00002694 if (end < start) {
2695 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2696 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2697 dmi_get_system_info(DMI_BIOS_VENDOR),
2698 dmi_get_system_info(DMI_BIOS_VERSION),
2699 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002700 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002701 }
2702
David Woodhouse2ff729f2009-08-26 14:25:41 +01002703 if (end >> agaw_to_width(domain->agaw)) {
2704 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2705 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2706 agaw_to_width(domain->agaw),
2707 dmi_get_system_info(DMI_BIOS_VENDOR),
2708 dmi_get_system_info(DMI_BIOS_VERSION),
2709 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002710 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002711 }
David Woodhouse19943b02009-08-04 16:19:20 +01002712
Joerg Roedeld66ce542015-09-23 19:00:10 +02002713 return iommu_domain_identity_map(domain, start, end);
2714}
2715
2716static int iommu_prepare_identity_map(struct device *dev,
2717 unsigned long long start,
2718 unsigned long long end)
2719{
2720 struct dmar_domain *domain;
2721 int ret;
2722
2723 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2724 if (!domain)
2725 return -ENOMEM;
2726
2727 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002728 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002729 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002730
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002731 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002732}
2733
2734static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002735 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002736{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002737 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002738 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002739 return iommu_prepare_identity_map(dev, rmrr->base_address,
2740 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002741}
2742
Suresh Siddhad3f13812011-08-23 17:05:25 -07002743#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002744static inline void iommu_prepare_isa(void)
2745{
2746 struct pci_dev *pdev;
2747 int ret;
2748
2749 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2750 if (!pdev)
2751 return;
2752
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002753 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002754 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002755
2756 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002757 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002758
Yijing Wang9b27e822014-05-20 20:37:52 +08002759 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002760}
2761#else
2762static inline void iommu_prepare_isa(void)
2763{
2764 return;
2765}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002766#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002767
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002768static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002769
Matt Kraai071e1372009-08-23 22:30:22 -07002770static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002771{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002772 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002773
Jiang Liuab8dfe22014-07-11 14:19:27 +08002774 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002775 if (!si_domain)
2776 return -EFAULT;
2777
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002778 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2779 domain_exit(si_domain);
2780 return -EFAULT;
2781 }
2782
Joerg Roedel0dc79712015-07-21 15:40:06 +02002783 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002784
David Woodhouse19943b02009-08-04 16:19:20 +01002785 if (hw)
2786 return 0;
2787
David Woodhousec7ab48d2009-06-26 19:10:36 +01002788 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002789 unsigned long start_pfn, end_pfn;
2790 int i;
2791
2792 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2793 ret = iommu_domain_identity_map(si_domain,
2794 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2795 if (ret)
2796 return ret;
2797 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002798 }
2799
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002800 return 0;
2801}
2802
David Woodhouse9b226622014-03-09 14:03:28 -07002803static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002804{
2805 struct device_domain_info *info;
2806
2807 if (likely(!iommu_identity_mapping))
2808 return 0;
2809
David Woodhouse9b226622014-03-09 14:03:28 -07002810 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002811 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2812 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002813
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002814 return 0;
2815}
2816
Joerg Roedel28ccce02015-07-21 14:45:31 +02002817static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002818{
David Woodhouse0ac72662014-03-09 13:19:22 -07002819 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002820 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002821 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002822
David Woodhouse5913c9b2014-03-09 16:27:31 -07002823 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002824 if (!iommu)
2825 return -ENODEV;
2826
Joerg Roedel5db31562015-07-22 12:40:43 +02002827 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002828 if (ndomain != domain)
2829 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002830
2831 return 0;
2832}
2833
David Woodhouse0b9d9752014-03-09 15:48:15 -07002834static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002835{
2836 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002837 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002838 int i;
2839
Jiang Liu0e242612014-02-19 14:07:34 +08002840 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002841 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002842 /*
2843 * Return TRUE if this RMRR contains the device that
2844 * is passed in.
2845 */
2846 for_each_active_dev_scope(rmrr->devices,
2847 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002848 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002849 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002850 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002851 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002852 }
Jiang Liu0e242612014-02-19 14:07:34 +08002853 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002854 return false;
2855}
2856
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002857/*
2858 * There are a couple cases where we need to restrict the functionality of
2859 * devices associated with RMRRs. The first is when evaluating a device for
2860 * identity mapping because problems exist when devices are moved in and out
2861 * of domains and their respective RMRR information is lost. This means that
2862 * a device with associated RMRRs will never be in a "passthrough" domain.
2863 * The second is use of the device through the IOMMU API. This interface
2864 * expects to have full control of the IOVA space for the device. We cannot
2865 * satisfy both the requirement that RMRR access is maintained and have an
2866 * unencumbered IOVA space. We also have no ability to quiesce the device's
2867 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2868 * We therefore prevent devices associated with an RMRR from participating in
2869 * the IOMMU API, which eliminates them from device assignment.
2870 *
2871 * In both cases we assume that PCI USB devices with RMRRs have them largely
2872 * for historical reasons and that the RMRR space is not actively used post
2873 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002874 *
2875 * The same exception is made for graphics devices, with the requirement that
2876 * any use of the RMRR regions will be torn down before assigning the device
2877 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002878 */
2879static bool device_is_rmrr_locked(struct device *dev)
2880{
2881 if (!device_has_rmrr(dev))
2882 return false;
2883
2884 if (dev_is_pci(dev)) {
2885 struct pci_dev *pdev = to_pci_dev(dev);
2886
David Woodhouse18436af2015-03-25 15:05:47 +00002887 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002888 return false;
2889 }
2890
2891 return true;
2892}
2893
David Woodhouse3bdb2592014-03-09 16:03:08 -07002894static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002895{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002896
David Woodhouse3bdb2592014-03-09 16:03:08 -07002897 if (dev_is_pci(dev)) {
2898 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002899
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002900 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002901 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002902
David Woodhouse3bdb2592014-03-09 16:03:08 -07002903 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2904 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002905
David Woodhouse3bdb2592014-03-09 16:03:08 -07002906 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2907 return 1;
2908
2909 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2910 return 0;
2911
2912 /*
2913 * We want to start off with all devices in the 1:1 domain, and
2914 * take them out later if we find they can't access all of memory.
2915 *
2916 * However, we can't do this for PCI devices behind bridges,
2917 * because all PCI devices behind the same bridge will end up
2918 * with the same source-id on their transactions.
2919 *
2920 * Practically speaking, we can't change things around for these
2921 * devices at run-time, because we can't be sure there'll be no
2922 * DMA transactions in flight for any of their siblings.
2923 *
2924 * So PCI devices (unless they're on the root bus) as well as
2925 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2926 * the 1:1 domain, just in _case_ one of their siblings turns out
2927 * not to be able to map all of memory.
2928 */
2929 if (!pci_is_pcie(pdev)) {
2930 if (!pci_is_root_bus(pdev->bus))
2931 return 0;
2932 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2933 return 0;
2934 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2935 return 0;
2936 } else {
2937 if (device_has_rmrr(dev))
2938 return 0;
2939 }
David Woodhouse6941af22009-07-04 18:24:27 +01002940
David Woodhouse3dfc8132009-07-04 19:11:08 +01002941 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002942 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002943 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002944 * take them out of the 1:1 domain later.
2945 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002946 if (!startup) {
2947 /*
2948 * If the device's dma_mask is less than the system's memory
2949 * size then this is not a candidate for identity mapping.
2950 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002951 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002952
David Woodhouse3bdb2592014-03-09 16:03:08 -07002953 if (dev->coherent_dma_mask &&
2954 dev->coherent_dma_mask < dma_mask)
2955 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002956
David Woodhouse3bdb2592014-03-09 16:03:08 -07002957 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002958 }
David Woodhouse6941af22009-07-04 18:24:27 +01002959
2960 return 1;
2961}
2962
David Woodhousecf04eee2014-03-21 16:49:04 +00002963static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2964{
2965 int ret;
2966
2967 if (!iommu_should_identity_map(dev, 1))
2968 return 0;
2969
Joerg Roedel28ccce02015-07-21 14:45:31 +02002970 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002971 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002972 pr_info("%s identity mapping for device %s\n",
2973 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002974 else if (ret == -ENODEV)
2975 /* device not associated with an iommu */
2976 ret = 0;
2977
2978 return ret;
2979}
2980
2981
Matt Kraai071e1372009-08-23 22:30:22 -07002982static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002983{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002984 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002985 struct dmar_drhd_unit *drhd;
2986 struct intel_iommu *iommu;
2987 struct device *dev;
2988 int i;
2989 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002990
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002991 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002992 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2993 if (ret)
2994 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002995 }
2996
David Woodhousecf04eee2014-03-21 16:49:04 +00002997 for_each_active_iommu(iommu, drhd)
2998 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2999 struct acpi_device_physical_node *pn;
3000 struct acpi_device *adev;
3001
3002 if (dev->bus != &acpi_bus_type)
3003 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003004
David Woodhousecf04eee2014-03-21 16:49:04 +00003005 adev= to_acpi_device(dev);
3006 mutex_lock(&adev->physical_node_lock);
3007 list_for_each_entry(pn, &adev->physical_node_list, node) {
3008 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
3009 if (ret)
3010 break;
3011 }
3012 mutex_unlock(&adev->physical_node_lock);
3013 if (ret)
3014 return ret;
3015 }
3016
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003017 return 0;
3018}
3019
Jiang Liuffebeb42014-11-09 22:48:02 +08003020static void intel_iommu_init_qi(struct intel_iommu *iommu)
3021{
3022 /*
3023 * Start from the sane iommu hardware state.
3024 * If the queued invalidation is already initialized by us
3025 * (for example, while enabling interrupt-remapping) then
3026 * we got the things already rolling from a sane state.
3027 */
3028 if (!iommu->qi) {
3029 /*
3030 * Clear any previous faults.
3031 */
3032 dmar_fault(-1, iommu);
3033 /*
3034 * Disable queued invalidation if supported and already enabled
3035 * before OS handover.
3036 */
3037 dmar_disable_qi(iommu);
3038 }
3039
3040 if (dmar_enable_qi(iommu)) {
3041 /*
3042 * Queued Invalidate not enabled, use Register Based Invalidate
3043 */
3044 iommu->flush.flush_context = __iommu_flush_context;
3045 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003046 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003047 iommu->name);
3048 } else {
3049 iommu->flush.flush_context = qi_flush_context;
3050 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003051 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003052 }
3053}
3054
Joerg Roedel091d42e2015-06-12 11:56:10 +02003055static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003056 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003057 struct context_entry **tbl,
3058 int bus, bool ext)
3059{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003060 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003061 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003062 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003063 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003064 phys_addr_t old_ce_phys;
3065
3066 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003067 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003068
3069 for (devfn = 0; devfn < 256; devfn++) {
3070 /* First calculate the correct index */
3071 idx = (ext ? devfn * 2 : devfn) % 256;
3072
3073 if (idx == 0) {
3074 /* First save what we may have and clean up */
3075 if (new_ce) {
3076 tbl[tbl_idx] = new_ce;
3077 __iommu_flush_cache(iommu, new_ce,
3078 VTD_PAGE_SIZE);
3079 pos = 1;
3080 }
3081
3082 if (old_ce)
3083 iounmap(old_ce);
3084
3085 ret = 0;
3086 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003087 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003088 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003089 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003090
3091 if (!old_ce_phys) {
3092 if (ext && devfn == 0) {
3093 /* No LCTP, try UCTP */
3094 devfn = 0x7f;
3095 continue;
3096 } else {
3097 goto out;
3098 }
3099 }
3100
3101 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003102 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3103 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003104 if (!old_ce)
3105 goto out;
3106
3107 new_ce = alloc_pgtable_page(iommu->node);
3108 if (!new_ce)
3109 goto out_unmap;
3110
3111 ret = 0;
3112 }
3113
3114 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003115 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003116
Joerg Roedelcf484d02015-06-12 12:21:46 +02003117 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003118 continue;
3119
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003120 did = context_domain_id(&ce);
3121 if (did >= 0 && did < cap_ndoms(iommu->cap))
3122 set_bit(did, iommu->domain_ids);
3123
Joerg Roedelcf484d02015-06-12 12:21:46 +02003124 /*
3125 * We need a marker for copied context entries. This
3126 * marker needs to work for the old format as well as
3127 * for extended context entries.
3128 *
3129 * Bit 67 of the context entry is used. In the old
3130 * format this bit is available to software, in the
3131 * extended format it is the PGE bit, but PGE is ignored
3132 * by HW if PASIDs are disabled (and thus still
3133 * available).
3134 *
3135 * So disable PASIDs first and then mark the entry
3136 * copied. This means that we don't copy PASID
3137 * translations from the old kernel, but this is fine as
3138 * faults there are not fatal.
3139 */
3140 context_clear_pasid_enable(&ce);
3141 context_set_copied(&ce);
3142
Joerg Roedel091d42e2015-06-12 11:56:10 +02003143 new_ce[idx] = ce;
3144 }
3145
3146 tbl[tbl_idx + pos] = new_ce;
3147
3148 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3149
3150out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003151 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003152
3153out:
3154 return ret;
3155}
3156
3157static int copy_translation_tables(struct intel_iommu *iommu)
3158{
3159 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003160 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003161 phys_addr_t old_rt_phys;
3162 int ctxt_table_entries;
3163 unsigned long flags;
3164 u64 rtaddr_reg;
3165 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003166 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003167
3168 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3169 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003170 new_ext = !!ecap_ecs(iommu->ecap);
3171
3172 /*
3173 * The RTT bit can only be changed when translation is disabled,
3174 * but disabling translation means to open a window for data
3175 * corruption. So bail out and don't copy anything if we would
3176 * have to change the bit.
3177 */
3178 if (new_ext != ext)
3179 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003180
3181 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3182 if (!old_rt_phys)
3183 return -EINVAL;
3184
Dan Williamsdfddb9692015-10-09 18:16:46 -04003185 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003186 if (!old_rt)
3187 return -ENOMEM;
3188
3189 /* This is too big for the stack - allocate it from slab */
3190 ctxt_table_entries = ext ? 512 : 256;
3191 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003192 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003193 if (!ctxt_tbls)
3194 goto out_unmap;
3195
3196 for (bus = 0; bus < 256; bus++) {
3197 ret = copy_context_table(iommu, &old_rt[bus],
3198 ctxt_tbls, bus, ext);
3199 if (ret) {
3200 pr_err("%s: Failed to copy context table for bus %d\n",
3201 iommu->name, bus);
3202 continue;
3203 }
3204 }
3205
3206 spin_lock_irqsave(&iommu->lock, flags);
3207
3208 /* Context tables are copied, now write them to the root_entry table */
3209 for (bus = 0; bus < 256; bus++) {
3210 int idx = ext ? bus * 2 : bus;
3211 u64 val;
3212
3213 if (ctxt_tbls[idx]) {
3214 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3215 iommu->root_entry[bus].lo = val;
3216 }
3217
3218 if (!ext || !ctxt_tbls[idx + 1])
3219 continue;
3220
3221 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3222 iommu->root_entry[bus].hi = val;
3223 }
3224
3225 spin_unlock_irqrestore(&iommu->lock, flags);
3226
3227 kfree(ctxt_tbls);
3228
3229 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3230
3231 ret = 0;
3232
3233out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003234 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003235
3236 return ret;
3237}
3238
Joseph Cihulab7792602011-05-03 00:08:37 -07003239static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003240{
3241 struct dmar_drhd_unit *drhd;
3242 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003243 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003244 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003245 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003246 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003247
3248 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003249 * for each drhd
3250 * allocate root
3251 * initialize and program root entry to not present
3252 * endfor
3253 */
3254 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003255 /*
3256 * lock not needed as this is only incremented in the single
3257 * threaded kernel __init code path all other access are read
3258 * only
3259 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003260 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003261 g_num_of_iommus++;
3262 continue;
3263 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003264 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003265 }
3266
Jiang Liuffebeb42014-11-09 22:48:02 +08003267 /* Preallocate enough resources for IOMMU hot-addition */
3268 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3269 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3270
Weidong Hand9630fe2008-12-08 11:06:32 +08003271 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3272 GFP_KERNEL);
3273 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003274 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003275 ret = -ENOMEM;
3276 goto error;
3277 }
3278
Jiang Liu7c919772014-01-06 14:18:18 +08003279 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003280 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003281
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003282 intel_iommu_init_qi(iommu);
3283
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003284 ret = iommu_init_domains(iommu);
3285 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003286 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003287
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003288 init_translation_status(iommu);
3289
Joerg Roedel091d42e2015-06-12 11:56:10 +02003290 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3291 iommu_disable_translation(iommu);
3292 clear_translation_pre_enabled(iommu);
3293 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3294 iommu->name);
3295 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003296
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003297 /*
3298 * TBD:
3299 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003300 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003301 */
3302 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003303 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003304 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003305
Joerg Roedel091d42e2015-06-12 11:56:10 +02003306 if (translation_pre_enabled(iommu)) {
3307 pr_info("Translation already enabled - trying to copy translation structures\n");
3308
3309 ret = copy_translation_tables(iommu);
3310 if (ret) {
3311 /*
3312 * We found the IOMMU with translation
3313 * enabled - but failed to copy over the
3314 * old root-entry table. Try to proceed
3315 * by disabling translation now and
3316 * allocating a clean root-entry table.
3317 * This might cause DMAR faults, but
3318 * probably the dump will still succeed.
3319 */
3320 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3321 iommu->name);
3322 iommu_disable_translation(iommu);
3323 clear_translation_pre_enabled(iommu);
3324 } else {
3325 pr_info("Copied translation tables from previous kernel for %s\n",
3326 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003327 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003328 }
3329 }
3330
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003331 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003332 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003333#ifdef CONFIG_INTEL_IOMMU_SVM
3334 if (pasid_enabled(iommu))
3335 intel_svm_alloc_pasid_tables(iommu);
3336#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003337 }
3338
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003339 /*
3340 * Now that qi is enabled on all iommus, set the root entry and flush
3341 * caches. This is required on some Intel X58 chipsets, otherwise the
3342 * flush_context function will loop forever and the boot hangs.
3343 */
3344 for_each_active_iommu(iommu, drhd) {
3345 iommu_flush_write_buffer(iommu);
3346 iommu_set_root_entry(iommu);
3347 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3348 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3349 }
3350
David Woodhouse19943b02009-08-04 16:19:20 +01003351 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003352 iommu_identity_mapping |= IDENTMAP_ALL;
3353
Suresh Siddhad3f13812011-08-23 17:05:25 -07003354#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003355 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003356#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003357
Ashok Raj21e722c2017-01-30 09:39:53 -08003358 check_tylersburg_isoch();
3359
Joerg Roedel86080cc2015-06-12 12:27:16 +02003360 if (iommu_identity_mapping) {
3361 ret = si_domain_init(hw_pass_through);
3362 if (ret)
3363 goto free_iommu;
3364 }
3365
David Woodhousee0fc7e02009-09-30 09:12:17 -07003366
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003367 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003368 * If we copied translations from a previous kernel in the kdump
3369 * case, we can not assign the devices to domains now, as that
3370 * would eliminate the old mappings. So skip this part and defer
3371 * the assignment to device driver initialization time.
3372 */
3373 if (copied_tables)
3374 goto domains_done;
3375
3376 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003377 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003378 * identity mappings for rmrr, gfx, and isa and may fall back to static
3379 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003380 */
David Woodhouse19943b02009-08-04 16:19:20 +01003381 if (iommu_identity_mapping) {
3382 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3383 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003384 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003385 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003386 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003387 }
David Woodhouse19943b02009-08-04 16:19:20 +01003388 /*
3389 * For each rmrr
3390 * for each dev attached to rmrr
3391 * do
3392 * locate drhd for dev, alloc domain for dev
3393 * allocate free domain
3394 * allocate page table entries for rmrr
3395 * if context not allocated for bus
3396 * allocate and init context
3397 * set present in root table for this bus
3398 * init context with domain, translation etc
3399 * endfor
3400 * endfor
3401 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003402 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003403 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003404 /* some BIOS lists non-exist devices in DMAR table. */
3405 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003406 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003407 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003408 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003409 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003410 }
3411 }
3412
3413 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003414
Joerg Roedela87f4912015-06-12 12:32:54 +02003415domains_done:
3416
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003417 /*
3418 * for each drhd
3419 * enable fault log
3420 * global invalidate context cache
3421 * global invalidate iotlb
3422 * enable translation
3423 */
Jiang Liu7c919772014-01-06 14:18:18 +08003424 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003425 if (drhd->ignored) {
3426 /*
3427 * we always have to disable PMRs or DMA may fail on
3428 * this device
3429 */
3430 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003431 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003432 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003433 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003434
3435 iommu_flush_write_buffer(iommu);
3436
David Woodhousea222a7f2015-10-07 23:35:18 +01003437#ifdef CONFIG_INTEL_IOMMU_SVM
3438 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3439 ret = intel_svm_enable_prq(iommu);
3440 if (ret)
3441 goto free_iommu;
3442 }
3443#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003444 ret = dmar_set_interrupt(iommu);
3445 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003446 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003447
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003448 if (!translation_pre_enabled(iommu))
3449 iommu_enable_translation(iommu);
3450
David Woodhouseb94996c2009-09-19 15:28:12 -07003451 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003452 }
3453
3454 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003455
3456free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003457 for_each_active_iommu(iommu, drhd) {
3458 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003459 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003460 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003461
Weidong Hand9630fe2008-12-08 11:06:32 +08003462 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003463
Jiang Liu989d51f2014-02-19 14:07:21 +08003464error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003465 return ret;
3466}
3467
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003468/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003469static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003470 struct dmar_domain *domain,
3471 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003472{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003473 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003474
David Woodhouse875764d2009-06-28 21:20:51 +01003475 /* Restrict dma_mask to the width that the iommu can handle */
3476 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003477 /* Ensure we reserve the whole size-aligned region */
3478 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003479
3480 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003481 /*
3482 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003483 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003484 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003485 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003486 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003487 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003488 if (iova_pfn)
3489 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003490 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003491 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3492 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003493 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003494 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003495 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003496 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003497 }
3498
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003499 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003500}
3501
Peter Xub316d022017-05-22 18:28:51 +08003502static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003503{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003504 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003505 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003506 struct device *i_dev;
3507 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003508
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003509 domain = find_domain(dev);
3510 if (domain)
3511 goto out;
3512
3513 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3514 if (!domain)
3515 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003516
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003517 /* We have a new domain - setup possible RMRRs for the device */
3518 rcu_read_lock();
3519 for_each_rmrr_units(rmrr) {
3520 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3521 i, i_dev) {
3522 if (i_dev != dev)
3523 continue;
3524
3525 ret = domain_prepare_identity_map(dev, domain,
3526 rmrr->base_address,
3527 rmrr->end_address);
3528 if (ret)
3529 dev_err(dev, "Mapping reserved region failed\n");
3530 }
3531 }
3532 rcu_read_unlock();
3533
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003534 tmp = set_domain_for_dev(dev, domain);
3535 if (!tmp || domain != tmp) {
3536 domain_exit(domain);
3537 domain = tmp;
3538 }
3539
3540out:
3541
3542 if (!domain)
3543 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3544
3545
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003546 return domain;
3547}
3548
David Woodhouseecb509e2014-03-09 16:29:55 -07003549/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003550static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003551{
3552 int found;
3553
David Woodhouse3d891942014-03-06 15:59:26 +00003554 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003555 return 1;
3556
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003557 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003558 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003559
David Woodhouse9b226622014-03-09 14:03:28 -07003560 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003561 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003562 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003563 return 1;
3564 else {
3565 /*
3566 * 32 bit DMA is removed from si_domain and fall back
3567 * to non-identity mapping.
3568 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003569 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003570 pr_info("32bit %s uses non-identity mapping\n",
3571 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003572 return 0;
3573 }
3574 } else {
3575 /*
3576 * In case of a detached 64 bit DMA device from vm, the device
3577 * is put into si_domain for identity mapping.
3578 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003579 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003580 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003581 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003582 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003583 pr_info("64bit %s uses identity mapping\n",
3584 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003585 return 1;
3586 }
3587 }
3588 }
3589
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003590 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003591}
3592
David Woodhouse5040a912014-03-09 16:14:00 -07003593static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003594 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003595{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003596 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003597 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003598 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003599 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003600 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003601 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003602 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003603
3604 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003605
David Woodhouse5040a912014-03-09 16:14:00 -07003606 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003607 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003608
David Woodhouse5040a912014-03-09 16:14:00 -07003609 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003610 if (!domain)
3611 return 0;
3612
Weidong Han8c11e792008-12-08 15:29:22 +08003613 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003614 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003615
Omer Peleg2aac6302016-04-20 11:33:57 +03003616 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3617 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003618 goto error;
3619
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003620 /*
3621 * Check if DMAR supports zero-length reads on write only
3622 * mappings..
3623 */
3624 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003625 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003626 prot |= DMA_PTE_READ;
3627 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3628 prot |= DMA_PTE_WRITE;
3629 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003630 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003631 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003632 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003633 * is not a big problem
3634 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003635 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003636 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003637 if (ret)
3638 goto error;
3639
Omer Peleg2aac6302016-04-20 11:33:57 +03003640 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003641 start_paddr += paddr & ~PAGE_MASK;
3642 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003643
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003644error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003645 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003646 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003647 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003648 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003649 return 0;
3650}
3651
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003652static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3653 unsigned long offset, size_t size,
3654 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003655 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003656{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003657 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003658 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003659}
3660
Omer Peleg769530e2016-04-20 11:33:25 +03003661static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003662{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003663 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003664 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003665 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003666 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003667 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003668 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003669
David Woodhouse73676832009-07-04 14:08:36 +01003670 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003671 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003672
David Woodhouse1525a292014-03-06 16:19:30 +00003673 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003674 BUG_ON(!domain);
3675
Weidong Han8c11e792008-12-08 15:29:22 +08003676 iommu = domain_get_iommu(domain);
3677
Omer Peleg2aac6302016-04-20 11:33:57 +03003678 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003679
Omer Peleg769530e2016-04-20 11:33:25 +03003680 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003681 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003682 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003683
David Woodhoused794dc92009-06-28 00:27:49 +01003684 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003685 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003686
David Woodhouseea8ea462014-03-05 17:09:32 +00003687 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003688
mark gross5e0d2a62008-03-04 15:22:08 -08003689 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003690 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003691 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003692 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003693 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003694 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003695 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003696 queue_iova(&domain->iovad, iova_pfn, nrpages,
3697 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003698 /*
3699 * queue up the release of the unmap to save the 1/6th of the
3700 * cpu used up by the iotlb flush operation...
3701 */
mark gross5e0d2a62008-03-04 15:22:08 -08003702 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003703}
3704
Jiang Liud41a4ad2014-07-11 14:19:34 +08003705static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3706 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003707 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003708{
Omer Peleg769530e2016-04-20 11:33:25 +03003709 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003710}
3711
David Woodhouse5040a912014-03-09 16:14:00 -07003712static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003713 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003714 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003715{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003716 void *vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003717
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003718 vaddr = dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3719 if (iommu_no_mapping(dev) || !vaddr)
3720 return vaddr;
Alex Williamsone8bb9102009-11-04 15:59:34 -07003721
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003722 *dma_handle = __intel_map_single(dev, virt_to_phys(vaddr),
3723 PAGE_ALIGN(size), DMA_BIDIRECTIONAL,
3724 dev->coherent_dma_mask);
3725 if (!*dma_handle)
3726 goto out_free_pages;
3727 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003728
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003729out_free_pages:
3730 dma_direct_free(dev, size, vaddr, *dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003731 return NULL;
3732}
3733
David Woodhouse5040a912014-03-09 16:14:00 -07003734static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003735 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003736{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003737 if (!iommu_no_mapping(dev))
3738 intel_unmap(dev, dma_handle, PAGE_ALIGN(size));
3739 dma_direct_free(dev, size, vaddr, dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003740}
3741
David Woodhouse5040a912014-03-09 16:14:00 -07003742static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003743 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003744 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003745{
Omer Peleg769530e2016-04-20 11:33:25 +03003746 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3747 unsigned long nrpages = 0;
3748 struct scatterlist *sg;
3749 int i;
3750
3751 for_each_sg(sglist, sg, nelems, i) {
3752 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3753 }
3754
3755 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003756}
3757
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003758static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003759 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760{
3761 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003762 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003763
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003764 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003765 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003766 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003767 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003768 }
3769 return nelems;
3770}
3771
David Woodhouse5040a912014-03-09 16:14:00 -07003772static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003773 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003774{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003775 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003776 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003777 size_t size = 0;
3778 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003779 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003780 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003781 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003782 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003783 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003784
3785 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003786 if (iommu_no_mapping(dev))
3787 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003788
David Woodhouse5040a912014-03-09 16:14:00 -07003789 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003790 if (!domain)
3791 return 0;
3792
Weidong Han8c11e792008-12-08 15:29:22 +08003793 iommu = domain_get_iommu(domain);
3794
David Woodhouseb536d242009-06-28 14:49:31 +01003795 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003796 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003797
Omer Peleg2aac6302016-04-20 11:33:57 +03003798 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003799 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003800 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003801 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003802 return 0;
3803 }
3804
3805 /*
3806 * Check if DMAR supports zero-length reads on write only
3807 * mappings..
3808 */
3809 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003810 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003811 prot |= DMA_PTE_READ;
3812 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3813 prot |= DMA_PTE_WRITE;
3814
Omer Peleg2aac6302016-04-20 11:33:57 +03003815 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003816
Fenghua Yuf5329592009-08-04 15:09:37 -07003817 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003818 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003819 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003820 start_vpfn + size - 1,
3821 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003822 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003823 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003824 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003825
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003826 return nelems;
3827}
3828
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003829static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3830{
3831 return !dma_addr;
3832}
3833
Arvind Yadav01e19322017-06-28 16:39:32 +05303834const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003835 .alloc = intel_alloc_coherent,
3836 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003837 .map_sg = intel_map_sg,
3838 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003839 .map_page = intel_map_page,
3840 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003841 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003842#ifdef CONFIG_X86
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003843 .dma_supported = dma_direct_supported,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003844#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003845};
3846
3847static inline int iommu_domain_cache_init(void)
3848{
3849 int ret = 0;
3850
3851 iommu_domain_cache = kmem_cache_create("iommu_domain",
3852 sizeof(struct dmar_domain),
3853 0,
3854 SLAB_HWCACHE_ALIGN,
3855
3856 NULL);
3857 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003858 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003859 ret = -ENOMEM;
3860 }
3861
3862 return ret;
3863}
3864
3865static inline int iommu_devinfo_cache_init(void)
3866{
3867 int ret = 0;
3868
3869 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3870 sizeof(struct device_domain_info),
3871 0,
3872 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003873 NULL);
3874 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003875 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003876 ret = -ENOMEM;
3877 }
3878
3879 return ret;
3880}
3881
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003882static int __init iommu_init_mempool(void)
3883{
3884 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003885 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003886 if (ret)
3887 return ret;
3888
3889 ret = iommu_domain_cache_init();
3890 if (ret)
3891 goto domain_error;
3892
3893 ret = iommu_devinfo_cache_init();
3894 if (!ret)
3895 return ret;
3896
3897 kmem_cache_destroy(iommu_domain_cache);
3898domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003899 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003900
3901 return -ENOMEM;
3902}
3903
3904static void __init iommu_exit_mempool(void)
3905{
3906 kmem_cache_destroy(iommu_devinfo_cache);
3907 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003908 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003909}
3910
Dan Williams556ab452010-07-23 15:47:56 -07003911static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3912{
3913 struct dmar_drhd_unit *drhd;
3914 u32 vtbar;
3915 int rc;
3916
3917 /* We know that this device on this chipset has its own IOMMU.
3918 * If we find it under a different IOMMU, then the BIOS is lying
3919 * to us. Hope that the IOMMU for this device is actually
3920 * disabled, and it needs no translation...
3921 */
3922 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3923 if (rc) {
3924 /* "can't" happen */
3925 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3926 return;
3927 }
3928 vtbar &= 0xffff0000;
3929
3930 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3931 drhd = dmar_find_matched_drhd_unit(pdev);
3932 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3933 TAINT_FIRMWARE_WORKAROUND,
3934 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3935 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3936}
3937DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3938
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003939static void __init init_no_remapping_devices(void)
3940{
3941 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003942 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003943 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003944
3945 for_each_drhd_unit(drhd) {
3946 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003947 for_each_active_dev_scope(drhd->devices,
3948 drhd->devices_cnt, i, dev)
3949 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003950 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003951 if (i == drhd->devices_cnt)
3952 drhd->ignored = 1;
3953 }
3954 }
3955
Jiang Liu7c919772014-01-06 14:18:18 +08003956 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003957 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003958 continue;
3959
Jiang Liub683b232014-02-19 14:07:32 +08003960 for_each_active_dev_scope(drhd->devices,
3961 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003962 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003963 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003964 if (i < drhd->devices_cnt)
3965 continue;
3966
David Woodhousec0771df2011-10-14 20:59:46 +01003967 /* This IOMMU has *only* gfx devices. Either bypass it or
3968 set the gfx_mapped flag, as appropriate */
3969 if (dmar_map_gfx) {
3970 intel_iommu_gfx_mapped = 1;
3971 } else {
3972 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08003973 for_each_active_dev_scope(drhd->devices,
3974 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003975 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003976 }
3977 }
3978}
3979
Fenghua Yuf59c7b62009-03-27 14:22:42 -07003980#ifdef CONFIG_SUSPEND
3981static int init_iommu_hw(void)
3982{
3983 struct dmar_drhd_unit *drhd;
3984 struct intel_iommu *iommu = NULL;
3985
3986 for_each_active_iommu(iommu, drhd)
3987 if (iommu->qi)
3988 dmar_reenable_qi(iommu);
3989
Joseph Cihulab7792602011-05-03 00:08:37 -07003990 for_each_iommu(iommu, drhd) {
3991 if (drhd->ignored) {
3992 /*
3993 * we always have to disable PMRs or DMA may fail on
3994 * this device
3995 */
3996 if (force_on)
3997 iommu_disable_protect_mem_regions(iommu);
3998 continue;
3999 }
4000
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004001 iommu_flush_write_buffer(iommu);
4002
4003 iommu_set_root_entry(iommu);
4004
4005 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004006 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004007 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4008 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004009 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004010 }
4011
4012 return 0;
4013}
4014
4015static void iommu_flush_all(void)
4016{
4017 struct dmar_drhd_unit *drhd;
4018 struct intel_iommu *iommu;
4019
4020 for_each_active_iommu(iommu, drhd) {
4021 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004022 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004023 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004024 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004025 }
4026}
4027
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004028static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004029{
4030 struct dmar_drhd_unit *drhd;
4031 struct intel_iommu *iommu = NULL;
4032 unsigned long flag;
4033
4034 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004035 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004036 GFP_ATOMIC);
4037 if (!iommu->iommu_state)
4038 goto nomem;
4039 }
4040
4041 iommu_flush_all();
4042
4043 for_each_active_iommu(iommu, drhd) {
4044 iommu_disable_translation(iommu);
4045
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004046 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004047
4048 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4049 readl(iommu->reg + DMAR_FECTL_REG);
4050 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4051 readl(iommu->reg + DMAR_FEDATA_REG);
4052 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4053 readl(iommu->reg + DMAR_FEADDR_REG);
4054 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4055 readl(iommu->reg + DMAR_FEUADDR_REG);
4056
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004057 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004058 }
4059 return 0;
4060
4061nomem:
4062 for_each_active_iommu(iommu, drhd)
4063 kfree(iommu->iommu_state);
4064
4065 return -ENOMEM;
4066}
4067
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004068static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004069{
4070 struct dmar_drhd_unit *drhd;
4071 struct intel_iommu *iommu = NULL;
4072 unsigned long flag;
4073
4074 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004075 if (force_on)
4076 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4077 else
4078 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004079 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004080 }
4081
4082 for_each_active_iommu(iommu, drhd) {
4083
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004084 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004085
4086 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4087 iommu->reg + DMAR_FECTL_REG);
4088 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4089 iommu->reg + DMAR_FEDATA_REG);
4090 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4091 iommu->reg + DMAR_FEADDR_REG);
4092 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4093 iommu->reg + DMAR_FEUADDR_REG);
4094
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004095 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004096 }
4097
4098 for_each_active_iommu(iommu, drhd)
4099 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004100}
4101
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004102static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004103 .resume = iommu_resume,
4104 .suspend = iommu_suspend,
4105};
4106
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004107static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004108{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004109 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004110}
4111
4112#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004113static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004114#endif /* CONFIG_PM */
4115
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004116
Jiang Liuc2a0b532014-11-09 22:47:56 +08004117int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004118{
4119 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004120 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004121 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004122 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004123
4124 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4125 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004126 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004127
4128 rmrru->hdr = header;
4129 rmrr = (struct acpi_dmar_reserved_memory *)header;
4130 rmrru->base_address = rmrr->base_address;
4131 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004132
4133 length = rmrr->end_address - rmrr->base_address + 1;
4134 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4135 IOMMU_RESV_DIRECT);
4136 if (!rmrru->resv)
4137 goto free_rmrru;
4138
Jiang Liu2e455282014-02-19 14:07:36 +08004139 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4140 ((void *)rmrr) + rmrr->header.length,
4141 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004142 if (rmrru->devices_cnt && rmrru->devices == NULL)
4143 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004144
Jiang Liu2e455282014-02-19 14:07:36 +08004145 list_add(&rmrru->list, &dmar_rmrr_units);
4146
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004147 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004148free_all:
4149 kfree(rmrru->resv);
4150free_rmrru:
4151 kfree(rmrru);
4152out:
4153 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004154}
4155
Jiang Liu6b197242014-11-09 22:47:58 +08004156static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4157{
4158 struct dmar_atsr_unit *atsru;
4159 struct acpi_dmar_atsr *tmp;
4160
4161 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4162 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4163 if (atsr->segment != tmp->segment)
4164 continue;
4165 if (atsr->header.length != tmp->header.length)
4166 continue;
4167 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4168 return atsru;
4169 }
4170
4171 return NULL;
4172}
4173
4174int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004175{
4176 struct acpi_dmar_atsr *atsr;
4177 struct dmar_atsr_unit *atsru;
4178
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004179 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004180 return 0;
4181
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004182 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004183 atsru = dmar_find_atsr(atsr);
4184 if (atsru)
4185 return 0;
4186
4187 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004188 if (!atsru)
4189 return -ENOMEM;
4190
Jiang Liu6b197242014-11-09 22:47:58 +08004191 /*
4192 * If memory is allocated from slab by ACPI _DSM method, we need to
4193 * copy the memory content because the memory buffer will be freed
4194 * on return.
4195 */
4196 atsru->hdr = (void *)(atsru + 1);
4197 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004198 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004199 if (!atsru->include_all) {
4200 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4201 (void *)atsr + atsr->header.length,
4202 &atsru->devices_cnt);
4203 if (atsru->devices_cnt && atsru->devices == NULL) {
4204 kfree(atsru);
4205 return -ENOMEM;
4206 }
4207 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004208
Jiang Liu0e242612014-02-19 14:07:34 +08004209 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004210
4211 return 0;
4212}
4213
Jiang Liu9bdc5312014-01-06 14:18:27 +08004214static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4215{
4216 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4217 kfree(atsru);
4218}
4219
Jiang Liu6b197242014-11-09 22:47:58 +08004220int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4221{
4222 struct acpi_dmar_atsr *atsr;
4223 struct dmar_atsr_unit *atsru;
4224
4225 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4226 atsru = dmar_find_atsr(atsr);
4227 if (atsru) {
4228 list_del_rcu(&atsru->list);
4229 synchronize_rcu();
4230 intel_iommu_free_atsr(atsru);
4231 }
4232
4233 return 0;
4234}
4235
4236int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4237{
4238 int i;
4239 struct device *dev;
4240 struct acpi_dmar_atsr *atsr;
4241 struct dmar_atsr_unit *atsru;
4242
4243 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4244 atsru = dmar_find_atsr(atsr);
4245 if (!atsru)
4246 return 0;
4247
Linus Torvalds194dc872016-07-27 20:03:31 -07004248 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004249 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4250 i, dev)
4251 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004252 }
Jiang Liu6b197242014-11-09 22:47:58 +08004253
4254 return 0;
4255}
4256
Jiang Liuffebeb42014-11-09 22:48:02 +08004257static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4258{
4259 int sp, ret = 0;
4260 struct intel_iommu *iommu = dmaru->iommu;
4261
4262 if (g_iommus[iommu->seq_id])
4263 return 0;
4264
4265 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004266 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004267 iommu->name);
4268 return -ENXIO;
4269 }
4270 if (!ecap_sc_support(iommu->ecap) &&
4271 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004272 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004273 iommu->name);
4274 return -ENXIO;
4275 }
4276 sp = domain_update_iommu_superpage(iommu) - 1;
4277 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004278 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004279 iommu->name);
4280 return -ENXIO;
4281 }
4282
4283 /*
4284 * Disable translation if already enabled prior to OS handover.
4285 */
4286 if (iommu->gcmd & DMA_GCMD_TE)
4287 iommu_disable_translation(iommu);
4288
4289 g_iommus[iommu->seq_id] = iommu;
4290 ret = iommu_init_domains(iommu);
4291 if (ret == 0)
4292 ret = iommu_alloc_root_entry(iommu);
4293 if (ret)
4294 goto out;
4295
David Woodhouse8a94ade2015-03-24 14:54:56 +00004296#ifdef CONFIG_INTEL_IOMMU_SVM
4297 if (pasid_enabled(iommu))
4298 intel_svm_alloc_pasid_tables(iommu);
4299#endif
4300
Jiang Liuffebeb42014-11-09 22:48:02 +08004301 if (dmaru->ignored) {
4302 /*
4303 * we always have to disable PMRs or DMA may fail on this device
4304 */
4305 if (force_on)
4306 iommu_disable_protect_mem_regions(iommu);
4307 return 0;
4308 }
4309
4310 intel_iommu_init_qi(iommu);
4311 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004312
4313#ifdef CONFIG_INTEL_IOMMU_SVM
4314 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4315 ret = intel_svm_enable_prq(iommu);
4316 if (ret)
4317 goto disable_iommu;
4318 }
4319#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004320 ret = dmar_set_interrupt(iommu);
4321 if (ret)
4322 goto disable_iommu;
4323
4324 iommu_set_root_entry(iommu);
4325 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4326 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4327 iommu_enable_translation(iommu);
4328
Jiang Liuffebeb42014-11-09 22:48:02 +08004329 iommu_disable_protect_mem_regions(iommu);
4330 return 0;
4331
4332disable_iommu:
4333 disable_dmar_iommu(iommu);
4334out:
4335 free_dmar_iommu(iommu);
4336 return ret;
4337}
4338
Jiang Liu6b197242014-11-09 22:47:58 +08004339int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4340{
Jiang Liuffebeb42014-11-09 22:48:02 +08004341 int ret = 0;
4342 struct intel_iommu *iommu = dmaru->iommu;
4343
4344 if (!intel_iommu_enabled)
4345 return 0;
4346 if (iommu == NULL)
4347 return -EINVAL;
4348
4349 if (insert) {
4350 ret = intel_iommu_add(dmaru);
4351 } else {
4352 disable_dmar_iommu(iommu);
4353 free_dmar_iommu(iommu);
4354 }
4355
4356 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004357}
4358
Jiang Liu9bdc5312014-01-06 14:18:27 +08004359static void intel_iommu_free_dmars(void)
4360{
4361 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4362 struct dmar_atsr_unit *atsru, *atsr_n;
4363
4364 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4365 list_del(&rmrru->list);
4366 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004367 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004368 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004369 }
4370
Jiang Liu9bdc5312014-01-06 14:18:27 +08004371 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4372 list_del(&atsru->list);
4373 intel_iommu_free_atsr(atsru);
4374 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004375}
4376
4377int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4378{
Jiang Liub683b232014-02-19 14:07:32 +08004379 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004380 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004381 struct pci_dev *bridge = NULL;
4382 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004383 struct acpi_dmar_atsr *atsr;
4384 struct dmar_atsr_unit *atsru;
4385
4386 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004387 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004388 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004389 /* If it's an integrated device, allow ATS */
4390 if (!bridge)
4391 return 1;
4392 /* Connected via non-PCIe: no ATS */
4393 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004394 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004395 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004396 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004397 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004398 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004399 }
4400
Jiang Liu0e242612014-02-19 14:07:34 +08004401 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004402 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4403 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4404 if (atsr->segment != pci_domain_nr(dev->bus))
4405 continue;
4406
Jiang Liub683b232014-02-19 14:07:32 +08004407 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004408 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004409 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004410
4411 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004412 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004413 }
Jiang Liub683b232014-02-19 14:07:32 +08004414 ret = 0;
4415out:
Jiang Liu0e242612014-02-19 14:07:34 +08004416 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004417
Jiang Liub683b232014-02-19 14:07:32 +08004418 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004419}
4420
Jiang Liu59ce0512014-02-19 14:07:35 +08004421int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4422{
4423 int ret = 0;
4424 struct dmar_rmrr_unit *rmrru;
4425 struct dmar_atsr_unit *atsru;
4426 struct acpi_dmar_atsr *atsr;
4427 struct acpi_dmar_reserved_memory *rmrr;
4428
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004429 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004430 return 0;
4431
4432 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4433 rmrr = container_of(rmrru->hdr,
4434 struct acpi_dmar_reserved_memory, header);
4435 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4436 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4437 ((void *)rmrr) + rmrr->header.length,
4438 rmrr->segment, rmrru->devices,
4439 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004440 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004441 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004442 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004443 dmar_remove_dev_scope(info, rmrr->segment,
4444 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004445 }
4446 }
4447
4448 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4449 if (atsru->include_all)
4450 continue;
4451
4452 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4453 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4454 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4455 (void *)atsr + atsr->header.length,
4456 atsr->segment, atsru->devices,
4457 atsru->devices_cnt);
4458 if (ret > 0)
4459 break;
4460 else if(ret < 0)
4461 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004462 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004463 if (dmar_remove_dev_scope(info, atsr->segment,
4464 atsru->devices, atsru->devices_cnt))
4465 break;
4466 }
4467 }
4468
4469 return 0;
4470}
4471
Fenghua Yu99dcade2009-11-11 07:23:06 -08004472/*
4473 * Here we only respond to action of unbound device from driver.
4474 *
4475 * Added device is not attached to its DMAR domain here yet. That will happen
4476 * when mapping the device to iova.
4477 */
4478static int device_notifier(struct notifier_block *nb,
4479 unsigned long action, void *data)
4480{
4481 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004482 struct dmar_domain *domain;
4483
David Woodhouse3d891942014-03-06 15:59:26 +00004484 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004485 return 0;
4486
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004487 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004488 return 0;
4489
David Woodhouse1525a292014-03-06 16:19:30 +00004490 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004491 if (!domain)
4492 return 0;
4493
Joerg Roedele6de0f82015-07-22 16:30:36 +02004494 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004495 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004496 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004497
Fenghua Yu99dcade2009-11-11 07:23:06 -08004498 return 0;
4499}
4500
4501static struct notifier_block device_nb = {
4502 .notifier_call = device_notifier,
4503};
4504
Jiang Liu75f05562014-02-19 14:07:37 +08004505static int intel_iommu_memory_notifier(struct notifier_block *nb,
4506 unsigned long val, void *v)
4507{
4508 struct memory_notify *mhp = v;
4509 unsigned long long start, end;
4510 unsigned long start_vpfn, last_vpfn;
4511
4512 switch (val) {
4513 case MEM_GOING_ONLINE:
4514 start = mhp->start_pfn << PAGE_SHIFT;
4515 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4516 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004517 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004518 start, end);
4519 return NOTIFY_BAD;
4520 }
4521 break;
4522
4523 case MEM_OFFLINE:
4524 case MEM_CANCEL_ONLINE:
4525 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4526 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4527 while (start_vpfn <= last_vpfn) {
4528 struct iova *iova;
4529 struct dmar_drhd_unit *drhd;
4530 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004531 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004532
4533 iova = find_iova(&si_domain->iovad, start_vpfn);
4534 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004535 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004536 start_vpfn);
4537 break;
4538 }
4539
4540 iova = split_and_remove_iova(&si_domain->iovad, iova,
4541 start_vpfn, last_vpfn);
4542 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004543 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004544 start_vpfn, last_vpfn);
4545 return NOTIFY_BAD;
4546 }
4547
David Woodhouseea8ea462014-03-05 17:09:32 +00004548 freelist = domain_unmap(si_domain, iova->pfn_lo,
4549 iova->pfn_hi);
4550
Jiang Liu75f05562014-02-19 14:07:37 +08004551 rcu_read_lock();
4552 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004553 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004554 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004555 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004556 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004557 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004558
4559 start_vpfn = iova->pfn_hi + 1;
4560 free_iova_mem(iova);
4561 }
4562 break;
4563 }
4564
4565 return NOTIFY_OK;
4566}
4567
4568static struct notifier_block intel_iommu_memory_nb = {
4569 .notifier_call = intel_iommu_memory_notifier,
4570 .priority = 0
4571};
4572
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004573static void free_all_cpu_cached_iovas(unsigned int cpu)
4574{
4575 int i;
4576
4577 for (i = 0; i < g_num_of_iommus; i++) {
4578 struct intel_iommu *iommu = g_iommus[i];
4579 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004580 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004581
4582 if (!iommu)
4583 continue;
4584
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004585 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004586 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004587
4588 if (!domain)
4589 continue;
4590 free_cpu_cached_iovas(cpu, &domain->iovad);
4591 }
4592 }
4593}
4594
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004595static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004596{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004597 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004598 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004599}
4600
Joerg Roedel161b28a2017-03-28 17:04:52 +02004601static void intel_disable_iommus(void)
4602{
4603 struct intel_iommu *iommu = NULL;
4604 struct dmar_drhd_unit *drhd;
4605
4606 for_each_iommu(iommu, drhd)
4607 iommu_disable_translation(iommu);
4608}
4609
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004610static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4611{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004612 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4613
4614 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004615}
4616
Alex Williamsona5459cf2014-06-12 16:12:31 -06004617static ssize_t intel_iommu_show_version(struct device *dev,
4618 struct device_attribute *attr,
4619 char *buf)
4620{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004621 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004622 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4623 return sprintf(buf, "%d:%d\n",
4624 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4625}
4626static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4627
4628static ssize_t intel_iommu_show_address(struct device *dev,
4629 struct device_attribute *attr,
4630 char *buf)
4631{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004632 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004633 return sprintf(buf, "%llx\n", iommu->reg_phys);
4634}
4635static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4636
4637static ssize_t intel_iommu_show_cap(struct device *dev,
4638 struct device_attribute *attr,
4639 char *buf)
4640{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004641 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004642 return sprintf(buf, "%llx\n", iommu->cap);
4643}
4644static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4645
4646static ssize_t intel_iommu_show_ecap(struct device *dev,
4647 struct device_attribute *attr,
4648 char *buf)
4649{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004650 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004651 return sprintf(buf, "%llx\n", iommu->ecap);
4652}
4653static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4654
Alex Williamson2238c082015-07-14 15:24:53 -06004655static ssize_t intel_iommu_show_ndoms(struct device *dev,
4656 struct device_attribute *attr,
4657 char *buf)
4658{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004659 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004660 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4661}
4662static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4663
4664static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4665 struct device_attribute *attr,
4666 char *buf)
4667{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004668 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004669 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4670 cap_ndoms(iommu->cap)));
4671}
4672static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4673
Alex Williamsona5459cf2014-06-12 16:12:31 -06004674static struct attribute *intel_iommu_attrs[] = {
4675 &dev_attr_version.attr,
4676 &dev_attr_address.attr,
4677 &dev_attr_cap.attr,
4678 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004679 &dev_attr_domains_supported.attr,
4680 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004681 NULL,
4682};
4683
4684static struct attribute_group intel_iommu_group = {
4685 .name = "intel-iommu",
4686 .attrs = intel_iommu_attrs,
4687};
4688
4689const struct attribute_group *intel_iommu_groups[] = {
4690 &intel_iommu_group,
4691 NULL,
4692};
4693
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004694int __init intel_iommu_init(void)
4695{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004696 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004697 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004698 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004699
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004700 /* VT-d is required for a TXT/tboot launch, so enforce that */
4701 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004702
Jiang Liu3a5670e2014-02-19 14:07:33 +08004703 if (iommu_init_mempool()) {
4704 if (force_on)
4705 panic("tboot: Failed to initialize iommu memory\n");
4706 return -ENOMEM;
4707 }
4708
4709 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004710 if (dmar_table_init()) {
4711 if (force_on)
4712 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004713 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004714 }
4715
Suresh Siddhac2c72862011-08-23 17:05:19 -07004716 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004717 if (force_on)
4718 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004719 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004720 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004721
Joerg Roedelec154bf2017-10-06 15:00:53 +02004722 up_write(&dmar_global_lock);
4723
4724 /*
4725 * The bus notifier takes the dmar_global_lock, so lockdep will
4726 * complain later when we register it under the lock.
4727 */
4728 dmar_register_bus_notifier();
4729
4730 down_write(&dmar_global_lock);
4731
Joerg Roedel161b28a2017-03-28 17:04:52 +02004732 if (no_iommu || dmar_disabled) {
4733 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004734 * We exit the function here to ensure IOMMU's remapping and
4735 * mempool aren't setup, which means that the IOMMU's PMRs
4736 * won't be disabled via the call to init_dmars(). So disable
4737 * it explicitly here. The PMRs were setup by tboot prior to
4738 * calling SENTER, but the kernel is expected to reset/tear
4739 * down the PMRs.
4740 */
4741 if (intel_iommu_tboot_noforce) {
4742 for_each_iommu(iommu, drhd)
4743 iommu_disable_protect_mem_regions(iommu);
4744 }
4745
4746 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004747 * Make sure the IOMMUs are switched off, even when we
4748 * boot into a kexec kernel and the previous kernel left
4749 * them enabled
4750 */
4751 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004752 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004753 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004754
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004755 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004756 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004757
4758 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004759 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004760
Joseph Cihula51a63e62011-03-21 11:04:24 -07004761 if (dmar_init_reserved_ranges()) {
4762 if (force_on)
4763 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004764 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004765 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004766
4767 init_no_remapping_devices();
4768
Joseph Cihulab7792602011-05-03 00:08:37 -07004769 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004770 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004771 if (force_on)
4772 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004773 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004774 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004775 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004776 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004777 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004778
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004779#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004780 swiotlb = 0;
4781#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004782 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004783
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004784 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004785
Joerg Roedel39ab9552017-02-01 16:56:46 +01004786 for_each_active_iommu(iommu, drhd) {
4787 iommu_device_sysfs_add(&iommu->iommu, NULL,
4788 intel_iommu_groups,
4789 "%s", iommu->name);
4790 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4791 iommu_device_register(&iommu->iommu);
4792 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004793
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004794 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004795 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004796 if (si_domain && !hw_pass_through)
4797 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004798 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4799 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004800 intel_iommu_enabled = 1;
4801
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004802 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004803
4804out_free_reserved_range:
4805 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004806out_free_dmar:
4807 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004808 up_write(&dmar_global_lock);
4809 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004810 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004811}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004812
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004813static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004814{
4815 struct intel_iommu *iommu = opaque;
4816
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004817 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004818 return 0;
4819}
4820
4821/*
4822 * NB - intel-iommu lacks any sort of reference counting for the users of
4823 * dependent devices. If multiple endpoints have intersecting dependent
4824 * devices, unbinding the driver from any one of them will possibly leave
4825 * the others unable to operate.
4826 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004827static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004828{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004829 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004830 return;
4831
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004832 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004833}
4834
Joerg Roedel127c7612015-07-23 17:44:46 +02004835static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004836{
Weidong Hanc7151a82008-12-08 22:51:37 +08004837 struct intel_iommu *iommu;
4838 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004839
Joerg Roedel55d94042015-07-22 16:50:40 +02004840 assert_spin_locked(&device_domain_lock);
4841
Joerg Roedelb608ac32015-07-21 18:19:08 +02004842 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004843 return;
4844
Joerg Roedel127c7612015-07-23 17:44:46 +02004845 iommu = info->iommu;
4846
4847 if (info->dev) {
4848 iommu_disable_dev_iotlb(info);
4849 domain_context_clear(iommu, info->dev);
4850 }
4851
Joerg Roedelb608ac32015-07-21 18:19:08 +02004852 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004853
Joerg Roedeld160aca2015-07-22 11:52:53 +02004854 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004855 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004856 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004857
4858 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004859}
4860
Joerg Roedel55d94042015-07-22 16:50:40 +02004861static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4862 struct device *dev)
4863{
Joerg Roedel127c7612015-07-23 17:44:46 +02004864 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004865 unsigned long flags;
4866
Weidong Hanc7151a82008-12-08 22:51:37 +08004867 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004868 info = dev->archdata.iommu;
4869 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004870 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004871}
4872
4873static int md_domain_init(struct dmar_domain *domain, int guest_width)
4874{
4875 int adjust_width;
4876
Zhen Leiaa3ac942017-09-21 16:52:45 +01004877 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004878 domain_reserve_special_ranges(domain);
4879
4880 /* calculate AGAW */
4881 domain->gaw = guest_width;
4882 adjust_width = guestwidth_to_adjustwidth(guest_width);
4883 domain->agaw = width_to_agaw(adjust_width);
4884
Weidong Han5e98c4b2008-12-08 23:03:27 +08004885 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004886 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004887 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004888 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004889
4890 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004891 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004892 if (!domain->pgd)
4893 return -ENOMEM;
4894 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4895 return 0;
4896}
4897
Joerg Roedel00a77de2015-03-26 13:43:08 +01004898static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004899{
Joerg Roedel5d450802008-12-03 14:52:32 +01004900 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004901 struct iommu_domain *domain;
4902
4903 if (type != IOMMU_DOMAIN_UNMANAGED)
4904 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004905
Jiang Liuab8dfe22014-07-11 14:19:27 +08004906 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004907 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004908 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004909 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004910 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004911 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004912 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004913 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004914 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004915 }
Allen Kay8140a952011-10-14 12:32:17 -07004916 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004917
Joerg Roedel00a77de2015-03-26 13:43:08 +01004918 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004919 domain->geometry.aperture_start = 0;
4920 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4921 domain->geometry.force_aperture = true;
4922
Joerg Roedel00a77de2015-03-26 13:43:08 +01004923 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004924}
Kay, Allen M38717942008-09-09 18:37:29 +03004925
Joerg Roedel00a77de2015-03-26 13:43:08 +01004926static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004927{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004928 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004929}
Kay, Allen M38717942008-09-09 18:37:29 +03004930
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004931static int intel_iommu_attach_device(struct iommu_domain *domain,
4932 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004933{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004934 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004935 struct intel_iommu *iommu;
4936 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004937 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004938
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004939 if (device_is_rmrr_locked(dev)) {
4940 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4941 return -EPERM;
4942 }
4943
David Woodhouse7207d8f2014-03-09 16:31:06 -07004944 /* normally dev is not mapped */
4945 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004946 struct dmar_domain *old_domain;
4947
David Woodhouse1525a292014-03-06 16:19:30 +00004948 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004949 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004950 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004951 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004952 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004953
4954 if (!domain_type_is_vm_or_si(old_domain) &&
4955 list_empty(&old_domain->devices))
4956 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004957 }
4958 }
4959
David Woodhouse156baca2014-03-09 14:00:57 -07004960 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004961 if (!iommu)
4962 return -ENODEV;
4963
4964 /* check if this iommu agaw is sufficient for max mapped address */
4965 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004966 if (addr_width > cap_mgaw(iommu->cap))
4967 addr_width = cap_mgaw(iommu->cap);
4968
4969 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004970 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004971 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01004972 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004973 return -EFAULT;
4974 }
Tom Lyona99c47a2010-05-17 08:20:45 +01004975 dmar_domain->gaw = addr_width;
4976
4977 /*
4978 * Knock out extra levels of page tables if necessary
4979 */
4980 while (iommu->agaw < dmar_domain->agaw) {
4981 struct dma_pte *pte;
4982
4983 pte = dmar_domain->pgd;
4984 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08004985 dmar_domain->pgd = (struct dma_pte *)
4986 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01004987 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01004988 }
4989 dmar_domain->agaw--;
4990 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004991
Joerg Roedel28ccce02015-07-21 14:45:31 +02004992 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004993}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004994
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004995static void intel_iommu_detach_device(struct iommu_domain *domain,
4996 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004997{
Joerg Roedele6de0f82015-07-22 16:30:36 +02004998 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03004999}
Kay, Allen M38717942008-09-09 18:37:29 +03005000
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005001static int intel_iommu_map(struct iommu_domain *domain,
5002 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005003 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005004{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005005 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005006 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005007 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005008 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005009
Joerg Roedeldde57a22008-12-03 15:04:09 +01005010 if (iommu_prot & IOMMU_READ)
5011 prot |= DMA_PTE_READ;
5012 if (iommu_prot & IOMMU_WRITE)
5013 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005014 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5015 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005016
David Woodhouse163cc522009-06-28 00:51:17 +01005017 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005018 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005019 u64 end;
5020
5021 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005022 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005023 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005024 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005025 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005026 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005027 return -EFAULT;
5028 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005029 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005030 }
David Woodhousead051222009-06-28 14:22:28 +01005031 /* Round up size to next multiple of PAGE_SIZE, if it and
5032 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005033 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005034 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5035 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005036 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005037}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005038
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005039static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005040 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005041{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005042 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005043 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005044 unsigned long start_pfn, last_pfn;
5045 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005046 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005047
David Woodhouse5cf0a762014-03-19 16:07:49 +00005048 /* Cope with horrid API which requires us to unmap more than the
5049 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005050 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005051
5052 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5053 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5054
David Woodhouseea8ea462014-03-05 17:09:32 +00005055 start_pfn = iova >> VTD_PAGE_SHIFT;
5056 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5057
5058 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5059
5060 npages = last_pfn - start_pfn + 1;
5061
Shaokun Zhangf746a022018-03-22 18:18:06 +08005062 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005063 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5064 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005065
5066 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005067
David Woodhouse163cc522009-06-28 00:51:17 +01005068 if (dmar_domain->max_addr == iova + size)
5069 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005070
David Woodhouse5cf0a762014-03-19 16:07:49 +00005071 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005072}
Kay, Allen M38717942008-09-09 18:37:29 +03005073
Joerg Roedeld14d6572008-12-03 15:06:57 +01005074static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305075 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005076{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005077 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005078 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005079 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005080 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005081
David Woodhouse5cf0a762014-03-19 16:07:49 +00005082 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005083 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005084 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005085
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005086 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005087}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005088
Joerg Roedel5d587b82014-09-05 10:50:45 +02005089static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005090{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005091 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005092 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005093 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005094 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005095
Joerg Roedel5d587b82014-09-05 10:50:45 +02005096 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005097}
5098
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005099static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005100{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005101 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005102 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005103 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005104
Alex Williamsona5459cf2014-06-12 16:12:31 -06005105 iommu = device_to_iommu(dev, &bus, &devfn);
5106 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005107 return -ENODEV;
5108
Joerg Roedele3d10af2017-02-01 17:23:22 +01005109 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005110
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005111 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005112
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005113 if (IS_ERR(group))
5114 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005115
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005116 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005117 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005118}
5119
5120static void intel_iommu_remove_device(struct device *dev)
5121{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005122 struct intel_iommu *iommu;
5123 u8 bus, devfn;
5124
5125 iommu = device_to_iommu(dev, &bus, &devfn);
5126 if (!iommu)
5127 return;
5128
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005129 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005130
Joerg Roedele3d10af2017-02-01 17:23:22 +01005131 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005132}
5133
Eric Auger0659b8d2017-01-19 20:57:53 +00005134static void intel_iommu_get_resv_regions(struct device *device,
5135 struct list_head *head)
5136{
5137 struct iommu_resv_region *reg;
5138 struct dmar_rmrr_unit *rmrr;
5139 struct device *i_dev;
5140 int i;
5141
5142 rcu_read_lock();
5143 for_each_rmrr_units(rmrr) {
5144 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5145 i, i_dev) {
5146 if (i_dev != device)
5147 continue;
5148
5149 list_add_tail(&rmrr->resv->list, head);
5150 }
5151 }
5152 rcu_read_unlock();
5153
5154 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5155 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005156 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005157 if (!reg)
5158 return;
5159 list_add_tail(&reg->list, head);
5160}
5161
5162static void intel_iommu_put_resv_regions(struct device *dev,
5163 struct list_head *head)
5164{
5165 struct iommu_resv_region *entry, *next;
5166
5167 list_for_each_entry_safe(entry, next, head, list) {
5168 if (entry->type == IOMMU_RESV_RESERVED)
5169 kfree(entry);
5170 }
Kay, Allen M38717942008-09-09 18:37:29 +03005171}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005172
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005173#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005174#define MAX_NR_PASID_BITS (20)
5175static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5176{
5177 /*
5178 * Convert ecap_pss to extend context entry pts encoding, also
5179 * respect the soft pasid_max value set by the iommu.
5180 * - number of PASID bits = ecap_pss + 1
5181 * - number of PASID table entries = 2^(pts + 5)
5182 * Therefore, pts = ecap_pss - 4
5183 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5184 */
5185 if (ecap_pss(iommu->ecap) < 5)
5186 return 0;
5187
5188 /* pasid_max is encoded as actual number of entries not the bits */
5189 return find_first_bit((unsigned long *)&iommu->pasid_max,
5190 MAX_NR_PASID_BITS) - 5;
5191}
5192
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005193int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5194{
5195 struct device_domain_info *info;
5196 struct context_entry *context;
5197 struct dmar_domain *domain;
5198 unsigned long flags;
5199 u64 ctx_lo;
5200 int ret;
5201
5202 domain = get_valid_domain_for_dev(sdev->dev);
5203 if (!domain)
5204 return -EINVAL;
5205
5206 spin_lock_irqsave(&device_domain_lock, flags);
5207 spin_lock(&iommu->lock);
5208
5209 ret = -EINVAL;
5210 info = sdev->dev->archdata.iommu;
5211 if (!info || !info->pasid_supported)
5212 goto out;
5213
5214 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5215 if (WARN_ON(!context))
5216 goto out;
5217
5218 ctx_lo = context[0].lo;
5219
5220 sdev->did = domain->iommu_did[iommu->seq_id];
5221 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5222
5223 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005224 if (iommu->pasid_state_table)
5225 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005226 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5227 intel_iommu_get_pts(iommu);
5228
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005229 wmb();
5230 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5231 * extended to permit requests-with-PASID if the PASIDE bit
5232 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5233 * however, the PASIDE bit is ignored and requests-with-PASID
5234 * are unconditionally blocked. Which makes less sense.
5235 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5236 * "guest mode" translation types depending on whether ATS
5237 * is available or not. Annoyingly, we can't use the new
5238 * modes *unless* PASIDE is set. */
5239 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5240 ctx_lo &= ~CONTEXT_TT_MASK;
5241 if (info->ats_supported)
5242 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5243 else
5244 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5245 }
5246 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005247 if (iommu->pasid_state_table)
5248 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005249 if (info->pri_supported)
5250 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005251 context[0].lo = ctx_lo;
5252 wmb();
5253 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5254 DMA_CCMD_MASK_NOBIT,
5255 DMA_CCMD_DEVICE_INVL);
5256 }
5257
5258 /* Enable PASID support in the device, if it wasn't already */
5259 if (!info->pasid_enabled)
5260 iommu_enable_dev_iotlb(info);
5261
5262 if (info->ats_enabled) {
5263 sdev->dev_iotlb = 1;
5264 sdev->qdep = info->ats_qdep;
5265 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5266 sdev->qdep = 0;
5267 }
5268 ret = 0;
5269
5270 out:
5271 spin_unlock(&iommu->lock);
5272 spin_unlock_irqrestore(&device_domain_lock, flags);
5273
5274 return ret;
5275}
5276
5277struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5278{
5279 struct intel_iommu *iommu;
5280 u8 bus, devfn;
5281
5282 if (iommu_dummy(dev)) {
5283 dev_warn(dev,
5284 "No IOMMU translation for device; cannot enable SVM\n");
5285 return NULL;
5286 }
5287
5288 iommu = device_to_iommu(dev, &bus, &devfn);
5289 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005290 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005291 return NULL;
5292 }
5293
5294 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005295 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005296 return NULL;
5297 }
5298
5299 return iommu;
5300}
5301#endif /* CONFIG_INTEL_IOMMU_SVM */
5302
Joerg Roedelb0119e82017-02-01 13:23:08 +01005303const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005304 .capable = intel_iommu_capable,
5305 .domain_alloc = intel_iommu_domain_alloc,
5306 .domain_free = intel_iommu_domain_free,
5307 .attach_dev = intel_iommu_attach_device,
5308 .detach_dev = intel_iommu_detach_device,
5309 .map = intel_iommu_map,
5310 .unmap = intel_iommu_unmap,
5311 .map_sg = default_iommu_map_sg,
5312 .iova_to_phys = intel_iommu_iova_to_phys,
5313 .add_device = intel_iommu_add_device,
5314 .remove_device = intel_iommu_remove_device,
5315 .get_resv_regions = intel_iommu_get_resv_regions,
5316 .put_resv_regions = intel_iommu_put_resv_regions,
5317 .device_group = pci_device_group,
5318 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005319};
David Woodhouse9af88142009-02-13 23:18:03 +00005320
Daniel Vetter94526182013-01-20 23:50:13 +01005321static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5322{
5323 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005324 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005325 dmar_map_gfx = 0;
5326}
5327
5328DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5329DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5330DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5331DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5332DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5333DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5334DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5335
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005336static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005337{
5338 /*
5339 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005340 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005341 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005342 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005343 rwbf_quirk = 1;
5344}
5345
5346DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005347DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5348DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5349DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5350DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5351DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5352DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005353
Adam Jacksoneecfd572010-08-25 21:17:34 +01005354#define GGC 0x52
5355#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5356#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5357#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5358#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5359#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5360#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5361#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5362#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5363
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005364static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005365{
5366 unsigned short ggc;
5367
Adam Jacksoneecfd572010-08-25 21:17:34 +01005368 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005369 return;
5370
Adam Jacksoneecfd572010-08-25 21:17:34 +01005371 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005372 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005373 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005374 } else if (dmar_map_gfx) {
5375 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005376 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005377 intel_iommu_strict = 1;
5378 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005379}
5380DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5381DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5382DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5383DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5384
David Woodhousee0fc7e02009-09-30 09:12:17 -07005385/* On Tylersburg chipsets, some BIOSes have been known to enable the
5386 ISOCH DMAR unit for the Azalia sound device, but not give it any
5387 TLB entries, which causes it to deadlock. Check for that. We do
5388 this in a function called from init_dmars(), instead of in a PCI
5389 quirk, because we don't want to print the obnoxious "BIOS broken"
5390 message if VT-d is actually disabled.
5391*/
5392static void __init check_tylersburg_isoch(void)
5393{
5394 struct pci_dev *pdev;
5395 uint32_t vtisochctrl;
5396
5397 /* If there's no Azalia in the system anyway, forget it. */
5398 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5399 if (!pdev)
5400 return;
5401 pci_dev_put(pdev);
5402
5403 /* System Management Registers. Might be hidden, in which case
5404 we can't do the sanity check. But that's OK, because the
5405 known-broken BIOSes _don't_ actually hide it, so far. */
5406 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5407 if (!pdev)
5408 return;
5409
5410 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5411 pci_dev_put(pdev);
5412 return;
5413 }
5414
5415 pci_dev_put(pdev);
5416
5417 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5418 if (vtisochctrl & 1)
5419 return;
5420
5421 /* Drop all bits other than the number of TLB entries */
5422 vtisochctrl &= 0x1c;
5423
5424 /* If we have the recommended number of TLB entries (16), fine. */
5425 if (vtisochctrl == 0x10)
5426 return;
5427
5428 /* Zero TLB entries? You get to ride the short bus to school. */
5429 if (!vtisochctrl) {
5430 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5431 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5432 dmi_get_system_info(DMI_BIOS_VENDOR),
5433 dmi_get_system_info(DMI_BIOS_VERSION),
5434 dmi_get_system_info(DMI_PRODUCT_VERSION));
5435 iommu_identity_mapping |= IDENTMAP_AZALIA;
5436 return;
5437 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005438
5439 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005440 vtisochctrl);
5441}