blob: b344a883f11690969865e936e30f4053ecf97005 [file] [log] [blame]
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001/*
David Woodhouseea8ea462014-03-05 17:09:32 +00002 * Copyright © 2006-2014 Intel Corporation.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
David Woodhouseea8ea462014-03-05 17:09:32 +000013 * Authors: David Woodhouse <dwmw2@infradead.org>,
14 * Ashok Raj <ashok.raj@intel.com>,
15 * Shaohua Li <shaohua.li@intel.com>,
16 * Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
17 * Fenghua Yu <fenghua.yu@intel.com>
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020018 * Joerg Roedel <jroedel@suse.de>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070019 */
20
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020021#define pr_fmt(fmt) "DMAR: " fmt
22
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070023#include <linux/init.h>
24#include <linux/bitmap.h>
mark gross5e0d2a62008-03-04 15:22:08 -080025#include <linux/debugfs.h>
Paul Gortmaker54485c32011-10-29 10:26:25 -040026#include <linux/export.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070027#include <linux/slab.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070030#include <linux/spinlock.h>
31#include <linux/pci.h>
32#include <linux/dmar.h>
33#include <linux/dma-mapping.h>
34#include <linux/mempool.h>
Jiang Liu75f05562014-02-19 14:07:37 +080035#include <linux/memory.h>
Omer Pelegaa473242016-04-20 11:33:02 +030036#include <linux/cpu.h>
mark gross5e0d2a62008-03-04 15:22:08 -080037#include <linux/timer.h>
Dan Williamsdfddb9692015-10-09 18:16:46 -040038#include <linux/io.h>
Kay, Allen M38717942008-09-09 18:37:29 +030039#include <linux/iova.h>
Joerg Roedel5d450802008-12-03 14:52:32 +010040#include <linux/iommu.h>
Kay, Allen M38717942008-09-09 18:37:29 +030041#include <linux/intel-iommu.h>
Rafael J. Wysocki134fac32011-03-23 22:16:14 +010042#include <linux/syscore_ops.h>
Shane Wang69575d32009-09-01 18:25:07 -070043#include <linux/tboot.h>
Stephen Rothwelladb2fe02009-08-31 15:24:23 +100044#include <linux/dmi.h>
Joerg Roedel5cdede22011-04-04 15:55:18 +020045#include <linux/pci-ats.h>
Tejun Heo0ee332c2011-12-08 10:22:09 -080046#include <linux/memblock.h>
Akinobu Mita36746432014-06-04 16:06:51 -070047#include <linux/dma-contiguous.h>
Christoph Hellwigfec777c2018-03-19 11:38:15 +010048#include <linux/dma-direct.h>
Joerg Roedel091d42e2015-06-12 11:56:10 +020049#include <linux/crash_dump.h>
Suresh Siddha8a8f4222012-03-30 11:47:08 -070050#include <asm/irq_remapping.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070051#include <asm/cacheflush.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090052#include <asm/iommu.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070053
Joerg Roedel078e1ee2012-09-26 12:44:43 +020054#include "irq_remapping.h"
55
Fenghua Yu5b6985c2008-10-16 18:02:32 -070056#define ROOT_SIZE VTD_PAGE_SIZE
57#define CONTEXT_SIZE VTD_PAGE_SIZE
58
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070059#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000060#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070061#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070062#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070063
64#define IOAPIC_RANGE_START (0xfee00000)
65#define IOAPIC_RANGE_END (0xfeefffff)
66#define IOVA_START_ADDR (0x1000)
67
Sohil Mehta5e3b4a12017-12-20 11:59:24 -080068#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070069
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070070#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080071#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070072
David Woodhouse2ebe3152009-09-19 07:34:04 -070073#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
74#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
75
76/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
77 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
78#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
79 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
80#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070081
Robin Murphy1b722502015-01-12 17:51:15 +000082/* IO virtual address start page frame number */
83#define IOVA_START_PFN (1)
84
Mark McLoughlinf27be032008-11-20 15:49:43 +000085#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
mark gross5e0d2a62008-03-04 15:22:08 -080086
Andrew Mortondf08cdc2010-09-22 13:05:11 -070087/* page table handling */
88#define LEVEL_STRIDE (9)
89#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
90
Ohad Ben-Cohen6d1c56a2011-11-10 11:32:30 +020091/*
92 * This bitmap is used to advertise the page sizes our hardware support
93 * to the IOMMU core, which will then use this information to split
94 * physically contiguous memory regions it is mapping into page sizes
95 * that we support.
96 *
97 * Traditionally the IOMMU core just handed us the mappings directly,
98 * after making sure the size is an order of a 4KiB page and that the
99 * mapping has natural alignment.
100 *
101 * To retain this behavior, we currently advertise that we support
102 * all page sizes that are an order of 4KiB.
103 *
104 * If at some point we'd like to utilize the IOMMU core's new behavior,
105 * we could change this to advertise the real page sizes we support.
106 */
107#define INTEL_IOMMU_PGSIZES (~0xFFFUL)
108
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700109static inline int agaw_to_level(int agaw)
110{
111 return agaw + 2;
112}
113
114static inline int agaw_to_width(int agaw)
115{
Jiang Liu5c645b32014-01-06 14:18:12 +0800116 return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700117}
118
119static inline int width_to_agaw(int width)
120{
Jiang Liu5c645b32014-01-06 14:18:12 +0800121 return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700122}
123
124static inline unsigned int level_to_offset_bits(int level)
125{
126 return (level - 1) * LEVEL_STRIDE;
127}
128
129static inline int pfn_level_offset(unsigned long pfn, int level)
130{
131 return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
132}
133
134static inline unsigned long level_mask(int level)
135{
136 return -1UL << level_to_offset_bits(level);
137}
138
139static inline unsigned long level_size(int level)
140{
141 return 1UL << level_to_offset_bits(level);
142}
143
144static inline unsigned long align_to_level(unsigned long pfn, int level)
145{
146 return (pfn + level_size(level) - 1) & level_mask(level);
147}
David Woodhousefd18de52009-05-10 23:57:41 +0100148
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100149static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
150{
Jiang Liu5c645b32014-01-06 14:18:12 +0800151 return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100152}
153
David Woodhousedd4e8312009-06-27 16:21:20 +0100154/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
155 are never going to work. */
156static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
157{
158 return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT);
159}
160
161static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn)
162{
163 return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
164}
165static inline unsigned long page_to_dma_pfn(struct page *pg)
166{
167 return mm_to_dma_pfn(page_to_pfn(pg));
168}
169static inline unsigned long virt_to_dma_pfn(void *p)
170{
171 return page_to_dma_pfn(virt_to_page(p));
172}
173
Weidong Hand9630fe2008-12-08 11:06:32 +0800174/* global iommu list, set NULL for ignored DMAR units */
175static struct intel_iommu **g_iommus;
176
David Woodhousee0fc7e02009-09-30 09:12:17 -0700177static void __init check_tylersburg_isoch(void);
David Woodhouse9af88142009-02-13 23:18:03 +0000178static int rwbf_quirk;
179
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000180/*
Joseph Cihulab7792602011-05-03 00:08:37 -0700181 * set to 1 to panic kernel if can't successfully enable VT-d
182 * (used when kernel is launched w/ TXT)
183 */
184static int force_on = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700185int intel_iommu_tboot_noforce;
Joseph Cihulab7792602011-05-03 00:08:37 -0700186
187/*
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000188 * 0: Present
189 * 1-11: Reserved
190 * 12-63: Context Ptr (12 - (haw-1))
191 * 64-127: Reserved
192 */
193struct root_entry {
David Woodhouse03ecc322015-02-13 14:35:21 +0000194 u64 lo;
195 u64 hi;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000196};
197#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000198
Joerg Roedel091d42e2015-06-12 11:56:10 +0200199/*
200 * Take a root_entry and return the Lower Context Table Pointer (LCTP)
201 * if marked present.
202 */
203static phys_addr_t root_entry_lctp(struct root_entry *re)
204{
205 if (!(re->lo & 1))
206 return 0;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000207
Joerg Roedel091d42e2015-06-12 11:56:10 +0200208 return re->lo & VTD_PAGE_MASK;
209}
210
211/*
212 * Take a root_entry and return the Upper Context Table Pointer (UCTP)
213 * if marked present.
214 */
215static phys_addr_t root_entry_uctp(struct root_entry *re)
216{
217 if (!(re->hi & 1))
218 return 0;
219
220 return re->hi & VTD_PAGE_MASK;
221}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000222/*
223 * low 64 bits:
224 * 0: present
225 * 1: fault processing disable
226 * 2-3: translation type
227 * 12-63: address space root
228 * high 64 bits:
229 * 0-2: address width
230 * 3-6: aval
231 * 8-23: domain id
232 */
233struct context_entry {
234 u64 lo;
235 u64 hi;
236};
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000237
Joerg Roedelcf484d02015-06-12 12:21:46 +0200238static inline void context_clear_pasid_enable(struct context_entry *context)
239{
240 context->lo &= ~(1ULL << 11);
241}
242
243static inline bool context_pasid_enabled(struct context_entry *context)
244{
245 return !!(context->lo & (1ULL << 11));
246}
247
248static inline void context_set_copied(struct context_entry *context)
249{
250 context->hi |= (1ull << 3);
251}
252
253static inline bool context_copied(struct context_entry *context)
254{
255 return !!(context->hi & (1ULL << 3));
256}
257
258static inline bool __context_present(struct context_entry *context)
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000259{
260 return (context->lo & 1);
261}
Joerg Roedelcf484d02015-06-12 12:21:46 +0200262
263static inline bool context_present(struct context_entry *context)
264{
265 return context_pasid_enabled(context) ?
266 __context_present(context) :
267 __context_present(context) && !context_copied(context);
268}
269
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000270static inline void context_set_present(struct context_entry *context)
271{
272 context->lo |= 1;
273}
274
275static inline void context_set_fault_enable(struct context_entry *context)
276{
277 context->lo &= (((u64)-1) << 2) | 1;
278}
279
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000280static inline void context_set_translation_type(struct context_entry *context,
281 unsigned long value)
282{
283 context->lo &= (((u64)-1) << 4) | 3;
284 context->lo |= (value & 3) << 2;
285}
286
287static inline void context_set_address_root(struct context_entry *context,
288 unsigned long value)
289{
Li, Zhen-Hua1a2262f2014-11-05 15:30:19 +0800290 context->lo &= ~VTD_PAGE_MASK;
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000291 context->lo |= value & VTD_PAGE_MASK;
292}
293
294static inline void context_set_address_width(struct context_entry *context,
295 unsigned long value)
296{
297 context->hi |= value & 7;
298}
299
300static inline void context_set_domain_id(struct context_entry *context,
301 unsigned long value)
302{
303 context->hi |= (value & ((1 << 16) - 1)) << 8;
304}
305
Joerg Roedeldbcd8612015-06-12 12:02:09 +0200306static inline int context_domain_id(struct context_entry *c)
307{
308 return((c->hi >> 8) & 0xffff);
309}
310
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000311static inline void context_clear_entry(struct context_entry *context)
312{
313 context->lo = 0;
314 context->hi = 0;
315}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000316
Mark McLoughlin622ba122008-11-20 15:49:46 +0000317/*
318 * 0: readable
319 * 1: writable
320 * 2-6: reserved
321 * 7: super page
Sheng Yang9cf06692009-03-18 15:33:07 +0800322 * 8-10: available
323 * 11: snoop behavior
Mark McLoughlin622ba122008-11-20 15:49:46 +0000324 * 12-63: Host physcial address
325 */
326struct dma_pte {
327 u64 val;
328};
Mark McLoughlin622ba122008-11-20 15:49:46 +0000329
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000330static inline void dma_clear_pte(struct dma_pte *pte)
331{
332 pte->val = 0;
333}
334
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000335static inline u64 dma_pte_addr(struct dma_pte *pte)
336{
David Woodhousec85994e2009-07-01 19:21:24 +0100337#ifdef CONFIG_64BIT
338 return pte->val & VTD_PAGE_MASK;
339#else
340 /* Must have a full atomic 64-bit read */
David Woodhouse1a8bd482010-08-10 01:38:53 +0100341 return __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
David Woodhousec85994e2009-07-01 19:21:24 +0100342#endif
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000343}
344
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000345static inline bool dma_pte_present(struct dma_pte *pte)
346{
347 return (pte->val & 3) != 0;
348}
Mark McLoughlin622ba122008-11-20 15:49:46 +0000349
Allen Kay4399c8b2011-10-14 12:32:46 -0700350static inline bool dma_pte_superpage(struct dma_pte *pte)
351{
Joerg Roedelc3c75eb2014-07-04 11:19:10 +0200352 return (pte->val & DMA_PTE_LARGE_PAGE);
Allen Kay4399c8b2011-10-14 12:32:46 -0700353}
354
David Woodhouse75e6bf92009-07-02 11:21:16 +0100355static inline int first_pte_in_page(struct dma_pte *pte)
356{
357 return !((unsigned long)pte & ~VTD_PAGE_MASK);
358}
359
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700360/*
361 * This domain is a statically identity mapping domain.
362 * 1. This domain creats a static 1:1 mapping to all usable memory.
363 * 2. It maps to each iommu if successful.
364 * 3. Each iommu mapps to this domain if successful.
365 */
David Woodhouse19943b02009-08-04 16:19:20 +0100366static struct dmar_domain *si_domain;
367static int hw_pass_through = 1;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700368
Joerg Roedel28ccce02015-07-21 14:45:31 +0200369/*
370 * Domain represents a virtual machine, more than one devices
Weidong Han1ce28fe2008-12-08 16:35:39 +0800371 * across iommus may be owned in one domain, e.g. kvm guest.
372 */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800373#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
Weidong Han1ce28fe2008-12-08 16:35:39 +0800374
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700375/* si_domain contains mulitple devices */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800376#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700377
Joerg Roedel29a27712015-07-21 17:17:12 +0200378#define for_each_domain_iommu(idx, domain) \
379 for (idx = 0; idx < g_num_of_iommus; idx++) \
380 if (domain->iommu_refcnt[idx])
381
Mark McLoughlin99126f72008-11-20 15:49:47 +0000382struct dmar_domain {
Suresh Siddha4c923d42009-10-02 11:01:24 -0700383 int nid; /* node id */
Joerg Roedel29a27712015-07-21 17:17:12 +0200384
385 unsigned iommu_refcnt[DMAR_UNITS_SUPPORTED];
386 /* Refcount of devices per iommu */
387
Mark McLoughlin99126f72008-11-20 15:49:47 +0000388
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +0200389 u16 iommu_did[DMAR_UNITS_SUPPORTED];
390 /* Domain ids per IOMMU. Use u16 since
391 * domain ids are 16 bit wide according
392 * to VT-d spec, section 9.3 */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000393
Omer Peleg0824c592016-04-20 19:03:35 +0300394 bool has_iotlb_device;
Joerg Roedel00a77de2015-03-26 13:43:08 +0100395 struct list_head devices; /* all devices' list */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000396 struct iova_domain iovad; /* iova's that belong to this domain */
397
398 struct dma_pte *pgd; /* virtual address */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000399 int gaw; /* max guest address width */
400
401 /* adjusted guest address width, 0 is level 2 30-bit */
402 int agaw;
403
Weidong Han3b5410e2008-12-08 09:17:15 +0800404 int flags; /* flags to find out type of domain */
Weidong Han8e6040972008-12-08 15:49:06 +0800405
406 int iommu_coherency;/* indicate coherency of iommu access */
Sheng Yang58c610b2009-03-18 15:33:05 +0800407 int iommu_snooping; /* indicate snooping control feature*/
Weidong Hanc7151a82008-12-08 22:51:37 +0800408 int iommu_count; /* reference count of iommu */
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100409 int iommu_superpage;/* Level of superpages supported:
410 0 == 4KiB (no superpages), 1 == 2MiB,
411 2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
Weidong Hanfe40f1e2008-12-08 23:10:23 +0800412 u64 max_addr; /* maximum mapped address */
Joerg Roedel00a77de2015-03-26 13:43:08 +0100413
414 struct iommu_domain domain; /* generic domain data structure for
415 iommu core */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000416};
417
Mark McLoughlina647dac2008-11-20 15:49:48 +0000418/* PCI domain-device relationship */
419struct device_domain_info {
420 struct list_head link; /* link to domain siblings */
421 struct list_head global; /* link to global list */
David Woodhouse276dbf992009-04-04 01:45:37 +0100422 u8 bus; /* PCI bus number */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000423 u8 devfn; /* PCI devfn number */
David Woodhouseb16d0cb2015-10-12 14:17:37 +0100424 u8 pasid_supported:3;
425 u8 pasid_enabled:1;
426 u8 pri_supported:1;
427 u8 pri_enabled:1;
428 u8 ats_supported:1;
429 u8 ats_enabled:1;
430 u8 ats_qdep;
David Woodhouse0bcb3e22014-03-06 17:12:03 +0000431 struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
Yu Zhao93a23a72009-05-18 13:51:37 +0800432 struct intel_iommu *iommu; /* IOMMU used by this device */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000433 struct dmar_domain *domain; /* pointer to domain */
434};
435
Jiang Liub94e4112014-02-19 14:07:25 +0800436struct dmar_rmrr_unit {
437 struct list_head list; /* list of rmrr units */
438 struct acpi_dmar_header *hdr; /* ACPI header */
439 u64 base_address; /* reserved base address*/
440 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000441 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800442 int devices_cnt; /* target device count */
Eric Auger0659b8d2017-01-19 20:57:53 +0000443 struct iommu_resv_region *resv; /* reserved region handle */
Jiang Liub94e4112014-02-19 14:07:25 +0800444};
445
446struct dmar_atsr_unit {
447 struct list_head list; /* list of ATSR units */
448 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000449 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800450 int devices_cnt; /* target device count */
451 u8 include_all:1; /* include all ports */
452};
453
454static LIST_HEAD(dmar_atsr_units);
455static LIST_HEAD(dmar_rmrr_units);
456
457#define for_each_rmrr_units(rmrr) \
458 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
459
mark gross5e0d2a62008-03-04 15:22:08 -0800460/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800461static int g_num_of_iommus;
462
Jiang Liu92d03cc2014-02-19 14:07:28 +0800463static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700464static void domain_remove_dev_info(struct dmar_domain *domain);
Joerg Roedele6de0f82015-07-22 16:30:36 +0200465static void dmar_remove_one_dev_info(struct dmar_domain *domain,
466 struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200467static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Joerg Roedel2452d9d2015-07-23 16:20:14 +0200468static void domain_context_clear(struct intel_iommu *iommu,
469 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800470static int domain_detach_iommu(struct dmar_domain *domain,
471 struct intel_iommu *iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700472
Suresh Siddhad3f13812011-08-23 17:05:25 -0700473#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800474int dmar_disabled = 0;
475#else
476int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700477#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800478
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200479int intel_iommu_enabled = 0;
480EXPORT_SYMBOL_GPL(intel_iommu_enabled);
481
David Woodhouse2d9e6672010-06-15 10:57:57 +0100482static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700483static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800484static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100485static int intel_iommu_superpage = 1;
David Woodhousec83b2f22015-06-12 10:15:49 +0100486static int intel_iommu_ecs = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100487static int iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100488
David Woodhouseae853dd2015-09-09 11:58:59 +0100489#define IDENTMAP_ALL 1
490#define IDENTMAP_GFX 2
491#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100492
Lu Baoluab967462018-05-04 13:08:18 +0800493#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap))
494#define pasid_enabled(iommu) (ecs_enabled(iommu) && ecap_pasid(iommu->ecap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700495
David Woodhousec0771df2011-10-14 20:59:46 +0100496int intel_iommu_gfx_mapped;
497EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
498
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700499#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
500static DEFINE_SPINLOCK(device_domain_lock);
501static LIST_HEAD(device_domain_list);
502
Joerg Roedelb0119e82017-02-01 13:23:08 +0100503const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100504
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200505static bool translation_pre_enabled(struct intel_iommu *iommu)
506{
507 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
508}
509
Joerg Roedel091d42e2015-06-12 11:56:10 +0200510static void clear_translation_pre_enabled(struct intel_iommu *iommu)
511{
512 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
513}
514
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200515static void init_translation_status(struct intel_iommu *iommu)
516{
517 u32 gsts;
518
519 gsts = readl(iommu->reg + DMAR_GSTS_REG);
520 if (gsts & DMA_GSTS_TES)
521 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
522}
523
Joerg Roedel00a77de2015-03-26 13:43:08 +0100524/* Convert generic 'struct iommu_domain to private struct dmar_domain */
525static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
526{
527 return container_of(dom, struct dmar_domain, domain);
528}
529
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700530static int __init intel_iommu_setup(char *str)
531{
532 if (!str)
533 return -EINVAL;
534 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800535 if (!strncmp(str, "on", 2)) {
536 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200537 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800538 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700539 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200540 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700541 } else if (!strncmp(str, "igfx_off", 8)) {
542 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200543 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700544 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200545 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700546 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800547 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200548 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800549 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100550 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200551 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100552 intel_iommu_superpage = 0;
David Woodhousec83b2f22015-06-12 10:15:49 +0100553 } else if (!strncmp(str, "ecs_off", 7)) {
554 printk(KERN_INFO
555 "Intel-IOMMU: disable extended context table support\n");
556 intel_iommu_ecs = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700557 } else if (!strncmp(str, "tboot_noforce", 13)) {
558 printk(KERN_INFO
559 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
560 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700561 }
562
563 str += strcspn(str, ",");
564 while (*str == ',')
565 str++;
566 }
567 return 0;
568}
569__setup("intel_iommu=", intel_iommu_setup);
570
571static struct kmem_cache *iommu_domain_cache;
572static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700573
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200574static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
575{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200576 struct dmar_domain **domains;
577 int idx = did >> 8;
578
579 domains = iommu->domains[idx];
580 if (!domains)
581 return NULL;
582
583 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200584}
585
586static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
587 struct dmar_domain *domain)
588{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200589 struct dmar_domain **domains;
590 int idx = did >> 8;
591
592 if (!iommu->domains[idx]) {
593 size_t size = 256 * sizeof(struct dmar_domain *);
594 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
595 }
596
597 domains = iommu->domains[idx];
598 if (WARN_ON(!domains))
599 return;
600 else
601 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200602}
603
Suresh Siddha4c923d42009-10-02 11:01:24 -0700604static inline void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700605{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700606 struct page *page;
607 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700608
Suresh Siddha4c923d42009-10-02 11:01:24 -0700609 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
610 if (page)
611 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700612 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700613}
614
615static inline void free_pgtable_page(void *vaddr)
616{
617 free_page((unsigned long)vaddr);
618}
619
620static inline void *alloc_domain_mem(void)
621{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900622 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700623}
624
Kay, Allen M38717942008-09-09 18:37:29 +0300625static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700626{
627 kmem_cache_free(iommu_domain_cache, vaddr);
628}
629
630static inline void * alloc_devinfo_mem(void)
631{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900632 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700633}
634
635static inline void free_devinfo_mem(void *vaddr)
636{
637 kmem_cache_free(iommu_devinfo_cache, vaddr);
638}
639
Jiang Liuab8dfe22014-07-11 14:19:27 +0800640static inline int domain_type_is_vm(struct dmar_domain *domain)
641{
642 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
643}
644
Joerg Roedel28ccce02015-07-21 14:45:31 +0200645static inline int domain_type_is_si(struct dmar_domain *domain)
646{
647 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
648}
649
Jiang Liuab8dfe22014-07-11 14:19:27 +0800650static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
651{
652 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
653 DOMAIN_FLAG_STATIC_IDENTITY);
654}
Weidong Han1b573682008-12-08 15:34:06 +0800655
Jiang Liu162d1b12014-07-11 14:19:35 +0800656static inline int domain_pfn_supported(struct dmar_domain *domain,
657 unsigned long pfn)
658{
659 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
660
661 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
662}
663
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700664static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800665{
666 unsigned long sagaw;
667 int agaw = -1;
668
669 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700670 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800671 agaw >= 0; agaw--) {
672 if (test_bit(agaw, &sagaw))
673 break;
674 }
675
676 return agaw;
677}
678
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700679/*
680 * Calculate max SAGAW for each iommu.
681 */
682int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
683{
684 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
685}
686
687/*
688 * calculate agaw for each iommu.
689 * "SAGAW" may be different across iommus, use a default agaw, and
690 * get a supported less agaw for iommus that don't support the default agaw.
691 */
692int iommu_calculate_agaw(struct intel_iommu *iommu)
693{
694 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
695}
696
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700697/* This functionin only returns single iommu in a domain */
Weidong Han8c11e792008-12-08 15:29:22 +0800698static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
699{
700 int iommu_id;
701
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700702 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800703 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200704 for_each_domain_iommu(iommu_id, domain)
705 break;
706
Weidong Han8c11e792008-12-08 15:29:22 +0800707 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
708 return NULL;
709
710 return g_iommus[iommu_id];
711}
712
Weidong Han8e6040972008-12-08 15:49:06 +0800713static void domain_update_iommu_coherency(struct dmar_domain *domain)
714{
David Woodhoused0501962014-03-11 17:10:29 -0700715 struct dmar_drhd_unit *drhd;
716 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100717 bool found = false;
718 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800719
David Woodhoused0501962014-03-11 17:10:29 -0700720 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800721
Joerg Roedel29a27712015-07-21 17:17:12 +0200722 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100723 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800724 if (!ecap_coherent(g_iommus[i]->ecap)) {
725 domain->iommu_coherency = 0;
726 break;
727 }
Weidong Han8e6040972008-12-08 15:49:06 +0800728 }
David Woodhoused0501962014-03-11 17:10:29 -0700729 if (found)
730 return;
731
732 /* No hardware attached; use lowest common denominator */
733 rcu_read_lock();
734 for_each_active_iommu(iommu, drhd) {
735 if (!ecap_coherent(iommu->ecap)) {
736 domain->iommu_coherency = 0;
737 break;
738 }
739 }
740 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800741}
742
Jiang Liu161f6932014-07-11 14:19:37 +0800743static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100744{
Allen Kay8140a952011-10-14 12:32:17 -0700745 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800746 struct intel_iommu *iommu;
747 int ret = 1;
748
749 rcu_read_lock();
750 for_each_active_iommu(iommu, drhd) {
751 if (iommu != skip) {
752 if (!ecap_sc_support(iommu->ecap)) {
753 ret = 0;
754 break;
755 }
756 }
757 }
758 rcu_read_unlock();
759
760 return ret;
761}
762
763static int domain_update_iommu_superpage(struct intel_iommu *skip)
764{
765 struct dmar_drhd_unit *drhd;
766 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700767 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100768
769 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800770 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100771 }
772
Allen Kay8140a952011-10-14 12:32:17 -0700773 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800774 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700775 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800776 if (iommu != skip) {
777 mask &= cap_super_page_val(iommu->cap);
778 if (!mask)
779 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100780 }
781 }
Jiang Liu0e242612014-02-19 14:07:34 +0800782 rcu_read_unlock();
783
Jiang Liu161f6932014-07-11 14:19:37 +0800784 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100785}
786
Sheng Yang58c610b2009-03-18 15:33:05 +0800787/* Some capabilities may be different across iommus */
788static void domain_update_iommu_cap(struct dmar_domain *domain)
789{
790 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800791 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
792 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800793}
794
David Woodhouse03ecc322015-02-13 14:35:21 +0000795static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu,
796 u8 bus, u8 devfn, int alloc)
797{
798 struct root_entry *root = &iommu->root_entry[bus];
799 struct context_entry *context;
800 u64 *entry;
801
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200802 entry = &root->lo;
David Woodhousec83b2f22015-06-12 10:15:49 +0100803 if (ecs_enabled(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000804 if (devfn >= 0x80) {
805 devfn -= 0x80;
806 entry = &root->hi;
807 }
808 devfn *= 2;
809 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000810 if (*entry & 1)
811 context = phys_to_virt(*entry & VTD_PAGE_MASK);
812 else {
813 unsigned long phy_addr;
814 if (!alloc)
815 return NULL;
816
817 context = alloc_pgtable_page(iommu->node);
818 if (!context)
819 return NULL;
820
821 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
822 phy_addr = virt_to_phys((void *)context);
823 *entry = phy_addr | 1;
824 __iommu_flush_cache(iommu, entry, sizeof(*entry));
825 }
826 return &context[devfn];
827}
828
David Woodhouse4ed6a542015-05-11 14:59:20 +0100829static int iommu_dummy(struct device *dev)
830{
831 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
832}
833
David Woodhouse156baca2014-03-09 14:00:57 -0700834static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800835{
836 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800837 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700838 struct device *tmp;
839 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800840 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800841 int i;
842
David Woodhouse4ed6a542015-05-11 14:59:20 +0100843 if (iommu_dummy(dev))
844 return NULL;
845
David Woodhouse156baca2014-03-09 14:00:57 -0700846 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700847 struct pci_dev *pf_pdev;
848
David Woodhouse156baca2014-03-09 14:00:57 -0700849 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600850
851#ifdef CONFIG_X86
852 /* VMD child devices currently cannot be handled individually */
853 if (is_vmd(pdev->bus))
854 return NULL;
855#endif
856
Ashok Raj1c387182016-10-21 15:32:05 -0700857 /* VFs aren't listed in scope tables; we need to look up
858 * the PF instead to find the IOMMU. */
859 pf_pdev = pci_physfn(pdev);
860 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700861 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100862 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700863 dev = &ACPI_COMPANION(dev)->dev;
864
Jiang Liu0e242612014-02-19 14:07:34 +0800865 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800866 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700867 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100868 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800869
Jiang Liub683b232014-02-19 14:07:32 +0800870 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700871 drhd->devices_cnt, i, tmp) {
872 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700873 /* For a VF use its original BDF# not that of the PF
874 * which we used for the IOMMU lookup. Strictly speaking
875 * we could do this for all PCI devices; we only need to
876 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100877 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700878 goto got_pdev;
879
David Woodhouse156baca2014-03-09 14:00:57 -0700880 *bus = drhd->devices[i].bus;
881 *devfn = drhd->devices[i].devfn;
882 goto out;
883 }
884
885 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000886 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700887
888 ptmp = to_pci_dev(tmp);
889 if (ptmp->subordinate &&
890 ptmp->subordinate->number <= pdev->bus->number &&
891 ptmp->subordinate->busn_res.end >= pdev->bus->number)
892 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100893 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800894
David Woodhouse156baca2014-03-09 14:00:57 -0700895 if (pdev && drhd->include_all) {
896 got_pdev:
897 *bus = pdev->bus->number;
898 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800899 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700900 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800901 }
Jiang Liub683b232014-02-19 14:07:32 +0800902 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700903 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800904 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800905
Jiang Liub683b232014-02-19 14:07:32 +0800906 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800907}
908
Weidong Han5331fe62008-12-08 23:00:00 +0800909static void domain_flush_cache(struct dmar_domain *domain,
910 void *addr, int size)
911{
912 if (!domain->iommu_coherency)
913 clflush_cache_range(addr, size);
914}
915
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700916static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
917{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700918 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000919 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700920 unsigned long flags;
921
922 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000923 context = iommu_context_addr(iommu, bus, devfn, 0);
924 if (context)
925 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700926 spin_unlock_irqrestore(&iommu->lock, flags);
927 return ret;
928}
929
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700930static void free_context_table(struct intel_iommu *iommu)
931{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700932 int i;
933 unsigned long flags;
934 struct context_entry *context;
935
936 spin_lock_irqsave(&iommu->lock, flags);
937 if (!iommu->root_entry) {
938 goto out;
939 }
940 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000941 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700942 if (context)
943 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000944
David Woodhousec83b2f22015-06-12 10:15:49 +0100945 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000946 continue;
947
948 context = iommu_context_addr(iommu, i, 0x80, 0);
949 if (context)
950 free_pgtable_page(context);
951
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700952 }
953 free_pgtable_page(iommu->root_entry);
954 iommu->root_entry = NULL;
955out:
956 spin_unlock_irqrestore(&iommu->lock, flags);
957}
958
David Woodhouseb026fd22009-06-28 10:37:25 +0100959static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000960 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700961{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700962 struct dma_pte *parent, *pte = NULL;
963 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700964 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700965
966 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200967
Jiang Liu162d1b12014-07-11 14:19:35 +0800968 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200969 /* Address beyond IOMMU's addressing capabilities. */
970 return NULL;
971
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700972 parent = domain->pgd;
973
David Woodhouse5cf0a762014-03-19 16:07:49 +0000974 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700975 void *tmp_page;
976
David Woodhouseb026fd22009-06-28 10:37:25 +0100977 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700978 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000979 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100980 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000981 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700982 break;
983
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000984 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100985 uint64_t pteval;
986
Suresh Siddha4c923d42009-10-02 11:01:24 -0700987 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700988
David Woodhouse206a73c2009-07-01 19:30:28 +0100989 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700990 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100991
David Woodhousec85994e2009-07-01 19:21:24 +0100992 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400993 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 +0800994 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100995 /* Someone else set it while we were thinking; use theirs. */
996 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800997 else
David Woodhousec85994e2009-07-01 19:21:24 +0100998 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700999 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001000 if (level == 1)
1001 break;
1002
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001003 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001004 level--;
1005 }
1006
David Woodhouse5cf0a762014-03-19 16:07:49 +00001007 if (!*target_level)
1008 *target_level = level;
1009
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001010 return pte;
1011}
1012
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001013
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001014/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001015static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1016 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001017 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001018{
1019 struct dma_pte *parent, *pte = NULL;
1020 int total = agaw_to_level(domain->agaw);
1021 int offset;
1022
1023 parent = domain->pgd;
1024 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001025 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001026 pte = &parent[offset];
1027 if (level == total)
1028 return pte;
1029
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001030 if (!dma_pte_present(pte)) {
1031 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001032 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001033 }
1034
Yijing Wange16922a2014-05-20 20:37:51 +08001035 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001036 *large_page = total;
1037 return pte;
1038 }
1039
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001040 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001041 total--;
1042 }
1043 return NULL;
1044}
1045
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001046/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001047static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001048 unsigned long start_pfn,
1049 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001050{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001051 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001052 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001053
Jiang Liu162d1b12014-07-11 14:19:35 +08001054 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1055 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001056 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001057
David Woodhouse04b18e62009-06-27 19:15:01 +01001058 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001059 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001060 large_page = 1;
1061 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001062 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001063 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001064 continue;
1065 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001066 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001067 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001068 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001069 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001070 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1071
David Woodhouse310a5ab2009-06-28 18:52:20 +01001072 domain_flush_cache(domain, first_pte,
1073 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001074
1075 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001076}
1077
Alex Williamson3269ee02013-06-15 10:27:19 -06001078static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001079 int retain_level, struct dma_pte *pte,
1080 unsigned long pfn, unsigned long start_pfn,
1081 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001082{
1083 pfn = max(start_pfn, pfn);
1084 pte = &pte[pfn_level_offset(pfn, level)];
1085
1086 do {
1087 unsigned long level_pfn;
1088 struct dma_pte *level_pte;
1089
1090 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1091 goto next;
1092
David Dillowf7116e12017-01-30 19:11:11 -08001093 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001094 level_pte = phys_to_virt(dma_pte_addr(pte));
1095
David Dillowbc24c572017-06-28 19:42:23 -07001096 if (level > 2) {
1097 dma_pte_free_level(domain, level - 1, retain_level,
1098 level_pte, level_pfn, start_pfn,
1099 last_pfn);
1100 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001101
David Dillowbc24c572017-06-28 19:42:23 -07001102 /*
1103 * Free the page table if we're below the level we want to
1104 * retain and the range covers the entire table.
1105 */
1106 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001107 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001108 dma_clear_pte(pte);
1109 domain_flush_cache(domain, pte, sizeof(*pte));
1110 free_pgtable_page(level_pte);
1111 }
1112next:
1113 pfn += level_size(level);
1114 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1115}
1116
David Dillowbc24c572017-06-28 19:42:23 -07001117/*
1118 * clear last level (leaf) ptes and free page table pages below the
1119 * level we wish to keep intact.
1120 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001121static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001122 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001123 unsigned long last_pfn,
1124 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001125{
Jiang Liu162d1b12014-07-11 14:19:35 +08001126 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1127 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001128 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001129
Jiang Liud41a4ad2014-07-11 14:19:34 +08001130 dma_pte_clear_range(domain, start_pfn, last_pfn);
1131
David Woodhousef3a0a522009-06-30 03:40:07 +01001132 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001133 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001134 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001135
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001136 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001137 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001138 free_pgtable_page(domain->pgd);
1139 domain->pgd = NULL;
1140 }
1141}
1142
David Woodhouseea8ea462014-03-05 17:09:32 +00001143/* When a page at a given level is being unlinked from its parent, we don't
1144 need to *modify* it at all. All we need to do is make a list of all the
1145 pages which can be freed just as soon as we've flushed the IOTLB and we
1146 know the hardware page-walk will no longer touch them.
1147 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1148 be freed. */
1149static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1150 int level, struct dma_pte *pte,
1151 struct page *freelist)
1152{
1153 struct page *pg;
1154
1155 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1156 pg->freelist = freelist;
1157 freelist = pg;
1158
1159 if (level == 1)
1160 return freelist;
1161
Jiang Liuadeb2592014-04-09 10:20:39 +08001162 pte = page_address(pg);
1163 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001164 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1165 freelist = dma_pte_list_pagetables(domain, level - 1,
1166 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001167 pte++;
1168 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001169
1170 return freelist;
1171}
1172
1173static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1174 struct dma_pte *pte, unsigned long pfn,
1175 unsigned long start_pfn,
1176 unsigned long last_pfn,
1177 struct page *freelist)
1178{
1179 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1180
1181 pfn = max(start_pfn, pfn);
1182 pte = &pte[pfn_level_offset(pfn, level)];
1183
1184 do {
1185 unsigned long level_pfn;
1186
1187 if (!dma_pte_present(pte))
1188 goto next;
1189
1190 level_pfn = pfn & level_mask(level);
1191
1192 /* If range covers entire pagetable, free it */
1193 if (start_pfn <= level_pfn &&
1194 last_pfn >= level_pfn + level_size(level) - 1) {
1195 /* These suborbinate page tables are going away entirely. Don't
1196 bother to clear them; we're just going to *free* them. */
1197 if (level > 1 && !dma_pte_superpage(pte))
1198 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1199
1200 dma_clear_pte(pte);
1201 if (!first_pte)
1202 first_pte = pte;
1203 last_pte = pte;
1204 } else if (level > 1) {
1205 /* Recurse down into a level that isn't *entirely* obsolete */
1206 freelist = dma_pte_clear_level(domain, level - 1,
1207 phys_to_virt(dma_pte_addr(pte)),
1208 level_pfn, start_pfn, last_pfn,
1209 freelist);
1210 }
1211next:
1212 pfn += level_size(level);
1213 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1214
1215 if (first_pte)
1216 domain_flush_cache(domain, first_pte,
1217 (void *)++last_pte - (void *)first_pte);
1218
1219 return freelist;
1220}
1221
1222/* We can't just free the pages because the IOMMU may still be walking
1223 the page tables, and may have cached the intermediate levels. The
1224 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001225static struct page *domain_unmap(struct dmar_domain *domain,
1226 unsigned long start_pfn,
1227 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001228{
David Woodhouseea8ea462014-03-05 17:09:32 +00001229 struct page *freelist = NULL;
1230
Jiang Liu162d1b12014-07-11 14:19:35 +08001231 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1232 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001233 BUG_ON(start_pfn > last_pfn);
1234
1235 /* we don't need lock here; nobody else touches the iova range */
1236 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1237 domain->pgd, 0, start_pfn, last_pfn, NULL);
1238
1239 /* free pgd */
1240 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1241 struct page *pgd_page = virt_to_page(domain->pgd);
1242 pgd_page->freelist = freelist;
1243 freelist = pgd_page;
1244
1245 domain->pgd = NULL;
1246 }
1247
1248 return freelist;
1249}
1250
Joerg Roedelb6904202015-08-13 11:32:18 +02001251static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001252{
1253 struct page *pg;
1254
1255 while ((pg = freelist)) {
1256 freelist = pg->freelist;
1257 free_pgtable_page(page_address(pg));
1258 }
1259}
1260
Joerg Roedel13cf0172017-08-11 11:40:10 +02001261static void iova_entry_free(unsigned long data)
1262{
1263 struct page *freelist = (struct page *)data;
1264
1265 dma_free_pagelist(freelist);
1266}
1267
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001268/* iommu handling */
1269static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1270{
1271 struct root_entry *root;
1272 unsigned long flags;
1273
Suresh Siddha4c923d42009-10-02 11:01:24 -07001274 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001275 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001276 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001277 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001278 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001279 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001280
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001281 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001282
1283 spin_lock_irqsave(&iommu->lock, flags);
1284 iommu->root_entry = root;
1285 spin_unlock_irqrestore(&iommu->lock, flags);
1286
1287 return 0;
1288}
1289
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001290static void iommu_set_root_entry(struct intel_iommu *iommu)
1291{
David Woodhouse03ecc322015-02-13 14:35:21 +00001292 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001293 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001294 unsigned long flag;
1295
David Woodhouse03ecc322015-02-13 14:35:21 +00001296 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001297 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001298 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001299
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001300 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001301 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001302
David Woodhousec416daa2009-05-10 20:30:58 +01001303 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001304
1305 /* Make sure hardware complete it */
1306 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001307 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001308
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001309 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001310}
1311
1312static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1313{
1314 u32 val;
1315 unsigned long flag;
1316
David Woodhouse9af88142009-02-13 23:18:03 +00001317 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001318 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001319
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001320 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001321 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001322
1323 /* Make sure hardware complete it */
1324 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001325 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001326
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001327 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001328}
1329
1330/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001331static void __iommu_flush_context(struct intel_iommu *iommu,
1332 u16 did, u16 source_id, u8 function_mask,
1333 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001334{
1335 u64 val = 0;
1336 unsigned long flag;
1337
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001338 switch (type) {
1339 case DMA_CCMD_GLOBAL_INVL:
1340 val = DMA_CCMD_GLOBAL_INVL;
1341 break;
1342 case DMA_CCMD_DOMAIN_INVL:
1343 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1344 break;
1345 case DMA_CCMD_DEVICE_INVL:
1346 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1347 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1348 break;
1349 default:
1350 BUG();
1351 }
1352 val |= DMA_CCMD_ICC;
1353
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001354 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001355 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1356
1357 /* Make sure hardware complete it */
1358 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1359 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1360
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001361 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001362}
1363
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001364/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001365static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1366 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001367{
1368 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1369 u64 val = 0, val_iva = 0;
1370 unsigned long flag;
1371
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001372 switch (type) {
1373 case DMA_TLB_GLOBAL_FLUSH:
1374 /* global flush doesn't need set IVA_REG */
1375 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1376 break;
1377 case DMA_TLB_DSI_FLUSH:
1378 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1379 break;
1380 case DMA_TLB_PSI_FLUSH:
1381 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001382 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001383 val_iva = size_order | addr;
1384 break;
1385 default:
1386 BUG();
1387 }
1388 /* Note: set drain read/write */
1389#if 0
1390 /*
1391 * This is probably to be super secure.. Looks like we can
1392 * ignore it without any impact.
1393 */
1394 if (cap_read_drain(iommu->cap))
1395 val |= DMA_TLB_READ_DRAIN;
1396#endif
1397 if (cap_write_drain(iommu->cap))
1398 val |= DMA_TLB_WRITE_DRAIN;
1399
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001400 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001401 /* Note: Only uses first TLB reg currently */
1402 if (val_iva)
1403 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1404 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1405
1406 /* Make sure hardware complete it */
1407 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1408 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1409
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001410 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001411
1412 /* check IOTLB invalidation granularity */
1413 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001414 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001415 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001416 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001417 (unsigned long long)DMA_TLB_IIRG(type),
1418 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001419}
1420
David Woodhouse64ae8922014-03-09 12:52:30 -07001421static struct device_domain_info *
1422iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1423 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001424{
Yu Zhao93a23a72009-05-18 13:51:37 +08001425 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001426
Joerg Roedel55d94042015-07-22 16:50:40 +02001427 assert_spin_locked(&device_domain_lock);
1428
Yu Zhao93a23a72009-05-18 13:51:37 +08001429 if (!iommu->qi)
1430 return NULL;
1431
Yu Zhao93a23a72009-05-18 13:51:37 +08001432 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001433 if (info->iommu == iommu && info->bus == bus &&
1434 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001435 if (info->ats_supported && info->dev)
1436 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001437 break;
1438 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001439
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001440 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001441}
1442
Omer Peleg0824c592016-04-20 19:03:35 +03001443static void domain_update_iotlb(struct dmar_domain *domain)
1444{
1445 struct device_domain_info *info;
1446 bool has_iotlb_device = false;
1447
1448 assert_spin_locked(&device_domain_lock);
1449
1450 list_for_each_entry(info, &domain->devices, link) {
1451 struct pci_dev *pdev;
1452
1453 if (!info->dev || !dev_is_pci(info->dev))
1454 continue;
1455
1456 pdev = to_pci_dev(info->dev);
1457 if (pdev->ats_enabled) {
1458 has_iotlb_device = true;
1459 break;
1460 }
1461 }
1462
1463 domain->has_iotlb_device = has_iotlb_device;
1464}
1465
Yu Zhao93a23a72009-05-18 13:51:37 +08001466static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1467{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001468 struct pci_dev *pdev;
1469
Omer Peleg0824c592016-04-20 19:03:35 +03001470 assert_spin_locked(&device_domain_lock);
1471
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001472 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001473 return;
1474
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001475 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001476
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001477#ifdef CONFIG_INTEL_IOMMU_SVM
1478 /* The PCIe spec, in its wisdom, declares that the behaviour of
1479 the device if you enable PASID support after ATS support is
1480 undefined. So always enable PASID support on devices which
1481 have it, even if we can't yet know if we're ever going to
1482 use it. */
1483 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1484 info->pasid_enabled = 1;
1485
1486 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1487 info->pri_enabled = 1;
1488#endif
1489 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1490 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001491 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001492 info->ats_qdep = pci_ats_queue_depth(pdev);
1493 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001494}
1495
1496static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1497{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001498 struct pci_dev *pdev;
1499
Omer Peleg0824c592016-04-20 19:03:35 +03001500 assert_spin_locked(&device_domain_lock);
1501
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001502 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001503 return;
1504
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001505 pdev = to_pci_dev(info->dev);
1506
1507 if (info->ats_enabled) {
1508 pci_disable_ats(pdev);
1509 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001510 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001511 }
1512#ifdef CONFIG_INTEL_IOMMU_SVM
1513 if (info->pri_enabled) {
1514 pci_disable_pri(pdev);
1515 info->pri_enabled = 0;
1516 }
1517 if (info->pasid_enabled) {
1518 pci_disable_pasid(pdev);
1519 info->pasid_enabled = 0;
1520 }
1521#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001522}
1523
1524static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1525 u64 addr, unsigned mask)
1526{
1527 u16 sid, qdep;
1528 unsigned long flags;
1529 struct device_domain_info *info;
1530
Omer Peleg0824c592016-04-20 19:03:35 +03001531 if (!domain->has_iotlb_device)
1532 return;
1533
Yu Zhao93a23a72009-05-18 13:51:37 +08001534 spin_lock_irqsave(&device_domain_lock, flags);
1535 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001536 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001537 continue;
1538
1539 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001540 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001541 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1542 }
1543 spin_unlock_irqrestore(&device_domain_lock, flags);
1544}
1545
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001546static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1547 struct dmar_domain *domain,
1548 unsigned long pfn, unsigned int pages,
1549 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001550{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001551 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001552 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001553 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001554
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001555 BUG_ON(pages == 0);
1556
David Woodhouseea8ea462014-03-05 17:09:32 +00001557 if (ih)
1558 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001559 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001560 * Fallback to domain selective flush if no PSI support or the size is
1561 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001562 * PSI requires page size to be 2 ^ x, and the base address is naturally
1563 * aligned to the size
1564 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001565 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1566 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001567 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001568 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001569 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001570 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001571
1572 /*
Nadav Amit82653632010-04-01 13:24:40 +03001573 * In caching mode, changes of pages from non-present to present require
1574 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001575 */
Nadav Amit82653632010-04-01 13:24:40 +03001576 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001577 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001578}
1579
Peter Xueed91a02018-05-04 10:34:52 +08001580/* Notification for newly created mappings */
1581static inline void __mapping_notify_one(struct intel_iommu *iommu,
1582 struct dmar_domain *domain,
1583 unsigned long pfn, unsigned int pages)
1584{
1585 /* It's a non-present to present mapping. Only flush if caching mode */
1586 if (cap_caching_mode(iommu->cap))
1587 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1588 else
1589 iommu_flush_write_buffer(iommu);
1590}
1591
Joerg Roedel13cf0172017-08-11 11:40:10 +02001592static void iommu_flush_iova(struct iova_domain *iovad)
1593{
1594 struct dmar_domain *domain;
1595 int idx;
1596
1597 domain = container_of(iovad, struct dmar_domain, iovad);
1598
1599 for_each_domain_iommu(idx, domain) {
1600 struct intel_iommu *iommu = g_iommus[idx];
1601 u16 did = domain->iommu_did[iommu->seq_id];
1602
1603 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1604
1605 if (!cap_caching_mode(iommu->cap))
1606 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1607 0, MAX_AGAW_PFN_WIDTH);
1608 }
1609}
1610
mark grossf8bab732008-02-08 04:18:38 -08001611static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1612{
1613 u32 pmen;
1614 unsigned long flags;
1615
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001616 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001617 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1618 pmen &= ~DMA_PMEN_EPM;
1619 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1620
1621 /* wait for the protected region status bit to clear */
1622 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1623 readl, !(pmen & DMA_PMEN_PRS), pmen);
1624
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001625 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001626}
1627
Jiang Liu2a41cce2014-07-11 14:19:33 +08001628static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001629{
1630 u32 sts;
1631 unsigned long flags;
1632
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001633 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001634 iommu->gcmd |= DMA_GCMD_TE;
1635 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001636
1637 /* Make sure hardware complete it */
1638 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001639 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001640
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001641 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001642}
1643
Jiang Liu2a41cce2014-07-11 14:19:33 +08001644static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001645{
1646 u32 sts;
1647 unsigned long flag;
1648
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001649 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001650 iommu->gcmd &= ~DMA_GCMD_TE;
1651 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1652
1653 /* Make sure hardware complete it */
1654 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001655 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001656
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001657 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001658}
1659
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001660
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001661static int iommu_init_domains(struct intel_iommu *iommu)
1662{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001663 u32 ndomains, nlongs;
1664 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001665
1666 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001667 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001668 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001669 nlongs = BITS_TO_LONGS(ndomains);
1670
Donald Dutile94a91b52009-08-20 16:51:34 -04001671 spin_lock_init(&iommu->lock);
1672
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001673 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1674 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001675 pr_err("%s: Allocating domain id array failed\n",
1676 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001677 return -ENOMEM;
1678 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001679
Wei Yang86f004c2016-05-21 02:41:51 +00001680 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001681 iommu->domains = kzalloc(size, GFP_KERNEL);
1682
1683 if (iommu->domains) {
1684 size = 256 * sizeof(struct dmar_domain *);
1685 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1686 }
1687
1688 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001689 pr_err("%s: Allocating domain array failed\n",
1690 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001691 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001692 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001693 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001694 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001695 return -ENOMEM;
1696 }
1697
Joerg Roedel8bf47812015-07-21 10:41:21 +02001698
1699
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001700 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001701 * If Caching mode is set, then invalid translations are tagged
1702 * with domain-id 0, hence we need to pre-allocate it. We also
1703 * use domain-id 0 as a marker for non-allocated domain-id, so
1704 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001705 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001706 set_bit(0, iommu->domain_ids);
1707
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001708 return 0;
1709}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001710
Jiang Liuffebeb42014-11-09 22:48:02 +08001711static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001712{
Joerg Roedel29a27712015-07-21 17:17:12 +02001713 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001714 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001715
Joerg Roedel29a27712015-07-21 17:17:12 +02001716 if (!iommu->domains || !iommu->domain_ids)
1717 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001718
Joerg Roedelbea64032016-11-08 15:08:26 +01001719again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001720 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001721 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1722 struct dmar_domain *domain;
1723
1724 if (info->iommu != iommu)
1725 continue;
1726
1727 if (!info->dev || !info->domain)
1728 continue;
1729
1730 domain = info->domain;
1731
Joerg Roedelbea64032016-11-08 15:08:26 +01001732 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001733
Joerg Roedelbea64032016-11-08 15:08:26 +01001734 if (!domain_type_is_vm_or_si(domain)) {
1735 /*
1736 * The domain_exit() function can't be called under
1737 * device_domain_lock, as it takes this lock itself.
1738 * So release the lock here and re-run the loop
1739 * afterwards.
1740 */
1741 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001742 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001743 goto again;
1744 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001745 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001746 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001747
1748 if (iommu->gcmd & DMA_GCMD_TE)
1749 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001750}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001751
Jiang Liuffebeb42014-11-09 22:48:02 +08001752static void free_dmar_iommu(struct intel_iommu *iommu)
1753{
1754 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001755 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001756 int i;
1757
1758 for (i = 0; i < elems; i++)
1759 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001760 kfree(iommu->domains);
1761 kfree(iommu->domain_ids);
1762 iommu->domains = NULL;
1763 iommu->domain_ids = NULL;
1764 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001765
Weidong Hand9630fe2008-12-08 11:06:32 +08001766 g_iommus[iommu->seq_id] = NULL;
1767
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001768 /* free context mapping */
1769 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001770
1771#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001772 if (pasid_enabled(iommu)) {
1773 if (ecap_prs(iommu->ecap))
1774 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001775 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001776 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001777#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001778}
1779
Jiang Liuab8dfe22014-07-11 14:19:27 +08001780static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001781{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001782 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001783
1784 domain = alloc_domain_mem();
1785 if (!domain)
1786 return NULL;
1787
Jiang Liuab8dfe22014-07-11 14:19:27 +08001788 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001789 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001790 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001791 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001792 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001793
1794 return domain;
1795}
1796
Joerg Roedeld160aca2015-07-22 11:52:53 +02001797/* Must be called with iommu->lock */
1798static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001799 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800{
Jiang Liu44bde612014-07-11 14:19:29 +08001801 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001802 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001803
Joerg Roedel55d94042015-07-22 16:50:40 +02001804 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001805 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001806
Joerg Roedel29a27712015-07-21 17:17:12 +02001807 domain->iommu_refcnt[iommu->seq_id] += 1;
1808 domain->iommu_count += 1;
1809 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001810 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001811 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1812
1813 if (num >= ndomains) {
1814 pr_err("%s: No free domain ids\n", iommu->name);
1815 domain->iommu_refcnt[iommu->seq_id] -= 1;
1816 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001817 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001818 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001819
Joerg Roedeld160aca2015-07-22 11:52:53 +02001820 set_bit(num, iommu->domain_ids);
1821 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001822
Joerg Roedeld160aca2015-07-22 11:52:53 +02001823 domain->iommu_did[iommu->seq_id] = num;
1824 domain->nid = iommu->node;
1825
Jiang Liufb170fb2014-07-11 14:19:28 +08001826 domain_update_iommu_cap(domain);
1827 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001828
Joerg Roedel55d94042015-07-22 16:50:40 +02001829 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001830}
1831
1832static int domain_detach_iommu(struct dmar_domain *domain,
1833 struct intel_iommu *iommu)
1834{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001835 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001836
Joerg Roedel55d94042015-07-22 16:50:40 +02001837 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001838 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001839
Joerg Roedel29a27712015-07-21 17:17:12 +02001840 domain->iommu_refcnt[iommu->seq_id] -= 1;
1841 count = --domain->iommu_count;
1842 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001843 num = domain->iommu_did[iommu->seq_id];
1844 clear_bit(num, iommu->domain_ids);
1845 set_iommu_domain(iommu, num, NULL);
1846
Jiang Liufb170fb2014-07-11 14:19:28 +08001847 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001848 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001849 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001850
1851 return count;
1852}
1853
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001854static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001855static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001856
Joseph Cihula51a63e62011-03-21 11:04:24 -07001857static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001858{
1859 struct pci_dev *pdev = NULL;
1860 struct iova *iova;
1861 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001862
Zhen Leiaa3ac942017-09-21 16:52:45 +01001863 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001864
Mark Gross8a443df2008-03-04 14:59:31 -08001865 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1866 &reserved_rbtree_key);
1867
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001868 /* IOAPIC ranges shouldn't be accessed by DMA */
1869 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1870 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001871 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001872 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001873 return -ENODEV;
1874 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875
1876 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1877 for_each_pci_dev(pdev) {
1878 struct resource *r;
1879
1880 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1881 r = &pdev->resource[i];
1882 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1883 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001884 iova = reserve_iova(&reserved_iova_list,
1885 IOVA_PFN(r->start),
1886 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001887 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001888 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001889 return -ENODEV;
1890 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001891 }
1892 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001893 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001894}
1895
1896static void domain_reserve_special_ranges(struct dmar_domain *domain)
1897{
1898 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1899}
1900
1901static inline int guestwidth_to_adjustwidth(int gaw)
1902{
1903 int agaw;
1904 int r = (gaw - 12) % 9;
1905
1906 if (r == 0)
1907 agaw = gaw;
1908 else
1909 agaw = gaw + 9 - r;
1910 if (agaw > 64)
1911 agaw = 64;
1912 return agaw;
1913}
1914
Joerg Roedeldc534b22015-07-22 12:44:02 +02001915static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1916 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001917{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001918 int adjust_width, agaw;
1919 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001920 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001921
Zhen Leiaa3ac942017-09-21 16:52:45 +01001922 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001923
1924 err = init_iova_flush_queue(&domain->iovad,
1925 iommu_flush_iova, iova_entry_free);
1926 if (err)
1927 return err;
1928
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001929 domain_reserve_special_ranges(domain);
1930
1931 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001932 if (guest_width > cap_mgaw(iommu->cap))
1933 guest_width = cap_mgaw(iommu->cap);
1934 domain->gaw = guest_width;
1935 adjust_width = guestwidth_to_adjustwidth(guest_width);
1936 agaw = width_to_agaw(adjust_width);
1937 sagaw = cap_sagaw(iommu->cap);
1938 if (!test_bit(agaw, &sagaw)) {
1939 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001940 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001941 agaw = find_next_bit(&sagaw, 5, agaw);
1942 if (agaw >= 5)
1943 return -ENODEV;
1944 }
1945 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946
Weidong Han8e6040972008-12-08 15:49:06 +08001947 if (ecap_coherent(iommu->ecap))
1948 domain->iommu_coherency = 1;
1949 else
1950 domain->iommu_coherency = 0;
1951
Sheng Yang58c610b2009-03-18 15:33:05 +08001952 if (ecap_sc_support(iommu->ecap))
1953 domain->iommu_snooping = 1;
1954 else
1955 domain->iommu_snooping = 0;
1956
David Woodhouse214e39a2014-03-19 10:38:49 +00001957 if (intel_iommu_superpage)
1958 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1959 else
1960 domain->iommu_superpage = 0;
1961
Suresh Siddha4c923d42009-10-02 11:01:24 -07001962 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001963
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001964 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001965 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001966 if (!domain->pgd)
1967 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001968 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001969 return 0;
1970}
1971
1972static void domain_exit(struct dmar_domain *domain)
1973{
David Woodhouseea8ea462014-03-05 17:09:32 +00001974 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001975
1976 /* Domain 0 is reserved, so dont process it */
1977 if (!domain)
1978 return;
1979
Joerg Roedeld160aca2015-07-22 11:52:53 +02001980 /* Remove associated devices and clear attached or cached domains */
1981 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001982 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001983 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08001984
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001985 /* destroy iovas */
1986 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001987
David Woodhouseea8ea462014-03-05 17:09:32 +00001988 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001989
David Woodhouseea8ea462014-03-05 17:09:32 +00001990 dma_free_pagelist(freelist);
1991
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001992 free_domain_mem(domain);
1993}
1994
David Woodhouse64ae8922014-03-09 12:52:30 -07001995static int domain_context_mapping_one(struct dmar_domain *domain,
1996 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001997 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001998{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001999 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002000 int translation = CONTEXT_TT_MULTI_LEVEL;
2001 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002003 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002004 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002005 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002006
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002007 WARN_ON(did == 0);
2008
Joerg Roedel28ccce02015-07-21 14:45:31 +02002009 if (hw_pass_through && domain_type_is_si(domain))
2010 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002011
2012 pr_debug("Set context mapping for %02x:%02x.%d\n",
2013 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002014
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002015 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002016
Joerg Roedel55d94042015-07-22 16:50:40 +02002017 spin_lock_irqsave(&device_domain_lock, flags);
2018 spin_lock(&iommu->lock);
2019
2020 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002021 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002022 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002023 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002024
Joerg Roedel55d94042015-07-22 16:50:40 +02002025 ret = 0;
2026 if (context_present(context))
2027 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002028
Xunlei Pangaec0e862016-12-05 20:09:07 +08002029 /*
2030 * For kdump cases, old valid entries may be cached due to the
2031 * in-flight DMA and copied pgtable, but there is no unmapping
2032 * behaviour for them, thus we need an explicit cache flush for
2033 * the newly-mapped device. For kdump, at this point, the device
2034 * is supposed to finish reset at its driver probe stage, so no
2035 * in-flight DMA will exist, and we don't need to worry anymore
2036 * hereafter.
2037 */
2038 if (context_copied(context)) {
2039 u16 did_old = context_domain_id(context);
2040
Christos Gkekasb117e032017-10-08 23:33:31 +01002041 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002042 iommu->flush.flush_context(iommu, did_old,
2043 (((u16)bus) << 8) | devfn,
2044 DMA_CCMD_MASK_NOBIT,
2045 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002046 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2047 DMA_TLB_DSI_FLUSH);
2048 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002049 }
2050
Weidong Hanea6606b2008-12-08 23:08:15 +08002051 pgd = domain->pgd;
2052
Joerg Roedelde24e552015-07-21 14:53:04 +02002053 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002054 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002055
Joerg Roedelde24e552015-07-21 14:53:04 +02002056 /*
2057 * Skip top levels of page tables for iommu which has less agaw
2058 * than default. Unnecessary for PT mode.
2059 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002060 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002061 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002062 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002063 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002064 if (!dma_pte_present(pgd))
2065 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002066 }
2067
David Woodhouse64ae8922014-03-09 12:52:30 -07002068 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002069 if (info && info->ats_supported)
2070 translation = CONTEXT_TT_DEV_IOTLB;
2071 else
2072 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002073
Yu Zhao93a23a72009-05-18 13:51:37 +08002074 context_set_address_root(context, virt_to_phys(pgd));
2075 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002076 } else {
2077 /*
2078 * In pass through mode, AW must be programmed to
2079 * indicate the largest AGAW value supported by
2080 * hardware. And ASR is ignored by hardware.
2081 */
2082 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002083 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002084
2085 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002086 context_set_fault_enable(context);
2087 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002088 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002089
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002090 /*
2091 * It's a non-present to present mapping. If hardware doesn't cache
2092 * non-present entry we only need to flush the write-buffer. If the
2093 * _does_ cache non-present entries, then it does so in the special
2094 * domain #0, which we have to flush:
2095 */
2096 if (cap_caching_mode(iommu->cap)) {
2097 iommu->flush.flush_context(iommu, 0,
2098 (((u16)bus) << 8) | devfn,
2099 DMA_CCMD_MASK_NOBIT,
2100 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002101 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002102 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002103 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002104 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002105 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002106
Joerg Roedel55d94042015-07-22 16:50:40 +02002107 ret = 0;
2108
2109out_unlock:
2110 spin_unlock(&iommu->lock);
2111 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002112
Wei Yang5c365d12016-07-13 13:53:21 +00002113 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002114}
2115
Alex Williamson579305f2014-07-03 09:51:43 -06002116struct domain_context_mapping_data {
2117 struct dmar_domain *domain;
2118 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002119};
2120
2121static int domain_context_mapping_cb(struct pci_dev *pdev,
2122 u16 alias, void *opaque)
2123{
2124 struct domain_context_mapping_data *data = opaque;
2125
2126 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002127 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002128}
2129
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002130static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002131domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002132{
David Woodhouse64ae8922014-03-09 12:52:30 -07002133 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002134 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002135 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002136
David Woodhousee1f167f2014-03-09 15:24:46 -07002137 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002138 if (!iommu)
2139 return -ENODEV;
2140
Alex Williamson579305f2014-07-03 09:51:43 -06002141 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002142 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002143
2144 data.domain = domain;
2145 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002146
2147 return pci_for_each_dma_alias(to_pci_dev(dev),
2148 &domain_context_mapping_cb, &data);
2149}
2150
2151static int domain_context_mapped_cb(struct pci_dev *pdev,
2152 u16 alias, void *opaque)
2153{
2154 struct intel_iommu *iommu = opaque;
2155
2156 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002157}
2158
David Woodhousee1f167f2014-03-09 15:24:46 -07002159static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002160{
Weidong Han5331fe62008-12-08 23:00:00 +08002161 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002162 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002163
David Woodhousee1f167f2014-03-09 15:24:46 -07002164 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002165 if (!iommu)
2166 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002167
Alex Williamson579305f2014-07-03 09:51:43 -06002168 if (!dev_is_pci(dev))
2169 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002170
Alex Williamson579305f2014-07-03 09:51:43 -06002171 return !pci_for_each_dma_alias(to_pci_dev(dev),
2172 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002173}
2174
Fenghua Yuf5329592009-08-04 15:09:37 -07002175/* Returns a number of VTD pages, but aligned to MM page size */
2176static inline unsigned long aligned_nrpages(unsigned long host_addr,
2177 size_t size)
2178{
2179 host_addr &= ~PAGE_MASK;
2180 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2181}
2182
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002183/* Return largest possible superpage level for a given mapping */
2184static inline int hardware_largepage_caps(struct dmar_domain *domain,
2185 unsigned long iov_pfn,
2186 unsigned long phy_pfn,
2187 unsigned long pages)
2188{
2189 int support, level = 1;
2190 unsigned long pfnmerge;
2191
2192 support = domain->iommu_superpage;
2193
2194 /* To use a large page, the virtual *and* physical addresses
2195 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2196 of them will mean we have to use smaller pages. So just
2197 merge them and check both at once. */
2198 pfnmerge = iov_pfn | phy_pfn;
2199
2200 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2201 pages >>= VTD_STRIDE_SHIFT;
2202 if (!pages)
2203 break;
2204 pfnmerge >>= VTD_STRIDE_SHIFT;
2205 level++;
2206 support--;
2207 }
2208 return level;
2209}
2210
David Woodhouse9051aa02009-06-29 12:30:54 +01002211static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2212 struct scatterlist *sg, unsigned long phys_pfn,
2213 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002214{
2215 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002216 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002217 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002218 unsigned int largepage_lvl = 0;
2219 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002220
Jiang Liu162d1b12014-07-11 14:19:35 +08002221 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002222
2223 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2224 return -EINVAL;
2225
2226 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2227
Jiang Liucc4f14a2014-11-26 09:42:10 +08002228 if (!sg) {
2229 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002230 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2231 }
2232
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002233 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002234 uint64_t tmp;
2235
David Woodhousee1605492009-06-29 11:17:38 +01002236 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002237 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2238
Fenghua Yuf5329592009-08-04 15:09:37 -07002239 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002240 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002241 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002242 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002243 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002244 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002245
David Woodhousee1605492009-06-29 11:17:38 +01002246 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002247 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2248
David Woodhouse5cf0a762014-03-19 16:07:49 +00002249 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002250 if (!pte)
2251 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002252 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002253 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002254 unsigned long nr_superpages, end_pfn;
2255
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002256 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002257 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002258
2259 nr_superpages = sg_res / lvl_pages;
2260 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2261
Jiang Liud41a4ad2014-07-11 14:19:34 +08002262 /*
2263 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002264 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002265 * We're adding new large pages, so make sure
2266 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002267 */
David Dillowbc24c572017-06-28 19:42:23 -07002268 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2269 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002270 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002271 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002272 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002273
David Woodhousee1605492009-06-29 11:17:38 +01002274 }
2275 /* We don't need lock here, nobody else
2276 * touches the iova range
2277 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002278 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002279 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002280 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002281 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2282 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002283 if (dumps) {
2284 dumps--;
2285 debug_dma_dump_mappings(NULL);
2286 }
2287 WARN_ON(1);
2288 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002289
2290 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2291
2292 BUG_ON(nr_pages < lvl_pages);
2293 BUG_ON(sg_res < lvl_pages);
2294
2295 nr_pages -= lvl_pages;
2296 iov_pfn += lvl_pages;
2297 phys_pfn += lvl_pages;
2298 pteval += lvl_pages * VTD_PAGE_SIZE;
2299 sg_res -= lvl_pages;
2300
2301 /* If the next PTE would be the first in a new page, then we
2302 need to flush the cache on the entries we've just written.
2303 And then we'll need to recalculate 'pte', so clear it and
2304 let it get set again in the if (!pte) block above.
2305
2306 If we're done (!nr_pages) we need to flush the cache too.
2307
2308 Also if we've been setting superpages, we may need to
2309 recalculate 'pte' and switch back to smaller pages for the
2310 end of the mapping, if the trailing size is not enough to
2311 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002312 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002313 if (!nr_pages || first_pte_in_page(pte) ||
2314 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002315 domain_flush_cache(domain, first_pte,
2316 (void *)pte - (void *)first_pte);
2317 pte = NULL;
2318 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002319
2320 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002321 sg = sg_next(sg);
2322 }
2323 return 0;
2324}
2325
Peter Xu87684fd2018-05-04 10:34:53 +08002326static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2327 struct scatterlist *sg, unsigned long phys_pfn,
2328 unsigned long nr_pages, int prot)
2329{
2330 int ret;
2331 struct intel_iommu *iommu;
2332
2333 /* Do the real mapping first */
2334 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2335 if (ret)
2336 return ret;
2337
2338 /* Notify about the new mapping */
2339 if (domain_type_is_vm(domain)) {
2340 /* VM typed domains can have more than one IOMMUs */
2341 int iommu_id;
2342 for_each_domain_iommu(iommu_id, domain) {
2343 iommu = g_iommus[iommu_id];
2344 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2345 }
2346 } else {
2347 /* General domains only have one IOMMU */
2348 iommu = domain_get_iommu(domain);
2349 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2350 }
2351
2352 return 0;
2353}
2354
David Woodhouse9051aa02009-06-29 12:30:54 +01002355static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2356 struct scatterlist *sg, unsigned long nr_pages,
2357 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002358{
Peter Xu87684fd2018-05-04 10:34:53 +08002359 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002360}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002361
David Woodhouse9051aa02009-06-29 12:30:54 +01002362static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2363 unsigned long phys_pfn, unsigned long nr_pages,
2364 int prot)
2365{
Peter Xu87684fd2018-05-04 10:34:53 +08002366 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002367}
2368
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002369static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002370{
Filippo Sironi50822192017-08-31 10:58:11 +02002371 unsigned long flags;
2372 struct context_entry *context;
2373 u16 did_old;
2374
Weidong Hanc7151a82008-12-08 22:51:37 +08002375 if (!iommu)
2376 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002377
Filippo Sironi50822192017-08-31 10:58:11 +02002378 spin_lock_irqsave(&iommu->lock, flags);
2379 context = iommu_context_addr(iommu, bus, devfn, 0);
2380 if (!context) {
2381 spin_unlock_irqrestore(&iommu->lock, flags);
2382 return;
2383 }
2384 did_old = context_domain_id(context);
2385 context_clear_entry(context);
2386 __iommu_flush_cache(iommu, context, sizeof(*context));
2387 spin_unlock_irqrestore(&iommu->lock, flags);
2388 iommu->flush.flush_context(iommu,
2389 did_old,
2390 (((u16)bus) << 8) | devfn,
2391 DMA_CCMD_MASK_NOBIT,
2392 DMA_CCMD_DEVICE_INVL);
2393 iommu->flush.flush_iotlb(iommu,
2394 did_old,
2395 0,
2396 0,
2397 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002398}
2399
David Woodhouse109b9b02012-05-25 17:43:02 +01002400static inline void unlink_domain_info(struct device_domain_info *info)
2401{
2402 assert_spin_locked(&device_domain_lock);
2403 list_del(&info->link);
2404 list_del(&info->global);
2405 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002406 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002407}
2408
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002409static void domain_remove_dev_info(struct dmar_domain *domain)
2410{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002411 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002412 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002413
2414 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002415 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002416 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002417 spin_unlock_irqrestore(&device_domain_lock, flags);
2418}
2419
2420/*
2421 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002422 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002423 */
David Woodhouse1525a292014-03-06 16:19:30 +00002424static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002425{
2426 struct device_domain_info *info;
2427
2428 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002429 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002430 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002431 return info->domain;
2432 return NULL;
2433}
2434
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002435static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002436dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2437{
2438 struct device_domain_info *info;
2439
2440 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002441 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002442 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002443 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002444
2445 return NULL;
2446}
2447
Joerg Roedel5db31562015-07-22 12:40:43 +02002448static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2449 int bus, int devfn,
2450 struct device *dev,
2451 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002452{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002453 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002454 struct device_domain_info *info;
2455 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002456 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002457
2458 info = alloc_devinfo_mem();
2459 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002460 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002461
Jiang Liu745f2582014-02-19 14:07:26 +08002462 info->bus = bus;
2463 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002464 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2465 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2466 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002467 info->dev = dev;
2468 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002469 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002470
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002471 if (dev && dev_is_pci(dev)) {
2472 struct pci_dev *pdev = to_pci_dev(info->dev);
2473
Gil Kupfercef74402018-05-10 17:56:02 -05002474 if (!pci_ats_disabled() &&
2475 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002476 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2477 dmar_find_matched_atsr_unit(pdev))
2478 info->ats_supported = 1;
2479
2480 if (ecs_enabled(iommu)) {
2481 if (pasid_enabled(iommu)) {
2482 int features = pci_pasid_features(pdev);
2483 if (features >= 0)
2484 info->pasid_supported = features | 1;
2485 }
2486
2487 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2488 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2489 info->pri_supported = 1;
2490 }
2491 }
2492
Jiang Liu745f2582014-02-19 14:07:26 +08002493 spin_lock_irqsave(&device_domain_lock, flags);
2494 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002495 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002496
2497 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002498 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002499 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002500 if (info2) {
2501 found = info2->domain;
2502 info2->dev = dev;
2503 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002504 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002505
Jiang Liu745f2582014-02-19 14:07:26 +08002506 if (found) {
2507 spin_unlock_irqrestore(&device_domain_lock, flags);
2508 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002509 /* Caller must free the original domain */
2510 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002511 }
2512
Joerg Roedeld160aca2015-07-22 11:52:53 +02002513 spin_lock(&iommu->lock);
2514 ret = domain_attach_iommu(domain, iommu);
2515 spin_unlock(&iommu->lock);
2516
2517 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002518 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302519 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002520 return NULL;
2521 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002522
David Woodhouseb718cd32014-03-09 13:11:33 -07002523 list_add(&info->link, &domain->devices);
2524 list_add(&info->global, &device_domain_list);
2525 if (dev)
2526 dev->archdata.iommu = info;
2527 spin_unlock_irqrestore(&device_domain_lock, flags);
2528
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002529 if (dev && domain_context_mapping(domain, dev)) {
2530 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002531 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002532 return NULL;
2533 }
2534
David Woodhouseb718cd32014-03-09 13:11:33 -07002535 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002536}
2537
Alex Williamson579305f2014-07-03 09:51:43 -06002538static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2539{
2540 *(u16 *)opaque = alias;
2541 return 0;
2542}
2543
Joerg Roedel76208352016-08-25 14:25:12 +02002544static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002545{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002546 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002547 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002548 struct intel_iommu *iommu;
Lu Baolufcc35c62018-05-04 13:08:17 +08002549 u16 dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002550 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002551 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002552
David Woodhouse146922e2014-03-09 15:44:17 -07002553 iommu = device_to_iommu(dev, &bus, &devfn);
2554 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002555 return NULL;
2556
2557 if (dev_is_pci(dev)) {
2558 struct pci_dev *pdev = to_pci_dev(dev);
2559
2560 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2561
2562 spin_lock_irqsave(&device_domain_lock, flags);
2563 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2564 PCI_BUS_NUM(dma_alias),
2565 dma_alias & 0xff);
2566 if (info) {
2567 iommu = info->iommu;
2568 domain = info->domain;
2569 }
2570 spin_unlock_irqrestore(&device_domain_lock, flags);
2571
Joerg Roedel76208352016-08-25 14:25:12 +02002572 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002573 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002574 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002575 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002576
David Woodhouse146922e2014-03-09 15:44:17 -07002577 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002578 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002579 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002580 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002581 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002582 domain_exit(domain);
2583 return NULL;
2584 }
2585
Joerg Roedel76208352016-08-25 14:25:12 +02002586out:
Alex Williamson579305f2014-07-03 09:51:43 -06002587
Joerg Roedel76208352016-08-25 14:25:12 +02002588 return domain;
2589}
2590
2591static struct dmar_domain *set_domain_for_dev(struct device *dev,
2592 struct dmar_domain *domain)
2593{
2594 struct intel_iommu *iommu;
2595 struct dmar_domain *tmp;
2596 u16 req_id, dma_alias;
2597 u8 bus, devfn;
2598
2599 iommu = device_to_iommu(dev, &bus, &devfn);
2600 if (!iommu)
2601 return NULL;
2602
2603 req_id = ((u16)bus << 8) | devfn;
2604
2605 if (dev_is_pci(dev)) {
2606 struct pci_dev *pdev = to_pci_dev(dev);
2607
2608 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2609
2610 /* register PCI DMA alias device */
2611 if (req_id != dma_alias) {
2612 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2613 dma_alias & 0xff, NULL, domain);
2614
2615 if (!tmp || tmp != domain)
2616 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002617 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002618 }
2619
Joerg Roedel5db31562015-07-22 12:40:43 +02002620 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002621 if (!tmp || tmp != domain)
2622 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002623
Joerg Roedel76208352016-08-25 14:25:12 +02002624 return domain;
2625}
2626
2627static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2628{
2629 struct dmar_domain *domain, *tmp;
2630
2631 domain = find_domain(dev);
2632 if (domain)
2633 goto out;
2634
2635 domain = find_or_alloc_domain(dev, gaw);
2636 if (!domain)
2637 goto out;
2638
2639 tmp = set_domain_for_dev(dev, domain);
2640 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002641 domain_exit(domain);
2642 domain = tmp;
2643 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002644
Joerg Roedel76208352016-08-25 14:25:12 +02002645out:
2646
David Woodhouseb718cd32014-03-09 13:11:33 -07002647 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002648}
2649
David Woodhouseb2132032009-06-26 18:50:28 +01002650static int iommu_domain_identity_map(struct dmar_domain *domain,
2651 unsigned long long start,
2652 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002653{
David Woodhousec5395d52009-06-28 16:35:56 +01002654 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2655 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002656
David Woodhousec5395d52009-06-28 16:35:56 +01002657 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2658 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002659 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002660 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002661 }
2662
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002663 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002664 /*
2665 * RMRR range might have overlap with physical memory range,
2666 * clear it first
2667 */
David Woodhousec5395d52009-06-28 16:35:56 +01002668 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002669
Peter Xu87684fd2018-05-04 10:34:53 +08002670 return __domain_mapping(domain, first_vpfn, NULL,
2671 first_vpfn, last_vpfn - first_vpfn + 1,
2672 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002673}
2674
Joerg Roedeld66ce542015-09-23 19:00:10 +02002675static int domain_prepare_identity_map(struct device *dev,
2676 struct dmar_domain *domain,
2677 unsigned long long start,
2678 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002679{
David Woodhouse19943b02009-08-04 16:19:20 +01002680 /* For _hardware_ passthrough, don't bother. But for software
2681 passthrough, we do it anyway -- it may indicate a memory
2682 range which is reserved in E820, so which didn't get set
2683 up to start with in si_domain */
2684 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002685 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2686 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002687 return 0;
2688 }
2689
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002690 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2691 dev_name(dev), start, end);
2692
David Woodhouse5595b522009-12-02 09:21:55 +00002693 if (end < start) {
2694 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2695 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
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 Woodhouse5595b522009-12-02 09:21:55 +00002700 }
2701
David Woodhouse2ff729f2009-08-26 14:25:41 +01002702 if (end >> agaw_to_width(domain->agaw)) {
2703 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2704 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2705 agaw_to_width(domain->agaw),
2706 dmi_get_system_info(DMI_BIOS_VENDOR),
2707 dmi_get_system_info(DMI_BIOS_VERSION),
2708 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002709 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002710 }
David Woodhouse19943b02009-08-04 16:19:20 +01002711
Joerg Roedeld66ce542015-09-23 19:00:10 +02002712 return iommu_domain_identity_map(domain, start, end);
2713}
2714
2715static int iommu_prepare_identity_map(struct device *dev,
2716 unsigned long long start,
2717 unsigned long long end)
2718{
2719 struct dmar_domain *domain;
2720 int ret;
2721
2722 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2723 if (!domain)
2724 return -ENOMEM;
2725
2726 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002727 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002728 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002729
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002730 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002731}
2732
2733static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002734 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002735{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002736 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002737 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002738 return iommu_prepare_identity_map(dev, rmrr->base_address,
2739 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002740}
2741
Suresh Siddhad3f13812011-08-23 17:05:25 -07002742#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002743static inline void iommu_prepare_isa(void)
2744{
2745 struct pci_dev *pdev;
2746 int ret;
2747
2748 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2749 if (!pdev)
2750 return;
2751
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002752 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002753 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002754
2755 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002756 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002757
Yijing Wang9b27e822014-05-20 20:37:52 +08002758 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002759}
2760#else
2761static inline void iommu_prepare_isa(void)
2762{
2763 return;
2764}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002765#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002766
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002767static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002768
Matt Kraai071e1372009-08-23 22:30:22 -07002769static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002770{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002771 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002772
Jiang Liuab8dfe22014-07-11 14:19:27 +08002773 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002774 if (!si_domain)
2775 return -EFAULT;
2776
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002777 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2778 domain_exit(si_domain);
2779 return -EFAULT;
2780 }
2781
Joerg Roedel0dc79712015-07-21 15:40:06 +02002782 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002783
David Woodhouse19943b02009-08-04 16:19:20 +01002784 if (hw)
2785 return 0;
2786
David Woodhousec7ab48d2009-06-26 19:10:36 +01002787 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002788 unsigned long start_pfn, end_pfn;
2789 int i;
2790
2791 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2792 ret = iommu_domain_identity_map(si_domain,
2793 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2794 if (ret)
2795 return ret;
2796 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002797 }
2798
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002799 return 0;
2800}
2801
David Woodhouse9b226622014-03-09 14:03:28 -07002802static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002803{
2804 struct device_domain_info *info;
2805
2806 if (likely(!iommu_identity_mapping))
2807 return 0;
2808
David Woodhouse9b226622014-03-09 14:03:28 -07002809 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002810 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2811 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002812
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002813 return 0;
2814}
2815
Joerg Roedel28ccce02015-07-21 14:45:31 +02002816static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002817{
David Woodhouse0ac72662014-03-09 13:19:22 -07002818 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002819 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002820 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002821
David Woodhouse5913c9b2014-03-09 16:27:31 -07002822 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002823 if (!iommu)
2824 return -ENODEV;
2825
Joerg Roedel5db31562015-07-22 12:40:43 +02002826 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002827 if (ndomain != domain)
2828 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002829
2830 return 0;
2831}
2832
David Woodhouse0b9d9752014-03-09 15:48:15 -07002833static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002834{
2835 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002836 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002837 int i;
2838
Jiang Liu0e242612014-02-19 14:07:34 +08002839 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002840 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002841 /*
2842 * Return TRUE if this RMRR contains the device that
2843 * is passed in.
2844 */
2845 for_each_active_dev_scope(rmrr->devices,
2846 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002847 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002848 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002849 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002850 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002851 }
Jiang Liu0e242612014-02-19 14:07:34 +08002852 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002853 return false;
2854}
2855
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002856/*
2857 * There are a couple cases where we need to restrict the functionality of
2858 * devices associated with RMRRs. The first is when evaluating a device for
2859 * identity mapping because problems exist when devices are moved in and out
2860 * of domains and their respective RMRR information is lost. This means that
2861 * a device with associated RMRRs will never be in a "passthrough" domain.
2862 * The second is use of the device through the IOMMU API. This interface
2863 * expects to have full control of the IOVA space for the device. We cannot
2864 * satisfy both the requirement that RMRR access is maintained and have an
2865 * unencumbered IOVA space. We also have no ability to quiesce the device's
2866 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2867 * We therefore prevent devices associated with an RMRR from participating in
2868 * the IOMMU API, which eliminates them from device assignment.
2869 *
2870 * In both cases we assume that PCI USB devices with RMRRs have them largely
2871 * for historical reasons and that the RMRR space is not actively used post
2872 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002873 *
2874 * The same exception is made for graphics devices, with the requirement that
2875 * any use of the RMRR regions will be torn down before assigning the device
2876 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002877 */
2878static bool device_is_rmrr_locked(struct device *dev)
2879{
2880 if (!device_has_rmrr(dev))
2881 return false;
2882
2883 if (dev_is_pci(dev)) {
2884 struct pci_dev *pdev = to_pci_dev(dev);
2885
David Woodhouse18436af2015-03-25 15:05:47 +00002886 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002887 return false;
2888 }
2889
2890 return true;
2891}
2892
David Woodhouse3bdb2592014-03-09 16:03:08 -07002893static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002894{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002895
David Woodhouse3bdb2592014-03-09 16:03:08 -07002896 if (dev_is_pci(dev)) {
2897 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002898
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002899 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002900 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002901
David Woodhouse3bdb2592014-03-09 16:03:08 -07002902 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2903 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002904
David Woodhouse3bdb2592014-03-09 16:03:08 -07002905 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2906 return 1;
2907
2908 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2909 return 0;
2910
2911 /*
2912 * We want to start off with all devices in the 1:1 domain, and
2913 * take them out later if we find they can't access all of memory.
2914 *
2915 * However, we can't do this for PCI devices behind bridges,
2916 * because all PCI devices behind the same bridge will end up
2917 * with the same source-id on their transactions.
2918 *
2919 * Practically speaking, we can't change things around for these
2920 * devices at run-time, because we can't be sure there'll be no
2921 * DMA transactions in flight for any of their siblings.
2922 *
2923 * So PCI devices (unless they're on the root bus) as well as
2924 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2925 * the 1:1 domain, just in _case_ one of their siblings turns out
2926 * not to be able to map all of memory.
2927 */
2928 if (!pci_is_pcie(pdev)) {
2929 if (!pci_is_root_bus(pdev->bus))
2930 return 0;
2931 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2932 return 0;
2933 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2934 return 0;
2935 } else {
2936 if (device_has_rmrr(dev))
2937 return 0;
2938 }
David Woodhouse6941af22009-07-04 18:24:27 +01002939
David Woodhouse3dfc8132009-07-04 19:11:08 +01002940 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002941 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002942 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002943 * take them out of the 1:1 domain later.
2944 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002945 if (!startup) {
2946 /*
2947 * If the device's dma_mask is less than the system's memory
2948 * size then this is not a candidate for identity mapping.
2949 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002950 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002951
David Woodhouse3bdb2592014-03-09 16:03:08 -07002952 if (dev->coherent_dma_mask &&
2953 dev->coherent_dma_mask < dma_mask)
2954 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002955
David Woodhouse3bdb2592014-03-09 16:03:08 -07002956 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002957 }
David Woodhouse6941af22009-07-04 18:24:27 +01002958
2959 return 1;
2960}
2961
David Woodhousecf04eee2014-03-21 16:49:04 +00002962static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2963{
2964 int ret;
2965
2966 if (!iommu_should_identity_map(dev, 1))
2967 return 0;
2968
Joerg Roedel28ccce02015-07-21 14:45:31 +02002969 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002970 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002971 pr_info("%s identity mapping for device %s\n",
2972 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002973 else if (ret == -ENODEV)
2974 /* device not associated with an iommu */
2975 ret = 0;
2976
2977 return ret;
2978}
2979
2980
Matt Kraai071e1372009-08-23 22:30:22 -07002981static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002982{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002983 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002984 struct dmar_drhd_unit *drhd;
2985 struct intel_iommu *iommu;
2986 struct device *dev;
2987 int i;
2988 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002989
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002990 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002991 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2992 if (ret)
2993 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002994 }
2995
David Woodhousecf04eee2014-03-21 16:49:04 +00002996 for_each_active_iommu(iommu, drhd)
2997 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2998 struct acpi_device_physical_node *pn;
2999 struct acpi_device *adev;
3000
3001 if (dev->bus != &acpi_bus_type)
3002 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003003
David Woodhousecf04eee2014-03-21 16:49:04 +00003004 adev= to_acpi_device(dev);
3005 mutex_lock(&adev->physical_node_lock);
3006 list_for_each_entry(pn, &adev->physical_node_list, node) {
3007 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
3008 if (ret)
3009 break;
3010 }
3011 mutex_unlock(&adev->physical_node_lock);
3012 if (ret)
3013 return ret;
3014 }
3015
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003016 return 0;
3017}
3018
Jiang Liuffebeb42014-11-09 22:48:02 +08003019static void intel_iommu_init_qi(struct intel_iommu *iommu)
3020{
3021 /*
3022 * Start from the sane iommu hardware state.
3023 * If the queued invalidation is already initialized by us
3024 * (for example, while enabling interrupt-remapping) then
3025 * we got the things already rolling from a sane state.
3026 */
3027 if (!iommu->qi) {
3028 /*
3029 * Clear any previous faults.
3030 */
3031 dmar_fault(-1, iommu);
3032 /*
3033 * Disable queued invalidation if supported and already enabled
3034 * before OS handover.
3035 */
3036 dmar_disable_qi(iommu);
3037 }
3038
3039 if (dmar_enable_qi(iommu)) {
3040 /*
3041 * Queued Invalidate not enabled, use Register Based Invalidate
3042 */
3043 iommu->flush.flush_context = __iommu_flush_context;
3044 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003045 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003046 iommu->name);
3047 } else {
3048 iommu->flush.flush_context = qi_flush_context;
3049 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003050 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003051 }
3052}
3053
Joerg Roedel091d42e2015-06-12 11:56:10 +02003054static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003055 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003056 struct context_entry **tbl,
3057 int bus, bool ext)
3058{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003059 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003060 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003061 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003062 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003063 phys_addr_t old_ce_phys;
3064
3065 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003066 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003067
3068 for (devfn = 0; devfn < 256; devfn++) {
3069 /* First calculate the correct index */
3070 idx = (ext ? devfn * 2 : devfn) % 256;
3071
3072 if (idx == 0) {
3073 /* First save what we may have and clean up */
3074 if (new_ce) {
3075 tbl[tbl_idx] = new_ce;
3076 __iommu_flush_cache(iommu, new_ce,
3077 VTD_PAGE_SIZE);
3078 pos = 1;
3079 }
3080
3081 if (old_ce)
3082 iounmap(old_ce);
3083
3084 ret = 0;
3085 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003086 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003087 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003088 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003089
3090 if (!old_ce_phys) {
3091 if (ext && devfn == 0) {
3092 /* No LCTP, try UCTP */
3093 devfn = 0x7f;
3094 continue;
3095 } else {
3096 goto out;
3097 }
3098 }
3099
3100 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003101 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3102 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003103 if (!old_ce)
3104 goto out;
3105
3106 new_ce = alloc_pgtable_page(iommu->node);
3107 if (!new_ce)
3108 goto out_unmap;
3109
3110 ret = 0;
3111 }
3112
3113 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003114 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003115
Joerg Roedelcf484d02015-06-12 12:21:46 +02003116 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003117 continue;
3118
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003119 did = context_domain_id(&ce);
3120 if (did >= 0 && did < cap_ndoms(iommu->cap))
3121 set_bit(did, iommu->domain_ids);
3122
Joerg Roedelcf484d02015-06-12 12:21:46 +02003123 /*
3124 * We need a marker for copied context entries. This
3125 * marker needs to work for the old format as well as
3126 * for extended context entries.
3127 *
3128 * Bit 67 of the context entry is used. In the old
3129 * format this bit is available to software, in the
3130 * extended format it is the PGE bit, but PGE is ignored
3131 * by HW if PASIDs are disabled (and thus still
3132 * available).
3133 *
3134 * So disable PASIDs first and then mark the entry
3135 * copied. This means that we don't copy PASID
3136 * translations from the old kernel, but this is fine as
3137 * faults there are not fatal.
3138 */
3139 context_clear_pasid_enable(&ce);
3140 context_set_copied(&ce);
3141
Joerg Roedel091d42e2015-06-12 11:56:10 +02003142 new_ce[idx] = ce;
3143 }
3144
3145 tbl[tbl_idx + pos] = new_ce;
3146
3147 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3148
3149out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003150 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003151
3152out:
3153 return ret;
3154}
3155
3156static int copy_translation_tables(struct intel_iommu *iommu)
3157{
3158 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003159 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003160 phys_addr_t old_rt_phys;
3161 int ctxt_table_entries;
3162 unsigned long flags;
3163 u64 rtaddr_reg;
3164 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003165 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003166
3167 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3168 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003169 new_ext = !!ecap_ecs(iommu->ecap);
3170
3171 /*
3172 * The RTT bit can only be changed when translation is disabled,
3173 * but disabling translation means to open a window for data
3174 * corruption. So bail out and don't copy anything if we would
3175 * have to change the bit.
3176 */
3177 if (new_ext != ext)
3178 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003179
3180 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3181 if (!old_rt_phys)
3182 return -EINVAL;
3183
Dan Williamsdfddb9692015-10-09 18:16:46 -04003184 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003185 if (!old_rt)
3186 return -ENOMEM;
3187
3188 /* This is too big for the stack - allocate it from slab */
3189 ctxt_table_entries = ext ? 512 : 256;
3190 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003191 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003192 if (!ctxt_tbls)
3193 goto out_unmap;
3194
3195 for (bus = 0; bus < 256; bus++) {
3196 ret = copy_context_table(iommu, &old_rt[bus],
3197 ctxt_tbls, bus, ext);
3198 if (ret) {
3199 pr_err("%s: Failed to copy context table for bus %d\n",
3200 iommu->name, bus);
3201 continue;
3202 }
3203 }
3204
3205 spin_lock_irqsave(&iommu->lock, flags);
3206
3207 /* Context tables are copied, now write them to the root_entry table */
3208 for (bus = 0; bus < 256; bus++) {
3209 int idx = ext ? bus * 2 : bus;
3210 u64 val;
3211
3212 if (ctxt_tbls[idx]) {
3213 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3214 iommu->root_entry[bus].lo = val;
3215 }
3216
3217 if (!ext || !ctxt_tbls[idx + 1])
3218 continue;
3219
3220 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3221 iommu->root_entry[bus].hi = val;
3222 }
3223
3224 spin_unlock_irqrestore(&iommu->lock, flags);
3225
3226 kfree(ctxt_tbls);
3227
3228 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3229
3230 ret = 0;
3231
3232out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003233 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003234
3235 return ret;
3236}
3237
Joseph Cihulab7792602011-05-03 00:08:37 -07003238static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003239{
3240 struct dmar_drhd_unit *drhd;
3241 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003242 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003243 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003244 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003245 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003246
3247 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003248 * for each drhd
3249 * allocate root
3250 * initialize and program root entry to not present
3251 * endfor
3252 */
3253 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003254 /*
3255 * lock not needed as this is only incremented in the single
3256 * threaded kernel __init code path all other access are read
3257 * only
3258 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003259 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003260 g_num_of_iommus++;
3261 continue;
3262 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003263 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003264 }
3265
Jiang Liuffebeb42014-11-09 22:48:02 +08003266 /* Preallocate enough resources for IOMMU hot-addition */
3267 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3268 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3269
Weidong Hand9630fe2008-12-08 11:06:32 +08003270 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3271 GFP_KERNEL);
3272 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003273 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003274 ret = -ENOMEM;
3275 goto error;
3276 }
3277
Jiang Liu7c919772014-01-06 14:18:18 +08003278 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003279 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003280
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003281 intel_iommu_init_qi(iommu);
3282
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003283 ret = iommu_init_domains(iommu);
3284 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003285 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003286
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003287 init_translation_status(iommu);
3288
Joerg Roedel091d42e2015-06-12 11:56:10 +02003289 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3290 iommu_disable_translation(iommu);
3291 clear_translation_pre_enabled(iommu);
3292 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3293 iommu->name);
3294 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003295
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003296 /*
3297 * TBD:
3298 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003299 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003300 */
3301 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003302 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003303 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003304
Joerg Roedel091d42e2015-06-12 11:56:10 +02003305 if (translation_pre_enabled(iommu)) {
3306 pr_info("Translation already enabled - trying to copy translation structures\n");
3307
3308 ret = copy_translation_tables(iommu);
3309 if (ret) {
3310 /*
3311 * We found the IOMMU with translation
3312 * enabled - but failed to copy over the
3313 * old root-entry table. Try to proceed
3314 * by disabling translation now and
3315 * allocating a clean root-entry table.
3316 * This might cause DMAR faults, but
3317 * probably the dump will still succeed.
3318 */
3319 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3320 iommu->name);
3321 iommu_disable_translation(iommu);
3322 clear_translation_pre_enabled(iommu);
3323 } else {
3324 pr_info("Copied translation tables from previous kernel for %s\n",
3325 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003326 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003327 }
3328 }
3329
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003330 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003331 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003332#ifdef CONFIG_INTEL_IOMMU_SVM
3333 if (pasid_enabled(iommu))
3334 intel_svm_alloc_pasid_tables(iommu);
3335#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003336 }
3337
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003338 /*
3339 * Now that qi is enabled on all iommus, set the root entry and flush
3340 * caches. This is required on some Intel X58 chipsets, otherwise the
3341 * flush_context function will loop forever and the boot hangs.
3342 */
3343 for_each_active_iommu(iommu, drhd) {
3344 iommu_flush_write_buffer(iommu);
3345 iommu_set_root_entry(iommu);
3346 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3347 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3348 }
3349
David Woodhouse19943b02009-08-04 16:19:20 +01003350 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003351 iommu_identity_mapping |= IDENTMAP_ALL;
3352
Suresh Siddhad3f13812011-08-23 17:05:25 -07003353#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003354 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003355#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003356
Ashok Raj21e722c2017-01-30 09:39:53 -08003357 check_tylersburg_isoch();
3358
Joerg Roedel86080cc2015-06-12 12:27:16 +02003359 if (iommu_identity_mapping) {
3360 ret = si_domain_init(hw_pass_through);
3361 if (ret)
3362 goto free_iommu;
3363 }
3364
David Woodhousee0fc7e02009-09-30 09:12:17 -07003365
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003366 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003367 * If we copied translations from a previous kernel in the kdump
3368 * case, we can not assign the devices to domains now, as that
3369 * would eliminate the old mappings. So skip this part and defer
3370 * the assignment to device driver initialization time.
3371 */
3372 if (copied_tables)
3373 goto domains_done;
3374
3375 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003376 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003377 * identity mappings for rmrr, gfx, and isa and may fall back to static
3378 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003379 */
David Woodhouse19943b02009-08-04 16:19:20 +01003380 if (iommu_identity_mapping) {
3381 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3382 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003383 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003384 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003385 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003386 }
David Woodhouse19943b02009-08-04 16:19:20 +01003387 /*
3388 * For each rmrr
3389 * for each dev attached to rmrr
3390 * do
3391 * locate drhd for dev, alloc domain for dev
3392 * allocate free domain
3393 * allocate page table entries for rmrr
3394 * if context not allocated for bus
3395 * allocate and init context
3396 * set present in root table for this bus
3397 * init context with domain, translation etc
3398 * endfor
3399 * endfor
3400 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003401 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003402 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003403 /* some BIOS lists non-exist devices in DMAR table. */
3404 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003405 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003406 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003407 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003408 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003409 }
3410 }
3411
3412 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003413
Joerg Roedela87f4912015-06-12 12:32:54 +02003414domains_done:
3415
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003416 /*
3417 * for each drhd
3418 * enable fault log
3419 * global invalidate context cache
3420 * global invalidate iotlb
3421 * enable translation
3422 */
Jiang Liu7c919772014-01-06 14:18:18 +08003423 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003424 if (drhd->ignored) {
3425 /*
3426 * we always have to disable PMRs or DMA may fail on
3427 * this device
3428 */
3429 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003430 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003431 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003432 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003433
3434 iommu_flush_write_buffer(iommu);
3435
David Woodhousea222a7f2015-10-07 23:35:18 +01003436#ifdef CONFIG_INTEL_IOMMU_SVM
3437 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3438 ret = intel_svm_enable_prq(iommu);
3439 if (ret)
3440 goto free_iommu;
3441 }
3442#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003443 ret = dmar_set_interrupt(iommu);
3444 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003445 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003446
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003447 if (!translation_pre_enabled(iommu))
3448 iommu_enable_translation(iommu);
3449
David Woodhouseb94996c2009-09-19 15:28:12 -07003450 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003451 }
3452
3453 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003454
3455free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003456 for_each_active_iommu(iommu, drhd) {
3457 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003458 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003459 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003460
Weidong Hand9630fe2008-12-08 11:06:32 +08003461 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003462
Jiang Liu989d51f2014-02-19 14:07:21 +08003463error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003464 return ret;
3465}
3466
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003467/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003468static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003469 struct dmar_domain *domain,
3470 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003471{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003472 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003473
David Woodhouse875764d2009-06-28 21:20:51 +01003474 /* Restrict dma_mask to the width that the iommu can handle */
3475 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003476 /* Ensure we reserve the whole size-aligned region */
3477 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003478
3479 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003480 /*
3481 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003482 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003483 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003484 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003485 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003486 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003487 if (iova_pfn)
3488 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003489 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003490 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3491 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003492 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003493 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003494 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003495 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003496 }
3497
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003498 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003499}
3500
Peter Xub316d022017-05-22 18:28:51 +08003501static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003502{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003503 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003504 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003505 struct device *i_dev;
3506 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003507
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003508 domain = find_domain(dev);
3509 if (domain)
3510 goto out;
3511
3512 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3513 if (!domain)
3514 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003515
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003516 /* We have a new domain - setup possible RMRRs for the device */
3517 rcu_read_lock();
3518 for_each_rmrr_units(rmrr) {
3519 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3520 i, i_dev) {
3521 if (i_dev != dev)
3522 continue;
3523
3524 ret = domain_prepare_identity_map(dev, domain,
3525 rmrr->base_address,
3526 rmrr->end_address);
3527 if (ret)
3528 dev_err(dev, "Mapping reserved region failed\n");
3529 }
3530 }
3531 rcu_read_unlock();
3532
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003533 tmp = set_domain_for_dev(dev, domain);
3534 if (!tmp || domain != tmp) {
3535 domain_exit(domain);
3536 domain = tmp;
3537 }
3538
3539out:
3540
3541 if (!domain)
3542 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3543
3544
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003545 return domain;
3546}
3547
David Woodhouseecb509e2014-03-09 16:29:55 -07003548/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003549static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003550{
3551 int found;
3552
David Woodhouse3d891942014-03-06 15:59:26 +00003553 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003554 return 1;
3555
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003556 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003557 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003558
David Woodhouse9b226622014-03-09 14:03:28 -07003559 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003560 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003561 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003562 return 1;
3563 else {
3564 /*
3565 * 32 bit DMA is removed from si_domain and fall back
3566 * to non-identity mapping.
3567 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003568 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003569 pr_info("32bit %s uses non-identity mapping\n",
3570 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003571 return 0;
3572 }
3573 } else {
3574 /*
3575 * In case of a detached 64 bit DMA device from vm, the device
3576 * is put into si_domain for identity mapping.
3577 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003578 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003579 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003580 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003581 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003582 pr_info("64bit %s uses identity mapping\n",
3583 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003584 return 1;
3585 }
3586 }
3587 }
3588
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003589 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003590}
3591
David Woodhouse5040a912014-03-09 16:14:00 -07003592static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003593 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003594{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003595 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003596 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003597 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003598 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003599 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003600 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003601 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003602
3603 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003604
David Woodhouse5040a912014-03-09 16:14:00 -07003605 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003606 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003607
David Woodhouse5040a912014-03-09 16:14:00 -07003608 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003609 if (!domain)
3610 return 0;
3611
Weidong Han8c11e792008-12-08 15:29:22 +08003612 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003613 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003614
Omer Peleg2aac6302016-04-20 11:33:57 +03003615 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3616 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003617 goto error;
3618
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003619 /*
3620 * Check if DMAR supports zero-length reads on write only
3621 * mappings..
3622 */
3623 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003624 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003625 prot |= DMA_PTE_READ;
3626 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3627 prot |= DMA_PTE_WRITE;
3628 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003629 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003630 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003631 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003632 * is not a big problem
3633 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003634 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003635 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003636 if (ret)
3637 goto error;
3638
Omer Peleg2aac6302016-04-20 11:33:57 +03003639 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003640 start_paddr += paddr & ~PAGE_MASK;
3641 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003642
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003643error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003644 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003645 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003646 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003647 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003648 return 0;
3649}
3650
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003651static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3652 unsigned long offset, size_t size,
3653 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003654 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003655{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003656 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003657 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003658}
3659
Omer Peleg769530e2016-04-20 11:33:25 +03003660static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003661{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003662 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003663 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003664 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003665 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003666 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003667 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003668
David Woodhouse73676832009-07-04 14:08:36 +01003669 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003670 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003671
David Woodhouse1525a292014-03-06 16:19:30 +00003672 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003673 BUG_ON(!domain);
3674
Weidong Han8c11e792008-12-08 15:29:22 +08003675 iommu = domain_get_iommu(domain);
3676
Omer Peleg2aac6302016-04-20 11:33:57 +03003677 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003678
Omer Peleg769530e2016-04-20 11:33:25 +03003679 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003680 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003681 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003682
David Woodhoused794dc92009-06-28 00:27:49 +01003683 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003684 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003685
David Woodhouseea8ea462014-03-05 17:09:32 +00003686 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003687
mark gross5e0d2a62008-03-04 15:22:08 -08003688 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003689 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003690 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003691 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003692 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003693 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003694 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003695 queue_iova(&domain->iovad, iova_pfn, nrpages,
3696 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003697 /*
3698 * queue up the release of the unmap to save the 1/6th of the
3699 * cpu used up by the iotlb flush operation...
3700 */
mark gross5e0d2a62008-03-04 15:22:08 -08003701 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003702}
3703
Jiang Liud41a4ad2014-07-11 14:19:34 +08003704static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3705 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003706 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003707{
Omer Peleg769530e2016-04-20 11:33:25 +03003708 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003709}
3710
David Woodhouse5040a912014-03-09 16:14:00 -07003711static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003712 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003713 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003714{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003715 struct page *page = NULL;
3716 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003717
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003718 size = PAGE_ALIGN(size);
3719 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003720
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003721 if (!iommu_no_mapping(dev))
3722 flags &= ~(GFP_DMA | GFP_DMA32);
3723 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3724 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
3725 flags |= GFP_DMA;
3726 else
3727 flags |= GFP_DMA32;
3728 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003729
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003730 if (gfpflags_allow_blocking(flags)) {
3731 unsigned int count = size >> PAGE_SHIFT;
3732
3733 page = dma_alloc_from_contiguous(dev, count, order, flags);
3734 if (page && iommu_no_mapping(dev) &&
3735 page_to_phys(page) + size > dev->coherent_dma_mask) {
3736 dma_release_from_contiguous(dev, page, count);
3737 page = NULL;
3738 }
3739 }
3740
3741 if (!page)
3742 page = alloc_pages(flags, order);
3743 if (!page)
3744 return NULL;
3745 memset(page_address(page), 0, size);
3746
3747 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3748 DMA_BIDIRECTIONAL,
3749 dev->coherent_dma_mask);
3750 if (*dma_handle)
3751 return page_address(page);
3752 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3753 __free_pages(page, order);
3754
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003755 return NULL;
3756}
3757
David Woodhouse5040a912014-03-09 16:14:00 -07003758static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003759 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003761 int order;
3762 struct page *page = virt_to_page(vaddr);
3763
3764 size = PAGE_ALIGN(size);
3765 order = get_order(size);
3766
3767 intel_unmap(dev, dma_handle, size);
3768 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3769 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003770}
3771
David Woodhouse5040a912014-03-09 16:14:00 -07003772static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003773 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003774 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003775{
Omer Peleg769530e2016-04-20 11:33:25 +03003776 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3777 unsigned long nrpages = 0;
3778 struct scatterlist *sg;
3779 int i;
3780
3781 for_each_sg(sglist, sg, nelems, i) {
3782 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3783 }
3784
3785 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003786}
3787
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003788static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003789 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003790{
3791 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003792 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003793
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003794 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003795 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003796 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003797 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003798 }
3799 return nelems;
3800}
3801
David Woodhouse5040a912014-03-09 16:14:00 -07003802static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003803 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003804{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003805 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003806 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003807 size_t size = 0;
3808 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003809 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003810 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003811 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003812 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003813 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003814
3815 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003816 if (iommu_no_mapping(dev))
3817 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003818
David Woodhouse5040a912014-03-09 16:14:00 -07003819 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003820 if (!domain)
3821 return 0;
3822
Weidong Han8c11e792008-12-08 15:29:22 +08003823 iommu = domain_get_iommu(domain);
3824
David Woodhouseb536d242009-06-28 14:49:31 +01003825 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003826 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003827
Omer Peleg2aac6302016-04-20 11:33:57 +03003828 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003829 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003830 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003831 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003832 return 0;
3833 }
3834
3835 /*
3836 * Check if DMAR supports zero-length reads on write only
3837 * mappings..
3838 */
3839 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003840 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003841 prot |= DMA_PTE_READ;
3842 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3843 prot |= DMA_PTE_WRITE;
3844
Omer Peleg2aac6302016-04-20 11:33:57 +03003845 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003846
Fenghua Yuf5329592009-08-04 15:09:37 -07003847 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003848 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003849 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003850 start_vpfn + size - 1,
3851 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003852 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003853 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003854 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003855
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003856 return nelems;
3857}
3858
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003859static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3860{
3861 return !dma_addr;
3862}
3863
Arvind Yadav01e19322017-06-28 16:39:32 +05303864const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003865 .alloc = intel_alloc_coherent,
3866 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003867 .map_sg = intel_map_sg,
3868 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003869 .map_page = intel_map_page,
3870 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003871 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003872#ifdef CONFIG_X86
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003873 .dma_supported = dma_direct_supported,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003874#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003875};
3876
3877static inline int iommu_domain_cache_init(void)
3878{
3879 int ret = 0;
3880
3881 iommu_domain_cache = kmem_cache_create("iommu_domain",
3882 sizeof(struct dmar_domain),
3883 0,
3884 SLAB_HWCACHE_ALIGN,
3885
3886 NULL);
3887 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003888 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003889 ret = -ENOMEM;
3890 }
3891
3892 return ret;
3893}
3894
3895static inline int iommu_devinfo_cache_init(void)
3896{
3897 int ret = 0;
3898
3899 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3900 sizeof(struct device_domain_info),
3901 0,
3902 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003903 NULL);
3904 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003905 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003906 ret = -ENOMEM;
3907 }
3908
3909 return ret;
3910}
3911
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003912static int __init iommu_init_mempool(void)
3913{
3914 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003915 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003916 if (ret)
3917 return ret;
3918
3919 ret = iommu_domain_cache_init();
3920 if (ret)
3921 goto domain_error;
3922
3923 ret = iommu_devinfo_cache_init();
3924 if (!ret)
3925 return ret;
3926
3927 kmem_cache_destroy(iommu_domain_cache);
3928domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003929 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003930
3931 return -ENOMEM;
3932}
3933
3934static void __init iommu_exit_mempool(void)
3935{
3936 kmem_cache_destroy(iommu_devinfo_cache);
3937 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003938 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003939}
3940
Dan Williams556ab452010-07-23 15:47:56 -07003941static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3942{
3943 struct dmar_drhd_unit *drhd;
3944 u32 vtbar;
3945 int rc;
3946
3947 /* We know that this device on this chipset has its own IOMMU.
3948 * If we find it under a different IOMMU, then the BIOS is lying
3949 * to us. Hope that the IOMMU for this device is actually
3950 * disabled, and it needs no translation...
3951 */
3952 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3953 if (rc) {
3954 /* "can't" happen */
3955 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3956 return;
3957 }
3958 vtbar &= 0xffff0000;
3959
3960 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3961 drhd = dmar_find_matched_drhd_unit(pdev);
3962 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3963 TAINT_FIRMWARE_WORKAROUND,
3964 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3965 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3966}
3967DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3968
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003969static void __init init_no_remapping_devices(void)
3970{
3971 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003972 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003973 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003974
3975 for_each_drhd_unit(drhd) {
3976 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003977 for_each_active_dev_scope(drhd->devices,
3978 drhd->devices_cnt, i, dev)
3979 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003980 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003981 if (i == drhd->devices_cnt)
3982 drhd->ignored = 1;
3983 }
3984 }
3985
Jiang Liu7c919772014-01-06 14:18:18 +08003986 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003987 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003988 continue;
3989
Jiang Liub683b232014-02-19 14:07:32 +08003990 for_each_active_dev_scope(drhd->devices,
3991 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003992 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003993 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003994 if (i < drhd->devices_cnt)
3995 continue;
3996
David Woodhousec0771df2011-10-14 20:59:46 +01003997 /* This IOMMU has *only* gfx devices. Either bypass it or
3998 set the gfx_mapped flag, as appropriate */
3999 if (dmar_map_gfx) {
4000 intel_iommu_gfx_mapped = 1;
4001 } else {
4002 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004003 for_each_active_dev_scope(drhd->devices,
4004 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004005 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004006 }
4007 }
4008}
4009
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004010#ifdef CONFIG_SUSPEND
4011static int init_iommu_hw(void)
4012{
4013 struct dmar_drhd_unit *drhd;
4014 struct intel_iommu *iommu = NULL;
4015
4016 for_each_active_iommu(iommu, drhd)
4017 if (iommu->qi)
4018 dmar_reenable_qi(iommu);
4019
Joseph Cihulab7792602011-05-03 00:08:37 -07004020 for_each_iommu(iommu, drhd) {
4021 if (drhd->ignored) {
4022 /*
4023 * we always have to disable PMRs or DMA may fail on
4024 * this device
4025 */
4026 if (force_on)
4027 iommu_disable_protect_mem_regions(iommu);
4028 continue;
4029 }
4030
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004031 iommu_flush_write_buffer(iommu);
4032
4033 iommu_set_root_entry(iommu);
4034
4035 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004036 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004037 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4038 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004039 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004040 }
4041
4042 return 0;
4043}
4044
4045static void iommu_flush_all(void)
4046{
4047 struct dmar_drhd_unit *drhd;
4048 struct intel_iommu *iommu;
4049
4050 for_each_active_iommu(iommu, drhd) {
4051 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004052 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004053 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004054 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004055 }
4056}
4057
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004058static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004059{
4060 struct dmar_drhd_unit *drhd;
4061 struct intel_iommu *iommu = NULL;
4062 unsigned long flag;
4063
4064 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004065 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004066 GFP_ATOMIC);
4067 if (!iommu->iommu_state)
4068 goto nomem;
4069 }
4070
4071 iommu_flush_all();
4072
4073 for_each_active_iommu(iommu, drhd) {
4074 iommu_disable_translation(iommu);
4075
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004076 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004077
4078 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4079 readl(iommu->reg + DMAR_FECTL_REG);
4080 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4081 readl(iommu->reg + DMAR_FEDATA_REG);
4082 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4083 readl(iommu->reg + DMAR_FEADDR_REG);
4084 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4085 readl(iommu->reg + DMAR_FEUADDR_REG);
4086
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004087 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004088 }
4089 return 0;
4090
4091nomem:
4092 for_each_active_iommu(iommu, drhd)
4093 kfree(iommu->iommu_state);
4094
4095 return -ENOMEM;
4096}
4097
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004098static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004099{
4100 struct dmar_drhd_unit *drhd;
4101 struct intel_iommu *iommu = NULL;
4102 unsigned long flag;
4103
4104 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004105 if (force_on)
4106 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4107 else
4108 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004109 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004110 }
4111
4112 for_each_active_iommu(iommu, drhd) {
4113
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004114 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004115
4116 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4117 iommu->reg + DMAR_FECTL_REG);
4118 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4119 iommu->reg + DMAR_FEDATA_REG);
4120 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4121 iommu->reg + DMAR_FEADDR_REG);
4122 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4123 iommu->reg + DMAR_FEUADDR_REG);
4124
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004125 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004126 }
4127
4128 for_each_active_iommu(iommu, drhd)
4129 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004130}
4131
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004132static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004133 .resume = iommu_resume,
4134 .suspend = iommu_suspend,
4135};
4136
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004137static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004138{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004139 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004140}
4141
4142#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004143static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004144#endif /* CONFIG_PM */
4145
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004146
Jiang Liuc2a0b532014-11-09 22:47:56 +08004147int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004148{
4149 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004150 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004151 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004152 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004153
4154 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4155 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004156 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004157
4158 rmrru->hdr = header;
4159 rmrr = (struct acpi_dmar_reserved_memory *)header;
4160 rmrru->base_address = rmrr->base_address;
4161 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004162
4163 length = rmrr->end_address - rmrr->base_address + 1;
4164 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4165 IOMMU_RESV_DIRECT);
4166 if (!rmrru->resv)
4167 goto free_rmrru;
4168
Jiang Liu2e455282014-02-19 14:07:36 +08004169 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4170 ((void *)rmrr) + rmrr->header.length,
4171 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004172 if (rmrru->devices_cnt && rmrru->devices == NULL)
4173 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004174
Jiang Liu2e455282014-02-19 14:07:36 +08004175 list_add(&rmrru->list, &dmar_rmrr_units);
4176
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004177 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004178free_all:
4179 kfree(rmrru->resv);
4180free_rmrru:
4181 kfree(rmrru);
4182out:
4183 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004184}
4185
Jiang Liu6b197242014-11-09 22:47:58 +08004186static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4187{
4188 struct dmar_atsr_unit *atsru;
4189 struct acpi_dmar_atsr *tmp;
4190
4191 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4192 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4193 if (atsr->segment != tmp->segment)
4194 continue;
4195 if (atsr->header.length != tmp->header.length)
4196 continue;
4197 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4198 return atsru;
4199 }
4200
4201 return NULL;
4202}
4203
4204int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004205{
4206 struct acpi_dmar_atsr *atsr;
4207 struct dmar_atsr_unit *atsru;
4208
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004209 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004210 return 0;
4211
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004212 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004213 atsru = dmar_find_atsr(atsr);
4214 if (atsru)
4215 return 0;
4216
4217 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004218 if (!atsru)
4219 return -ENOMEM;
4220
Jiang Liu6b197242014-11-09 22:47:58 +08004221 /*
4222 * If memory is allocated from slab by ACPI _DSM method, we need to
4223 * copy the memory content because the memory buffer will be freed
4224 * on return.
4225 */
4226 atsru->hdr = (void *)(atsru + 1);
4227 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004228 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004229 if (!atsru->include_all) {
4230 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4231 (void *)atsr + atsr->header.length,
4232 &atsru->devices_cnt);
4233 if (atsru->devices_cnt && atsru->devices == NULL) {
4234 kfree(atsru);
4235 return -ENOMEM;
4236 }
4237 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004238
Jiang Liu0e242612014-02-19 14:07:34 +08004239 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004240
4241 return 0;
4242}
4243
Jiang Liu9bdc5312014-01-06 14:18:27 +08004244static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4245{
4246 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4247 kfree(atsru);
4248}
4249
Jiang Liu6b197242014-11-09 22:47:58 +08004250int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4251{
4252 struct acpi_dmar_atsr *atsr;
4253 struct dmar_atsr_unit *atsru;
4254
4255 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4256 atsru = dmar_find_atsr(atsr);
4257 if (atsru) {
4258 list_del_rcu(&atsru->list);
4259 synchronize_rcu();
4260 intel_iommu_free_atsr(atsru);
4261 }
4262
4263 return 0;
4264}
4265
4266int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4267{
4268 int i;
4269 struct device *dev;
4270 struct acpi_dmar_atsr *atsr;
4271 struct dmar_atsr_unit *atsru;
4272
4273 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4274 atsru = dmar_find_atsr(atsr);
4275 if (!atsru)
4276 return 0;
4277
Linus Torvalds194dc872016-07-27 20:03:31 -07004278 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004279 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4280 i, dev)
4281 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004282 }
Jiang Liu6b197242014-11-09 22:47:58 +08004283
4284 return 0;
4285}
4286
Jiang Liuffebeb42014-11-09 22:48:02 +08004287static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4288{
4289 int sp, ret = 0;
4290 struct intel_iommu *iommu = dmaru->iommu;
4291
4292 if (g_iommus[iommu->seq_id])
4293 return 0;
4294
4295 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004296 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004297 iommu->name);
4298 return -ENXIO;
4299 }
4300 if (!ecap_sc_support(iommu->ecap) &&
4301 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004302 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004303 iommu->name);
4304 return -ENXIO;
4305 }
4306 sp = domain_update_iommu_superpage(iommu) - 1;
4307 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004308 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004309 iommu->name);
4310 return -ENXIO;
4311 }
4312
4313 /*
4314 * Disable translation if already enabled prior to OS handover.
4315 */
4316 if (iommu->gcmd & DMA_GCMD_TE)
4317 iommu_disable_translation(iommu);
4318
4319 g_iommus[iommu->seq_id] = iommu;
4320 ret = iommu_init_domains(iommu);
4321 if (ret == 0)
4322 ret = iommu_alloc_root_entry(iommu);
4323 if (ret)
4324 goto out;
4325
David Woodhouse8a94ade2015-03-24 14:54:56 +00004326#ifdef CONFIG_INTEL_IOMMU_SVM
4327 if (pasid_enabled(iommu))
4328 intel_svm_alloc_pasid_tables(iommu);
4329#endif
4330
Jiang Liuffebeb42014-11-09 22:48:02 +08004331 if (dmaru->ignored) {
4332 /*
4333 * we always have to disable PMRs or DMA may fail on this device
4334 */
4335 if (force_on)
4336 iommu_disable_protect_mem_regions(iommu);
4337 return 0;
4338 }
4339
4340 intel_iommu_init_qi(iommu);
4341 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004342
4343#ifdef CONFIG_INTEL_IOMMU_SVM
4344 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4345 ret = intel_svm_enable_prq(iommu);
4346 if (ret)
4347 goto disable_iommu;
4348 }
4349#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004350 ret = dmar_set_interrupt(iommu);
4351 if (ret)
4352 goto disable_iommu;
4353
4354 iommu_set_root_entry(iommu);
4355 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4356 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4357 iommu_enable_translation(iommu);
4358
Jiang Liuffebeb42014-11-09 22:48:02 +08004359 iommu_disable_protect_mem_regions(iommu);
4360 return 0;
4361
4362disable_iommu:
4363 disable_dmar_iommu(iommu);
4364out:
4365 free_dmar_iommu(iommu);
4366 return ret;
4367}
4368
Jiang Liu6b197242014-11-09 22:47:58 +08004369int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4370{
Jiang Liuffebeb42014-11-09 22:48:02 +08004371 int ret = 0;
4372 struct intel_iommu *iommu = dmaru->iommu;
4373
4374 if (!intel_iommu_enabled)
4375 return 0;
4376 if (iommu == NULL)
4377 return -EINVAL;
4378
4379 if (insert) {
4380 ret = intel_iommu_add(dmaru);
4381 } else {
4382 disable_dmar_iommu(iommu);
4383 free_dmar_iommu(iommu);
4384 }
4385
4386 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004387}
4388
Jiang Liu9bdc5312014-01-06 14:18:27 +08004389static void intel_iommu_free_dmars(void)
4390{
4391 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4392 struct dmar_atsr_unit *atsru, *atsr_n;
4393
4394 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4395 list_del(&rmrru->list);
4396 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004397 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004398 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004399 }
4400
Jiang Liu9bdc5312014-01-06 14:18:27 +08004401 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4402 list_del(&atsru->list);
4403 intel_iommu_free_atsr(atsru);
4404 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004405}
4406
4407int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4408{
Jiang Liub683b232014-02-19 14:07:32 +08004409 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004410 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004411 struct pci_dev *bridge = NULL;
4412 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004413 struct acpi_dmar_atsr *atsr;
4414 struct dmar_atsr_unit *atsru;
4415
4416 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004417 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004418 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004419 /* If it's an integrated device, allow ATS */
4420 if (!bridge)
4421 return 1;
4422 /* Connected via non-PCIe: no ATS */
4423 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004424 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004425 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004426 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004427 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004428 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004429 }
4430
Jiang Liu0e242612014-02-19 14:07:34 +08004431 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004432 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4433 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4434 if (atsr->segment != pci_domain_nr(dev->bus))
4435 continue;
4436
Jiang Liub683b232014-02-19 14:07:32 +08004437 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004438 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004439 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004440
4441 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004442 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004443 }
Jiang Liub683b232014-02-19 14:07:32 +08004444 ret = 0;
4445out:
Jiang Liu0e242612014-02-19 14:07:34 +08004446 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004447
Jiang Liub683b232014-02-19 14:07:32 +08004448 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004449}
4450
Jiang Liu59ce0512014-02-19 14:07:35 +08004451int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4452{
4453 int ret = 0;
4454 struct dmar_rmrr_unit *rmrru;
4455 struct dmar_atsr_unit *atsru;
4456 struct acpi_dmar_atsr *atsr;
4457 struct acpi_dmar_reserved_memory *rmrr;
4458
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004459 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004460 return 0;
4461
4462 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4463 rmrr = container_of(rmrru->hdr,
4464 struct acpi_dmar_reserved_memory, header);
4465 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4466 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4467 ((void *)rmrr) + rmrr->header.length,
4468 rmrr->segment, rmrru->devices,
4469 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004470 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004471 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004472 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004473 dmar_remove_dev_scope(info, rmrr->segment,
4474 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004475 }
4476 }
4477
4478 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4479 if (atsru->include_all)
4480 continue;
4481
4482 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4483 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4484 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4485 (void *)atsr + atsr->header.length,
4486 atsr->segment, atsru->devices,
4487 atsru->devices_cnt);
4488 if (ret > 0)
4489 break;
4490 else if(ret < 0)
4491 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004492 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004493 if (dmar_remove_dev_scope(info, atsr->segment,
4494 atsru->devices, atsru->devices_cnt))
4495 break;
4496 }
4497 }
4498
4499 return 0;
4500}
4501
Fenghua Yu99dcade2009-11-11 07:23:06 -08004502/*
4503 * Here we only respond to action of unbound device from driver.
4504 *
4505 * Added device is not attached to its DMAR domain here yet. That will happen
4506 * when mapping the device to iova.
4507 */
4508static int device_notifier(struct notifier_block *nb,
4509 unsigned long action, void *data)
4510{
4511 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004512 struct dmar_domain *domain;
4513
David Woodhouse3d891942014-03-06 15:59:26 +00004514 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004515 return 0;
4516
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004517 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004518 return 0;
4519
David Woodhouse1525a292014-03-06 16:19:30 +00004520 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004521 if (!domain)
4522 return 0;
4523
Joerg Roedele6de0f82015-07-22 16:30:36 +02004524 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004525 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004526 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004527
Fenghua Yu99dcade2009-11-11 07:23:06 -08004528 return 0;
4529}
4530
4531static struct notifier_block device_nb = {
4532 .notifier_call = device_notifier,
4533};
4534
Jiang Liu75f05562014-02-19 14:07:37 +08004535static int intel_iommu_memory_notifier(struct notifier_block *nb,
4536 unsigned long val, void *v)
4537{
4538 struct memory_notify *mhp = v;
4539 unsigned long long start, end;
4540 unsigned long start_vpfn, last_vpfn;
4541
4542 switch (val) {
4543 case MEM_GOING_ONLINE:
4544 start = mhp->start_pfn << PAGE_SHIFT;
4545 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4546 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004547 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004548 start, end);
4549 return NOTIFY_BAD;
4550 }
4551 break;
4552
4553 case MEM_OFFLINE:
4554 case MEM_CANCEL_ONLINE:
4555 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4556 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4557 while (start_vpfn <= last_vpfn) {
4558 struct iova *iova;
4559 struct dmar_drhd_unit *drhd;
4560 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004561 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004562
4563 iova = find_iova(&si_domain->iovad, start_vpfn);
4564 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004565 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004566 start_vpfn);
4567 break;
4568 }
4569
4570 iova = split_and_remove_iova(&si_domain->iovad, iova,
4571 start_vpfn, last_vpfn);
4572 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004573 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004574 start_vpfn, last_vpfn);
4575 return NOTIFY_BAD;
4576 }
4577
David Woodhouseea8ea462014-03-05 17:09:32 +00004578 freelist = domain_unmap(si_domain, iova->pfn_lo,
4579 iova->pfn_hi);
4580
Jiang Liu75f05562014-02-19 14:07:37 +08004581 rcu_read_lock();
4582 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004583 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004584 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004585 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004586 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004587 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004588
4589 start_vpfn = iova->pfn_hi + 1;
4590 free_iova_mem(iova);
4591 }
4592 break;
4593 }
4594
4595 return NOTIFY_OK;
4596}
4597
4598static struct notifier_block intel_iommu_memory_nb = {
4599 .notifier_call = intel_iommu_memory_notifier,
4600 .priority = 0
4601};
4602
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004603static void free_all_cpu_cached_iovas(unsigned int cpu)
4604{
4605 int i;
4606
4607 for (i = 0; i < g_num_of_iommus; i++) {
4608 struct intel_iommu *iommu = g_iommus[i];
4609 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004610 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004611
4612 if (!iommu)
4613 continue;
4614
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004615 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004616 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004617
4618 if (!domain)
4619 continue;
4620 free_cpu_cached_iovas(cpu, &domain->iovad);
4621 }
4622 }
4623}
4624
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004625static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004626{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004627 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004628 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004629}
4630
Joerg Roedel161b28a2017-03-28 17:04:52 +02004631static void intel_disable_iommus(void)
4632{
4633 struct intel_iommu *iommu = NULL;
4634 struct dmar_drhd_unit *drhd;
4635
4636 for_each_iommu(iommu, drhd)
4637 iommu_disable_translation(iommu);
4638}
4639
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004640static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4641{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004642 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4643
4644 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004645}
4646
Alex Williamsona5459cf2014-06-12 16:12:31 -06004647static ssize_t intel_iommu_show_version(struct device *dev,
4648 struct device_attribute *attr,
4649 char *buf)
4650{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004651 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004652 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4653 return sprintf(buf, "%d:%d\n",
4654 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4655}
4656static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4657
4658static ssize_t intel_iommu_show_address(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 Williamsona5459cf2014-06-12 16:12:31 -06004663 return sprintf(buf, "%llx\n", iommu->reg_phys);
4664}
4665static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4666
4667static ssize_t intel_iommu_show_cap(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 Williamsona5459cf2014-06-12 16:12:31 -06004672 return sprintf(buf, "%llx\n", iommu->cap);
4673}
4674static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4675
4676static ssize_t intel_iommu_show_ecap(struct device *dev,
4677 struct device_attribute *attr,
4678 char *buf)
4679{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004680 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004681 return sprintf(buf, "%llx\n", iommu->ecap);
4682}
4683static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4684
Alex Williamson2238c082015-07-14 15:24:53 -06004685static ssize_t intel_iommu_show_ndoms(struct device *dev,
4686 struct device_attribute *attr,
4687 char *buf)
4688{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004689 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004690 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4691}
4692static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4693
4694static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4695 struct device_attribute *attr,
4696 char *buf)
4697{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004698 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004699 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4700 cap_ndoms(iommu->cap)));
4701}
4702static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4703
Alex Williamsona5459cf2014-06-12 16:12:31 -06004704static struct attribute *intel_iommu_attrs[] = {
4705 &dev_attr_version.attr,
4706 &dev_attr_address.attr,
4707 &dev_attr_cap.attr,
4708 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004709 &dev_attr_domains_supported.attr,
4710 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004711 NULL,
4712};
4713
4714static struct attribute_group intel_iommu_group = {
4715 .name = "intel-iommu",
4716 .attrs = intel_iommu_attrs,
4717};
4718
4719const struct attribute_group *intel_iommu_groups[] = {
4720 &intel_iommu_group,
4721 NULL,
4722};
4723
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004724int __init intel_iommu_init(void)
4725{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004726 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004727 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004728 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004729
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004730 /* VT-d is required for a TXT/tboot launch, so enforce that */
4731 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004732
Jiang Liu3a5670e2014-02-19 14:07:33 +08004733 if (iommu_init_mempool()) {
4734 if (force_on)
4735 panic("tboot: Failed to initialize iommu memory\n");
4736 return -ENOMEM;
4737 }
4738
4739 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004740 if (dmar_table_init()) {
4741 if (force_on)
4742 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004743 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004744 }
4745
Suresh Siddhac2c72862011-08-23 17:05:19 -07004746 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004747 if (force_on)
4748 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004749 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004750 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004751
Joerg Roedelec154bf2017-10-06 15:00:53 +02004752 up_write(&dmar_global_lock);
4753
4754 /*
4755 * The bus notifier takes the dmar_global_lock, so lockdep will
4756 * complain later when we register it under the lock.
4757 */
4758 dmar_register_bus_notifier();
4759
4760 down_write(&dmar_global_lock);
4761
Joerg Roedel161b28a2017-03-28 17:04:52 +02004762 if (no_iommu || dmar_disabled) {
4763 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004764 * We exit the function here to ensure IOMMU's remapping and
4765 * mempool aren't setup, which means that the IOMMU's PMRs
4766 * won't be disabled via the call to init_dmars(). So disable
4767 * it explicitly here. The PMRs were setup by tboot prior to
4768 * calling SENTER, but the kernel is expected to reset/tear
4769 * down the PMRs.
4770 */
4771 if (intel_iommu_tboot_noforce) {
4772 for_each_iommu(iommu, drhd)
4773 iommu_disable_protect_mem_regions(iommu);
4774 }
4775
4776 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004777 * Make sure the IOMMUs are switched off, even when we
4778 * boot into a kexec kernel and the previous kernel left
4779 * them enabled
4780 */
4781 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004782 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004783 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004784
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004785 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004786 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004787
4788 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004789 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004790
Joseph Cihula51a63e62011-03-21 11:04:24 -07004791 if (dmar_init_reserved_ranges()) {
4792 if (force_on)
4793 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004794 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004795 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004796
4797 init_no_remapping_devices();
4798
Joseph Cihulab7792602011-05-03 00:08:37 -07004799 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004800 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004801 if (force_on)
4802 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004803 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004804 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004805 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004806 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004807 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004808
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004809#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004810 swiotlb = 0;
4811#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004812 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004813
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004814 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004815
Joerg Roedel39ab9552017-02-01 16:56:46 +01004816 for_each_active_iommu(iommu, drhd) {
4817 iommu_device_sysfs_add(&iommu->iommu, NULL,
4818 intel_iommu_groups,
4819 "%s", iommu->name);
4820 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4821 iommu_device_register(&iommu->iommu);
4822 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004823
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004824 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004825 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004826 if (si_domain && !hw_pass_through)
4827 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004828 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4829 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004830 intel_iommu_enabled = 1;
4831
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004832 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004833
4834out_free_reserved_range:
4835 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004836out_free_dmar:
4837 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004838 up_write(&dmar_global_lock);
4839 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004840 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004841}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004842
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004843static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004844{
4845 struct intel_iommu *iommu = opaque;
4846
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004847 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004848 return 0;
4849}
4850
4851/*
4852 * NB - intel-iommu lacks any sort of reference counting for the users of
4853 * dependent devices. If multiple endpoints have intersecting dependent
4854 * devices, unbinding the driver from any one of them will possibly leave
4855 * the others unable to operate.
4856 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004857static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004858{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004859 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004860 return;
4861
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004862 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004863}
4864
Joerg Roedel127c7612015-07-23 17:44:46 +02004865static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004866{
Weidong Hanc7151a82008-12-08 22:51:37 +08004867 struct intel_iommu *iommu;
4868 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004869
Joerg Roedel55d94042015-07-22 16:50:40 +02004870 assert_spin_locked(&device_domain_lock);
4871
Joerg Roedelb608ac32015-07-21 18:19:08 +02004872 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004873 return;
4874
Joerg Roedel127c7612015-07-23 17:44:46 +02004875 iommu = info->iommu;
4876
4877 if (info->dev) {
4878 iommu_disable_dev_iotlb(info);
4879 domain_context_clear(iommu, info->dev);
4880 }
4881
Joerg Roedelb608ac32015-07-21 18:19:08 +02004882 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004883
Joerg Roedeld160aca2015-07-22 11:52:53 +02004884 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004885 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004886 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004887
4888 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004889}
4890
Joerg Roedel55d94042015-07-22 16:50:40 +02004891static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4892 struct device *dev)
4893{
Joerg Roedel127c7612015-07-23 17:44:46 +02004894 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004895 unsigned long flags;
4896
Weidong Hanc7151a82008-12-08 22:51:37 +08004897 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004898 info = dev->archdata.iommu;
4899 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004900 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004901}
4902
4903static int md_domain_init(struct dmar_domain *domain, int guest_width)
4904{
4905 int adjust_width;
4906
Zhen Leiaa3ac942017-09-21 16:52:45 +01004907 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004908 domain_reserve_special_ranges(domain);
4909
4910 /* calculate AGAW */
4911 domain->gaw = guest_width;
4912 adjust_width = guestwidth_to_adjustwidth(guest_width);
4913 domain->agaw = width_to_agaw(adjust_width);
4914
Weidong Han5e98c4b2008-12-08 23:03:27 +08004915 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004916 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004917 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004918 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004919
4920 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004921 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004922 if (!domain->pgd)
4923 return -ENOMEM;
4924 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4925 return 0;
4926}
4927
Joerg Roedel00a77de2015-03-26 13:43:08 +01004928static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004929{
Joerg Roedel5d450802008-12-03 14:52:32 +01004930 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004931 struct iommu_domain *domain;
4932
4933 if (type != IOMMU_DOMAIN_UNMANAGED)
4934 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004935
Jiang Liuab8dfe22014-07-11 14:19:27 +08004936 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004937 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004938 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004939 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004940 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004941 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004942 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004943 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004944 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004945 }
Allen Kay8140a952011-10-14 12:32:17 -07004946 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004947
Joerg Roedel00a77de2015-03-26 13:43:08 +01004948 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004949 domain->geometry.aperture_start = 0;
4950 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4951 domain->geometry.force_aperture = true;
4952
Joerg Roedel00a77de2015-03-26 13:43:08 +01004953 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004954}
Kay, Allen M38717942008-09-09 18:37:29 +03004955
Joerg Roedel00a77de2015-03-26 13:43:08 +01004956static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004957{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004958 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004959}
Kay, Allen M38717942008-09-09 18:37:29 +03004960
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004961static int intel_iommu_attach_device(struct iommu_domain *domain,
4962 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004963{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004964 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004965 struct intel_iommu *iommu;
4966 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004967 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004968
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004969 if (device_is_rmrr_locked(dev)) {
4970 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4971 return -EPERM;
4972 }
4973
David Woodhouse7207d8f2014-03-09 16:31:06 -07004974 /* normally dev is not mapped */
4975 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004976 struct dmar_domain *old_domain;
4977
David Woodhouse1525a292014-03-06 16:19:30 +00004978 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004979 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004980 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004981 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004982 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004983
4984 if (!domain_type_is_vm_or_si(old_domain) &&
4985 list_empty(&old_domain->devices))
4986 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004987 }
4988 }
4989
David Woodhouse156baca2014-03-09 14:00:57 -07004990 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004991 if (!iommu)
4992 return -ENODEV;
4993
4994 /* check if this iommu agaw is sufficient for max mapped address */
4995 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004996 if (addr_width > cap_mgaw(iommu->cap))
4997 addr_width = cap_mgaw(iommu->cap);
4998
4999 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005000 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005001 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01005002 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005003 return -EFAULT;
5004 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005005 dmar_domain->gaw = addr_width;
5006
5007 /*
5008 * Knock out extra levels of page tables if necessary
5009 */
5010 while (iommu->agaw < dmar_domain->agaw) {
5011 struct dma_pte *pte;
5012
5013 pte = dmar_domain->pgd;
5014 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005015 dmar_domain->pgd = (struct dma_pte *)
5016 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005017 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005018 }
5019 dmar_domain->agaw--;
5020 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005021
Joerg Roedel28ccce02015-07-21 14:45:31 +02005022 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005023}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005024
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005025static void intel_iommu_detach_device(struct iommu_domain *domain,
5026 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005027{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005028 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005029}
Kay, Allen M38717942008-09-09 18:37:29 +03005030
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005031static int intel_iommu_map(struct iommu_domain *domain,
5032 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005033 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005034{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005035 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005036 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005037 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005038 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005039
Joerg Roedeldde57a22008-12-03 15:04:09 +01005040 if (iommu_prot & IOMMU_READ)
5041 prot |= DMA_PTE_READ;
5042 if (iommu_prot & IOMMU_WRITE)
5043 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005044 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5045 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005046
David Woodhouse163cc522009-06-28 00:51:17 +01005047 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005048 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005049 u64 end;
5050
5051 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005052 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005053 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005054 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005055 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005056 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005057 return -EFAULT;
5058 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005059 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005060 }
David Woodhousead051222009-06-28 14:22:28 +01005061 /* Round up size to next multiple of PAGE_SIZE, if it and
5062 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005063 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005064 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5065 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005066 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005067}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005068
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005069static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005070 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005071{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005072 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005073 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005074 unsigned long start_pfn, last_pfn;
5075 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005076 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005077
David Woodhouse5cf0a762014-03-19 16:07:49 +00005078 /* Cope with horrid API which requires us to unmap more than the
5079 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005080 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005081
5082 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5083 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5084
David Woodhouseea8ea462014-03-05 17:09:32 +00005085 start_pfn = iova >> VTD_PAGE_SHIFT;
5086 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5087
5088 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5089
5090 npages = last_pfn - start_pfn + 1;
5091
Shaokun Zhangf746a022018-03-22 18:18:06 +08005092 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005093 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5094 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005095
5096 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005097
David Woodhouse163cc522009-06-28 00:51:17 +01005098 if (dmar_domain->max_addr == iova + size)
5099 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005100
David Woodhouse5cf0a762014-03-19 16:07:49 +00005101 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005102}
Kay, Allen M38717942008-09-09 18:37:29 +03005103
Joerg Roedeld14d6572008-12-03 15:06:57 +01005104static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305105 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005106{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005107 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005108 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005109 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005110 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005111
David Woodhouse5cf0a762014-03-19 16:07:49 +00005112 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005113 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005114 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005115
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005116 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005117}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005118
Joerg Roedel5d587b82014-09-05 10:50:45 +02005119static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005120{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005121 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005122 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005123 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005124 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005125
Joerg Roedel5d587b82014-09-05 10:50:45 +02005126 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005127}
5128
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005129static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005130{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005131 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005132 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005133 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005134
Alex Williamsona5459cf2014-06-12 16:12:31 -06005135 iommu = device_to_iommu(dev, &bus, &devfn);
5136 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005137 return -ENODEV;
5138
Joerg Roedele3d10af2017-02-01 17:23:22 +01005139 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005140
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005141 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005142
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005143 if (IS_ERR(group))
5144 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005145
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005146 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005147 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005148}
5149
5150static void intel_iommu_remove_device(struct device *dev)
5151{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005152 struct intel_iommu *iommu;
5153 u8 bus, devfn;
5154
5155 iommu = device_to_iommu(dev, &bus, &devfn);
5156 if (!iommu)
5157 return;
5158
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005159 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005160
Joerg Roedele3d10af2017-02-01 17:23:22 +01005161 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005162}
5163
Eric Auger0659b8d2017-01-19 20:57:53 +00005164static void intel_iommu_get_resv_regions(struct device *device,
5165 struct list_head *head)
5166{
5167 struct iommu_resv_region *reg;
5168 struct dmar_rmrr_unit *rmrr;
5169 struct device *i_dev;
5170 int i;
5171
5172 rcu_read_lock();
5173 for_each_rmrr_units(rmrr) {
5174 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5175 i, i_dev) {
5176 if (i_dev != device)
5177 continue;
5178
5179 list_add_tail(&rmrr->resv->list, head);
5180 }
5181 }
5182 rcu_read_unlock();
5183
5184 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5185 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005186 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005187 if (!reg)
5188 return;
5189 list_add_tail(&reg->list, head);
5190}
5191
5192static void intel_iommu_put_resv_regions(struct device *dev,
5193 struct list_head *head)
5194{
5195 struct iommu_resv_region *entry, *next;
5196
5197 list_for_each_entry_safe(entry, next, head, list) {
5198 if (entry->type == IOMMU_RESV_RESERVED)
5199 kfree(entry);
5200 }
Kay, Allen M38717942008-09-09 18:37:29 +03005201}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005202
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005203#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005204#define MAX_NR_PASID_BITS (20)
5205static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5206{
5207 /*
5208 * Convert ecap_pss to extend context entry pts encoding, also
5209 * respect the soft pasid_max value set by the iommu.
5210 * - number of PASID bits = ecap_pss + 1
5211 * - number of PASID table entries = 2^(pts + 5)
5212 * Therefore, pts = ecap_pss - 4
5213 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5214 */
5215 if (ecap_pss(iommu->ecap) < 5)
5216 return 0;
5217
5218 /* pasid_max is encoded as actual number of entries not the bits */
5219 return find_first_bit((unsigned long *)&iommu->pasid_max,
5220 MAX_NR_PASID_BITS) - 5;
5221}
5222
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005223int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5224{
5225 struct device_domain_info *info;
5226 struct context_entry *context;
5227 struct dmar_domain *domain;
5228 unsigned long flags;
5229 u64 ctx_lo;
5230 int ret;
5231
5232 domain = get_valid_domain_for_dev(sdev->dev);
5233 if (!domain)
5234 return -EINVAL;
5235
5236 spin_lock_irqsave(&device_domain_lock, flags);
5237 spin_lock(&iommu->lock);
5238
5239 ret = -EINVAL;
5240 info = sdev->dev->archdata.iommu;
5241 if (!info || !info->pasid_supported)
5242 goto out;
5243
5244 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5245 if (WARN_ON(!context))
5246 goto out;
5247
5248 ctx_lo = context[0].lo;
5249
5250 sdev->did = domain->iommu_did[iommu->seq_id];
5251 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5252
5253 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005254 if (iommu->pasid_state_table)
5255 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005256 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5257 intel_iommu_get_pts(iommu);
5258
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005259 wmb();
5260 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5261 * extended to permit requests-with-PASID if the PASIDE bit
5262 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5263 * however, the PASIDE bit is ignored and requests-with-PASID
5264 * are unconditionally blocked. Which makes less sense.
5265 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5266 * "guest mode" translation types depending on whether ATS
5267 * is available or not. Annoyingly, we can't use the new
5268 * modes *unless* PASIDE is set. */
5269 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5270 ctx_lo &= ~CONTEXT_TT_MASK;
5271 if (info->ats_supported)
5272 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5273 else
5274 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5275 }
5276 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005277 if (iommu->pasid_state_table)
5278 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005279 if (info->pri_supported)
5280 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005281 context[0].lo = ctx_lo;
5282 wmb();
5283 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5284 DMA_CCMD_MASK_NOBIT,
5285 DMA_CCMD_DEVICE_INVL);
5286 }
5287
5288 /* Enable PASID support in the device, if it wasn't already */
5289 if (!info->pasid_enabled)
5290 iommu_enable_dev_iotlb(info);
5291
5292 if (info->ats_enabled) {
5293 sdev->dev_iotlb = 1;
5294 sdev->qdep = info->ats_qdep;
5295 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5296 sdev->qdep = 0;
5297 }
5298 ret = 0;
5299
5300 out:
5301 spin_unlock(&iommu->lock);
5302 spin_unlock_irqrestore(&device_domain_lock, flags);
5303
5304 return ret;
5305}
5306
5307struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5308{
5309 struct intel_iommu *iommu;
5310 u8 bus, devfn;
5311
5312 if (iommu_dummy(dev)) {
5313 dev_warn(dev,
5314 "No IOMMU translation for device; cannot enable SVM\n");
5315 return NULL;
5316 }
5317
5318 iommu = device_to_iommu(dev, &bus, &devfn);
5319 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005320 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005321 return NULL;
5322 }
5323
5324 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005325 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005326 return NULL;
5327 }
5328
5329 return iommu;
5330}
5331#endif /* CONFIG_INTEL_IOMMU_SVM */
5332
Joerg Roedelb0119e82017-02-01 13:23:08 +01005333const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005334 .capable = intel_iommu_capable,
5335 .domain_alloc = intel_iommu_domain_alloc,
5336 .domain_free = intel_iommu_domain_free,
5337 .attach_dev = intel_iommu_attach_device,
5338 .detach_dev = intel_iommu_detach_device,
5339 .map = intel_iommu_map,
5340 .unmap = intel_iommu_unmap,
5341 .map_sg = default_iommu_map_sg,
5342 .iova_to_phys = intel_iommu_iova_to_phys,
5343 .add_device = intel_iommu_add_device,
5344 .remove_device = intel_iommu_remove_device,
5345 .get_resv_regions = intel_iommu_get_resv_regions,
5346 .put_resv_regions = intel_iommu_put_resv_regions,
5347 .device_group = pci_device_group,
5348 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005349};
David Woodhouse9af88142009-02-13 23:18:03 +00005350
Daniel Vetter94526182013-01-20 23:50:13 +01005351static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5352{
5353 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005354 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005355 dmar_map_gfx = 0;
5356}
5357
5358DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5359DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5360DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5361DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5362DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5363DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5364DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5365
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005366static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005367{
5368 /*
5369 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005370 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005371 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005372 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005373 rwbf_quirk = 1;
5374}
5375
5376DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005377DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5378DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5379DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5380DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5381DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5382DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005383
Adam Jacksoneecfd572010-08-25 21:17:34 +01005384#define GGC 0x52
5385#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5386#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5387#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5388#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5389#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5390#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5391#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5392#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5393
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005394static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005395{
5396 unsigned short ggc;
5397
Adam Jacksoneecfd572010-08-25 21:17:34 +01005398 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005399 return;
5400
Adam Jacksoneecfd572010-08-25 21:17:34 +01005401 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005402 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005403 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005404 } else if (dmar_map_gfx) {
5405 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005406 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005407 intel_iommu_strict = 1;
5408 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005409}
5410DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5411DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5412DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5413DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5414
David Woodhousee0fc7e02009-09-30 09:12:17 -07005415/* On Tylersburg chipsets, some BIOSes have been known to enable the
5416 ISOCH DMAR unit for the Azalia sound device, but not give it any
5417 TLB entries, which causes it to deadlock. Check for that. We do
5418 this in a function called from init_dmars(), instead of in a PCI
5419 quirk, because we don't want to print the obnoxious "BIOS broken"
5420 message if VT-d is actually disabled.
5421*/
5422static void __init check_tylersburg_isoch(void)
5423{
5424 struct pci_dev *pdev;
5425 uint32_t vtisochctrl;
5426
5427 /* If there's no Azalia in the system anyway, forget it. */
5428 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5429 if (!pdev)
5430 return;
5431 pci_dev_put(pdev);
5432
5433 /* System Management Registers. Might be hidden, in which case
5434 we can't do the sanity check. But that's OK, because the
5435 known-broken BIOSes _don't_ actually hide it, so far. */
5436 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5437 if (!pdev)
5438 return;
5439
5440 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5441 pci_dev_put(pdev);
5442 return;
5443 }
5444
5445 pci_dev_put(pdev);
5446
5447 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5448 if (vtisochctrl & 1)
5449 return;
5450
5451 /* Drop all bits other than the number of TLB entries */
5452 vtisochctrl &= 0x1c;
5453
5454 /* If we have the recommended number of TLB entries (16), fine. */
5455 if (vtisochctrl == 0x10)
5456 return;
5457
5458 /* Zero TLB entries? You get to ride the short bus to school. */
5459 if (!vtisochctrl) {
5460 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5461 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5462 dmi_get_system_info(DMI_BIOS_VENDOR),
5463 dmi_get_system_info(DMI_BIOS_VERSION),
5464 dmi_get_system_info(DMI_PRODUCT_VERSION));
5465 iommu_identity_mapping |= IDENTMAP_AZALIA;
5466 return;
5467 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005468
5469 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005470 vtisochctrl);
5471}