blob: 2b9784a1887b8766d37ec87fadc1c27209c5f790 [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 Williamsdfddb962015-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"
Lu Baolu56283172018-07-14 15:46:54 +080055#include "intel-pasid.h"
Joerg Roedel078e1ee2012-09-26 12:44:43 +020056
Fenghua Yu5b6985c2008-10-16 18:02:32 -070057#define ROOT_SIZE VTD_PAGE_SIZE
58#define CONTEXT_SIZE VTD_PAGE_SIZE
59
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070060#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000061#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070062#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070063#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070064
65#define IOAPIC_RANGE_START (0xfee00000)
66#define IOAPIC_RANGE_END (0xfeefffff)
67#define IOVA_START_ADDR (0x1000)
68
Sohil Mehta5e3b4a12017-12-20 11:59:24 -080069#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070070
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070071#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080072#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070073
David Woodhouse2ebe3152009-09-19 07:34:04 -070074#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
75#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
76
77/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
78 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
79#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
80 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
81#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070082
Robin Murphy1b722502015-01-12 17:51:15 +000083/* IO virtual address start page frame number */
84#define IOVA_START_PFN (1)
85
Mark McLoughlinf27be032008-11-20 15:49:43 +000086#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
mark gross5e0d2a62008-03-04 15:22:08 -080087
Andrew Mortondf08cdc2010-09-22 13:05:11 -070088/* page table handling */
89#define LEVEL_STRIDE (9)
90#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
91
Ohad Ben-Cohen6d1c56a2011-11-10 11:32:30 +020092/*
93 * This bitmap is used to advertise the page sizes our hardware support
94 * to the IOMMU core, which will then use this information to split
95 * physically contiguous memory regions it is mapping into page sizes
96 * that we support.
97 *
98 * Traditionally the IOMMU core just handed us the mappings directly,
99 * after making sure the size is an order of a 4KiB page and that the
100 * mapping has natural alignment.
101 *
102 * To retain this behavior, we currently advertise that we support
103 * all page sizes that are an order of 4KiB.
104 *
105 * If at some point we'd like to utilize the IOMMU core's new behavior,
106 * we could change this to advertise the real page sizes we support.
107 */
108#define INTEL_IOMMU_PGSIZES (~0xFFFUL)
109
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700110static inline int agaw_to_level(int agaw)
111{
112 return agaw + 2;
113}
114
115static inline int agaw_to_width(int agaw)
116{
Jiang Liu5c645b32014-01-06 14:18:12 +0800117 return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700118}
119
120static inline int width_to_agaw(int width)
121{
Jiang Liu5c645b32014-01-06 14:18:12 +0800122 return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700123}
124
125static inline unsigned int level_to_offset_bits(int level)
126{
127 return (level - 1) * LEVEL_STRIDE;
128}
129
130static inline int pfn_level_offset(unsigned long pfn, int level)
131{
132 return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
133}
134
135static inline unsigned long level_mask(int level)
136{
137 return -1UL << level_to_offset_bits(level);
138}
139
140static inline unsigned long level_size(int level)
141{
142 return 1UL << level_to_offset_bits(level);
143}
144
145static inline unsigned long align_to_level(unsigned long pfn, int level)
146{
147 return (pfn + level_size(level) - 1) & level_mask(level);
148}
David Woodhousefd18de52009-05-10 23:57:41 +0100149
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100150static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
151{
Jiang Liu5c645b32014-01-06 14:18:12 +0800152 return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100153}
154
David Woodhousedd4e8312009-06-27 16:21:20 +0100155/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
156 are never going to work. */
157static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
158{
159 return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT);
160}
161
162static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn)
163{
164 return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
165}
166static inline unsigned long page_to_dma_pfn(struct page *pg)
167{
168 return mm_to_dma_pfn(page_to_pfn(pg));
169}
170static inline unsigned long virt_to_dma_pfn(void *p)
171{
172 return page_to_dma_pfn(virt_to_page(p));
173}
174
Weidong Hand9630fe2008-12-08 11:06:32 +0800175/* global iommu list, set NULL for ignored DMAR units */
176static struct intel_iommu **g_iommus;
177
David Woodhousee0fc7e02009-09-30 09:12:17 -0700178static void __init check_tylersburg_isoch(void);
David Woodhouse9af88142009-02-13 23:18:03 +0000179static int rwbf_quirk;
180
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000181/*
Joseph Cihulab7792602011-05-03 00:08:37 -0700182 * set to 1 to panic kernel if can't successfully enable VT-d
183 * (used when kernel is launched w/ TXT)
184 */
185static int force_on = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700186int intel_iommu_tboot_noforce;
Joseph Cihulab7792602011-05-03 00:08:37 -0700187
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000188#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000189
Joerg Roedel091d42e2015-06-12 11:56:10 +0200190/*
191 * Take a root_entry and return the Lower Context Table Pointer (LCTP)
192 * if marked present.
193 */
194static phys_addr_t root_entry_lctp(struct root_entry *re)
195{
196 if (!(re->lo & 1))
197 return 0;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000198
Joerg Roedel091d42e2015-06-12 11:56:10 +0200199 return re->lo & VTD_PAGE_MASK;
200}
201
202/*
203 * Take a root_entry and return the Upper Context Table Pointer (UCTP)
204 * if marked present.
205 */
206static phys_addr_t root_entry_uctp(struct root_entry *re)
207{
208 if (!(re->hi & 1))
209 return 0;
210
211 return re->hi & VTD_PAGE_MASK;
212}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000213
Joerg Roedelcf484d02015-06-12 12:21:46 +0200214static inline void context_clear_pasid_enable(struct context_entry *context)
215{
216 context->lo &= ~(1ULL << 11);
217}
218
219static inline bool context_pasid_enabled(struct context_entry *context)
220{
221 return !!(context->lo & (1ULL << 11));
222}
223
224static inline void context_set_copied(struct context_entry *context)
225{
226 context->hi |= (1ull << 3);
227}
228
229static inline bool context_copied(struct context_entry *context)
230{
231 return !!(context->hi & (1ULL << 3));
232}
233
234static inline bool __context_present(struct context_entry *context)
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000235{
236 return (context->lo & 1);
237}
Joerg Roedelcf484d02015-06-12 12:21:46 +0200238
Sohil Mehta26b86092018-09-11 17:11:36 -0700239bool context_present(struct context_entry *context)
Joerg Roedelcf484d02015-06-12 12:21:46 +0200240{
241 return context_pasid_enabled(context) ?
242 __context_present(context) :
243 __context_present(context) && !context_copied(context);
244}
245
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000246static inline void context_set_present(struct context_entry *context)
247{
248 context->lo |= 1;
249}
250
251static inline void context_set_fault_enable(struct context_entry *context)
252{
253 context->lo &= (((u64)-1) << 2) | 1;
254}
255
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000256static inline void context_set_translation_type(struct context_entry *context,
257 unsigned long value)
258{
259 context->lo &= (((u64)-1) << 4) | 3;
260 context->lo |= (value & 3) << 2;
261}
262
263static inline void context_set_address_root(struct context_entry *context,
264 unsigned long value)
265{
Li, Zhen-Hua1a2262f2014-11-05 15:30:19 +0800266 context->lo &= ~VTD_PAGE_MASK;
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000267 context->lo |= value & VTD_PAGE_MASK;
268}
269
270static inline void context_set_address_width(struct context_entry *context,
271 unsigned long value)
272{
273 context->hi |= value & 7;
274}
275
276static inline void context_set_domain_id(struct context_entry *context,
277 unsigned long value)
278{
279 context->hi |= (value & ((1 << 16) - 1)) << 8;
280}
281
Joerg Roedeldbcd8612015-06-12 12:02:09 +0200282static inline int context_domain_id(struct context_entry *c)
283{
284 return((c->hi >> 8) & 0xffff);
285}
286
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000287static inline void context_clear_entry(struct context_entry *context)
288{
289 context->lo = 0;
290 context->hi = 0;
291}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000292
Mark McLoughlin622ba122008-11-20 15:49:46 +0000293/*
294 * 0: readable
295 * 1: writable
296 * 2-6: reserved
297 * 7: super page
Sheng Yang9cf06692009-03-18 15:33:07 +0800298 * 8-10: available
299 * 11: snoop behavior
Mark McLoughlin622ba122008-11-20 15:49:46 +0000300 * 12-63: Host physcial address
301 */
302struct dma_pte {
303 u64 val;
304};
Mark McLoughlin622ba122008-11-20 15:49:46 +0000305
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000306static inline void dma_clear_pte(struct dma_pte *pte)
307{
308 pte->val = 0;
309}
310
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000311static inline u64 dma_pte_addr(struct dma_pte *pte)
312{
David Woodhousec85994e2009-07-01 19:21:24 +0100313#ifdef CONFIG_64BIT
314 return pte->val & VTD_PAGE_MASK;
315#else
316 /* Must have a full atomic 64-bit read */
David Woodhouse1a8bd482010-08-10 01:38:53 +0100317 return __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
David Woodhousec85994e2009-07-01 19:21:24 +0100318#endif
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000319}
320
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000321static inline bool dma_pte_present(struct dma_pte *pte)
322{
323 return (pte->val & 3) != 0;
324}
Mark McLoughlin622ba122008-11-20 15:49:46 +0000325
Allen Kay4399c8b2011-10-14 12:32:46 -0700326static inline bool dma_pte_superpage(struct dma_pte *pte)
327{
Joerg Roedelc3c75eb2014-07-04 11:19:10 +0200328 return (pte->val & DMA_PTE_LARGE_PAGE);
Allen Kay4399c8b2011-10-14 12:32:46 -0700329}
330
David Woodhouse75e6bf92009-07-02 11:21:16 +0100331static inline int first_pte_in_page(struct dma_pte *pte)
332{
333 return !((unsigned long)pte & ~VTD_PAGE_MASK);
334}
335
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700336/*
337 * This domain is a statically identity mapping domain.
338 * 1. This domain creats a static 1:1 mapping to all usable memory.
339 * 2. It maps to each iommu if successful.
340 * 3. Each iommu mapps to this domain if successful.
341 */
David Woodhouse19943b02009-08-04 16:19:20 +0100342static struct dmar_domain *si_domain;
343static int hw_pass_through = 1;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700344
Joerg Roedel28ccce02015-07-21 14:45:31 +0200345/*
346 * Domain represents a virtual machine, more than one devices
Weidong Han1ce28fe2008-12-08 16:35:39 +0800347 * across iommus may be owned in one domain, e.g. kvm guest.
348 */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800349#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
Weidong Han1ce28fe2008-12-08 16:35:39 +0800350
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700351/* si_domain contains mulitple devices */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800352#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700353
Joerg Roedel29a27712015-07-21 17:17:12 +0200354#define for_each_domain_iommu(idx, domain) \
355 for (idx = 0; idx < g_num_of_iommus; idx++) \
356 if (domain->iommu_refcnt[idx])
357
Jiang Liub94e4112014-02-19 14:07:25 +0800358struct dmar_rmrr_unit {
359 struct list_head list; /* list of rmrr units */
360 struct acpi_dmar_header *hdr; /* ACPI header */
361 u64 base_address; /* reserved base address*/
362 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000363 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800364 int devices_cnt; /* target device count */
Eric Auger0659b8d2017-01-19 20:57:53 +0000365 struct iommu_resv_region *resv; /* reserved region handle */
Jiang Liub94e4112014-02-19 14:07:25 +0800366};
367
368struct dmar_atsr_unit {
369 struct list_head list; /* list of ATSR units */
370 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000371 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800372 int devices_cnt; /* target device count */
373 u8 include_all:1; /* include all ports */
374};
375
376static LIST_HEAD(dmar_atsr_units);
377static LIST_HEAD(dmar_rmrr_units);
378
379#define for_each_rmrr_units(rmrr) \
380 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
381
mark gross5e0d2a62008-03-04 15:22:08 -0800382/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800383static int g_num_of_iommus;
384
Jiang Liu92d03cc2014-02-19 14:07:28 +0800385static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700386static void domain_remove_dev_info(struct dmar_domain *domain);
Joerg Roedele6de0f82015-07-22 16:30:36 +0200387static void dmar_remove_one_dev_info(struct dmar_domain *domain,
388 struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200389static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Joerg Roedel2452d9d2015-07-23 16:20:14 +0200390static void domain_context_clear(struct intel_iommu *iommu,
391 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800392static int domain_detach_iommu(struct dmar_domain *domain,
393 struct intel_iommu *iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700394
Suresh Siddhad3f13812011-08-23 17:05:25 -0700395#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800396int dmar_disabled = 0;
397#else
398int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700399#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800400
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200401int intel_iommu_enabled = 0;
402EXPORT_SYMBOL_GPL(intel_iommu_enabled);
403
David Woodhouse2d9e6672010-06-15 10:57:57 +0100404static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700405static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800406static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100407static int intel_iommu_superpage = 1;
Lu Baolu765b6a92018-12-10 09:58:55 +0800408static int intel_iommu_sm = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100409static int iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100410
David Woodhouseae853dd2015-09-09 11:58:59 +0100411#define IDENTMAP_ALL 1
412#define IDENTMAP_GFX 2
413#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100414
Lu Baolu765b6a92018-12-10 09:58:55 +0800415#define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap))
416#define pasid_supported(iommu) (sm_supported(iommu) && \
417 ecap_pasid((iommu)->ecap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700418
David Woodhousec0771df2011-10-14 20:59:46 +0100419int intel_iommu_gfx_mapped;
420EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
421
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700422#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
423static DEFINE_SPINLOCK(device_domain_lock);
424static LIST_HEAD(device_domain_list);
425
Lu Baolu85319dc2018-07-14 15:46:58 +0800426/*
427 * Iterate over elements in device_domain_list and call the specified
428 * callback @fn against each element. This helper should only be used
429 * in the context where the device_domain_lock has already been holden.
430 */
431int for_each_device_domain(int (*fn)(struct device_domain_info *info,
432 void *data), void *data)
433{
434 int ret = 0;
435 struct device_domain_info *info;
436
437 assert_spin_locked(&device_domain_lock);
438 list_for_each_entry(info, &device_domain_list, global) {
439 ret = fn(info, data);
440 if (ret)
441 return ret;
442 }
443
444 return 0;
445}
446
Joerg Roedelb0119e82017-02-01 13:23:08 +0100447const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100448
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200449static bool translation_pre_enabled(struct intel_iommu *iommu)
450{
451 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
452}
453
Joerg Roedel091d42e2015-06-12 11:56:10 +0200454static void clear_translation_pre_enabled(struct intel_iommu *iommu)
455{
456 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
457}
458
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200459static void init_translation_status(struct intel_iommu *iommu)
460{
461 u32 gsts;
462
463 gsts = readl(iommu->reg + DMAR_GSTS_REG);
464 if (gsts & DMA_GSTS_TES)
465 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
466}
467
Joerg Roedel00a77de2015-03-26 13:43:08 +0100468/* Convert generic 'struct iommu_domain to private struct dmar_domain */
469static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
470{
471 return container_of(dom, struct dmar_domain, domain);
472}
473
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700474static int __init intel_iommu_setup(char *str)
475{
476 if (!str)
477 return -EINVAL;
478 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800479 if (!strncmp(str, "on", 2)) {
480 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200481 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800482 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700483 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200484 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700485 } else if (!strncmp(str, "igfx_off", 8)) {
486 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200487 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700488 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200489 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700490 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800491 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200492 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800493 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100494 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200495 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100496 intel_iommu_superpage = 0;
Lu Baolu765b6a92018-12-10 09:58:55 +0800497 } else if (!strncmp(str, "sm_off", 6)) {
498 pr_info("Intel-IOMMU: disable scalable mode support\n");
499 intel_iommu_sm = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700500 } else if (!strncmp(str, "tboot_noforce", 13)) {
501 printk(KERN_INFO
502 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
503 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700504 }
505
506 str += strcspn(str, ",");
507 while (*str == ',')
508 str++;
509 }
510 return 0;
511}
512__setup("intel_iommu=", intel_iommu_setup);
513
514static struct kmem_cache *iommu_domain_cache;
515static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700516
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200517static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
518{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200519 struct dmar_domain **domains;
520 int idx = did >> 8;
521
522 domains = iommu->domains[idx];
523 if (!domains)
524 return NULL;
525
526 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200527}
528
529static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
530 struct dmar_domain *domain)
531{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200532 struct dmar_domain **domains;
533 int idx = did >> 8;
534
535 if (!iommu->domains[idx]) {
536 size_t size = 256 * sizeof(struct dmar_domain *);
537 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
538 }
539
540 domains = iommu->domains[idx];
541 if (WARN_ON(!domains))
542 return;
543 else
544 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200545}
546
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800547void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700548{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700549 struct page *page;
550 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700551
Suresh Siddha4c923d42009-10-02 11:01:24 -0700552 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
553 if (page)
554 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700555 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700556}
557
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800558void free_pgtable_page(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700559{
560 free_page((unsigned long)vaddr);
561}
562
563static inline void *alloc_domain_mem(void)
564{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900565 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700566}
567
Kay, Allen M38717942008-09-09 18:37:29 +0300568static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700569{
570 kmem_cache_free(iommu_domain_cache, vaddr);
571}
572
573static inline void * alloc_devinfo_mem(void)
574{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900575 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700576}
577
578static inline void free_devinfo_mem(void *vaddr)
579{
580 kmem_cache_free(iommu_devinfo_cache, vaddr);
581}
582
Jiang Liuab8dfe22014-07-11 14:19:27 +0800583static inline int domain_type_is_vm(struct dmar_domain *domain)
584{
585 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
586}
587
Joerg Roedel28ccce02015-07-21 14:45:31 +0200588static inline int domain_type_is_si(struct dmar_domain *domain)
589{
590 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
591}
592
Jiang Liuab8dfe22014-07-11 14:19:27 +0800593static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
594{
595 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
596 DOMAIN_FLAG_STATIC_IDENTITY);
597}
Weidong Han1b573682008-12-08 15:34:06 +0800598
Jiang Liu162d1b12014-07-11 14:19:35 +0800599static inline int domain_pfn_supported(struct dmar_domain *domain,
600 unsigned long pfn)
601{
602 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
603
604 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
605}
606
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700607static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800608{
609 unsigned long sagaw;
610 int agaw = -1;
611
612 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700613 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800614 agaw >= 0; agaw--) {
615 if (test_bit(agaw, &sagaw))
616 break;
617 }
618
619 return agaw;
620}
621
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700622/*
623 * Calculate max SAGAW for each iommu.
624 */
625int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
626{
627 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
628}
629
630/*
631 * calculate agaw for each iommu.
632 * "SAGAW" may be different across iommus, use a default agaw, and
633 * get a supported less agaw for iommus that don't support the default agaw.
634 */
635int iommu_calculate_agaw(struct intel_iommu *iommu)
636{
637 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
638}
639
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700640/* This functionin only returns single iommu in a domain */
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800641struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
Weidong Han8c11e792008-12-08 15:29:22 +0800642{
643 int iommu_id;
644
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700645 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800646 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200647 for_each_domain_iommu(iommu_id, domain)
648 break;
649
Weidong Han8c11e792008-12-08 15:29:22 +0800650 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
651 return NULL;
652
653 return g_iommus[iommu_id];
654}
655
Weidong Han8e6040972008-12-08 15:49:06 +0800656static void domain_update_iommu_coherency(struct dmar_domain *domain)
657{
David Woodhoused0501962014-03-11 17:10:29 -0700658 struct dmar_drhd_unit *drhd;
659 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100660 bool found = false;
661 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800662
David Woodhoused0501962014-03-11 17:10:29 -0700663 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800664
Joerg Roedel29a27712015-07-21 17:17:12 +0200665 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100666 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800667 if (!ecap_coherent(g_iommus[i]->ecap)) {
668 domain->iommu_coherency = 0;
669 break;
670 }
Weidong Han8e6040972008-12-08 15:49:06 +0800671 }
David Woodhoused0501962014-03-11 17:10:29 -0700672 if (found)
673 return;
674
675 /* No hardware attached; use lowest common denominator */
676 rcu_read_lock();
677 for_each_active_iommu(iommu, drhd) {
678 if (!ecap_coherent(iommu->ecap)) {
679 domain->iommu_coherency = 0;
680 break;
681 }
682 }
683 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800684}
685
Jiang Liu161f6932014-07-11 14:19:37 +0800686static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100687{
Allen Kay8140a952011-10-14 12:32:17 -0700688 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800689 struct intel_iommu *iommu;
690 int ret = 1;
691
692 rcu_read_lock();
693 for_each_active_iommu(iommu, drhd) {
694 if (iommu != skip) {
695 if (!ecap_sc_support(iommu->ecap)) {
696 ret = 0;
697 break;
698 }
699 }
700 }
701 rcu_read_unlock();
702
703 return ret;
704}
705
706static int domain_update_iommu_superpage(struct intel_iommu *skip)
707{
708 struct dmar_drhd_unit *drhd;
709 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700710 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100711
712 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800713 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100714 }
715
Allen Kay8140a952011-10-14 12:32:17 -0700716 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800717 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700718 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800719 if (iommu != skip) {
720 mask &= cap_super_page_val(iommu->cap);
721 if (!mask)
722 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100723 }
724 }
Jiang Liu0e242612014-02-19 14:07:34 +0800725 rcu_read_unlock();
726
Jiang Liu161f6932014-07-11 14:19:37 +0800727 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100728}
729
Sheng Yang58c610b2009-03-18 15:33:05 +0800730/* Some capabilities may be different across iommus */
731static void domain_update_iommu_cap(struct dmar_domain *domain)
732{
733 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800734 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
735 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800736}
737
Sohil Mehta26b86092018-09-11 17:11:36 -0700738struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
739 u8 devfn, int alloc)
David Woodhouse03ecc322015-02-13 14:35:21 +0000740{
741 struct root_entry *root = &iommu->root_entry[bus];
742 struct context_entry *context;
743 u64 *entry;
744
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200745 entry = &root->lo;
Lu Baolu765b6a92018-12-10 09:58:55 +0800746 if (sm_supported(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000747 if (devfn >= 0x80) {
748 devfn -= 0x80;
749 entry = &root->hi;
750 }
751 devfn *= 2;
752 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000753 if (*entry & 1)
754 context = phys_to_virt(*entry & VTD_PAGE_MASK);
755 else {
756 unsigned long phy_addr;
757 if (!alloc)
758 return NULL;
759
760 context = alloc_pgtable_page(iommu->node);
761 if (!context)
762 return NULL;
763
764 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
765 phy_addr = virt_to_phys((void *)context);
766 *entry = phy_addr | 1;
767 __iommu_flush_cache(iommu, entry, sizeof(*entry));
768 }
769 return &context[devfn];
770}
771
David Woodhouse4ed6a542015-05-11 14:59:20 +0100772static int iommu_dummy(struct device *dev)
773{
774 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
775}
776
David Woodhouse156baca2014-03-09 14:00:57 -0700777static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800778{
779 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800780 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700781 struct device *tmp;
782 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800783 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800784 int i;
785
David Woodhouse4ed6a542015-05-11 14:59:20 +0100786 if (iommu_dummy(dev))
787 return NULL;
788
David Woodhouse156baca2014-03-09 14:00:57 -0700789 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700790 struct pci_dev *pf_pdev;
791
David Woodhouse156baca2014-03-09 14:00:57 -0700792 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600793
794#ifdef CONFIG_X86
795 /* VMD child devices currently cannot be handled individually */
796 if (is_vmd(pdev->bus))
797 return NULL;
798#endif
799
Ashok Raj1c387182016-10-21 15:32:05 -0700800 /* VFs aren't listed in scope tables; we need to look up
801 * the PF instead to find the IOMMU. */
802 pf_pdev = pci_physfn(pdev);
803 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700804 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100805 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700806 dev = &ACPI_COMPANION(dev)->dev;
807
Jiang Liu0e242612014-02-19 14:07:34 +0800808 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800809 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700810 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100811 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800812
Jiang Liub683b232014-02-19 14:07:32 +0800813 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700814 drhd->devices_cnt, i, tmp) {
815 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700816 /* For a VF use its original BDF# not that of the PF
817 * which we used for the IOMMU lookup. Strictly speaking
818 * we could do this for all PCI devices; we only need to
819 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100820 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700821 goto got_pdev;
822
David Woodhouse156baca2014-03-09 14:00:57 -0700823 *bus = drhd->devices[i].bus;
824 *devfn = drhd->devices[i].devfn;
825 goto out;
826 }
827
828 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000829 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700830
831 ptmp = to_pci_dev(tmp);
832 if (ptmp->subordinate &&
833 ptmp->subordinate->number <= pdev->bus->number &&
834 ptmp->subordinate->busn_res.end >= pdev->bus->number)
835 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100836 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800837
David Woodhouse156baca2014-03-09 14:00:57 -0700838 if (pdev && drhd->include_all) {
839 got_pdev:
840 *bus = pdev->bus->number;
841 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800842 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700843 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800844 }
Jiang Liub683b232014-02-19 14:07:32 +0800845 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700846 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800847 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800848
Jiang Liub683b232014-02-19 14:07:32 +0800849 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800850}
851
Weidong Han5331fe62008-12-08 23:00:00 +0800852static void domain_flush_cache(struct dmar_domain *domain,
853 void *addr, int size)
854{
855 if (!domain->iommu_coherency)
856 clflush_cache_range(addr, size);
857}
858
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700859static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
860{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700861 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000862 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700863 unsigned long flags;
864
865 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000866 context = iommu_context_addr(iommu, bus, devfn, 0);
867 if (context)
868 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700869 spin_unlock_irqrestore(&iommu->lock, flags);
870 return ret;
871}
872
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700873static void free_context_table(struct intel_iommu *iommu)
874{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700875 int i;
876 unsigned long flags;
877 struct context_entry *context;
878
879 spin_lock_irqsave(&iommu->lock, flags);
880 if (!iommu->root_entry) {
881 goto out;
882 }
883 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000884 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700885 if (context)
886 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000887
Lu Baolu765b6a92018-12-10 09:58:55 +0800888 if (!sm_supported(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000889 continue;
890
891 context = iommu_context_addr(iommu, i, 0x80, 0);
892 if (context)
893 free_pgtable_page(context);
894
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700895 }
896 free_pgtable_page(iommu->root_entry);
897 iommu->root_entry = NULL;
898out:
899 spin_unlock_irqrestore(&iommu->lock, flags);
900}
901
David Woodhouseb026fd22009-06-28 10:37:25 +0100902static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000903 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700904{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700905 struct dma_pte *parent, *pte = NULL;
906 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700907 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700908
909 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200910
Jiang Liu162d1b12014-07-11 14:19:35 +0800911 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200912 /* Address beyond IOMMU's addressing capabilities. */
913 return NULL;
914
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700915 parent = domain->pgd;
916
David Woodhouse5cf0a762014-03-19 16:07:49 +0000917 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700918 void *tmp_page;
919
David Woodhouseb026fd22009-06-28 10:37:25 +0100920 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700921 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000922 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100923 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000924 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700925 break;
926
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000927 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100928 uint64_t pteval;
929
Suresh Siddha4c923d42009-10-02 11:01:24 -0700930 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700931
David Woodhouse206a73c2009-07-01 19:30:28 +0100932 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700933 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100934
David Woodhousec85994e2009-07-01 19:21:24 +0100935 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400936 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 +0800937 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100938 /* Someone else set it while we were thinking; use theirs. */
939 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800940 else
David Woodhousec85994e2009-07-01 19:21:24 +0100941 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700942 }
David Woodhouse5cf0a762014-03-19 16:07:49 +0000943 if (level == 1)
944 break;
945
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000946 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700947 level--;
948 }
949
David Woodhouse5cf0a762014-03-19 16:07:49 +0000950 if (!*target_level)
951 *target_level = level;
952
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700953 return pte;
954}
955
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100956
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700957/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +0100958static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
959 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100960 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700961{
962 struct dma_pte *parent, *pte = NULL;
963 int total = agaw_to_level(domain->agaw);
964 int offset;
965
966 parent = domain->pgd;
967 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +0100968 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700969 pte = &parent[offset];
970 if (level == total)
971 return pte;
972
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100973 if (!dma_pte_present(pte)) {
974 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700975 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100976 }
977
Yijing Wange16922a2014-05-20 20:37:51 +0800978 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100979 *large_page = total;
980 return pte;
981 }
982
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000983 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700984 total--;
985 }
986 return NULL;
987}
988
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700989/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +0000990static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf52009-06-27 22:09:11 +0100991 unsigned long start_pfn,
992 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700993{
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100994 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +0100995 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700996
Jiang Liu162d1b12014-07-11 14:19:35 +0800997 BUG_ON(!domain_pfn_supported(domain, start_pfn));
998 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -0700999 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001000
David Woodhouse04b18e62009-06-27 19:15:01 +01001001 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001002 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001003 large_page = 1;
1004 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001005 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001006 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001007 continue;
1008 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001009 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001010 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001011 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001012 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001013 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1014
David Woodhouse310a5ab2009-06-28 18:52:20 +01001015 domain_flush_cache(domain, first_pte,
1016 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001017
1018 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001019}
1020
Alex Williamson3269ee02013-06-15 10:27:19 -06001021static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001022 int retain_level, struct dma_pte *pte,
1023 unsigned long pfn, unsigned long start_pfn,
1024 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001025{
1026 pfn = max(start_pfn, pfn);
1027 pte = &pte[pfn_level_offset(pfn, level)];
1028
1029 do {
1030 unsigned long level_pfn;
1031 struct dma_pte *level_pte;
1032
1033 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1034 goto next;
1035
David Dillowf7116e12017-01-30 19:11:11 -08001036 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001037 level_pte = phys_to_virt(dma_pte_addr(pte));
1038
David Dillowbc24c572017-06-28 19:42:23 -07001039 if (level > 2) {
1040 dma_pte_free_level(domain, level - 1, retain_level,
1041 level_pte, level_pfn, start_pfn,
1042 last_pfn);
1043 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001044
David Dillowbc24c572017-06-28 19:42:23 -07001045 /*
1046 * Free the page table if we're below the level we want to
1047 * retain and the range covers the entire table.
1048 */
1049 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001050 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001051 dma_clear_pte(pte);
1052 domain_flush_cache(domain, pte, sizeof(*pte));
1053 free_pgtable_page(level_pte);
1054 }
1055next:
1056 pfn += level_size(level);
1057 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1058}
1059
David Dillowbc24c572017-06-28 19:42:23 -07001060/*
1061 * clear last level (leaf) ptes and free page table pages below the
1062 * level we wish to keep intact.
1063 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001064static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001065 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001066 unsigned long last_pfn,
1067 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001068{
Jiang Liu162d1b12014-07-11 14:19:35 +08001069 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1070 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001071 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001072
Jiang Liud41a4ad2014-07-11 14:19:34 +08001073 dma_pte_clear_range(domain, start_pfn, last_pfn);
1074
David Woodhousef3a0a522009-06-30 03:40:07 +01001075 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001076 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001077 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001078
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001079 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001080 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001081 free_pgtable_page(domain->pgd);
1082 domain->pgd = NULL;
1083 }
1084}
1085
David Woodhouseea8ea462014-03-05 17:09:32 +00001086/* When a page at a given level is being unlinked from its parent, we don't
1087 need to *modify* it at all. All we need to do is make a list of all the
1088 pages which can be freed just as soon as we've flushed the IOTLB and we
1089 know the hardware page-walk will no longer touch them.
1090 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1091 be freed. */
1092static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1093 int level, struct dma_pte *pte,
1094 struct page *freelist)
1095{
1096 struct page *pg;
1097
1098 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1099 pg->freelist = freelist;
1100 freelist = pg;
1101
1102 if (level == 1)
1103 return freelist;
1104
Jiang Liuadeb2592014-04-09 10:20:39 +08001105 pte = page_address(pg);
1106 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001107 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1108 freelist = dma_pte_list_pagetables(domain, level - 1,
1109 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001110 pte++;
1111 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001112
1113 return freelist;
1114}
1115
1116static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1117 struct dma_pte *pte, unsigned long pfn,
1118 unsigned long start_pfn,
1119 unsigned long last_pfn,
1120 struct page *freelist)
1121{
1122 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1123
1124 pfn = max(start_pfn, pfn);
1125 pte = &pte[pfn_level_offset(pfn, level)];
1126
1127 do {
1128 unsigned long level_pfn;
1129
1130 if (!dma_pte_present(pte))
1131 goto next;
1132
1133 level_pfn = pfn & level_mask(level);
1134
1135 /* If range covers entire pagetable, free it */
1136 if (start_pfn <= level_pfn &&
1137 last_pfn >= level_pfn + level_size(level) - 1) {
1138 /* These suborbinate page tables are going away entirely. Don't
1139 bother to clear them; we're just going to *free* them. */
1140 if (level > 1 && !dma_pte_superpage(pte))
1141 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1142
1143 dma_clear_pte(pte);
1144 if (!first_pte)
1145 first_pte = pte;
1146 last_pte = pte;
1147 } else if (level > 1) {
1148 /* Recurse down into a level that isn't *entirely* obsolete */
1149 freelist = dma_pte_clear_level(domain, level - 1,
1150 phys_to_virt(dma_pte_addr(pte)),
1151 level_pfn, start_pfn, last_pfn,
1152 freelist);
1153 }
1154next:
1155 pfn += level_size(level);
1156 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1157
1158 if (first_pte)
1159 domain_flush_cache(domain, first_pte,
1160 (void *)++last_pte - (void *)first_pte);
1161
1162 return freelist;
1163}
1164
1165/* We can't just free the pages because the IOMMU may still be walking
1166 the page tables, and may have cached the intermediate levels. The
1167 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001168static struct page *domain_unmap(struct dmar_domain *domain,
1169 unsigned long start_pfn,
1170 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001171{
David Woodhouseea8ea462014-03-05 17:09:32 +00001172 struct page *freelist = NULL;
1173
Jiang Liu162d1b12014-07-11 14:19:35 +08001174 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1175 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001176 BUG_ON(start_pfn > last_pfn);
1177
1178 /* we don't need lock here; nobody else touches the iova range */
1179 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1180 domain->pgd, 0, start_pfn, last_pfn, NULL);
1181
1182 /* free pgd */
1183 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1184 struct page *pgd_page = virt_to_page(domain->pgd);
1185 pgd_page->freelist = freelist;
1186 freelist = pgd_page;
1187
1188 domain->pgd = NULL;
1189 }
1190
1191 return freelist;
1192}
1193
Joerg Roedelb6904202015-08-13 11:32:18 +02001194static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001195{
1196 struct page *pg;
1197
1198 while ((pg = freelist)) {
1199 freelist = pg->freelist;
1200 free_pgtable_page(page_address(pg));
1201 }
1202}
1203
Joerg Roedel13cf0172017-08-11 11:40:10 +02001204static void iova_entry_free(unsigned long data)
1205{
1206 struct page *freelist = (struct page *)data;
1207
1208 dma_free_pagelist(freelist);
1209}
1210
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001211/* iommu handling */
1212static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1213{
1214 struct root_entry *root;
1215 unsigned long flags;
1216
Suresh Siddha4c923d42009-10-02 11:01:24 -07001217 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001218 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001219 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001220 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001221 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001222 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001223
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001224 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001225
1226 spin_lock_irqsave(&iommu->lock, flags);
1227 iommu->root_entry = root;
1228 spin_unlock_irqrestore(&iommu->lock, flags);
1229
1230 return 0;
1231}
1232
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001233static void iommu_set_root_entry(struct intel_iommu *iommu)
1234{
David Woodhouse03ecc322015-02-13 14:35:21 +00001235 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001236 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001237 unsigned long flag;
1238
David Woodhouse03ecc322015-02-13 14:35:21 +00001239 addr = virt_to_phys(iommu->root_entry);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001240
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001241 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001242 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001243
David Woodhousec416daa2009-05-10 20:30:58 +01001244 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001245
1246 /* Make sure hardware complete it */
1247 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001248 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001249
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001250 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001251}
1252
1253static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1254{
1255 u32 val;
1256 unsigned long flag;
1257
David Woodhouse9af88142009-02-13 23:18:03 +00001258 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001259 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001260
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001261 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001262 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001263
1264 /* Make sure hardware complete it */
1265 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001266 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001267
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001268 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001269}
1270
1271/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001272static void __iommu_flush_context(struct intel_iommu *iommu,
1273 u16 did, u16 source_id, u8 function_mask,
1274 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001275{
1276 u64 val = 0;
1277 unsigned long flag;
1278
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001279 switch (type) {
1280 case DMA_CCMD_GLOBAL_INVL:
1281 val = DMA_CCMD_GLOBAL_INVL;
1282 break;
1283 case DMA_CCMD_DOMAIN_INVL:
1284 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1285 break;
1286 case DMA_CCMD_DEVICE_INVL:
1287 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1288 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1289 break;
1290 default:
1291 BUG();
1292 }
1293 val |= DMA_CCMD_ICC;
1294
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001295 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001296 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1297
1298 /* Make sure hardware complete it */
1299 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1300 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1301
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001302 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001303}
1304
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001305/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001306static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1307 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001308{
1309 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1310 u64 val = 0, val_iva = 0;
1311 unsigned long flag;
1312
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001313 switch (type) {
1314 case DMA_TLB_GLOBAL_FLUSH:
1315 /* global flush doesn't need set IVA_REG */
1316 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1317 break;
1318 case DMA_TLB_DSI_FLUSH:
1319 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1320 break;
1321 case DMA_TLB_PSI_FLUSH:
1322 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001323 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001324 val_iva = size_order | addr;
1325 break;
1326 default:
1327 BUG();
1328 }
1329 /* Note: set drain read/write */
1330#if 0
1331 /*
1332 * This is probably to be super secure.. Looks like we can
1333 * ignore it without any impact.
1334 */
1335 if (cap_read_drain(iommu->cap))
1336 val |= DMA_TLB_READ_DRAIN;
1337#endif
1338 if (cap_write_drain(iommu->cap))
1339 val |= DMA_TLB_WRITE_DRAIN;
1340
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001341 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001342 /* Note: Only uses first TLB reg currently */
1343 if (val_iva)
1344 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1345 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1346
1347 /* Make sure hardware complete it */
1348 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1349 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1350
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001351 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001352
1353 /* check IOTLB invalidation granularity */
1354 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001355 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001356 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001357 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001358 (unsigned long long)DMA_TLB_IIRG(type),
1359 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001360}
1361
David Woodhouse64ae8922014-03-09 12:52:30 -07001362static struct device_domain_info *
1363iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1364 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001365{
Yu Zhao93a23a72009-05-18 13:51:37 +08001366 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001367
Joerg Roedel55d94042015-07-22 16:50:40 +02001368 assert_spin_locked(&device_domain_lock);
1369
Yu Zhao93a23a72009-05-18 13:51:37 +08001370 if (!iommu->qi)
1371 return NULL;
1372
Yu Zhao93a23a72009-05-18 13:51:37 +08001373 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001374 if (info->iommu == iommu && info->bus == bus &&
1375 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001376 if (info->ats_supported && info->dev)
1377 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001378 break;
1379 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001380
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001381 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001382}
1383
Omer Peleg0824c592016-04-20 19:03:35 +03001384static void domain_update_iotlb(struct dmar_domain *domain)
1385{
1386 struct device_domain_info *info;
1387 bool has_iotlb_device = false;
1388
1389 assert_spin_locked(&device_domain_lock);
1390
1391 list_for_each_entry(info, &domain->devices, link) {
1392 struct pci_dev *pdev;
1393
1394 if (!info->dev || !dev_is_pci(info->dev))
1395 continue;
1396
1397 pdev = to_pci_dev(info->dev);
1398 if (pdev->ats_enabled) {
1399 has_iotlb_device = true;
1400 break;
1401 }
1402 }
1403
1404 domain->has_iotlb_device = has_iotlb_device;
1405}
1406
Yu Zhao93a23a72009-05-18 13:51:37 +08001407static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1408{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001409 struct pci_dev *pdev;
1410
Omer Peleg0824c592016-04-20 19:03:35 +03001411 assert_spin_locked(&device_domain_lock);
1412
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001413 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001414 return;
1415
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001416 pdev = to_pci_dev(info->dev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001417 /* For IOMMU that supports device IOTLB throttling (DIT), we assign
1418 * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
1419 * queue depth at PF level. If DIT is not set, PFSID will be treated as
1420 * reserved, which should be set to 0.
1421 */
1422 if (!ecap_dit(info->iommu->ecap))
1423 info->pfsid = 0;
1424 else {
1425 struct pci_dev *pf_pdev;
1426
1427 /* pdev will be returned if device is not a vf */
1428 pf_pdev = pci_physfn(pdev);
1429 info->pfsid = PCI_DEVID(pf_pdev->bus->number, pf_pdev->devfn);
1430 }
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001431
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001432#ifdef CONFIG_INTEL_IOMMU_SVM
1433 /* The PCIe spec, in its wisdom, declares that the behaviour of
1434 the device if you enable PASID support after ATS support is
1435 undefined. So always enable PASID support on devices which
1436 have it, even if we can't yet know if we're ever going to
1437 use it. */
1438 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1439 info->pasid_enabled = 1;
1440
1441 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1442 info->pri_enabled = 1;
1443#endif
1444 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1445 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001446 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001447 info->ats_qdep = pci_ats_queue_depth(pdev);
1448 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001449}
1450
1451static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1452{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001453 struct pci_dev *pdev;
1454
Omer Peleg0824c592016-04-20 19:03:35 +03001455 assert_spin_locked(&device_domain_lock);
1456
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001457 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001458 return;
1459
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001460 pdev = to_pci_dev(info->dev);
1461
1462 if (info->ats_enabled) {
1463 pci_disable_ats(pdev);
1464 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001465 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001466 }
1467#ifdef CONFIG_INTEL_IOMMU_SVM
1468 if (info->pri_enabled) {
1469 pci_disable_pri(pdev);
1470 info->pri_enabled = 0;
1471 }
1472 if (info->pasid_enabled) {
1473 pci_disable_pasid(pdev);
1474 info->pasid_enabled = 0;
1475 }
1476#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001477}
1478
1479static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1480 u64 addr, unsigned mask)
1481{
1482 u16 sid, qdep;
1483 unsigned long flags;
1484 struct device_domain_info *info;
1485
Omer Peleg0824c592016-04-20 19:03:35 +03001486 if (!domain->has_iotlb_device)
1487 return;
1488
Yu Zhao93a23a72009-05-18 13:51:37 +08001489 spin_lock_irqsave(&device_domain_lock, flags);
1490 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001491 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001492 continue;
1493
1494 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001495 qdep = info->ats_qdep;
Jacob Pan1c48db42018-06-07 09:57:00 -07001496 qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
1497 qdep, addr, mask);
Yu Zhao93a23a72009-05-18 13:51:37 +08001498 }
1499 spin_unlock_irqrestore(&device_domain_lock, flags);
1500}
1501
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001502static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1503 struct dmar_domain *domain,
1504 unsigned long pfn, unsigned int pages,
1505 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001506{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001507 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001508 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001509 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001510
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001511 BUG_ON(pages == 0);
1512
David Woodhouseea8ea462014-03-05 17:09:32 +00001513 if (ih)
1514 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001515 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001516 * Fallback to domain selective flush if no PSI support or the size is
1517 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001518 * PSI requires page size to be 2 ^ x, and the base address is naturally
1519 * aligned to the size
1520 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001521 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1522 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001523 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001524 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001525 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001526 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001527
1528 /*
Nadav Amit82653632010-04-01 13:24:40 +03001529 * In caching mode, changes of pages from non-present to present require
1530 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001531 */
Nadav Amit82653632010-04-01 13:24:40 +03001532 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001533 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001534}
1535
Peter Xueed91a02018-05-04 10:34:52 +08001536/* Notification for newly created mappings */
1537static inline void __mapping_notify_one(struct intel_iommu *iommu,
1538 struct dmar_domain *domain,
1539 unsigned long pfn, unsigned int pages)
1540{
1541 /* It's a non-present to present mapping. Only flush if caching mode */
1542 if (cap_caching_mode(iommu->cap))
1543 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1544 else
1545 iommu_flush_write_buffer(iommu);
1546}
1547
Joerg Roedel13cf0172017-08-11 11:40:10 +02001548static void iommu_flush_iova(struct iova_domain *iovad)
1549{
1550 struct dmar_domain *domain;
1551 int idx;
1552
1553 domain = container_of(iovad, struct dmar_domain, iovad);
1554
1555 for_each_domain_iommu(idx, domain) {
1556 struct intel_iommu *iommu = g_iommus[idx];
1557 u16 did = domain->iommu_did[iommu->seq_id];
1558
1559 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1560
1561 if (!cap_caching_mode(iommu->cap))
1562 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1563 0, MAX_AGAW_PFN_WIDTH);
1564 }
1565}
1566
mark grossf8bab732008-02-08 04:18:38 -08001567static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1568{
1569 u32 pmen;
1570 unsigned long flags;
1571
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001572 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001573 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1574 pmen &= ~DMA_PMEN_EPM;
1575 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1576
1577 /* wait for the protected region status bit to clear */
1578 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1579 readl, !(pmen & DMA_PMEN_PRS), pmen);
1580
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001581 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001582}
1583
Jiang Liu2a41cce2014-07-11 14:19:33 +08001584static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001585{
1586 u32 sts;
1587 unsigned long flags;
1588
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001589 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001590 iommu->gcmd |= DMA_GCMD_TE;
1591 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001592
1593 /* Make sure hardware complete it */
1594 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001595 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001596
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001597 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001598}
1599
Jiang Liu2a41cce2014-07-11 14:19:33 +08001600static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001601{
1602 u32 sts;
1603 unsigned long flag;
1604
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001605 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001606 iommu->gcmd &= ~DMA_GCMD_TE;
1607 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1608
1609 /* Make sure hardware complete it */
1610 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001611 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001612
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001613 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001614}
1615
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001616
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001617static int iommu_init_domains(struct intel_iommu *iommu)
1618{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001619 u32 ndomains, nlongs;
1620 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001621
1622 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001623 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001624 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001625 nlongs = BITS_TO_LONGS(ndomains);
1626
Donald Dutile94a91b502009-08-20 16:51:34 -04001627 spin_lock_init(&iommu->lock);
1628
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001629 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1630 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001631 pr_err("%s: Allocating domain id array failed\n",
1632 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001633 return -ENOMEM;
1634 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001635
Wei Yang86f004c2016-05-21 02:41:51 +00001636 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001637 iommu->domains = kzalloc(size, GFP_KERNEL);
1638
1639 if (iommu->domains) {
1640 size = 256 * sizeof(struct dmar_domain *);
1641 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1642 }
1643
1644 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001645 pr_err("%s: Allocating domain array failed\n",
1646 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001647 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001648 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001649 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001650 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001651 return -ENOMEM;
1652 }
1653
Joerg Roedel8bf47812015-07-21 10:41:21 +02001654
1655
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001656 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001657 * If Caching mode is set, then invalid translations are tagged
1658 * with domain-id 0, hence we need to pre-allocate it. We also
1659 * use domain-id 0 as a marker for non-allocated domain-id, so
1660 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001661 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001662 set_bit(0, iommu->domain_ids);
1663
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001664 return 0;
1665}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001666
Jiang Liuffebeb42014-11-09 22:48:02 +08001667static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001668{
Joerg Roedel29a27712015-07-21 17:17:12 +02001669 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001670 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671
Joerg Roedel29a27712015-07-21 17:17:12 +02001672 if (!iommu->domains || !iommu->domain_ids)
1673 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001674
Joerg Roedelbea64032016-11-08 15:08:26 +01001675again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001676 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001677 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1678 struct dmar_domain *domain;
1679
1680 if (info->iommu != iommu)
1681 continue;
1682
1683 if (!info->dev || !info->domain)
1684 continue;
1685
1686 domain = info->domain;
1687
Joerg Roedelbea64032016-11-08 15:08:26 +01001688 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001689
Joerg Roedelbea64032016-11-08 15:08:26 +01001690 if (!domain_type_is_vm_or_si(domain)) {
1691 /*
1692 * The domain_exit() function can't be called under
1693 * device_domain_lock, as it takes this lock itself.
1694 * So release the lock here and re-run the loop
1695 * afterwards.
1696 */
1697 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001698 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001699 goto again;
1700 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001701 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001702 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001703
1704 if (iommu->gcmd & DMA_GCMD_TE)
1705 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001706}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001707
Jiang Liuffebeb42014-11-09 22:48:02 +08001708static void free_dmar_iommu(struct intel_iommu *iommu)
1709{
1710 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001711 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001712 int i;
1713
1714 for (i = 0; i < elems; i++)
1715 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001716 kfree(iommu->domains);
1717 kfree(iommu->domain_ids);
1718 iommu->domains = NULL;
1719 iommu->domain_ids = NULL;
1720 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001721
Weidong Hand9630fe2008-12-08 11:06:32 +08001722 g_iommus[iommu->seq_id] = NULL;
1723
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001724 /* free context mapping */
1725 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001726
1727#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08001728 if (pasid_supported(iommu)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01001729 if (ecap_prs(iommu->ecap))
1730 intel_svm_finish_prq(iommu);
Lu Baolud9737952018-07-14 15:47:02 +08001731 intel_svm_exit(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001732 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001733#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001734}
1735
Jiang Liuab8dfe22014-07-11 14:19:27 +08001736static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001737{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001738 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001739
1740 domain = alloc_domain_mem();
1741 if (!domain)
1742 return NULL;
1743
Jiang Liuab8dfe22014-07-11 14:19:27 +08001744 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001745 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001746 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001747 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001748 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001749
1750 return domain;
1751}
1752
Joerg Roedeld160aca2015-07-22 11:52:53 +02001753/* Must be called with iommu->lock */
1754static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001755 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001756{
Jiang Liu44bde612014-07-11 14:19:29 +08001757 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001758 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001759
Joerg Roedel55d94042015-07-22 16:50:40 +02001760 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001761 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001762
Joerg Roedel29a27712015-07-21 17:17:12 +02001763 domain->iommu_refcnt[iommu->seq_id] += 1;
1764 domain->iommu_count += 1;
1765 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001766 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001767 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1768
1769 if (num >= ndomains) {
1770 pr_err("%s: No free domain ids\n", iommu->name);
1771 domain->iommu_refcnt[iommu->seq_id] -= 1;
1772 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001773 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001774 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001775
Joerg Roedeld160aca2015-07-22 11:52:53 +02001776 set_bit(num, iommu->domain_ids);
1777 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001778
Joerg Roedeld160aca2015-07-22 11:52:53 +02001779 domain->iommu_did[iommu->seq_id] = num;
1780 domain->nid = iommu->node;
1781
Jiang Liufb170fb2014-07-11 14:19:28 +08001782 domain_update_iommu_cap(domain);
1783 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001784
Joerg Roedel55d94042015-07-22 16:50:40 +02001785 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001786}
1787
1788static int domain_detach_iommu(struct dmar_domain *domain,
1789 struct intel_iommu *iommu)
1790{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001791 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001792
Joerg Roedel55d94042015-07-22 16:50:40 +02001793 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001794 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001795
Joerg Roedel29a27712015-07-21 17:17:12 +02001796 domain->iommu_refcnt[iommu->seq_id] -= 1;
1797 count = --domain->iommu_count;
1798 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001799 num = domain->iommu_did[iommu->seq_id];
1800 clear_bit(num, iommu->domain_ids);
1801 set_iommu_domain(iommu, num, NULL);
1802
Jiang Liufb170fb2014-07-11 14:19:28 +08001803 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001804 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001805 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001806
1807 return count;
1808}
1809
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001810static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001811static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001812
Joseph Cihula51a63e62011-03-21 11:04:24 -07001813static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001814{
1815 struct pci_dev *pdev = NULL;
1816 struct iova *iova;
1817 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001818
Zhen Leiaa3ac942017-09-21 16:52:45 +01001819 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001820
Mark Gross8a443df2008-03-04 14:59:31 -08001821 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1822 &reserved_rbtree_key);
1823
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001824 /* IOAPIC ranges shouldn't be accessed by DMA */
1825 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1826 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001827 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001828 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001829 return -ENODEV;
1830 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001831
1832 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1833 for_each_pci_dev(pdev) {
1834 struct resource *r;
1835
1836 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1837 r = &pdev->resource[i];
1838 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1839 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001840 iova = reserve_iova(&reserved_iova_list,
1841 IOVA_PFN(r->start),
1842 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001843 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001844 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001845 return -ENODEV;
1846 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001847 }
1848 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001849 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001850}
1851
1852static void domain_reserve_special_ranges(struct dmar_domain *domain)
1853{
1854 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1855}
1856
1857static inline int guestwidth_to_adjustwidth(int gaw)
1858{
1859 int agaw;
1860 int r = (gaw - 12) % 9;
1861
1862 if (r == 0)
1863 agaw = gaw;
1864 else
1865 agaw = gaw + 9 - r;
1866 if (agaw > 64)
1867 agaw = 64;
1868 return agaw;
1869}
1870
Joerg Roedeldc534b22015-07-22 12:44:02 +02001871static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1872 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001873{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001874 int adjust_width, agaw;
1875 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001876 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001877
Zhen Leiaa3ac942017-09-21 16:52:45 +01001878 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001879
1880 err = init_iova_flush_queue(&domain->iovad,
1881 iommu_flush_iova, iova_entry_free);
1882 if (err)
1883 return err;
1884
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001885 domain_reserve_special_ranges(domain);
1886
1887 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001888 if (guest_width > cap_mgaw(iommu->cap))
1889 guest_width = cap_mgaw(iommu->cap);
1890 domain->gaw = guest_width;
1891 adjust_width = guestwidth_to_adjustwidth(guest_width);
1892 agaw = width_to_agaw(adjust_width);
1893 sagaw = cap_sagaw(iommu->cap);
1894 if (!test_bit(agaw, &sagaw)) {
1895 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001896 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001897 agaw = find_next_bit(&sagaw, 5, agaw);
1898 if (agaw >= 5)
1899 return -ENODEV;
1900 }
1901 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001902
Weidong Han8e6040972008-12-08 15:49:06 +08001903 if (ecap_coherent(iommu->ecap))
1904 domain->iommu_coherency = 1;
1905 else
1906 domain->iommu_coherency = 0;
1907
Sheng Yang58c610b2009-03-18 15:33:05 +08001908 if (ecap_sc_support(iommu->ecap))
1909 domain->iommu_snooping = 1;
1910 else
1911 domain->iommu_snooping = 0;
1912
David Woodhouse214e39a2014-03-19 10:38:49 +00001913 if (intel_iommu_superpage)
1914 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1915 else
1916 domain->iommu_superpage = 0;
1917
Suresh Siddha4c923d42009-10-02 11:01:24 -07001918 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001919
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001920 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001921 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001922 if (!domain->pgd)
1923 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001924 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001925 return 0;
1926}
1927
1928static void domain_exit(struct dmar_domain *domain)
1929{
David Woodhouseea8ea462014-03-05 17:09:32 +00001930 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001931
1932 /* Domain 0 is reserved, so dont process it */
1933 if (!domain)
1934 return;
1935
Joerg Roedeld160aca2015-07-22 11:52:53 +02001936 /* Remove associated devices and clear attached or cached domains */
1937 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001938 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001939 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08001940
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001941 /* destroy iovas */
1942 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001943
David Woodhouseea8ea462014-03-05 17:09:32 +00001944 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001945
David Woodhouseea8ea462014-03-05 17:09:32 +00001946 dma_free_pagelist(freelist);
1947
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001948 free_domain_mem(domain);
1949}
1950
David Woodhouse64ae8922014-03-09 12:52:30 -07001951static int domain_context_mapping_one(struct dmar_domain *domain,
1952 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001953 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001954{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001955 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02001956 int translation = CONTEXT_TT_MULTI_LEVEL;
1957 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001958 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001959 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08001960 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02001961 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02001962
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001963 WARN_ON(did == 0);
1964
Joerg Roedel28ccce02015-07-21 14:45:31 +02001965 if (hw_pass_through && domain_type_is_si(domain))
1966 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001967
1968 pr_debug("Set context mapping for %02x:%02x.%d\n",
1969 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07001970
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001971 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08001972
Joerg Roedel55d94042015-07-22 16:50:40 +02001973 spin_lock_irqsave(&device_domain_lock, flags);
1974 spin_lock(&iommu->lock);
1975
1976 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00001977 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001978 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02001979 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001980
Joerg Roedel55d94042015-07-22 16:50:40 +02001981 ret = 0;
1982 if (context_present(context))
1983 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02001984
Xunlei Pangaec0e862016-12-05 20:09:07 +08001985 /*
1986 * For kdump cases, old valid entries may be cached due to the
1987 * in-flight DMA and copied pgtable, but there is no unmapping
1988 * behaviour for them, thus we need an explicit cache flush for
1989 * the newly-mapped device. For kdump, at this point, the device
1990 * is supposed to finish reset at its driver probe stage, so no
1991 * in-flight DMA will exist, and we don't need to worry anymore
1992 * hereafter.
1993 */
1994 if (context_copied(context)) {
1995 u16 did_old = context_domain_id(context);
1996
Christos Gkekasb117e032017-10-08 23:33:31 +01001997 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08001998 iommu->flush.flush_context(iommu, did_old,
1999 (((u16)bus) << 8) | devfn,
2000 DMA_CCMD_MASK_NOBIT,
2001 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002002 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2003 DMA_TLB_DSI_FLUSH);
2004 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002005 }
2006
Weidong Hanea6606b2008-12-08 23:08:15 +08002007 pgd = domain->pgd;
2008
Joerg Roedelde24e552015-07-21 14:53:04 +02002009 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002010 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002011
Joerg Roedelde24e552015-07-21 14:53:04 +02002012 /*
2013 * Skip top levels of page tables for iommu which has less agaw
2014 * than default. Unnecessary for PT mode.
2015 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002016 if (translation != CONTEXT_TT_PASS_THROUGH) {
Sohil Mehta3569dd02018-11-21 15:29:33 -08002017 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002018 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002019 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002020 if (!dma_pte_present(pgd))
2021 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002022 }
2023
David Woodhouse64ae8922014-03-09 12:52:30 -07002024 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002025 if (info && info->ats_supported)
2026 translation = CONTEXT_TT_DEV_IOTLB;
2027 else
2028 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002029
Yu Zhao93a23a72009-05-18 13:51:37 +08002030 context_set_address_root(context, virt_to_phys(pgd));
Sohil Mehta3569dd02018-11-21 15:29:33 -08002031 context_set_address_width(context, agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002032 } else {
2033 /*
2034 * In pass through mode, AW must be programmed to
2035 * indicate the largest AGAW value supported by
2036 * hardware. And ASR is ignored by hardware.
2037 */
2038 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002039 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002040
2041 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002042 context_set_fault_enable(context);
2043 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002044 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002045
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002046 /*
2047 * It's a non-present to present mapping. If hardware doesn't cache
2048 * non-present entry we only need to flush the write-buffer. If the
2049 * _does_ cache non-present entries, then it does so in the special
2050 * domain #0, which we have to flush:
2051 */
2052 if (cap_caching_mode(iommu->cap)) {
2053 iommu->flush.flush_context(iommu, 0,
2054 (((u16)bus) << 8) | devfn,
2055 DMA_CCMD_MASK_NOBIT,
2056 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002057 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002058 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002059 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002060 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002061 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002062
Joerg Roedel55d94042015-07-22 16:50:40 +02002063 ret = 0;
2064
2065out_unlock:
2066 spin_unlock(&iommu->lock);
2067 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002068
Wei Yang5c365d12016-07-13 13:53:21 +00002069 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002070}
2071
Alex Williamson579305f2014-07-03 09:51:43 -06002072struct domain_context_mapping_data {
2073 struct dmar_domain *domain;
2074 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002075};
2076
2077static int domain_context_mapping_cb(struct pci_dev *pdev,
2078 u16 alias, void *opaque)
2079{
2080 struct domain_context_mapping_data *data = opaque;
2081
2082 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002083 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002084}
2085
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002086static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002087domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002088{
David Woodhouse64ae8922014-03-09 12:52:30 -07002089 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002090 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002091 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002092
David Woodhousee1f167f2014-03-09 15:24:46 -07002093 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002094 if (!iommu)
2095 return -ENODEV;
2096
Alex Williamson579305f2014-07-03 09:51:43 -06002097 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002098 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002099
2100 data.domain = domain;
2101 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002102
2103 return pci_for_each_dma_alias(to_pci_dev(dev),
2104 &domain_context_mapping_cb, &data);
2105}
2106
2107static int domain_context_mapped_cb(struct pci_dev *pdev,
2108 u16 alias, void *opaque)
2109{
2110 struct intel_iommu *iommu = opaque;
2111
2112 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002113}
2114
David Woodhousee1f167f2014-03-09 15:24:46 -07002115static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002116{
Weidong Han5331fe62008-12-08 23:00:00 +08002117 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002118 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002119
David Woodhousee1f167f2014-03-09 15:24:46 -07002120 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002121 if (!iommu)
2122 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002123
Alex Williamson579305f2014-07-03 09:51:43 -06002124 if (!dev_is_pci(dev))
2125 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002126
Alex Williamson579305f2014-07-03 09:51:43 -06002127 return !pci_for_each_dma_alias(to_pci_dev(dev),
2128 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002129}
2130
Fenghua Yuf5329592009-08-04 15:09:37 -07002131/* Returns a number of VTD pages, but aligned to MM page size */
2132static inline unsigned long aligned_nrpages(unsigned long host_addr,
2133 size_t size)
2134{
2135 host_addr &= ~PAGE_MASK;
2136 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2137}
2138
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002139/* Return largest possible superpage level for a given mapping */
2140static inline int hardware_largepage_caps(struct dmar_domain *domain,
2141 unsigned long iov_pfn,
2142 unsigned long phy_pfn,
2143 unsigned long pages)
2144{
2145 int support, level = 1;
2146 unsigned long pfnmerge;
2147
2148 support = domain->iommu_superpage;
2149
2150 /* To use a large page, the virtual *and* physical addresses
2151 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2152 of them will mean we have to use smaller pages. So just
2153 merge them and check both at once. */
2154 pfnmerge = iov_pfn | phy_pfn;
2155
2156 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2157 pages >>= VTD_STRIDE_SHIFT;
2158 if (!pages)
2159 break;
2160 pfnmerge >>= VTD_STRIDE_SHIFT;
2161 level++;
2162 support--;
2163 }
2164 return level;
2165}
2166
David Woodhouse9051aa02009-06-29 12:30:54 +01002167static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2168 struct scatterlist *sg, unsigned long phys_pfn,
2169 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002170{
2171 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002172 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002173 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002174 unsigned int largepage_lvl = 0;
2175 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002176
Jiang Liu162d1b12014-07-11 14:19:35 +08002177 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002178
2179 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2180 return -EINVAL;
2181
2182 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2183
Jiang Liucc4f14a2014-11-26 09:42:10 +08002184 if (!sg) {
2185 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002186 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2187 }
2188
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002189 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002190 uint64_t tmp;
2191
David Woodhousee1605492009-06-29 11:17:38 +01002192 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002193 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2194
Fenghua Yuf5329592009-08-04 15:09:37 -07002195 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002196 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002197 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002198 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002199 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002200 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002201
David Woodhousee1605492009-06-29 11:17:38 +01002202 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002203 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2204
David Woodhouse5cf0a762014-03-19 16:07:49 +00002205 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002206 if (!pte)
2207 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002208 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002209 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002210 unsigned long nr_superpages, end_pfn;
2211
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002212 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002213 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002214
2215 nr_superpages = sg_res / lvl_pages;
2216 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2217
Jiang Liud41a4ad2014-07-11 14:19:34 +08002218 /*
2219 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002220 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002221 * We're adding new large pages, so make sure
2222 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002223 */
David Dillowbc24c572017-06-28 19:42:23 -07002224 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2225 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002226 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002227 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002228 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002229
David Woodhousee1605492009-06-29 11:17:38 +01002230 }
2231 /* We don't need lock here, nobody else
2232 * touches the iova range
2233 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002234 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002235 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002236 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002237 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2238 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002239 if (dumps) {
2240 dumps--;
2241 debug_dma_dump_mappings(NULL);
2242 }
2243 WARN_ON(1);
2244 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002245
2246 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2247
2248 BUG_ON(nr_pages < lvl_pages);
2249 BUG_ON(sg_res < lvl_pages);
2250
2251 nr_pages -= lvl_pages;
2252 iov_pfn += lvl_pages;
2253 phys_pfn += lvl_pages;
2254 pteval += lvl_pages * VTD_PAGE_SIZE;
2255 sg_res -= lvl_pages;
2256
2257 /* If the next PTE would be the first in a new page, then we
2258 need to flush the cache on the entries we've just written.
2259 And then we'll need to recalculate 'pte', so clear it and
2260 let it get set again in the if (!pte) block above.
2261
2262 If we're done (!nr_pages) we need to flush the cache too.
2263
2264 Also if we've been setting superpages, we may need to
2265 recalculate 'pte' and switch back to smaller pages for the
2266 end of the mapping, if the trailing size is not enough to
2267 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002268 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002269 if (!nr_pages || first_pte_in_page(pte) ||
2270 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002271 domain_flush_cache(domain, first_pte,
2272 (void *)pte - (void *)first_pte);
2273 pte = NULL;
2274 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002275
2276 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002277 sg = sg_next(sg);
2278 }
2279 return 0;
2280}
2281
Peter Xu87684fd2018-05-04 10:34:53 +08002282static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2283 struct scatterlist *sg, unsigned long phys_pfn,
2284 unsigned long nr_pages, int prot)
2285{
2286 int ret;
2287 struct intel_iommu *iommu;
2288
2289 /* Do the real mapping first */
2290 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2291 if (ret)
2292 return ret;
2293
2294 /* Notify about the new mapping */
2295 if (domain_type_is_vm(domain)) {
2296 /* VM typed domains can have more than one IOMMUs */
2297 int iommu_id;
2298 for_each_domain_iommu(iommu_id, domain) {
2299 iommu = g_iommus[iommu_id];
2300 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2301 }
2302 } else {
2303 /* General domains only have one IOMMU */
2304 iommu = domain_get_iommu(domain);
2305 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2306 }
2307
2308 return 0;
2309}
2310
David Woodhouse9051aa02009-06-29 12:30:54 +01002311static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2312 struct scatterlist *sg, unsigned long nr_pages,
2313 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002314{
Peter Xu87684fd2018-05-04 10:34:53 +08002315 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002316}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002317
David Woodhouse9051aa02009-06-29 12:30:54 +01002318static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2319 unsigned long phys_pfn, unsigned long nr_pages,
2320 int prot)
2321{
Peter Xu87684fd2018-05-04 10:34:53 +08002322 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002323}
2324
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002325static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002326{
Filippo Sironi50822192017-08-31 10:58:11 +02002327 unsigned long flags;
2328 struct context_entry *context;
2329 u16 did_old;
2330
Weidong Hanc7151a82008-12-08 22:51:37 +08002331 if (!iommu)
2332 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002333
Filippo Sironi50822192017-08-31 10:58:11 +02002334 spin_lock_irqsave(&iommu->lock, flags);
2335 context = iommu_context_addr(iommu, bus, devfn, 0);
2336 if (!context) {
2337 spin_unlock_irqrestore(&iommu->lock, flags);
2338 return;
2339 }
2340 did_old = context_domain_id(context);
2341 context_clear_entry(context);
2342 __iommu_flush_cache(iommu, context, sizeof(*context));
2343 spin_unlock_irqrestore(&iommu->lock, flags);
2344 iommu->flush.flush_context(iommu,
2345 did_old,
2346 (((u16)bus) << 8) | devfn,
2347 DMA_CCMD_MASK_NOBIT,
2348 DMA_CCMD_DEVICE_INVL);
2349 iommu->flush.flush_iotlb(iommu,
2350 did_old,
2351 0,
2352 0,
2353 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002354}
2355
David Woodhouse109b9b02012-05-25 17:43:02 +01002356static inline void unlink_domain_info(struct device_domain_info *info)
2357{
2358 assert_spin_locked(&device_domain_lock);
2359 list_del(&info->link);
2360 list_del(&info->global);
2361 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002362 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002363}
2364
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002365static void domain_remove_dev_info(struct dmar_domain *domain)
2366{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002367 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002368 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002369
2370 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002371 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002372 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002373 spin_unlock_irqrestore(&device_domain_lock, flags);
2374}
2375
2376/*
2377 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002378 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002379 */
David Woodhouse1525a292014-03-06 16:19:30 +00002380static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002381{
2382 struct device_domain_info *info;
2383
2384 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002385 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002386 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002387 return info->domain;
2388 return NULL;
2389}
2390
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002391static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002392dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2393{
2394 struct device_domain_info *info;
2395
2396 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002397 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002398 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002399 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002400
2401 return NULL;
2402}
2403
Joerg Roedel5db31562015-07-22 12:40:43 +02002404static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2405 int bus, int devfn,
2406 struct device *dev,
2407 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002408{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002409 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002410 struct device_domain_info *info;
2411 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002412 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002413
2414 info = alloc_devinfo_mem();
2415 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002416 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002417
Jiang Liu745f2582014-02-19 14:07:26 +08002418 info->bus = bus;
2419 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002420 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2421 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2422 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002423 info->dev = dev;
2424 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002425 info->iommu = iommu;
Lu Baolucc580e42018-07-14 15:46:59 +08002426 info->pasid_table = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002427
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002428 if (dev && dev_is_pci(dev)) {
2429 struct pci_dev *pdev = to_pci_dev(info->dev);
2430
Gil Kupfercef74402018-05-10 17:56:02 -05002431 if (!pci_ats_disabled() &&
2432 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002433 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2434 dmar_find_matched_atsr_unit(pdev))
2435 info->ats_supported = 1;
2436
Lu Baolu765b6a92018-12-10 09:58:55 +08002437 if (sm_supported(iommu)) {
2438 if (pasid_supported(iommu)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002439 int features = pci_pasid_features(pdev);
2440 if (features >= 0)
2441 info->pasid_supported = features | 1;
2442 }
2443
2444 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2445 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2446 info->pri_supported = 1;
2447 }
2448 }
2449
Jiang Liu745f2582014-02-19 14:07:26 +08002450 spin_lock_irqsave(&device_domain_lock, flags);
2451 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002452 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002453
2454 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002455 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002456 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002457 if (info2) {
2458 found = info2->domain;
2459 info2->dev = dev;
2460 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002461 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002462
Jiang Liu745f2582014-02-19 14:07:26 +08002463 if (found) {
2464 spin_unlock_irqrestore(&device_domain_lock, flags);
2465 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002466 /* Caller must free the original domain */
2467 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002468 }
2469
Joerg Roedeld160aca2015-07-22 11:52:53 +02002470 spin_lock(&iommu->lock);
2471 ret = domain_attach_iommu(domain, iommu);
2472 spin_unlock(&iommu->lock);
2473
2474 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002475 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302476 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002477 return NULL;
2478 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002479
David Woodhouseb718cd32014-03-09 13:11:33 -07002480 list_add(&info->link, &domain->devices);
2481 list_add(&info->global, &device_domain_list);
2482 if (dev)
2483 dev->archdata.iommu = info;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002484
2485 if (dev && dev_is_pci(dev) && info->pasid_supported) {
2486 ret = intel_pasid_alloc_table(dev);
2487 if (ret) {
Lu Baolube9e6592018-09-08 09:42:53 +08002488 pr_warn("No pasid table for %s, pasid disabled\n",
2489 dev_name(dev));
2490 info->pasid_supported = 0;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002491 }
2492 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002493 spin_unlock_irqrestore(&device_domain_lock, flags);
2494
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002495 if (dev && domain_context_mapping(domain, dev)) {
2496 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002497 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002498 return NULL;
2499 }
2500
David Woodhouseb718cd32014-03-09 13:11:33 -07002501 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002502}
2503
Alex Williamson579305f2014-07-03 09:51:43 -06002504static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2505{
2506 *(u16 *)opaque = alias;
2507 return 0;
2508}
2509
Joerg Roedel76208352016-08-25 14:25:12 +02002510static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002511{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002512 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002513 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002514 struct intel_iommu *iommu;
Lu Baolufcc35c62018-05-04 13:08:17 +08002515 u16 dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002516 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002517 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002518
David Woodhouse146922e2014-03-09 15:44:17 -07002519 iommu = device_to_iommu(dev, &bus, &devfn);
2520 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002521 return NULL;
2522
2523 if (dev_is_pci(dev)) {
2524 struct pci_dev *pdev = to_pci_dev(dev);
2525
2526 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2527
2528 spin_lock_irqsave(&device_domain_lock, flags);
2529 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2530 PCI_BUS_NUM(dma_alias),
2531 dma_alias & 0xff);
2532 if (info) {
2533 iommu = info->iommu;
2534 domain = info->domain;
2535 }
2536 spin_unlock_irqrestore(&device_domain_lock, flags);
2537
Joerg Roedel76208352016-08-25 14:25:12 +02002538 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002539 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002540 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002541 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002542
David Woodhouse146922e2014-03-09 15:44:17 -07002543 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002544 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002545 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002546 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002547 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002548 domain_exit(domain);
2549 return NULL;
2550 }
2551
Joerg Roedel76208352016-08-25 14:25:12 +02002552out:
Alex Williamson579305f2014-07-03 09:51:43 -06002553
Joerg Roedel76208352016-08-25 14:25:12 +02002554 return domain;
2555}
2556
2557static struct dmar_domain *set_domain_for_dev(struct device *dev,
2558 struct dmar_domain *domain)
2559{
2560 struct intel_iommu *iommu;
2561 struct dmar_domain *tmp;
2562 u16 req_id, dma_alias;
2563 u8 bus, devfn;
2564
2565 iommu = device_to_iommu(dev, &bus, &devfn);
2566 if (!iommu)
2567 return NULL;
2568
2569 req_id = ((u16)bus << 8) | devfn;
2570
2571 if (dev_is_pci(dev)) {
2572 struct pci_dev *pdev = to_pci_dev(dev);
2573
2574 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2575
2576 /* register PCI DMA alias device */
2577 if (req_id != dma_alias) {
2578 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2579 dma_alias & 0xff, NULL, domain);
2580
2581 if (!tmp || tmp != domain)
2582 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002583 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002584 }
2585
Joerg Roedel5db31562015-07-22 12:40:43 +02002586 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002587 if (!tmp || tmp != domain)
2588 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002589
Joerg Roedel76208352016-08-25 14:25:12 +02002590 return domain;
2591}
2592
2593static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2594{
2595 struct dmar_domain *domain, *tmp;
2596
2597 domain = find_domain(dev);
2598 if (domain)
2599 goto out;
2600
2601 domain = find_or_alloc_domain(dev, gaw);
2602 if (!domain)
2603 goto out;
2604
2605 tmp = set_domain_for_dev(dev, domain);
2606 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002607 domain_exit(domain);
2608 domain = tmp;
2609 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002610
Joerg Roedel76208352016-08-25 14:25:12 +02002611out:
2612
David Woodhouseb718cd32014-03-09 13:11:33 -07002613 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002614}
2615
David Woodhouseb2132032009-06-26 18:50:28 +01002616static int iommu_domain_identity_map(struct dmar_domain *domain,
2617 unsigned long long start,
2618 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002619{
David Woodhousec5395d52009-06-28 16:35:56 +01002620 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2621 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002622
David Woodhousec5395d52009-06-28 16:35:56 +01002623 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2624 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002625 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002626 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002627 }
2628
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002629 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002630 /*
2631 * RMRR range might have overlap with physical memory range,
2632 * clear it first
2633 */
David Woodhousec5395d52009-06-28 16:35:56 +01002634 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002635
Peter Xu87684fd2018-05-04 10:34:53 +08002636 return __domain_mapping(domain, first_vpfn, NULL,
2637 first_vpfn, last_vpfn - first_vpfn + 1,
2638 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002639}
2640
Joerg Roedeld66ce542015-09-23 19:00:10 +02002641static int domain_prepare_identity_map(struct device *dev,
2642 struct dmar_domain *domain,
2643 unsigned long long start,
2644 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002645{
David Woodhouse19943b02009-08-04 16:19:20 +01002646 /* For _hardware_ passthrough, don't bother. But for software
2647 passthrough, we do it anyway -- it may indicate a memory
2648 range which is reserved in E820, so which didn't get set
2649 up to start with in si_domain */
2650 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002651 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2652 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002653 return 0;
2654 }
2655
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002656 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2657 dev_name(dev), start, end);
2658
David Woodhouse5595b522009-12-02 09:21:55 +00002659 if (end < start) {
2660 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2661 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2662 dmi_get_system_info(DMI_BIOS_VENDOR),
2663 dmi_get_system_info(DMI_BIOS_VERSION),
2664 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002665 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002666 }
2667
David Woodhouse2ff729f2009-08-26 14:25:41 +01002668 if (end >> agaw_to_width(domain->agaw)) {
2669 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2670 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2671 agaw_to_width(domain->agaw),
2672 dmi_get_system_info(DMI_BIOS_VENDOR),
2673 dmi_get_system_info(DMI_BIOS_VERSION),
2674 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002675 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002676 }
David Woodhouse19943b02009-08-04 16:19:20 +01002677
Joerg Roedeld66ce542015-09-23 19:00:10 +02002678 return iommu_domain_identity_map(domain, start, end);
2679}
2680
2681static int iommu_prepare_identity_map(struct device *dev,
2682 unsigned long long start,
2683 unsigned long long end)
2684{
2685 struct dmar_domain *domain;
2686 int ret;
2687
2688 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2689 if (!domain)
2690 return -ENOMEM;
2691
2692 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002693 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002694 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002695
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002696 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002697}
2698
2699static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002700 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002701{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002702 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002703 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002704 return iommu_prepare_identity_map(dev, rmrr->base_address,
2705 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002706}
2707
Suresh Siddhad3f13812011-08-23 17:05:25 -07002708#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002709static inline void iommu_prepare_isa(void)
2710{
2711 struct pci_dev *pdev;
2712 int ret;
2713
2714 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2715 if (!pdev)
2716 return;
2717
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002718 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002719 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002720
2721 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002722 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002723
Yijing Wang9b27e822014-05-20 20:37:52 +08002724 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002725}
2726#else
2727static inline void iommu_prepare_isa(void)
2728{
2729 return;
2730}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002731#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002732
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002733static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002734
Matt Kraai071e1372009-08-23 22:30:22 -07002735static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002736{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002737 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002738
Jiang Liuab8dfe22014-07-11 14:19:27 +08002739 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002740 if (!si_domain)
2741 return -EFAULT;
2742
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002743 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2744 domain_exit(si_domain);
2745 return -EFAULT;
2746 }
2747
Joerg Roedel0dc79712015-07-21 15:40:06 +02002748 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002749
David Woodhouse19943b02009-08-04 16:19:20 +01002750 if (hw)
2751 return 0;
2752
David Woodhousec7ab48d2009-06-26 19:10:36 +01002753 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002754 unsigned long start_pfn, end_pfn;
2755 int i;
2756
2757 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2758 ret = iommu_domain_identity_map(si_domain,
2759 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2760 if (ret)
2761 return ret;
2762 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002763 }
2764
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002765 return 0;
2766}
2767
David Woodhouse9b226622014-03-09 14:03:28 -07002768static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002769{
2770 struct device_domain_info *info;
2771
2772 if (likely(!iommu_identity_mapping))
2773 return 0;
2774
David Woodhouse9b226622014-03-09 14:03:28 -07002775 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002776 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2777 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002778
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002779 return 0;
2780}
2781
Joerg Roedel28ccce02015-07-21 14:45:31 +02002782static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002783{
David Woodhouse0ac72662014-03-09 13:19:22 -07002784 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002785 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002786 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002787
David Woodhouse5913c9b2014-03-09 16:27:31 -07002788 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002789 if (!iommu)
2790 return -ENODEV;
2791
Joerg Roedel5db31562015-07-22 12:40:43 +02002792 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002793 if (ndomain != domain)
2794 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002795
2796 return 0;
2797}
2798
David Woodhouse0b9d9752014-03-09 15:48:15 -07002799static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002800{
2801 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002802 struct device *tmp;
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002803 int i;
2804
Jiang Liu0e242612014-02-19 14:07:34 +08002805 rcu_read_lock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002806 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002807 /*
2808 * Return TRUE if this RMRR contains the device that
2809 * is passed in.
2810 */
2811 for_each_active_dev_scope(rmrr->devices,
2812 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002813 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002814 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002815 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002816 }
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002817 }
Jiang Liu0e242612014-02-19 14:07:34 +08002818 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002819 return false;
2820}
2821
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002822/*
2823 * There are a couple cases where we need to restrict the functionality of
2824 * devices associated with RMRRs. The first is when evaluating a device for
2825 * identity mapping because problems exist when devices are moved in and out
2826 * of domains and their respective RMRR information is lost. This means that
2827 * a device with associated RMRRs will never be in a "passthrough" domain.
2828 * The second is use of the device through the IOMMU API. This interface
2829 * expects to have full control of the IOVA space for the device. We cannot
2830 * satisfy both the requirement that RMRR access is maintained and have an
2831 * unencumbered IOVA space. We also have no ability to quiesce the device's
2832 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2833 * We therefore prevent devices associated with an RMRR from participating in
2834 * the IOMMU API, which eliminates them from device assignment.
2835 *
2836 * In both cases we assume that PCI USB devices with RMRRs have them largely
2837 * for historical reasons and that the RMRR space is not actively used post
2838 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002839 *
2840 * The same exception is made for graphics devices, with the requirement that
2841 * any use of the RMRR regions will be torn down before assigning the device
2842 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002843 */
2844static bool device_is_rmrr_locked(struct device *dev)
2845{
2846 if (!device_has_rmrr(dev))
2847 return false;
2848
2849 if (dev_is_pci(dev)) {
2850 struct pci_dev *pdev = to_pci_dev(dev);
2851
David Woodhouse18436af2015-03-25 15:05:47 +00002852 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002853 return false;
2854 }
2855
2856 return true;
2857}
2858
David Woodhouse3bdb2592014-03-09 16:03:08 -07002859static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002860{
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002861
David Woodhouse3bdb2592014-03-09 16:03:08 -07002862 if (dev_is_pci(dev)) {
2863 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002864
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002865 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002866 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002867
David Woodhouse3bdb2592014-03-09 16:03:08 -07002868 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2869 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002870
David Woodhouse3bdb2592014-03-09 16:03:08 -07002871 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2872 return 1;
2873
2874 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2875 return 0;
2876
2877 /*
2878 * We want to start off with all devices in the 1:1 domain, and
2879 * take them out later if we find they can't access all of memory.
2880 *
2881 * However, we can't do this for PCI devices behind bridges,
2882 * because all PCI devices behind the same bridge will end up
2883 * with the same source-id on their transactions.
2884 *
2885 * Practically speaking, we can't change things around for these
2886 * devices at run-time, because we can't be sure there'll be no
2887 * DMA transactions in flight for any of their siblings.
2888 *
2889 * So PCI devices (unless they're on the root bus) as well as
2890 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2891 * the 1:1 domain, just in _case_ one of their siblings turns out
2892 * not to be able to map all of memory.
2893 */
2894 if (!pci_is_pcie(pdev)) {
2895 if (!pci_is_root_bus(pdev->bus))
2896 return 0;
2897 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2898 return 0;
2899 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2900 return 0;
2901 } else {
2902 if (device_has_rmrr(dev))
2903 return 0;
2904 }
David Woodhouse6941af22009-07-04 18:24:27 +01002905
David Woodhouse3dfc8132009-07-04 19:11:08 +01002906 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002907 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002908 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002909 * take them out of the 1:1 domain later.
2910 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002911 if (!startup) {
2912 /*
2913 * If the device's dma_mask is less than the system's memory
2914 * size then this is not a candidate for identity mapping.
2915 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002916 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002917
David Woodhouse3bdb2592014-03-09 16:03:08 -07002918 if (dev->coherent_dma_mask &&
2919 dev->coherent_dma_mask < dma_mask)
2920 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002921
David Woodhouse3bdb2592014-03-09 16:03:08 -07002922 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002923 }
David Woodhouse6941af22009-07-04 18:24:27 +01002924
2925 return 1;
2926}
2927
David Woodhousecf04eee2014-03-21 16:49:04 +00002928static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2929{
2930 int ret;
2931
2932 if (!iommu_should_identity_map(dev, 1))
2933 return 0;
2934
Joerg Roedel28ccce02015-07-21 14:45:31 +02002935 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002936 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002937 pr_info("%s identity mapping for device %s\n",
2938 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002939 else if (ret == -ENODEV)
2940 /* device not associated with an iommu */
2941 ret = 0;
2942
2943 return ret;
2944}
2945
2946
Matt Kraai071e1372009-08-23 22:30:22 -07002947static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002948{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002949 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002950 struct dmar_drhd_unit *drhd;
2951 struct intel_iommu *iommu;
2952 struct device *dev;
2953 int i;
2954 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002955
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002956 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002957 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2958 if (ret)
2959 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002960 }
2961
David Woodhousecf04eee2014-03-21 16:49:04 +00002962 for_each_active_iommu(iommu, drhd)
2963 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2964 struct acpi_device_physical_node *pn;
2965 struct acpi_device *adev;
2966
2967 if (dev->bus != &acpi_bus_type)
2968 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002969
David Woodhousecf04eee2014-03-21 16:49:04 +00002970 adev= to_acpi_device(dev);
2971 mutex_lock(&adev->physical_node_lock);
2972 list_for_each_entry(pn, &adev->physical_node_list, node) {
2973 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2974 if (ret)
2975 break;
2976 }
2977 mutex_unlock(&adev->physical_node_lock);
2978 if (ret)
2979 return ret;
2980 }
2981
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002982 return 0;
2983}
2984
Jiang Liuffebeb42014-11-09 22:48:02 +08002985static void intel_iommu_init_qi(struct intel_iommu *iommu)
2986{
2987 /*
2988 * Start from the sane iommu hardware state.
2989 * If the queued invalidation is already initialized by us
2990 * (for example, while enabling interrupt-remapping) then
2991 * we got the things already rolling from a sane state.
2992 */
2993 if (!iommu->qi) {
2994 /*
2995 * Clear any previous faults.
2996 */
2997 dmar_fault(-1, iommu);
2998 /*
2999 * Disable queued invalidation if supported and already enabled
3000 * before OS handover.
3001 */
3002 dmar_disable_qi(iommu);
3003 }
3004
3005 if (dmar_enable_qi(iommu)) {
3006 /*
3007 * Queued Invalidate not enabled, use Register Based Invalidate
3008 */
3009 iommu->flush.flush_context = __iommu_flush_context;
3010 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003011 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003012 iommu->name);
3013 } else {
3014 iommu->flush.flush_context = qi_flush_context;
3015 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003016 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003017 }
3018}
3019
Joerg Roedel091d42e2015-06-12 11:56:10 +02003020static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb962015-10-09 18:16:46 -04003021 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003022 struct context_entry **tbl,
3023 int bus, bool ext)
3024{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003025 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003026 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb962015-10-09 18:16:46 -04003027 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003028 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003029 phys_addr_t old_ce_phys;
3030
3031 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb962015-10-09 18:16:46 -04003032 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003033
3034 for (devfn = 0; devfn < 256; devfn++) {
3035 /* First calculate the correct index */
3036 idx = (ext ? devfn * 2 : devfn) % 256;
3037
3038 if (idx == 0) {
3039 /* First save what we may have and clean up */
3040 if (new_ce) {
3041 tbl[tbl_idx] = new_ce;
3042 __iommu_flush_cache(iommu, new_ce,
3043 VTD_PAGE_SIZE);
3044 pos = 1;
3045 }
3046
3047 if (old_ce)
3048 iounmap(old_ce);
3049
3050 ret = 0;
3051 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003052 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003053 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003054 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003055
3056 if (!old_ce_phys) {
3057 if (ext && devfn == 0) {
3058 /* No LCTP, try UCTP */
3059 devfn = 0x7f;
3060 continue;
3061 } else {
3062 goto out;
3063 }
3064 }
3065
3066 ret = -ENOMEM;
Dan Williamsdfddb962015-10-09 18:16:46 -04003067 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3068 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003069 if (!old_ce)
3070 goto out;
3071
3072 new_ce = alloc_pgtable_page(iommu->node);
3073 if (!new_ce)
3074 goto out_unmap;
3075
3076 ret = 0;
3077 }
3078
3079 /* Now copy the context entry */
Dan Williamsdfddb962015-10-09 18:16:46 -04003080 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003081
Joerg Roedelcf484d02015-06-12 12:21:46 +02003082 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003083 continue;
3084
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003085 did = context_domain_id(&ce);
3086 if (did >= 0 && did < cap_ndoms(iommu->cap))
3087 set_bit(did, iommu->domain_ids);
3088
Joerg Roedelcf484d02015-06-12 12:21:46 +02003089 /*
3090 * We need a marker for copied context entries. This
3091 * marker needs to work for the old format as well as
3092 * for extended context entries.
3093 *
3094 * Bit 67 of the context entry is used. In the old
3095 * format this bit is available to software, in the
3096 * extended format it is the PGE bit, but PGE is ignored
3097 * by HW if PASIDs are disabled (and thus still
3098 * available).
3099 *
3100 * So disable PASIDs first and then mark the entry
3101 * copied. This means that we don't copy PASID
3102 * translations from the old kernel, but this is fine as
3103 * faults there are not fatal.
3104 */
3105 context_clear_pasid_enable(&ce);
3106 context_set_copied(&ce);
3107
Joerg Roedel091d42e2015-06-12 11:56:10 +02003108 new_ce[idx] = ce;
3109 }
3110
3111 tbl[tbl_idx + pos] = new_ce;
3112
3113 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3114
3115out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003116 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003117
3118out:
3119 return ret;
3120}
3121
3122static int copy_translation_tables(struct intel_iommu *iommu)
3123{
3124 struct context_entry **ctxt_tbls;
Dan Williamsdfddb962015-10-09 18:16:46 -04003125 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003126 phys_addr_t old_rt_phys;
3127 int ctxt_table_entries;
3128 unsigned long flags;
3129 u64 rtaddr_reg;
3130 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003131 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003132
3133 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3134 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003135 new_ext = !!ecap_ecs(iommu->ecap);
3136
3137 /*
3138 * The RTT bit can only be changed when translation is disabled,
3139 * but disabling translation means to open a window for data
3140 * corruption. So bail out and don't copy anything if we would
3141 * have to change the bit.
3142 */
3143 if (new_ext != ext)
3144 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003145
3146 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3147 if (!old_rt_phys)
3148 return -EINVAL;
3149
Dan Williamsdfddb962015-10-09 18:16:46 -04003150 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003151 if (!old_rt)
3152 return -ENOMEM;
3153
3154 /* This is too big for the stack - allocate it from slab */
3155 ctxt_table_entries = ext ? 512 : 256;
3156 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003157 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003158 if (!ctxt_tbls)
3159 goto out_unmap;
3160
3161 for (bus = 0; bus < 256; bus++) {
3162 ret = copy_context_table(iommu, &old_rt[bus],
3163 ctxt_tbls, bus, ext);
3164 if (ret) {
3165 pr_err("%s: Failed to copy context table for bus %d\n",
3166 iommu->name, bus);
3167 continue;
3168 }
3169 }
3170
3171 spin_lock_irqsave(&iommu->lock, flags);
3172
3173 /* Context tables are copied, now write them to the root_entry table */
3174 for (bus = 0; bus < 256; bus++) {
3175 int idx = ext ? bus * 2 : bus;
3176 u64 val;
3177
3178 if (ctxt_tbls[idx]) {
3179 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3180 iommu->root_entry[bus].lo = val;
3181 }
3182
3183 if (!ext || !ctxt_tbls[idx + 1])
3184 continue;
3185
3186 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3187 iommu->root_entry[bus].hi = val;
3188 }
3189
3190 spin_unlock_irqrestore(&iommu->lock, flags);
3191
3192 kfree(ctxt_tbls);
3193
3194 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3195
3196 ret = 0;
3197
3198out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003199 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003200
3201 return ret;
3202}
3203
Joseph Cihulab7792602011-05-03 00:08:37 -07003204static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003205{
3206 struct dmar_drhd_unit *drhd;
3207 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003208 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003209 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003210 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003211 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003212
3213 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003214 * for each drhd
3215 * allocate root
3216 * initialize and program root entry to not present
3217 * endfor
3218 */
3219 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003220 /*
3221 * lock not needed as this is only incremented in the single
3222 * threaded kernel __init code path all other access are read
3223 * only
3224 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003225 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003226 g_num_of_iommus++;
3227 continue;
3228 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003229 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003230 }
3231
Jiang Liuffebeb42014-11-09 22:48:02 +08003232 /* Preallocate enough resources for IOMMU hot-addition */
3233 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3234 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3235
Weidong Hand9630fe2008-12-08 11:06:32 +08003236 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3237 GFP_KERNEL);
3238 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003239 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003240 ret = -ENOMEM;
3241 goto error;
3242 }
3243
Jiang Liu7c919772014-01-06 14:18:18 +08003244 for_each_active_iommu(iommu, drhd) {
Lu Baolu56283172018-07-14 15:46:54 +08003245 /*
3246 * Find the max pasid size of all IOMMU's in the system.
3247 * We need to ensure the system pasid table is no bigger
3248 * than the smallest supported.
3249 */
Lu Baolu765b6a92018-12-10 09:58:55 +08003250 if (pasid_supported(iommu)) {
Lu Baolu56283172018-07-14 15:46:54 +08003251 u32 temp = 2 << ecap_pss(iommu->ecap);
3252
3253 intel_pasid_max_id = min_t(u32, temp,
3254 intel_pasid_max_id);
3255 }
3256
Weidong Hand9630fe2008-12-08 11:06:32 +08003257 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003258
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003259 intel_iommu_init_qi(iommu);
3260
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003261 ret = iommu_init_domains(iommu);
3262 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003263 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003264
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003265 init_translation_status(iommu);
3266
Joerg Roedel091d42e2015-06-12 11:56:10 +02003267 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3268 iommu_disable_translation(iommu);
3269 clear_translation_pre_enabled(iommu);
3270 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3271 iommu->name);
3272 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003273
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003274 /*
3275 * TBD:
3276 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003277 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003278 */
3279 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003280 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003281 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003282
Joerg Roedel091d42e2015-06-12 11:56:10 +02003283 if (translation_pre_enabled(iommu)) {
3284 pr_info("Translation already enabled - trying to copy translation structures\n");
3285
3286 ret = copy_translation_tables(iommu);
3287 if (ret) {
3288 /*
3289 * We found the IOMMU with translation
3290 * enabled - but failed to copy over the
3291 * old root-entry table. Try to proceed
3292 * by disabling translation now and
3293 * allocating a clean root-entry table.
3294 * This might cause DMAR faults, but
3295 * probably the dump will still succeed.
3296 */
3297 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3298 iommu->name);
3299 iommu_disable_translation(iommu);
3300 clear_translation_pre_enabled(iommu);
3301 } else {
3302 pr_info("Copied translation tables from previous kernel for %s\n",
3303 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003304 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003305 }
3306 }
3307
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003308 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003309 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003310#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003311 if (pasid_supported(iommu))
Lu Baolud9737952018-07-14 15:47:02 +08003312 intel_svm_init(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00003313#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003314 }
3315
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003316 /*
3317 * Now that qi is enabled on all iommus, set the root entry and flush
3318 * caches. This is required on some Intel X58 chipsets, otherwise the
3319 * flush_context function will loop forever and the boot hangs.
3320 */
3321 for_each_active_iommu(iommu, drhd) {
3322 iommu_flush_write_buffer(iommu);
3323 iommu_set_root_entry(iommu);
3324 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3325 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3326 }
3327
David Woodhouse19943b02009-08-04 16:19:20 +01003328 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003329 iommu_identity_mapping |= IDENTMAP_ALL;
3330
Suresh Siddhad3f13812011-08-23 17:05:25 -07003331#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003332 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003333#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003334
Ashok Raj21e722c2017-01-30 09:39:53 -08003335 check_tylersburg_isoch();
3336
Joerg Roedel86080cc2015-06-12 12:27:16 +02003337 if (iommu_identity_mapping) {
3338 ret = si_domain_init(hw_pass_through);
3339 if (ret)
3340 goto free_iommu;
3341 }
3342
David Woodhousee0fc7e02009-09-30 09:12:17 -07003343
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003344 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003345 * If we copied translations from a previous kernel in the kdump
3346 * case, we can not assign the devices to domains now, as that
3347 * would eliminate the old mappings. So skip this part and defer
3348 * the assignment to device driver initialization time.
3349 */
3350 if (copied_tables)
3351 goto domains_done;
3352
3353 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003354 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003355 * identity mappings for rmrr, gfx, and isa and may fall back to static
3356 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003357 */
David Woodhouse19943b02009-08-04 16:19:20 +01003358 if (iommu_identity_mapping) {
3359 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3360 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003361 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003362 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003363 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003364 }
David Woodhouse19943b02009-08-04 16:19:20 +01003365 /*
3366 * For each rmrr
3367 * for each dev attached to rmrr
3368 * do
3369 * locate drhd for dev, alloc domain for dev
3370 * allocate free domain
3371 * allocate page table entries for rmrr
3372 * if context not allocated for bus
3373 * allocate and init context
3374 * set present in root table for this bus
3375 * init context with domain, translation etc
3376 * endfor
3377 * endfor
3378 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003379 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003380 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003381 /* some BIOS lists non-exist devices in DMAR table. */
3382 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003383 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003384 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003385 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003386 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003387 }
3388 }
3389
3390 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003391
Joerg Roedela87f4912015-06-12 12:32:54 +02003392domains_done:
3393
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003394 /*
3395 * for each drhd
3396 * enable fault log
3397 * global invalidate context cache
3398 * global invalidate iotlb
3399 * enable translation
3400 */
Jiang Liu7c919772014-01-06 14:18:18 +08003401 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003402 if (drhd->ignored) {
3403 /*
3404 * we always have to disable PMRs or DMA may fail on
3405 * this device
3406 */
3407 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003408 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003409 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003410 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003411
3412 iommu_flush_write_buffer(iommu);
3413
David Woodhousea222a7f2015-10-07 23:35:18 +01003414#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003415 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01003416 ret = intel_svm_enable_prq(iommu);
3417 if (ret)
3418 goto free_iommu;
3419 }
3420#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003421 ret = dmar_set_interrupt(iommu);
3422 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003423 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003424
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003425 if (!translation_pre_enabled(iommu))
3426 iommu_enable_translation(iommu);
3427
David Woodhouseb94996c2009-09-19 15:28:12 -07003428 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003429 }
3430
3431 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003432
3433free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003434 for_each_active_iommu(iommu, drhd) {
3435 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003436 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003437 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003438
Weidong Hand9630fe2008-12-08 11:06:32 +08003439 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003440
Jiang Liu989d51f2014-02-19 14:07:21 +08003441error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003442 return ret;
3443}
3444
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003445/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003446static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003447 struct dmar_domain *domain,
3448 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003449{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003450 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003451
David Woodhouse875764d2009-06-28 21:20:51 +01003452 /* Restrict dma_mask to the width that the iommu can handle */
3453 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003454 /* Ensure we reserve the whole size-aligned region */
3455 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003456
3457 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003458 /*
3459 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003460 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003461 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003462 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003463 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003464 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003465 if (iova_pfn)
3466 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003467 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003468 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3469 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003470 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003471 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003472 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003473 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003474 }
3475
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003476 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003477}
3478
Lu Baolu9ddbfb42018-07-14 15:46:57 +08003479struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003480{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003481 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003482 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003483 struct device *i_dev;
3484 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003485
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003486 domain = find_domain(dev);
3487 if (domain)
3488 goto out;
3489
3490 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3491 if (!domain)
3492 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003493
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003494 /* We have a new domain - setup possible RMRRs for the device */
3495 rcu_read_lock();
3496 for_each_rmrr_units(rmrr) {
3497 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3498 i, i_dev) {
3499 if (i_dev != dev)
3500 continue;
3501
3502 ret = domain_prepare_identity_map(dev, domain,
3503 rmrr->base_address,
3504 rmrr->end_address);
3505 if (ret)
3506 dev_err(dev, "Mapping reserved region failed\n");
3507 }
3508 }
3509 rcu_read_unlock();
3510
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003511 tmp = set_domain_for_dev(dev, domain);
3512 if (!tmp || domain != tmp) {
3513 domain_exit(domain);
3514 domain = tmp;
3515 }
3516
3517out:
3518
3519 if (!domain)
3520 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3521
3522
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003523 return domain;
3524}
3525
David Woodhouseecb509e2014-03-09 16:29:55 -07003526/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003527static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003528{
3529 int found;
3530
David Woodhouse3d891942014-03-06 15:59:26 +00003531 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003532 return 1;
3533
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003534 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003535 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003536
David Woodhouse9b226622014-03-09 14:03:28 -07003537 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003538 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003539 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003540 return 1;
3541 else {
3542 /*
3543 * 32 bit DMA is removed from si_domain and fall back
3544 * to non-identity mapping.
3545 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003546 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003547 pr_info("32bit %s uses non-identity mapping\n",
3548 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003549 return 0;
3550 }
3551 } else {
3552 /*
3553 * In case of a detached 64 bit DMA device from vm, the device
3554 * is put into si_domain for identity mapping.
3555 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003556 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003557 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003558 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003559 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003560 pr_info("64bit %s uses identity mapping\n",
3561 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003562 return 1;
3563 }
3564 }
3565 }
3566
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003567 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003568}
3569
David Woodhouse5040a912014-03-09 16:14:00 -07003570static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003571 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003572{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003573 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003574 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003575 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003576 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003577 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003578 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003579 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003580
3581 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003582
David Woodhouse5040a912014-03-09 16:14:00 -07003583 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003584 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003585
David Woodhouse5040a912014-03-09 16:14:00 -07003586 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003587 if (!domain)
3588 return 0;
3589
Weidong Han8c11e792008-12-08 15:29:22 +08003590 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003591 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003592
Omer Peleg2aac6302016-04-20 11:33:57 +03003593 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3594 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003595 goto error;
3596
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003597 /*
3598 * Check if DMAR supports zero-length reads on write only
3599 * mappings..
3600 */
3601 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003602 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003603 prot |= DMA_PTE_READ;
3604 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3605 prot |= DMA_PTE_WRITE;
3606 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003607 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003608 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003609 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003610 * is not a big problem
3611 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003612 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003613 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003614 if (ret)
3615 goto error;
3616
Omer Peleg2aac6302016-04-20 11:33:57 +03003617 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003618 start_paddr += paddr & ~PAGE_MASK;
3619 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003620
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003621error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003622 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003623 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003624 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003625 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003626 return 0;
3627}
3628
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003629static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3630 unsigned long offset, size_t size,
3631 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003632 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003633{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003634 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003635 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003636}
3637
Omer Peleg769530e2016-04-20 11:33:25 +03003638static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003639{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003640 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003641 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003642 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003643 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003644 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003645 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003646
David Woodhouse73676832009-07-04 14:08:36 +01003647 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003648 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003649
David Woodhouse1525a292014-03-06 16:19:30 +00003650 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003651 BUG_ON(!domain);
3652
Weidong Han8c11e792008-12-08 15:29:22 +08003653 iommu = domain_get_iommu(domain);
3654
Omer Peleg2aac6302016-04-20 11:33:57 +03003655 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003656
Omer Peleg769530e2016-04-20 11:33:25 +03003657 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003658 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003659 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003660
David Woodhoused794dc92009-06-28 00:27:49 +01003661 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003662 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003663
David Woodhouseea8ea462014-03-05 17:09:32 +00003664 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003665
mark gross5e0d2a62008-03-04 15:22:08 -08003666 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003667 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003668 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003669 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003670 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003671 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003672 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003673 queue_iova(&domain->iovad, iova_pfn, nrpages,
3674 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003675 /*
3676 * queue up the release of the unmap to save the 1/6th of the
3677 * cpu used up by the iotlb flush operation...
3678 */
mark gross5e0d2a62008-03-04 15:22:08 -08003679 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003680}
3681
Jiang Liud41a4ad2014-07-11 14:19:34 +08003682static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3683 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003684 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003685{
Omer Peleg769530e2016-04-20 11:33:25 +03003686 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003687}
3688
David Woodhouse5040a912014-03-09 16:14:00 -07003689static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003690 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003691 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003692{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003693 struct page *page = NULL;
3694 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003695
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003696 size = PAGE_ALIGN(size);
3697 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003698
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003699 if (!iommu_no_mapping(dev))
3700 flags &= ~(GFP_DMA | GFP_DMA32);
3701 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3702 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
3703 flags |= GFP_DMA;
3704 else
3705 flags |= GFP_DMA32;
3706 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003707
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003708 if (gfpflags_allow_blocking(flags)) {
3709 unsigned int count = size >> PAGE_SHIFT;
3710
Marek Szyprowskid834c5a2018-08-17 15:49:00 -07003711 page = dma_alloc_from_contiguous(dev, count, order,
3712 flags & __GFP_NOWARN);
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003713 if (page && iommu_no_mapping(dev) &&
3714 page_to_phys(page) + size > dev->coherent_dma_mask) {
3715 dma_release_from_contiguous(dev, page, count);
3716 page = NULL;
3717 }
3718 }
3719
3720 if (!page)
3721 page = alloc_pages(flags, order);
3722 if (!page)
3723 return NULL;
3724 memset(page_address(page), 0, size);
3725
3726 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3727 DMA_BIDIRECTIONAL,
3728 dev->coherent_dma_mask);
3729 if (*dma_handle)
3730 return page_address(page);
3731 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3732 __free_pages(page, order);
3733
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003734 return NULL;
3735}
3736
David Woodhouse5040a912014-03-09 16:14:00 -07003737static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003738 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003739{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003740 int order;
3741 struct page *page = virt_to_page(vaddr);
3742
3743 size = PAGE_ALIGN(size);
3744 order = get_order(size);
3745
3746 intel_unmap(dev, dma_handle, size);
3747 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3748 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003749}
3750
David Woodhouse5040a912014-03-09 16:14:00 -07003751static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003752 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003753 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003754{
Omer Peleg769530e2016-04-20 11:33:25 +03003755 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3756 unsigned long nrpages = 0;
3757 struct scatterlist *sg;
3758 int i;
3759
3760 for_each_sg(sglist, sg, nelems, i) {
3761 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3762 }
3763
3764 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003765}
3766
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003767static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003768 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003769{
3770 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003771 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003772
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003773 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003774 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003775 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003776 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003777 }
3778 return nelems;
3779}
3780
David Woodhouse5040a912014-03-09 16:14:00 -07003781static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003782 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003783{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003784 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003785 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003786 size_t size = 0;
3787 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003788 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003789 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003790 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003791 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003792 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003793
3794 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003795 if (iommu_no_mapping(dev))
3796 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003797
David Woodhouse5040a912014-03-09 16:14:00 -07003798 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003799 if (!domain)
3800 return 0;
3801
Weidong Han8c11e792008-12-08 15:29:22 +08003802 iommu = domain_get_iommu(domain);
3803
David Woodhouseb536d242009-06-28 14:49:31 +01003804 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003805 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003806
Omer Peleg2aac6302016-04-20 11:33:57 +03003807 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003808 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003809 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003810 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003811 return 0;
3812 }
3813
3814 /*
3815 * Check if DMAR supports zero-length reads on write only
3816 * mappings..
3817 */
3818 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003819 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003820 prot |= DMA_PTE_READ;
3821 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3822 prot |= DMA_PTE_WRITE;
3823
Omer Peleg2aac6302016-04-20 11:33:57 +03003824 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003825
Fenghua Yuf5329592009-08-04 15:09:37 -07003826 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003827 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003828 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003829 start_vpfn + size - 1,
3830 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003831 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003832 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003833 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003834
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003835 return nelems;
3836}
3837
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003838static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3839{
3840 return !dma_addr;
3841}
3842
Christoph Hellwig02b4da52018-09-17 19:10:31 +02003843static const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003844 .alloc = intel_alloc_coherent,
3845 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003846 .map_sg = intel_map_sg,
3847 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003848 .map_page = intel_map_page,
3849 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003850 .mapping_error = intel_mapping_error,
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003851 .dma_supported = dma_direct_supported,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003852};
3853
3854static inline int iommu_domain_cache_init(void)
3855{
3856 int ret = 0;
3857
3858 iommu_domain_cache = kmem_cache_create("iommu_domain",
3859 sizeof(struct dmar_domain),
3860 0,
3861 SLAB_HWCACHE_ALIGN,
3862
3863 NULL);
3864 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003865 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003866 ret = -ENOMEM;
3867 }
3868
3869 return ret;
3870}
3871
3872static inline int iommu_devinfo_cache_init(void)
3873{
3874 int ret = 0;
3875
3876 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3877 sizeof(struct device_domain_info),
3878 0,
3879 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003880 NULL);
3881 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003882 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003883 ret = -ENOMEM;
3884 }
3885
3886 return ret;
3887}
3888
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003889static int __init iommu_init_mempool(void)
3890{
3891 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003892 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003893 if (ret)
3894 return ret;
3895
3896 ret = iommu_domain_cache_init();
3897 if (ret)
3898 goto domain_error;
3899
3900 ret = iommu_devinfo_cache_init();
3901 if (!ret)
3902 return ret;
3903
3904 kmem_cache_destroy(iommu_domain_cache);
3905domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003906 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003907
3908 return -ENOMEM;
3909}
3910
3911static void __init iommu_exit_mempool(void)
3912{
3913 kmem_cache_destroy(iommu_devinfo_cache);
3914 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003915 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003916}
3917
Dan Williams556ab452010-07-23 15:47:56 -07003918static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3919{
3920 struct dmar_drhd_unit *drhd;
3921 u32 vtbar;
3922 int rc;
3923
3924 /* We know that this device on this chipset has its own IOMMU.
3925 * If we find it under a different IOMMU, then the BIOS is lying
3926 * to us. Hope that the IOMMU for this device is actually
3927 * disabled, and it needs no translation...
3928 */
3929 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3930 if (rc) {
3931 /* "can't" happen */
3932 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3933 return;
3934 }
3935 vtbar &= 0xffff0000;
3936
3937 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3938 drhd = dmar_find_matched_drhd_unit(pdev);
3939 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3940 TAINT_FIRMWARE_WORKAROUND,
3941 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3942 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3943}
3944DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3945
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003946static void __init init_no_remapping_devices(void)
3947{
3948 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003949 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003950 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003951
3952 for_each_drhd_unit(drhd) {
3953 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003954 for_each_active_dev_scope(drhd->devices,
3955 drhd->devices_cnt, i, dev)
3956 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003957 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003958 if (i == drhd->devices_cnt)
3959 drhd->ignored = 1;
3960 }
3961 }
3962
Jiang Liu7c919772014-01-06 14:18:18 +08003963 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003964 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003965 continue;
3966
Jiang Liub683b232014-02-19 14:07:32 +08003967 for_each_active_dev_scope(drhd->devices,
3968 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003969 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003970 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003971 if (i < drhd->devices_cnt)
3972 continue;
3973
David Woodhousec0771df2011-10-14 20:59:46 +01003974 /* This IOMMU has *only* gfx devices. Either bypass it or
3975 set the gfx_mapped flag, as appropriate */
3976 if (dmar_map_gfx) {
3977 intel_iommu_gfx_mapped = 1;
3978 } else {
3979 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08003980 for_each_active_dev_scope(drhd->devices,
3981 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003982 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003983 }
3984 }
3985}
3986
Fenghua Yuf59c7b62009-03-27 14:22:42 -07003987#ifdef CONFIG_SUSPEND
3988static int init_iommu_hw(void)
3989{
3990 struct dmar_drhd_unit *drhd;
3991 struct intel_iommu *iommu = NULL;
3992
3993 for_each_active_iommu(iommu, drhd)
3994 if (iommu->qi)
3995 dmar_reenable_qi(iommu);
3996
Joseph Cihulab7792602011-05-03 00:08:37 -07003997 for_each_iommu(iommu, drhd) {
3998 if (drhd->ignored) {
3999 /*
4000 * we always have to disable PMRs or DMA may fail on
4001 * this device
4002 */
4003 if (force_on)
4004 iommu_disable_protect_mem_regions(iommu);
4005 continue;
4006 }
4007
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004008 iommu_flush_write_buffer(iommu);
4009
4010 iommu_set_root_entry(iommu);
4011
4012 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004013 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004014 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4015 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004016 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004017 }
4018
4019 return 0;
4020}
4021
4022static void iommu_flush_all(void)
4023{
4024 struct dmar_drhd_unit *drhd;
4025 struct intel_iommu *iommu;
4026
4027 for_each_active_iommu(iommu, drhd) {
4028 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004029 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004030 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004031 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004032 }
4033}
4034
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004035static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004036{
4037 struct dmar_drhd_unit *drhd;
4038 struct intel_iommu *iommu = NULL;
4039 unsigned long flag;
4040
4041 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004042 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004043 GFP_ATOMIC);
4044 if (!iommu->iommu_state)
4045 goto nomem;
4046 }
4047
4048 iommu_flush_all();
4049
4050 for_each_active_iommu(iommu, drhd) {
4051 iommu_disable_translation(iommu);
4052
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004053 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004054
4055 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4056 readl(iommu->reg + DMAR_FECTL_REG);
4057 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4058 readl(iommu->reg + DMAR_FEDATA_REG);
4059 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4060 readl(iommu->reg + DMAR_FEADDR_REG);
4061 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4062 readl(iommu->reg + DMAR_FEUADDR_REG);
4063
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004064 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004065 }
4066 return 0;
4067
4068nomem:
4069 for_each_active_iommu(iommu, drhd)
4070 kfree(iommu->iommu_state);
4071
4072 return -ENOMEM;
4073}
4074
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004075static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004076{
4077 struct dmar_drhd_unit *drhd;
4078 struct intel_iommu *iommu = NULL;
4079 unsigned long flag;
4080
4081 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004082 if (force_on)
4083 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4084 else
4085 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004086 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004087 }
4088
4089 for_each_active_iommu(iommu, drhd) {
4090
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004091 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004092
4093 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4094 iommu->reg + DMAR_FECTL_REG);
4095 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4096 iommu->reg + DMAR_FEDATA_REG);
4097 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4098 iommu->reg + DMAR_FEADDR_REG);
4099 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4100 iommu->reg + DMAR_FEUADDR_REG);
4101
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004102 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004103 }
4104
4105 for_each_active_iommu(iommu, drhd)
4106 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004107}
4108
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004109static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004110 .resume = iommu_resume,
4111 .suspend = iommu_suspend,
4112};
4113
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004114static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004115{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004116 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004117}
4118
4119#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004120static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004121#endif /* CONFIG_PM */
4122
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004123
Jiang Liuc2a0b532014-11-09 22:47:56 +08004124int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004125{
4126 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004127 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004128 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004129 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004130
4131 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4132 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004133 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004134
4135 rmrru->hdr = header;
4136 rmrr = (struct acpi_dmar_reserved_memory *)header;
4137 rmrru->base_address = rmrr->base_address;
4138 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004139
4140 length = rmrr->end_address - rmrr->base_address + 1;
4141 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4142 IOMMU_RESV_DIRECT);
4143 if (!rmrru->resv)
4144 goto free_rmrru;
4145
Jiang Liu2e455282014-02-19 14:07:36 +08004146 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4147 ((void *)rmrr) + rmrr->header.length,
4148 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004149 if (rmrru->devices_cnt && rmrru->devices == NULL)
4150 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004151
Jiang Liu2e455282014-02-19 14:07:36 +08004152 list_add(&rmrru->list, &dmar_rmrr_units);
4153
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004154 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004155free_all:
4156 kfree(rmrru->resv);
4157free_rmrru:
4158 kfree(rmrru);
4159out:
4160 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004161}
4162
Jiang Liu6b197242014-11-09 22:47:58 +08004163static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4164{
4165 struct dmar_atsr_unit *atsru;
4166 struct acpi_dmar_atsr *tmp;
4167
4168 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4169 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4170 if (atsr->segment != tmp->segment)
4171 continue;
4172 if (atsr->header.length != tmp->header.length)
4173 continue;
4174 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4175 return atsru;
4176 }
4177
4178 return NULL;
4179}
4180
4181int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004182{
4183 struct acpi_dmar_atsr *atsr;
4184 struct dmar_atsr_unit *atsru;
4185
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004186 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004187 return 0;
4188
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004189 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004190 atsru = dmar_find_atsr(atsr);
4191 if (atsru)
4192 return 0;
4193
4194 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004195 if (!atsru)
4196 return -ENOMEM;
4197
Jiang Liu6b197242014-11-09 22:47:58 +08004198 /*
4199 * If memory is allocated from slab by ACPI _DSM method, we need to
4200 * copy the memory content because the memory buffer will be freed
4201 * on return.
4202 */
4203 atsru->hdr = (void *)(atsru + 1);
4204 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004205 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004206 if (!atsru->include_all) {
4207 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4208 (void *)atsr + atsr->header.length,
4209 &atsru->devices_cnt);
4210 if (atsru->devices_cnt && atsru->devices == NULL) {
4211 kfree(atsru);
4212 return -ENOMEM;
4213 }
4214 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004215
Jiang Liu0e242612014-02-19 14:07:34 +08004216 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004217
4218 return 0;
4219}
4220
Jiang Liu9bdc5312014-01-06 14:18:27 +08004221static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4222{
4223 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4224 kfree(atsru);
4225}
4226
Jiang Liu6b197242014-11-09 22:47:58 +08004227int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4228{
4229 struct acpi_dmar_atsr *atsr;
4230 struct dmar_atsr_unit *atsru;
4231
4232 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4233 atsru = dmar_find_atsr(atsr);
4234 if (atsru) {
4235 list_del_rcu(&atsru->list);
4236 synchronize_rcu();
4237 intel_iommu_free_atsr(atsru);
4238 }
4239
4240 return 0;
4241}
4242
4243int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4244{
4245 int i;
4246 struct device *dev;
4247 struct acpi_dmar_atsr *atsr;
4248 struct dmar_atsr_unit *atsru;
4249
4250 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4251 atsru = dmar_find_atsr(atsr);
4252 if (!atsru)
4253 return 0;
4254
Linus Torvalds194dc872016-07-27 20:03:31 -07004255 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004256 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4257 i, dev)
4258 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004259 }
Jiang Liu6b197242014-11-09 22:47:58 +08004260
4261 return 0;
4262}
4263
Jiang Liuffebeb42014-11-09 22:48:02 +08004264static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4265{
4266 int sp, ret = 0;
4267 struct intel_iommu *iommu = dmaru->iommu;
4268
4269 if (g_iommus[iommu->seq_id])
4270 return 0;
4271
4272 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004273 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004274 iommu->name);
4275 return -ENXIO;
4276 }
4277 if (!ecap_sc_support(iommu->ecap) &&
4278 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004279 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004280 iommu->name);
4281 return -ENXIO;
4282 }
4283 sp = domain_update_iommu_superpage(iommu) - 1;
4284 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004285 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004286 iommu->name);
4287 return -ENXIO;
4288 }
4289
4290 /*
4291 * Disable translation if already enabled prior to OS handover.
4292 */
4293 if (iommu->gcmd & DMA_GCMD_TE)
4294 iommu_disable_translation(iommu);
4295
4296 g_iommus[iommu->seq_id] = iommu;
4297 ret = iommu_init_domains(iommu);
4298 if (ret == 0)
4299 ret = iommu_alloc_root_entry(iommu);
4300 if (ret)
4301 goto out;
4302
David Woodhouse8a94ade2015-03-24 14:54:56 +00004303#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004304 if (pasid_supported(iommu))
Lu Baolud9737952018-07-14 15:47:02 +08004305 intel_svm_init(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00004306#endif
4307
Jiang Liuffebeb42014-11-09 22:48:02 +08004308 if (dmaru->ignored) {
4309 /*
4310 * we always have to disable PMRs or DMA may fail on this device
4311 */
4312 if (force_on)
4313 iommu_disable_protect_mem_regions(iommu);
4314 return 0;
4315 }
4316
4317 intel_iommu_init_qi(iommu);
4318 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004319
4320#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004321 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01004322 ret = intel_svm_enable_prq(iommu);
4323 if (ret)
4324 goto disable_iommu;
4325 }
4326#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004327 ret = dmar_set_interrupt(iommu);
4328 if (ret)
4329 goto disable_iommu;
4330
4331 iommu_set_root_entry(iommu);
4332 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4333 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4334 iommu_enable_translation(iommu);
4335
Jiang Liuffebeb42014-11-09 22:48:02 +08004336 iommu_disable_protect_mem_regions(iommu);
4337 return 0;
4338
4339disable_iommu:
4340 disable_dmar_iommu(iommu);
4341out:
4342 free_dmar_iommu(iommu);
4343 return ret;
4344}
4345
Jiang Liu6b197242014-11-09 22:47:58 +08004346int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4347{
Jiang Liuffebeb42014-11-09 22:48:02 +08004348 int ret = 0;
4349 struct intel_iommu *iommu = dmaru->iommu;
4350
4351 if (!intel_iommu_enabled)
4352 return 0;
4353 if (iommu == NULL)
4354 return -EINVAL;
4355
4356 if (insert) {
4357 ret = intel_iommu_add(dmaru);
4358 } else {
4359 disable_dmar_iommu(iommu);
4360 free_dmar_iommu(iommu);
4361 }
4362
4363 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004364}
4365
Jiang Liu9bdc5312014-01-06 14:18:27 +08004366static void intel_iommu_free_dmars(void)
4367{
4368 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4369 struct dmar_atsr_unit *atsru, *atsr_n;
4370
4371 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4372 list_del(&rmrru->list);
4373 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004374 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004375 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004376 }
4377
Jiang Liu9bdc5312014-01-06 14:18:27 +08004378 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4379 list_del(&atsru->list);
4380 intel_iommu_free_atsr(atsru);
4381 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004382}
4383
4384int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4385{
Jiang Liub683b232014-02-19 14:07:32 +08004386 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004387 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004388 struct pci_dev *bridge = NULL;
4389 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004390 struct acpi_dmar_atsr *atsr;
4391 struct dmar_atsr_unit *atsru;
4392
4393 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004394 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004395 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004396 /* If it's an integrated device, allow ATS */
4397 if (!bridge)
4398 return 1;
4399 /* Connected via non-PCIe: no ATS */
4400 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004401 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004402 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004403 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004404 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004405 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004406 }
4407
Jiang Liu0e242612014-02-19 14:07:34 +08004408 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004409 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4410 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4411 if (atsr->segment != pci_domain_nr(dev->bus))
4412 continue;
4413
Jiang Liub683b232014-02-19 14:07:32 +08004414 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004415 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004416 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004417
4418 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004419 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004420 }
Jiang Liub683b232014-02-19 14:07:32 +08004421 ret = 0;
4422out:
Jiang Liu0e242612014-02-19 14:07:34 +08004423 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004424
Jiang Liub683b232014-02-19 14:07:32 +08004425 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004426}
4427
Jiang Liu59ce0512014-02-19 14:07:35 +08004428int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4429{
4430 int ret = 0;
4431 struct dmar_rmrr_unit *rmrru;
4432 struct dmar_atsr_unit *atsru;
4433 struct acpi_dmar_atsr *atsr;
4434 struct acpi_dmar_reserved_memory *rmrr;
4435
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004436 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004437 return 0;
4438
4439 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4440 rmrr = container_of(rmrru->hdr,
4441 struct acpi_dmar_reserved_memory, header);
4442 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4443 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4444 ((void *)rmrr) + rmrr->header.length,
4445 rmrr->segment, rmrru->devices,
4446 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004447 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004448 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004449 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004450 dmar_remove_dev_scope(info, rmrr->segment,
4451 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004452 }
4453 }
4454
4455 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4456 if (atsru->include_all)
4457 continue;
4458
4459 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4460 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4461 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4462 (void *)atsr + atsr->header.length,
4463 atsr->segment, atsru->devices,
4464 atsru->devices_cnt);
4465 if (ret > 0)
4466 break;
4467 else if(ret < 0)
4468 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004469 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004470 if (dmar_remove_dev_scope(info, atsr->segment,
4471 atsru->devices, atsru->devices_cnt))
4472 break;
4473 }
4474 }
4475
4476 return 0;
4477}
4478
Fenghua Yu99dcade2009-11-11 07:23:06 -08004479/*
4480 * Here we only respond to action of unbound device from driver.
4481 *
4482 * Added device is not attached to its DMAR domain here yet. That will happen
4483 * when mapping the device to iova.
4484 */
4485static int device_notifier(struct notifier_block *nb,
4486 unsigned long action, void *data)
4487{
4488 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004489 struct dmar_domain *domain;
4490
David Woodhouse3d891942014-03-06 15:59:26 +00004491 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004492 return 0;
4493
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004494 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004495 return 0;
4496
David Woodhouse1525a292014-03-06 16:19:30 +00004497 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004498 if (!domain)
4499 return 0;
4500
Joerg Roedele6de0f82015-07-22 16:30:36 +02004501 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004502 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004503 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004504
Fenghua Yu99dcade2009-11-11 07:23:06 -08004505 return 0;
4506}
4507
4508static struct notifier_block device_nb = {
4509 .notifier_call = device_notifier,
4510};
4511
Jiang Liu75f05562014-02-19 14:07:37 +08004512static int intel_iommu_memory_notifier(struct notifier_block *nb,
4513 unsigned long val, void *v)
4514{
4515 struct memory_notify *mhp = v;
4516 unsigned long long start, end;
4517 unsigned long start_vpfn, last_vpfn;
4518
4519 switch (val) {
4520 case MEM_GOING_ONLINE:
4521 start = mhp->start_pfn << PAGE_SHIFT;
4522 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4523 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004524 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004525 start, end);
4526 return NOTIFY_BAD;
4527 }
4528 break;
4529
4530 case MEM_OFFLINE:
4531 case MEM_CANCEL_ONLINE:
4532 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4533 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4534 while (start_vpfn <= last_vpfn) {
4535 struct iova *iova;
4536 struct dmar_drhd_unit *drhd;
4537 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004538 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004539
4540 iova = find_iova(&si_domain->iovad, start_vpfn);
4541 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004542 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004543 start_vpfn);
4544 break;
4545 }
4546
4547 iova = split_and_remove_iova(&si_domain->iovad, iova,
4548 start_vpfn, last_vpfn);
4549 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004550 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004551 start_vpfn, last_vpfn);
4552 return NOTIFY_BAD;
4553 }
4554
David Woodhouseea8ea462014-03-05 17:09:32 +00004555 freelist = domain_unmap(si_domain, iova->pfn_lo,
4556 iova->pfn_hi);
4557
Jiang Liu75f05562014-02-19 14:07:37 +08004558 rcu_read_lock();
4559 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004560 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004561 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004562 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004563 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004564 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004565
4566 start_vpfn = iova->pfn_hi + 1;
4567 free_iova_mem(iova);
4568 }
4569 break;
4570 }
4571
4572 return NOTIFY_OK;
4573}
4574
4575static struct notifier_block intel_iommu_memory_nb = {
4576 .notifier_call = intel_iommu_memory_notifier,
4577 .priority = 0
4578};
4579
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004580static void free_all_cpu_cached_iovas(unsigned int cpu)
4581{
4582 int i;
4583
4584 for (i = 0; i < g_num_of_iommus; i++) {
4585 struct intel_iommu *iommu = g_iommus[i];
4586 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004587 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004588
4589 if (!iommu)
4590 continue;
4591
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004592 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004593 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004594
4595 if (!domain)
4596 continue;
4597 free_cpu_cached_iovas(cpu, &domain->iovad);
4598 }
4599 }
4600}
4601
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004602static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004603{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004604 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004605 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004606}
4607
Joerg Roedel161b28a2017-03-28 17:04:52 +02004608static void intel_disable_iommus(void)
4609{
4610 struct intel_iommu *iommu = NULL;
4611 struct dmar_drhd_unit *drhd;
4612
4613 for_each_iommu(iommu, drhd)
4614 iommu_disable_translation(iommu);
4615}
4616
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004617static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4618{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004619 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4620
4621 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004622}
4623
Alex Williamsona5459cf2014-06-12 16:12:31 -06004624static ssize_t intel_iommu_show_version(struct device *dev,
4625 struct device_attribute *attr,
4626 char *buf)
4627{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004628 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004629 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4630 return sprintf(buf, "%d:%d\n",
4631 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4632}
4633static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4634
4635static ssize_t intel_iommu_show_address(struct device *dev,
4636 struct device_attribute *attr,
4637 char *buf)
4638{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004639 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004640 return sprintf(buf, "%llx\n", iommu->reg_phys);
4641}
4642static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4643
4644static ssize_t intel_iommu_show_cap(struct device *dev,
4645 struct device_attribute *attr,
4646 char *buf)
4647{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004648 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004649 return sprintf(buf, "%llx\n", iommu->cap);
4650}
4651static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4652
4653static ssize_t intel_iommu_show_ecap(struct device *dev,
4654 struct device_attribute *attr,
4655 char *buf)
4656{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004657 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004658 return sprintf(buf, "%llx\n", iommu->ecap);
4659}
4660static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4661
Alex Williamson2238c082015-07-14 15:24:53 -06004662static ssize_t intel_iommu_show_ndoms(struct device *dev,
4663 struct device_attribute *attr,
4664 char *buf)
4665{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004666 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004667 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4668}
4669static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4670
4671static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4672 struct device_attribute *attr,
4673 char *buf)
4674{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004675 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004676 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4677 cap_ndoms(iommu->cap)));
4678}
4679static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4680
Alex Williamsona5459cf2014-06-12 16:12:31 -06004681static struct attribute *intel_iommu_attrs[] = {
4682 &dev_attr_version.attr,
4683 &dev_attr_address.attr,
4684 &dev_attr_cap.attr,
4685 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004686 &dev_attr_domains_supported.attr,
4687 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004688 NULL,
4689};
4690
4691static struct attribute_group intel_iommu_group = {
4692 .name = "intel-iommu",
4693 .attrs = intel_iommu_attrs,
4694};
4695
4696const struct attribute_group *intel_iommu_groups[] = {
4697 &intel_iommu_group,
4698 NULL,
4699};
4700
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004701int __init intel_iommu_init(void)
4702{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004703 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004704 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004705 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004706
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004707 /* VT-d is required for a TXT/tboot launch, so enforce that */
4708 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004709
Jiang Liu3a5670e2014-02-19 14:07:33 +08004710 if (iommu_init_mempool()) {
4711 if (force_on)
4712 panic("tboot: Failed to initialize iommu memory\n");
4713 return -ENOMEM;
4714 }
4715
4716 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004717 if (dmar_table_init()) {
4718 if (force_on)
4719 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004720 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004721 }
4722
Suresh Siddhac2c72862011-08-23 17:05:19 -07004723 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004724 if (force_on)
4725 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004726 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004727 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004728
Joerg Roedelec154bf2017-10-06 15:00:53 +02004729 up_write(&dmar_global_lock);
4730
4731 /*
4732 * The bus notifier takes the dmar_global_lock, so lockdep will
4733 * complain later when we register it under the lock.
4734 */
4735 dmar_register_bus_notifier();
4736
4737 down_write(&dmar_global_lock);
4738
Joerg Roedel161b28a2017-03-28 17:04:52 +02004739 if (no_iommu || dmar_disabled) {
4740 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004741 * We exit the function here to ensure IOMMU's remapping and
4742 * mempool aren't setup, which means that the IOMMU's PMRs
4743 * won't be disabled via the call to init_dmars(). So disable
4744 * it explicitly here. The PMRs were setup by tboot prior to
4745 * calling SENTER, but the kernel is expected to reset/tear
4746 * down the PMRs.
4747 */
4748 if (intel_iommu_tboot_noforce) {
4749 for_each_iommu(iommu, drhd)
4750 iommu_disable_protect_mem_regions(iommu);
4751 }
4752
4753 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004754 * Make sure the IOMMUs are switched off, even when we
4755 * boot into a kexec kernel and the previous kernel left
4756 * them enabled
4757 */
4758 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004759 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004760 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004761
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004762 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004763 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004764
4765 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004766 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004767
Joseph Cihula51a63e62011-03-21 11:04:24 -07004768 if (dmar_init_reserved_ranges()) {
4769 if (force_on)
4770 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004771 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004772 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004773
4774 init_no_remapping_devices();
4775
Joseph Cihulab7792602011-05-03 00:08:37 -07004776 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004777 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004778 if (force_on)
4779 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004780 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004781 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004782 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004783 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004784 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004785
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004786#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004787 swiotlb = 0;
4788#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004789 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004790
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004791 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004792
Joerg Roedel39ab9552017-02-01 16:56:46 +01004793 for_each_active_iommu(iommu, drhd) {
4794 iommu_device_sysfs_add(&iommu->iommu, NULL,
4795 intel_iommu_groups,
4796 "%s", iommu->name);
4797 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4798 iommu_device_register(&iommu->iommu);
4799 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004800
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004801 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004802 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004803 if (si_domain && !hw_pass_through)
4804 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004805 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4806 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004807 intel_iommu_enabled = 1;
Sohil Mehtaee2636b2018-09-11 17:11:38 -07004808 intel_iommu_debugfs_init();
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004809
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004810 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004811
4812out_free_reserved_range:
4813 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004814out_free_dmar:
4815 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004816 up_write(&dmar_global_lock);
4817 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004818 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004819}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004820
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004821static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004822{
4823 struct intel_iommu *iommu = opaque;
4824
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004825 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004826 return 0;
4827}
4828
4829/*
4830 * NB - intel-iommu lacks any sort of reference counting for the users of
4831 * dependent devices. If multiple endpoints have intersecting dependent
4832 * devices, unbinding the driver from any one of them will possibly leave
4833 * the others unable to operate.
4834 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004835static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004836{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004837 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004838 return;
4839
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004840 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004841}
4842
Joerg Roedel127c7612015-07-23 17:44:46 +02004843static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004844{
Weidong Hanc7151a82008-12-08 22:51:37 +08004845 struct intel_iommu *iommu;
4846 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004847
Joerg Roedel55d94042015-07-22 16:50:40 +02004848 assert_spin_locked(&device_domain_lock);
4849
Joerg Roedelb608ac32015-07-21 18:19:08 +02004850 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004851 return;
4852
Joerg Roedel127c7612015-07-23 17:44:46 +02004853 iommu = info->iommu;
4854
4855 if (info->dev) {
4856 iommu_disable_dev_iotlb(info);
4857 domain_context_clear(iommu, info->dev);
Lu Baolua7fc93f2018-07-14 15:47:00 +08004858 intel_pasid_free_table(info->dev);
Joerg Roedel127c7612015-07-23 17:44:46 +02004859 }
4860
Joerg Roedelb608ac32015-07-21 18:19:08 +02004861 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004862
Joerg Roedeld160aca2015-07-22 11:52:53 +02004863 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004864 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004865 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004866
4867 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004868}
4869
Joerg Roedel55d94042015-07-22 16:50:40 +02004870static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4871 struct device *dev)
4872{
Joerg Roedel127c7612015-07-23 17:44:46 +02004873 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004874 unsigned long flags;
4875
Weidong Hanc7151a82008-12-08 22:51:37 +08004876 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004877 info = dev->archdata.iommu;
4878 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004879 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004880}
4881
4882static int md_domain_init(struct dmar_domain *domain, int guest_width)
4883{
4884 int adjust_width;
4885
Zhen Leiaa3ac942017-09-21 16:52:45 +01004886 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004887 domain_reserve_special_ranges(domain);
4888
4889 /* calculate AGAW */
4890 domain->gaw = guest_width;
4891 adjust_width = guestwidth_to_adjustwidth(guest_width);
4892 domain->agaw = width_to_agaw(adjust_width);
4893
Weidong Han5e98c4b2008-12-08 23:03:27 +08004894 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004895 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004896 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004897 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004898
4899 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004900 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004901 if (!domain->pgd)
4902 return -ENOMEM;
4903 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4904 return 0;
4905}
4906
Joerg Roedel00a77de2015-03-26 13:43:08 +01004907static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004908{
Joerg Roedel5d450802008-12-03 14:52:32 +01004909 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004910 struct iommu_domain *domain;
4911
4912 if (type != IOMMU_DOMAIN_UNMANAGED)
4913 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004914
Jiang Liuab8dfe22014-07-11 14:19:27 +08004915 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004916 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004917 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004918 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004919 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004920 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004921 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004922 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004923 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004924 }
Allen Kay8140a952011-10-14 12:32:17 -07004925 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004926
Joerg Roedel00a77de2015-03-26 13:43:08 +01004927 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004928 domain->geometry.aperture_start = 0;
4929 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4930 domain->geometry.force_aperture = true;
4931
Joerg Roedel00a77de2015-03-26 13:43:08 +01004932 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004933}
Kay, Allen M38717942008-09-09 18:37:29 +03004934
Joerg Roedel00a77de2015-03-26 13:43:08 +01004935static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004936{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004937 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004938}
Kay, Allen M38717942008-09-09 18:37:29 +03004939
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004940static int intel_iommu_attach_device(struct iommu_domain *domain,
4941 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004942{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004943 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004944 struct intel_iommu *iommu;
4945 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004946 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004947
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004948 if (device_is_rmrr_locked(dev)) {
4949 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4950 return -EPERM;
4951 }
4952
David Woodhouse7207d8f2014-03-09 16:31:06 -07004953 /* normally dev is not mapped */
4954 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004955 struct dmar_domain *old_domain;
4956
David Woodhouse1525a292014-03-06 16:19:30 +00004957 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004958 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004959 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004960 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004961 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004962
4963 if (!domain_type_is_vm_or_si(old_domain) &&
4964 list_empty(&old_domain->devices))
4965 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004966 }
4967 }
4968
David Woodhouse156baca2014-03-09 14:00:57 -07004969 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004970 if (!iommu)
4971 return -ENODEV;
4972
4973 /* check if this iommu agaw is sufficient for max mapped address */
4974 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004975 if (addr_width > cap_mgaw(iommu->cap))
4976 addr_width = cap_mgaw(iommu->cap);
4977
4978 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004979 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004980 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01004981 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004982 return -EFAULT;
4983 }
Tom Lyona99c47a2010-05-17 08:20:45 +01004984 dmar_domain->gaw = addr_width;
4985
4986 /*
4987 * Knock out extra levels of page tables if necessary
4988 */
4989 while (iommu->agaw < dmar_domain->agaw) {
4990 struct dma_pte *pte;
4991
4992 pte = dmar_domain->pgd;
4993 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08004994 dmar_domain->pgd = (struct dma_pte *)
4995 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01004996 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01004997 }
4998 dmar_domain->agaw--;
4999 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005000
Joerg Roedel28ccce02015-07-21 14:45:31 +02005001 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005002}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005003
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005004static void intel_iommu_detach_device(struct iommu_domain *domain,
5005 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005006{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005007 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005008}
Kay, Allen M38717942008-09-09 18:37:29 +03005009
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005010static int intel_iommu_map(struct iommu_domain *domain,
5011 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005012 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005013{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005014 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005015 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005016 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005017 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005018
Joerg Roedeldde57a22008-12-03 15:04:09 +01005019 if (iommu_prot & IOMMU_READ)
5020 prot |= DMA_PTE_READ;
5021 if (iommu_prot & IOMMU_WRITE)
5022 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005023 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5024 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005025
David Woodhouse163cc522009-06-28 00:51:17 +01005026 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005027 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005028 u64 end;
5029
5030 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005031 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005032 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005033 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005034 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005035 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005036 return -EFAULT;
5037 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005038 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005039 }
David Woodhousead051222009-06-28 14:22:28 +01005040 /* Round up size to next multiple of PAGE_SIZE, if it and
5041 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005042 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005043 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5044 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005045 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005046}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005047
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005048static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005049 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005050{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005051 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005052 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005053 unsigned long start_pfn, last_pfn;
5054 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005055 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005056
David Woodhouse5cf0a762014-03-19 16:07:49 +00005057 /* Cope with horrid API which requires us to unmap more than the
5058 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005059 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005060
5061 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5062 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5063
David Woodhouseea8ea462014-03-05 17:09:32 +00005064 start_pfn = iova >> VTD_PAGE_SHIFT;
5065 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5066
5067 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5068
5069 npages = last_pfn - start_pfn + 1;
5070
Shaokun Zhangf746a022018-03-22 18:18:06 +08005071 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005072 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5073 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005074
5075 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005076
David Woodhouse163cc522009-06-28 00:51:17 +01005077 if (dmar_domain->max_addr == iova + size)
5078 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005079
David Woodhouse5cf0a762014-03-19 16:07:49 +00005080 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005081}
Kay, Allen M38717942008-09-09 18:37:29 +03005082
Joerg Roedeld14d6572008-12-03 15:06:57 +01005083static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305084 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005085{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005086 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005087 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005088 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005089 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005090
David Woodhouse5cf0a762014-03-19 16:07:49 +00005091 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005092 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005093 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005094
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005095 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005096}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005097
Joerg Roedel5d587b82014-09-05 10:50:45 +02005098static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005099{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005100 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005101 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005102 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005103 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005104
Joerg Roedel5d587b82014-09-05 10:50:45 +02005105 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005106}
5107
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005108static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005109{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005110 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005111 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005112 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005113
Alex Williamsona5459cf2014-06-12 16:12:31 -06005114 iommu = device_to_iommu(dev, &bus, &devfn);
5115 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005116 return -ENODEV;
5117
Joerg Roedele3d10af2017-02-01 17:23:22 +01005118 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005119
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005120 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005121
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005122 if (IS_ERR(group))
5123 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005124
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005125 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005126 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005127}
5128
5129static void intel_iommu_remove_device(struct device *dev)
5130{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005131 struct intel_iommu *iommu;
5132 u8 bus, devfn;
5133
5134 iommu = device_to_iommu(dev, &bus, &devfn);
5135 if (!iommu)
5136 return;
5137
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005138 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005139
Joerg Roedele3d10af2017-02-01 17:23:22 +01005140 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005141}
5142
Eric Auger0659b8d2017-01-19 20:57:53 +00005143static void intel_iommu_get_resv_regions(struct device *device,
5144 struct list_head *head)
5145{
5146 struct iommu_resv_region *reg;
5147 struct dmar_rmrr_unit *rmrr;
5148 struct device *i_dev;
5149 int i;
5150
5151 rcu_read_lock();
5152 for_each_rmrr_units(rmrr) {
5153 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5154 i, i_dev) {
5155 if (i_dev != device)
5156 continue;
5157
5158 list_add_tail(&rmrr->resv->list, head);
5159 }
5160 }
5161 rcu_read_unlock();
5162
5163 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5164 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005165 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005166 if (!reg)
5167 return;
5168 list_add_tail(&reg->list, head);
5169}
5170
5171static void intel_iommu_put_resv_regions(struct device *dev,
5172 struct list_head *head)
5173{
5174 struct iommu_resv_region *entry, *next;
5175
5176 list_for_each_entry_safe(entry, next, head, list) {
5177 if (entry->type == IOMMU_RESV_RESERVED)
5178 kfree(entry);
5179 }
Kay, Allen M38717942008-09-09 18:37:29 +03005180}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005181
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005182#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005183#define MAX_NR_PASID_BITS (20)
Lu Baolu4774cc52018-07-14 15:47:01 +08005184static inline unsigned long intel_iommu_get_pts(struct device *dev)
Jacob Pan65ca7f52016-12-06 10:14:23 -08005185{
Lu Baolu4774cc52018-07-14 15:47:01 +08005186 int pts, max_pasid;
5187
5188 max_pasid = intel_pasid_get_dev_max_id(dev);
5189 pts = find_first_bit((unsigned long *)&max_pasid, MAX_NR_PASID_BITS);
5190 if (pts < 5)
Jacob Pan65ca7f52016-12-06 10:14:23 -08005191 return 0;
5192
Lu Baolu4774cc52018-07-14 15:47:01 +08005193 return pts - 5;
Jacob Pan65ca7f52016-12-06 10:14:23 -08005194}
5195
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005196int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5197{
5198 struct device_domain_info *info;
5199 struct context_entry *context;
5200 struct dmar_domain *domain;
5201 unsigned long flags;
5202 u64 ctx_lo;
5203 int ret;
5204
5205 domain = get_valid_domain_for_dev(sdev->dev);
5206 if (!domain)
5207 return -EINVAL;
5208
5209 spin_lock_irqsave(&device_domain_lock, flags);
5210 spin_lock(&iommu->lock);
5211
5212 ret = -EINVAL;
5213 info = sdev->dev->archdata.iommu;
5214 if (!info || !info->pasid_supported)
5215 goto out;
5216
5217 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5218 if (WARN_ON(!context))
5219 goto out;
5220
5221 ctx_lo = context[0].lo;
5222
5223 sdev->did = domain->iommu_did[iommu->seq_id];
5224 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5225
5226 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005227 if (iommu->pasid_state_table)
5228 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Lu Baolu4774cc52018-07-14 15:47:01 +08005229 context[1].lo = (u64)virt_to_phys(info->pasid_table->table) |
5230 intel_iommu_get_pts(sdev->dev);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005231
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005232 wmb();
5233 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5234 * extended to permit requests-with-PASID if the PASIDE bit
5235 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5236 * however, the PASIDE bit is ignored and requests-with-PASID
5237 * are unconditionally blocked. Which makes less sense.
5238 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5239 * "guest mode" translation types depending on whether ATS
5240 * is available or not. Annoyingly, we can't use the new
5241 * modes *unless* PASIDE is set. */
5242 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5243 ctx_lo &= ~CONTEXT_TT_MASK;
5244 if (info->ats_supported)
5245 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5246 else
5247 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5248 }
5249 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005250 if (iommu->pasid_state_table)
5251 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005252 if (info->pri_supported)
5253 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005254 context[0].lo = ctx_lo;
5255 wmb();
5256 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5257 DMA_CCMD_MASK_NOBIT,
5258 DMA_CCMD_DEVICE_INVL);
5259 }
5260
5261 /* Enable PASID support in the device, if it wasn't already */
5262 if (!info->pasid_enabled)
5263 iommu_enable_dev_iotlb(info);
5264
5265 if (info->ats_enabled) {
5266 sdev->dev_iotlb = 1;
5267 sdev->qdep = info->ats_qdep;
5268 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5269 sdev->qdep = 0;
5270 }
5271 ret = 0;
5272
5273 out:
5274 spin_unlock(&iommu->lock);
5275 spin_unlock_irqrestore(&device_domain_lock, flags);
5276
5277 return ret;
5278}
5279
5280struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5281{
5282 struct intel_iommu *iommu;
5283 u8 bus, devfn;
5284
5285 if (iommu_dummy(dev)) {
5286 dev_warn(dev,
5287 "No IOMMU translation for device; cannot enable SVM\n");
5288 return NULL;
5289 }
5290
5291 iommu = device_to_iommu(dev, &bus, &devfn);
5292 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005293 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005294 return NULL;
5295 }
5296
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005297 return iommu;
5298}
5299#endif /* CONFIG_INTEL_IOMMU_SVM */
5300
Joerg Roedelb0119e82017-02-01 13:23:08 +01005301const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005302 .capable = intel_iommu_capable,
5303 .domain_alloc = intel_iommu_domain_alloc,
5304 .domain_free = intel_iommu_domain_free,
5305 .attach_dev = intel_iommu_attach_device,
5306 .detach_dev = intel_iommu_detach_device,
5307 .map = intel_iommu_map,
5308 .unmap = intel_iommu_unmap,
Eric Auger0659b8d2017-01-19 20:57:53 +00005309 .iova_to_phys = intel_iommu_iova_to_phys,
5310 .add_device = intel_iommu_add_device,
5311 .remove_device = intel_iommu_remove_device,
5312 .get_resv_regions = intel_iommu_get_resv_regions,
5313 .put_resv_regions = intel_iommu_put_resv_regions,
5314 .device_group = pci_device_group,
5315 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005316};
David Woodhouse9af88142009-02-13 23:18:03 +00005317
Daniel Vetter94526182013-01-20 23:50:13 +01005318static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5319{
5320 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005321 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005322 dmar_map_gfx = 0;
5323}
5324
5325DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5326DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5327DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5328DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5329DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5330DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5331DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5332
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005333static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005334{
5335 /*
5336 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005337 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005338 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005339 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005340 rwbf_quirk = 1;
5341}
5342
5343DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005344DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5345DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5346DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5347DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5348DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5349DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005350
Adam Jacksoneecfd572010-08-25 21:17:34 +01005351#define GGC 0x52
5352#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5353#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5354#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5355#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5356#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5357#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5358#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5359#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5360
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005361static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005362{
5363 unsigned short ggc;
5364
Adam Jacksoneecfd572010-08-25 21:17:34 +01005365 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005366 return;
5367
Adam Jacksoneecfd572010-08-25 21:17:34 +01005368 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005369 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005370 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005371 } else if (dmar_map_gfx) {
5372 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005373 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005374 intel_iommu_strict = 1;
5375 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005376}
5377DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5378DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5379DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5380DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5381
David Woodhousee0fc7e02009-09-30 09:12:17 -07005382/* On Tylersburg chipsets, some BIOSes have been known to enable the
5383 ISOCH DMAR unit for the Azalia sound device, but not give it any
5384 TLB entries, which causes it to deadlock. Check for that. We do
5385 this in a function called from init_dmars(), instead of in a PCI
5386 quirk, because we don't want to print the obnoxious "BIOS broken"
5387 message if VT-d is actually disabled.
5388*/
5389static void __init check_tylersburg_isoch(void)
5390{
5391 struct pci_dev *pdev;
5392 uint32_t vtisochctrl;
5393
5394 /* If there's no Azalia in the system anyway, forget it. */
5395 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5396 if (!pdev)
5397 return;
5398 pci_dev_put(pdev);
5399
5400 /* System Management Registers. Might be hidden, in which case
5401 we can't do the sanity check. But that's OK, because the
5402 known-broken BIOSes _don't_ actually hide it, so far. */
5403 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5404 if (!pdev)
5405 return;
5406
5407 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5408 pci_dev_put(pdev);
5409 return;
5410 }
5411
5412 pci_dev_put(pdev);
5413
5414 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5415 if (vtisochctrl & 1)
5416 return;
5417
5418 /* Drop all bits other than the number of TLB entries */
5419 vtisochctrl &= 0x1c;
5420
5421 /* If we have the recommended number of TLB entries (16), fine. */
5422 if (vtisochctrl == 0x10)
5423 return;
5424
5425 /* Zero TLB entries? You get to ride the short bus to school. */
5426 if (!vtisochctrl) {
5427 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5428 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5429 dmi_get_system_info(DMI_BIOS_VENDOR),
5430 dmi_get_system_info(DMI_BIOS_VERSION),
5431 dmi_get_system_info(DMI_PRODUCT_VERSION));
5432 iommu_identity_mapping |= IDENTMAP_AZALIA;
5433 return;
5434 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005435
5436 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005437 vtisochctrl);
5438}