blob: 772b404a6604b3b315ff77de14115d76a3e8d677 [file] [log] [blame]
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001/*
David Woodhouseea8ea462014-03-05 17:09:32 +00002 * Copyright © 2006-2014 Intel Corporation.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
David Woodhouseea8ea462014-03-05 17:09:32 +000013 * Authors: David Woodhouse <dwmw2@infradead.org>,
14 * Ashok Raj <ashok.raj@intel.com>,
15 * Shaohua Li <shaohua.li@intel.com>,
16 * Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
17 * Fenghua Yu <fenghua.yu@intel.com>
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020018 * Joerg Roedel <jroedel@suse.de>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070019 */
20
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020021#define pr_fmt(fmt) "DMAR: " fmt
22
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070023#include <linux/init.h>
24#include <linux/bitmap.h>
mark gross5e0d2a62008-03-04 15:22:08 -080025#include <linux/debugfs.h>
Paul Gortmaker54485c32011-10-29 10:26:25 -040026#include <linux/export.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070027#include <linux/slab.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070030#include <linux/spinlock.h>
31#include <linux/pci.h>
32#include <linux/dmar.h>
33#include <linux/dma-mapping.h>
Christoph Hellwigd657c5c2018-03-19 11:38:20 +010034#include <linux/dma-direct.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070035#include <linux/mempool.h>
Jiang Liu75f05562014-02-19 14:07:37 +080036#include <linux/memory.h>
Omer Pelegaa473242016-04-20 11:33:02 +030037#include <linux/cpu.h>
mark gross5e0d2a62008-03-04 15:22:08 -080038#include <linux/timer.h>
Dan Williamsdfddb9692015-10-09 18:16:46 -040039#include <linux/io.h>
Kay, Allen M38717942008-09-09 18:37:29 +030040#include <linux/iova.h>
Joerg Roedel5d450802008-12-03 14:52:32 +010041#include <linux/iommu.h>
Kay, Allen M38717942008-09-09 18:37:29 +030042#include <linux/intel-iommu.h>
Rafael J. Wysocki134fac32011-03-23 22:16:14 +010043#include <linux/syscore_ops.h>
Shane Wang69575d32009-09-01 18:25:07 -070044#include <linux/tboot.h>
Stephen Rothwelladb2fe02009-08-31 15:24:23 +100045#include <linux/dmi.h>
Joerg Roedel5cdede22011-04-04 15:55:18 +020046#include <linux/pci-ats.h>
Tejun Heo0ee332c2011-12-08 10:22:09 -080047#include <linux/memblock.h>
Akinobu Mita36746432014-06-04 16:06:51 -070048#include <linux/dma-contiguous.h>
Christoph Hellwigfec777c2018-03-19 11:38:15 +010049#include <linux/dma-direct.h>
Joerg Roedel091d42e2015-06-12 11:56:10 +020050#include <linux/crash_dump.h>
Suresh Siddha8a8f4222012-03-30 11:47:08 -070051#include <asm/irq_remapping.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070052#include <asm/cacheflush.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090053#include <asm/iommu.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070054
Joerg Roedel078e1ee2012-09-26 12:44:43 +020055#include "irq_remapping.h"
56
Fenghua Yu5b6985c2008-10-16 18:02:32 -070057#define ROOT_SIZE VTD_PAGE_SIZE
58#define CONTEXT_SIZE VTD_PAGE_SIZE
59
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070060#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000061#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070062#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070063#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070064
65#define IOAPIC_RANGE_START (0xfee00000)
66#define IOAPIC_RANGE_END (0xfeefffff)
67#define IOVA_START_ADDR (0x1000)
68
Sohil Mehta5e3b4a12017-12-20 11:59:24 -080069#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070070
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070071#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080072#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070073
David Woodhouse2ebe3152009-09-19 07:34:04 -070074#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
75#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
76
77/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
78 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
79#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
80 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
81#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070082
Robin Murphy1b722502015-01-12 17:51:15 +000083/* IO virtual address start page frame number */
84#define IOVA_START_PFN (1)
85
Mark McLoughlinf27be032008-11-20 15:49:43 +000086#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
mark gross5e0d2a62008-03-04 15:22:08 -080087
Andrew Mortondf08cdc2010-09-22 13:05:11 -070088/* page table handling */
89#define LEVEL_STRIDE (9)
90#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
91
Ohad Ben-Cohen6d1c56a2011-11-10 11:32:30 +020092/*
93 * This bitmap is used to advertise the page sizes our hardware support
94 * to the IOMMU core, which will then use this information to split
95 * physically contiguous memory regions it is mapping into page sizes
96 * that we support.
97 *
98 * Traditionally the IOMMU core just handed us the mappings directly,
99 * after making sure the size is an order of a 4KiB page and that the
100 * mapping has natural alignment.
101 *
102 * To retain this behavior, we currently advertise that we support
103 * all page sizes that are an order of 4KiB.
104 *
105 * If at some point we'd like to utilize the IOMMU core's new behavior,
106 * we could change this to advertise the real page sizes we support.
107 */
108#define INTEL_IOMMU_PGSIZES (~0xFFFUL)
109
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700110static inline int agaw_to_level(int agaw)
111{
112 return agaw + 2;
113}
114
115static inline int agaw_to_width(int agaw)
116{
Jiang Liu5c645b32014-01-06 14:18:12 +0800117 return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700118}
119
120static inline int width_to_agaw(int width)
121{
Jiang Liu5c645b32014-01-06 14:18:12 +0800122 return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700123}
124
125static inline unsigned int level_to_offset_bits(int level)
126{
127 return (level - 1) * LEVEL_STRIDE;
128}
129
130static inline int pfn_level_offset(unsigned long pfn, int level)
131{
132 return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
133}
134
135static inline unsigned long level_mask(int level)
136{
137 return -1UL << level_to_offset_bits(level);
138}
139
140static inline unsigned long level_size(int level)
141{
142 return 1UL << level_to_offset_bits(level);
143}
144
145static inline unsigned long align_to_level(unsigned long pfn, int level)
146{
147 return (pfn + level_size(level) - 1) & level_mask(level);
148}
David Woodhousefd18de52009-05-10 23:57:41 +0100149
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100150static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
151{
Jiang Liu5c645b32014-01-06 14:18:12 +0800152 return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100153}
154
David Woodhousedd4e8312009-06-27 16:21:20 +0100155/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
156 are never going to work. */
157static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
158{
159 return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT);
160}
161
162static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn)
163{
164 return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
165}
166static inline unsigned long page_to_dma_pfn(struct page *pg)
167{
168 return mm_to_dma_pfn(page_to_pfn(pg));
169}
170static inline unsigned long virt_to_dma_pfn(void *p)
171{
172 return page_to_dma_pfn(virt_to_page(p));
173}
174
Weidong Hand9630fe2008-12-08 11:06:32 +0800175/* global iommu list, set NULL for ignored DMAR units */
176static struct intel_iommu **g_iommus;
177
David Woodhousee0fc7e02009-09-30 09:12:17 -0700178static void __init check_tylersburg_isoch(void);
David Woodhouse9af88142009-02-13 23:18:03 +0000179static int rwbf_quirk;
180
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000181/*
Joseph Cihulab7792602011-05-03 00:08:37 -0700182 * set to 1 to panic kernel if can't successfully enable VT-d
183 * (used when kernel is launched w/ TXT)
184 */
185static int force_on = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700186int intel_iommu_tboot_noforce;
Joseph Cihulab7792602011-05-03 00:08:37 -0700187
188/*
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000189 * 0: Present
190 * 1-11: Reserved
191 * 12-63: Context Ptr (12 - (haw-1))
192 * 64-127: Reserved
193 */
194struct root_entry {
David Woodhouse03ecc322015-02-13 14:35:21 +0000195 u64 lo;
196 u64 hi;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000197};
198#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000199
Joerg Roedel091d42e2015-06-12 11:56:10 +0200200/*
201 * Take a root_entry and return the Lower Context Table Pointer (LCTP)
202 * if marked present.
203 */
204static phys_addr_t root_entry_lctp(struct root_entry *re)
205{
206 if (!(re->lo & 1))
207 return 0;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000208
Joerg Roedel091d42e2015-06-12 11:56:10 +0200209 return re->lo & VTD_PAGE_MASK;
210}
211
212/*
213 * Take a root_entry and return the Upper Context Table Pointer (UCTP)
214 * if marked present.
215 */
216static phys_addr_t root_entry_uctp(struct root_entry *re)
217{
218 if (!(re->hi & 1))
219 return 0;
220
221 return re->hi & VTD_PAGE_MASK;
222}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000223/*
224 * low 64 bits:
225 * 0: present
226 * 1: fault processing disable
227 * 2-3: translation type
228 * 12-63: address space root
229 * high 64 bits:
230 * 0-2: address width
231 * 3-6: aval
232 * 8-23: domain id
233 */
234struct context_entry {
235 u64 lo;
236 u64 hi;
237};
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000238
Joerg Roedelcf484d02015-06-12 12:21:46 +0200239static inline void context_clear_pasid_enable(struct context_entry *context)
240{
241 context->lo &= ~(1ULL << 11);
242}
243
244static inline bool context_pasid_enabled(struct context_entry *context)
245{
246 return !!(context->lo & (1ULL << 11));
247}
248
249static inline void context_set_copied(struct context_entry *context)
250{
251 context->hi |= (1ull << 3);
252}
253
254static inline bool context_copied(struct context_entry *context)
255{
256 return !!(context->hi & (1ULL << 3));
257}
258
259static inline bool __context_present(struct context_entry *context)
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000260{
261 return (context->lo & 1);
262}
Joerg Roedelcf484d02015-06-12 12:21:46 +0200263
264static inline bool context_present(struct context_entry *context)
265{
266 return context_pasid_enabled(context) ?
267 __context_present(context) :
268 __context_present(context) && !context_copied(context);
269}
270
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000271static inline void context_set_present(struct context_entry *context)
272{
273 context->lo |= 1;
274}
275
276static inline void context_set_fault_enable(struct context_entry *context)
277{
278 context->lo &= (((u64)-1) << 2) | 1;
279}
280
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000281static inline void context_set_translation_type(struct context_entry *context,
282 unsigned long value)
283{
284 context->lo &= (((u64)-1) << 4) | 3;
285 context->lo |= (value & 3) << 2;
286}
287
288static inline void context_set_address_root(struct context_entry *context,
289 unsigned long value)
290{
Li, Zhen-Hua1a2262f2014-11-05 15:30:19 +0800291 context->lo &= ~VTD_PAGE_MASK;
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000292 context->lo |= value & VTD_PAGE_MASK;
293}
294
295static inline void context_set_address_width(struct context_entry *context,
296 unsigned long value)
297{
298 context->hi |= value & 7;
299}
300
301static inline void context_set_domain_id(struct context_entry *context,
302 unsigned long value)
303{
304 context->hi |= (value & ((1 << 16) - 1)) << 8;
305}
306
Joerg Roedeldbcd8612015-06-12 12:02:09 +0200307static inline int context_domain_id(struct context_entry *c)
308{
309 return((c->hi >> 8) & 0xffff);
310}
311
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000312static inline void context_clear_entry(struct context_entry *context)
313{
314 context->lo = 0;
315 context->hi = 0;
316}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000317
Mark McLoughlin622ba122008-11-20 15:49:46 +0000318/*
319 * 0: readable
320 * 1: writable
321 * 2-6: reserved
322 * 7: super page
Sheng Yang9cf06692009-03-18 15:33:07 +0800323 * 8-10: available
324 * 11: snoop behavior
Mark McLoughlin622ba122008-11-20 15:49:46 +0000325 * 12-63: Host physcial address
326 */
327struct dma_pte {
328 u64 val;
329};
Mark McLoughlin622ba122008-11-20 15:49:46 +0000330
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000331static inline void dma_clear_pte(struct dma_pte *pte)
332{
333 pte->val = 0;
334}
335
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000336static inline u64 dma_pte_addr(struct dma_pte *pte)
337{
David Woodhousec85994e2009-07-01 19:21:24 +0100338#ifdef CONFIG_64BIT
339 return pte->val & VTD_PAGE_MASK;
340#else
341 /* Must have a full atomic 64-bit read */
David Woodhouse1a8bd482010-08-10 01:38:53 +0100342 return __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
David Woodhousec85994e2009-07-01 19:21:24 +0100343#endif
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000344}
345
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000346static inline bool dma_pte_present(struct dma_pte *pte)
347{
348 return (pte->val & 3) != 0;
349}
Mark McLoughlin622ba122008-11-20 15:49:46 +0000350
Allen Kay4399c8b2011-10-14 12:32:46 -0700351static inline bool dma_pte_superpage(struct dma_pte *pte)
352{
Joerg Roedelc3c75eb2014-07-04 11:19:10 +0200353 return (pte->val & DMA_PTE_LARGE_PAGE);
Allen Kay4399c8b2011-10-14 12:32:46 -0700354}
355
David Woodhouse75e6bf92009-07-02 11:21:16 +0100356static inline int first_pte_in_page(struct dma_pte *pte)
357{
358 return !((unsigned long)pte & ~VTD_PAGE_MASK);
359}
360
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700361/*
362 * This domain is a statically identity mapping domain.
363 * 1. This domain creats a static 1:1 mapping to all usable memory.
364 * 2. It maps to each iommu if successful.
365 * 3. Each iommu mapps to this domain if successful.
366 */
David Woodhouse19943b02009-08-04 16:19:20 +0100367static struct dmar_domain *si_domain;
368static int hw_pass_through = 1;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700369
Joerg Roedel28ccce02015-07-21 14:45:31 +0200370/*
371 * Domain represents a virtual machine, more than one devices
Weidong Han1ce28fe2008-12-08 16:35:39 +0800372 * across iommus may be owned in one domain, e.g. kvm guest.
373 */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800374#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
Weidong Han1ce28fe2008-12-08 16:35:39 +0800375
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700376/* si_domain contains mulitple devices */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800377#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700378
Joerg Roedel29a27712015-07-21 17:17:12 +0200379#define for_each_domain_iommu(idx, domain) \
380 for (idx = 0; idx < g_num_of_iommus; idx++) \
381 if (domain->iommu_refcnt[idx])
382
Mark McLoughlin99126f72008-11-20 15:49:47 +0000383struct dmar_domain {
Suresh Siddha4c923d42009-10-02 11:01:24 -0700384 int nid; /* node id */
Joerg Roedel29a27712015-07-21 17:17:12 +0200385
386 unsigned iommu_refcnt[DMAR_UNITS_SUPPORTED];
387 /* Refcount of devices per iommu */
388
Mark McLoughlin99126f72008-11-20 15:49:47 +0000389
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +0200390 u16 iommu_did[DMAR_UNITS_SUPPORTED];
391 /* Domain ids per IOMMU. Use u16 since
392 * domain ids are 16 bit wide according
393 * to VT-d spec, section 9.3 */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000394
Omer Peleg0824c592016-04-20 19:03:35 +0300395 bool has_iotlb_device;
Joerg Roedel00a77de2015-03-26 13:43:08 +0100396 struct list_head devices; /* all devices' list */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000397 struct iova_domain iovad; /* iova's that belong to this domain */
398
399 struct dma_pte *pgd; /* virtual address */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000400 int gaw; /* max guest address width */
401
402 /* adjusted guest address width, 0 is level 2 30-bit */
403 int agaw;
404
Weidong Han3b5410e2008-12-08 09:17:15 +0800405 int flags; /* flags to find out type of domain */
Weidong Han8e6040972008-12-08 15:49:06 +0800406
407 int iommu_coherency;/* indicate coherency of iommu access */
Sheng Yang58c610b2009-03-18 15:33:05 +0800408 int iommu_snooping; /* indicate snooping control feature*/
Weidong Hanc7151a82008-12-08 22:51:37 +0800409 int iommu_count; /* reference count of iommu */
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100410 int iommu_superpage;/* Level of superpages supported:
411 0 == 4KiB (no superpages), 1 == 2MiB,
412 2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
Weidong Hanfe40f1e2008-12-08 23:10:23 +0800413 u64 max_addr; /* maximum mapped address */
Joerg Roedel00a77de2015-03-26 13:43:08 +0100414
415 struct iommu_domain domain; /* generic domain data structure for
416 iommu core */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000417};
418
Mark McLoughlina647dac2008-11-20 15:49:48 +0000419/* PCI domain-device relationship */
420struct device_domain_info {
421 struct list_head link; /* link to domain siblings */
422 struct list_head global; /* link to global list */
David Woodhouse276dbf992009-04-04 01:45:37 +0100423 u8 bus; /* PCI bus number */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000424 u8 devfn; /* PCI devfn number */
David Woodhouseb16d0cb2015-10-12 14:17:37 +0100425 u8 pasid_supported:3;
426 u8 pasid_enabled:1;
427 u8 pri_supported:1;
428 u8 pri_enabled:1;
429 u8 ats_supported:1;
430 u8 ats_enabled:1;
431 u8 ats_qdep;
David Woodhouse0bcb3e22014-03-06 17:12:03 +0000432 struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
Yu Zhao93a23a72009-05-18 13:51:37 +0800433 struct intel_iommu *iommu; /* IOMMU used by this device */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000434 struct dmar_domain *domain; /* pointer to domain */
435};
436
Jiang Liub94e4112014-02-19 14:07:25 +0800437struct dmar_rmrr_unit {
438 struct list_head list; /* list of rmrr units */
439 struct acpi_dmar_header *hdr; /* ACPI header */
440 u64 base_address; /* reserved base address*/
441 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000442 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800443 int devices_cnt; /* target device count */
Eric Auger0659b8d2017-01-19 20:57:53 +0000444 struct iommu_resv_region *resv; /* reserved region handle */
Jiang Liub94e4112014-02-19 14:07:25 +0800445};
446
447struct dmar_atsr_unit {
448 struct list_head list; /* list of ATSR units */
449 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000450 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800451 int devices_cnt; /* target device count */
452 u8 include_all:1; /* include all ports */
453};
454
455static LIST_HEAD(dmar_atsr_units);
456static LIST_HEAD(dmar_rmrr_units);
457
458#define for_each_rmrr_units(rmrr) \
459 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
460
mark gross5e0d2a62008-03-04 15:22:08 -0800461/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800462static int g_num_of_iommus;
463
Jiang Liu92d03cc2014-02-19 14:07:28 +0800464static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700465static void domain_remove_dev_info(struct dmar_domain *domain);
Joerg Roedele6de0f82015-07-22 16:30:36 +0200466static void dmar_remove_one_dev_info(struct dmar_domain *domain,
467 struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200468static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Joerg Roedel2452d9d2015-07-23 16:20:14 +0200469static void domain_context_clear(struct intel_iommu *iommu,
470 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800471static int domain_detach_iommu(struct dmar_domain *domain,
472 struct intel_iommu *iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700473
Suresh Siddhad3f13812011-08-23 17:05:25 -0700474#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800475int dmar_disabled = 0;
476#else
477int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700478#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800479
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200480int intel_iommu_enabled = 0;
481EXPORT_SYMBOL_GPL(intel_iommu_enabled);
482
David Woodhouse2d9e6672010-06-15 10:57:57 +0100483static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700484static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800485static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100486static int intel_iommu_superpage = 1;
David Woodhousec83b2f22015-06-12 10:15:49 +0100487static int intel_iommu_ecs = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100488static int intel_iommu_pasid28;
489static int iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100490
David Woodhouseae853dd2015-09-09 11:58:59 +0100491#define IDENTMAP_ALL 1
492#define IDENTMAP_GFX 2
493#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100494
David Woodhoused42fde72015-10-24 21:33:01 +0200495/* Broadwell and Skylake have broken ECS support — normal so-called "second
496 * level" translation of DMA requests-without-PASID doesn't actually happen
497 * unless you also set the NESTE bit in an extended context-entry. Which of
498 * course means that SVM doesn't work because it's trying to do nested
499 * translation of the physical addresses it finds in the process page tables,
500 * through the IOVA->phys mapping found in the "second level" page tables.
501 *
502 * The VT-d specification was retroactively changed to change the definition
503 * of the capability bits and pretend that Broadwell/Skylake never happened...
504 * but unfortunately the wrong bit was changed. It's ECS which is broken, but
505 * for some reason it was the PASID capability bit which was redefined (from
506 * bit 28 on BDW/SKL to bit 40 in future).
507 *
508 * So our test for ECS needs to eschew those implementations which set the old
509 * PASID capabiity bit 28, since those are the ones on which ECS is broken.
510 * Unless we are working around the 'pasid28' limitations, that is, by putting
511 * the device into passthrough mode for normal DMA and thus masking the bug.
512 */
David Woodhousec83b2f22015-06-12 10:15:49 +0100513#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \
David Woodhoused42fde72015-10-24 21:33:01 +0200514 (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap)))
515/* PASID support is thus enabled if ECS is enabled and *either* of the old
516 * or new capability bits are set. */
517#define pasid_enabled(iommu) (ecs_enabled(iommu) && \
518 (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700519
David Woodhousec0771df2011-10-14 20:59:46 +0100520int intel_iommu_gfx_mapped;
521EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
522
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700523#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
524static DEFINE_SPINLOCK(device_domain_lock);
525static LIST_HEAD(device_domain_list);
526
Joerg Roedelb0119e82017-02-01 13:23:08 +0100527const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100528
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200529static bool translation_pre_enabled(struct intel_iommu *iommu)
530{
531 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
532}
533
Joerg Roedel091d42e2015-06-12 11:56:10 +0200534static void clear_translation_pre_enabled(struct intel_iommu *iommu)
535{
536 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
537}
538
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200539static void init_translation_status(struct intel_iommu *iommu)
540{
541 u32 gsts;
542
543 gsts = readl(iommu->reg + DMAR_GSTS_REG);
544 if (gsts & DMA_GSTS_TES)
545 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
546}
547
Joerg Roedel00a77de2015-03-26 13:43:08 +0100548/* Convert generic 'struct iommu_domain to private struct dmar_domain */
549static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
550{
551 return container_of(dom, struct dmar_domain, domain);
552}
553
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700554static int __init intel_iommu_setup(char *str)
555{
556 if (!str)
557 return -EINVAL;
558 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800559 if (!strncmp(str, "on", 2)) {
560 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200561 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800562 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700563 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200564 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700565 } else if (!strncmp(str, "igfx_off", 8)) {
566 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200567 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700568 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200569 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700570 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800571 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200572 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800573 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100574 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200575 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100576 intel_iommu_superpage = 0;
David Woodhousec83b2f22015-06-12 10:15:49 +0100577 } else if (!strncmp(str, "ecs_off", 7)) {
578 printk(KERN_INFO
579 "Intel-IOMMU: disable extended context table support\n");
580 intel_iommu_ecs = 0;
David Woodhouseae853dd2015-09-09 11:58:59 +0100581 } else if (!strncmp(str, "pasid28", 7)) {
582 printk(KERN_INFO
583 "Intel-IOMMU: enable pre-production PASID support\n");
584 intel_iommu_pasid28 = 1;
585 iommu_identity_mapping |= IDENTMAP_GFX;
Shaohua Libfd20f12017-04-26 09:18:35 -0700586 } else if (!strncmp(str, "tboot_noforce", 13)) {
587 printk(KERN_INFO
588 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
589 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700590 }
591
592 str += strcspn(str, ",");
593 while (*str == ',')
594 str++;
595 }
596 return 0;
597}
598__setup("intel_iommu=", intel_iommu_setup);
599
600static struct kmem_cache *iommu_domain_cache;
601static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700602
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200603static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
604{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200605 struct dmar_domain **domains;
606 int idx = did >> 8;
607
608 domains = iommu->domains[idx];
609 if (!domains)
610 return NULL;
611
612 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200613}
614
615static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
616 struct dmar_domain *domain)
617{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200618 struct dmar_domain **domains;
619 int idx = did >> 8;
620
621 if (!iommu->domains[idx]) {
622 size_t size = 256 * sizeof(struct dmar_domain *);
623 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
624 }
625
626 domains = iommu->domains[idx];
627 if (WARN_ON(!domains))
628 return;
629 else
630 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200631}
632
Suresh Siddha4c923d42009-10-02 11:01:24 -0700633static inline void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700634{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700635 struct page *page;
636 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700637
Suresh Siddha4c923d42009-10-02 11:01:24 -0700638 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
639 if (page)
640 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700641 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700642}
643
644static inline void free_pgtable_page(void *vaddr)
645{
646 free_page((unsigned long)vaddr);
647}
648
649static inline void *alloc_domain_mem(void)
650{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900651 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700652}
653
Kay, Allen M38717942008-09-09 18:37:29 +0300654static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700655{
656 kmem_cache_free(iommu_domain_cache, vaddr);
657}
658
659static inline void * alloc_devinfo_mem(void)
660{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900661 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700662}
663
664static inline void free_devinfo_mem(void *vaddr)
665{
666 kmem_cache_free(iommu_devinfo_cache, vaddr);
667}
668
Jiang Liuab8dfe22014-07-11 14:19:27 +0800669static inline int domain_type_is_vm(struct dmar_domain *domain)
670{
671 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
672}
673
Joerg Roedel28ccce02015-07-21 14:45:31 +0200674static inline int domain_type_is_si(struct dmar_domain *domain)
675{
676 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
677}
678
Jiang Liuab8dfe22014-07-11 14:19:27 +0800679static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
680{
681 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
682 DOMAIN_FLAG_STATIC_IDENTITY);
683}
Weidong Han1b573682008-12-08 15:34:06 +0800684
Jiang Liu162d1b12014-07-11 14:19:35 +0800685static inline int domain_pfn_supported(struct dmar_domain *domain,
686 unsigned long pfn)
687{
688 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
689
690 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
691}
692
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700693static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800694{
695 unsigned long sagaw;
696 int agaw = -1;
697
698 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700699 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800700 agaw >= 0; agaw--) {
701 if (test_bit(agaw, &sagaw))
702 break;
703 }
704
705 return agaw;
706}
707
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700708/*
709 * Calculate max SAGAW for each iommu.
710 */
711int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
712{
713 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
714}
715
716/*
717 * calculate agaw for each iommu.
718 * "SAGAW" may be different across iommus, use a default agaw, and
719 * get a supported less agaw for iommus that don't support the default agaw.
720 */
721int iommu_calculate_agaw(struct intel_iommu *iommu)
722{
723 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
724}
725
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700726/* This functionin only returns single iommu in a domain */
Weidong Han8c11e792008-12-08 15:29:22 +0800727static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
728{
729 int iommu_id;
730
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700731 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800732 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200733 for_each_domain_iommu(iommu_id, domain)
734 break;
735
Weidong Han8c11e792008-12-08 15:29:22 +0800736 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
737 return NULL;
738
739 return g_iommus[iommu_id];
740}
741
Weidong Han8e6040972008-12-08 15:49:06 +0800742static void domain_update_iommu_coherency(struct dmar_domain *domain)
743{
David Woodhoused0501962014-03-11 17:10:29 -0700744 struct dmar_drhd_unit *drhd;
745 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100746 bool found = false;
747 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800748
David Woodhoused0501962014-03-11 17:10:29 -0700749 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800750
Joerg Roedel29a27712015-07-21 17:17:12 +0200751 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100752 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800753 if (!ecap_coherent(g_iommus[i]->ecap)) {
754 domain->iommu_coherency = 0;
755 break;
756 }
Weidong Han8e6040972008-12-08 15:49:06 +0800757 }
David Woodhoused0501962014-03-11 17:10:29 -0700758 if (found)
759 return;
760
761 /* No hardware attached; use lowest common denominator */
762 rcu_read_lock();
763 for_each_active_iommu(iommu, drhd) {
764 if (!ecap_coherent(iommu->ecap)) {
765 domain->iommu_coherency = 0;
766 break;
767 }
768 }
769 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800770}
771
Jiang Liu161f6932014-07-11 14:19:37 +0800772static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100773{
Allen Kay8140a952011-10-14 12:32:17 -0700774 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800775 struct intel_iommu *iommu;
776 int ret = 1;
777
778 rcu_read_lock();
779 for_each_active_iommu(iommu, drhd) {
780 if (iommu != skip) {
781 if (!ecap_sc_support(iommu->ecap)) {
782 ret = 0;
783 break;
784 }
785 }
786 }
787 rcu_read_unlock();
788
789 return ret;
790}
791
792static int domain_update_iommu_superpage(struct intel_iommu *skip)
793{
794 struct dmar_drhd_unit *drhd;
795 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700796 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100797
798 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800799 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100800 }
801
Allen Kay8140a952011-10-14 12:32:17 -0700802 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800803 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700804 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800805 if (iommu != skip) {
806 mask &= cap_super_page_val(iommu->cap);
807 if (!mask)
808 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100809 }
810 }
Jiang Liu0e242612014-02-19 14:07:34 +0800811 rcu_read_unlock();
812
Jiang Liu161f6932014-07-11 14:19:37 +0800813 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100814}
815
Sheng Yang58c610b2009-03-18 15:33:05 +0800816/* Some capabilities may be different across iommus */
817static void domain_update_iommu_cap(struct dmar_domain *domain)
818{
819 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800820 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
821 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800822}
823
David Woodhouse03ecc322015-02-13 14:35:21 +0000824static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu,
825 u8 bus, u8 devfn, int alloc)
826{
827 struct root_entry *root = &iommu->root_entry[bus];
828 struct context_entry *context;
829 u64 *entry;
830
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200831 entry = &root->lo;
David Woodhousec83b2f22015-06-12 10:15:49 +0100832 if (ecs_enabled(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000833 if (devfn >= 0x80) {
834 devfn -= 0x80;
835 entry = &root->hi;
836 }
837 devfn *= 2;
838 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000839 if (*entry & 1)
840 context = phys_to_virt(*entry & VTD_PAGE_MASK);
841 else {
842 unsigned long phy_addr;
843 if (!alloc)
844 return NULL;
845
846 context = alloc_pgtable_page(iommu->node);
847 if (!context)
848 return NULL;
849
850 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
851 phy_addr = virt_to_phys((void *)context);
852 *entry = phy_addr | 1;
853 __iommu_flush_cache(iommu, entry, sizeof(*entry));
854 }
855 return &context[devfn];
856}
857
David Woodhouse4ed6a542015-05-11 14:59:20 +0100858static int iommu_dummy(struct device *dev)
859{
860 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
861}
862
David Woodhouse156baca2014-03-09 14:00:57 -0700863static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800864{
865 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800866 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700867 struct device *tmp;
868 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800869 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800870 int i;
871
David Woodhouse4ed6a542015-05-11 14:59:20 +0100872 if (iommu_dummy(dev))
873 return NULL;
874
David Woodhouse156baca2014-03-09 14:00:57 -0700875 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700876 struct pci_dev *pf_pdev;
877
David Woodhouse156baca2014-03-09 14:00:57 -0700878 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600879
880#ifdef CONFIG_X86
881 /* VMD child devices currently cannot be handled individually */
882 if (is_vmd(pdev->bus))
883 return NULL;
884#endif
885
Ashok Raj1c387182016-10-21 15:32:05 -0700886 /* VFs aren't listed in scope tables; we need to look up
887 * the PF instead to find the IOMMU. */
888 pf_pdev = pci_physfn(pdev);
889 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700890 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100891 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700892 dev = &ACPI_COMPANION(dev)->dev;
893
Jiang Liu0e242612014-02-19 14:07:34 +0800894 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800895 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700896 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100897 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800898
Jiang Liub683b232014-02-19 14:07:32 +0800899 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700900 drhd->devices_cnt, i, tmp) {
901 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700902 /* For a VF use its original BDF# not that of the PF
903 * which we used for the IOMMU lookup. Strictly speaking
904 * we could do this for all PCI devices; we only need to
905 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100906 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700907 goto got_pdev;
908
David Woodhouse156baca2014-03-09 14:00:57 -0700909 *bus = drhd->devices[i].bus;
910 *devfn = drhd->devices[i].devfn;
911 goto out;
912 }
913
914 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000915 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700916
917 ptmp = to_pci_dev(tmp);
918 if (ptmp->subordinate &&
919 ptmp->subordinate->number <= pdev->bus->number &&
920 ptmp->subordinate->busn_res.end >= pdev->bus->number)
921 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100922 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800923
David Woodhouse156baca2014-03-09 14:00:57 -0700924 if (pdev && drhd->include_all) {
925 got_pdev:
926 *bus = pdev->bus->number;
927 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800928 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700929 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800930 }
Jiang Liub683b232014-02-19 14:07:32 +0800931 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700932 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800933 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800934
Jiang Liub683b232014-02-19 14:07:32 +0800935 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800936}
937
Weidong Han5331fe62008-12-08 23:00:00 +0800938static void domain_flush_cache(struct dmar_domain *domain,
939 void *addr, int size)
940{
941 if (!domain->iommu_coherency)
942 clflush_cache_range(addr, size);
943}
944
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700945static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
946{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700947 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000948 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700949 unsigned long flags;
950
951 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000952 context = iommu_context_addr(iommu, bus, devfn, 0);
953 if (context)
954 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700955 spin_unlock_irqrestore(&iommu->lock, flags);
956 return ret;
957}
958
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700959static void free_context_table(struct intel_iommu *iommu)
960{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700961 int i;
962 unsigned long flags;
963 struct context_entry *context;
964
965 spin_lock_irqsave(&iommu->lock, flags);
966 if (!iommu->root_entry) {
967 goto out;
968 }
969 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000970 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700971 if (context)
972 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000973
David Woodhousec83b2f22015-06-12 10:15:49 +0100974 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000975 continue;
976
977 context = iommu_context_addr(iommu, i, 0x80, 0);
978 if (context)
979 free_pgtable_page(context);
980
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700981 }
982 free_pgtable_page(iommu->root_entry);
983 iommu->root_entry = NULL;
984out:
985 spin_unlock_irqrestore(&iommu->lock, flags);
986}
987
David Woodhouseb026fd22009-06-28 10:37:25 +0100988static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000989 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700990{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700991 struct dma_pte *parent, *pte = NULL;
992 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700993 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700994
995 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200996
Jiang Liu162d1b12014-07-11 14:19:35 +0800997 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200998 /* Address beyond IOMMU's addressing capabilities. */
999 return NULL;
1000
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001001 parent = domain->pgd;
1002
David Woodhouse5cf0a762014-03-19 16:07:49 +00001003 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001004 void *tmp_page;
1005
David Woodhouseb026fd22009-06-28 10:37:25 +01001006 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001007 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +00001008 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001009 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +00001010 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001011 break;
1012
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001013 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +01001014 uint64_t pteval;
1015
Suresh Siddha4c923d42009-10-02 11:01:24 -07001016 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001017
David Woodhouse206a73c2009-07-01 19:30:28 +01001018 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001019 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +01001020
David Woodhousec85994e2009-07-01 19:21:24 +01001021 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -04001022 pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
Yijing Wangeffad4b2014-05-26 20:13:47 +08001023 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +01001024 /* Someone else set it while we were thinking; use theirs. */
1025 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +08001026 else
David Woodhousec85994e2009-07-01 19:21:24 +01001027 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001028 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001029 if (level == 1)
1030 break;
1031
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001032 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001033 level--;
1034 }
1035
David Woodhouse5cf0a762014-03-19 16:07:49 +00001036 if (!*target_level)
1037 *target_level = level;
1038
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001039 return pte;
1040}
1041
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001042
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001043/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001044static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1045 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001046 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001047{
1048 struct dma_pte *parent, *pte = NULL;
1049 int total = agaw_to_level(domain->agaw);
1050 int offset;
1051
1052 parent = domain->pgd;
1053 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001054 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001055 pte = &parent[offset];
1056 if (level == total)
1057 return pte;
1058
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001059 if (!dma_pte_present(pte)) {
1060 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001061 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001062 }
1063
Yijing Wange16922a2014-05-20 20:37:51 +08001064 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001065 *large_page = total;
1066 return pte;
1067 }
1068
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001069 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001070 total--;
1071 }
1072 return NULL;
1073}
1074
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001075/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001076static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001077 unsigned long start_pfn,
1078 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001079{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001080 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001081 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001082
Jiang Liu162d1b12014-07-11 14:19:35 +08001083 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1084 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001085 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001086
David Woodhouse04b18e62009-06-27 19:15:01 +01001087 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001088 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001089 large_page = 1;
1090 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001091 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001092 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001093 continue;
1094 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001095 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001096 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001097 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001098 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001099 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1100
David Woodhouse310a5ab2009-06-28 18:52:20 +01001101 domain_flush_cache(domain, first_pte,
1102 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001103
1104 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001105}
1106
Alex Williamson3269ee02013-06-15 10:27:19 -06001107static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001108 int retain_level, struct dma_pte *pte,
1109 unsigned long pfn, unsigned long start_pfn,
1110 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001111{
1112 pfn = max(start_pfn, pfn);
1113 pte = &pte[pfn_level_offset(pfn, level)];
1114
1115 do {
1116 unsigned long level_pfn;
1117 struct dma_pte *level_pte;
1118
1119 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1120 goto next;
1121
David Dillowf7116e12017-01-30 19:11:11 -08001122 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001123 level_pte = phys_to_virt(dma_pte_addr(pte));
1124
David Dillowbc24c572017-06-28 19:42:23 -07001125 if (level > 2) {
1126 dma_pte_free_level(domain, level - 1, retain_level,
1127 level_pte, level_pfn, start_pfn,
1128 last_pfn);
1129 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001130
David Dillowbc24c572017-06-28 19:42:23 -07001131 /*
1132 * Free the page table if we're below the level we want to
1133 * retain and the range covers the entire table.
1134 */
1135 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001136 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001137 dma_clear_pte(pte);
1138 domain_flush_cache(domain, pte, sizeof(*pte));
1139 free_pgtable_page(level_pte);
1140 }
1141next:
1142 pfn += level_size(level);
1143 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1144}
1145
David Dillowbc24c572017-06-28 19:42:23 -07001146/*
1147 * clear last level (leaf) ptes and free page table pages below the
1148 * level we wish to keep intact.
1149 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001150static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001151 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001152 unsigned long last_pfn,
1153 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001154{
Jiang Liu162d1b12014-07-11 14:19:35 +08001155 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1156 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001157 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001158
Jiang Liud41a4ad2014-07-11 14:19:34 +08001159 dma_pte_clear_range(domain, start_pfn, last_pfn);
1160
David Woodhousef3a0a522009-06-30 03:40:07 +01001161 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001162 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001163 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001164
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001165 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001166 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001167 free_pgtable_page(domain->pgd);
1168 domain->pgd = NULL;
1169 }
1170}
1171
David Woodhouseea8ea462014-03-05 17:09:32 +00001172/* When a page at a given level is being unlinked from its parent, we don't
1173 need to *modify* it at all. All we need to do is make a list of all the
1174 pages which can be freed just as soon as we've flushed the IOTLB and we
1175 know the hardware page-walk will no longer touch them.
1176 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1177 be freed. */
1178static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1179 int level, struct dma_pte *pte,
1180 struct page *freelist)
1181{
1182 struct page *pg;
1183
1184 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1185 pg->freelist = freelist;
1186 freelist = pg;
1187
1188 if (level == 1)
1189 return freelist;
1190
Jiang Liuadeb2592014-04-09 10:20:39 +08001191 pte = page_address(pg);
1192 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001193 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1194 freelist = dma_pte_list_pagetables(domain, level - 1,
1195 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001196 pte++;
1197 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001198
1199 return freelist;
1200}
1201
1202static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1203 struct dma_pte *pte, unsigned long pfn,
1204 unsigned long start_pfn,
1205 unsigned long last_pfn,
1206 struct page *freelist)
1207{
1208 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1209
1210 pfn = max(start_pfn, pfn);
1211 pte = &pte[pfn_level_offset(pfn, level)];
1212
1213 do {
1214 unsigned long level_pfn;
1215
1216 if (!dma_pte_present(pte))
1217 goto next;
1218
1219 level_pfn = pfn & level_mask(level);
1220
1221 /* If range covers entire pagetable, free it */
1222 if (start_pfn <= level_pfn &&
1223 last_pfn >= level_pfn + level_size(level) - 1) {
1224 /* These suborbinate page tables are going away entirely. Don't
1225 bother to clear them; we're just going to *free* them. */
1226 if (level > 1 && !dma_pte_superpage(pte))
1227 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1228
1229 dma_clear_pte(pte);
1230 if (!first_pte)
1231 first_pte = pte;
1232 last_pte = pte;
1233 } else if (level > 1) {
1234 /* Recurse down into a level that isn't *entirely* obsolete */
1235 freelist = dma_pte_clear_level(domain, level - 1,
1236 phys_to_virt(dma_pte_addr(pte)),
1237 level_pfn, start_pfn, last_pfn,
1238 freelist);
1239 }
1240next:
1241 pfn += level_size(level);
1242 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1243
1244 if (first_pte)
1245 domain_flush_cache(domain, first_pte,
1246 (void *)++last_pte - (void *)first_pte);
1247
1248 return freelist;
1249}
1250
1251/* We can't just free the pages because the IOMMU may still be walking
1252 the page tables, and may have cached the intermediate levels. The
1253 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001254static struct page *domain_unmap(struct dmar_domain *domain,
1255 unsigned long start_pfn,
1256 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001257{
David Woodhouseea8ea462014-03-05 17:09:32 +00001258 struct page *freelist = NULL;
1259
Jiang Liu162d1b12014-07-11 14:19:35 +08001260 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1261 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001262 BUG_ON(start_pfn > last_pfn);
1263
1264 /* we don't need lock here; nobody else touches the iova range */
1265 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1266 domain->pgd, 0, start_pfn, last_pfn, NULL);
1267
1268 /* free pgd */
1269 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1270 struct page *pgd_page = virt_to_page(domain->pgd);
1271 pgd_page->freelist = freelist;
1272 freelist = pgd_page;
1273
1274 domain->pgd = NULL;
1275 }
1276
1277 return freelist;
1278}
1279
Joerg Roedelb6904202015-08-13 11:32:18 +02001280static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001281{
1282 struct page *pg;
1283
1284 while ((pg = freelist)) {
1285 freelist = pg->freelist;
1286 free_pgtable_page(page_address(pg));
1287 }
1288}
1289
Joerg Roedel13cf0172017-08-11 11:40:10 +02001290static void iova_entry_free(unsigned long data)
1291{
1292 struct page *freelist = (struct page *)data;
1293
1294 dma_free_pagelist(freelist);
1295}
1296
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001297/* iommu handling */
1298static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1299{
1300 struct root_entry *root;
1301 unsigned long flags;
1302
Suresh Siddha4c923d42009-10-02 11:01:24 -07001303 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001304 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001305 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001306 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001307 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001308 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001309
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001310 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001311
1312 spin_lock_irqsave(&iommu->lock, flags);
1313 iommu->root_entry = root;
1314 spin_unlock_irqrestore(&iommu->lock, flags);
1315
1316 return 0;
1317}
1318
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001319static void iommu_set_root_entry(struct intel_iommu *iommu)
1320{
David Woodhouse03ecc322015-02-13 14:35:21 +00001321 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001322 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001323 unsigned long flag;
1324
David Woodhouse03ecc322015-02-13 14:35:21 +00001325 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001326 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001327 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001328
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001329 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001330 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001331
David Woodhousec416daa2009-05-10 20:30:58 +01001332 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001333
1334 /* Make sure hardware complete it */
1335 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001336 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001337
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001338 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001339}
1340
1341static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1342{
1343 u32 val;
1344 unsigned long flag;
1345
David Woodhouse9af88142009-02-13 23:18:03 +00001346 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001347 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001348
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001349 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001350 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001351
1352 /* Make sure hardware complete it */
1353 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001354 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001355
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001356 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001357}
1358
1359/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001360static void __iommu_flush_context(struct intel_iommu *iommu,
1361 u16 did, u16 source_id, u8 function_mask,
1362 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001363{
1364 u64 val = 0;
1365 unsigned long flag;
1366
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001367 switch (type) {
1368 case DMA_CCMD_GLOBAL_INVL:
1369 val = DMA_CCMD_GLOBAL_INVL;
1370 break;
1371 case DMA_CCMD_DOMAIN_INVL:
1372 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1373 break;
1374 case DMA_CCMD_DEVICE_INVL:
1375 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1376 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1377 break;
1378 default:
1379 BUG();
1380 }
1381 val |= DMA_CCMD_ICC;
1382
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001383 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001384 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1385
1386 /* Make sure hardware complete it */
1387 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1388 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1389
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001390 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001391}
1392
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001393/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001394static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1395 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001396{
1397 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1398 u64 val = 0, val_iva = 0;
1399 unsigned long flag;
1400
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001401 switch (type) {
1402 case DMA_TLB_GLOBAL_FLUSH:
1403 /* global flush doesn't need set IVA_REG */
1404 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1405 break;
1406 case DMA_TLB_DSI_FLUSH:
1407 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1408 break;
1409 case DMA_TLB_PSI_FLUSH:
1410 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001411 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001412 val_iva = size_order | addr;
1413 break;
1414 default:
1415 BUG();
1416 }
1417 /* Note: set drain read/write */
1418#if 0
1419 /*
1420 * This is probably to be super secure.. Looks like we can
1421 * ignore it without any impact.
1422 */
1423 if (cap_read_drain(iommu->cap))
1424 val |= DMA_TLB_READ_DRAIN;
1425#endif
1426 if (cap_write_drain(iommu->cap))
1427 val |= DMA_TLB_WRITE_DRAIN;
1428
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001429 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001430 /* Note: Only uses first TLB reg currently */
1431 if (val_iva)
1432 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1433 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1434
1435 /* Make sure hardware complete it */
1436 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1437 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1438
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001439 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001440
1441 /* check IOTLB invalidation granularity */
1442 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001443 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001444 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001445 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001446 (unsigned long long)DMA_TLB_IIRG(type),
1447 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001448}
1449
David Woodhouse64ae8922014-03-09 12:52:30 -07001450static struct device_domain_info *
1451iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1452 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001453{
Yu Zhao93a23a72009-05-18 13:51:37 +08001454 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001455
Joerg Roedel55d94042015-07-22 16:50:40 +02001456 assert_spin_locked(&device_domain_lock);
1457
Yu Zhao93a23a72009-05-18 13:51:37 +08001458 if (!iommu->qi)
1459 return NULL;
1460
Yu Zhao93a23a72009-05-18 13:51:37 +08001461 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001462 if (info->iommu == iommu && info->bus == bus &&
1463 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001464 if (info->ats_supported && info->dev)
1465 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001466 break;
1467 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001468
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001469 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001470}
1471
Omer Peleg0824c592016-04-20 19:03:35 +03001472static void domain_update_iotlb(struct dmar_domain *domain)
1473{
1474 struct device_domain_info *info;
1475 bool has_iotlb_device = false;
1476
1477 assert_spin_locked(&device_domain_lock);
1478
1479 list_for_each_entry(info, &domain->devices, link) {
1480 struct pci_dev *pdev;
1481
1482 if (!info->dev || !dev_is_pci(info->dev))
1483 continue;
1484
1485 pdev = to_pci_dev(info->dev);
1486 if (pdev->ats_enabled) {
1487 has_iotlb_device = true;
1488 break;
1489 }
1490 }
1491
1492 domain->has_iotlb_device = has_iotlb_device;
1493}
1494
Yu Zhao93a23a72009-05-18 13:51:37 +08001495static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1496{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001497 struct pci_dev *pdev;
1498
Omer Peleg0824c592016-04-20 19:03:35 +03001499 assert_spin_locked(&device_domain_lock);
1500
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001501 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001502 return;
1503
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001504 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001505
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001506#ifdef CONFIG_INTEL_IOMMU_SVM
1507 /* The PCIe spec, in its wisdom, declares that the behaviour of
1508 the device if you enable PASID support after ATS support is
1509 undefined. So always enable PASID support on devices which
1510 have it, even if we can't yet know if we're ever going to
1511 use it. */
1512 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1513 info->pasid_enabled = 1;
1514
1515 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1516 info->pri_enabled = 1;
1517#endif
1518 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1519 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001520 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001521 info->ats_qdep = pci_ats_queue_depth(pdev);
1522 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001523}
1524
1525static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1526{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001527 struct pci_dev *pdev;
1528
Omer Peleg0824c592016-04-20 19:03:35 +03001529 assert_spin_locked(&device_domain_lock);
1530
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001531 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001532 return;
1533
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001534 pdev = to_pci_dev(info->dev);
1535
1536 if (info->ats_enabled) {
1537 pci_disable_ats(pdev);
1538 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001539 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001540 }
1541#ifdef CONFIG_INTEL_IOMMU_SVM
1542 if (info->pri_enabled) {
1543 pci_disable_pri(pdev);
1544 info->pri_enabled = 0;
1545 }
1546 if (info->pasid_enabled) {
1547 pci_disable_pasid(pdev);
1548 info->pasid_enabled = 0;
1549 }
1550#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001551}
1552
1553static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1554 u64 addr, unsigned mask)
1555{
1556 u16 sid, qdep;
1557 unsigned long flags;
1558 struct device_domain_info *info;
1559
Omer Peleg0824c592016-04-20 19:03:35 +03001560 if (!domain->has_iotlb_device)
1561 return;
1562
Yu Zhao93a23a72009-05-18 13:51:37 +08001563 spin_lock_irqsave(&device_domain_lock, flags);
1564 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001565 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001566 continue;
1567
1568 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001569 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001570 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1571 }
1572 spin_unlock_irqrestore(&device_domain_lock, flags);
1573}
1574
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001575static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1576 struct dmar_domain *domain,
1577 unsigned long pfn, unsigned int pages,
1578 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001579{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001580 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001581 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001582 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001583
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001584 BUG_ON(pages == 0);
1585
David Woodhouseea8ea462014-03-05 17:09:32 +00001586 if (ih)
1587 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001588 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001589 * Fallback to domain selective flush if no PSI support or the size is
1590 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001591 * PSI requires page size to be 2 ^ x, and the base address is naturally
1592 * aligned to the size
1593 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001594 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1595 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001596 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001597 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001598 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001599 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001600
1601 /*
Nadav Amit82653632010-04-01 13:24:40 +03001602 * In caching mode, changes of pages from non-present to present require
1603 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001604 */
Nadav Amit82653632010-04-01 13:24:40 +03001605 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001606 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001607}
1608
Joerg Roedel13cf0172017-08-11 11:40:10 +02001609static void iommu_flush_iova(struct iova_domain *iovad)
1610{
1611 struct dmar_domain *domain;
1612 int idx;
1613
1614 domain = container_of(iovad, struct dmar_domain, iovad);
1615
1616 for_each_domain_iommu(idx, domain) {
1617 struct intel_iommu *iommu = g_iommus[idx];
1618 u16 did = domain->iommu_did[iommu->seq_id];
1619
1620 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1621
1622 if (!cap_caching_mode(iommu->cap))
1623 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1624 0, MAX_AGAW_PFN_WIDTH);
1625 }
1626}
1627
mark grossf8bab732008-02-08 04:18:38 -08001628static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1629{
1630 u32 pmen;
1631 unsigned long flags;
1632
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001633 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001634 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1635 pmen &= ~DMA_PMEN_EPM;
1636 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1637
1638 /* wait for the protected region status bit to clear */
1639 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1640 readl, !(pmen & DMA_PMEN_PRS), pmen);
1641
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001642 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001643}
1644
Jiang Liu2a41cce2014-07-11 14:19:33 +08001645static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001646{
1647 u32 sts;
1648 unsigned long flags;
1649
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001650 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001651 iommu->gcmd |= DMA_GCMD_TE;
1652 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001653
1654 /* Make sure hardware complete it */
1655 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001656 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001657
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001658 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001659}
1660
Jiang Liu2a41cce2014-07-11 14:19:33 +08001661static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001662{
1663 u32 sts;
1664 unsigned long flag;
1665
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001666 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001667 iommu->gcmd &= ~DMA_GCMD_TE;
1668 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1669
1670 /* Make sure hardware complete it */
1671 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001672 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001673
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001674 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001675}
1676
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001677
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678static int iommu_init_domains(struct intel_iommu *iommu)
1679{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001680 u32 ndomains, nlongs;
1681 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001682
1683 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001684 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001685 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001686 nlongs = BITS_TO_LONGS(ndomains);
1687
Donald Dutile94a91b52009-08-20 16:51:34 -04001688 spin_lock_init(&iommu->lock);
1689
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001690 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1691 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001692 pr_err("%s: Allocating domain id array failed\n",
1693 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001694 return -ENOMEM;
1695 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001696
Wei Yang86f004c2016-05-21 02:41:51 +00001697 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001698 iommu->domains = kzalloc(size, GFP_KERNEL);
1699
1700 if (iommu->domains) {
1701 size = 256 * sizeof(struct dmar_domain *);
1702 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1703 }
1704
1705 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001706 pr_err("%s: Allocating domain array failed\n",
1707 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001708 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001709 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001710 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001711 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001712 return -ENOMEM;
1713 }
1714
Joerg Roedel8bf47812015-07-21 10:41:21 +02001715
1716
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001717 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001718 * If Caching mode is set, then invalid translations are tagged
1719 * with domain-id 0, hence we need to pre-allocate it. We also
1720 * use domain-id 0 as a marker for non-allocated domain-id, so
1721 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001722 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001723 set_bit(0, iommu->domain_ids);
1724
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001725 return 0;
1726}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001727
Jiang Liuffebeb42014-11-09 22:48:02 +08001728static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001729{
Joerg Roedel29a27712015-07-21 17:17:12 +02001730 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001731 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001732
Joerg Roedel29a27712015-07-21 17:17:12 +02001733 if (!iommu->domains || !iommu->domain_ids)
1734 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001735
Joerg Roedelbea64032016-11-08 15:08:26 +01001736again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001737 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001738 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1739 struct dmar_domain *domain;
1740
1741 if (info->iommu != iommu)
1742 continue;
1743
1744 if (!info->dev || !info->domain)
1745 continue;
1746
1747 domain = info->domain;
1748
Joerg Roedelbea64032016-11-08 15:08:26 +01001749 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001750
Joerg Roedelbea64032016-11-08 15:08:26 +01001751 if (!domain_type_is_vm_or_si(domain)) {
1752 /*
1753 * The domain_exit() function can't be called under
1754 * device_domain_lock, as it takes this lock itself.
1755 * So release the lock here and re-run the loop
1756 * afterwards.
1757 */
1758 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001759 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001760 goto again;
1761 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001762 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001763 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001764
1765 if (iommu->gcmd & DMA_GCMD_TE)
1766 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001767}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001768
Jiang Liuffebeb42014-11-09 22:48:02 +08001769static void free_dmar_iommu(struct intel_iommu *iommu)
1770{
1771 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001772 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001773 int i;
1774
1775 for (i = 0; i < elems; i++)
1776 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001777 kfree(iommu->domains);
1778 kfree(iommu->domain_ids);
1779 iommu->domains = NULL;
1780 iommu->domain_ids = NULL;
1781 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001782
Weidong Hand9630fe2008-12-08 11:06:32 +08001783 g_iommus[iommu->seq_id] = NULL;
1784
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001785 /* free context mapping */
1786 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001787
1788#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001789 if (pasid_enabled(iommu)) {
1790 if (ecap_prs(iommu->ecap))
1791 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001792 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001793 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001794#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001795}
1796
Jiang Liuab8dfe22014-07-11 14:19:27 +08001797static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001798{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001799 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800
1801 domain = alloc_domain_mem();
1802 if (!domain)
1803 return NULL;
1804
Jiang Liuab8dfe22014-07-11 14:19:27 +08001805 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001806 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001807 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001808 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001809 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001810
1811 return domain;
1812}
1813
Joerg Roedeld160aca2015-07-22 11:52:53 +02001814/* Must be called with iommu->lock */
1815static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001816 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001817{
Jiang Liu44bde612014-07-11 14:19:29 +08001818 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001819 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001820
Joerg Roedel55d94042015-07-22 16:50:40 +02001821 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001822 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001823
Joerg Roedel29a27712015-07-21 17:17:12 +02001824 domain->iommu_refcnt[iommu->seq_id] += 1;
1825 domain->iommu_count += 1;
1826 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001827 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001828 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1829
1830 if (num >= ndomains) {
1831 pr_err("%s: No free domain ids\n", iommu->name);
1832 domain->iommu_refcnt[iommu->seq_id] -= 1;
1833 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001834 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001835 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001836
Joerg Roedeld160aca2015-07-22 11:52:53 +02001837 set_bit(num, iommu->domain_ids);
1838 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001839
Joerg Roedeld160aca2015-07-22 11:52:53 +02001840 domain->iommu_did[iommu->seq_id] = num;
1841 domain->nid = iommu->node;
1842
Jiang Liufb170fb2014-07-11 14:19:28 +08001843 domain_update_iommu_cap(domain);
1844 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001845
Joerg Roedel55d94042015-07-22 16:50:40 +02001846 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001847}
1848
1849static int domain_detach_iommu(struct dmar_domain *domain,
1850 struct intel_iommu *iommu)
1851{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001852 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001853
Joerg Roedel55d94042015-07-22 16:50:40 +02001854 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001855 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001856
Joerg Roedel29a27712015-07-21 17:17:12 +02001857 domain->iommu_refcnt[iommu->seq_id] -= 1;
1858 count = --domain->iommu_count;
1859 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001860 num = domain->iommu_did[iommu->seq_id];
1861 clear_bit(num, iommu->domain_ids);
1862 set_iommu_domain(iommu, num, NULL);
1863
Jiang Liufb170fb2014-07-11 14:19:28 +08001864 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001865 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001866 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001867
1868 return count;
1869}
1870
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001871static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001872static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001873
Joseph Cihula51a63e62011-03-21 11:04:24 -07001874static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875{
1876 struct pci_dev *pdev = NULL;
1877 struct iova *iova;
1878 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001879
Zhen Leiaa3ac942017-09-21 16:52:45 +01001880 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001881
Mark Gross8a443df2008-03-04 14:59:31 -08001882 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1883 &reserved_rbtree_key);
1884
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001885 /* IOAPIC ranges shouldn't be accessed by DMA */
1886 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1887 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001888 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001889 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001890 return -ENODEV;
1891 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001892
1893 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1894 for_each_pci_dev(pdev) {
1895 struct resource *r;
1896
1897 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1898 r = &pdev->resource[i];
1899 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1900 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001901 iova = reserve_iova(&reserved_iova_list,
1902 IOVA_PFN(r->start),
1903 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001904 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001905 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001906 return -ENODEV;
1907 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001908 }
1909 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001910 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001911}
1912
1913static void domain_reserve_special_ranges(struct dmar_domain *domain)
1914{
1915 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1916}
1917
1918static inline int guestwidth_to_adjustwidth(int gaw)
1919{
1920 int agaw;
1921 int r = (gaw - 12) % 9;
1922
1923 if (r == 0)
1924 agaw = gaw;
1925 else
1926 agaw = gaw + 9 - r;
1927 if (agaw > 64)
1928 agaw = 64;
1929 return agaw;
1930}
1931
Joerg Roedeldc534b22015-07-22 12:44:02 +02001932static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1933 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001934{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001935 int adjust_width, agaw;
1936 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001937 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001938
Zhen Leiaa3ac942017-09-21 16:52:45 +01001939 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001940
1941 err = init_iova_flush_queue(&domain->iovad,
1942 iommu_flush_iova, iova_entry_free);
1943 if (err)
1944 return err;
1945
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946 domain_reserve_special_ranges(domain);
1947
1948 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001949 if (guest_width > cap_mgaw(iommu->cap))
1950 guest_width = cap_mgaw(iommu->cap);
1951 domain->gaw = guest_width;
1952 adjust_width = guestwidth_to_adjustwidth(guest_width);
1953 agaw = width_to_agaw(adjust_width);
1954 sagaw = cap_sagaw(iommu->cap);
1955 if (!test_bit(agaw, &sagaw)) {
1956 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001957 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001958 agaw = find_next_bit(&sagaw, 5, agaw);
1959 if (agaw >= 5)
1960 return -ENODEV;
1961 }
1962 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001963
Weidong Han8e6040972008-12-08 15:49:06 +08001964 if (ecap_coherent(iommu->ecap))
1965 domain->iommu_coherency = 1;
1966 else
1967 domain->iommu_coherency = 0;
1968
Sheng Yang58c610b2009-03-18 15:33:05 +08001969 if (ecap_sc_support(iommu->ecap))
1970 domain->iommu_snooping = 1;
1971 else
1972 domain->iommu_snooping = 0;
1973
David Woodhouse214e39a2014-03-19 10:38:49 +00001974 if (intel_iommu_superpage)
1975 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1976 else
1977 domain->iommu_superpage = 0;
1978
Suresh Siddha4c923d42009-10-02 11:01:24 -07001979 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001980
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001982 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001983 if (!domain->pgd)
1984 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001985 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 return 0;
1987}
1988
1989static void domain_exit(struct dmar_domain *domain)
1990{
David Woodhouseea8ea462014-03-05 17:09:32 +00001991 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001992
1993 /* Domain 0 is reserved, so dont process it */
1994 if (!domain)
1995 return;
1996
Joerg Roedeld160aca2015-07-22 11:52:53 +02001997 /* Remove associated devices and clear attached or cached domains */
1998 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001999 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002000 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002001
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002 /* destroy iovas */
2003 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004
David Woodhouseea8ea462014-03-05 17:09:32 +00002005 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002006
David Woodhouseea8ea462014-03-05 17:09:32 +00002007 dma_free_pagelist(freelist);
2008
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002009 free_domain_mem(domain);
2010}
2011
David Woodhouse64ae8922014-03-09 12:52:30 -07002012static int domain_context_mapping_one(struct dmar_domain *domain,
2013 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002014 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002015{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002016 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002017 int translation = CONTEXT_TT_MULTI_LEVEL;
2018 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002019 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002020 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002021 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002022 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002023
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002024 WARN_ON(did == 0);
2025
Joerg Roedel28ccce02015-07-21 14:45:31 +02002026 if (hw_pass_through && domain_type_is_si(domain))
2027 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002028
2029 pr_debug("Set context mapping for %02x:%02x.%d\n",
2030 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002031
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002032 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002033
Joerg Roedel55d94042015-07-22 16:50:40 +02002034 spin_lock_irqsave(&device_domain_lock, flags);
2035 spin_lock(&iommu->lock);
2036
2037 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002038 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002039 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002040 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002041
Joerg Roedel55d94042015-07-22 16:50:40 +02002042 ret = 0;
2043 if (context_present(context))
2044 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002045
Xunlei Pangaec0e862016-12-05 20:09:07 +08002046 /*
2047 * For kdump cases, old valid entries may be cached due to the
2048 * in-flight DMA and copied pgtable, but there is no unmapping
2049 * behaviour for them, thus we need an explicit cache flush for
2050 * the newly-mapped device. For kdump, at this point, the device
2051 * is supposed to finish reset at its driver probe stage, so no
2052 * in-flight DMA will exist, and we don't need to worry anymore
2053 * hereafter.
2054 */
2055 if (context_copied(context)) {
2056 u16 did_old = context_domain_id(context);
2057
Christos Gkekasb117e032017-10-08 23:33:31 +01002058 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002059 iommu->flush.flush_context(iommu, did_old,
2060 (((u16)bus) << 8) | devfn,
2061 DMA_CCMD_MASK_NOBIT,
2062 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002063 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2064 DMA_TLB_DSI_FLUSH);
2065 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002066 }
2067
Weidong Hanea6606b2008-12-08 23:08:15 +08002068 pgd = domain->pgd;
2069
Joerg Roedelde24e552015-07-21 14:53:04 +02002070 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002071 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002072
Joerg Roedelde24e552015-07-21 14:53:04 +02002073 /*
2074 * Skip top levels of page tables for iommu which has less agaw
2075 * than default. Unnecessary for PT mode.
2076 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002077 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002078 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002079 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002080 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002081 if (!dma_pte_present(pgd))
2082 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002083 }
2084
David Woodhouse64ae8922014-03-09 12:52:30 -07002085 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002086 if (info && info->ats_supported)
2087 translation = CONTEXT_TT_DEV_IOTLB;
2088 else
2089 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002090
Yu Zhao93a23a72009-05-18 13:51:37 +08002091 context_set_address_root(context, virt_to_phys(pgd));
2092 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002093 } else {
2094 /*
2095 * In pass through mode, AW must be programmed to
2096 * indicate the largest AGAW value supported by
2097 * hardware. And ASR is ignored by hardware.
2098 */
2099 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002100 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002101
2102 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002103 context_set_fault_enable(context);
2104 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002105 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002106
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002107 /*
2108 * It's a non-present to present mapping. If hardware doesn't cache
2109 * non-present entry we only need to flush the write-buffer. If the
2110 * _does_ cache non-present entries, then it does so in the special
2111 * domain #0, which we have to flush:
2112 */
2113 if (cap_caching_mode(iommu->cap)) {
2114 iommu->flush.flush_context(iommu, 0,
2115 (((u16)bus) << 8) | devfn,
2116 DMA_CCMD_MASK_NOBIT,
2117 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002118 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002119 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002120 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002121 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002122 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002123
Joerg Roedel55d94042015-07-22 16:50:40 +02002124 ret = 0;
2125
2126out_unlock:
2127 spin_unlock(&iommu->lock);
2128 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002129
Wei Yang5c365d12016-07-13 13:53:21 +00002130 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002131}
2132
Alex Williamson579305f2014-07-03 09:51:43 -06002133struct domain_context_mapping_data {
2134 struct dmar_domain *domain;
2135 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002136};
2137
2138static int domain_context_mapping_cb(struct pci_dev *pdev,
2139 u16 alias, void *opaque)
2140{
2141 struct domain_context_mapping_data *data = opaque;
2142
2143 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002144 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002145}
2146
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002147static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002148domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002149{
David Woodhouse64ae8922014-03-09 12:52:30 -07002150 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002151 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002152 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002153
David Woodhousee1f167f2014-03-09 15:24:46 -07002154 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002155 if (!iommu)
2156 return -ENODEV;
2157
Alex Williamson579305f2014-07-03 09:51:43 -06002158 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002159 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002160
2161 data.domain = domain;
2162 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002163
2164 return pci_for_each_dma_alias(to_pci_dev(dev),
2165 &domain_context_mapping_cb, &data);
2166}
2167
2168static int domain_context_mapped_cb(struct pci_dev *pdev,
2169 u16 alias, void *opaque)
2170{
2171 struct intel_iommu *iommu = opaque;
2172
2173 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002174}
2175
David Woodhousee1f167f2014-03-09 15:24:46 -07002176static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002177{
Weidong Han5331fe62008-12-08 23:00:00 +08002178 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002179 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002180
David Woodhousee1f167f2014-03-09 15:24:46 -07002181 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002182 if (!iommu)
2183 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002184
Alex Williamson579305f2014-07-03 09:51:43 -06002185 if (!dev_is_pci(dev))
2186 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002187
Alex Williamson579305f2014-07-03 09:51:43 -06002188 return !pci_for_each_dma_alias(to_pci_dev(dev),
2189 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002190}
2191
Fenghua Yuf5329592009-08-04 15:09:37 -07002192/* Returns a number of VTD pages, but aligned to MM page size */
2193static inline unsigned long aligned_nrpages(unsigned long host_addr,
2194 size_t size)
2195{
2196 host_addr &= ~PAGE_MASK;
2197 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2198}
2199
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002200/* Return largest possible superpage level for a given mapping */
2201static inline int hardware_largepage_caps(struct dmar_domain *domain,
2202 unsigned long iov_pfn,
2203 unsigned long phy_pfn,
2204 unsigned long pages)
2205{
2206 int support, level = 1;
2207 unsigned long pfnmerge;
2208
2209 support = domain->iommu_superpage;
2210
2211 /* To use a large page, the virtual *and* physical addresses
2212 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2213 of them will mean we have to use smaller pages. So just
2214 merge them and check both at once. */
2215 pfnmerge = iov_pfn | phy_pfn;
2216
2217 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2218 pages >>= VTD_STRIDE_SHIFT;
2219 if (!pages)
2220 break;
2221 pfnmerge >>= VTD_STRIDE_SHIFT;
2222 level++;
2223 support--;
2224 }
2225 return level;
2226}
2227
David Woodhouse9051aa02009-06-29 12:30:54 +01002228static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2229 struct scatterlist *sg, unsigned long phys_pfn,
2230 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002231{
2232 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002233 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002234 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002235 unsigned int largepage_lvl = 0;
2236 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002237
Jiang Liu162d1b12014-07-11 14:19:35 +08002238 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002239
2240 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2241 return -EINVAL;
2242
2243 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2244
Jiang Liucc4f14a2014-11-26 09:42:10 +08002245 if (!sg) {
2246 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002247 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2248 }
2249
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002250 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002251 uint64_t tmp;
2252
David Woodhousee1605492009-06-29 11:17:38 +01002253 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002254 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2255
Fenghua Yuf5329592009-08-04 15:09:37 -07002256 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002257 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002258 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002259 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002260 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002261 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262
David Woodhousee1605492009-06-29 11:17:38 +01002263 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002264 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2265
David Woodhouse5cf0a762014-03-19 16:07:49 +00002266 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002267 if (!pte)
2268 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002269 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002270 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002271 unsigned long nr_superpages, end_pfn;
2272
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002273 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002274 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002275
2276 nr_superpages = sg_res / lvl_pages;
2277 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2278
Jiang Liud41a4ad2014-07-11 14:19:34 +08002279 /*
2280 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002281 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002282 * We're adding new large pages, so make sure
2283 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002284 */
David Dillowbc24c572017-06-28 19:42:23 -07002285 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2286 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002287 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002288 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002289 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002290
David Woodhousee1605492009-06-29 11:17:38 +01002291 }
2292 /* We don't need lock here, nobody else
2293 * touches the iova range
2294 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002295 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002296 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002297 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002298 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2299 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002300 if (dumps) {
2301 dumps--;
2302 debug_dma_dump_mappings(NULL);
2303 }
2304 WARN_ON(1);
2305 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002306
2307 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2308
2309 BUG_ON(nr_pages < lvl_pages);
2310 BUG_ON(sg_res < lvl_pages);
2311
2312 nr_pages -= lvl_pages;
2313 iov_pfn += lvl_pages;
2314 phys_pfn += lvl_pages;
2315 pteval += lvl_pages * VTD_PAGE_SIZE;
2316 sg_res -= lvl_pages;
2317
2318 /* If the next PTE would be the first in a new page, then we
2319 need to flush the cache on the entries we've just written.
2320 And then we'll need to recalculate 'pte', so clear it and
2321 let it get set again in the if (!pte) block above.
2322
2323 If we're done (!nr_pages) we need to flush the cache too.
2324
2325 Also if we've been setting superpages, we may need to
2326 recalculate 'pte' and switch back to smaller pages for the
2327 end of the mapping, if the trailing size is not enough to
2328 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002329 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002330 if (!nr_pages || first_pte_in_page(pte) ||
2331 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002332 domain_flush_cache(domain, first_pte,
2333 (void *)pte - (void *)first_pte);
2334 pte = NULL;
2335 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002336
2337 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002338 sg = sg_next(sg);
2339 }
2340 return 0;
2341}
2342
David Woodhouse9051aa02009-06-29 12:30:54 +01002343static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2344 struct scatterlist *sg, unsigned long nr_pages,
2345 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002346{
David Woodhouse9051aa02009-06-29 12:30:54 +01002347 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2348}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002349
David Woodhouse9051aa02009-06-29 12:30:54 +01002350static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2351 unsigned long phys_pfn, unsigned long nr_pages,
2352 int prot)
2353{
2354 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002355}
2356
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002357static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002358{
Filippo Sironi50822192017-08-31 10:58:11 +02002359 unsigned long flags;
2360 struct context_entry *context;
2361 u16 did_old;
2362
Weidong Hanc7151a82008-12-08 22:51:37 +08002363 if (!iommu)
2364 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002365
Filippo Sironi50822192017-08-31 10:58:11 +02002366 spin_lock_irqsave(&iommu->lock, flags);
2367 context = iommu_context_addr(iommu, bus, devfn, 0);
2368 if (!context) {
2369 spin_unlock_irqrestore(&iommu->lock, flags);
2370 return;
2371 }
2372 did_old = context_domain_id(context);
2373 context_clear_entry(context);
2374 __iommu_flush_cache(iommu, context, sizeof(*context));
2375 spin_unlock_irqrestore(&iommu->lock, flags);
2376 iommu->flush.flush_context(iommu,
2377 did_old,
2378 (((u16)bus) << 8) | devfn,
2379 DMA_CCMD_MASK_NOBIT,
2380 DMA_CCMD_DEVICE_INVL);
2381 iommu->flush.flush_iotlb(iommu,
2382 did_old,
2383 0,
2384 0,
2385 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002386}
2387
David Woodhouse109b9b02012-05-25 17:43:02 +01002388static inline void unlink_domain_info(struct device_domain_info *info)
2389{
2390 assert_spin_locked(&device_domain_lock);
2391 list_del(&info->link);
2392 list_del(&info->global);
2393 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002394 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002395}
2396
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002397static void domain_remove_dev_info(struct dmar_domain *domain)
2398{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002399 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002400 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002401
2402 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002403 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002404 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002405 spin_unlock_irqrestore(&device_domain_lock, flags);
2406}
2407
2408/*
2409 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002410 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002411 */
David Woodhouse1525a292014-03-06 16:19:30 +00002412static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002413{
2414 struct device_domain_info *info;
2415
2416 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002417 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002418 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002419 return info->domain;
2420 return NULL;
2421}
2422
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002423static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002424dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2425{
2426 struct device_domain_info *info;
2427
2428 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002429 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002430 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002431 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002432
2433 return NULL;
2434}
2435
Joerg Roedel5db31562015-07-22 12:40:43 +02002436static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2437 int bus, int devfn,
2438 struct device *dev,
2439 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002440{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002441 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002442 struct device_domain_info *info;
2443 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002444 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002445
2446 info = alloc_devinfo_mem();
2447 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002448 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002449
Jiang Liu745f2582014-02-19 14:07:26 +08002450 info->bus = bus;
2451 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002452 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2453 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2454 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002455 info->dev = dev;
2456 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002457 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002458
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002459 if (dev && dev_is_pci(dev)) {
2460 struct pci_dev *pdev = to_pci_dev(info->dev);
2461
Gil Kupfercef74402018-05-10 17:56:02 -05002462 if (!pci_ats_disabled() &&
2463 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002464 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2465 dmar_find_matched_atsr_unit(pdev))
2466 info->ats_supported = 1;
2467
2468 if (ecs_enabled(iommu)) {
2469 if (pasid_enabled(iommu)) {
2470 int features = pci_pasid_features(pdev);
2471 if (features >= 0)
2472 info->pasid_supported = features | 1;
2473 }
2474
2475 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2476 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2477 info->pri_supported = 1;
2478 }
2479 }
2480
Jiang Liu745f2582014-02-19 14:07:26 +08002481 spin_lock_irqsave(&device_domain_lock, flags);
2482 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002483 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002484
2485 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002486 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002487 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002488 if (info2) {
2489 found = info2->domain;
2490 info2->dev = dev;
2491 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002492 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002493
Jiang Liu745f2582014-02-19 14:07:26 +08002494 if (found) {
2495 spin_unlock_irqrestore(&device_domain_lock, flags);
2496 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002497 /* Caller must free the original domain */
2498 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002499 }
2500
Joerg Roedeld160aca2015-07-22 11:52:53 +02002501 spin_lock(&iommu->lock);
2502 ret = domain_attach_iommu(domain, iommu);
2503 spin_unlock(&iommu->lock);
2504
2505 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002506 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302507 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002508 return NULL;
2509 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002510
David Woodhouseb718cd32014-03-09 13:11:33 -07002511 list_add(&info->link, &domain->devices);
2512 list_add(&info->global, &device_domain_list);
2513 if (dev)
2514 dev->archdata.iommu = info;
2515 spin_unlock_irqrestore(&device_domain_lock, flags);
2516
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002517 if (dev && domain_context_mapping(domain, dev)) {
2518 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002519 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002520 return NULL;
2521 }
2522
David Woodhouseb718cd32014-03-09 13:11:33 -07002523 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002524}
2525
Alex Williamson579305f2014-07-03 09:51:43 -06002526static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2527{
2528 *(u16 *)opaque = alias;
2529 return 0;
2530}
2531
Joerg Roedel76208352016-08-25 14:25:12 +02002532static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002533{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002534 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002535 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002536 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002537 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002538 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002539 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002540
David Woodhouse146922e2014-03-09 15:44:17 -07002541 iommu = device_to_iommu(dev, &bus, &devfn);
2542 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002543 return NULL;
2544
Joerg Roedel08a7f452015-07-23 18:09:11 +02002545 req_id = ((u16)bus << 8) | devfn;
2546
Alex Williamson579305f2014-07-03 09:51:43 -06002547 if (dev_is_pci(dev)) {
2548 struct pci_dev *pdev = to_pci_dev(dev);
2549
2550 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2551
2552 spin_lock_irqsave(&device_domain_lock, flags);
2553 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2554 PCI_BUS_NUM(dma_alias),
2555 dma_alias & 0xff);
2556 if (info) {
2557 iommu = info->iommu;
2558 domain = info->domain;
2559 }
2560 spin_unlock_irqrestore(&device_domain_lock, flags);
2561
Joerg Roedel76208352016-08-25 14:25:12 +02002562 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002563 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002564 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002565 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002566
David Woodhouse146922e2014-03-09 15:44:17 -07002567 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002568 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002569 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002570 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002571 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002572 domain_exit(domain);
2573 return NULL;
2574 }
2575
Joerg Roedel76208352016-08-25 14:25:12 +02002576out:
Alex Williamson579305f2014-07-03 09:51:43 -06002577
Joerg Roedel76208352016-08-25 14:25:12 +02002578 return domain;
2579}
2580
2581static struct dmar_domain *set_domain_for_dev(struct device *dev,
2582 struct dmar_domain *domain)
2583{
2584 struct intel_iommu *iommu;
2585 struct dmar_domain *tmp;
2586 u16 req_id, dma_alias;
2587 u8 bus, devfn;
2588
2589 iommu = device_to_iommu(dev, &bus, &devfn);
2590 if (!iommu)
2591 return NULL;
2592
2593 req_id = ((u16)bus << 8) | devfn;
2594
2595 if (dev_is_pci(dev)) {
2596 struct pci_dev *pdev = to_pci_dev(dev);
2597
2598 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2599
2600 /* register PCI DMA alias device */
2601 if (req_id != dma_alias) {
2602 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2603 dma_alias & 0xff, NULL, domain);
2604
2605 if (!tmp || tmp != domain)
2606 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002607 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002608 }
2609
Joerg Roedel5db31562015-07-22 12:40:43 +02002610 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002611 if (!tmp || tmp != domain)
2612 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002613
Joerg Roedel76208352016-08-25 14:25:12 +02002614 return domain;
2615}
2616
2617static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2618{
2619 struct dmar_domain *domain, *tmp;
2620
2621 domain = find_domain(dev);
2622 if (domain)
2623 goto out;
2624
2625 domain = find_or_alloc_domain(dev, gaw);
2626 if (!domain)
2627 goto out;
2628
2629 tmp = set_domain_for_dev(dev, domain);
2630 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002631 domain_exit(domain);
2632 domain = tmp;
2633 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002634
Joerg Roedel76208352016-08-25 14:25:12 +02002635out:
2636
David Woodhouseb718cd32014-03-09 13:11:33 -07002637 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002638}
2639
David Woodhouseb2132032009-06-26 18:50:28 +01002640static int iommu_domain_identity_map(struct dmar_domain *domain,
2641 unsigned long long start,
2642 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002643{
David Woodhousec5395d52009-06-28 16:35:56 +01002644 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2645 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002646
David Woodhousec5395d52009-06-28 16:35:56 +01002647 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2648 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002649 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002650 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002651 }
2652
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002653 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002654 /*
2655 * RMRR range might have overlap with physical memory range,
2656 * clear it first
2657 */
David Woodhousec5395d52009-06-28 16:35:56 +01002658 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002659
David Woodhousec5395d52009-06-28 16:35:56 +01002660 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2661 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002662 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002663}
2664
Joerg Roedeld66ce542015-09-23 19:00:10 +02002665static int domain_prepare_identity_map(struct device *dev,
2666 struct dmar_domain *domain,
2667 unsigned long long start,
2668 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002669{
David Woodhouse19943b02009-08-04 16:19:20 +01002670 /* For _hardware_ passthrough, don't bother. But for software
2671 passthrough, we do it anyway -- it may indicate a memory
2672 range which is reserved in E820, so which didn't get set
2673 up to start with in si_domain */
2674 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002675 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2676 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002677 return 0;
2678 }
2679
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002680 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2681 dev_name(dev), start, end);
2682
David Woodhouse5595b522009-12-02 09:21:55 +00002683 if (end < start) {
2684 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2685 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2686 dmi_get_system_info(DMI_BIOS_VENDOR),
2687 dmi_get_system_info(DMI_BIOS_VERSION),
2688 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002689 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002690 }
2691
David Woodhouse2ff729f2009-08-26 14:25:41 +01002692 if (end >> agaw_to_width(domain->agaw)) {
2693 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2694 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2695 agaw_to_width(domain->agaw),
2696 dmi_get_system_info(DMI_BIOS_VENDOR),
2697 dmi_get_system_info(DMI_BIOS_VERSION),
2698 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002699 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002700 }
David Woodhouse19943b02009-08-04 16:19:20 +01002701
Joerg Roedeld66ce542015-09-23 19:00:10 +02002702 return iommu_domain_identity_map(domain, start, end);
2703}
2704
2705static int iommu_prepare_identity_map(struct device *dev,
2706 unsigned long long start,
2707 unsigned long long end)
2708{
2709 struct dmar_domain *domain;
2710 int ret;
2711
2712 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2713 if (!domain)
2714 return -ENOMEM;
2715
2716 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002717 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002718 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002719
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002720 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002721}
2722
2723static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002724 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002725{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002726 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002727 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002728 return iommu_prepare_identity_map(dev, rmrr->base_address,
2729 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002730}
2731
Suresh Siddhad3f13812011-08-23 17:05:25 -07002732#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002733static inline void iommu_prepare_isa(void)
2734{
2735 struct pci_dev *pdev;
2736 int ret;
2737
2738 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2739 if (!pdev)
2740 return;
2741
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002742 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002743 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002744
2745 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002746 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002747
Yijing Wang9b27e822014-05-20 20:37:52 +08002748 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002749}
2750#else
2751static inline void iommu_prepare_isa(void)
2752{
2753 return;
2754}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002755#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002756
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002757static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002758
Matt Kraai071e1372009-08-23 22:30:22 -07002759static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002760{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002761 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002762
Jiang Liuab8dfe22014-07-11 14:19:27 +08002763 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002764 if (!si_domain)
2765 return -EFAULT;
2766
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002767 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2768 domain_exit(si_domain);
2769 return -EFAULT;
2770 }
2771
Joerg Roedel0dc79712015-07-21 15:40:06 +02002772 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002773
David Woodhouse19943b02009-08-04 16:19:20 +01002774 if (hw)
2775 return 0;
2776
David Woodhousec7ab48d2009-06-26 19:10:36 +01002777 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002778 unsigned long start_pfn, end_pfn;
2779 int i;
2780
2781 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2782 ret = iommu_domain_identity_map(si_domain,
2783 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2784 if (ret)
2785 return ret;
2786 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002787 }
2788
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002789 return 0;
2790}
2791
David Woodhouse9b226622014-03-09 14:03:28 -07002792static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002793{
2794 struct device_domain_info *info;
2795
2796 if (likely(!iommu_identity_mapping))
2797 return 0;
2798
David Woodhouse9b226622014-03-09 14:03:28 -07002799 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002800 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2801 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002802
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002803 return 0;
2804}
2805
Joerg Roedel28ccce02015-07-21 14:45:31 +02002806static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002807{
David Woodhouse0ac72662014-03-09 13:19:22 -07002808 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002809 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002810 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002811
David Woodhouse5913c9b2014-03-09 16:27:31 -07002812 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002813 if (!iommu)
2814 return -ENODEV;
2815
Joerg Roedel5db31562015-07-22 12:40:43 +02002816 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002817 if (ndomain != domain)
2818 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002819
2820 return 0;
2821}
2822
David Woodhouse0b9d9752014-03-09 15:48:15 -07002823static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002824{
2825 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002826 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002827 int i;
2828
Jiang Liu0e242612014-02-19 14:07:34 +08002829 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002830 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002831 /*
2832 * Return TRUE if this RMRR contains the device that
2833 * is passed in.
2834 */
2835 for_each_active_dev_scope(rmrr->devices,
2836 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002837 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002838 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002839 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002840 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002841 }
Jiang Liu0e242612014-02-19 14:07:34 +08002842 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002843 return false;
2844}
2845
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002846/*
2847 * There are a couple cases where we need to restrict the functionality of
2848 * devices associated with RMRRs. The first is when evaluating a device for
2849 * identity mapping because problems exist when devices are moved in and out
2850 * of domains and their respective RMRR information is lost. This means that
2851 * a device with associated RMRRs will never be in a "passthrough" domain.
2852 * The second is use of the device through the IOMMU API. This interface
2853 * expects to have full control of the IOVA space for the device. We cannot
2854 * satisfy both the requirement that RMRR access is maintained and have an
2855 * unencumbered IOVA space. We also have no ability to quiesce the device's
2856 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2857 * We therefore prevent devices associated with an RMRR from participating in
2858 * the IOMMU API, which eliminates them from device assignment.
2859 *
2860 * In both cases we assume that PCI USB devices with RMRRs have them largely
2861 * for historical reasons and that the RMRR space is not actively used post
2862 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002863 *
2864 * The same exception is made for graphics devices, with the requirement that
2865 * any use of the RMRR regions will be torn down before assigning the device
2866 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002867 */
2868static bool device_is_rmrr_locked(struct device *dev)
2869{
2870 if (!device_has_rmrr(dev))
2871 return false;
2872
2873 if (dev_is_pci(dev)) {
2874 struct pci_dev *pdev = to_pci_dev(dev);
2875
David Woodhouse18436af2015-03-25 15:05:47 +00002876 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002877 return false;
2878 }
2879
2880 return true;
2881}
2882
David Woodhouse3bdb2592014-03-09 16:03:08 -07002883static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002884{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002885
David Woodhouse3bdb2592014-03-09 16:03:08 -07002886 if (dev_is_pci(dev)) {
2887 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002888
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002889 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002890 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002891
David Woodhouse3bdb2592014-03-09 16:03:08 -07002892 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2893 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002894
David Woodhouse3bdb2592014-03-09 16:03:08 -07002895 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2896 return 1;
2897
2898 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2899 return 0;
2900
2901 /*
2902 * We want to start off with all devices in the 1:1 domain, and
2903 * take them out later if we find they can't access all of memory.
2904 *
2905 * However, we can't do this for PCI devices behind bridges,
2906 * because all PCI devices behind the same bridge will end up
2907 * with the same source-id on their transactions.
2908 *
2909 * Practically speaking, we can't change things around for these
2910 * devices at run-time, because we can't be sure there'll be no
2911 * DMA transactions in flight for any of their siblings.
2912 *
2913 * So PCI devices (unless they're on the root bus) as well as
2914 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2915 * the 1:1 domain, just in _case_ one of their siblings turns out
2916 * not to be able to map all of memory.
2917 */
2918 if (!pci_is_pcie(pdev)) {
2919 if (!pci_is_root_bus(pdev->bus))
2920 return 0;
2921 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2922 return 0;
2923 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2924 return 0;
2925 } else {
2926 if (device_has_rmrr(dev))
2927 return 0;
2928 }
David Woodhouse6941af22009-07-04 18:24:27 +01002929
David Woodhouse3dfc8132009-07-04 19:11:08 +01002930 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002931 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002932 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002933 * take them out of the 1:1 domain later.
2934 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002935 if (!startup) {
2936 /*
2937 * If the device's dma_mask is less than the system's memory
2938 * size then this is not a candidate for identity mapping.
2939 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002940 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002941
David Woodhouse3bdb2592014-03-09 16:03:08 -07002942 if (dev->coherent_dma_mask &&
2943 dev->coherent_dma_mask < dma_mask)
2944 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002945
David Woodhouse3bdb2592014-03-09 16:03:08 -07002946 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002947 }
David Woodhouse6941af22009-07-04 18:24:27 +01002948
2949 return 1;
2950}
2951
David Woodhousecf04eee2014-03-21 16:49:04 +00002952static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2953{
2954 int ret;
2955
2956 if (!iommu_should_identity_map(dev, 1))
2957 return 0;
2958
Joerg Roedel28ccce02015-07-21 14:45:31 +02002959 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002960 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002961 pr_info("%s identity mapping for device %s\n",
2962 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002963 else if (ret == -ENODEV)
2964 /* device not associated with an iommu */
2965 ret = 0;
2966
2967 return ret;
2968}
2969
2970
Matt Kraai071e1372009-08-23 22:30:22 -07002971static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002972{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002973 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002974 struct dmar_drhd_unit *drhd;
2975 struct intel_iommu *iommu;
2976 struct device *dev;
2977 int i;
2978 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002979
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002980 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002981 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2982 if (ret)
2983 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002984 }
2985
David Woodhousecf04eee2014-03-21 16:49:04 +00002986 for_each_active_iommu(iommu, drhd)
2987 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2988 struct acpi_device_physical_node *pn;
2989 struct acpi_device *adev;
2990
2991 if (dev->bus != &acpi_bus_type)
2992 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002993
David Woodhousecf04eee2014-03-21 16:49:04 +00002994 adev= to_acpi_device(dev);
2995 mutex_lock(&adev->physical_node_lock);
2996 list_for_each_entry(pn, &adev->physical_node_list, node) {
2997 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2998 if (ret)
2999 break;
3000 }
3001 mutex_unlock(&adev->physical_node_lock);
3002 if (ret)
3003 return ret;
3004 }
3005
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003006 return 0;
3007}
3008
Jiang Liuffebeb42014-11-09 22:48:02 +08003009static void intel_iommu_init_qi(struct intel_iommu *iommu)
3010{
3011 /*
3012 * Start from the sane iommu hardware state.
3013 * If the queued invalidation is already initialized by us
3014 * (for example, while enabling interrupt-remapping) then
3015 * we got the things already rolling from a sane state.
3016 */
3017 if (!iommu->qi) {
3018 /*
3019 * Clear any previous faults.
3020 */
3021 dmar_fault(-1, iommu);
3022 /*
3023 * Disable queued invalidation if supported and already enabled
3024 * before OS handover.
3025 */
3026 dmar_disable_qi(iommu);
3027 }
3028
3029 if (dmar_enable_qi(iommu)) {
3030 /*
3031 * Queued Invalidate not enabled, use Register Based Invalidate
3032 */
3033 iommu->flush.flush_context = __iommu_flush_context;
3034 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003035 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003036 iommu->name);
3037 } else {
3038 iommu->flush.flush_context = qi_flush_context;
3039 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003040 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003041 }
3042}
3043
Joerg Roedel091d42e2015-06-12 11:56:10 +02003044static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003045 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003046 struct context_entry **tbl,
3047 int bus, bool ext)
3048{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003049 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003050 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003051 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003052 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003053 phys_addr_t old_ce_phys;
3054
3055 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003056 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003057
3058 for (devfn = 0; devfn < 256; devfn++) {
3059 /* First calculate the correct index */
3060 idx = (ext ? devfn * 2 : devfn) % 256;
3061
3062 if (idx == 0) {
3063 /* First save what we may have and clean up */
3064 if (new_ce) {
3065 tbl[tbl_idx] = new_ce;
3066 __iommu_flush_cache(iommu, new_ce,
3067 VTD_PAGE_SIZE);
3068 pos = 1;
3069 }
3070
3071 if (old_ce)
3072 iounmap(old_ce);
3073
3074 ret = 0;
3075 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003076 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003077 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003078 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003079
3080 if (!old_ce_phys) {
3081 if (ext && devfn == 0) {
3082 /* No LCTP, try UCTP */
3083 devfn = 0x7f;
3084 continue;
3085 } else {
3086 goto out;
3087 }
3088 }
3089
3090 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003091 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3092 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003093 if (!old_ce)
3094 goto out;
3095
3096 new_ce = alloc_pgtable_page(iommu->node);
3097 if (!new_ce)
3098 goto out_unmap;
3099
3100 ret = 0;
3101 }
3102
3103 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003104 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003105
Joerg Roedelcf484d02015-06-12 12:21:46 +02003106 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003107 continue;
3108
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003109 did = context_domain_id(&ce);
3110 if (did >= 0 && did < cap_ndoms(iommu->cap))
3111 set_bit(did, iommu->domain_ids);
3112
Joerg Roedelcf484d02015-06-12 12:21:46 +02003113 /*
3114 * We need a marker for copied context entries. This
3115 * marker needs to work for the old format as well as
3116 * for extended context entries.
3117 *
3118 * Bit 67 of the context entry is used. In the old
3119 * format this bit is available to software, in the
3120 * extended format it is the PGE bit, but PGE is ignored
3121 * by HW if PASIDs are disabled (and thus still
3122 * available).
3123 *
3124 * So disable PASIDs first and then mark the entry
3125 * copied. This means that we don't copy PASID
3126 * translations from the old kernel, but this is fine as
3127 * faults there are not fatal.
3128 */
3129 context_clear_pasid_enable(&ce);
3130 context_set_copied(&ce);
3131
Joerg Roedel091d42e2015-06-12 11:56:10 +02003132 new_ce[idx] = ce;
3133 }
3134
3135 tbl[tbl_idx + pos] = new_ce;
3136
3137 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3138
3139out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003140 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003141
3142out:
3143 return ret;
3144}
3145
3146static int copy_translation_tables(struct intel_iommu *iommu)
3147{
3148 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003149 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003150 phys_addr_t old_rt_phys;
3151 int ctxt_table_entries;
3152 unsigned long flags;
3153 u64 rtaddr_reg;
3154 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003155 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003156
3157 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3158 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003159 new_ext = !!ecap_ecs(iommu->ecap);
3160
3161 /*
3162 * The RTT bit can only be changed when translation is disabled,
3163 * but disabling translation means to open a window for data
3164 * corruption. So bail out and don't copy anything if we would
3165 * have to change the bit.
3166 */
3167 if (new_ext != ext)
3168 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003169
3170 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3171 if (!old_rt_phys)
3172 return -EINVAL;
3173
Dan Williamsdfddb9692015-10-09 18:16:46 -04003174 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003175 if (!old_rt)
3176 return -ENOMEM;
3177
3178 /* This is too big for the stack - allocate it from slab */
3179 ctxt_table_entries = ext ? 512 : 256;
3180 ret = -ENOMEM;
3181 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3182 if (!ctxt_tbls)
3183 goto out_unmap;
3184
3185 for (bus = 0; bus < 256; bus++) {
3186 ret = copy_context_table(iommu, &old_rt[bus],
3187 ctxt_tbls, bus, ext);
3188 if (ret) {
3189 pr_err("%s: Failed to copy context table for bus %d\n",
3190 iommu->name, bus);
3191 continue;
3192 }
3193 }
3194
3195 spin_lock_irqsave(&iommu->lock, flags);
3196
3197 /* Context tables are copied, now write them to the root_entry table */
3198 for (bus = 0; bus < 256; bus++) {
3199 int idx = ext ? bus * 2 : bus;
3200 u64 val;
3201
3202 if (ctxt_tbls[idx]) {
3203 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3204 iommu->root_entry[bus].lo = val;
3205 }
3206
3207 if (!ext || !ctxt_tbls[idx + 1])
3208 continue;
3209
3210 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3211 iommu->root_entry[bus].hi = val;
3212 }
3213
3214 spin_unlock_irqrestore(&iommu->lock, flags);
3215
3216 kfree(ctxt_tbls);
3217
3218 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3219
3220 ret = 0;
3221
3222out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003223 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003224
3225 return ret;
3226}
3227
Joseph Cihulab7792602011-05-03 00:08:37 -07003228static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003229{
3230 struct dmar_drhd_unit *drhd;
3231 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003232 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003233 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003234 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003235 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003236
3237 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003238 * for each drhd
3239 * allocate root
3240 * initialize and program root entry to not present
3241 * endfor
3242 */
3243 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003244 /*
3245 * lock not needed as this is only incremented in the single
3246 * threaded kernel __init code path all other access are read
3247 * only
3248 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003249 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003250 g_num_of_iommus++;
3251 continue;
3252 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003253 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003254 }
3255
Jiang Liuffebeb42014-11-09 22:48:02 +08003256 /* Preallocate enough resources for IOMMU hot-addition */
3257 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3258 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3259
Weidong Hand9630fe2008-12-08 11:06:32 +08003260 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3261 GFP_KERNEL);
3262 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003263 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003264 ret = -ENOMEM;
3265 goto error;
3266 }
3267
Jiang Liu7c919772014-01-06 14:18:18 +08003268 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003269 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003270
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003271 intel_iommu_init_qi(iommu);
3272
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003273 ret = iommu_init_domains(iommu);
3274 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003275 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003276
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003277 init_translation_status(iommu);
3278
Joerg Roedel091d42e2015-06-12 11:56:10 +02003279 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3280 iommu_disable_translation(iommu);
3281 clear_translation_pre_enabled(iommu);
3282 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3283 iommu->name);
3284 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003285
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003286 /*
3287 * TBD:
3288 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003289 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003290 */
3291 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003292 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003293 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003294
Joerg Roedel091d42e2015-06-12 11:56:10 +02003295 if (translation_pre_enabled(iommu)) {
3296 pr_info("Translation already enabled - trying to copy translation structures\n");
3297
3298 ret = copy_translation_tables(iommu);
3299 if (ret) {
3300 /*
3301 * We found the IOMMU with translation
3302 * enabled - but failed to copy over the
3303 * old root-entry table. Try to proceed
3304 * by disabling translation now and
3305 * allocating a clean root-entry table.
3306 * This might cause DMAR faults, but
3307 * probably the dump will still succeed.
3308 */
3309 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3310 iommu->name);
3311 iommu_disable_translation(iommu);
3312 clear_translation_pre_enabled(iommu);
3313 } else {
3314 pr_info("Copied translation tables from previous kernel for %s\n",
3315 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003316 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003317 }
3318 }
3319
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003320 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003321 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003322#ifdef CONFIG_INTEL_IOMMU_SVM
3323 if (pasid_enabled(iommu))
3324 intel_svm_alloc_pasid_tables(iommu);
3325#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003326 }
3327
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003328 /*
3329 * Now that qi is enabled on all iommus, set the root entry and flush
3330 * caches. This is required on some Intel X58 chipsets, otherwise the
3331 * flush_context function will loop forever and the boot hangs.
3332 */
3333 for_each_active_iommu(iommu, drhd) {
3334 iommu_flush_write_buffer(iommu);
3335 iommu_set_root_entry(iommu);
3336 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3337 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3338 }
3339
David Woodhouse19943b02009-08-04 16:19:20 +01003340 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003341 iommu_identity_mapping |= IDENTMAP_ALL;
3342
Suresh Siddhad3f13812011-08-23 17:05:25 -07003343#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003344 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003345#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003346
Ashok Raj21e722c2017-01-30 09:39:53 -08003347 check_tylersburg_isoch();
3348
Joerg Roedel86080cc2015-06-12 12:27:16 +02003349 if (iommu_identity_mapping) {
3350 ret = si_domain_init(hw_pass_through);
3351 if (ret)
3352 goto free_iommu;
3353 }
3354
David Woodhousee0fc7e02009-09-30 09:12:17 -07003355
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003356 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003357 * If we copied translations from a previous kernel in the kdump
3358 * case, we can not assign the devices to domains now, as that
3359 * would eliminate the old mappings. So skip this part and defer
3360 * the assignment to device driver initialization time.
3361 */
3362 if (copied_tables)
3363 goto domains_done;
3364
3365 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003366 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003367 * identity mappings for rmrr, gfx, and isa and may fall back to static
3368 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003369 */
David Woodhouse19943b02009-08-04 16:19:20 +01003370 if (iommu_identity_mapping) {
3371 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3372 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003373 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003374 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003375 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003376 }
David Woodhouse19943b02009-08-04 16:19:20 +01003377 /*
3378 * For each rmrr
3379 * for each dev attached to rmrr
3380 * do
3381 * locate drhd for dev, alloc domain for dev
3382 * allocate free domain
3383 * allocate page table entries for rmrr
3384 * if context not allocated for bus
3385 * allocate and init context
3386 * set present in root table for this bus
3387 * init context with domain, translation etc
3388 * endfor
3389 * endfor
3390 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003391 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003392 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003393 /* some BIOS lists non-exist devices in DMAR table. */
3394 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003395 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003396 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003397 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003398 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003399 }
3400 }
3401
3402 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003403
Joerg Roedela87f4912015-06-12 12:32:54 +02003404domains_done:
3405
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003406 /*
3407 * for each drhd
3408 * enable fault log
3409 * global invalidate context cache
3410 * global invalidate iotlb
3411 * enable translation
3412 */
Jiang Liu7c919772014-01-06 14:18:18 +08003413 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003414 if (drhd->ignored) {
3415 /*
3416 * we always have to disable PMRs or DMA may fail on
3417 * this device
3418 */
3419 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003420 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003421 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003422 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003423
3424 iommu_flush_write_buffer(iommu);
3425
David Woodhousea222a7f2015-10-07 23:35:18 +01003426#ifdef CONFIG_INTEL_IOMMU_SVM
3427 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3428 ret = intel_svm_enable_prq(iommu);
3429 if (ret)
3430 goto free_iommu;
3431 }
3432#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003433 ret = dmar_set_interrupt(iommu);
3434 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003435 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003436
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003437 if (!translation_pre_enabled(iommu))
3438 iommu_enable_translation(iommu);
3439
David Woodhouseb94996c2009-09-19 15:28:12 -07003440 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003441 }
3442
3443 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003444
3445free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003446 for_each_active_iommu(iommu, drhd) {
3447 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003448 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003449 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003450
Weidong Hand9630fe2008-12-08 11:06:32 +08003451 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003452
Jiang Liu989d51f2014-02-19 14:07:21 +08003453error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003454 return ret;
3455}
3456
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003457/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003458static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003459 struct dmar_domain *domain,
3460 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003461{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003462 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003463
David Woodhouse875764d2009-06-28 21:20:51 +01003464 /* Restrict dma_mask to the width that the iommu can handle */
3465 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003466 /* Ensure we reserve the whole size-aligned region */
3467 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003468
3469 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003470 /*
3471 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003472 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003473 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003474 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003475 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003476 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003477 if (iova_pfn)
3478 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003479 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003480 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3481 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003482 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003483 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003484 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003485 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003486 }
3487
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003488 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003489}
3490
Peter Xub316d022017-05-22 18:28:51 +08003491static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003492{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003493 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003494 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003495 struct device *i_dev;
3496 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003497
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003498 domain = find_domain(dev);
3499 if (domain)
3500 goto out;
3501
3502 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3503 if (!domain)
3504 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003505
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003506 /* We have a new domain - setup possible RMRRs for the device */
3507 rcu_read_lock();
3508 for_each_rmrr_units(rmrr) {
3509 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3510 i, i_dev) {
3511 if (i_dev != dev)
3512 continue;
3513
3514 ret = domain_prepare_identity_map(dev, domain,
3515 rmrr->base_address,
3516 rmrr->end_address);
3517 if (ret)
3518 dev_err(dev, "Mapping reserved region failed\n");
3519 }
3520 }
3521 rcu_read_unlock();
3522
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003523 tmp = set_domain_for_dev(dev, domain);
3524 if (!tmp || domain != tmp) {
3525 domain_exit(domain);
3526 domain = tmp;
3527 }
3528
3529out:
3530
3531 if (!domain)
3532 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3533
3534
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003535 return domain;
3536}
3537
David Woodhouseecb509e2014-03-09 16:29:55 -07003538/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003539static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003540{
3541 int found;
3542
David Woodhouse3d891942014-03-06 15:59:26 +00003543 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003544 return 1;
3545
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003546 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003547 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003548
David Woodhouse9b226622014-03-09 14:03:28 -07003549 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003550 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003551 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003552 return 1;
3553 else {
3554 /*
3555 * 32 bit DMA is removed from si_domain and fall back
3556 * to non-identity mapping.
3557 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003558 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003559 pr_info("32bit %s uses non-identity mapping\n",
3560 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003561 return 0;
3562 }
3563 } else {
3564 /*
3565 * In case of a detached 64 bit DMA device from vm, the device
3566 * is put into si_domain for identity mapping.
3567 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003568 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003569 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003570 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003571 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003572 pr_info("64bit %s uses identity mapping\n",
3573 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003574 return 1;
3575 }
3576 }
3577 }
3578
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003579 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003580}
3581
David Woodhouse5040a912014-03-09 16:14:00 -07003582static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003583 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003584{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003585 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003586 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003587 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003588 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003589 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003590 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003591 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003592
3593 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003594
David Woodhouse5040a912014-03-09 16:14:00 -07003595 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003596 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003597
David Woodhouse5040a912014-03-09 16:14:00 -07003598 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003599 if (!domain)
3600 return 0;
3601
Weidong Han8c11e792008-12-08 15:29:22 +08003602 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003603 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003604
Omer Peleg2aac6302016-04-20 11:33:57 +03003605 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3606 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003607 goto error;
3608
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003609 /*
3610 * Check if DMAR supports zero-length reads on write only
3611 * mappings..
3612 */
3613 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003614 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003615 prot |= DMA_PTE_READ;
3616 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3617 prot |= DMA_PTE_WRITE;
3618 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003619 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003620 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003621 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003622 * is not a big problem
3623 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003624 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003625 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003626 if (ret)
3627 goto error;
3628
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003629 /* it's a non-present to present mapping. Only flush if caching mode */
3630 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003631 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003632 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003633 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003634 else
Weidong Han8c11e792008-12-08 15:29:22 +08003635 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003636
Omer Peleg2aac6302016-04-20 11:33:57 +03003637 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003638 start_paddr += paddr & ~PAGE_MASK;
3639 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003640
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003641error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003642 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003643 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003644 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003645 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003646 return 0;
3647}
3648
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003649static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3650 unsigned long offset, size_t size,
3651 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003652 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003653{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003654 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003655 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003656}
3657
Omer Peleg769530e2016-04-20 11:33:25 +03003658static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003659{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003660 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003661 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003662 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003663 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003664 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003665 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003666
David Woodhouse73676832009-07-04 14:08:36 +01003667 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003668 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003669
David Woodhouse1525a292014-03-06 16:19:30 +00003670 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003671 BUG_ON(!domain);
3672
Weidong Han8c11e792008-12-08 15:29:22 +08003673 iommu = domain_get_iommu(domain);
3674
Omer Peleg2aac6302016-04-20 11:33:57 +03003675 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003676
Omer Peleg769530e2016-04-20 11:33:25 +03003677 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003678 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003679 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003680
David Woodhoused794dc92009-06-28 00:27:49 +01003681 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003682 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003683
David Woodhouseea8ea462014-03-05 17:09:32 +00003684 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003685
mark gross5e0d2a62008-03-04 15:22:08 -08003686 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003687 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003688 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003689 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003690 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003691 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003692 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003693 queue_iova(&domain->iovad, iova_pfn, nrpages,
3694 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003695 /*
3696 * queue up the release of the unmap to save the 1/6th of the
3697 * cpu used up by the iotlb flush operation...
3698 */
mark gross5e0d2a62008-03-04 15:22:08 -08003699 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003700}
3701
Jiang Liud41a4ad2014-07-11 14:19:34 +08003702static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3703 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003704 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003705{
Omer Peleg769530e2016-04-20 11:33:25 +03003706 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003707}
3708
David Woodhouse5040a912014-03-09 16:14:00 -07003709static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003710 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003711 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003712{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003713 void *vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003714
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003715 vaddr = dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3716 if (iommu_no_mapping(dev) || !vaddr)
3717 return vaddr;
Alex Williamsone8bb9102009-11-04 15:59:34 -07003718
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003719 *dma_handle = __intel_map_single(dev, virt_to_phys(vaddr),
3720 PAGE_ALIGN(size), DMA_BIDIRECTIONAL,
3721 dev->coherent_dma_mask);
3722 if (!*dma_handle)
3723 goto out_free_pages;
3724 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003725
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003726out_free_pages:
3727 dma_direct_free(dev, size, vaddr, *dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003728 return NULL;
3729}
3730
David Woodhouse5040a912014-03-09 16:14:00 -07003731static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003732 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003733{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003734 if (!iommu_no_mapping(dev))
3735 intel_unmap(dev, dma_handle, PAGE_ALIGN(size));
3736 dma_direct_free(dev, size, vaddr, dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003737}
3738
David Woodhouse5040a912014-03-09 16:14:00 -07003739static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003740 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003741 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003742{
Omer Peleg769530e2016-04-20 11:33:25 +03003743 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3744 unsigned long nrpages = 0;
3745 struct scatterlist *sg;
3746 int i;
3747
3748 for_each_sg(sglist, sg, nelems, i) {
3749 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3750 }
3751
3752 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003753}
3754
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003755static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003756 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003757{
3758 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003759 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003761 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003762 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003763 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003764 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003765 }
3766 return nelems;
3767}
3768
David Woodhouse5040a912014-03-09 16:14:00 -07003769static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003770 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003771{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003772 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003773 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003774 size_t size = 0;
3775 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003776 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003777 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003778 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003779 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003780 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003781
3782 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003783 if (iommu_no_mapping(dev))
3784 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003785
David Woodhouse5040a912014-03-09 16:14:00 -07003786 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003787 if (!domain)
3788 return 0;
3789
Weidong Han8c11e792008-12-08 15:29:22 +08003790 iommu = domain_get_iommu(domain);
3791
David Woodhouseb536d242009-06-28 14:49:31 +01003792 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003793 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003794
Omer Peleg2aac6302016-04-20 11:33:57 +03003795 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003796 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003797 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003798 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003799 return 0;
3800 }
3801
3802 /*
3803 * Check if DMAR supports zero-length reads on write only
3804 * mappings..
3805 */
3806 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003807 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003808 prot |= DMA_PTE_READ;
3809 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3810 prot |= DMA_PTE_WRITE;
3811
Omer Peleg2aac6302016-04-20 11:33:57 +03003812 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003813
Fenghua Yuf5329592009-08-04 15:09:37 -07003814 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003815 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003816 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003817 start_vpfn + size - 1,
3818 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003819 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003820 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003821 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003822
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003823 /* it's a non-present to present mapping. Only flush if caching mode */
3824 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003825 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003826 else
Weidong Han8c11e792008-12-08 15:29:22 +08003827 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003828
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003829 return nelems;
3830}
3831
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003832static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3833{
3834 return !dma_addr;
3835}
3836
Arvind Yadav01e19322017-06-28 16:39:32 +05303837const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003838 .alloc = intel_alloc_coherent,
3839 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003840 .map_sg = intel_map_sg,
3841 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003842 .map_page = intel_map_page,
3843 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003844 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003845#ifdef CONFIG_X86
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003846 .dma_supported = dma_direct_supported,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003847#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003848};
3849
3850static inline int iommu_domain_cache_init(void)
3851{
3852 int ret = 0;
3853
3854 iommu_domain_cache = kmem_cache_create("iommu_domain",
3855 sizeof(struct dmar_domain),
3856 0,
3857 SLAB_HWCACHE_ALIGN,
3858
3859 NULL);
3860 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003861 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003862 ret = -ENOMEM;
3863 }
3864
3865 return ret;
3866}
3867
3868static inline int iommu_devinfo_cache_init(void)
3869{
3870 int ret = 0;
3871
3872 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3873 sizeof(struct device_domain_info),
3874 0,
3875 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003876 NULL);
3877 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003878 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003879 ret = -ENOMEM;
3880 }
3881
3882 return ret;
3883}
3884
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003885static int __init iommu_init_mempool(void)
3886{
3887 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003888 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003889 if (ret)
3890 return ret;
3891
3892 ret = iommu_domain_cache_init();
3893 if (ret)
3894 goto domain_error;
3895
3896 ret = iommu_devinfo_cache_init();
3897 if (!ret)
3898 return ret;
3899
3900 kmem_cache_destroy(iommu_domain_cache);
3901domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003902 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003903
3904 return -ENOMEM;
3905}
3906
3907static void __init iommu_exit_mempool(void)
3908{
3909 kmem_cache_destroy(iommu_devinfo_cache);
3910 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003911 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003912}
3913
Dan Williams556ab452010-07-23 15:47:56 -07003914static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3915{
3916 struct dmar_drhd_unit *drhd;
3917 u32 vtbar;
3918 int rc;
3919
3920 /* We know that this device on this chipset has its own IOMMU.
3921 * If we find it under a different IOMMU, then the BIOS is lying
3922 * to us. Hope that the IOMMU for this device is actually
3923 * disabled, and it needs no translation...
3924 */
3925 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3926 if (rc) {
3927 /* "can't" happen */
3928 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3929 return;
3930 }
3931 vtbar &= 0xffff0000;
3932
3933 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3934 drhd = dmar_find_matched_drhd_unit(pdev);
3935 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3936 TAINT_FIRMWARE_WORKAROUND,
3937 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3938 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3939}
3940DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3941
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003942static void __init init_no_remapping_devices(void)
3943{
3944 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003945 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003946 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003947
3948 for_each_drhd_unit(drhd) {
3949 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003950 for_each_active_dev_scope(drhd->devices,
3951 drhd->devices_cnt, i, dev)
3952 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003953 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003954 if (i == drhd->devices_cnt)
3955 drhd->ignored = 1;
3956 }
3957 }
3958
Jiang Liu7c919772014-01-06 14:18:18 +08003959 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003960 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003961 continue;
3962
Jiang Liub683b232014-02-19 14:07:32 +08003963 for_each_active_dev_scope(drhd->devices,
3964 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003965 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003966 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003967 if (i < drhd->devices_cnt)
3968 continue;
3969
David Woodhousec0771df2011-10-14 20:59:46 +01003970 /* This IOMMU has *only* gfx devices. Either bypass it or
3971 set the gfx_mapped flag, as appropriate */
3972 if (dmar_map_gfx) {
3973 intel_iommu_gfx_mapped = 1;
3974 } else {
3975 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08003976 for_each_active_dev_scope(drhd->devices,
3977 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003978 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003979 }
3980 }
3981}
3982
Fenghua Yuf59c7b62009-03-27 14:22:42 -07003983#ifdef CONFIG_SUSPEND
3984static int init_iommu_hw(void)
3985{
3986 struct dmar_drhd_unit *drhd;
3987 struct intel_iommu *iommu = NULL;
3988
3989 for_each_active_iommu(iommu, drhd)
3990 if (iommu->qi)
3991 dmar_reenable_qi(iommu);
3992
Joseph Cihulab7792602011-05-03 00:08:37 -07003993 for_each_iommu(iommu, drhd) {
3994 if (drhd->ignored) {
3995 /*
3996 * we always have to disable PMRs or DMA may fail on
3997 * this device
3998 */
3999 if (force_on)
4000 iommu_disable_protect_mem_regions(iommu);
4001 continue;
4002 }
4003
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004004 iommu_flush_write_buffer(iommu);
4005
4006 iommu_set_root_entry(iommu);
4007
4008 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004009 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004010 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4011 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004012 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004013 }
4014
4015 return 0;
4016}
4017
4018static void iommu_flush_all(void)
4019{
4020 struct dmar_drhd_unit *drhd;
4021 struct intel_iommu *iommu;
4022
4023 for_each_active_iommu(iommu, drhd) {
4024 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004025 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004026 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004027 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004028 }
4029}
4030
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004031static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004032{
4033 struct dmar_drhd_unit *drhd;
4034 struct intel_iommu *iommu = NULL;
4035 unsigned long flag;
4036
4037 for_each_active_iommu(iommu, drhd) {
4038 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4039 GFP_ATOMIC);
4040 if (!iommu->iommu_state)
4041 goto nomem;
4042 }
4043
4044 iommu_flush_all();
4045
4046 for_each_active_iommu(iommu, drhd) {
4047 iommu_disable_translation(iommu);
4048
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004049 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004050
4051 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4052 readl(iommu->reg + DMAR_FECTL_REG);
4053 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4054 readl(iommu->reg + DMAR_FEDATA_REG);
4055 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4056 readl(iommu->reg + DMAR_FEADDR_REG);
4057 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4058 readl(iommu->reg + DMAR_FEUADDR_REG);
4059
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004060 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004061 }
4062 return 0;
4063
4064nomem:
4065 for_each_active_iommu(iommu, drhd)
4066 kfree(iommu->iommu_state);
4067
4068 return -ENOMEM;
4069}
4070
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004071static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004072{
4073 struct dmar_drhd_unit *drhd;
4074 struct intel_iommu *iommu = NULL;
4075 unsigned long flag;
4076
4077 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004078 if (force_on)
4079 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4080 else
4081 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004082 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004083 }
4084
4085 for_each_active_iommu(iommu, drhd) {
4086
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004087 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004088
4089 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4090 iommu->reg + DMAR_FECTL_REG);
4091 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4092 iommu->reg + DMAR_FEDATA_REG);
4093 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4094 iommu->reg + DMAR_FEADDR_REG);
4095 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4096 iommu->reg + DMAR_FEUADDR_REG);
4097
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004098 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004099 }
4100
4101 for_each_active_iommu(iommu, drhd)
4102 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004103}
4104
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004105static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004106 .resume = iommu_resume,
4107 .suspend = iommu_suspend,
4108};
4109
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004110static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004111{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004112 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004113}
4114
4115#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004116static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004117#endif /* CONFIG_PM */
4118
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004119
Jiang Liuc2a0b532014-11-09 22:47:56 +08004120int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004121{
4122 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004123 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004124 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004125 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004126
4127 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4128 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004129 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004130
4131 rmrru->hdr = header;
4132 rmrr = (struct acpi_dmar_reserved_memory *)header;
4133 rmrru->base_address = rmrr->base_address;
4134 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004135
4136 length = rmrr->end_address - rmrr->base_address + 1;
4137 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4138 IOMMU_RESV_DIRECT);
4139 if (!rmrru->resv)
4140 goto free_rmrru;
4141
Jiang Liu2e455282014-02-19 14:07:36 +08004142 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4143 ((void *)rmrr) + rmrr->header.length,
4144 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004145 if (rmrru->devices_cnt && rmrru->devices == NULL)
4146 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004147
Jiang Liu2e455282014-02-19 14:07:36 +08004148 list_add(&rmrru->list, &dmar_rmrr_units);
4149
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004150 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004151free_all:
4152 kfree(rmrru->resv);
4153free_rmrru:
4154 kfree(rmrru);
4155out:
4156 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004157}
4158
Jiang Liu6b197242014-11-09 22:47:58 +08004159static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4160{
4161 struct dmar_atsr_unit *atsru;
4162 struct acpi_dmar_atsr *tmp;
4163
4164 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4165 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4166 if (atsr->segment != tmp->segment)
4167 continue;
4168 if (atsr->header.length != tmp->header.length)
4169 continue;
4170 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4171 return atsru;
4172 }
4173
4174 return NULL;
4175}
4176
4177int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004178{
4179 struct acpi_dmar_atsr *atsr;
4180 struct dmar_atsr_unit *atsru;
4181
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004182 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004183 return 0;
4184
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004185 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004186 atsru = dmar_find_atsr(atsr);
4187 if (atsru)
4188 return 0;
4189
4190 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004191 if (!atsru)
4192 return -ENOMEM;
4193
Jiang Liu6b197242014-11-09 22:47:58 +08004194 /*
4195 * If memory is allocated from slab by ACPI _DSM method, we need to
4196 * copy the memory content because the memory buffer will be freed
4197 * on return.
4198 */
4199 atsru->hdr = (void *)(atsru + 1);
4200 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004201 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004202 if (!atsru->include_all) {
4203 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4204 (void *)atsr + atsr->header.length,
4205 &atsru->devices_cnt);
4206 if (atsru->devices_cnt && atsru->devices == NULL) {
4207 kfree(atsru);
4208 return -ENOMEM;
4209 }
4210 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004211
Jiang Liu0e242612014-02-19 14:07:34 +08004212 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004213
4214 return 0;
4215}
4216
Jiang Liu9bdc5312014-01-06 14:18:27 +08004217static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4218{
4219 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4220 kfree(atsru);
4221}
4222
Jiang Liu6b197242014-11-09 22:47:58 +08004223int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4224{
4225 struct acpi_dmar_atsr *atsr;
4226 struct dmar_atsr_unit *atsru;
4227
4228 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4229 atsru = dmar_find_atsr(atsr);
4230 if (atsru) {
4231 list_del_rcu(&atsru->list);
4232 synchronize_rcu();
4233 intel_iommu_free_atsr(atsru);
4234 }
4235
4236 return 0;
4237}
4238
4239int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4240{
4241 int i;
4242 struct device *dev;
4243 struct acpi_dmar_atsr *atsr;
4244 struct dmar_atsr_unit *atsru;
4245
4246 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4247 atsru = dmar_find_atsr(atsr);
4248 if (!atsru)
4249 return 0;
4250
Linus Torvalds194dc872016-07-27 20:03:31 -07004251 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004252 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4253 i, dev)
4254 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004255 }
Jiang Liu6b197242014-11-09 22:47:58 +08004256
4257 return 0;
4258}
4259
Jiang Liuffebeb42014-11-09 22:48:02 +08004260static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4261{
4262 int sp, ret = 0;
4263 struct intel_iommu *iommu = dmaru->iommu;
4264
4265 if (g_iommus[iommu->seq_id])
4266 return 0;
4267
4268 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004269 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004270 iommu->name);
4271 return -ENXIO;
4272 }
4273 if (!ecap_sc_support(iommu->ecap) &&
4274 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004275 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004276 iommu->name);
4277 return -ENXIO;
4278 }
4279 sp = domain_update_iommu_superpage(iommu) - 1;
4280 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004281 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004282 iommu->name);
4283 return -ENXIO;
4284 }
4285
4286 /*
4287 * Disable translation if already enabled prior to OS handover.
4288 */
4289 if (iommu->gcmd & DMA_GCMD_TE)
4290 iommu_disable_translation(iommu);
4291
4292 g_iommus[iommu->seq_id] = iommu;
4293 ret = iommu_init_domains(iommu);
4294 if (ret == 0)
4295 ret = iommu_alloc_root_entry(iommu);
4296 if (ret)
4297 goto out;
4298
David Woodhouse8a94ade2015-03-24 14:54:56 +00004299#ifdef CONFIG_INTEL_IOMMU_SVM
4300 if (pasid_enabled(iommu))
4301 intel_svm_alloc_pasid_tables(iommu);
4302#endif
4303
Jiang Liuffebeb42014-11-09 22:48:02 +08004304 if (dmaru->ignored) {
4305 /*
4306 * we always have to disable PMRs or DMA may fail on this device
4307 */
4308 if (force_on)
4309 iommu_disable_protect_mem_regions(iommu);
4310 return 0;
4311 }
4312
4313 intel_iommu_init_qi(iommu);
4314 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004315
4316#ifdef CONFIG_INTEL_IOMMU_SVM
4317 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4318 ret = intel_svm_enable_prq(iommu);
4319 if (ret)
4320 goto disable_iommu;
4321 }
4322#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004323 ret = dmar_set_interrupt(iommu);
4324 if (ret)
4325 goto disable_iommu;
4326
4327 iommu_set_root_entry(iommu);
4328 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4329 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4330 iommu_enable_translation(iommu);
4331
Jiang Liuffebeb42014-11-09 22:48:02 +08004332 iommu_disable_protect_mem_regions(iommu);
4333 return 0;
4334
4335disable_iommu:
4336 disable_dmar_iommu(iommu);
4337out:
4338 free_dmar_iommu(iommu);
4339 return ret;
4340}
4341
Jiang Liu6b197242014-11-09 22:47:58 +08004342int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4343{
Jiang Liuffebeb42014-11-09 22:48:02 +08004344 int ret = 0;
4345 struct intel_iommu *iommu = dmaru->iommu;
4346
4347 if (!intel_iommu_enabled)
4348 return 0;
4349 if (iommu == NULL)
4350 return -EINVAL;
4351
4352 if (insert) {
4353 ret = intel_iommu_add(dmaru);
4354 } else {
4355 disable_dmar_iommu(iommu);
4356 free_dmar_iommu(iommu);
4357 }
4358
4359 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004360}
4361
Jiang Liu9bdc5312014-01-06 14:18:27 +08004362static void intel_iommu_free_dmars(void)
4363{
4364 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4365 struct dmar_atsr_unit *atsru, *atsr_n;
4366
4367 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4368 list_del(&rmrru->list);
4369 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004370 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004371 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004372 }
4373
Jiang Liu9bdc5312014-01-06 14:18:27 +08004374 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4375 list_del(&atsru->list);
4376 intel_iommu_free_atsr(atsru);
4377 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004378}
4379
4380int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4381{
Jiang Liub683b232014-02-19 14:07:32 +08004382 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004383 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004384 struct pci_dev *bridge = NULL;
4385 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004386 struct acpi_dmar_atsr *atsr;
4387 struct dmar_atsr_unit *atsru;
4388
4389 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004390 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004391 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004392 /* If it's an integrated device, allow ATS */
4393 if (!bridge)
4394 return 1;
4395 /* Connected via non-PCIe: no ATS */
4396 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004397 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004398 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004399 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004400 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004401 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004402 }
4403
Jiang Liu0e242612014-02-19 14:07:34 +08004404 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004405 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4406 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4407 if (atsr->segment != pci_domain_nr(dev->bus))
4408 continue;
4409
Jiang Liub683b232014-02-19 14:07:32 +08004410 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004411 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004412 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004413
4414 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004415 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004416 }
Jiang Liub683b232014-02-19 14:07:32 +08004417 ret = 0;
4418out:
Jiang Liu0e242612014-02-19 14:07:34 +08004419 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004420
Jiang Liub683b232014-02-19 14:07:32 +08004421 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004422}
4423
Jiang Liu59ce0512014-02-19 14:07:35 +08004424int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4425{
4426 int ret = 0;
4427 struct dmar_rmrr_unit *rmrru;
4428 struct dmar_atsr_unit *atsru;
4429 struct acpi_dmar_atsr *atsr;
4430 struct acpi_dmar_reserved_memory *rmrr;
4431
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004432 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004433 return 0;
4434
4435 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4436 rmrr = container_of(rmrru->hdr,
4437 struct acpi_dmar_reserved_memory, header);
4438 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4439 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4440 ((void *)rmrr) + rmrr->header.length,
4441 rmrr->segment, rmrru->devices,
4442 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004443 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004444 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004445 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004446 dmar_remove_dev_scope(info, rmrr->segment,
4447 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004448 }
4449 }
4450
4451 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4452 if (atsru->include_all)
4453 continue;
4454
4455 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4456 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4457 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4458 (void *)atsr + atsr->header.length,
4459 atsr->segment, atsru->devices,
4460 atsru->devices_cnt);
4461 if (ret > 0)
4462 break;
4463 else if(ret < 0)
4464 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004465 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004466 if (dmar_remove_dev_scope(info, atsr->segment,
4467 atsru->devices, atsru->devices_cnt))
4468 break;
4469 }
4470 }
4471
4472 return 0;
4473}
4474
Fenghua Yu99dcade2009-11-11 07:23:06 -08004475/*
4476 * Here we only respond to action of unbound device from driver.
4477 *
4478 * Added device is not attached to its DMAR domain here yet. That will happen
4479 * when mapping the device to iova.
4480 */
4481static int device_notifier(struct notifier_block *nb,
4482 unsigned long action, void *data)
4483{
4484 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004485 struct dmar_domain *domain;
4486
David Woodhouse3d891942014-03-06 15:59:26 +00004487 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004488 return 0;
4489
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004490 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004491 return 0;
4492
David Woodhouse1525a292014-03-06 16:19:30 +00004493 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004494 if (!domain)
4495 return 0;
4496
Joerg Roedele6de0f82015-07-22 16:30:36 +02004497 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004498 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004499 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004500
Fenghua Yu99dcade2009-11-11 07:23:06 -08004501 return 0;
4502}
4503
4504static struct notifier_block device_nb = {
4505 .notifier_call = device_notifier,
4506};
4507
Jiang Liu75f05562014-02-19 14:07:37 +08004508static int intel_iommu_memory_notifier(struct notifier_block *nb,
4509 unsigned long val, void *v)
4510{
4511 struct memory_notify *mhp = v;
4512 unsigned long long start, end;
4513 unsigned long start_vpfn, last_vpfn;
4514
4515 switch (val) {
4516 case MEM_GOING_ONLINE:
4517 start = mhp->start_pfn << PAGE_SHIFT;
4518 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4519 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004520 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004521 start, end);
4522 return NOTIFY_BAD;
4523 }
4524 break;
4525
4526 case MEM_OFFLINE:
4527 case MEM_CANCEL_ONLINE:
4528 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4529 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4530 while (start_vpfn <= last_vpfn) {
4531 struct iova *iova;
4532 struct dmar_drhd_unit *drhd;
4533 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004534 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004535
4536 iova = find_iova(&si_domain->iovad, start_vpfn);
4537 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004538 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004539 start_vpfn);
4540 break;
4541 }
4542
4543 iova = split_and_remove_iova(&si_domain->iovad, iova,
4544 start_vpfn, last_vpfn);
4545 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004546 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004547 start_vpfn, last_vpfn);
4548 return NOTIFY_BAD;
4549 }
4550
David Woodhouseea8ea462014-03-05 17:09:32 +00004551 freelist = domain_unmap(si_domain, iova->pfn_lo,
4552 iova->pfn_hi);
4553
Jiang Liu75f05562014-02-19 14:07:37 +08004554 rcu_read_lock();
4555 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004556 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004557 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004558 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004559 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004560 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004561
4562 start_vpfn = iova->pfn_hi + 1;
4563 free_iova_mem(iova);
4564 }
4565 break;
4566 }
4567
4568 return NOTIFY_OK;
4569}
4570
4571static struct notifier_block intel_iommu_memory_nb = {
4572 .notifier_call = intel_iommu_memory_notifier,
4573 .priority = 0
4574};
4575
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004576static void free_all_cpu_cached_iovas(unsigned int cpu)
4577{
4578 int i;
4579
4580 for (i = 0; i < g_num_of_iommus; i++) {
4581 struct intel_iommu *iommu = g_iommus[i];
4582 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004583 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004584
4585 if (!iommu)
4586 continue;
4587
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004588 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004589 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004590
4591 if (!domain)
4592 continue;
4593 free_cpu_cached_iovas(cpu, &domain->iovad);
4594 }
4595 }
4596}
4597
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004598static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004599{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004600 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004601 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004602}
4603
Joerg Roedel161b28a2017-03-28 17:04:52 +02004604static void intel_disable_iommus(void)
4605{
4606 struct intel_iommu *iommu = NULL;
4607 struct dmar_drhd_unit *drhd;
4608
4609 for_each_iommu(iommu, drhd)
4610 iommu_disable_translation(iommu);
4611}
4612
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004613static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4614{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004615 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4616
4617 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004618}
4619
Alex Williamsona5459cf2014-06-12 16:12:31 -06004620static ssize_t intel_iommu_show_version(struct device *dev,
4621 struct device_attribute *attr,
4622 char *buf)
4623{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004624 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004625 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4626 return sprintf(buf, "%d:%d\n",
4627 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4628}
4629static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4630
4631static ssize_t intel_iommu_show_address(struct device *dev,
4632 struct device_attribute *attr,
4633 char *buf)
4634{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004635 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004636 return sprintf(buf, "%llx\n", iommu->reg_phys);
4637}
4638static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4639
4640static ssize_t intel_iommu_show_cap(struct device *dev,
4641 struct device_attribute *attr,
4642 char *buf)
4643{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004644 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004645 return sprintf(buf, "%llx\n", iommu->cap);
4646}
4647static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4648
4649static ssize_t intel_iommu_show_ecap(struct device *dev,
4650 struct device_attribute *attr,
4651 char *buf)
4652{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004653 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004654 return sprintf(buf, "%llx\n", iommu->ecap);
4655}
4656static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4657
Alex Williamson2238c082015-07-14 15:24:53 -06004658static ssize_t intel_iommu_show_ndoms(struct device *dev,
4659 struct device_attribute *attr,
4660 char *buf)
4661{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004662 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004663 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4664}
4665static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4666
4667static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4668 struct device_attribute *attr,
4669 char *buf)
4670{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004671 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004672 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4673 cap_ndoms(iommu->cap)));
4674}
4675static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4676
Alex Williamsona5459cf2014-06-12 16:12:31 -06004677static struct attribute *intel_iommu_attrs[] = {
4678 &dev_attr_version.attr,
4679 &dev_attr_address.attr,
4680 &dev_attr_cap.attr,
4681 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004682 &dev_attr_domains_supported.attr,
4683 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004684 NULL,
4685};
4686
4687static struct attribute_group intel_iommu_group = {
4688 .name = "intel-iommu",
4689 .attrs = intel_iommu_attrs,
4690};
4691
4692const struct attribute_group *intel_iommu_groups[] = {
4693 &intel_iommu_group,
4694 NULL,
4695};
4696
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004697int __init intel_iommu_init(void)
4698{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004699 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004700 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004701 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004702
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004703 /* VT-d is required for a TXT/tboot launch, so enforce that */
4704 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004705
Jiang Liu3a5670e2014-02-19 14:07:33 +08004706 if (iommu_init_mempool()) {
4707 if (force_on)
4708 panic("tboot: Failed to initialize iommu memory\n");
4709 return -ENOMEM;
4710 }
4711
4712 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004713 if (dmar_table_init()) {
4714 if (force_on)
4715 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004716 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004717 }
4718
Suresh Siddhac2c72862011-08-23 17:05:19 -07004719 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004720 if (force_on)
4721 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004722 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004723 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004724
Joerg Roedelec154bf2017-10-06 15:00:53 +02004725 up_write(&dmar_global_lock);
4726
4727 /*
4728 * The bus notifier takes the dmar_global_lock, so lockdep will
4729 * complain later when we register it under the lock.
4730 */
4731 dmar_register_bus_notifier();
4732
4733 down_write(&dmar_global_lock);
4734
Joerg Roedel161b28a2017-03-28 17:04:52 +02004735 if (no_iommu || dmar_disabled) {
4736 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004737 * We exit the function here to ensure IOMMU's remapping and
4738 * mempool aren't setup, which means that the IOMMU's PMRs
4739 * won't be disabled via the call to init_dmars(). So disable
4740 * it explicitly here. The PMRs were setup by tboot prior to
4741 * calling SENTER, but the kernel is expected to reset/tear
4742 * down the PMRs.
4743 */
4744 if (intel_iommu_tboot_noforce) {
4745 for_each_iommu(iommu, drhd)
4746 iommu_disable_protect_mem_regions(iommu);
4747 }
4748
4749 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004750 * Make sure the IOMMUs are switched off, even when we
4751 * boot into a kexec kernel and the previous kernel left
4752 * them enabled
4753 */
4754 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004755 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004756 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004757
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004758 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004759 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004760
4761 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004762 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004763
Joseph Cihula51a63e62011-03-21 11:04:24 -07004764 if (dmar_init_reserved_ranges()) {
4765 if (force_on)
4766 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004767 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004768 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004769
4770 init_no_remapping_devices();
4771
Joseph Cihulab7792602011-05-03 00:08:37 -07004772 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004773 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004774 if (force_on)
4775 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004776 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004777 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004778 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004779 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004780 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004781
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004782#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004783 swiotlb = 0;
4784#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004785 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004786
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004787 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004788
Joerg Roedel39ab9552017-02-01 16:56:46 +01004789 for_each_active_iommu(iommu, drhd) {
4790 iommu_device_sysfs_add(&iommu->iommu, NULL,
4791 intel_iommu_groups,
4792 "%s", iommu->name);
4793 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4794 iommu_device_register(&iommu->iommu);
4795 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004796
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004797 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004798 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004799 if (si_domain && !hw_pass_through)
4800 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004801 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4802 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004803 intel_iommu_enabled = 1;
4804
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004805 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004806
4807out_free_reserved_range:
4808 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004809out_free_dmar:
4810 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004811 up_write(&dmar_global_lock);
4812 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004813 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004814}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004815
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004816static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004817{
4818 struct intel_iommu *iommu = opaque;
4819
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004820 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004821 return 0;
4822}
4823
4824/*
4825 * NB - intel-iommu lacks any sort of reference counting for the users of
4826 * dependent devices. If multiple endpoints have intersecting dependent
4827 * devices, unbinding the driver from any one of them will possibly leave
4828 * the others unable to operate.
4829 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004830static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004831{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004832 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004833 return;
4834
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004835 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004836}
4837
Joerg Roedel127c7612015-07-23 17:44:46 +02004838static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004839{
Weidong Hanc7151a82008-12-08 22:51:37 +08004840 struct intel_iommu *iommu;
4841 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004842
Joerg Roedel55d94042015-07-22 16:50:40 +02004843 assert_spin_locked(&device_domain_lock);
4844
Joerg Roedelb608ac32015-07-21 18:19:08 +02004845 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004846 return;
4847
Joerg Roedel127c7612015-07-23 17:44:46 +02004848 iommu = info->iommu;
4849
4850 if (info->dev) {
4851 iommu_disable_dev_iotlb(info);
4852 domain_context_clear(iommu, info->dev);
4853 }
4854
Joerg Roedelb608ac32015-07-21 18:19:08 +02004855 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004856
Joerg Roedeld160aca2015-07-22 11:52:53 +02004857 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004858 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004859 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004860
4861 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004862}
4863
Joerg Roedel55d94042015-07-22 16:50:40 +02004864static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4865 struct device *dev)
4866{
Joerg Roedel127c7612015-07-23 17:44:46 +02004867 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004868 unsigned long flags;
4869
Weidong Hanc7151a82008-12-08 22:51:37 +08004870 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004871 info = dev->archdata.iommu;
4872 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004873 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004874}
4875
4876static int md_domain_init(struct dmar_domain *domain, int guest_width)
4877{
4878 int adjust_width;
4879
Zhen Leiaa3ac942017-09-21 16:52:45 +01004880 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004881 domain_reserve_special_ranges(domain);
4882
4883 /* calculate AGAW */
4884 domain->gaw = guest_width;
4885 adjust_width = guestwidth_to_adjustwidth(guest_width);
4886 domain->agaw = width_to_agaw(adjust_width);
4887
Weidong Han5e98c4b2008-12-08 23:03:27 +08004888 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004889 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004890 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004891 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004892
4893 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004894 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004895 if (!domain->pgd)
4896 return -ENOMEM;
4897 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4898 return 0;
4899}
4900
Joerg Roedel00a77de2015-03-26 13:43:08 +01004901static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004902{
Joerg Roedel5d450802008-12-03 14:52:32 +01004903 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004904 struct iommu_domain *domain;
4905
4906 if (type != IOMMU_DOMAIN_UNMANAGED)
4907 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004908
Jiang Liuab8dfe22014-07-11 14:19:27 +08004909 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004910 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004911 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004912 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004913 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004914 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004915 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004916 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004917 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004918 }
Allen Kay8140a952011-10-14 12:32:17 -07004919 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004920
Joerg Roedel00a77de2015-03-26 13:43:08 +01004921 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004922 domain->geometry.aperture_start = 0;
4923 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4924 domain->geometry.force_aperture = true;
4925
Joerg Roedel00a77de2015-03-26 13:43:08 +01004926 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004927}
Kay, Allen M38717942008-09-09 18:37:29 +03004928
Joerg Roedel00a77de2015-03-26 13:43:08 +01004929static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004930{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004931 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004932}
Kay, Allen M38717942008-09-09 18:37:29 +03004933
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004934static int intel_iommu_attach_device(struct iommu_domain *domain,
4935 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004936{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004937 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004938 struct intel_iommu *iommu;
4939 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004940 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004941
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004942 if (device_is_rmrr_locked(dev)) {
4943 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4944 return -EPERM;
4945 }
4946
David Woodhouse7207d8f2014-03-09 16:31:06 -07004947 /* normally dev is not mapped */
4948 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004949 struct dmar_domain *old_domain;
4950
David Woodhouse1525a292014-03-06 16:19:30 +00004951 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004952 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004953 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004954 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004955 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004956
4957 if (!domain_type_is_vm_or_si(old_domain) &&
4958 list_empty(&old_domain->devices))
4959 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004960 }
4961 }
4962
David Woodhouse156baca2014-03-09 14:00:57 -07004963 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004964 if (!iommu)
4965 return -ENODEV;
4966
4967 /* check if this iommu agaw is sufficient for max mapped address */
4968 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004969 if (addr_width > cap_mgaw(iommu->cap))
4970 addr_width = cap_mgaw(iommu->cap);
4971
4972 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004973 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004974 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01004975 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004976 return -EFAULT;
4977 }
Tom Lyona99c47a2010-05-17 08:20:45 +01004978 dmar_domain->gaw = addr_width;
4979
4980 /*
4981 * Knock out extra levels of page tables if necessary
4982 */
4983 while (iommu->agaw < dmar_domain->agaw) {
4984 struct dma_pte *pte;
4985
4986 pte = dmar_domain->pgd;
4987 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08004988 dmar_domain->pgd = (struct dma_pte *)
4989 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01004990 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01004991 }
4992 dmar_domain->agaw--;
4993 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004994
Joerg Roedel28ccce02015-07-21 14:45:31 +02004995 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004996}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004997
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004998static void intel_iommu_detach_device(struct iommu_domain *domain,
4999 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005000{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005001 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005002}
Kay, Allen M38717942008-09-09 18:37:29 +03005003
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005004static int intel_iommu_map(struct iommu_domain *domain,
5005 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005006 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005007{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005008 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005009 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005010 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005011 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005012
Joerg Roedeldde57a22008-12-03 15:04:09 +01005013 if (iommu_prot & IOMMU_READ)
5014 prot |= DMA_PTE_READ;
5015 if (iommu_prot & IOMMU_WRITE)
5016 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005017 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5018 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005019
David Woodhouse163cc522009-06-28 00:51:17 +01005020 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005021 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005022 u64 end;
5023
5024 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005025 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005026 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005027 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005028 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005029 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005030 return -EFAULT;
5031 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005032 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005033 }
David Woodhousead051222009-06-28 14:22:28 +01005034 /* Round up size to next multiple of PAGE_SIZE, if it and
5035 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005036 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005037 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5038 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005039 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005040}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005041
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005042static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005043 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005044{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005045 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005046 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005047 unsigned long start_pfn, last_pfn;
5048 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005049 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005050
David Woodhouse5cf0a762014-03-19 16:07:49 +00005051 /* Cope with horrid API which requires us to unmap more than the
5052 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005053 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005054
5055 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5056 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5057
David Woodhouseea8ea462014-03-05 17:09:32 +00005058 start_pfn = iova >> VTD_PAGE_SHIFT;
5059 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5060
5061 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5062
5063 npages = last_pfn - start_pfn + 1;
5064
Shaokun Zhangf746a022018-03-22 18:18:06 +08005065 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005066 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5067 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005068
5069 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005070
David Woodhouse163cc522009-06-28 00:51:17 +01005071 if (dmar_domain->max_addr == iova + size)
5072 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005073
David Woodhouse5cf0a762014-03-19 16:07:49 +00005074 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005075}
Kay, Allen M38717942008-09-09 18:37:29 +03005076
Joerg Roedeld14d6572008-12-03 15:06:57 +01005077static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305078 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005079{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005080 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005081 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005082 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005083 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005084
David Woodhouse5cf0a762014-03-19 16:07:49 +00005085 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005086 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005087 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005088
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005089 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005090}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005091
Joerg Roedel5d587b82014-09-05 10:50:45 +02005092static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005093{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005094 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005095 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005096 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005097 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005098
Joerg Roedel5d587b82014-09-05 10:50:45 +02005099 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005100}
5101
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005102static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005103{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005104 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005105 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005106 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005107
Alex Williamsona5459cf2014-06-12 16:12:31 -06005108 iommu = device_to_iommu(dev, &bus, &devfn);
5109 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005110 return -ENODEV;
5111
Joerg Roedele3d10af2017-02-01 17:23:22 +01005112 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005113
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005114 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005115
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005116 if (IS_ERR(group))
5117 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005118
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005119 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005120 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005121}
5122
5123static void intel_iommu_remove_device(struct device *dev)
5124{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005125 struct intel_iommu *iommu;
5126 u8 bus, devfn;
5127
5128 iommu = device_to_iommu(dev, &bus, &devfn);
5129 if (!iommu)
5130 return;
5131
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005132 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005133
Joerg Roedele3d10af2017-02-01 17:23:22 +01005134 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005135}
5136
Eric Auger0659b8d2017-01-19 20:57:53 +00005137static void intel_iommu_get_resv_regions(struct device *device,
5138 struct list_head *head)
5139{
5140 struct iommu_resv_region *reg;
5141 struct dmar_rmrr_unit *rmrr;
5142 struct device *i_dev;
5143 int i;
5144
5145 rcu_read_lock();
5146 for_each_rmrr_units(rmrr) {
5147 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5148 i, i_dev) {
5149 if (i_dev != device)
5150 continue;
5151
5152 list_add_tail(&rmrr->resv->list, head);
5153 }
5154 }
5155 rcu_read_unlock();
5156
5157 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5158 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005159 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005160 if (!reg)
5161 return;
5162 list_add_tail(&reg->list, head);
5163}
5164
5165static void intel_iommu_put_resv_regions(struct device *dev,
5166 struct list_head *head)
5167{
5168 struct iommu_resv_region *entry, *next;
5169
5170 list_for_each_entry_safe(entry, next, head, list) {
5171 if (entry->type == IOMMU_RESV_RESERVED)
5172 kfree(entry);
5173 }
Kay, Allen M38717942008-09-09 18:37:29 +03005174}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005175
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005176#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005177#define MAX_NR_PASID_BITS (20)
5178static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5179{
5180 /*
5181 * Convert ecap_pss to extend context entry pts encoding, also
5182 * respect the soft pasid_max value set by the iommu.
5183 * - number of PASID bits = ecap_pss + 1
5184 * - number of PASID table entries = 2^(pts + 5)
5185 * Therefore, pts = ecap_pss - 4
5186 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5187 */
5188 if (ecap_pss(iommu->ecap) < 5)
5189 return 0;
5190
5191 /* pasid_max is encoded as actual number of entries not the bits */
5192 return find_first_bit((unsigned long *)&iommu->pasid_max,
5193 MAX_NR_PASID_BITS) - 5;
5194}
5195
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005196int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5197{
5198 struct device_domain_info *info;
5199 struct context_entry *context;
5200 struct dmar_domain *domain;
5201 unsigned long flags;
5202 u64 ctx_lo;
5203 int ret;
5204
5205 domain = get_valid_domain_for_dev(sdev->dev);
5206 if (!domain)
5207 return -EINVAL;
5208
5209 spin_lock_irqsave(&device_domain_lock, flags);
5210 spin_lock(&iommu->lock);
5211
5212 ret = -EINVAL;
5213 info = sdev->dev->archdata.iommu;
5214 if (!info || !info->pasid_supported)
5215 goto out;
5216
5217 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5218 if (WARN_ON(!context))
5219 goto out;
5220
5221 ctx_lo = context[0].lo;
5222
5223 sdev->did = domain->iommu_did[iommu->seq_id];
5224 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5225
5226 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005227 if (iommu->pasid_state_table)
5228 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005229 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5230 intel_iommu_get_pts(iommu);
5231
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005232 wmb();
5233 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5234 * extended to permit requests-with-PASID if the PASIDE bit
5235 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5236 * however, the PASIDE bit is ignored and requests-with-PASID
5237 * are unconditionally blocked. Which makes less sense.
5238 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5239 * "guest mode" translation types depending on whether ATS
5240 * is available or not. Annoyingly, we can't use the new
5241 * modes *unless* PASIDE is set. */
5242 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5243 ctx_lo &= ~CONTEXT_TT_MASK;
5244 if (info->ats_supported)
5245 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5246 else
5247 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5248 }
5249 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005250 if (iommu->pasid_state_table)
5251 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005252 if (info->pri_supported)
5253 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005254 context[0].lo = ctx_lo;
5255 wmb();
5256 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5257 DMA_CCMD_MASK_NOBIT,
5258 DMA_CCMD_DEVICE_INVL);
5259 }
5260
5261 /* Enable PASID support in the device, if it wasn't already */
5262 if (!info->pasid_enabled)
5263 iommu_enable_dev_iotlb(info);
5264
5265 if (info->ats_enabled) {
5266 sdev->dev_iotlb = 1;
5267 sdev->qdep = info->ats_qdep;
5268 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5269 sdev->qdep = 0;
5270 }
5271 ret = 0;
5272
5273 out:
5274 spin_unlock(&iommu->lock);
5275 spin_unlock_irqrestore(&device_domain_lock, flags);
5276
5277 return ret;
5278}
5279
5280struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5281{
5282 struct intel_iommu *iommu;
5283 u8 bus, devfn;
5284
5285 if (iommu_dummy(dev)) {
5286 dev_warn(dev,
5287 "No IOMMU translation for device; cannot enable SVM\n");
5288 return NULL;
5289 }
5290
5291 iommu = device_to_iommu(dev, &bus, &devfn);
5292 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005293 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005294 return NULL;
5295 }
5296
5297 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005298 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005299 return NULL;
5300 }
5301
5302 return iommu;
5303}
5304#endif /* CONFIG_INTEL_IOMMU_SVM */
5305
Joerg Roedelb0119e82017-02-01 13:23:08 +01005306const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005307 .capable = intel_iommu_capable,
5308 .domain_alloc = intel_iommu_domain_alloc,
5309 .domain_free = intel_iommu_domain_free,
5310 .attach_dev = intel_iommu_attach_device,
5311 .detach_dev = intel_iommu_detach_device,
5312 .map = intel_iommu_map,
5313 .unmap = intel_iommu_unmap,
5314 .map_sg = default_iommu_map_sg,
5315 .iova_to_phys = intel_iommu_iova_to_phys,
5316 .add_device = intel_iommu_add_device,
5317 .remove_device = intel_iommu_remove_device,
5318 .get_resv_regions = intel_iommu_get_resv_regions,
5319 .put_resv_regions = intel_iommu_put_resv_regions,
5320 .device_group = pci_device_group,
5321 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005322};
David Woodhouse9af88142009-02-13 23:18:03 +00005323
Daniel Vetter94526182013-01-20 23:50:13 +01005324static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5325{
5326 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005327 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005328 dmar_map_gfx = 0;
5329}
5330
5331DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5332DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5333DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5334DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5335DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5336DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5337DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5338
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005339static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005340{
5341 /*
5342 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005343 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005344 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005345 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005346 rwbf_quirk = 1;
5347}
5348
5349DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005350DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5351DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5352DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5353DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5354DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5355DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005356
Adam Jacksoneecfd572010-08-25 21:17:34 +01005357#define GGC 0x52
5358#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5359#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5360#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5361#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5362#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5363#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5364#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5365#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5366
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005367static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005368{
5369 unsigned short ggc;
5370
Adam Jacksoneecfd572010-08-25 21:17:34 +01005371 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005372 return;
5373
Adam Jacksoneecfd572010-08-25 21:17:34 +01005374 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005375 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005376 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005377 } else if (dmar_map_gfx) {
5378 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005379 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005380 intel_iommu_strict = 1;
5381 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005382}
5383DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5384DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5385DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5386DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5387
David Woodhousee0fc7e02009-09-30 09:12:17 -07005388/* On Tylersburg chipsets, some BIOSes have been known to enable the
5389 ISOCH DMAR unit for the Azalia sound device, but not give it any
5390 TLB entries, which causes it to deadlock. Check for that. We do
5391 this in a function called from init_dmars(), instead of in a PCI
5392 quirk, because we don't want to print the obnoxious "BIOS broken"
5393 message if VT-d is actually disabled.
5394*/
5395static void __init check_tylersburg_isoch(void)
5396{
5397 struct pci_dev *pdev;
5398 uint32_t vtisochctrl;
5399
5400 /* If there's no Azalia in the system anyway, forget it. */
5401 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5402 if (!pdev)
5403 return;
5404 pci_dev_put(pdev);
5405
5406 /* System Management Registers. Might be hidden, in which case
5407 we can't do the sanity check. But that's OK, because the
5408 known-broken BIOSes _don't_ actually hide it, so far. */
5409 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5410 if (!pdev)
5411 return;
5412
5413 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5414 pci_dev_put(pdev);
5415 return;
5416 }
5417
5418 pci_dev_put(pdev);
5419
5420 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5421 if (vtisochctrl & 1)
5422 return;
5423
5424 /* Drop all bits other than the number of TLB entries */
5425 vtisochctrl &= 0x1c;
5426
5427 /* If we have the recommended number of TLB entries (16), fine. */
5428 if (vtisochctrl == 0x10)
5429 return;
5430
5431 /* Zero TLB entries? You get to ride the short bus to school. */
5432 if (!vtisochctrl) {
5433 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5434 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5435 dmi_get_system_info(DMI_BIOS_VENDOR),
5436 dmi_get_system_info(DMI_BIOS_VERSION),
5437 dmi_get_system_info(DMI_PRODUCT_VERSION));
5438 iommu_identity_mapping |= IDENTMAP_AZALIA;
5439 return;
5440 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005441
5442 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005443 vtisochctrl);
5444}