blob: 66d07b1a3be2eb76c6cd7c8356ac38152c6b59c6 [file] [log] [blame]
Thomas Gleixner2025cf92019-05-29 07:18:02 -07001// SPDX-License-Identifier: GPL-2.0-only
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002/*
David Woodhouseea8ea462014-03-05 17:09:32 +00003 * Copyright © 2006-2014 Intel Corporation.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004 *
David Woodhouseea8ea462014-03-05 17:09:32 +00005 * Authors: David Woodhouse <dwmw2@infradead.org>,
6 * Ashok Raj <ashok.raj@intel.com>,
7 * Shaohua Li <shaohua.li@intel.com>,
8 * Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
9 * Fenghua Yu <fenghua.yu@intel.com>
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020010 * Joerg Roedel <jroedel@suse.de>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070011 */
12
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020013#define pr_fmt(fmt) "DMAR: " fmt
Bjorn Helgaas932a6522019-02-08 16:06:00 -060014#define dev_fmt(fmt) pr_fmt(fmt)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020015
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070016#include <linux/init.h>
17#include <linux/bitmap.h>
mark gross5e0d2a62008-03-04 15:22:08 -080018#include <linux/debugfs.h>
Paul Gortmaker54485c32011-10-29 10:26:25 -040019#include <linux/export.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070020#include <linux/slab.h>
21#include <linux/irq.h>
22#include <linux/interrupt.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070023#include <linux/spinlock.h>
24#include <linux/pci.h>
25#include <linux/dmar.h>
26#include <linux/dma-mapping.h>
27#include <linux/mempool.h>
Jiang Liu75f05562014-02-19 14:07:37 +080028#include <linux/memory.h>
Omer Pelegaa473242016-04-20 11:33:02 +030029#include <linux/cpu.h>
mark gross5e0d2a62008-03-04 15:22:08 -080030#include <linux/timer.h>
Dan Williamsdfddb962015-10-09 18:16:46 -040031#include <linux/io.h>
Kay, Allen M38717942008-09-09 18:37:29 +030032#include <linux/iova.h>
Joerg Roedel5d450802008-12-03 14:52:32 +010033#include <linux/iommu.h>
Kay, Allen M38717942008-09-09 18:37:29 +030034#include <linux/intel-iommu.h>
Rafael J. Wysocki134fac32011-03-23 22:16:14 +010035#include <linux/syscore_ops.h>
Shane Wang69575d32009-09-01 18:25:07 -070036#include <linux/tboot.h>
Stephen Rothwelladb2fe02009-08-31 15:24:23 +100037#include <linux/dmi.h>
Joerg Roedel5cdede22011-04-04 15:55:18 +020038#include <linux/pci-ats.h>
Tejun Heo0ee332c2011-12-08 10:22:09 -080039#include <linux/memblock.h>
Akinobu Mita36746432014-06-04 16:06:51 -070040#include <linux/dma-contiguous.h>
Christoph Hellwigfec777c2018-03-19 11:38:15 +010041#include <linux/dma-direct.h>
Joerg Roedel091d42e2015-06-12 11:56:10 +020042#include <linux/crash_dump.h>
Anshuman Khandual98fa15f2019-03-05 15:42:58 -080043#include <linux/numa.h>
Lu Baolucfb94a32019-09-06 14:14:52 +080044#include <linux/swiotlb.h>
Suresh Siddha8a8f4222012-03-30 11:47:08 -070045#include <asm/irq_remapping.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070046#include <asm/cacheflush.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090047#include <asm/iommu.h>
Lu Baolucfb94a32019-09-06 14:14:52 +080048#include <trace/events/intel_iommu.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070049
Joerg Roedel672cf6d2020-06-09 15:03:03 +020050#include "../irq_remapping.h"
Lu Baolu56283172018-07-14 15:46:54 +080051#include "intel-pasid.h"
Joerg Roedel078e1ee2012-09-26 12:44:43 +020052
Fenghua Yu5b6985c2008-10-16 18:02:32 -070053#define ROOT_SIZE VTD_PAGE_SIZE
54#define CONTEXT_SIZE VTD_PAGE_SIZE
55
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070056#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000057#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070058#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070059#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070060
61#define IOAPIC_RANGE_START (0xfee00000)
62#define IOAPIC_RANGE_END (0xfeefffff)
63#define IOVA_START_ADDR (0x1000)
64
Sohil Mehta5e3b4a12017-12-20 11:59:24 -080065#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070066
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070067#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080068#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070069
David Woodhouse2ebe3152009-09-19 07:34:04 -070070#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
71#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
72
73/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
74 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
75#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
76 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
77#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070078
Robin Murphy1b722502015-01-12 17:51:15 +000079/* IO virtual address start page frame number */
80#define IOVA_START_PFN (1)
81
Mark McLoughlinf27be032008-11-20 15:49:43 +000082#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
mark gross5e0d2a62008-03-04 15:22:08 -080083
Andrew Mortondf08cdc2010-09-22 13:05:11 -070084/* page table handling */
85#define LEVEL_STRIDE (9)
86#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
87
Ohad Ben-Cohen6d1c56a2011-11-10 11:32:30 +020088/*
89 * This bitmap is used to advertise the page sizes our hardware support
90 * to the IOMMU core, which will then use this information to split
91 * physically contiguous memory regions it is mapping into page sizes
92 * that we support.
93 *
94 * Traditionally the IOMMU core just handed us the mappings directly,
95 * after making sure the size is an order of a 4KiB page and that the
96 * mapping has natural alignment.
97 *
98 * To retain this behavior, we currently advertise that we support
99 * all page sizes that are an order of 4KiB.
100 *
101 * If at some point we'd like to utilize the IOMMU core's new behavior,
102 * we could change this to advertise the real page sizes we support.
103 */
104#define INTEL_IOMMU_PGSIZES (~0xFFFUL)
105
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700106static inline int agaw_to_level(int agaw)
107{
108 return agaw + 2;
109}
110
111static inline int agaw_to_width(int agaw)
112{
Jiang Liu5c645b32014-01-06 14:18:12 +0800113 return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700114}
115
116static inline int width_to_agaw(int width)
117{
Jiang Liu5c645b32014-01-06 14:18:12 +0800118 return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700119}
120
121static inline unsigned int level_to_offset_bits(int level)
122{
123 return (level - 1) * LEVEL_STRIDE;
124}
125
126static inline int pfn_level_offset(unsigned long pfn, int level)
127{
128 return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
129}
130
131static inline unsigned long level_mask(int level)
132{
133 return -1UL << level_to_offset_bits(level);
134}
135
136static inline unsigned long level_size(int level)
137{
138 return 1UL << level_to_offset_bits(level);
139}
140
141static inline unsigned long align_to_level(unsigned long pfn, int level)
142{
143 return (pfn + level_size(level) - 1) & level_mask(level);
144}
David Woodhousefd18de52009-05-10 23:57:41 +0100145
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100146static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
147{
Jiang Liu5c645b32014-01-06 14:18:12 +0800148 return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100149}
150
David Woodhousedd4e8312009-06-27 16:21:20 +0100151/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
152 are never going to work. */
153static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
154{
155 return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT);
156}
157
158static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn)
159{
160 return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
161}
162static inline unsigned long page_to_dma_pfn(struct page *pg)
163{
164 return mm_to_dma_pfn(page_to_pfn(pg));
165}
166static inline unsigned long virt_to_dma_pfn(void *p)
167{
168 return page_to_dma_pfn(virt_to_page(p));
169}
170
Weidong Hand9630fe2008-12-08 11:06:32 +0800171/* global iommu list, set NULL for ignored DMAR units */
172static struct intel_iommu **g_iommus;
173
David Woodhousee0fc7e02009-09-30 09:12:17 -0700174static void __init check_tylersburg_isoch(void);
David Woodhouse9af88142009-02-13 23:18:03 +0000175static int rwbf_quirk;
176
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000177/*
Joseph Cihulab7792602011-05-03 00:08:37 -0700178 * set to 1 to panic kernel if can't successfully enable VT-d
179 * (used when kernel is launched w/ TXT)
180 */
181static int force_on = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700182int intel_iommu_tboot_noforce;
Lu Baolu89a60792018-10-23 15:45:01 +0800183static int no_platform_optin;
Joseph Cihulab7792602011-05-03 00:08:37 -0700184
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000185#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000186
Joerg Roedel091d42e2015-06-12 11:56:10 +0200187/*
188 * Take a root_entry and return the Lower Context Table Pointer (LCTP)
189 * if marked present.
190 */
191static phys_addr_t root_entry_lctp(struct root_entry *re)
192{
193 if (!(re->lo & 1))
194 return 0;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000195
Joerg Roedel091d42e2015-06-12 11:56:10 +0200196 return re->lo & VTD_PAGE_MASK;
197}
198
199/*
200 * Take a root_entry and return the Upper Context Table Pointer (UCTP)
201 * if marked present.
202 */
203static phys_addr_t root_entry_uctp(struct root_entry *re)
204{
205 if (!(re->hi & 1))
206 return 0;
207
208 return re->hi & VTD_PAGE_MASK;
209}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000210
Joerg Roedelcf484d02015-06-12 12:21:46 +0200211static inline void context_clear_pasid_enable(struct context_entry *context)
212{
213 context->lo &= ~(1ULL << 11);
214}
215
216static inline bool context_pasid_enabled(struct context_entry *context)
217{
218 return !!(context->lo & (1ULL << 11));
219}
220
221static inline void context_set_copied(struct context_entry *context)
222{
223 context->hi |= (1ull << 3);
224}
225
226static inline bool context_copied(struct context_entry *context)
227{
228 return !!(context->hi & (1ULL << 3));
229}
230
231static inline bool __context_present(struct context_entry *context)
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000232{
233 return (context->lo & 1);
234}
Joerg Roedelcf484d02015-06-12 12:21:46 +0200235
Sohil Mehta26b86092018-09-11 17:11:36 -0700236bool context_present(struct context_entry *context)
Joerg Roedelcf484d02015-06-12 12:21:46 +0200237{
238 return context_pasid_enabled(context) ?
239 __context_present(context) :
240 __context_present(context) && !context_copied(context);
241}
242
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000243static inline void context_set_present(struct context_entry *context)
244{
245 context->lo |= 1;
246}
247
248static inline void context_set_fault_enable(struct context_entry *context)
249{
250 context->lo &= (((u64)-1) << 2) | 1;
251}
252
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000253static inline void context_set_translation_type(struct context_entry *context,
254 unsigned long value)
255{
256 context->lo &= (((u64)-1) << 4) | 3;
257 context->lo |= (value & 3) << 2;
258}
259
260static inline void context_set_address_root(struct context_entry *context,
261 unsigned long value)
262{
Li, Zhen-Hua1a2262f2014-11-05 15:30:19 +0800263 context->lo &= ~VTD_PAGE_MASK;
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000264 context->lo |= value & VTD_PAGE_MASK;
265}
266
267static inline void context_set_address_width(struct context_entry *context,
268 unsigned long value)
269{
270 context->hi |= value & 7;
271}
272
273static inline void context_set_domain_id(struct context_entry *context,
274 unsigned long value)
275{
276 context->hi |= (value & ((1 << 16) - 1)) << 8;
277}
278
Joerg Roedeldbcd8612015-06-12 12:02:09 +0200279static inline int context_domain_id(struct context_entry *c)
280{
281 return((c->hi >> 8) & 0xffff);
282}
283
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000284static inline void context_clear_entry(struct context_entry *context)
285{
286 context->lo = 0;
287 context->hi = 0;
288}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000289
Mark McLoughlin622ba122008-11-20 15:49:46 +0000290/*
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700291 * This domain is a statically identity mapping domain.
292 * 1. This domain creats a static 1:1 mapping to all usable memory.
293 * 2. It maps to each iommu if successful.
294 * 3. Each iommu mapps to this domain if successful.
295 */
David Woodhouse19943b02009-08-04 16:19:20 +0100296static struct dmar_domain *si_domain;
297static int hw_pass_through = 1;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700298
Joerg Roedel29a27712015-07-21 17:17:12 +0200299#define for_each_domain_iommu(idx, domain) \
300 for (idx = 0; idx < g_num_of_iommus; idx++) \
301 if (domain->iommu_refcnt[idx])
302
Jiang Liub94e4112014-02-19 14:07:25 +0800303struct dmar_rmrr_unit {
304 struct list_head list; /* list of rmrr units */
305 struct acpi_dmar_header *hdr; /* ACPI header */
306 u64 base_address; /* reserved base address*/
307 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000308 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800309 int devices_cnt; /* target device count */
310};
311
312struct dmar_atsr_unit {
313 struct list_head list; /* list of ATSR units */
314 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000315 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800316 int devices_cnt; /* target device count */
317 u8 include_all:1; /* include all ports */
318};
319
320static LIST_HEAD(dmar_atsr_units);
321static LIST_HEAD(dmar_rmrr_units);
322
323#define for_each_rmrr_units(rmrr) \
324 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
325
mark gross5e0d2a62008-03-04 15:22:08 -0800326/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800327static int g_num_of_iommus;
328
Jiang Liu92d03cc2014-02-19 14:07:28 +0800329static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700330static void domain_remove_dev_info(struct dmar_domain *domain);
Bjorn Helgaas71753232019-02-08 16:06:15 -0600331static void dmar_remove_one_dev_info(struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200332static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Lu Baolu8af46c72019-05-25 13:41:32 +0800333static int intel_iommu_attach_device(struct iommu_domain *domain,
334 struct device *dev);
Lu Baolucfb94a32019-09-06 14:14:52 +0800335static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
336 dma_addr_t iova);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700337
Suresh Siddhad3f13812011-08-23 17:05:25 -0700338#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800339int dmar_disabled = 0;
340#else
341int dmar_disabled = 1;
Lu Baolu04618252020-01-02 08:18:02 +0800342#endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800343
Lu Baoluba61c3d2020-05-01 15:24:27 +0800344#ifdef CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
Lu Baolu04618252020-01-02 08:18:02 +0800345int intel_iommu_sm = 1;
346#else
Sai Praneeth Prakhyacdd3a242019-05-24 16:40:16 -0700347int intel_iommu_sm;
Lu Baoluba61c3d2020-05-01 15:24:27 +0800348#endif /* CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */
Lu Baolu04618252020-01-02 08:18:02 +0800349
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200350int intel_iommu_enabled = 0;
351EXPORT_SYMBOL_GPL(intel_iommu_enabled);
352
David Woodhouse2d9e6672010-06-15 10:57:57 +0100353static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700354static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800355static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100356static int intel_iommu_superpage = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100357static int iommu_identity_mapping;
Lu Baolue5e04d02019-09-06 14:14:49 +0800358static int intel_no_bounce;
David Woodhousec83b2f22015-06-12 10:15:49 +0100359
David Woodhouseae853dd2015-09-09 11:58:59 +0100360#define IDENTMAP_GFX 2
361#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100362
David Woodhousec0771df2011-10-14 20:59:46 +0100363int intel_iommu_gfx_mapped;
364EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
365
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700366#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
Lu Baolu8af46c72019-05-25 13:41:32 +0800367#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
Lu Baolue85bb992020-05-16 14:20:52 +0800368struct device_domain_info *get_domain_info(struct device *dev)
369{
370 struct device_domain_info *info;
371
372 if (!dev)
373 return NULL;
374
375 info = dev->archdata.iommu;
376 if (unlikely(info == DUMMY_DEVICE_DOMAIN_INFO ||
377 info == DEFER_DEVICE_DOMAIN_INFO))
378 return NULL;
379
380 return info;
381}
382
Lu Baolue2726da2020-01-02 08:18:22 +0800383DEFINE_SPINLOCK(device_domain_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700384static LIST_HEAD(device_domain_list);
385
Lu Baolue5e04d02019-09-06 14:14:49 +0800386#define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) && \
387 to_pci_dev(d)->untrusted)
388
Lu Baolu85319dc2018-07-14 15:46:58 +0800389/*
390 * Iterate over elements in device_domain_list and call the specified
Lu Baolu0bbeb012018-12-10 09:58:56 +0800391 * callback @fn against each element.
Lu Baolu85319dc2018-07-14 15:46:58 +0800392 */
393int for_each_device_domain(int (*fn)(struct device_domain_info *info,
394 void *data), void *data)
395{
396 int ret = 0;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800397 unsigned long flags;
Lu Baolu85319dc2018-07-14 15:46:58 +0800398 struct device_domain_info *info;
399
Lu Baolu0bbeb012018-12-10 09:58:56 +0800400 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800401 list_for_each_entry(info, &device_domain_list, global) {
402 ret = fn(info, data);
Lu Baolu0bbeb012018-12-10 09:58:56 +0800403 if (ret) {
404 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800405 return ret;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800406 }
Lu Baolu85319dc2018-07-14 15:46:58 +0800407 }
Lu Baolu0bbeb012018-12-10 09:58:56 +0800408 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800409
410 return 0;
411}
412
Joerg Roedelb0119e82017-02-01 13:23:08 +0100413const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100414
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200415static bool translation_pre_enabled(struct intel_iommu *iommu)
416{
417 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
418}
419
Joerg Roedel091d42e2015-06-12 11:56:10 +0200420static void clear_translation_pre_enabled(struct intel_iommu *iommu)
421{
422 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
423}
424
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200425static void init_translation_status(struct intel_iommu *iommu)
426{
427 u32 gsts;
428
429 gsts = readl(iommu->reg + DMAR_GSTS_REG);
430 if (gsts & DMA_GSTS_TES)
431 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
432}
433
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700434static int __init intel_iommu_setup(char *str)
435{
436 if (!str)
437 return -EINVAL;
438 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800439 if (!strncmp(str, "on", 2)) {
440 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200441 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800442 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700443 dmar_disabled = 1;
Lu Baolu89a60792018-10-23 15:45:01 +0800444 no_platform_optin = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200445 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700446 } else if (!strncmp(str, "igfx_off", 8)) {
447 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200448 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700449 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200450 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700451 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800452 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200453 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800454 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100455 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200456 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100457 intel_iommu_superpage = 0;
Lu Baolu8950dcd2019-01-24 10:31:32 +0800458 } else if (!strncmp(str, "sm_on", 5)) {
459 pr_info("Intel-IOMMU: scalable mode supported\n");
460 intel_iommu_sm = 1;
Shaohua Libfd20f12017-04-26 09:18:35 -0700461 } else if (!strncmp(str, "tboot_noforce", 13)) {
Andy Shevchenko86278922020-05-07 19:18:02 +0300462 pr_info("Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
Shaohua Libfd20f12017-04-26 09:18:35 -0700463 intel_iommu_tboot_noforce = 1;
Lu Baolue5e04d02019-09-06 14:14:49 +0800464 } else if (!strncmp(str, "nobounce", 8)) {
465 pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
466 intel_no_bounce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700467 }
468
469 str += strcspn(str, ",");
470 while (*str == ',')
471 str++;
472 }
473 return 0;
474}
475__setup("intel_iommu=", intel_iommu_setup);
476
477static struct kmem_cache *iommu_domain_cache;
478static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700479
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200480static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
481{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200482 struct dmar_domain **domains;
483 int idx = did >> 8;
484
485 domains = iommu->domains[idx];
486 if (!domains)
487 return NULL;
488
489 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200490}
491
492static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
493 struct dmar_domain *domain)
494{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200495 struct dmar_domain **domains;
496 int idx = did >> 8;
497
498 if (!iommu->domains[idx]) {
499 size_t size = 256 * sizeof(struct dmar_domain *);
500 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
501 }
502
503 domains = iommu->domains[idx];
504 if (WARN_ON(!domains))
505 return;
506 else
507 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200508}
509
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800510void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700511{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700512 struct page *page;
513 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700514
Suresh Siddha4c923d42009-10-02 11:01:24 -0700515 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
516 if (page)
517 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700518 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700519}
520
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800521void free_pgtable_page(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700522{
523 free_page((unsigned long)vaddr);
524}
525
526static inline void *alloc_domain_mem(void)
527{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900528 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700529}
530
Kay, Allen M38717942008-09-09 18:37:29 +0300531static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700532{
533 kmem_cache_free(iommu_domain_cache, vaddr);
534}
535
536static inline void * alloc_devinfo_mem(void)
537{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900538 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700539}
540
541static inline void free_devinfo_mem(void *vaddr)
542{
543 kmem_cache_free(iommu_devinfo_cache, vaddr);
544}
545
Joerg Roedel28ccce02015-07-21 14:45:31 +0200546static inline int domain_type_is_si(struct dmar_domain *domain)
547{
548 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
549}
550
Lu Baoluddf09b62020-01-02 08:18:17 +0800551static inline bool domain_use_first_level(struct dmar_domain *domain)
552{
553 return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL;
554}
555
Jiang Liu162d1b12014-07-11 14:19:35 +0800556static inline int domain_pfn_supported(struct dmar_domain *domain,
557 unsigned long pfn)
558{
559 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
560
561 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
562}
563
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700564static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800565{
566 unsigned long sagaw;
567 int agaw = -1;
568
569 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700570 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800571 agaw >= 0; agaw--) {
572 if (test_bit(agaw, &sagaw))
573 break;
574 }
575
576 return agaw;
577}
578
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700579/*
580 * Calculate max SAGAW for each iommu.
581 */
582int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
583{
584 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
585}
586
587/*
588 * calculate agaw for each iommu.
589 * "SAGAW" may be different across iommus, use a default agaw, and
590 * get a supported less agaw for iommus that don't support the default agaw.
591 */
592int iommu_calculate_agaw(struct intel_iommu *iommu)
593{
594 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
595}
596
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700597/* This functionin only returns single iommu in a domain */
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800598struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
Weidong Han8c11e792008-12-08 15:29:22 +0800599{
600 int iommu_id;
601
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700602 /* si_domain and vm domain should not get here. */
Lu Baolufa954e62019-05-25 13:41:28 +0800603 if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
604 return NULL;
605
Joerg Roedel29a27712015-07-21 17:17:12 +0200606 for_each_domain_iommu(iommu_id, domain)
607 break;
608
Weidong Han8c11e792008-12-08 15:29:22 +0800609 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
610 return NULL;
611
612 return g_iommus[iommu_id];
613}
614
Weidong Han8e6040972008-12-08 15:49:06 +0800615static void domain_update_iommu_coherency(struct dmar_domain *domain)
616{
David Woodhoused0501962014-03-11 17:10:29 -0700617 struct dmar_drhd_unit *drhd;
618 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100619 bool found = false;
620 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800621
David Woodhoused0501962014-03-11 17:10:29 -0700622 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800623
Joerg Roedel29a27712015-07-21 17:17:12 +0200624 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100625 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800626 if (!ecap_coherent(g_iommus[i]->ecap)) {
627 domain->iommu_coherency = 0;
628 break;
629 }
Weidong Han8e6040972008-12-08 15:49:06 +0800630 }
David Woodhoused0501962014-03-11 17:10:29 -0700631 if (found)
632 return;
633
634 /* No hardware attached; use lowest common denominator */
635 rcu_read_lock();
636 for_each_active_iommu(iommu, drhd) {
637 if (!ecap_coherent(iommu->ecap)) {
638 domain->iommu_coherency = 0;
639 break;
640 }
641 }
642 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800643}
644
Jiang Liu161f6932014-07-11 14:19:37 +0800645static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100646{
Allen Kay8140a952011-10-14 12:32:17 -0700647 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800648 struct intel_iommu *iommu;
649 int ret = 1;
650
651 rcu_read_lock();
652 for_each_active_iommu(iommu, drhd) {
653 if (iommu != skip) {
654 if (!ecap_sc_support(iommu->ecap)) {
655 ret = 0;
656 break;
657 }
658 }
659 }
660 rcu_read_unlock();
661
662 return ret;
663}
664
Lu Baolu64229e82020-01-02 08:18:20 +0800665static int domain_update_iommu_superpage(struct dmar_domain *domain,
666 struct intel_iommu *skip)
Jiang Liu161f6932014-07-11 14:19:37 +0800667{
668 struct dmar_drhd_unit *drhd;
669 struct intel_iommu *iommu;
Lu Baolu64229e82020-01-02 08:18:20 +0800670 int mask = 0x3;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100671
672 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800673 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100674 }
675
Allen Kay8140a952011-10-14 12:32:17 -0700676 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800677 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700678 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800679 if (iommu != skip) {
Lu Baolu64229e82020-01-02 08:18:20 +0800680 if (domain && domain_use_first_level(domain)) {
681 if (!cap_fl1gp_support(iommu->cap))
682 mask = 0x1;
683 } else {
684 mask &= cap_super_page_val(iommu->cap);
685 }
686
Jiang Liu161f6932014-07-11 14:19:37 +0800687 if (!mask)
688 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100689 }
690 }
Jiang Liu0e242612014-02-19 14:07:34 +0800691 rcu_read_unlock();
692
Jiang Liu161f6932014-07-11 14:19:37 +0800693 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100694}
695
Sheng Yang58c610b2009-03-18 15:33:05 +0800696/* Some capabilities may be different across iommus */
697static void domain_update_iommu_cap(struct dmar_domain *domain)
698{
699 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800700 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
Lu Baolu64229e82020-01-02 08:18:20 +0800701 domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800702}
703
Sohil Mehta26b86092018-09-11 17:11:36 -0700704struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
705 u8 devfn, int alloc)
David Woodhouse03ecc322015-02-13 14:35:21 +0000706{
707 struct root_entry *root = &iommu->root_entry[bus];
708 struct context_entry *context;
709 u64 *entry;
710
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200711 entry = &root->lo;
Lu Baolu765b6a92018-12-10 09:58:55 +0800712 if (sm_supported(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000713 if (devfn >= 0x80) {
714 devfn -= 0x80;
715 entry = &root->hi;
716 }
717 devfn *= 2;
718 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000719 if (*entry & 1)
720 context = phys_to_virt(*entry & VTD_PAGE_MASK);
721 else {
722 unsigned long phy_addr;
723 if (!alloc)
724 return NULL;
725
726 context = alloc_pgtable_page(iommu->node);
727 if (!context)
728 return NULL;
729
730 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
731 phy_addr = virt_to_phys((void *)context);
732 *entry = phy_addr | 1;
733 __iommu_flush_cache(iommu, entry, sizeof(*entry));
734 }
735 return &context[devfn];
736}
737
David Woodhouse4ed6a542015-05-11 14:59:20 +0100738static int iommu_dummy(struct device *dev)
739{
740 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
741}
742
Joerg Roedel1d46159782020-02-17 17:12:37 +0100743static bool attach_deferred(struct device *dev)
744{
745 return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
746}
747
Eric Augerb9a7f982019-06-03 08:53:32 +0200748/**
749 * is_downstream_to_pci_bridge - test if a device belongs to the PCI
750 * sub-hierarchy of a candidate PCI-PCI bridge
751 * @dev: candidate PCI device belonging to @bridge PCI sub-hierarchy
752 * @bridge: the candidate PCI-PCI bridge
753 *
754 * Return: true if @dev belongs to @bridge PCI sub-hierarchy, else false.
755 */
756static bool
757is_downstream_to_pci_bridge(struct device *dev, struct device *bridge)
758{
759 struct pci_dev *pdev, *pbridge;
760
761 if (!dev_is_pci(dev) || !dev_is_pci(bridge))
762 return false;
763
764 pdev = to_pci_dev(dev);
765 pbridge = to_pci_dev(bridge);
766
767 if (pbridge->subordinate &&
768 pbridge->subordinate->number <= pdev->bus->number &&
769 pbridge->subordinate->busn_res.end >= pdev->bus->number)
770 return true;
771
772 return false;
773}
774
David Woodhouse156baca2014-03-09 14:00:57 -0700775static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800776{
777 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800778 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700779 struct device *tmp;
Eric Augerb9a7f982019-06-03 08:53:32 +0200780 struct pci_dev *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800781 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800782 int i;
783
David Woodhouse4ed6a542015-05-11 14:59:20 +0100784 if (iommu_dummy(dev))
785 return NULL;
786
David Woodhouse156baca2014-03-09 14:00:57 -0700787 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700788 struct pci_dev *pf_pdev;
789
Jon Derricke3560ee2020-01-21 06:37:49 -0700790 pdev = pci_real_dma_dev(to_pci_dev(dev));
Jon Derrick5823e332017-08-30 15:05:59 -0600791
Ashok Raj1c387182016-10-21 15:32:05 -0700792 /* VFs aren't listed in scope tables; we need to look up
793 * the PF instead to find the IOMMU. */
794 pf_pdev = pci_physfn(pdev);
795 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700796 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100797 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700798 dev = &ACPI_COMPANION(dev)->dev;
799
Jiang Liu0e242612014-02-19 14:07:34 +0800800 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800801 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700802 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100803 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800804
Jiang Liub683b232014-02-19 14:07:32 +0800805 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700806 drhd->devices_cnt, i, tmp) {
807 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700808 /* For a VF use its original BDF# not that of the PF
809 * which we used for the IOMMU lookup. Strictly speaking
810 * we could do this for all PCI devices; we only need to
811 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100812 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700813 goto got_pdev;
814
David Woodhouse156baca2014-03-09 14:00:57 -0700815 *bus = drhd->devices[i].bus;
816 *devfn = drhd->devices[i].devfn;
817 goto out;
818 }
819
Eric Augerb9a7f982019-06-03 08:53:32 +0200820 if (is_downstream_to_pci_bridge(dev, tmp))
David Woodhouse156baca2014-03-09 14:00:57 -0700821 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100822 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800823
David Woodhouse156baca2014-03-09 14:00:57 -0700824 if (pdev && drhd->include_all) {
825 got_pdev:
826 *bus = pdev->bus->number;
827 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800828 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700829 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800830 }
Jiang Liub683b232014-02-19 14:07:32 +0800831 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700832 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800833 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800834
Jiang Liub683b232014-02-19 14:07:32 +0800835 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800836}
837
Weidong Han5331fe62008-12-08 23:00:00 +0800838static void domain_flush_cache(struct dmar_domain *domain,
839 void *addr, int size)
840{
841 if (!domain->iommu_coherency)
842 clflush_cache_range(addr, size);
843}
844
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700845static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
846{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700847 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000848 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700849 unsigned long flags;
850
851 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000852 context = iommu_context_addr(iommu, bus, devfn, 0);
853 if (context)
854 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700855 spin_unlock_irqrestore(&iommu->lock, flags);
856 return ret;
857}
858
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700859static void free_context_table(struct intel_iommu *iommu)
860{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700861 int i;
862 unsigned long flags;
863 struct context_entry *context;
864
865 spin_lock_irqsave(&iommu->lock, flags);
866 if (!iommu->root_entry) {
867 goto out;
868 }
869 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000870 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700871 if (context)
872 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000873
Lu Baolu765b6a92018-12-10 09:58:55 +0800874 if (!sm_supported(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000875 continue;
876
877 context = iommu_context_addr(iommu, i, 0x80, 0);
878 if (context)
879 free_pgtable_page(context);
880
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700881 }
882 free_pgtable_page(iommu->root_entry);
883 iommu->root_entry = NULL;
884out:
885 spin_unlock_irqrestore(&iommu->lock, flags);
886}
887
David Woodhouseb026fd22009-06-28 10:37:25 +0100888static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000889 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700890{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600891 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700892 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700893 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700894
895 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200896
Jiang Liu162d1b12014-07-11 14:19:35 +0800897 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200898 /* Address beyond IOMMU's addressing capabilities. */
899 return NULL;
900
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700901 parent = domain->pgd;
902
David Woodhouse5cf0a762014-03-19 16:07:49 +0000903 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700904 void *tmp_page;
905
David Woodhouseb026fd22009-06-28 10:37:25 +0100906 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700907 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000908 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100909 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000910 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700911 break;
912
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000913 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100914 uint64_t pteval;
915
Suresh Siddha4c923d42009-10-02 11:01:24 -0700916 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700917
David Woodhouse206a73c2009-07-01 19:30:28 +0100918 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700919 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100920
David Woodhousec85994e2009-07-01 19:21:24 +0100921 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400922 pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
Lu Baoluddf09b62020-01-02 08:18:17 +0800923 if (domain_use_first_level(domain))
Lu Baolu16ecf102020-06-23 07:13:41 +0800924 pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
Yijing Wangeffad4b2014-05-26 20:13:47 +0800925 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100926 /* Someone else set it while we were thinking; use theirs. */
927 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800928 else
David Woodhousec85994e2009-07-01 19:21:24 +0100929 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700930 }
David Woodhouse5cf0a762014-03-19 16:07:49 +0000931 if (level == 1)
932 break;
933
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000934 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700935 level--;
936 }
937
David Woodhouse5cf0a762014-03-19 16:07:49 +0000938 if (!*target_level)
939 *target_level = level;
940
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700941 return pte;
942}
943
944/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +0100945static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
946 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100947 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700948{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600949 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700950 int total = agaw_to_level(domain->agaw);
951 int offset;
952
953 parent = domain->pgd;
954 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +0100955 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700956 pte = &parent[offset];
957 if (level == total)
958 return pte;
959
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100960 if (!dma_pte_present(pte)) {
961 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700962 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100963 }
964
Yijing Wange16922a2014-05-20 20:37:51 +0800965 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100966 *large_page = total;
967 return pte;
968 }
969
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000970 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700971 total--;
972 }
973 return NULL;
974}
975
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700976/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +0000977static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf52009-06-27 22:09:11 +0100978 unsigned long start_pfn,
979 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700980{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600981 unsigned int large_page;
David Woodhouse310a5ab2009-06-28 18:52:20 +0100982 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700983
Jiang Liu162d1b12014-07-11 14:19:35 +0800984 BUG_ON(!domain_pfn_supported(domain, start_pfn));
985 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -0700986 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +0100987
David Woodhouse04b18e62009-06-27 19:15:01 +0100988 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -0700989 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100990 large_page = 1;
991 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100992 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100993 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100994 continue;
995 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100996 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +0100997 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100998 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100999 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001000 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1001
David Woodhouse310a5ab2009-06-28 18:52:20 +01001002 domain_flush_cache(domain, first_pte,
1003 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001004
1005 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001006}
1007
Alex Williamson3269ee02013-06-15 10:27:19 -06001008static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001009 int retain_level, struct dma_pte *pte,
1010 unsigned long pfn, unsigned long start_pfn,
1011 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001012{
1013 pfn = max(start_pfn, pfn);
1014 pte = &pte[pfn_level_offset(pfn, level)];
1015
1016 do {
1017 unsigned long level_pfn;
1018 struct dma_pte *level_pte;
1019
1020 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1021 goto next;
1022
David Dillowf7116e12017-01-30 19:11:11 -08001023 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001024 level_pte = phys_to_virt(dma_pte_addr(pte));
1025
David Dillowbc24c572017-06-28 19:42:23 -07001026 if (level > 2) {
1027 dma_pte_free_level(domain, level - 1, retain_level,
1028 level_pte, level_pfn, start_pfn,
1029 last_pfn);
1030 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001031
David Dillowbc24c572017-06-28 19:42:23 -07001032 /*
1033 * Free the page table if we're below the level we want to
1034 * retain and the range covers the entire table.
1035 */
1036 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001037 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001038 dma_clear_pte(pte);
1039 domain_flush_cache(domain, pte, sizeof(*pte));
1040 free_pgtable_page(level_pte);
1041 }
1042next:
1043 pfn += level_size(level);
1044 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1045}
1046
David Dillowbc24c572017-06-28 19:42:23 -07001047/*
1048 * clear last level (leaf) ptes and free page table pages below the
1049 * level we wish to keep intact.
1050 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001051static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001052 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001053 unsigned long last_pfn,
1054 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001055{
Jiang Liu162d1b12014-07-11 14:19:35 +08001056 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1057 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001058 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001059
Jiang Liud41a4ad2014-07-11 14:19:34 +08001060 dma_pte_clear_range(domain, start_pfn, last_pfn);
1061
David Woodhousef3a0a522009-06-30 03:40:07 +01001062 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001063 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001064 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001065
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001066 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001067 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001068 free_pgtable_page(domain->pgd);
1069 domain->pgd = NULL;
1070 }
1071}
1072
David Woodhouseea8ea462014-03-05 17:09:32 +00001073/* When a page at a given level is being unlinked from its parent, we don't
1074 need to *modify* it at all. All we need to do is make a list of all the
1075 pages which can be freed just as soon as we've flushed the IOTLB and we
1076 know the hardware page-walk will no longer touch them.
1077 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1078 be freed. */
1079static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1080 int level, struct dma_pte *pte,
1081 struct page *freelist)
1082{
1083 struct page *pg;
1084
1085 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1086 pg->freelist = freelist;
1087 freelist = pg;
1088
1089 if (level == 1)
1090 return freelist;
1091
Jiang Liuadeb2592014-04-09 10:20:39 +08001092 pte = page_address(pg);
1093 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001094 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1095 freelist = dma_pte_list_pagetables(domain, level - 1,
1096 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001097 pte++;
1098 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001099
1100 return freelist;
1101}
1102
1103static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1104 struct dma_pte *pte, unsigned long pfn,
1105 unsigned long start_pfn,
1106 unsigned long last_pfn,
1107 struct page *freelist)
1108{
1109 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1110
1111 pfn = max(start_pfn, pfn);
1112 pte = &pte[pfn_level_offset(pfn, level)];
1113
1114 do {
1115 unsigned long level_pfn;
1116
1117 if (!dma_pte_present(pte))
1118 goto next;
1119
1120 level_pfn = pfn & level_mask(level);
1121
1122 /* If range covers entire pagetable, free it */
1123 if (start_pfn <= level_pfn &&
1124 last_pfn >= level_pfn + level_size(level) - 1) {
1125 /* These suborbinate page tables are going away entirely. Don't
1126 bother to clear them; we're just going to *free* them. */
1127 if (level > 1 && !dma_pte_superpage(pte))
1128 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1129
1130 dma_clear_pte(pte);
1131 if (!first_pte)
1132 first_pte = pte;
1133 last_pte = pte;
1134 } else if (level > 1) {
1135 /* Recurse down into a level that isn't *entirely* obsolete */
1136 freelist = dma_pte_clear_level(domain, level - 1,
1137 phys_to_virt(dma_pte_addr(pte)),
1138 level_pfn, start_pfn, last_pfn,
1139 freelist);
1140 }
1141next:
1142 pfn += level_size(level);
1143 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1144
1145 if (first_pte)
1146 domain_flush_cache(domain, first_pte,
1147 (void *)++last_pte - (void *)first_pte);
1148
1149 return freelist;
1150}
1151
1152/* We can't just free the pages because the IOMMU may still be walking
1153 the page tables, and may have cached the intermediate levels. The
1154 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001155static struct page *domain_unmap(struct dmar_domain *domain,
1156 unsigned long start_pfn,
1157 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001158{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001159 struct page *freelist;
David Woodhouseea8ea462014-03-05 17:09:32 +00001160
Jiang Liu162d1b12014-07-11 14:19:35 +08001161 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1162 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001163 BUG_ON(start_pfn > last_pfn);
1164
1165 /* we don't need lock here; nobody else touches the iova range */
1166 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1167 domain->pgd, 0, start_pfn, last_pfn, NULL);
1168
1169 /* free pgd */
1170 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1171 struct page *pgd_page = virt_to_page(domain->pgd);
1172 pgd_page->freelist = freelist;
1173 freelist = pgd_page;
1174
1175 domain->pgd = NULL;
1176 }
1177
1178 return freelist;
1179}
1180
Joerg Roedelb6904202015-08-13 11:32:18 +02001181static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001182{
1183 struct page *pg;
1184
1185 while ((pg = freelist)) {
1186 freelist = pg->freelist;
1187 free_pgtable_page(page_address(pg));
1188 }
1189}
1190
Joerg Roedel13cf0172017-08-11 11:40:10 +02001191static void iova_entry_free(unsigned long data)
1192{
1193 struct page *freelist = (struct page *)data;
1194
1195 dma_free_pagelist(freelist);
1196}
1197
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001198/* iommu handling */
1199static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1200{
1201 struct root_entry *root;
1202 unsigned long flags;
1203
Suresh Siddha4c923d42009-10-02 11:01:24 -07001204 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001205 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001206 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001207 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001208 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001209 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001210
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001211 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001212
1213 spin_lock_irqsave(&iommu->lock, flags);
1214 iommu->root_entry = root;
1215 spin_unlock_irqrestore(&iommu->lock, flags);
1216
1217 return 0;
1218}
1219
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001220static void iommu_set_root_entry(struct intel_iommu *iommu)
1221{
David Woodhouse03ecc322015-02-13 14:35:21 +00001222 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001223 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001224 unsigned long flag;
1225
David Woodhouse03ecc322015-02-13 14:35:21 +00001226 addr = virt_to_phys(iommu->root_entry);
Lu Baolu7373a8c2018-12-10 09:59:03 +08001227 if (sm_supported(iommu))
1228 addr |= DMA_RTADDR_SMT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001229
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001230 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001231 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001232
David Woodhousec416daa2009-05-10 20:30:58 +01001233 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001234
1235 /* Make sure hardware complete it */
1236 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001237 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001238
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001239 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001240}
1241
Lu Baolu6f7db752018-12-10 09:59:00 +08001242void iommu_flush_write_buffer(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001243{
1244 u32 val;
1245 unsigned long flag;
1246
David Woodhouse9af88142009-02-13 23:18:03 +00001247 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001248 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001249
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001250 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001251 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001252
1253 /* Make sure hardware complete it */
1254 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001255 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001256
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001257 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001258}
1259
1260/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001261static void __iommu_flush_context(struct intel_iommu *iommu,
1262 u16 did, u16 source_id, u8 function_mask,
1263 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001264{
1265 u64 val = 0;
1266 unsigned long flag;
1267
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001268 switch (type) {
1269 case DMA_CCMD_GLOBAL_INVL:
1270 val = DMA_CCMD_GLOBAL_INVL;
1271 break;
1272 case DMA_CCMD_DOMAIN_INVL:
1273 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1274 break;
1275 case DMA_CCMD_DEVICE_INVL:
1276 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1277 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1278 break;
1279 default:
1280 BUG();
1281 }
1282 val |= DMA_CCMD_ICC;
1283
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001284 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001285 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1286
1287 /* Make sure hardware complete it */
1288 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1289 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1290
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001291 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001292}
1293
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001294/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001295static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1296 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001297{
1298 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1299 u64 val = 0, val_iva = 0;
1300 unsigned long flag;
1301
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001302 switch (type) {
1303 case DMA_TLB_GLOBAL_FLUSH:
1304 /* global flush doesn't need set IVA_REG */
1305 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1306 break;
1307 case DMA_TLB_DSI_FLUSH:
1308 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1309 break;
1310 case DMA_TLB_PSI_FLUSH:
1311 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001312 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001313 val_iva = size_order | addr;
1314 break;
1315 default:
1316 BUG();
1317 }
1318 /* Note: set drain read/write */
1319#if 0
1320 /*
1321 * This is probably to be super secure.. Looks like we can
1322 * ignore it without any impact.
1323 */
1324 if (cap_read_drain(iommu->cap))
1325 val |= DMA_TLB_READ_DRAIN;
1326#endif
1327 if (cap_write_drain(iommu->cap))
1328 val |= DMA_TLB_WRITE_DRAIN;
1329
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001330 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001331 /* Note: Only uses first TLB reg currently */
1332 if (val_iva)
1333 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1334 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1335
1336 /* Make sure hardware complete it */
1337 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1338 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1339
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001340 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001341
1342 /* check IOTLB invalidation granularity */
1343 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001344 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001345 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001346 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001347 (unsigned long long)DMA_TLB_IIRG(type),
1348 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001349}
1350
David Woodhouse64ae8922014-03-09 12:52:30 -07001351static struct device_domain_info *
1352iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1353 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001354{
Yu Zhao93a23a72009-05-18 13:51:37 +08001355 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001356
Joerg Roedel55d94042015-07-22 16:50:40 +02001357 assert_spin_locked(&device_domain_lock);
1358
Yu Zhao93a23a72009-05-18 13:51:37 +08001359 if (!iommu->qi)
1360 return NULL;
1361
Yu Zhao93a23a72009-05-18 13:51:37 +08001362 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001363 if (info->iommu == iommu && info->bus == bus &&
1364 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001365 if (info->ats_supported && info->dev)
1366 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001367 break;
1368 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001369
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001370 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001371}
1372
Omer Peleg0824c592016-04-20 19:03:35 +03001373static void domain_update_iotlb(struct dmar_domain *domain)
1374{
1375 struct device_domain_info *info;
1376 bool has_iotlb_device = false;
1377
1378 assert_spin_locked(&device_domain_lock);
1379
1380 list_for_each_entry(info, &domain->devices, link) {
1381 struct pci_dev *pdev;
1382
1383 if (!info->dev || !dev_is_pci(info->dev))
1384 continue;
1385
1386 pdev = to_pci_dev(info->dev);
1387 if (pdev->ats_enabled) {
1388 has_iotlb_device = true;
1389 break;
1390 }
1391 }
1392
1393 domain->has_iotlb_device = has_iotlb_device;
1394}
1395
Yu Zhao93a23a72009-05-18 13:51:37 +08001396static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1397{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001398 struct pci_dev *pdev;
1399
Omer Peleg0824c592016-04-20 19:03:35 +03001400 assert_spin_locked(&device_domain_lock);
1401
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001402 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001403 return;
1404
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001405 pdev = to_pci_dev(info->dev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001406 /* For IOMMU that supports device IOTLB throttling (DIT), we assign
1407 * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
1408 * queue depth at PF level. If DIT is not set, PFSID will be treated as
1409 * reserved, which should be set to 0.
1410 */
1411 if (!ecap_dit(info->iommu->ecap))
1412 info->pfsid = 0;
1413 else {
1414 struct pci_dev *pf_pdev;
1415
1416 /* pdev will be returned if device is not a vf */
1417 pf_pdev = pci_physfn(pdev);
Heiner Kallweitcc49baa2019-04-24 21:16:10 +02001418 info->pfsid = pci_dev_id(pf_pdev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001419 }
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001420
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001421#ifdef CONFIG_INTEL_IOMMU_SVM
1422 /* The PCIe spec, in its wisdom, declares that the behaviour of
1423 the device if you enable PASID support after ATS support is
1424 undefined. So always enable PASID support on devices which
1425 have it, even if we can't yet know if we're ever going to
1426 use it. */
1427 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1428 info->pasid_enabled = 1;
1429
Kuppuswamy Sathyanarayanan1b84778a2019-02-19 11:04:52 -08001430 if (info->pri_supported &&
1431 (info->pasid_enabled ? pci_prg_resp_pasid_required(pdev) : 1) &&
1432 !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001433 info->pri_enabled = 1;
1434#endif
Jean-Philippe Bruckerda656a02020-05-20 17:22:03 +02001435 if (info->ats_supported && pci_ats_page_aligned(pdev) &&
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001436 !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001437 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001438 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001439 info->ats_qdep = pci_ats_queue_depth(pdev);
1440 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001441}
1442
1443static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1444{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001445 struct pci_dev *pdev;
1446
Omer Peleg0824c592016-04-20 19:03:35 +03001447 assert_spin_locked(&device_domain_lock);
1448
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001449 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001450 return;
1451
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001452 pdev = to_pci_dev(info->dev);
1453
1454 if (info->ats_enabled) {
1455 pci_disable_ats(pdev);
1456 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001457 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001458 }
1459#ifdef CONFIG_INTEL_IOMMU_SVM
1460 if (info->pri_enabled) {
1461 pci_disable_pri(pdev);
1462 info->pri_enabled = 0;
1463 }
1464 if (info->pasid_enabled) {
1465 pci_disable_pasid(pdev);
1466 info->pasid_enabled = 0;
1467 }
1468#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001469}
1470
1471static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1472 u64 addr, unsigned mask)
1473{
1474 u16 sid, qdep;
1475 unsigned long flags;
1476 struct device_domain_info *info;
1477
Omer Peleg0824c592016-04-20 19:03:35 +03001478 if (!domain->has_iotlb_device)
1479 return;
1480
Yu Zhao93a23a72009-05-18 13:51:37 +08001481 spin_lock_irqsave(&device_domain_lock, flags);
1482 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001483 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001484 continue;
1485
1486 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001487 qdep = info->ats_qdep;
Jacob Pan1c48db42018-06-07 09:57:00 -07001488 qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
1489 qdep, addr, mask);
Yu Zhao93a23a72009-05-18 13:51:37 +08001490 }
1491 spin_unlock_irqrestore(&device_domain_lock, flags);
1492}
1493
Lu Baolu33cd6e62020-01-02 08:18:18 +08001494static void domain_flush_piotlb(struct intel_iommu *iommu,
1495 struct dmar_domain *domain,
1496 u64 addr, unsigned long npages, bool ih)
1497{
1498 u16 did = domain->iommu_did[iommu->seq_id];
1499
1500 if (domain->default_pasid)
1501 qi_flush_piotlb(iommu, did, domain->default_pasid,
1502 addr, npages, ih);
1503
1504 if (!list_empty(&domain->devices))
1505 qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, npages, ih);
1506}
1507
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001508static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1509 struct dmar_domain *domain,
1510 unsigned long pfn, unsigned int pages,
1511 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001512{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001513 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001514 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001515 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001516
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001517 BUG_ON(pages == 0);
1518
David Woodhouseea8ea462014-03-05 17:09:32 +00001519 if (ih)
1520 ih = 1 << 6;
Lu Baolu33cd6e62020-01-02 08:18:18 +08001521
1522 if (domain_use_first_level(domain)) {
1523 domain_flush_piotlb(iommu, domain, addr, pages, ih);
1524 } else {
1525 /*
1526 * Fallback to domain selective flush if no PSI support or
1527 * the size is too big. PSI requires page size to be 2 ^ x,
1528 * and the base address is naturally aligned to the size.
1529 */
1530 if (!cap_pgsel_inv(iommu->cap) ||
1531 mask > cap_max_amask_val(iommu->cap))
1532 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1533 DMA_TLB_DSI_FLUSH);
1534 else
1535 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
1536 DMA_TLB_PSI_FLUSH);
1537 }
Yu Zhaobf92df32009-06-29 11:31:45 +08001538
1539 /*
Nadav Amit82653632010-04-01 13:24:40 +03001540 * In caching mode, changes of pages from non-present to present require
1541 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001542 */
Nadav Amit82653632010-04-01 13:24:40 +03001543 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001544 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001545}
1546
Peter Xueed91a02018-05-04 10:34:52 +08001547/* Notification for newly created mappings */
1548static inline void __mapping_notify_one(struct intel_iommu *iommu,
1549 struct dmar_domain *domain,
1550 unsigned long pfn, unsigned int pages)
1551{
Lu Baolu33cd6e62020-01-02 08:18:18 +08001552 /*
1553 * It's a non-present to present mapping. Only flush if caching mode
1554 * and second level.
1555 */
1556 if (cap_caching_mode(iommu->cap) && !domain_use_first_level(domain))
Peter Xueed91a02018-05-04 10:34:52 +08001557 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1558 else
1559 iommu_flush_write_buffer(iommu);
1560}
1561
Joerg Roedel13cf0172017-08-11 11:40:10 +02001562static void iommu_flush_iova(struct iova_domain *iovad)
1563{
1564 struct dmar_domain *domain;
1565 int idx;
1566
1567 domain = container_of(iovad, struct dmar_domain, iovad);
1568
1569 for_each_domain_iommu(idx, domain) {
1570 struct intel_iommu *iommu = g_iommus[idx];
1571 u16 did = domain->iommu_did[iommu->seq_id];
1572
Lu Baolu33cd6e62020-01-02 08:18:18 +08001573 if (domain_use_first_level(domain))
1574 domain_flush_piotlb(iommu, domain, 0, -1, 0);
1575 else
1576 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1577 DMA_TLB_DSI_FLUSH);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001578
1579 if (!cap_caching_mode(iommu->cap))
1580 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1581 0, MAX_AGAW_PFN_WIDTH);
1582 }
1583}
1584
mark grossf8bab732008-02-08 04:18:38 -08001585static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1586{
1587 u32 pmen;
1588 unsigned long flags;
1589
Lu Baolu5bb71fc72019-03-20 09:58:33 +08001590 if (!cap_plmr(iommu->cap) && !cap_phmr(iommu->cap))
1591 return;
1592
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001593 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001594 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1595 pmen &= ~DMA_PMEN_EPM;
1596 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1597
1598 /* wait for the protected region status bit to clear */
1599 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1600 readl, !(pmen & DMA_PMEN_PRS), pmen);
1601
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001602 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001603}
1604
Jiang Liu2a41cce2014-07-11 14:19:33 +08001605static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001606{
1607 u32 sts;
1608 unsigned long flags;
1609
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001610 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001611 iommu->gcmd |= DMA_GCMD_TE;
1612 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001613
1614 /* Make sure hardware complete it */
1615 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001616 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001617
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001618 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001619}
1620
Jiang Liu2a41cce2014-07-11 14:19:33 +08001621static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001622{
1623 u32 sts;
1624 unsigned long flag;
1625
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001626 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001627 iommu->gcmd &= ~DMA_GCMD_TE;
1628 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1629
1630 /* Make sure hardware complete it */
1631 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001632 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001633
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001634 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001635}
1636
1637static int iommu_init_domains(struct intel_iommu *iommu)
1638{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001639 u32 ndomains, nlongs;
1640 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001641
1642 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001643 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001644 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001645 nlongs = BITS_TO_LONGS(ndomains);
1646
Donald Dutile94a91b502009-08-20 16:51:34 -04001647 spin_lock_init(&iommu->lock);
1648
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001649 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1650 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001651 pr_err("%s: Allocating domain id array failed\n",
1652 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001653 return -ENOMEM;
1654 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001655
Wei Yang86f004c2016-05-21 02:41:51 +00001656 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001657 iommu->domains = kzalloc(size, GFP_KERNEL);
1658
1659 if (iommu->domains) {
1660 size = 256 * sizeof(struct dmar_domain *);
1661 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1662 }
1663
1664 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001665 pr_err("%s: Allocating domain array failed\n",
1666 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001667 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001668 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001669 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001670 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671 return -ENOMEM;
1672 }
1673
1674 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001675 * If Caching mode is set, then invalid translations are tagged
1676 * with domain-id 0, hence we need to pre-allocate it. We also
1677 * use domain-id 0 as a marker for non-allocated domain-id, so
1678 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001679 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001680 set_bit(0, iommu->domain_ids);
1681
Lu Baolu3b33d4a2018-12-10 09:58:59 +08001682 /*
1683 * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid
1684 * entry for first-level or pass-through translation modes should
1685 * be programmed with a domain id different from those used for
1686 * second-level or nested translation. We reserve a domain id for
1687 * this purpose.
1688 */
1689 if (sm_supported(iommu))
1690 set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
1691
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001692 return 0;
1693}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001694
Jiang Liuffebeb42014-11-09 22:48:02 +08001695static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001696{
Joerg Roedel29a27712015-07-21 17:17:12 +02001697 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001698 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001699
Joerg Roedel29a27712015-07-21 17:17:12 +02001700 if (!iommu->domains || !iommu->domain_ids)
1701 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001702
Joerg Roedel55d94042015-07-22 16:50:40 +02001703 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001704 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
Joerg Roedel29a27712015-07-21 17:17:12 +02001705 if (info->iommu != iommu)
1706 continue;
1707
1708 if (!info->dev || !info->domain)
1709 continue;
1710
Joerg Roedelbea64032016-11-08 15:08:26 +01001711 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001712 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001713 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001714
1715 if (iommu->gcmd & DMA_GCMD_TE)
1716 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001717}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001718
Jiang Liuffebeb42014-11-09 22:48:02 +08001719static void free_dmar_iommu(struct intel_iommu *iommu)
1720{
1721 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001722 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001723 int i;
1724
1725 for (i = 0; i < elems; i++)
1726 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001727 kfree(iommu->domains);
1728 kfree(iommu->domain_ids);
1729 iommu->domains = NULL;
1730 iommu->domain_ids = NULL;
1731 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001732
Weidong Hand9630fe2008-12-08 11:06:32 +08001733 g_iommus[iommu->seq_id] = NULL;
1734
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001735 /* free context mapping */
1736 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001737
1738#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08001739 if (pasid_supported(iommu)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01001740 if (ecap_prs(iommu->ecap))
1741 intel_svm_finish_prq(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001742 }
Jacob Pan33753032020-05-16 14:20:51 +08001743 if (ecap_vcs(iommu->ecap) && vccap_pasid(iommu->vccap))
1744 ioasid_unregister_allocator(&iommu->pasid_allocator);
1745
David Woodhouse8a94ade2015-03-24 14:54:56 +00001746#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001747}
1748
Lu Baolua1948f22020-01-02 08:18:14 +08001749/*
1750 * Check and return whether first level is used by default for
Lu Baolub802d072020-01-02 08:18:21 +08001751 * DMA translation.
Lu Baolua1948f22020-01-02 08:18:14 +08001752 */
1753static bool first_level_by_default(void)
1754{
1755 struct dmar_drhd_unit *drhd;
1756 struct intel_iommu *iommu;
Lu Baolub802d072020-01-02 08:18:21 +08001757 static int first_level_support = -1;
Lu Baolua1948f22020-01-02 08:18:14 +08001758
1759 if (likely(first_level_support != -1))
1760 return first_level_support;
1761
1762 first_level_support = 1;
1763
1764 rcu_read_lock();
1765 for_each_active_iommu(iommu, drhd) {
1766 if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
1767 first_level_support = 0;
1768 break;
1769 }
1770 }
1771 rcu_read_unlock();
1772
1773 return first_level_support;
1774}
1775
Jiang Liuab8dfe22014-07-11 14:19:27 +08001776static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001777{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001778 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001779
1780 domain = alloc_domain_mem();
1781 if (!domain)
1782 return NULL;
1783
Jiang Liuab8dfe22014-07-11 14:19:27 +08001784 memset(domain, 0, sizeof(*domain));
Anshuman Khandual98fa15f2019-03-05 15:42:58 -08001785 domain->nid = NUMA_NO_NODE;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001786 domain->flags = flags;
Lu Baolua1948f22020-01-02 08:18:14 +08001787 if (first_level_by_default())
1788 domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
Omer Peleg0824c592016-04-20 19:03:35 +03001789 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001790 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001791
1792 return domain;
1793}
1794
Joerg Roedeld160aca2015-07-22 11:52:53 +02001795/* Must be called with iommu->lock */
1796static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001797 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001798{
Jiang Liu44bde612014-07-11 14:19:29 +08001799 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001800 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001801
Joerg Roedel55d94042015-07-22 16:50:40 +02001802 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001803 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001804
Joerg Roedel29a27712015-07-21 17:17:12 +02001805 domain->iommu_refcnt[iommu->seq_id] += 1;
1806 domain->iommu_count += 1;
1807 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001808 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001809 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1810
1811 if (num >= ndomains) {
1812 pr_err("%s: No free domain ids\n", iommu->name);
1813 domain->iommu_refcnt[iommu->seq_id] -= 1;
1814 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001815 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001816 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001817
Joerg Roedeld160aca2015-07-22 11:52:53 +02001818 set_bit(num, iommu->domain_ids);
1819 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001820
Joerg Roedeld160aca2015-07-22 11:52:53 +02001821 domain->iommu_did[iommu->seq_id] = num;
1822 domain->nid = iommu->node;
1823
Jiang Liufb170fb2014-07-11 14:19:28 +08001824 domain_update_iommu_cap(domain);
1825 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001826
Joerg Roedel55d94042015-07-22 16:50:40 +02001827 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001828}
1829
1830static int domain_detach_iommu(struct dmar_domain *domain,
1831 struct intel_iommu *iommu)
1832{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001833 int num, count;
Jiang Liufb170fb2014-07-11 14:19:28 +08001834
Joerg Roedel55d94042015-07-22 16:50:40 +02001835 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001836 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001837
Joerg Roedel29a27712015-07-21 17:17:12 +02001838 domain->iommu_refcnt[iommu->seq_id] -= 1;
1839 count = --domain->iommu_count;
1840 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001841 num = domain->iommu_did[iommu->seq_id];
1842 clear_bit(num, iommu->domain_ids);
1843 set_iommu_domain(iommu, num, NULL);
1844
Jiang Liufb170fb2014-07-11 14:19:28 +08001845 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001846 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001847 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001848
1849 return count;
1850}
1851
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001852static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001853static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001854
Joseph Cihula51a63e62011-03-21 11:04:24 -07001855static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001856{
1857 struct pci_dev *pdev = NULL;
1858 struct iova *iova;
1859 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001860
Zhen Leiaa3ac942017-09-21 16:52:45 +01001861 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001862
Mark Gross8a443df2008-03-04 14:59:31 -08001863 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1864 &reserved_rbtree_key);
1865
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001866 /* IOAPIC ranges shouldn't be accessed by DMA */
1867 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1868 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001869 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001870 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001871 return -ENODEV;
1872 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001873
1874 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1875 for_each_pci_dev(pdev) {
1876 struct resource *r;
1877
1878 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1879 r = &pdev->resource[i];
1880 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1881 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001882 iova = reserve_iova(&reserved_iova_list,
1883 IOVA_PFN(r->start),
1884 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001885 if (!iova) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06001886 pci_err(pdev, "Reserve iova for %pR failed\n", r);
Joseph Cihula51a63e62011-03-21 11:04:24 -07001887 return -ENODEV;
1888 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001889 }
1890 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001891 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001892}
1893
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001894static inline int guestwidth_to_adjustwidth(int gaw)
1895{
1896 int agaw;
1897 int r = (gaw - 12) % 9;
1898
1899 if (r == 0)
1900 agaw = gaw;
1901 else
1902 agaw = gaw + 9 - r;
1903 if (agaw > 64)
1904 agaw = 64;
1905 return agaw;
1906}
1907
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001908static void domain_exit(struct dmar_domain *domain)
1909{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001910
Joerg Roedeld160aca2015-07-22 11:52:53 +02001911 /* Remove associated devices and clear attached or cached domains */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001912 domain_remove_dev_info(domain);
Jiang Liu92d03cc2014-02-19 14:07:28 +08001913
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001914 /* destroy iovas */
Tom Murphye70b0812020-05-16 14:21:01 +08001915 if (domain->domain.type == IOMMU_DOMAIN_DMA)
1916 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001917
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001918 if (domain->pgd) {
1919 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001920
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001921 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
1922 dma_free_pagelist(freelist);
1923 }
David Woodhouseea8ea462014-03-05 17:09:32 +00001924
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001925 free_domain_mem(domain);
1926}
1927
Lu Baolu7373a8c2018-12-10 09:59:03 +08001928/*
1929 * Get the PASID directory size for scalable mode context entry.
1930 * Value of X in the PDTS field of a scalable mode context entry
1931 * indicates PASID directory with 2^(X + 7) entries.
1932 */
1933static inline unsigned long context_get_sm_pds(struct pasid_table *table)
1934{
1935 int pds, max_pde;
1936
1937 max_pde = table->max_pasid >> PASID_PDE_SHIFT;
1938 pds = find_first_bit((unsigned long *)&max_pde, MAX_NR_PASID_BITS);
1939 if (pds < 7)
1940 return 0;
1941
1942 return pds - 7;
1943}
1944
1945/*
1946 * Set the RID_PASID field of a scalable mode context entry. The
1947 * IOMMU hardware will use the PASID value set in this field for
1948 * DMA translations of DMA requests without PASID.
1949 */
1950static inline void
1951context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
1952{
1953 context->hi |= pasid & ((1 << 20) - 1);
Lu Baolu7373a8c2018-12-10 09:59:03 +08001954}
1955
1956/*
1957 * Set the DTE(Device-TLB Enable) field of a scalable mode context
1958 * entry.
1959 */
1960static inline void context_set_sm_dte(struct context_entry *context)
1961{
1962 context->lo |= (1 << 2);
1963}
1964
1965/*
1966 * Set the PRE(Page Request Enable) field of a scalable mode context
1967 * entry.
1968 */
1969static inline void context_set_sm_pre(struct context_entry *context)
1970{
1971 context->lo |= (1 << 4);
1972}
1973
1974/* Convert value to context PASID directory size field coding. */
1975#define context_pdts(pds) (((pds) & 0x7) << 9)
1976
David Woodhouse64ae8922014-03-09 12:52:30 -07001977static int domain_context_mapping_one(struct dmar_domain *domain,
1978 struct intel_iommu *iommu,
Lu Baoluca6e3222018-12-10 09:59:02 +08001979 struct pasid_table *table,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001980 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001982 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02001983 int translation = CONTEXT_TT_MULTI_LEVEL;
1984 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001985 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 unsigned long flags;
Lu Baolu7373a8c2018-12-10 09:59:03 +08001987 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02001988
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001989 WARN_ON(did == 0);
1990
Joerg Roedel28ccce02015-07-21 14:45:31 +02001991 if (hw_pass_through && domain_type_is_si(domain))
1992 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001993
1994 pr_debug("Set context mapping for %02x:%02x.%d\n",
1995 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07001996
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001997 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08001998
Joerg Roedel55d94042015-07-22 16:50:40 +02001999 spin_lock_irqsave(&device_domain_lock, flags);
2000 spin_lock(&iommu->lock);
2001
2002 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002003 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002005 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002006
Joerg Roedel55d94042015-07-22 16:50:40 +02002007 ret = 0;
2008 if (context_present(context))
2009 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002010
Xunlei Pangaec0e862016-12-05 20:09:07 +08002011 /*
2012 * For kdump cases, old valid entries may be cached due to the
2013 * in-flight DMA and copied pgtable, but there is no unmapping
2014 * behaviour for them, thus we need an explicit cache flush for
2015 * the newly-mapped device. For kdump, at this point, the device
2016 * is supposed to finish reset at its driver probe stage, so no
2017 * in-flight DMA will exist, and we don't need to worry anymore
2018 * hereafter.
2019 */
2020 if (context_copied(context)) {
2021 u16 did_old = context_domain_id(context);
2022
Christos Gkekasb117e032017-10-08 23:33:31 +01002023 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002024 iommu->flush.flush_context(iommu, did_old,
2025 (((u16)bus) << 8) | devfn,
2026 DMA_CCMD_MASK_NOBIT,
2027 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002028 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2029 DMA_TLB_DSI_FLUSH);
2030 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002031 }
2032
Joerg Roedelde24e552015-07-21 14:53:04 +02002033 context_clear_entry(context);
Weidong Hanea6606b2008-12-08 23:08:15 +08002034
Lu Baolu7373a8c2018-12-10 09:59:03 +08002035 if (sm_supported(iommu)) {
2036 unsigned long pds;
Joerg Roedelde24e552015-07-21 14:53:04 +02002037
Lu Baolu7373a8c2018-12-10 09:59:03 +08002038 WARN_ON(!table);
2039
2040 /* Setup the PASID DIR pointer: */
2041 pds = context_get_sm_pds(table);
2042 context->lo = (u64)virt_to_phys(table->table) |
2043 context_pdts(pds);
2044
2045 /* Setup the RID_PASID field: */
2046 context_set_sm_rid2pasid(context, PASID_RID2PASID);
2047
2048 /*
2049 * Setup the Device-TLB enable bit and Page request
2050 * Enable bit:
2051 */
David Woodhouse64ae8922014-03-09 12:52:30 -07002052 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002053 if (info && info->ats_supported)
Lu Baolu7373a8c2018-12-10 09:59:03 +08002054 context_set_sm_dte(context);
2055 if (info && info->pri_supported)
2056 context_set_sm_pre(context);
Joerg Roedelde24e552015-07-21 14:53:04 +02002057 } else {
Lu Baolu7373a8c2018-12-10 09:59:03 +08002058 struct dma_pte *pgd = domain->pgd;
2059 int agaw;
2060
2061 context_set_domain_id(context, did);
Lu Baolu7373a8c2018-12-10 09:59:03 +08002062
2063 if (translation != CONTEXT_TT_PASS_THROUGH) {
2064 /*
2065 * Skip top levels of page tables for iommu which has
2066 * less agaw than default. Unnecessary for PT mode.
2067 */
2068 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2069 ret = -ENOMEM;
2070 pgd = phys_to_virt(dma_pte_addr(pgd));
2071 if (!dma_pte_present(pgd))
2072 goto out_unlock;
2073 }
2074
2075 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
2076 if (info && info->ats_supported)
2077 translation = CONTEXT_TT_DEV_IOTLB;
2078 else
2079 translation = CONTEXT_TT_MULTI_LEVEL;
2080
2081 context_set_address_root(context, virt_to_phys(pgd));
2082 context_set_address_width(context, agaw);
2083 } else {
2084 /*
2085 * In pass through mode, AW must be programmed to
2086 * indicate the largest AGAW value supported by
2087 * hardware. And ASR is ignored by hardware.
2088 */
2089 context_set_address_width(context, iommu->msagaw);
2090 }
Lu Baolu41b80db2019-03-01 11:23:11 +08002091
2092 context_set_translation_type(context, translation);
Yu Zhao93a23a72009-05-18 13:51:37 +08002093 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002094
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002095 context_set_fault_enable(context);
2096 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002097 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002098
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002099 /*
2100 * It's a non-present to present mapping. If hardware doesn't cache
2101 * non-present entry we only need to flush the write-buffer. If the
2102 * _does_ cache non-present entries, then it does so in the special
2103 * domain #0, which we have to flush:
2104 */
2105 if (cap_caching_mode(iommu->cap)) {
2106 iommu->flush.flush_context(iommu, 0,
2107 (((u16)bus) << 8) | devfn,
2108 DMA_CCMD_MASK_NOBIT,
2109 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002110 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002111 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002112 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002113 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002114 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002115
Joerg Roedel55d94042015-07-22 16:50:40 +02002116 ret = 0;
2117
2118out_unlock:
2119 spin_unlock(&iommu->lock);
2120 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002121
Wei Yang5c365d12016-07-13 13:53:21 +00002122 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002123}
2124
Lu Baolu0ce4a852019-08-26 16:50:56 +08002125struct domain_context_mapping_data {
2126 struct dmar_domain *domain;
2127 struct intel_iommu *iommu;
2128 struct pasid_table *table;
2129};
2130
2131static int domain_context_mapping_cb(struct pci_dev *pdev,
2132 u16 alias, void *opaque)
2133{
2134 struct domain_context_mapping_data *data = opaque;
2135
2136 return domain_context_mapping_one(data->domain, data->iommu,
2137 data->table, PCI_BUS_NUM(alias),
2138 alias & 0xff);
2139}
2140
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002141static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002142domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002143{
Lu Baolu0ce4a852019-08-26 16:50:56 +08002144 struct domain_context_mapping_data data;
Lu Baoluca6e3222018-12-10 09:59:02 +08002145 struct pasid_table *table;
David Woodhouse64ae8922014-03-09 12:52:30 -07002146 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002147 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002148
David Woodhousee1f167f2014-03-09 15:24:46 -07002149 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002150 if (!iommu)
2151 return -ENODEV;
2152
Lu Baoluca6e3222018-12-10 09:59:02 +08002153 table = intel_pasid_get_table(dev);
Lu Baolu0ce4a852019-08-26 16:50:56 +08002154
2155 if (!dev_is_pci(dev))
2156 return domain_context_mapping_one(domain, iommu, table,
2157 bus, devfn);
2158
2159 data.domain = domain;
2160 data.iommu = iommu;
2161 data.table = table;
2162
2163 return pci_for_each_dma_alias(to_pci_dev(dev),
2164 &domain_context_mapping_cb, &data);
Alex Williamson579305f2014-07-03 09:51:43 -06002165}
2166
2167static int domain_context_mapped_cb(struct pci_dev *pdev,
2168 u16 alias, void *opaque)
2169{
2170 struct intel_iommu *iommu = opaque;
2171
2172 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002173}
2174
David Woodhousee1f167f2014-03-09 15:24:46 -07002175static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002176{
Weidong Han5331fe62008-12-08 23:00:00 +08002177 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002178 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002179
David Woodhousee1f167f2014-03-09 15:24:46 -07002180 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002181 if (!iommu)
2182 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002183
Alex Williamson579305f2014-07-03 09:51:43 -06002184 if (!dev_is_pci(dev))
2185 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002186
Alex Williamson579305f2014-07-03 09:51:43 -06002187 return !pci_for_each_dma_alias(to_pci_dev(dev),
2188 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002189}
2190
Fenghua Yuf5329592009-08-04 15:09:37 -07002191/* Returns a number of VTD pages, but aligned to MM page size */
2192static inline unsigned long aligned_nrpages(unsigned long host_addr,
2193 size_t size)
2194{
2195 host_addr &= ~PAGE_MASK;
2196 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2197}
2198
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002199/* Return largest possible superpage level for a given mapping */
2200static inline int hardware_largepage_caps(struct dmar_domain *domain,
2201 unsigned long iov_pfn,
2202 unsigned long phy_pfn,
2203 unsigned long pages)
2204{
2205 int support, level = 1;
2206 unsigned long pfnmerge;
2207
2208 support = domain->iommu_superpage;
2209
2210 /* To use a large page, the virtual *and* physical addresses
2211 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2212 of them will mean we have to use smaller pages. So just
2213 merge them and check both at once. */
2214 pfnmerge = iov_pfn | phy_pfn;
2215
2216 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2217 pages >>= VTD_STRIDE_SHIFT;
2218 if (!pages)
2219 break;
2220 pfnmerge >>= VTD_STRIDE_SHIFT;
2221 level++;
2222 support--;
2223 }
2224 return level;
2225}
2226
David Woodhouse9051aa02009-06-29 12:30:54 +01002227static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2228 struct scatterlist *sg, unsigned long phys_pfn,
2229 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002230{
2231 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002232 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002233 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002234 unsigned int largepage_lvl = 0;
2235 unsigned long lvl_pages = 0;
Lu Baoluddf09b62020-01-02 08:18:17 +08002236 u64 attr;
David Woodhousee1605492009-06-29 11:17:38 +01002237
Jiang Liu162d1b12014-07-11 14:19:35 +08002238 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002239
2240 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2241 return -EINVAL;
2242
Lu Baoluddf09b62020-01-02 08:18:17 +08002243 attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
2244 if (domain_use_first_level(domain))
Lu Baolu16ecf102020-06-23 07:13:41 +08002245 attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD | DMA_FL_PTE_US;
David Woodhousee1605492009-06-29 11:17:38 +01002246
Jiang Liucc4f14a2014-11-26 09:42:10 +08002247 if (!sg) {
2248 sg_res = nr_pages;
Lu Baoluddf09b62020-01-02 08:18:17 +08002249 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
David Woodhouse9051aa02009-06-29 12:30:54 +01002250 }
2251
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002252 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002253 uint64_t tmp;
2254
David Woodhousee1605492009-06-29 11:17:38 +01002255 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002256 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2257
Fenghua Yuf5329592009-08-04 15:09:37 -07002258 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002259 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002260 sg->dma_length = sg->length;
Lu Baoluddf09b62020-01-02 08:18:17 +08002261 pteval = (sg_phys(sg) - pgoff) | attr;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002263 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002264
David Woodhousee1605492009-06-29 11:17:38 +01002265 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002266 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2267
David Woodhouse5cf0a762014-03-19 16:07:49 +00002268 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002269 if (!pte)
2270 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002271 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002272 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002273 unsigned long nr_superpages, end_pfn;
2274
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002275 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002276 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002277
2278 nr_superpages = sg_res / lvl_pages;
2279 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2280
Jiang Liud41a4ad2014-07-11 14:19:34 +08002281 /*
2282 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002283 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002284 * We're adding new large pages, so make sure
2285 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002286 */
David Dillowbc24c572017-06-28 19:42:23 -07002287 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2288 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002289 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002290 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002291 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002292
David Woodhousee1605492009-06-29 11:17:38 +01002293 }
2294 /* We don't need lock here, nobody else
2295 * touches the iova range
2296 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002297 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002298 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002299 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002300 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2301 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002302 if (dumps) {
2303 dumps--;
2304 debug_dma_dump_mappings(NULL);
2305 }
2306 WARN_ON(1);
2307 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002308
2309 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2310
2311 BUG_ON(nr_pages < lvl_pages);
2312 BUG_ON(sg_res < lvl_pages);
2313
2314 nr_pages -= lvl_pages;
2315 iov_pfn += lvl_pages;
2316 phys_pfn += lvl_pages;
2317 pteval += lvl_pages * VTD_PAGE_SIZE;
2318 sg_res -= lvl_pages;
2319
2320 /* If the next PTE would be the first in a new page, then we
2321 need to flush the cache on the entries we've just written.
2322 And then we'll need to recalculate 'pte', so clear it and
2323 let it get set again in the if (!pte) block above.
2324
2325 If we're done (!nr_pages) we need to flush the cache too.
2326
2327 Also if we've been setting superpages, we may need to
2328 recalculate 'pte' and switch back to smaller pages for the
2329 end of the mapping, if the trailing size is not enough to
2330 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002331 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002332 if (!nr_pages || first_pte_in_page(pte) ||
2333 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002334 domain_flush_cache(domain, first_pte,
2335 (void *)pte - (void *)first_pte);
2336 pte = NULL;
2337 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002338
2339 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002340 sg = sg_next(sg);
2341 }
2342 return 0;
2343}
2344
Peter Xu87684fd2018-05-04 10:34:53 +08002345static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
Lu Baolu095303e2019-04-29 09:16:02 +08002346 struct scatterlist *sg, unsigned long phys_pfn,
2347 unsigned long nr_pages, int prot)
Peter Xu87684fd2018-05-04 10:34:53 +08002348{
Lu Baolufa954e62019-05-25 13:41:28 +08002349 int iommu_id, ret;
Lu Baolu095303e2019-04-29 09:16:02 +08002350 struct intel_iommu *iommu;
Peter Xu87684fd2018-05-04 10:34:53 +08002351
Lu Baolu095303e2019-04-29 09:16:02 +08002352 /* Do the real mapping first */
2353 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2354 if (ret)
2355 return ret;
Peter Xu87684fd2018-05-04 10:34:53 +08002356
Lu Baolufa954e62019-05-25 13:41:28 +08002357 for_each_domain_iommu(iommu_id, domain) {
2358 iommu = g_iommus[iommu_id];
Lu Baolu095303e2019-04-29 09:16:02 +08002359 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2360 }
2361
2362 return 0;
Peter Xu87684fd2018-05-04 10:34:53 +08002363}
2364
David Woodhouse9051aa02009-06-29 12:30:54 +01002365static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2366 struct scatterlist *sg, unsigned long nr_pages,
2367 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002368{
Peter Xu87684fd2018-05-04 10:34:53 +08002369 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002370}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002371
David Woodhouse9051aa02009-06-29 12:30:54 +01002372static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2373 unsigned long phys_pfn, unsigned long nr_pages,
2374 int prot)
2375{
Peter Xu87684fd2018-05-04 10:34:53 +08002376 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002377}
2378
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002379static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002380{
Filippo Sironi50822192017-08-31 10:58:11 +02002381 unsigned long flags;
2382 struct context_entry *context;
2383 u16 did_old;
2384
Weidong Hanc7151a82008-12-08 22:51:37 +08002385 if (!iommu)
2386 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002387
Filippo Sironi50822192017-08-31 10:58:11 +02002388 spin_lock_irqsave(&iommu->lock, flags);
2389 context = iommu_context_addr(iommu, bus, devfn, 0);
2390 if (!context) {
2391 spin_unlock_irqrestore(&iommu->lock, flags);
2392 return;
2393 }
2394 did_old = context_domain_id(context);
2395 context_clear_entry(context);
2396 __iommu_flush_cache(iommu, context, sizeof(*context));
2397 spin_unlock_irqrestore(&iommu->lock, flags);
2398 iommu->flush.flush_context(iommu,
2399 did_old,
2400 (((u16)bus) << 8) | devfn,
2401 DMA_CCMD_MASK_NOBIT,
2402 DMA_CCMD_DEVICE_INVL);
2403 iommu->flush.flush_iotlb(iommu,
2404 did_old,
2405 0,
2406 0,
2407 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002408}
2409
David Woodhouse109b9b02012-05-25 17:43:02 +01002410static inline void unlink_domain_info(struct device_domain_info *info)
2411{
2412 assert_spin_locked(&device_domain_lock);
2413 list_del(&info->link);
2414 list_del(&info->global);
2415 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002416 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002417}
2418
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002419static void domain_remove_dev_info(struct dmar_domain *domain)
2420{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002421 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002422 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002423
2424 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002425 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002426 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002427 spin_unlock_irqrestore(&device_domain_lock, flags);
2428}
2429
Lu Baolue2726da2020-01-02 08:18:22 +08002430struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002431{
2432 struct device_domain_info *info;
2433
Joerg Roedel1d46159782020-02-17 17:12:37 +01002434 if (unlikely(attach_deferred(dev) || iommu_dummy(dev)))
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002435 return NULL;
2436
2437 /* No lock here, assumes no domain exit in normal case */
Lu Baolue85bb992020-05-16 14:20:52 +08002438 info = get_domain_info(dev);
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002439 if (likely(info))
2440 return info->domain;
2441
2442 return NULL;
2443}
2444
Joerg Roedel034d98c2020-02-17 17:16:19 +01002445static void do_deferred_attach(struct device *dev)
2446{
2447 struct iommu_domain *domain;
2448
2449 dev->archdata.iommu = NULL;
2450 domain = iommu_get_domain_for_dev(dev);
2451 if (domain)
2452 intel_iommu_attach_device(domain, dev);
2453}
2454
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002455static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002456dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2457{
2458 struct device_domain_info *info;
2459
2460 list_for_each_entry(info, &device_domain_list, global)
Jon Derrick4fda2302020-05-27 10:56:16 -06002461 if (info->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002462 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002463 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002464
2465 return NULL;
2466}
2467
Lu Baoluddf09b62020-01-02 08:18:17 +08002468static int domain_setup_first_level(struct intel_iommu *iommu,
2469 struct dmar_domain *domain,
2470 struct device *dev,
2471 int pasid)
2472{
2473 int flags = PASID_FLAG_SUPERVISOR_MODE;
2474 struct dma_pte *pgd = domain->pgd;
2475 int agaw, level;
2476
2477 /*
2478 * Skip top levels of page tables for iommu which has
2479 * less agaw than default. Unnecessary for PT mode.
2480 */
2481 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2482 pgd = phys_to_virt(dma_pte_addr(pgd));
2483 if (!dma_pte_present(pgd))
2484 return -ENOMEM;
2485 }
2486
2487 level = agaw_to_level(agaw);
2488 if (level != 4 && level != 5)
2489 return -EINVAL;
2490
2491 flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;
2492
2493 return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,
2494 domain->iommu_did[iommu->seq_id],
2495 flags);
2496}
2497
Jon Derrick8038bdb2020-05-27 10:56:15 -06002498static bool dev_is_real_dma_subdevice(struct device *dev)
2499{
2500 return dev && dev_is_pci(dev) &&
2501 pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev);
2502}
2503
Joerg Roedel5db31562015-07-22 12:40:43 +02002504static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2505 int bus, int devfn,
2506 struct device *dev,
2507 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002508{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002509 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002510 struct device_domain_info *info;
2511 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002512 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002513
2514 info = alloc_devinfo_mem();
2515 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002516 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002517
Jon Derrick4fda2302020-05-27 10:56:16 -06002518 if (!dev_is_real_dma_subdevice(dev)) {
2519 info->bus = bus;
2520 info->devfn = devfn;
2521 info->segment = iommu->segment;
2522 } else {
2523 struct pci_dev *pdev = to_pci_dev(dev);
2524
2525 info->bus = pdev->bus->number;
2526 info->devfn = pdev->devfn;
2527 info->segment = pci_domain_nr(pdev->bus);
2528 }
2529
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002530 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2531 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2532 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002533 info->dev = dev;
2534 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002535 info->iommu = iommu;
Lu Baolucc580e42018-07-14 15:46:59 +08002536 info->pasid_table = NULL;
Lu Baolu95587a72019-03-25 09:30:30 +08002537 info->auxd_enabled = 0;
Lu Baolu67b8e022019-03-25 09:30:32 +08002538 INIT_LIST_HEAD(&info->auxiliary_domains);
Jiang Liu745f2582014-02-19 14:07:26 +08002539
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002540 if (dev && dev_is_pci(dev)) {
2541 struct pci_dev *pdev = to_pci_dev(info->dev);
2542
Jean-Philippe Bruckerda656a02020-05-20 17:22:03 +02002543 if (ecap_dev_iotlb_support(iommu->ecap) &&
2544 pci_ats_supported(pdev) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002545 dmar_find_matched_atsr_unit(pdev))
2546 info->ats_supported = 1;
2547
Lu Baolu765b6a92018-12-10 09:58:55 +08002548 if (sm_supported(iommu)) {
2549 if (pasid_supported(iommu)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002550 int features = pci_pasid_features(pdev);
2551 if (features >= 0)
2552 info->pasid_supported = features | 1;
2553 }
2554
2555 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2556 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2557 info->pri_supported = 1;
2558 }
2559 }
2560
Jiang Liu745f2582014-02-19 14:07:26 +08002561 spin_lock_irqsave(&device_domain_lock, flags);
2562 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002563 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002564
2565 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002566 struct device_domain_info *info2;
Jon Derrick4fda2302020-05-27 10:56:16 -06002567 info2 = dmar_search_domain_by_dev_info(info->segment, info->bus,
2568 info->devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002569 if (info2) {
2570 found = info2->domain;
2571 info2->dev = dev;
2572 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002573 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002574
Jiang Liu745f2582014-02-19 14:07:26 +08002575 if (found) {
2576 spin_unlock_irqrestore(&device_domain_lock, flags);
2577 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002578 /* Caller must free the original domain */
2579 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002580 }
2581
Joerg Roedeld160aca2015-07-22 11:52:53 +02002582 spin_lock(&iommu->lock);
2583 ret = domain_attach_iommu(domain, iommu);
2584 spin_unlock(&iommu->lock);
2585
2586 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002587 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302588 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002589 return NULL;
2590 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002591
David Woodhouseb718cd32014-03-09 13:11:33 -07002592 list_add(&info->link, &domain->devices);
2593 list_add(&info->global, &device_domain_list);
2594 if (dev)
2595 dev->archdata.iommu = info;
Lu Baolu0bbeb012018-12-10 09:58:56 +08002596 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolua7fc93f2018-07-14 15:47:00 +08002597
Lu Baolu0bbeb012018-12-10 09:58:56 +08002598 /* PASID table is mandatory for a PCI device in scalable mode. */
2599 if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
Lu Baolua7fc93f2018-07-14 15:47:00 +08002600 ret = intel_pasid_alloc_table(dev);
2601 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002602 dev_err(dev, "PASID table allocation failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002603 dmar_remove_one_dev_info(dev);
Lu Baolu0bbeb012018-12-10 09:58:56 +08002604 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002605 }
Lu Baoluef848b72018-12-10 09:59:01 +08002606
2607 /* Setup the PASID entry for requests without PASID: */
2608 spin_lock(&iommu->lock);
2609 if (hw_pass_through && domain_type_is_si(domain))
2610 ret = intel_pasid_setup_pass_through(iommu, domain,
2611 dev, PASID_RID2PASID);
Lu Baoluddf09b62020-01-02 08:18:17 +08002612 else if (domain_use_first_level(domain))
2613 ret = domain_setup_first_level(iommu, domain, dev,
2614 PASID_RID2PASID);
Lu Baoluef848b72018-12-10 09:59:01 +08002615 else
2616 ret = intel_pasid_setup_second_level(iommu, domain,
2617 dev, PASID_RID2PASID);
2618 spin_unlock(&iommu->lock);
2619 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002620 dev_err(dev, "Setup RID2PASID failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002621 dmar_remove_one_dev_info(dev);
Lu Baoluef848b72018-12-10 09:59:01 +08002622 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002623 }
2624 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002625
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002626 if (dev && domain_context_mapping(domain, dev)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002627 dev_err(dev, "Domain context map failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002628 dmar_remove_one_dev_info(dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002629 return NULL;
2630 }
2631
David Woodhouseb718cd32014-03-09 13:11:33 -07002632 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002633}
2634
David Woodhouseb2132032009-06-26 18:50:28 +01002635static int iommu_domain_identity_map(struct dmar_domain *domain,
Tom Murphye70b0812020-05-16 14:21:01 +08002636 unsigned long first_vpfn,
2637 unsigned long last_vpfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002638{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002639 /*
2640 * RMRR range might have overlap with physical memory range,
2641 * clear it first
2642 */
David Woodhousec5395d52009-06-28 16:35:56 +01002643 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002644
Peter Xu87684fd2018-05-04 10:34:53 +08002645 return __domain_mapping(domain, first_vpfn, NULL,
2646 first_vpfn, last_vpfn - first_vpfn + 1,
2647 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002648}
2649
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002650static int md_domain_init(struct dmar_domain *domain, int guest_width);
2651
Matt Kraai071e1372009-08-23 22:30:22 -07002652static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002653{
Lu Baolu4de354e2019-05-25 13:41:27 +08002654 struct dmar_rmrr_unit *rmrr;
2655 struct device *dev;
2656 int i, nid, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002657
Jiang Liuab8dfe22014-07-11 14:19:27 +08002658 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002659 if (!si_domain)
2660 return -EFAULT;
2661
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002662 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002663 domain_exit(si_domain);
2664 return -EFAULT;
2665 }
2666
David Woodhouse19943b02009-08-04 16:19:20 +01002667 if (hw)
2668 return 0;
2669
David Woodhousec7ab48d2009-06-26 19:10:36 +01002670 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002671 unsigned long start_pfn, end_pfn;
2672 int i;
2673
2674 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2675 ret = iommu_domain_identity_map(si_domain,
Tom Murphye70b0812020-05-16 14:21:01 +08002676 mm_to_dma_pfn(start_pfn),
2677 mm_to_dma_pfn(end_pfn));
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002678 if (ret)
2679 return ret;
2680 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002681 }
2682
Lu Baolu4de354e2019-05-25 13:41:27 +08002683 /*
Lu Baolu9235cb132020-01-15 11:03:58 +08002684 * Identity map the RMRRs so that devices with RMRRs could also use
2685 * the si_domain.
Lu Baolu4de354e2019-05-25 13:41:27 +08002686 */
2687 for_each_rmrr_units(rmrr) {
2688 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
2689 i, dev) {
2690 unsigned long long start = rmrr->base_address;
2691 unsigned long long end = rmrr->end_address;
2692
Lu Baolu4de354e2019-05-25 13:41:27 +08002693 if (WARN_ON(end < start ||
2694 end >> agaw_to_width(si_domain->agaw)))
2695 continue;
2696
2697 ret = iommu_domain_identity_map(si_domain, start, end);
2698 if (ret)
2699 return ret;
2700 }
2701 }
2702
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002703 return 0;
2704}
2705
Joerg Roedel28ccce02015-07-21 14:45:31 +02002706static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002707{
David Woodhouse0ac72662014-03-09 13:19:22 -07002708 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002709 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002710 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002711
David Woodhouse5913c9b2014-03-09 16:27:31 -07002712 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002713 if (!iommu)
2714 return -ENODEV;
2715
Joerg Roedel5db31562015-07-22 12:40:43 +02002716 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002717 if (ndomain != domain)
2718 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002719
2720 return 0;
2721}
2722
David Woodhouse0b9d9752014-03-09 15:48:15 -07002723static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002724{
2725 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002726 struct device *tmp;
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002727 int i;
2728
Jiang Liu0e242612014-02-19 14:07:34 +08002729 rcu_read_lock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002730 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002731 /*
2732 * Return TRUE if this RMRR contains the device that
2733 * is passed in.
2734 */
2735 for_each_active_dev_scope(rmrr->devices,
2736 rmrr->devices_cnt, i, tmp)
Eric Augere143fd42019-06-03 08:53:33 +02002737 if (tmp == dev ||
2738 is_downstream_to_pci_bridge(dev, tmp)) {
Jiang Liu0e242612014-02-19 14:07:34 +08002739 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002740 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002741 }
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002742 }
Jiang Liu0e242612014-02-19 14:07:34 +08002743 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002744 return false;
2745}
2746
Eric Auger1c5c59f2019-06-03 08:53:36 +02002747/**
2748 * device_rmrr_is_relaxable - Test whether the RMRR of this device
2749 * is relaxable (ie. is allowed to be not enforced under some conditions)
2750 * @dev: device handle
2751 *
2752 * We assume that PCI USB devices with RMRRs have them largely
2753 * for historical reasons and that the RMRR space is not actively used post
2754 * boot. This exclusion may change if vendors begin to abuse it.
2755 *
2756 * The same exception is made for graphics devices, with the requirement that
2757 * any use of the RMRR regions will be torn down before assigning the device
2758 * to a guest.
2759 *
2760 * Return: true if the RMRR is relaxable, false otherwise
2761 */
2762static bool device_rmrr_is_relaxable(struct device *dev)
2763{
2764 struct pci_dev *pdev;
2765
2766 if (!dev_is_pci(dev))
2767 return false;
2768
2769 pdev = to_pci_dev(dev);
2770 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
2771 return true;
2772 else
2773 return false;
2774}
2775
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002776/*
2777 * There are a couple cases where we need to restrict the functionality of
2778 * devices associated with RMRRs. The first is when evaluating a device for
2779 * identity mapping because problems exist when devices are moved in and out
2780 * of domains and their respective RMRR information is lost. This means that
2781 * a device with associated RMRRs will never be in a "passthrough" domain.
2782 * The second is use of the device through the IOMMU API. This interface
2783 * expects to have full control of the IOVA space for the device. We cannot
2784 * satisfy both the requirement that RMRR access is maintained and have an
2785 * unencumbered IOVA space. We also have no ability to quiesce the device's
2786 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2787 * We therefore prevent devices associated with an RMRR from participating in
2788 * the IOMMU API, which eliminates them from device assignment.
2789 *
Eric Auger1c5c59f2019-06-03 08:53:36 +02002790 * In both cases, devices which have relaxable RMRRs are not concerned by this
2791 * restriction. See device_rmrr_is_relaxable comment.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002792 */
2793static bool device_is_rmrr_locked(struct device *dev)
2794{
2795 if (!device_has_rmrr(dev))
2796 return false;
2797
Eric Auger1c5c59f2019-06-03 08:53:36 +02002798 if (device_rmrr_is_relaxable(dev))
2799 return false;
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002800
2801 return true;
2802}
2803
Lu Baoluf273a452019-05-25 13:41:26 +08002804/*
2805 * Return the required default domain type for a specific device.
2806 *
2807 * @dev: the device in query
2808 * @startup: true if this is during early boot
2809 *
2810 * Returns:
2811 * - IOMMU_DOMAIN_DMA: device requires a dynamic mapping domain
2812 * - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
2813 * - 0: both identity and dynamic domains work for this device
2814 */
Lu Baolu0e31a722019-05-25 13:41:34 +08002815static int device_def_domain_type(struct device *dev)
David Woodhouse6941af22009-07-04 18:24:27 +01002816{
David Woodhouse3bdb2592014-03-09 16:03:08 -07002817 if (dev_is_pci(dev)) {
2818 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002819
Lu Baolu89a60792018-10-23 15:45:01 +08002820 /*
2821 * Prevent any device marked as untrusted from getting
2822 * placed into the statically identity mapping domain.
2823 */
2824 if (pdev->untrusted)
Lu Baoluf273a452019-05-25 13:41:26 +08002825 return IOMMU_DOMAIN_DMA;
Lu Baolu89a60792018-10-23 15:45:01 +08002826
David Woodhouse3bdb2592014-03-09 16:03:08 -07002827 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002828 return IOMMU_DOMAIN_IDENTITY;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002829
David Woodhouse3bdb2592014-03-09 16:03:08 -07002830 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002831 return IOMMU_DOMAIN_IDENTITY;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002832 }
David Woodhouse6941af22009-07-04 18:24:27 +01002833
Lu Baolub89b6602020-01-15 11:03:59 +08002834 return 0;
Lu Baoluf273a452019-05-25 13:41:26 +08002835}
2836
Jiang Liuffebeb42014-11-09 22:48:02 +08002837static void intel_iommu_init_qi(struct intel_iommu *iommu)
2838{
2839 /*
2840 * Start from the sane iommu hardware state.
2841 * If the queued invalidation is already initialized by us
2842 * (for example, while enabling interrupt-remapping) then
2843 * we got the things already rolling from a sane state.
2844 */
2845 if (!iommu->qi) {
2846 /*
2847 * Clear any previous faults.
2848 */
2849 dmar_fault(-1, iommu);
2850 /*
2851 * Disable queued invalidation if supported and already enabled
2852 * before OS handover.
2853 */
2854 dmar_disable_qi(iommu);
2855 }
2856
2857 if (dmar_enable_qi(iommu)) {
2858 /*
2859 * Queued Invalidate not enabled, use Register Based Invalidate
2860 */
2861 iommu->flush.flush_context = __iommu_flush_context;
2862 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002863 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08002864 iommu->name);
2865 } else {
2866 iommu->flush.flush_context = qi_flush_context;
2867 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002868 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08002869 }
2870}
2871
Joerg Roedel091d42e2015-06-12 11:56:10 +02002872static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb962015-10-09 18:16:46 -04002873 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02002874 struct context_entry **tbl,
2875 int bus, bool ext)
2876{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02002877 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002878 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb962015-10-09 18:16:46 -04002879 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002880 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002881 phys_addr_t old_ce_phys;
2882
2883 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb962015-10-09 18:16:46 -04002884 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02002885
2886 for (devfn = 0; devfn < 256; devfn++) {
2887 /* First calculate the correct index */
2888 idx = (ext ? devfn * 2 : devfn) % 256;
2889
2890 if (idx == 0) {
2891 /* First save what we may have and clean up */
2892 if (new_ce) {
2893 tbl[tbl_idx] = new_ce;
2894 __iommu_flush_cache(iommu, new_ce,
2895 VTD_PAGE_SIZE);
2896 pos = 1;
2897 }
2898
2899 if (old_ce)
Pan Bian829383e2018-11-21 17:53:47 +08002900 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002901
2902 ret = 0;
2903 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002904 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002905 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002906 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002907
2908 if (!old_ce_phys) {
2909 if (ext && devfn == 0) {
2910 /* No LCTP, try UCTP */
2911 devfn = 0x7f;
2912 continue;
2913 } else {
2914 goto out;
2915 }
2916 }
2917
2918 ret = -ENOMEM;
Dan Williamsdfddb962015-10-09 18:16:46 -04002919 old_ce = memremap(old_ce_phys, PAGE_SIZE,
2920 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002921 if (!old_ce)
2922 goto out;
2923
2924 new_ce = alloc_pgtable_page(iommu->node);
2925 if (!new_ce)
2926 goto out_unmap;
2927
2928 ret = 0;
2929 }
2930
2931 /* Now copy the context entry */
Dan Williamsdfddb962015-10-09 18:16:46 -04002932 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02002933
Joerg Roedelcf484d02015-06-12 12:21:46 +02002934 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02002935 continue;
2936
Joerg Roedeldbcd8612015-06-12 12:02:09 +02002937 did = context_domain_id(&ce);
2938 if (did >= 0 && did < cap_ndoms(iommu->cap))
2939 set_bit(did, iommu->domain_ids);
2940
Joerg Roedelcf484d02015-06-12 12:21:46 +02002941 /*
2942 * We need a marker for copied context entries. This
2943 * marker needs to work for the old format as well as
2944 * for extended context entries.
2945 *
2946 * Bit 67 of the context entry is used. In the old
2947 * format this bit is available to software, in the
2948 * extended format it is the PGE bit, but PGE is ignored
2949 * by HW if PASIDs are disabled (and thus still
2950 * available).
2951 *
2952 * So disable PASIDs first and then mark the entry
2953 * copied. This means that we don't copy PASID
2954 * translations from the old kernel, but this is fine as
2955 * faults there are not fatal.
2956 */
2957 context_clear_pasid_enable(&ce);
2958 context_set_copied(&ce);
2959
Joerg Roedel091d42e2015-06-12 11:56:10 +02002960 new_ce[idx] = ce;
2961 }
2962
2963 tbl[tbl_idx + pos] = new_ce;
2964
2965 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
2966
2967out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04002968 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002969
2970out:
2971 return ret;
2972}
2973
2974static int copy_translation_tables(struct intel_iommu *iommu)
2975{
2976 struct context_entry **ctxt_tbls;
Dan Williamsdfddb962015-10-09 18:16:46 -04002977 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002978 phys_addr_t old_rt_phys;
2979 int ctxt_table_entries;
2980 unsigned long flags;
2981 u64 rtaddr_reg;
2982 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02002983 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002984
2985 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
2986 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02002987 new_ext = !!ecap_ecs(iommu->ecap);
2988
2989 /*
2990 * The RTT bit can only be changed when translation is disabled,
2991 * but disabling translation means to open a window for data
2992 * corruption. So bail out and don't copy anything if we would
2993 * have to change the bit.
2994 */
2995 if (new_ext != ext)
2996 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002997
2998 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
2999 if (!old_rt_phys)
3000 return -EINVAL;
3001
Dan Williamsdfddb962015-10-09 18:16:46 -04003002 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003003 if (!old_rt)
3004 return -ENOMEM;
3005
3006 /* This is too big for the stack - allocate it from slab */
3007 ctxt_table_entries = ext ? 512 : 256;
3008 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003009 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003010 if (!ctxt_tbls)
3011 goto out_unmap;
3012
3013 for (bus = 0; bus < 256; bus++) {
3014 ret = copy_context_table(iommu, &old_rt[bus],
3015 ctxt_tbls, bus, ext);
3016 if (ret) {
3017 pr_err("%s: Failed to copy context table for bus %d\n",
3018 iommu->name, bus);
3019 continue;
3020 }
3021 }
3022
3023 spin_lock_irqsave(&iommu->lock, flags);
3024
3025 /* Context tables are copied, now write them to the root_entry table */
3026 for (bus = 0; bus < 256; bus++) {
3027 int idx = ext ? bus * 2 : bus;
3028 u64 val;
3029
3030 if (ctxt_tbls[idx]) {
3031 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3032 iommu->root_entry[bus].lo = val;
3033 }
3034
3035 if (!ext || !ctxt_tbls[idx + 1])
3036 continue;
3037
3038 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3039 iommu->root_entry[bus].hi = val;
3040 }
3041
3042 spin_unlock_irqrestore(&iommu->lock, flags);
3043
3044 kfree(ctxt_tbls);
3045
3046 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3047
3048 ret = 0;
3049
3050out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003051 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003052
3053 return ret;
3054}
3055
Jacob Pan33753032020-05-16 14:20:51 +08003056#ifdef CONFIG_INTEL_IOMMU_SVM
3057static ioasid_t intel_vcmd_ioasid_alloc(ioasid_t min, ioasid_t max, void *data)
3058{
3059 struct intel_iommu *iommu = data;
3060 ioasid_t ioasid;
3061
3062 if (!iommu)
3063 return INVALID_IOASID;
3064 /*
3065 * VT-d virtual command interface always uses the full 20 bit
3066 * PASID range. Host can partition guest PASID range based on
3067 * policies but it is out of guest's control.
3068 */
3069 if (min < PASID_MIN || max > intel_pasid_max_id)
3070 return INVALID_IOASID;
3071
3072 if (vcmd_alloc_pasid(iommu, &ioasid))
3073 return INVALID_IOASID;
3074
3075 return ioasid;
3076}
3077
3078static void intel_vcmd_ioasid_free(ioasid_t ioasid, void *data)
3079{
3080 struct intel_iommu *iommu = data;
3081
3082 if (!iommu)
3083 return;
3084 /*
3085 * Sanity check the ioasid owner is done at upper layer, e.g. VFIO
3086 * We can only free the PASID when all the devices are unbound.
3087 */
3088 if (ioasid_find(NULL, ioasid, NULL)) {
3089 pr_alert("Cannot free active IOASID %d\n", ioasid);
3090 return;
3091 }
3092 vcmd_free_pasid(iommu, ioasid);
3093}
3094
3095static void register_pasid_allocator(struct intel_iommu *iommu)
3096{
3097 /*
3098 * If we are running in the host, no need for custom allocator
3099 * in that PASIDs are allocated from the host system-wide.
3100 */
3101 if (!cap_caching_mode(iommu->cap))
3102 return;
3103
3104 if (!sm_supported(iommu)) {
3105 pr_warn("VT-d Scalable Mode not enabled, no PASID allocation\n");
3106 return;
3107 }
3108
3109 /*
3110 * Register a custom PASID allocator if we are running in a guest,
3111 * guest PASID must be obtained via virtual command interface.
3112 * There can be multiple vIOMMUs in each guest but only one allocator
3113 * is active. All vIOMMU allocators will eventually be calling the same
3114 * host allocator.
3115 */
3116 if (!ecap_vcs(iommu->ecap) || !vccap_pasid(iommu->vccap))
3117 return;
3118
3119 pr_info("Register custom PASID allocator\n");
3120 iommu->pasid_allocator.alloc = intel_vcmd_ioasid_alloc;
3121 iommu->pasid_allocator.free = intel_vcmd_ioasid_free;
3122 iommu->pasid_allocator.pdata = (void *)iommu;
3123 if (ioasid_register_allocator(&iommu->pasid_allocator)) {
3124 pr_warn("Custom PASID allocator failed, scalable mode disabled\n");
3125 /*
3126 * Disable scalable mode on this IOMMU if there
3127 * is no custom allocator. Mixing SM capable vIOMMU
3128 * and non-SM vIOMMU are not supported.
3129 */
3130 intel_iommu_sm = 0;
3131 }
3132}
3133#endif
3134
Joseph Cihulab7792602011-05-03 00:08:37 -07003135static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003136{
3137 struct dmar_drhd_unit *drhd;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003138 struct intel_iommu *iommu;
Lu Baoludf4f3c62019-05-25 13:41:36 +08003139 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003140
3141 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003142 * for each drhd
3143 * allocate root
3144 * initialize and program root entry to not present
3145 * endfor
3146 */
3147 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003148 /*
3149 * lock not needed as this is only incremented in the single
3150 * threaded kernel __init code path all other access are read
3151 * only
3152 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003153 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003154 g_num_of_iommus++;
3155 continue;
3156 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003157 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003158 }
3159
Jiang Liuffebeb42014-11-09 22:48:02 +08003160 /* Preallocate enough resources for IOMMU hot-addition */
3161 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3162 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3163
Weidong Hand9630fe2008-12-08 11:06:32 +08003164 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3165 GFP_KERNEL);
3166 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003167 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003168 ret = -ENOMEM;
3169 goto error;
3170 }
3171
Lu Baolu6a8c6742019-06-12 08:28:47 +08003172 for_each_iommu(iommu, drhd) {
3173 if (drhd->ignored) {
3174 iommu_disable_translation(iommu);
3175 continue;
3176 }
3177
Lu Baolu56283172018-07-14 15:46:54 +08003178 /*
3179 * Find the max pasid size of all IOMMU's in the system.
3180 * We need to ensure the system pasid table is no bigger
3181 * than the smallest supported.
3182 */
Lu Baolu765b6a92018-12-10 09:58:55 +08003183 if (pasid_supported(iommu)) {
Lu Baolu56283172018-07-14 15:46:54 +08003184 u32 temp = 2 << ecap_pss(iommu->ecap);
3185
3186 intel_pasid_max_id = min_t(u32, temp,
3187 intel_pasid_max_id);
3188 }
3189
Weidong Hand9630fe2008-12-08 11:06:32 +08003190 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003191
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003192 intel_iommu_init_qi(iommu);
3193
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003194 ret = iommu_init_domains(iommu);
3195 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003196 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003197
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003198 init_translation_status(iommu);
3199
Joerg Roedel091d42e2015-06-12 11:56:10 +02003200 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3201 iommu_disable_translation(iommu);
3202 clear_translation_pre_enabled(iommu);
3203 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3204 iommu->name);
3205 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003206
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003207 /*
3208 * TBD:
3209 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003210 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003211 */
3212 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003213 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003214 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003215
Joerg Roedel091d42e2015-06-12 11:56:10 +02003216 if (translation_pre_enabled(iommu)) {
3217 pr_info("Translation already enabled - trying to copy translation structures\n");
3218
3219 ret = copy_translation_tables(iommu);
3220 if (ret) {
3221 /*
3222 * We found the IOMMU with translation
3223 * enabled - but failed to copy over the
3224 * old root-entry table. Try to proceed
3225 * by disabling translation now and
3226 * allocating a clean root-entry table.
3227 * This might cause DMAR faults, but
3228 * probably the dump will still succeed.
3229 */
3230 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3231 iommu->name);
3232 iommu_disable_translation(iommu);
3233 clear_translation_pre_enabled(iommu);
3234 } else {
3235 pr_info("Copied translation tables from previous kernel for %s\n",
3236 iommu->name);
3237 }
3238 }
3239
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003240 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003241 hw_pass_through = 0;
Jacob Panff3dc652020-01-02 08:18:03 +08003242 intel_svm_check(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003243 }
3244
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003245 /*
3246 * Now that qi is enabled on all iommus, set the root entry and flush
3247 * caches. This is required on some Intel X58 chipsets, otherwise the
3248 * flush_context function will loop forever and the boot hangs.
3249 */
3250 for_each_active_iommu(iommu, drhd) {
3251 iommu_flush_write_buffer(iommu);
Jacob Pan33753032020-05-16 14:20:51 +08003252#ifdef CONFIG_INTEL_IOMMU_SVM
3253 register_pasid_allocator(iommu);
3254#endif
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003255 iommu_set_root_entry(iommu);
3256 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3257 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3258 }
3259
Suresh Siddhad3f13812011-08-23 17:05:25 -07003260#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
Lu Baolu5daab582019-05-02 09:34:26 +08003261 dmar_map_gfx = 0;
David Woodhouse19943b02009-08-04 16:19:20 +01003262#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003263
Lu Baolu5daab582019-05-02 09:34:26 +08003264 if (!dmar_map_gfx)
3265 iommu_identity_mapping |= IDENTMAP_GFX;
3266
Ashok Raj21e722c2017-01-30 09:39:53 -08003267 check_tylersburg_isoch();
3268
Lu Baolu4de354e2019-05-25 13:41:27 +08003269 ret = si_domain_init(hw_pass_through);
3270 if (ret)
3271 goto free_iommu;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003272
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003273 /*
3274 * for each drhd
3275 * enable fault log
3276 * global invalidate context cache
3277 * global invalidate iotlb
3278 * enable translation
3279 */
Jiang Liu7c919772014-01-06 14:18:18 +08003280 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003281 if (drhd->ignored) {
3282 /*
3283 * we always have to disable PMRs or DMA may fail on
3284 * this device
3285 */
3286 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003287 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003288 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003289 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003290
3291 iommu_flush_write_buffer(iommu);
3292
David Woodhousea222a7f2015-10-07 23:35:18 +01003293#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003294 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
Lu Baolua7755c32019-04-19 14:43:29 +08003295 /*
3296 * Call dmar_alloc_hwirq() with dmar_global_lock held,
3297 * could cause possible lock race condition.
3298 */
3299 up_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003300 ret = intel_svm_enable_prq(iommu);
Lu Baolua7755c32019-04-19 14:43:29 +08003301 down_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003302 if (ret)
3303 goto free_iommu;
3304 }
3305#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003306 ret = dmar_set_interrupt(iommu);
3307 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003308 goto free_iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003309 }
3310
3311 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003312
3313free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003314 for_each_active_iommu(iommu, drhd) {
3315 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003316 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003317 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003318
Weidong Hand9630fe2008-12-08 11:06:32 +08003319 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003320
Jiang Liu989d51f2014-02-19 14:07:21 +08003321error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003322 return ret;
3323}
3324
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003325/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003326static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003327 struct dmar_domain *domain,
3328 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003329{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06003330 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003331
Lu Baolucb8b8922020-01-02 08:18:19 +08003332 /*
3333 * Restrict dma_mask to the width that the iommu can handle.
3334 * First-level translation restricts the input-address to a
3335 * canonical address (i.e., address bits 63:N have the same
3336 * value as address bit [N-1], where N is 48-bits with 4-level
3337 * paging and 57-bits with 5-level paging). Hence, skip bit
3338 * [N-1].
3339 */
3340 if (domain_use_first_level(domain))
3341 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw - 1),
3342 dma_mask);
3343 else
3344 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw),
3345 dma_mask);
3346
Robin Murphy8f6429c2015-07-16 19:40:12 +01003347 /* Ensure we reserve the whole size-aligned region */
3348 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003349
3350 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003351 /*
3352 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003353 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003354 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003355 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003356 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003357 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003358 if (iova_pfn)
3359 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003360 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003361 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3362 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003363 if (unlikely(!iova_pfn)) {
Qian Cai944c9172019-11-22 14:16:54 -05003364 dev_err_once(dev, "Allocating %ld-page iova failed\n",
3365 nrpages);
Omer Peleg2aac6302016-04-20 11:33:57 +03003366 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003367 }
3368
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003369 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003370}
3371
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003372static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
3373 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003374{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003375 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003376 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003377 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003378 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003379 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003380 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003381 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003382
3383 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003384
Lu Baolu6fc70202020-05-06 09:59:47 +08003385 if (unlikely(attach_deferred(dev)))
3386 do_deferred_attach(dev);
3387
Joerg Roedel96d170f2020-02-17 17:27:44 +01003388 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003389 if (!domain)
Christoph Hellwig524a6692018-11-21 19:34:10 +01003390 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003391
Weidong Han8c11e792008-12-08 15:29:22 +08003392 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003393 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003394
Omer Peleg2aac6302016-04-20 11:33:57 +03003395 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3396 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003397 goto error;
3398
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003399 /*
3400 * Check if DMAR supports zero-length reads on write only
3401 * mappings..
3402 */
3403 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003404 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003405 prot |= DMA_PTE_READ;
3406 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3407 prot |= DMA_PTE_WRITE;
3408 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003409 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003410 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003411 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003412 * is not a big problem
3413 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003414 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003415 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003416 if (ret)
3417 goto error;
3418
Omer Peleg2aac6302016-04-20 11:33:57 +03003419 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003420 start_paddr += paddr & ~PAGE_MASK;
Lu Baolu3b530342019-09-06 14:14:51 +08003421
3422 trace_map_single(dev, start_paddr, paddr, size << VTD_PAGE_SHIFT);
3423
David Woodhouse03d6a242009-06-28 15:33:46 +01003424 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003425
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003426error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003427 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003428 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003429 dev_err(dev, "Device request: %zx@%llx dir %d --- failed\n",
3430 size, (unsigned long long)paddr, dir);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003431 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003432}
3433
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003434static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3435 unsigned long offset, size_t size,
3436 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003437 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003438{
Lu Baolu6fc70202020-05-06 09:59:47 +08003439 return __intel_map_single(dev, page_to_phys(page) + offset,
3440 size, dir, *dev->dma_mask);
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003441}
3442
3443static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
3444 size_t size, enum dma_data_direction dir,
3445 unsigned long attrs)
3446{
Lu Baolu6fc70202020-05-06 09:59:47 +08003447 return __intel_map_single(dev, phys_addr, size, dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003448}
3449
Omer Peleg769530e2016-04-20 11:33:25 +03003450static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003451{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003452 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003453 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003454 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003455 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003456 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003457 struct page *freelist;
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003458 struct pci_dev *pdev = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003459
David Woodhouse1525a292014-03-06 16:19:30 +00003460 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003461 BUG_ON(!domain);
3462
Weidong Han8c11e792008-12-08 15:29:22 +08003463 iommu = domain_get_iommu(domain);
3464
Omer Peleg2aac6302016-04-20 11:33:57 +03003465 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003466
Omer Peleg769530e2016-04-20 11:33:25 +03003467 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003468 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003469 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003470
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003471 if (dev_is_pci(dev))
3472 pdev = to_pci_dev(dev);
3473
David Woodhouseea8ea462014-03-05 17:09:32 +00003474 freelist = domain_unmap(domain, start_pfn, last_pfn);
Dmitry Safonoveffa4672019-07-16 22:38:05 +01003475 if (intel_iommu_strict || (pdev && pdev->untrusted) ||
3476 !has_iova_flush_queue(&domain->iovad)) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003477 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003478 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003479 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003480 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003481 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003482 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003483 queue_iova(&domain->iovad, iova_pfn, nrpages,
3484 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003485 /*
3486 * queue up the release of the unmap to save the 1/6th of the
3487 * cpu used up by the iotlb flush operation...
3488 */
mark gross5e0d2a62008-03-04 15:22:08 -08003489 }
Lu Baolu3b530342019-09-06 14:14:51 +08003490
3491 trace_unmap_single(dev, dev_addr, size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003492}
3493
Jiang Liud41a4ad2014-07-11 14:19:34 +08003494static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3495 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003496 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003497{
Lu Baolu6fc70202020-05-06 09:59:47 +08003498 intel_unmap(dev, dev_addr, size);
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003499}
3500
3501static void intel_unmap_resource(struct device *dev, dma_addr_t dev_addr,
3502 size_t size, enum dma_data_direction dir, unsigned long attrs)
3503{
Lu Baolu6fc70202020-05-06 09:59:47 +08003504 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003505}
3506
David Woodhouse5040a912014-03-09 16:14:00 -07003507static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003508 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003509 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003510{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003511 struct page *page = NULL;
3512 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003513
Lu Baolu6fc70202020-05-06 09:59:47 +08003514 if (unlikely(attach_deferred(dev)))
3515 do_deferred_attach(dev);
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003516
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003517 size = PAGE_ALIGN(size);
3518 order = get_order(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003519
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003520 if (gfpflags_allow_blocking(flags)) {
3521 unsigned int count = size >> PAGE_SHIFT;
3522
Marek Szyprowskid834c5a2018-08-17 15:49:00 -07003523 page = dma_alloc_from_contiguous(dev, count, order,
3524 flags & __GFP_NOWARN);
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003525 }
3526
3527 if (!page)
3528 page = alloc_pages(flags, order);
3529 if (!page)
3530 return NULL;
3531 memset(page_address(page), 0, size);
3532
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003533 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3534 DMA_BIDIRECTIONAL,
3535 dev->coherent_dma_mask);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003536 if (*dma_handle != DMA_MAPPING_ERROR)
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003537 return page_address(page);
3538 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3539 __free_pages(page, order);
3540
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003541 return NULL;
3542}
3543
David Woodhouse5040a912014-03-09 16:14:00 -07003544static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003545 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003546{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003547 int order;
3548 struct page *page = virt_to_page(vaddr);
3549
3550 size = PAGE_ALIGN(size);
3551 order = get_order(size);
3552
3553 intel_unmap(dev, dma_handle, size);
3554 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3555 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003556}
3557
David Woodhouse5040a912014-03-09 16:14:00 -07003558static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003559 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003560 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003561{
Omer Peleg769530e2016-04-20 11:33:25 +03003562 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3563 unsigned long nrpages = 0;
3564 struct scatterlist *sg;
3565 int i;
3566
3567 for_each_sg(sglist, sg, nelems, i) {
3568 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3569 }
3570
3571 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Lu Baolu3b530342019-09-06 14:14:51 +08003572
3573 trace_unmap_sg(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003574}
3575
David Woodhouse5040a912014-03-09 16:14:00 -07003576static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003577 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003578{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003579 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003580 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003581 size_t size = 0;
3582 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003583 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003584 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003585 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003586 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003587 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003588
3589 BUG_ON(dir == DMA_NONE);
Lu Baolu6fc70202020-05-06 09:59:47 +08003590
3591 if (unlikely(attach_deferred(dev)))
3592 do_deferred_attach(dev);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003593
Joerg Roedel96d170f2020-02-17 17:27:44 +01003594 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003595 if (!domain)
3596 return 0;
3597
Weidong Han8c11e792008-12-08 15:29:22 +08003598 iommu = domain_get_iommu(domain);
3599
David Woodhouseb536d242009-06-28 14:49:31 +01003600 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003601 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003602
Omer Peleg2aac6302016-04-20 11:33:57 +03003603 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003604 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003605 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003606 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003607 return 0;
3608 }
3609
3610 /*
3611 * Check if DMAR supports zero-length reads on write only
3612 * mappings..
3613 */
3614 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003615 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003616 prot |= DMA_PTE_READ;
3617 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3618 prot |= DMA_PTE_WRITE;
3619
Omer Peleg2aac6302016-04-20 11:33:57 +03003620 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003621
Fenghua Yuf5329592009-08-04 15:09:37 -07003622 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003623 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003624 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003625 start_vpfn + size - 1,
3626 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003627 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003628 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003629 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003630
Lu Baolu984d03a2020-01-02 08:18:11 +08003631 for_each_sg(sglist, sg, nelems, i)
3632 trace_map_sg(dev, i + 1, nelems, sg);
Lu Baolu3b530342019-09-06 14:14:51 +08003633
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003634 return nelems;
3635}
3636
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003637static u64 intel_get_required_mask(struct device *dev)
3638{
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003639 return DMA_BIT_MASK(32);
3640}
3641
Christoph Hellwig02b4da52018-09-17 19:10:31 +02003642static const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003643 .alloc = intel_alloc_coherent,
3644 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003645 .map_sg = intel_map_sg,
3646 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003647 .map_page = intel_map_page,
3648 .unmap_page = intel_unmap_page,
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003649 .map_resource = intel_map_resource,
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003650 .unmap_resource = intel_unmap_resource,
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003651 .dma_supported = dma_direct_supported,
Christoph Hellwigf9f32322019-08-06 15:01:50 +03003652 .mmap = dma_common_mmap,
3653 .get_sgtable = dma_common_get_sgtable,
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003654 .get_required_mask = intel_get_required_mask,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003655};
3656
Lu Baolucfb94a32019-09-06 14:14:52 +08003657static void
3658bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size,
3659 enum dma_data_direction dir, enum dma_sync_target target)
3660{
3661 struct dmar_domain *domain;
3662 phys_addr_t tlb_addr;
3663
3664 domain = find_domain(dev);
3665 if (WARN_ON(!domain))
3666 return;
3667
3668 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr);
3669 if (is_swiotlb_buffer(tlb_addr))
3670 swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target);
3671}
3672
3673static dma_addr_t
3674bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
3675 enum dma_data_direction dir, unsigned long attrs,
3676 u64 dma_mask)
3677{
3678 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3679 struct dmar_domain *domain;
3680 struct intel_iommu *iommu;
3681 unsigned long iova_pfn;
3682 unsigned long nrpages;
3683 phys_addr_t tlb_addr;
3684 int prot = 0;
3685 int ret;
3686
Joerg Roedela11bfde2020-02-17 17:20:59 +01003687 if (unlikely(attach_deferred(dev)))
3688 do_deferred_attach(dev);
3689
Joerg Roedel96d170f2020-02-17 17:27:44 +01003690 domain = find_domain(dev);
Joerg Roedela11bfde2020-02-17 17:20:59 +01003691
Lu Baolucfb94a32019-09-06 14:14:52 +08003692 if (WARN_ON(dir == DMA_NONE || !domain))
3693 return DMA_MAPPING_ERROR;
3694
3695 iommu = domain_get_iommu(domain);
3696 if (WARN_ON(!iommu))
3697 return DMA_MAPPING_ERROR;
3698
3699 nrpages = aligned_nrpages(0, size);
3700 iova_pfn = intel_alloc_iova(dev, domain,
3701 dma_to_mm_pfn(nrpages), dma_mask);
3702 if (!iova_pfn)
3703 return DMA_MAPPING_ERROR;
3704
3705 /*
3706 * Check if DMAR supports zero-length reads on write only
3707 * mappings..
3708 */
3709 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ||
3710 !cap_zlr(iommu->cap))
3711 prot |= DMA_PTE_READ;
3712 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3713 prot |= DMA_PTE_WRITE;
3714
3715 /*
3716 * If both the physical buffer start address and size are
3717 * page aligned, we don't need to use a bounce page.
3718 */
3719 if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
3720 tlb_addr = swiotlb_tbl_map_single(dev,
3721 __phys_to_dma(dev, io_tlb_start),
3722 paddr, size, aligned_size, dir, attrs);
3723 if (tlb_addr == DMA_MAPPING_ERROR) {
3724 goto swiotlb_error;
3725 } else {
3726 /* Cleanup the padding area. */
3727 void *padding_start = phys_to_virt(tlb_addr);
3728 size_t padding_size = aligned_size;
3729
3730 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
3731 (dir == DMA_TO_DEVICE ||
3732 dir == DMA_BIDIRECTIONAL)) {
3733 padding_start += size;
3734 padding_size -= size;
3735 }
3736
3737 memset(padding_start, 0, padding_size);
3738 }
3739 } else {
3740 tlb_addr = paddr;
3741 }
3742
3743 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
3744 tlb_addr >> VTD_PAGE_SHIFT, nrpages, prot);
3745 if (ret)
3746 goto mapping_error;
3747
3748 trace_bounce_map_single(dev, iova_pfn << PAGE_SHIFT, paddr, size);
3749
3750 return (phys_addr_t)iova_pfn << PAGE_SHIFT;
3751
3752mapping_error:
3753 if (is_swiotlb_buffer(tlb_addr))
3754 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3755 aligned_size, dir, attrs);
3756swiotlb_error:
3757 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
3758 dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n",
3759 size, (unsigned long long)paddr, dir);
3760
3761 return DMA_MAPPING_ERROR;
3762}
3763
3764static void
3765bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
3766 enum dma_data_direction dir, unsigned long attrs)
3767{
3768 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3769 struct dmar_domain *domain;
3770 phys_addr_t tlb_addr;
3771
3772 domain = find_domain(dev);
3773 if (WARN_ON(!domain))
3774 return;
3775
3776 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, dev_addr);
3777 if (WARN_ON(!tlb_addr))
3778 return;
3779
3780 intel_unmap(dev, dev_addr, size);
3781 if (is_swiotlb_buffer(tlb_addr))
3782 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3783 aligned_size, dir, attrs);
3784
3785 trace_bounce_unmap_single(dev, dev_addr, size);
3786}
3787
3788static dma_addr_t
3789bounce_map_page(struct device *dev, struct page *page, unsigned long offset,
3790 size_t size, enum dma_data_direction dir, unsigned long attrs)
3791{
3792 return bounce_map_single(dev, page_to_phys(page) + offset,
3793 size, dir, attrs, *dev->dma_mask);
3794}
3795
3796static dma_addr_t
3797bounce_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
3798 enum dma_data_direction dir, unsigned long attrs)
3799{
3800 return bounce_map_single(dev, phys_addr, size,
3801 dir, attrs, *dev->dma_mask);
3802}
3803
3804static void
3805bounce_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size,
3806 enum dma_data_direction dir, unsigned long attrs)
3807{
3808 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3809}
3810
3811static void
3812bounce_unmap_resource(struct device *dev, dma_addr_t dev_addr, size_t size,
3813 enum dma_data_direction dir, unsigned long attrs)
3814{
3815 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3816}
3817
3818static void
3819bounce_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3820 enum dma_data_direction dir, unsigned long attrs)
3821{
3822 struct scatterlist *sg;
3823 int i;
3824
3825 for_each_sg(sglist, sg, nelems, i)
3826 bounce_unmap_page(dev, sg->dma_address,
3827 sg_dma_len(sg), dir, attrs);
3828}
3829
3830static int
3831bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3832 enum dma_data_direction dir, unsigned long attrs)
3833{
3834 int i;
3835 struct scatterlist *sg;
3836
3837 for_each_sg(sglist, sg, nelems, i) {
3838 sg->dma_address = bounce_map_page(dev, sg_page(sg),
3839 sg->offset, sg->length,
3840 dir, attrs);
3841 if (sg->dma_address == DMA_MAPPING_ERROR)
3842 goto out_unmap;
3843 sg_dma_len(sg) = sg->length;
3844 }
3845
Lu Baolu984d03a2020-01-02 08:18:11 +08003846 for_each_sg(sglist, sg, nelems, i)
3847 trace_bounce_map_sg(dev, i + 1, nelems, sg);
3848
Lu Baolucfb94a32019-09-06 14:14:52 +08003849 return nelems;
3850
3851out_unmap:
3852 bounce_unmap_sg(dev, sglist, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
3853 return 0;
3854}
3855
3856static void
3857bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
3858 size_t size, enum dma_data_direction dir)
3859{
3860 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU);
3861}
3862
3863static void
3864bounce_sync_single_for_device(struct device *dev, dma_addr_t addr,
3865 size_t size, enum dma_data_direction dir)
3866{
3867 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE);
3868}
3869
3870static void
3871bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
3872 int nelems, enum dma_data_direction dir)
3873{
3874 struct scatterlist *sg;
3875 int i;
3876
3877 for_each_sg(sglist, sg, nelems, i)
3878 bounce_sync_single(dev, sg_dma_address(sg),
3879 sg_dma_len(sg), dir, SYNC_FOR_CPU);
3880}
3881
3882static void
3883bounce_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
3884 int nelems, enum dma_data_direction dir)
3885{
3886 struct scatterlist *sg;
3887 int i;
3888
3889 for_each_sg(sglist, sg, nelems, i)
3890 bounce_sync_single(dev, sg_dma_address(sg),
3891 sg_dma_len(sg), dir, SYNC_FOR_DEVICE);
3892}
3893
3894static const struct dma_map_ops bounce_dma_ops = {
3895 .alloc = intel_alloc_coherent,
3896 .free = intel_free_coherent,
3897 .map_sg = bounce_map_sg,
3898 .unmap_sg = bounce_unmap_sg,
3899 .map_page = bounce_map_page,
3900 .unmap_page = bounce_unmap_page,
3901 .sync_single_for_cpu = bounce_sync_single_for_cpu,
3902 .sync_single_for_device = bounce_sync_single_for_device,
3903 .sync_sg_for_cpu = bounce_sync_sg_for_cpu,
3904 .sync_sg_for_device = bounce_sync_sg_for_device,
3905 .map_resource = bounce_map_resource,
3906 .unmap_resource = bounce_unmap_resource,
3907 .dma_supported = dma_direct_supported,
3908};
3909
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003910static inline int iommu_domain_cache_init(void)
3911{
3912 int ret = 0;
3913
3914 iommu_domain_cache = kmem_cache_create("iommu_domain",
3915 sizeof(struct dmar_domain),
3916 0,
3917 SLAB_HWCACHE_ALIGN,
3918
3919 NULL);
3920 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003921 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003922 ret = -ENOMEM;
3923 }
3924
3925 return ret;
3926}
3927
3928static inline int iommu_devinfo_cache_init(void)
3929{
3930 int ret = 0;
3931
3932 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3933 sizeof(struct device_domain_info),
3934 0,
3935 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003936 NULL);
3937 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003938 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003939 ret = -ENOMEM;
3940 }
3941
3942 return ret;
3943}
3944
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003945static int __init iommu_init_mempool(void)
3946{
3947 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003948 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003949 if (ret)
3950 return ret;
3951
3952 ret = iommu_domain_cache_init();
3953 if (ret)
3954 goto domain_error;
3955
3956 ret = iommu_devinfo_cache_init();
3957 if (!ret)
3958 return ret;
3959
3960 kmem_cache_destroy(iommu_domain_cache);
3961domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003962 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003963
3964 return -ENOMEM;
3965}
3966
3967static void __init iommu_exit_mempool(void)
3968{
3969 kmem_cache_destroy(iommu_devinfo_cache);
3970 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003971 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003972}
3973
Dan Williams556ab452010-07-23 15:47:56 -07003974static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3975{
3976 struct dmar_drhd_unit *drhd;
3977 u32 vtbar;
3978 int rc;
3979
3980 /* We know that this device on this chipset has its own IOMMU.
3981 * If we find it under a different IOMMU, then the BIOS is lying
3982 * to us. Hope that the IOMMU for this device is actually
3983 * disabled, and it needs no translation...
3984 */
3985 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3986 if (rc) {
3987 /* "can't" happen */
3988 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3989 return;
3990 }
3991 vtbar &= 0xffff0000;
3992
3993 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3994 drhd = dmar_find_matched_drhd_unit(pdev);
Hans de Goede81ee85d2020-03-09 19:25:10 +01003995 if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
3996 pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
3997 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
Dan Williams556ab452010-07-23 15:47:56 -07003998 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Hans de Goede81ee85d2020-03-09 19:25:10 +01003999 }
Dan Williams556ab452010-07-23 15:47:56 -07004000}
4001DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
4002
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004003static void __init init_no_remapping_devices(void)
4004{
4005 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00004006 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08004007 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004008
4009 for_each_drhd_unit(drhd) {
4010 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08004011 for_each_active_dev_scope(drhd->devices,
4012 drhd->devices_cnt, i, dev)
4013 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004014 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004015 if (i == drhd->devices_cnt)
4016 drhd->ignored = 1;
4017 }
4018 }
4019
Jiang Liu7c919772014-01-06 14:18:18 +08004020 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004021 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004022 continue;
4023
Jiang Liub683b232014-02-19 14:07:32 +08004024 for_each_active_dev_scope(drhd->devices,
4025 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004026 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004027 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004028 if (i < drhd->devices_cnt)
4029 continue;
4030
David Woodhousec0771df2011-10-14 20:59:46 +01004031 /* This IOMMU has *only* gfx devices. Either bypass it or
4032 set the gfx_mapped flag, as appropriate */
Lu Baolucf1ec452019-05-02 09:34:25 +08004033 if (!dmar_map_gfx) {
David Woodhousec0771df2011-10-14 20:59:46 +01004034 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004035 for_each_active_dev_scope(drhd->devices,
4036 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004037 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004038 }
4039 }
4040}
4041
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004042#ifdef CONFIG_SUSPEND
4043static int init_iommu_hw(void)
4044{
4045 struct dmar_drhd_unit *drhd;
4046 struct intel_iommu *iommu = NULL;
4047
4048 for_each_active_iommu(iommu, drhd)
4049 if (iommu->qi)
4050 dmar_reenable_qi(iommu);
4051
Joseph Cihulab7792602011-05-03 00:08:37 -07004052 for_each_iommu(iommu, drhd) {
4053 if (drhd->ignored) {
4054 /*
4055 * we always have to disable PMRs or DMA may fail on
4056 * this device
4057 */
4058 if (force_on)
4059 iommu_disable_protect_mem_regions(iommu);
4060 continue;
4061 }
Lu Baolu095303e2019-04-29 09:16:02 +08004062
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004063 iommu_flush_write_buffer(iommu);
4064
4065 iommu_set_root_entry(iommu);
4066
4067 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004068 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004069 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4070 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004071 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004072 }
4073
4074 return 0;
4075}
4076
4077static void iommu_flush_all(void)
4078{
4079 struct dmar_drhd_unit *drhd;
4080 struct intel_iommu *iommu;
4081
4082 for_each_active_iommu(iommu, drhd) {
4083 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004084 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004085 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004086 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004087 }
4088}
4089
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004090static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004091{
4092 struct dmar_drhd_unit *drhd;
4093 struct intel_iommu *iommu = NULL;
4094 unsigned long flag;
4095
4096 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004097 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004098 GFP_ATOMIC);
4099 if (!iommu->iommu_state)
4100 goto nomem;
4101 }
4102
4103 iommu_flush_all();
4104
4105 for_each_active_iommu(iommu, drhd) {
4106 iommu_disable_translation(iommu);
4107
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004108 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004109
4110 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4111 readl(iommu->reg + DMAR_FECTL_REG);
4112 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4113 readl(iommu->reg + DMAR_FEDATA_REG);
4114 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4115 readl(iommu->reg + DMAR_FEADDR_REG);
4116 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4117 readl(iommu->reg + DMAR_FEUADDR_REG);
4118
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004119 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004120 }
4121 return 0;
4122
4123nomem:
4124 for_each_active_iommu(iommu, drhd)
4125 kfree(iommu->iommu_state);
4126
4127 return -ENOMEM;
4128}
4129
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004130static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004131{
4132 struct dmar_drhd_unit *drhd;
4133 struct intel_iommu *iommu = NULL;
4134 unsigned long flag;
4135
4136 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004137 if (force_on)
4138 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4139 else
4140 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004141 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004142 }
4143
4144 for_each_active_iommu(iommu, drhd) {
4145
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004146 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004147
4148 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4149 iommu->reg + DMAR_FECTL_REG);
4150 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4151 iommu->reg + DMAR_FEDATA_REG);
4152 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4153 iommu->reg + DMAR_FEADDR_REG);
4154 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4155 iommu->reg + DMAR_FEUADDR_REG);
4156
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004157 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004158 }
4159
4160 for_each_active_iommu(iommu, drhd)
4161 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004162}
4163
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004164static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004165 .resume = iommu_resume,
4166 .suspend = iommu_suspend,
4167};
4168
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004169static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004170{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004171 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004172}
4173
4174#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004175static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004176#endif /* CONFIG_PM */
4177
Barret Rhodence4cc52b2020-01-15 11:03:57 +08004178static int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
4179{
4180 if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) ||
4181 !IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) ||
4182 rmrr->end_address <= rmrr->base_address ||
4183 arch_rmrr_sanity_check(rmrr))
4184 return -EINVAL;
4185
4186 return 0;
4187}
4188
Jiang Liuc2a0b532014-11-09 22:47:56 +08004189int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004190{
4191 struct acpi_dmar_reserved_memory *rmrr;
4192 struct dmar_rmrr_unit *rmrru;
Yian Chenf036c7f2019-10-17 04:39:19 -07004193
4194 rmrr = (struct acpi_dmar_reserved_memory *)header;
Hans de Goede96788c72020-03-09 15:01:38 +01004195 if (rmrr_sanity_check(rmrr)) {
4196 pr_warn(FW_BUG
Barret Rhodenf5a68bb2020-01-15 11:03:56 +08004197 "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
4198 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
4199 rmrr->base_address, rmrr->end_address,
4200 dmi_get_system_info(DMI_BIOS_VENDOR),
4201 dmi_get_system_info(DMI_BIOS_VERSION),
4202 dmi_get_system_info(DMI_PRODUCT_VERSION));
Hans de Goede96788c72020-03-09 15:01:38 +01004203 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
4204 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004205
4206 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4207 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004208 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004209
4210 rmrru->hdr = header;
Yian Chenf036c7f2019-10-17 04:39:19 -07004211
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004212 rmrru->base_address = rmrr->base_address;
4213 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004214
Jiang Liu2e455282014-02-19 14:07:36 +08004215 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4216 ((void *)rmrr) + rmrr->header.length,
4217 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004218 if (rmrru->devices_cnt && rmrru->devices == NULL)
Eric Auger5f64ce52019-06-03 08:53:31 +02004219 goto free_rmrru;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004220
Jiang Liu2e455282014-02-19 14:07:36 +08004221 list_add(&rmrru->list, &dmar_rmrr_units);
4222
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004223 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004224free_rmrru:
4225 kfree(rmrru);
4226out:
4227 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004228}
4229
Jiang Liu6b197242014-11-09 22:47:58 +08004230static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4231{
4232 struct dmar_atsr_unit *atsru;
4233 struct acpi_dmar_atsr *tmp;
4234
Qian Caic6f4ebd2020-03-17 11:03:26 -04004235 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list,
4236 dmar_rcu_check()) {
Jiang Liu6b197242014-11-09 22:47:58 +08004237 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4238 if (atsr->segment != tmp->segment)
4239 continue;
4240 if (atsr->header.length != tmp->header.length)
4241 continue;
4242 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4243 return atsru;
4244 }
4245
4246 return NULL;
4247}
4248
4249int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004250{
4251 struct acpi_dmar_atsr *atsr;
4252 struct dmar_atsr_unit *atsru;
4253
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004254 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004255 return 0;
4256
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004257 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004258 atsru = dmar_find_atsr(atsr);
4259 if (atsru)
4260 return 0;
4261
4262 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004263 if (!atsru)
4264 return -ENOMEM;
4265
Jiang Liu6b197242014-11-09 22:47:58 +08004266 /*
4267 * If memory is allocated from slab by ACPI _DSM method, we need to
4268 * copy the memory content because the memory buffer will be freed
4269 * on return.
4270 */
4271 atsru->hdr = (void *)(atsru + 1);
4272 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004273 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004274 if (!atsru->include_all) {
4275 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4276 (void *)atsr + atsr->header.length,
4277 &atsru->devices_cnt);
4278 if (atsru->devices_cnt && atsru->devices == NULL) {
4279 kfree(atsru);
4280 return -ENOMEM;
4281 }
4282 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004283
Jiang Liu0e242612014-02-19 14:07:34 +08004284 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004285
4286 return 0;
4287}
4288
Jiang Liu9bdc5312014-01-06 14:18:27 +08004289static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4290{
4291 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4292 kfree(atsru);
4293}
4294
Jiang Liu6b197242014-11-09 22:47:58 +08004295int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4296{
4297 struct acpi_dmar_atsr *atsr;
4298 struct dmar_atsr_unit *atsru;
4299
4300 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4301 atsru = dmar_find_atsr(atsr);
4302 if (atsru) {
4303 list_del_rcu(&atsru->list);
4304 synchronize_rcu();
4305 intel_iommu_free_atsr(atsru);
4306 }
4307
4308 return 0;
4309}
4310
4311int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4312{
4313 int i;
4314 struct device *dev;
4315 struct acpi_dmar_atsr *atsr;
4316 struct dmar_atsr_unit *atsru;
4317
4318 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4319 atsru = dmar_find_atsr(atsr);
4320 if (!atsru)
4321 return 0;
4322
Linus Torvalds194dc872016-07-27 20:03:31 -07004323 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004324 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4325 i, dev)
4326 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004327 }
Jiang Liu6b197242014-11-09 22:47:58 +08004328
4329 return 0;
4330}
4331
Jiang Liuffebeb42014-11-09 22:48:02 +08004332static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4333{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004334 int sp, ret;
Jiang Liuffebeb42014-11-09 22:48:02 +08004335 struct intel_iommu *iommu = dmaru->iommu;
4336
4337 if (g_iommus[iommu->seq_id])
4338 return 0;
4339
4340 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004341 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004342 iommu->name);
4343 return -ENXIO;
4344 }
4345 if (!ecap_sc_support(iommu->ecap) &&
4346 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004347 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004348 iommu->name);
4349 return -ENXIO;
4350 }
Lu Baolu64229e82020-01-02 08:18:20 +08004351 sp = domain_update_iommu_superpage(NULL, iommu) - 1;
Jiang Liuffebeb42014-11-09 22:48:02 +08004352 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004353 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004354 iommu->name);
4355 return -ENXIO;
4356 }
4357
4358 /*
4359 * Disable translation if already enabled prior to OS handover.
4360 */
4361 if (iommu->gcmd & DMA_GCMD_TE)
4362 iommu_disable_translation(iommu);
4363
4364 g_iommus[iommu->seq_id] = iommu;
4365 ret = iommu_init_domains(iommu);
4366 if (ret == 0)
4367 ret = iommu_alloc_root_entry(iommu);
4368 if (ret)
4369 goto out;
4370
Jacob Panff3dc652020-01-02 08:18:03 +08004371 intel_svm_check(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00004372
Jiang Liuffebeb42014-11-09 22:48:02 +08004373 if (dmaru->ignored) {
4374 /*
4375 * we always have to disable PMRs or DMA may fail on this device
4376 */
4377 if (force_on)
4378 iommu_disable_protect_mem_regions(iommu);
4379 return 0;
4380 }
4381
4382 intel_iommu_init_qi(iommu);
4383 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004384
4385#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004386 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01004387 ret = intel_svm_enable_prq(iommu);
4388 if (ret)
4389 goto disable_iommu;
4390 }
4391#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004392 ret = dmar_set_interrupt(iommu);
4393 if (ret)
4394 goto disable_iommu;
4395
4396 iommu_set_root_entry(iommu);
4397 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4398 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4399 iommu_enable_translation(iommu);
4400
Jiang Liuffebeb42014-11-09 22:48:02 +08004401 iommu_disable_protect_mem_regions(iommu);
4402 return 0;
4403
4404disable_iommu:
4405 disable_dmar_iommu(iommu);
4406out:
4407 free_dmar_iommu(iommu);
4408 return ret;
4409}
4410
Jiang Liu6b197242014-11-09 22:47:58 +08004411int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4412{
Jiang Liuffebeb42014-11-09 22:48:02 +08004413 int ret = 0;
4414 struct intel_iommu *iommu = dmaru->iommu;
4415
4416 if (!intel_iommu_enabled)
4417 return 0;
4418 if (iommu == NULL)
4419 return -EINVAL;
4420
4421 if (insert) {
4422 ret = intel_iommu_add(dmaru);
4423 } else {
4424 disable_dmar_iommu(iommu);
4425 free_dmar_iommu(iommu);
4426 }
4427
4428 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004429}
4430
Jiang Liu9bdc5312014-01-06 14:18:27 +08004431static void intel_iommu_free_dmars(void)
4432{
4433 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4434 struct dmar_atsr_unit *atsru, *atsr_n;
4435
4436 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4437 list_del(&rmrru->list);
4438 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
4439 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004440 }
4441
Jiang Liu9bdc5312014-01-06 14:18:27 +08004442 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4443 list_del(&atsru->list);
4444 intel_iommu_free_atsr(atsru);
4445 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004446}
4447
4448int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4449{
Jiang Liub683b232014-02-19 14:07:32 +08004450 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004451 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004452 struct pci_dev *bridge = NULL;
4453 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004454 struct acpi_dmar_atsr *atsr;
4455 struct dmar_atsr_unit *atsru;
4456
4457 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004458 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004459 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004460 /* If it's an integrated device, allow ATS */
4461 if (!bridge)
4462 return 1;
4463 /* Connected via non-PCIe: no ATS */
4464 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004465 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004466 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004467 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004468 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004469 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004470 }
4471
Jiang Liu0e242612014-02-19 14:07:34 +08004472 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004473 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4474 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4475 if (atsr->segment != pci_domain_nr(dev->bus))
4476 continue;
4477
Jiang Liub683b232014-02-19 14:07:32 +08004478 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004479 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004480 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004481
4482 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004483 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004484 }
Jiang Liub683b232014-02-19 14:07:32 +08004485 ret = 0;
4486out:
Jiang Liu0e242612014-02-19 14:07:34 +08004487 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004488
Jiang Liub683b232014-02-19 14:07:32 +08004489 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004490}
4491
Jiang Liu59ce0512014-02-19 14:07:35 +08004492int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4493{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004494 int ret;
Jiang Liu59ce0512014-02-19 14:07:35 +08004495 struct dmar_rmrr_unit *rmrru;
4496 struct dmar_atsr_unit *atsru;
4497 struct acpi_dmar_atsr *atsr;
4498 struct acpi_dmar_reserved_memory *rmrr;
4499
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004500 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004501 return 0;
4502
4503 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4504 rmrr = container_of(rmrru->hdr,
4505 struct acpi_dmar_reserved_memory, header);
4506 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4507 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4508 ((void *)rmrr) + rmrr->header.length,
4509 rmrr->segment, rmrru->devices,
4510 rmrru->devices_cnt);
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004511 if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004512 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004513 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004514 dmar_remove_dev_scope(info, rmrr->segment,
4515 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004516 }
4517 }
4518
4519 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4520 if (atsru->include_all)
4521 continue;
4522
4523 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4524 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4525 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4526 (void *)atsr + atsr->header.length,
4527 atsr->segment, atsru->devices,
4528 atsru->devices_cnt);
4529 if (ret > 0)
4530 break;
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004531 else if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004532 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004533 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004534 if (dmar_remove_dev_scope(info, atsr->segment,
4535 atsru->devices, atsru->devices_cnt))
4536 break;
4537 }
4538 }
4539
4540 return 0;
4541}
4542
Jiang Liu75f05562014-02-19 14:07:37 +08004543static int intel_iommu_memory_notifier(struct notifier_block *nb,
4544 unsigned long val, void *v)
4545{
4546 struct memory_notify *mhp = v;
Tom Murphye70b0812020-05-16 14:21:01 +08004547 unsigned long start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4548 unsigned long last_vpfn = mm_to_dma_pfn(mhp->start_pfn +
4549 mhp->nr_pages - 1);
Jiang Liu75f05562014-02-19 14:07:37 +08004550
4551 switch (val) {
4552 case MEM_GOING_ONLINE:
Tom Murphye70b0812020-05-16 14:21:01 +08004553 if (iommu_domain_identity_map(si_domain,
4554 start_vpfn, last_vpfn)) {
4555 pr_warn("Failed to build identity map for [%lx-%lx]\n",
4556 start_vpfn, last_vpfn);
Jiang Liu75f05562014-02-19 14:07:37 +08004557 return NOTIFY_BAD;
4558 }
4559 break;
4560
4561 case MEM_OFFLINE:
4562 case MEM_CANCEL_ONLINE:
Tom Murphye70b0812020-05-16 14:21:01 +08004563 {
Jiang Liu75f05562014-02-19 14:07:37 +08004564 struct dmar_drhd_unit *drhd;
4565 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004566 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004567
Tom Murphye70b0812020-05-16 14:21:01 +08004568 freelist = domain_unmap(si_domain,
4569 start_vpfn, last_vpfn);
David Woodhouseea8ea462014-03-05 17:09:32 +00004570
Jiang Liu75f05562014-02-19 14:07:37 +08004571 rcu_read_lock();
4572 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004573 iommu_flush_iotlb_psi(iommu, si_domain,
Tom Murphye70b0812020-05-16 14:21:01 +08004574 start_vpfn, mhp->nr_pages,
David Woodhouseea8ea462014-03-05 17:09:32 +00004575 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004576 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004577 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004578 }
4579 break;
4580 }
4581
4582 return NOTIFY_OK;
4583}
4584
4585static struct notifier_block intel_iommu_memory_nb = {
4586 .notifier_call = intel_iommu_memory_notifier,
4587 .priority = 0
4588};
4589
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004590static void free_all_cpu_cached_iovas(unsigned int cpu)
4591{
4592 int i;
4593
4594 for (i = 0; i < g_num_of_iommus; i++) {
4595 struct intel_iommu *iommu = g_iommus[i];
4596 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004597 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004598
4599 if (!iommu)
4600 continue;
4601
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004602 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004603 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004604
Tom Murphye70b0812020-05-16 14:21:01 +08004605 if (!domain || domain->domain.type != IOMMU_DOMAIN_DMA)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004606 continue;
Tom Murphye70b0812020-05-16 14:21:01 +08004607
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004608 free_cpu_cached_iovas(cpu, &domain->iovad);
4609 }
4610 }
4611}
4612
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004613static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004614{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004615 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004616 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004617}
4618
Joerg Roedel161b28a2017-03-28 17:04:52 +02004619static void intel_disable_iommus(void)
4620{
4621 struct intel_iommu *iommu = NULL;
4622 struct dmar_drhd_unit *drhd;
4623
4624 for_each_iommu(iommu, drhd)
4625 iommu_disable_translation(iommu);
4626}
4627
Deepa Dinamani6c3a44e2019-11-10 09:27:44 -08004628void intel_iommu_shutdown(void)
4629{
4630 struct dmar_drhd_unit *drhd;
4631 struct intel_iommu *iommu = NULL;
4632
4633 if (no_iommu || dmar_disabled)
4634 return;
4635
4636 down_write(&dmar_global_lock);
4637
4638 /* Disable PMRs explicitly here. */
4639 for_each_iommu(iommu, drhd)
4640 iommu_disable_protect_mem_regions(iommu);
4641
4642 /* Make sure the IOMMUs are switched off */
4643 intel_disable_iommus();
4644
4645 up_write(&dmar_global_lock);
4646}
4647
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004648static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4649{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004650 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4651
4652 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004653}
4654
Alex Williamsona5459cf2014-06-12 16:12:31 -06004655static ssize_t intel_iommu_show_version(struct device *dev,
4656 struct device_attribute *attr,
4657 char *buf)
4658{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004659 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004660 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4661 return sprintf(buf, "%d:%d\n",
4662 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4663}
4664static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4665
4666static ssize_t intel_iommu_show_address(struct device *dev,
4667 struct device_attribute *attr,
4668 char *buf)
4669{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004670 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004671 return sprintf(buf, "%llx\n", iommu->reg_phys);
4672}
4673static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4674
4675static ssize_t intel_iommu_show_cap(struct device *dev,
4676 struct device_attribute *attr,
4677 char *buf)
4678{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004679 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004680 return sprintf(buf, "%llx\n", iommu->cap);
4681}
4682static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4683
4684static ssize_t intel_iommu_show_ecap(struct device *dev,
4685 struct device_attribute *attr,
4686 char *buf)
4687{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004688 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004689 return sprintf(buf, "%llx\n", iommu->ecap);
4690}
4691static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4692
Alex Williamson2238c082015-07-14 15:24:53 -06004693static ssize_t intel_iommu_show_ndoms(struct device *dev,
4694 struct device_attribute *attr,
4695 char *buf)
4696{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004697 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004698 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4699}
4700static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4701
4702static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4703 struct device_attribute *attr,
4704 char *buf)
4705{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004706 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004707 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4708 cap_ndoms(iommu->cap)));
4709}
4710static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4711
Alex Williamsona5459cf2014-06-12 16:12:31 -06004712static struct attribute *intel_iommu_attrs[] = {
4713 &dev_attr_version.attr,
4714 &dev_attr_address.attr,
4715 &dev_attr_cap.attr,
4716 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004717 &dev_attr_domains_supported.attr,
4718 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004719 NULL,
4720};
4721
4722static struct attribute_group intel_iommu_group = {
4723 .name = "intel-iommu",
4724 .attrs = intel_iommu_attrs,
4725};
4726
4727const struct attribute_group *intel_iommu_groups[] = {
4728 &intel_iommu_group,
4729 NULL,
4730};
4731
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004732static inline bool has_untrusted_dev(void)
Lu Baolu89a60792018-10-23 15:45:01 +08004733{
4734 struct pci_dev *pdev = NULL;
Lu Baolu89a60792018-10-23 15:45:01 +08004735
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004736 for_each_pci_dev(pdev)
4737 if (pdev->untrusted)
4738 return true;
Lu Baolu89a60792018-10-23 15:45:01 +08004739
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004740 return false;
4741}
Lu Baolu89a60792018-10-23 15:45:01 +08004742
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004743static int __init platform_optin_force_iommu(void)
4744{
4745 if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
Lu Baolu89a60792018-10-23 15:45:01 +08004746 return 0;
4747
4748 if (no_iommu || dmar_disabled)
4749 pr_info("Intel-IOMMU force enabled due to platform opt in\n");
4750
4751 /*
4752 * If Intel-IOMMU is disabled by default, we will apply identity
4753 * map for all devices except those marked as being untrusted.
4754 */
4755 if (dmar_disabled)
Lu Baolub89b6602020-01-15 11:03:59 +08004756 iommu_set_default_passthrough(false);
Lu Baolu89a60792018-10-23 15:45:01 +08004757
4758 dmar_disabled = 0;
Lu Baolu89a60792018-10-23 15:45:01 +08004759 no_iommu = 0;
4760
4761 return 1;
4762}
4763
Lu Baolufa212a92019-05-25 13:41:31 +08004764static int __init probe_acpi_namespace_devices(void)
4765{
4766 struct dmar_drhd_unit *drhd;
Qian Caiaf88ec32019-06-03 10:05:19 -04004767 /* To avoid a -Wunused-but-set-variable warning. */
4768 struct intel_iommu *iommu __maybe_unused;
Lu Baolufa212a92019-05-25 13:41:31 +08004769 struct device *dev;
4770 int i, ret = 0;
4771
4772 for_each_active_iommu(iommu, drhd) {
4773 for_each_active_dev_scope(drhd->devices,
4774 drhd->devices_cnt, i, dev) {
4775 struct acpi_device_physical_node *pn;
4776 struct iommu_group *group;
4777 struct acpi_device *adev;
4778
4779 if (dev->bus != &acpi_bus_type)
4780 continue;
4781
4782 adev = to_acpi_device(dev);
4783 mutex_lock(&adev->physical_node_lock);
4784 list_for_each_entry(pn,
4785 &adev->physical_node_list, node) {
4786 group = iommu_group_get(pn->dev);
4787 if (group) {
4788 iommu_group_put(group);
4789 continue;
4790 }
4791
4792 pn->dev->bus->iommu_ops = &intel_iommu_ops;
4793 ret = iommu_probe_device(pn->dev);
4794 if (ret)
4795 break;
4796 }
4797 mutex_unlock(&adev->physical_node_lock);
4798
4799 if (ret)
4800 return ret;
4801 }
4802 }
4803
4804 return 0;
4805}
4806
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004807int __init intel_iommu_init(void)
4808{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004809 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004810 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004811 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004812
Lu Baolu89a60792018-10-23 15:45:01 +08004813 /*
4814 * Intel IOMMU is required for a TXT/tboot launch or platform
4815 * opt in, so enforce that.
4816 */
4817 force_on = tboot_force_iommu() || platform_optin_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004818
Jiang Liu3a5670e2014-02-19 14:07:33 +08004819 if (iommu_init_mempool()) {
4820 if (force_on)
4821 panic("tboot: Failed to initialize iommu memory\n");
4822 return -ENOMEM;
4823 }
4824
4825 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004826 if (dmar_table_init()) {
4827 if (force_on)
4828 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004829 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004830 }
4831
Suresh Siddhac2c72862011-08-23 17:05:19 -07004832 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004833 if (force_on)
4834 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004835 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004836 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004837
Joerg Roedelec154bf2017-10-06 15:00:53 +02004838 up_write(&dmar_global_lock);
4839
4840 /*
4841 * The bus notifier takes the dmar_global_lock, so lockdep will
4842 * complain later when we register it under the lock.
4843 */
4844 dmar_register_bus_notifier();
4845
4846 down_write(&dmar_global_lock);
4847
Megha Dey1da83472020-03-14 11:39:59 +08004848 if (!no_iommu)
4849 intel_iommu_debugfs_init();
4850
Joerg Roedel161b28a2017-03-28 17:04:52 +02004851 if (no_iommu || dmar_disabled) {
4852 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004853 * We exit the function here to ensure IOMMU's remapping and
4854 * mempool aren't setup, which means that the IOMMU's PMRs
4855 * won't be disabled via the call to init_dmars(). So disable
4856 * it explicitly here. The PMRs were setup by tboot prior to
4857 * calling SENTER, but the kernel is expected to reset/tear
4858 * down the PMRs.
4859 */
4860 if (intel_iommu_tboot_noforce) {
4861 for_each_iommu(iommu, drhd)
4862 iommu_disable_protect_mem_regions(iommu);
4863 }
4864
4865 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004866 * Make sure the IOMMUs are switched off, even when we
4867 * boot into a kexec kernel and the previous kernel left
4868 * them enabled
4869 */
4870 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004871 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004872 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004873
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004874 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004875 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004876
4877 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004878 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004879
Joseph Cihula51a63e62011-03-21 11:04:24 -07004880 if (dmar_init_reserved_ranges()) {
4881 if (force_on)
4882 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004883 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004884 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004885
Lu Baolucf1ec452019-05-02 09:34:25 +08004886 if (dmar_map_gfx)
4887 intel_iommu_gfx_mapped = 1;
4888
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004889 init_no_remapping_devices();
4890
Joseph Cihulab7792602011-05-03 00:08:37 -07004891 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004892 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004893 if (force_on)
4894 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004895 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004896 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004897 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004898 up_write(&dmar_global_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004899
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004900 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004901
Qian Cai2d48ea02020-03-05 15:00:46 -05004902 down_read(&dmar_global_lock);
Joerg Roedel39ab9552017-02-01 16:56:46 +01004903 for_each_active_iommu(iommu, drhd) {
4904 iommu_device_sysfs_add(&iommu->iommu, NULL,
4905 intel_iommu_groups,
4906 "%s", iommu->name);
4907 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4908 iommu_device_register(&iommu->iommu);
4909 }
Qian Cai2d48ea02020-03-05 15:00:46 -05004910 up_read(&dmar_global_lock);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004911
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004912 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Jiang Liu75f05562014-02-19 14:07:37 +08004913 if (si_domain && !hw_pass_through)
4914 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004915 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4916 intel_iommu_cpu_dead);
Lu Baolud8190dc2019-05-25 13:41:25 +08004917
Lu Baolud5692d42019-06-12 08:28:49 +08004918 down_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08004919 if (probe_acpi_namespace_devices())
4920 pr_warn("ACPI name space devices didn't probe correctly\n");
4921
Lu Baolud8190dc2019-05-25 13:41:25 +08004922 /* Finally, we enable the DMA remapping hardware. */
4923 for_each_iommu(iommu, drhd) {
Lu Baolu6a8c6742019-06-12 08:28:47 +08004924 if (!drhd->ignored && !translation_pre_enabled(iommu))
Lu Baolud8190dc2019-05-25 13:41:25 +08004925 iommu_enable_translation(iommu);
4926
4927 iommu_disable_protect_mem_regions(iommu);
4928 }
Qian Cai2d48ea02020-03-05 15:00:46 -05004929 up_read(&dmar_global_lock);
4930
Lu Baolud8190dc2019-05-25 13:41:25 +08004931 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
4932
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004933 intel_iommu_enabled = 1;
4934
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004935 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004936
4937out_free_reserved_range:
4938 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004939out_free_dmar:
4940 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004941 up_write(&dmar_global_lock);
4942 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004943 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004944}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004945
Lu Baolu0ce4a852019-08-26 16:50:56 +08004946static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
4947{
4948 struct intel_iommu *iommu = opaque;
4949
4950 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
4951 return 0;
4952}
4953
4954/*
4955 * NB - intel-iommu lacks any sort of reference counting for the users of
4956 * dependent devices. If multiple endpoints have intersecting dependent
4957 * devices, unbinding the driver from any one of them will possibly leave
4958 * the others unable to operate.
4959 */
4960static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
4961{
4962 if (!iommu || !dev || !dev_is_pci(dev))
4963 return;
4964
4965 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
4966}
4967
Joerg Roedel127c7612015-07-23 17:44:46 +02004968static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004969{
Lu Baolu942067f2019-05-25 13:41:29 +08004970 struct dmar_domain *domain;
Weidong Hanc7151a82008-12-08 22:51:37 +08004971 struct intel_iommu *iommu;
4972 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004973
Joerg Roedel55d94042015-07-22 16:50:40 +02004974 assert_spin_locked(&device_domain_lock);
4975
Joerg Roedelb608ac32015-07-21 18:19:08 +02004976 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004977 return;
4978
Joerg Roedel127c7612015-07-23 17:44:46 +02004979 iommu = info->iommu;
Lu Baolu942067f2019-05-25 13:41:29 +08004980 domain = info->domain;
Joerg Roedel127c7612015-07-23 17:44:46 +02004981
4982 if (info->dev) {
Lu Baoluef848b72018-12-10 09:59:01 +08004983 if (dev_is_pci(info->dev) && sm_supported(iommu))
4984 intel_pasid_tear_down_entry(iommu, info->dev,
Lu Baolu37e91bd2020-05-16 14:20:57 +08004985 PASID_RID2PASID, false);
Lu Baoluef848b72018-12-10 09:59:01 +08004986
Joerg Roedel127c7612015-07-23 17:44:46 +02004987 iommu_disable_dev_iotlb(info);
Jon Derrick8038bdb2020-05-27 10:56:15 -06004988 if (!dev_is_real_dma_subdevice(info->dev))
4989 domain_context_clear(iommu, info->dev);
Lu Baolua7fc93f2018-07-14 15:47:00 +08004990 intel_pasid_free_table(info->dev);
Joerg Roedel127c7612015-07-23 17:44:46 +02004991 }
4992
Joerg Roedelb608ac32015-07-21 18:19:08 +02004993 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004994
Joerg Roedeld160aca2015-07-22 11:52:53 +02004995 spin_lock_irqsave(&iommu->lock, flags);
Lu Baolu942067f2019-05-25 13:41:29 +08004996 domain_detach_iommu(domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004997 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004998
4999 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08005000}
5001
Bjorn Helgaas71753232019-02-08 16:06:15 -06005002static void dmar_remove_one_dev_info(struct device *dev)
Joerg Roedel55d94042015-07-22 16:50:40 +02005003{
Joerg Roedel127c7612015-07-23 17:44:46 +02005004 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02005005 unsigned long flags;
5006
Weidong Hanc7151a82008-12-08 22:51:37 +08005007 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolue85bb992020-05-16 14:20:52 +08005008 info = get_domain_info(dev);
5009 if (info)
Lu Baoluae23bfb62019-08-06 08:14:08 +08005010 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005011 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005012}
5013
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005014static int md_domain_init(struct dmar_domain *domain, int guest_width)
5015{
5016 int adjust_width;
5017
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005018 /* calculate AGAW */
5019 domain->gaw = guest_width;
5020 adjust_width = guestwidth_to_adjustwidth(guest_width);
5021 domain->agaw = width_to_agaw(adjust_width);
5022
5023 domain->iommu_coherency = 0;
5024 domain->iommu_snooping = 0;
5025 domain->iommu_superpage = 0;
5026 domain->max_addr = 0;
5027
5028 /* always allocate the top pgd */
5029 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
5030 if (!domain->pgd)
5031 return -ENOMEM;
5032 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5033 return 0;
5034}
5035
Tom Murphye70b0812020-05-16 14:21:01 +08005036static void intel_init_iova_domain(struct dmar_domain *dmar_domain)
5037{
5038 init_iova_domain(&dmar_domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
5039 copy_reserved_iova(&reserved_iova_list, &dmar_domain->iovad);
5040
5041 if (!intel_iommu_strict &&
5042 init_iova_flush_queue(&dmar_domain->iovad,
5043 iommu_flush_iova, iova_entry_free))
5044 pr_info("iova flush queue initialization failed\n");
5045}
5046
Joerg Roedel00a77de2015-03-26 13:43:08 +01005047static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03005048{
Joerg Roedel5d450802008-12-03 14:52:32 +01005049 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005050 struct iommu_domain *domain;
5051
Lu Baolu4de354e2019-05-25 13:41:27 +08005052 switch (type) {
Lu Baolufa954e62019-05-25 13:41:28 +08005053 case IOMMU_DOMAIN_DMA:
5054 /* fallthrough */
Lu Baolu4de354e2019-05-25 13:41:27 +08005055 case IOMMU_DOMAIN_UNMANAGED:
Lu Baolufa954e62019-05-25 13:41:28 +08005056 dmar_domain = alloc_domain(0);
Lu Baolu4de354e2019-05-25 13:41:27 +08005057 if (!dmar_domain) {
5058 pr_err("Can't allocate dmar_domain\n");
5059 return NULL;
5060 }
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005061 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Lu Baolu4de354e2019-05-25 13:41:27 +08005062 pr_err("Domain initialization failed\n");
5063 domain_exit(dmar_domain);
5064 return NULL;
5065 }
Lu Baolufa954e62019-05-25 13:41:28 +08005066
Tom Murphye70b0812020-05-16 14:21:01 +08005067 if (type == IOMMU_DOMAIN_DMA)
5068 intel_init_iova_domain(dmar_domain);
Lu Baolufa954e62019-05-25 13:41:28 +08005069
Lu Baolu4de354e2019-05-25 13:41:27 +08005070 domain_update_iommu_cap(dmar_domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005071
Lu Baolu4de354e2019-05-25 13:41:27 +08005072 domain = &dmar_domain->domain;
5073 domain->geometry.aperture_start = 0;
5074 domain->geometry.aperture_end =
5075 __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5076 domain->geometry.force_aperture = true;
5077
5078 return domain;
5079 case IOMMU_DOMAIN_IDENTITY:
5080 return &si_domain->domain;
5081 default:
Joerg Roedel00a77de2015-03-26 13:43:08 +01005082 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005083 }
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005084
Lu Baolu4de354e2019-05-25 13:41:27 +08005085 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005086}
Kay, Allen M38717942008-09-09 18:37:29 +03005087
Joerg Roedel00a77de2015-03-26 13:43:08 +01005088static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005089{
Lu Baolu4de354e2019-05-25 13:41:27 +08005090 if (domain != &si_domain->domain)
5091 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005092}
Kay, Allen M38717942008-09-09 18:37:29 +03005093
Lu Baolu67b8e022019-03-25 09:30:32 +08005094/*
5095 * Check whether a @domain could be attached to the @dev through the
5096 * aux-domain attach/detach APIs.
5097 */
5098static inline bool
5099is_aux_domain(struct device *dev, struct iommu_domain *domain)
5100{
Lu Baolue85bb992020-05-16 14:20:52 +08005101 struct device_domain_info *info = get_domain_info(dev);
Lu Baolu67b8e022019-03-25 09:30:32 +08005102
5103 return info && info->auxd_enabled &&
5104 domain->type == IOMMU_DOMAIN_UNMANAGED;
5105}
5106
5107static void auxiliary_link_device(struct dmar_domain *domain,
5108 struct device *dev)
5109{
Lu Baolue85bb992020-05-16 14:20:52 +08005110 struct device_domain_info *info = get_domain_info(dev);
Lu Baolu67b8e022019-03-25 09:30:32 +08005111
5112 assert_spin_locked(&device_domain_lock);
5113 if (WARN_ON(!info))
5114 return;
5115
5116 domain->auxd_refcnt++;
5117 list_add(&domain->auxd, &info->auxiliary_domains);
5118}
5119
5120static void auxiliary_unlink_device(struct dmar_domain *domain,
5121 struct device *dev)
5122{
Lu Baolue85bb992020-05-16 14:20:52 +08005123 struct device_domain_info *info = get_domain_info(dev);
Lu Baolu67b8e022019-03-25 09:30:32 +08005124
5125 assert_spin_locked(&device_domain_lock);
5126 if (WARN_ON(!info))
5127 return;
5128
5129 list_del(&domain->auxd);
5130 domain->auxd_refcnt--;
5131
5132 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005133 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005134}
5135
5136static int aux_domain_add_dev(struct dmar_domain *domain,
5137 struct device *dev)
5138{
5139 int ret;
5140 u8 bus, devfn;
5141 unsigned long flags;
5142 struct intel_iommu *iommu;
5143
5144 iommu = device_to_iommu(dev, &bus, &devfn);
5145 if (!iommu)
5146 return -ENODEV;
5147
5148 if (domain->default_pasid <= 0) {
5149 int pasid;
5150
Jacob Pan59a62332020-01-02 08:18:08 +08005151 /* No private data needed for the default pasid */
5152 pasid = ioasid_alloc(NULL, PASID_MIN,
5153 pci_max_pasids(to_pci_dev(dev)) - 1,
5154 NULL);
5155 if (pasid == INVALID_IOASID) {
Lu Baolu67b8e022019-03-25 09:30:32 +08005156 pr_err("Can't allocate default pasid\n");
5157 return -ENODEV;
5158 }
5159 domain->default_pasid = pasid;
5160 }
5161
5162 spin_lock_irqsave(&device_domain_lock, flags);
5163 /*
5164 * iommu->lock must be held to attach domain to iommu and setup the
5165 * pasid entry for second level translation.
5166 */
5167 spin_lock(&iommu->lock);
5168 ret = domain_attach_iommu(domain, iommu);
5169 if (ret)
5170 goto attach_failed;
5171
5172 /* Setup the PASID entry for mediated devices: */
Lu Baoluddf09b62020-01-02 08:18:17 +08005173 if (domain_use_first_level(domain))
5174 ret = domain_setup_first_level(iommu, domain, dev,
5175 domain->default_pasid);
5176 else
5177 ret = intel_pasid_setup_second_level(iommu, domain, dev,
5178 domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005179 if (ret)
5180 goto table_failed;
5181 spin_unlock(&iommu->lock);
5182
5183 auxiliary_link_device(domain, dev);
5184
5185 spin_unlock_irqrestore(&device_domain_lock, flags);
5186
5187 return 0;
5188
5189table_failed:
5190 domain_detach_iommu(domain, iommu);
5191attach_failed:
5192 spin_unlock(&iommu->lock);
5193 spin_unlock_irqrestore(&device_domain_lock, flags);
5194 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005195 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005196
5197 return ret;
5198}
5199
5200static void aux_domain_remove_dev(struct dmar_domain *domain,
5201 struct device *dev)
5202{
5203 struct device_domain_info *info;
5204 struct intel_iommu *iommu;
5205 unsigned long flags;
5206
5207 if (!is_aux_domain(dev, &domain->domain))
5208 return;
5209
5210 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolue85bb992020-05-16 14:20:52 +08005211 info = get_domain_info(dev);
Lu Baolu67b8e022019-03-25 09:30:32 +08005212 iommu = info->iommu;
5213
5214 auxiliary_unlink_device(domain, dev);
5215
5216 spin_lock(&iommu->lock);
Lu Baolu37e91bd2020-05-16 14:20:57 +08005217 intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid, false);
Lu Baolu67b8e022019-03-25 09:30:32 +08005218 domain_detach_iommu(domain, iommu);
5219 spin_unlock(&iommu->lock);
5220
5221 spin_unlock_irqrestore(&device_domain_lock, flags);
5222}
5223
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005224static int prepare_domain_attach_device(struct iommu_domain *domain,
5225 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005226{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005227 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005228 struct intel_iommu *iommu;
5229 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005230 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005231
David Woodhouse156baca2014-03-09 14:00:57 -07005232 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005233 if (!iommu)
5234 return -ENODEV;
5235
5236 /* check if this iommu agaw is sufficient for max mapped address */
5237 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005238 if (addr_width > cap_mgaw(iommu->cap))
5239 addr_width = cap_mgaw(iommu->cap);
5240
5241 if (dmar_domain->max_addr > (1LL << addr_width)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06005242 dev_err(dev, "%s: iommu width (%d) is not "
5243 "sufficient for the mapped address (%llx)\n",
5244 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005245 return -EFAULT;
5246 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005247 dmar_domain->gaw = addr_width;
5248
5249 /*
5250 * Knock out extra levels of page tables if necessary
5251 */
5252 while (iommu->agaw < dmar_domain->agaw) {
5253 struct dma_pte *pte;
5254
5255 pte = dmar_domain->pgd;
5256 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005257 dmar_domain->pgd = (struct dma_pte *)
5258 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005259 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005260 }
5261 dmar_domain->agaw--;
5262 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005263
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005264 return 0;
5265}
5266
5267static int intel_iommu_attach_device(struct iommu_domain *domain,
5268 struct device *dev)
5269{
5270 int ret;
5271
Lu Baolu56795822019-06-12 08:28:48 +08005272 if (domain->type == IOMMU_DOMAIN_UNMANAGED &&
5273 device_is_rmrr_locked(dev)) {
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005274 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5275 return -EPERM;
5276 }
5277
Lu Baolu67b8e022019-03-25 09:30:32 +08005278 if (is_aux_domain(dev, domain))
5279 return -EPERM;
5280
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005281 /* normally dev is not mapped */
5282 if (unlikely(domain_context_mapped(dev))) {
5283 struct dmar_domain *old_domain;
5284
5285 old_domain = find_domain(dev);
Lu Baolufa954e62019-05-25 13:41:28 +08005286 if (old_domain)
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005287 dmar_remove_one_dev_info(dev);
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005288 }
5289
5290 ret = prepare_domain_attach_device(domain, dev);
5291 if (ret)
5292 return ret;
5293
5294 return domain_add_dev_info(to_dmar_domain(domain), dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005295}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005296
Lu Baolu67b8e022019-03-25 09:30:32 +08005297static int intel_iommu_aux_attach_device(struct iommu_domain *domain,
5298 struct device *dev)
5299{
5300 int ret;
5301
5302 if (!is_aux_domain(dev, domain))
5303 return -EPERM;
5304
5305 ret = prepare_domain_attach_device(domain, dev);
5306 if (ret)
5307 return ret;
5308
5309 return aux_domain_add_dev(to_dmar_domain(domain), dev);
5310}
5311
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005312static void intel_iommu_detach_device(struct iommu_domain *domain,
5313 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005314{
Bjorn Helgaas71753232019-02-08 16:06:15 -06005315 dmar_remove_one_dev_info(dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005316}
Kay, Allen M38717942008-09-09 18:37:29 +03005317
Lu Baolu67b8e022019-03-25 09:30:32 +08005318static void intel_iommu_aux_detach_device(struct iommu_domain *domain,
5319 struct device *dev)
5320{
5321 aux_domain_remove_dev(to_dmar_domain(domain), dev);
5322}
5323
Jacob Pan6ee1b772020-05-16 14:20:49 +08005324/*
5325 * 2D array for converting and sanitizing IOMMU generic TLB granularity to
5326 * VT-d granularity. Invalidation is typically included in the unmap operation
5327 * as a result of DMA or VFIO unmap. However, for assigned devices guest
5328 * owns the first level page tables. Invalidations of translation caches in the
5329 * guest are trapped and passed down to the host.
5330 *
5331 * vIOMMU in the guest will only expose first level page tables, therefore
5332 * we do not support IOTLB granularity for request without PASID (second level).
5333 *
5334 * For example, to find the VT-d granularity encoding for IOTLB
5335 * type and page selective granularity within PASID:
5336 * X: indexed by iommu cache type
5337 * Y: indexed by enum iommu_inv_granularity
5338 * [IOMMU_CACHE_INV_TYPE_IOTLB][IOMMU_INV_GRANU_ADDR]
5339 */
5340
Qian Cai7809c4d2020-05-21 17:50:30 -04005341static const int
Jacob Pan6ee1b772020-05-16 14:20:49 +08005342inv_type_granu_table[IOMMU_CACHE_INV_TYPE_NR][IOMMU_INV_GRANU_NR] = {
5343 /*
5344 * PASID based IOTLB invalidation: PASID selective (per PASID),
5345 * page selective (address granularity)
5346 */
5347 {-EINVAL, QI_GRAN_NONG_PASID, QI_GRAN_PSI_PASID},
5348 /* PASID based dev TLBs */
5349 {-EINVAL, -EINVAL, QI_DEV_IOTLB_GRAN_PASID_SEL},
5350 /* PASID cache */
5351 {-EINVAL, -EINVAL, -EINVAL}
5352};
5353
5354static inline int to_vtd_granularity(int type, int granu)
5355{
5356 return inv_type_granu_table[type][granu];
5357}
5358
5359static inline u64 to_vtd_size(u64 granu_size, u64 nr_granules)
5360{
5361 u64 nr_pages = (granu_size * nr_granules) >> VTD_PAGE_SHIFT;
5362
5363 /* VT-d size is encoded as 2^size of 4K pages, 0 for 4k, 9 for 2MB, etc.
5364 * IOMMU cache invalidate API passes granu_size in bytes, and number of
5365 * granu size in contiguous memory.
5366 */
5367 return order_base_2(nr_pages);
5368}
5369
5370#ifdef CONFIG_INTEL_IOMMU_SVM
5371static int
5372intel_iommu_sva_invalidate(struct iommu_domain *domain, struct device *dev,
5373 struct iommu_cache_invalidate_info *inv_info)
5374{
5375 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5376 struct device_domain_info *info;
5377 struct intel_iommu *iommu;
5378 unsigned long flags;
5379 int cache_type;
5380 u8 bus, devfn;
5381 u16 did, sid;
5382 int ret = 0;
5383 u64 size = 0;
5384
5385 if (!inv_info || !dmar_domain ||
5386 inv_info->version != IOMMU_CACHE_INVALIDATE_INFO_VERSION_1)
5387 return -EINVAL;
5388
5389 if (!dev || !dev_is_pci(dev))
5390 return -ENODEV;
5391
5392 iommu = device_to_iommu(dev, &bus, &devfn);
5393 if (!iommu)
5394 return -ENODEV;
5395
5396 if (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE))
5397 return -EINVAL;
5398
5399 spin_lock_irqsave(&device_domain_lock, flags);
5400 spin_lock(&iommu->lock);
Lu Baolue85bb992020-05-16 14:20:52 +08005401 info = get_domain_info(dev);
Jacob Pan6ee1b772020-05-16 14:20:49 +08005402 if (!info) {
5403 ret = -EINVAL;
5404 goto out_unlock;
5405 }
5406 did = dmar_domain->iommu_did[iommu->seq_id];
5407 sid = PCI_DEVID(bus, devfn);
5408
5409 /* Size is only valid in address selective invalidation */
5410 if (inv_info->granularity != IOMMU_INV_GRANU_PASID)
5411 size = to_vtd_size(inv_info->addr_info.granule_size,
5412 inv_info->addr_info.nb_granules);
5413
5414 for_each_set_bit(cache_type,
5415 (unsigned long *)&inv_info->cache,
5416 IOMMU_CACHE_INV_TYPE_NR) {
5417 int granu = 0;
5418 u64 pasid = 0;
5419
5420 granu = to_vtd_granularity(cache_type, inv_info->granularity);
5421 if (granu == -EINVAL) {
5422 pr_err_ratelimited("Invalid cache type and granu combination %d/%d\n",
5423 cache_type, inv_info->granularity);
5424 break;
5425 }
5426
5427 /*
5428 * PASID is stored in different locations based on the
5429 * granularity.
5430 */
5431 if (inv_info->granularity == IOMMU_INV_GRANU_PASID &&
5432 (inv_info->pasid_info.flags & IOMMU_INV_PASID_FLAGS_PASID))
5433 pasid = inv_info->pasid_info.pasid;
5434 else if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
5435 (inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_PASID))
5436 pasid = inv_info->addr_info.pasid;
5437
5438 switch (BIT(cache_type)) {
5439 case IOMMU_CACHE_INV_TYPE_IOTLB:
5440 if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
5441 size &&
5442 (inv_info->addr_info.addr & ((BIT(VTD_PAGE_SHIFT + size)) - 1))) {
5443 pr_err_ratelimited("Address out of range, 0x%llx, size order %llu\n",
5444 inv_info->addr_info.addr, size);
5445 ret = -ERANGE;
5446 goto out_unlock;
5447 }
5448
5449 /*
5450 * If granu is PASID-selective, address is ignored.
5451 * We use npages = -1 to indicate that.
5452 */
5453 qi_flush_piotlb(iommu, did, pasid,
5454 mm_to_dma_pfn(inv_info->addr_info.addr),
5455 (granu == QI_GRAN_NONG_PASID) ? -1 : 1 << size,
5456 inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_LEAF);
5457
5458 /*
5459 * Always flush device IOTLB if ATS is enabled. vIOMMU
5460 * in the guest may assume IOTLB flush is inclusive,
5461 * which is more efficient.
5462 */
5463 if (info->ats_enabled)
5464 qi_flush_dev_iotlb_pasid(iommu, sid,
5465 info->pfsid, pasid,
5466 info->ats_qdep,
5467 inv_info->addr_info.addr,
5468 size, granu);
5469 break;
5470 case IOMMU_CACHE_INV_TYPE_DEV_IOTLB:
5471 if (info->ats_enabled)
5472 qi_flush_dev_iotlb_pasid(iommu, sid,
5473 info->pfsid, pasid,
5474 info->ats_qdep,
5475 inv_info->addr_info.addr,
5476 size, granu);
5477 else
5478 pr_warn_ratelimited("Passdown device IOTLB flush w/o ATS!\n");
5479 break;
5480 default:
5481 dev_err_ratelimited(dev, "Unsupported IOMMU invalidation type %d\n",
5482 cache_type);
5483 ret = -EINVAL;
5484 }
5485 }
5486out_unlock:
5487 spin_unlock(&iommu->lock);
5488 spin_unlock_irqrestore(&device_domain_lock, flags);
5489
5490 return ret;
5491}
5492#endif
5493
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005494static int intel_iommu_map(struct iommu_domain *domain,
5495 unsigned long iova, phys_addr_t hpa,
Tom Murphy781ca2d2019-09-08 09:56:38 -07005496 size_t size, int iommu_prot, gfp_t gfp)
Kay, Allen M38717942008-09-09 18:37:29 +03005497{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005498 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005499 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005500 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005501 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005502
Joerg Roedeldde57a22008-12-03 15:04:09 +01005503 if (iommu_prot & IOMMU_READ)
5504 prot |= DMA_PTE_READ;
5505 if (iommu_prot & IOMMU_WRITE)
5506 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005507 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5508 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005509
David Woodhouse163cc522009-06-28 00:51:17 +01005510 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005511 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005512 u64 end;
5513
5514 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005515 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005516 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005517 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005518 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005519 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005520 return -EFAULT;
5521 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005522 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005523 }
David Woodhousead051222009-06-28 14:22:28 +01005524 /* Round up size to next multiple of PAGE_SIZE, if it and
5525 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005526 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005527 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5528 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005529 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005530}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005531
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005532static size_t intel_iommu_unmap(struct iommu_domain *domain,
Will Deacon56f8af52019-07-02 16:44:06 +01005533 unsigned long iova, size_t size,
5534 struct iommu_iotlb_gather *gather)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005535{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005536 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005537 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005538 unsigned long start_pfn, last_pfn;
5539 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005540 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005541
David Woodhouse5cf0a762014-03-19 16:07:49 +00005542 /* Cope with horrid API which requires us to unmap more than the
5543 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005544 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005545
5546 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5547 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5548
David Woodhouseea8ea462014-03-05 17:09:32 +00005549 start_pfn = iova >> VTD_PAGE_SHIFT;
5550 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5551
5552 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5553
5554 npages = last_pfn - start_pfn + 1;
5555
Shaokun Zhangf746a022018-03-22 18:18:06 +08005556 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005557 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5558 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005559
5560 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005561
David Woodhouse163cc522009-06-28 00:51:17 +01005562 if (dmar_domain->max_addr == iova + size)
5563 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005564
David Woodhouse5cf0a762014-03-19 16:07:49 +00005565 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005566}
Kay, Allen M38717942008-09-09 18:37:29 +03005567
Joerg Roedeld14d6572008-12-03 15:06:57 +01005568static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305569 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005570{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005571 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005572 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005573 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005574 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005575
David Woodhouse5cf0a762014-03-19 16:07:49 +00005576 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Yonghyun Hwang77a1bce2020-02-26 12:30:06 -08005577 if (pte && dma_pte_present(pte))
5578 phys = dma_pte_addr(pte) +
5579 (iova & (BIT_MASK(level_to_offset_bits(level) +
5580 VTD_PAGE_SHIFT) - 1));
Kay, Allen M38717942008-09-09 18:37:29 +03005581
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005582 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005583}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005584
Lu Baolu95587a72019-03-25 09:30:30 +08005585static inline bool scalable_mode_support(void)
5586{
5587 struct dmar_drhd_unit *drhd;
5588 struct intel_iommu *iommu;
5589 bool ret = true;
5590
5591 rcu_read_lock();
5592 for_each_active_iommu(iommu, drhd) {
5593 if (!sm_supported(iommu)) {
5594 ret = false;
5595 break;
5596 }
5597 }
5598 rcu_read_unlock();
5599
5600 return ret;
5601}
5602
5603static inline bool iommu_pasid_support(void)
5604{
5605 struct dmar_drhd_unit *drhd;
5606 struct intel_iommu *iommu;
5607 bool ret = true;
5608
5609 rcu_read_lock();
5610 for_each_active_iommu(iommu, drhd) {
5611 if (!pasid_supported(iommu)) {
5612 ret = false;
5613 break;
5614 }
5615 }
5616 rcu_read_unlock();
5617
5618 return ret;
5619}
5620
Lu Baolu2cd13112020-01-02 08:18:15 +08005621static inline bool nested_mode_support(void)
5622{
5623 struct dmar_drhd_unit *drhd;
5624 struct intel_iommu *iommu;
5625 bool ret = true;
5626
5627 rcu_read_lock();
5628 for_each_active_iommu(iommu, drhd) {
5629 if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
5630 ret = false;
5631 break;
5632 }
5633 }
5634 rcu_read_unlock();
5635
5636 return ret;
5637}
5638
Joerg Roedel5d587b82014-09-05 10:50:45 +02005639static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005640{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005641 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005642 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005643 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005644 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005645
Joerg Roedel5d587b82014-09-05 10:50:45 +02005646 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005647}
5648
Joerg Roedele5d18412020-04-29 15:36:54 +02005649static struct iommu_device *intel_iommu_probe_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005650{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005651 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07005652 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005653
Alex Williamsona5459cf2014-06-12 16:12:31 -06005654 iommu = device_to_iommu(dev, &bus, &devfn);
5655 if (!iommu)
Joerg Roedele5d18412020-04-29 15:36:54 +02005656 return ERR_PTR(-ENODEV);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005657
Lu Baolu8af46c72019-05-25 13:41:32 +08005658 if (translation_pre_enabled(iommu))
5659 dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
5660
Joerg Roedele5d18412020-04-29 15:36:54 +02005661 return &iommu->iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005662}
5663
Joerg Roedele5d18412020-04-29 15:36:54 +02005664static void intel_iommu_release_device(struct device *dev)
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005665{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005666 struct intel_iommu *iommu;
5667 u8 bus, devfn;
5668
5669 iommu = device_to_iommu(dev, &bus, &devfn);
5670 if (!iommu)
5671 return;
5672
Lu Baolu458b7c82019-08-01 11:14:58 +08005673 dmar_remove_one_dev_info(dev);
5674
Lu Baolu6fc70202020-05-06 09:59:47 +08005675 set_dma_ops(dev, NULL);
5676}
Alex Williamsona5459cf2014-06-12 16:12:31 -06005677
Lu Baolu6fc70202020-05-06 09:59:47 +08005678static void intel_iommu_probe_finalize(struct device *dev)
5679{
5680 struct iommu_domain *domain;
Lu Baolucfb94a32019-09-06 14:14:52 +08005681
Lu Baolu6fc70202020-05-06 09:59:47 +08005682 domain = iommu_get_domain_for_dev(dev);
Lu Baolucfb94a32019-09-06 14:14:52 +08005683 if (device_needs_bounce(dev))
Lu Baolu6fc70202020-05-06 09:59:47 +08005684 set_dma_ops(dev, &bounce_dma_ops);
5685 else if (domain && domain->type == IOMMU_DOMAIN_DMA)
5686 set_dma_ops(dev, &intel_dma_ops);
5687 else
Lu Baolucfb94a32019-09-06 14:14:52 +08005688 set_dma_ops(dev, NULL);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005689}
5690
Eric Auger0659b8d2017-01-19 20:57:53 +00005691static void intel_iommu_get_resv_regions(struct device *device,
5692 struct list_head *head)
5693{
Eric Auger5f64ce52019-06-03 08:53:31 +02005694 int prot = DMA_PTE_READ | DMA_PTE_WRITE;
Eric Auger0659b8d2017-01-19 20:57:53 +00005695 struct iommu_resv_region *reg;
5696 struct dmar_rmrr_unit *rmrr;
5697 struct device *i_dev;
5698 int i;
5699
Eric Auger5f64ce52019-06-03 08:53:31 +02005700 down_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005701 for_each_rmrr_units(rmrr) {
5702 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5703 i, i_dev) {
Eric Auger5f64ce52019-06-03 08:53:31 +02005704 struct iommu_resv_region *resv;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005705 enum iommu_resv_type type;
Eric Auger5f64ce52019-06-03 08:53:31 +02005706 size_t length;
5707
Eric Auger3855ba22019-06-03 08:53:34 +02005708 if (i_dev != device &&
5709 !is_downstream_to_pci_bridge(device, i_dev))
Eric Auger0659b8d2017-01-19 20:57:53 +00005710 continue;
5711
Eric Auger5f64ce52019-06-03 08:53:31 +02005712 length = rmrr->end_address - rmrr->base_address + 1;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005713
5714 type = device_rmrr_is_relaxable(device) ?
5715 IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;
5716
Eric Auger5f64ce52019-06-03 08:53:31 +02005717 resv = iommu_alloc_resv_region(rmrr->base_address,
Eric Auger1c5c59f2019-06-03 08:53:36 +02005718 length, prot, type);
Eric Auger5f64ce52019-06-03 08:53:31 +02005719 if (!resv)
5720 break;
5721
5722 list_add_tail(&resv->list, head);
Eric Auger0659b8d2017-01-19 20:57:53 +00005723 }
5724 }
Eric Auger5f64ce52019-06-03 08:53:31 +02005725 up_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005726
Lu Baolud850c2e2019-05-25 13:41:24 +08005727#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
5728 if (dev_is_pci(device)) {
5729 struct pci_dev *pdev = to_pci_dev(device);
5730
5731 if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) {
Jerry Snitselaarcde93192019-12-12 22:36:42 -07005732 reg = iommu_alloc_resv_region(0, 1UL << 24, prot,
Alex Williamsond8018a02019-12-11 13:28:29 -07005733 IOMMU_RESV_DIRECT_RELAXABLE);
Lu Baolud850c2e2019-05-25 13:41:24 +08005734 if (reg)
5735 list_add_tail(&reg->list, head);
5736 }
5737 }
5738#endif /* CONFIG_INTEL_IOMMU_FLOPPY_WA */
5739
Eric Auger0659b8d2017-01-19 20:57:53 +00005740 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5741 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005742 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005743 if (!reg)
5744 return;
5745 list_add_tail(&reg->list, head);
5746}
5747
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005748int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005749{
5750 struct device_domain_info *info;
5751 struct context_entry *context;
5752 struct dmar_domain *domain;
5753 unsigned long flags;
5754 u64 ctx_lo;
5755 int ret;
5756
Lu Baolu4ec066c2019-05-25 13:41:33 +08005757 domain = find_domain(dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005758 if (!domain)
5759 return -EINVAL;
5760
5761 spin_lock_irqsave(&device_domain_lock, flags);
5762 spin_lock(&iommu->lock);
5763
5764 ret = -EINVAL;
Lu Baolue85bb992020-05-16 14:20:52 +08005765 info = get_domain_info(dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005766 if (!info || !info->pasid_supported)
5767 goto out;
5768
5769 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5770 if (WARN_ON(!context))
5771 goto out;
5772
5773 ctx_lo = context[0].lo;
5774
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005775 if (!(ctx_lo & CONTEXT_PASIDE)) {
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005776 ctx_lo |= CONTEXT_PASIDE;
5777 context[0].lo = ctx_lo;
5778 wmb();
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005779 iommu->flush.flush_context(iommu,
5780 domain->iommu_did[iommu->seq_id],
5781 PCI_DEVID(info->bus, info->devfn),
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005782 DMA_CCMD_MASK_NOBIT,
5783 DMA_CCMD_DEVICE_INVL);
5784 }
5785
5786 /* Enable PASID support in the device, if it wasn't already */
5787 if (!info->pasid_enabled)
5788 iommu_enable_dev_iotlb(info);
5789
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005790 ret = 0;
5791
5792 out:
5793 spin_unlock(&iommu->lock);
5794 spin_unlock_irqrestore(&device_domain_lock, flags);
5795
5796 return ret;
5797}
5798
James Sewart73bcbdc2019-05-25 13:41:23 +08005799static void intel_iommu_apply_resv_region(struct device *dev,
5800 struct iommu_domain *domain,
5801 struct iommu_resv_region *region)
5802{
5803 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5804 unsigned long start, end;
5805
5806 start = IOVA_PFN(region->start);
5807 end = IOVA_PFN(region->start + region->length - 1);
5808
5809 WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end));
5810}
5811
Patrick Steinhardt4a350a02019-12-27 00:56:18 +01005812static struct iommu_group *intel_iommu_device_group(struct device *dev)
5813{
5814 if (dev_is_pci(dev))
5815 return pci_device_group(dev);
5816 return generic_device_group(dev);
5817}
5818
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005819#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005820struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5821{
5822 struct intel_iommu *iommu;
5823 u8 bus, devfn;
5824
5825 if (iommu_dummy(dev)) {
5826 dev_warn(dev,
5827 "No IOMMU translation for device; cannot enable SVM\n");
5828 return NULL;
5829 }
5830
5831 iommu = device_to_iommu(dev, &bus, &devfn);
5832 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005833 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005834 return NULL;
5835 }
5836
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005837 return iommu;
5838}
5839#endif /* CONFIG_INTEL_IOMMU_SVM */
5840
Lu Baolu95587a72019-03-25 09:30:30 +08005841static int intel_iommu_enable_auxd(struct device *dev)
5842{
5843 struct device_domain_info *info;
5844 struct intel_iommu *iommu;
5845 unsigned long flags;
5846 u8 bus, devfn;
5847 int ret;
5848
5849 iommu = device_to_iommu(dev, &bus, &devfn);
5850 if (!iommu || dmar_disabled)
5851 return -EINVAL;
5852
5853 if (!sm_supported(iommu) || !pasid_supported(iommu))
5854 return -EINVAL;
5855
5856 ret = intel_iommu_enable_pasid(iommu, dev);
5857 if (ret)
5858 return -ENODEV;
5859
5860 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolue85bb992020-05-16 14:20:52 +08005861 info = get_domain_info(dev);
Lu Baolu95587a72019-03-25 09:30:30 +08005862 info->auxd_enabled = 1;
5863 spin_unlock_irqrestore(&device_domain_lock, flags);
5864
5865 return 0;
5866}
5867
5868static int intel_iommu_disable_auxd(struct device *dev)
5869{
5870 struct device_domain_info *info;
5871 unsigned long flags;
5872
5873 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolue85bb992020-05-16 14:20:52 +08005874 info = get_domain_info(dev);
Lu Baolu95587a72019-03-25 09:30:30 +08005875 if (!WARN_ON(!info))
5876 info->auxd_enabled = 0;
5877 spin_unlock_irqrestore(&device_domain_lock, flags);
5878
5879 return 0;
5880}
5881
5882/*
5883 * A PCI express designated vendor specific extended capability is defined
5884 * in the section 3.7 of Intel scalable I/O virtualization technical spec
5885 * for system software and tools to detect endpoint devices supporting the
5886 * Intel scalable IO virtualization without host driver dependency.
5887 *
5888 * Returns the address of the matching extended capability structure within
5889 * the device's PCI configuration space or 0 if the device does not support
5890 * it.
5891 */
5892static int siov_find_pci_dvsec(struct pci_dev *pdev)
5893{
5894 int pos;
5895 u16 vendor, id;
5896
5897 pos = pci_find_next_ext_capability(pdev, 0, 0x23);
5898 while (pos) {
5899 pci_read_config_word(pdev, pos + 4, &vendor);
5900 pci_read_config_word(pdev, pos + 8, &id);
5901 if (vendor == PCI_VENDOR_ID_INTEL && id == 5)
5902 return pos;
5903
5904 pos = pci_find_next_ext_capability(pdev, pos, 0x23);
5905 }
5906
5907 return 0;
5908}
5909
5910static bool
5911intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
5912{
5913 if (feat == IOMMU_DEV_FEAT_AUX) {
5914 int ret;
5915
5916 if (!dev_is_pci(dev) || dmar_disabled ||
5917 !scalable_mode_support() || !iommu_pasid_support())
5918 return false;
5919
5920 ret = pci_pasid_features(to_pci_dev(dev));
5921 if (ret < 0)
5922 return false;
5923
5924 return !!siov_find_pci_dvsec(to_pci_dev(dev));
5925 }
5926
Jacob Pan76fdd6c2020-05-16 14:20:53 +08005927 if (feat == IOMMU_DEV_FEAT_SVA) {
5928 struct device_domain_info *info = get_domain_info(dev);
5929
5930 return info && (info->iommu->flags & VTD_FLAG_SVM_CAPABLE) &&
5931 info->pasid_supported && info->pri_supported &&
5932 info->ats_supported;
5933 }
5934
Lu Baolu95587a72019-03-25 09:30:30 +08005935 return false;
5936}
5937
5938static int
5939intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
5940{
5941 if (feat == IOMMU_DEV_FEAT_AUX)
5942 return intel_iommu_enable_auxd(dev);
5943
Jacob Pan76fdd6c2020-05-16 14:20:53 +08005944 if (feat == IOMMU_DEV_FEAT_SVA) {
5945 struct device_domain_info *info = get_domain_info(dev);
5946
5947 if (!info)
5948 return -EINVAL;
5949
5950 if (info->iommu->flags & VTD_FLAG_SVM_CAPABLE)
5951 return 0;
5952 }
5953
Lu Baolu95587a72019-03-25 09:30:30 +08005954 return -ENODEV;
5955}
5956
5957static int
5958intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
5959{
5960 if (feat == IOMMU_DEV_FEAT_AUX)
5961 return intel_iommu_disable_auxd(dev);
5962
5963 return -ENODEV;
5964}
5965
5966static bool
5967intel_iommu_dev_feat_enabled(struct device *dev, enum iommu_dev_features feat)
5968{
Lu Baolue85bb992020-05-16 14:20:52 +08005969 struct device_domain_info *info = get_domain_info(dev);
Lu Baolu95587a72019-03-25 09:30:30 +08005970
5971 if (feat == IOMMU_DEV_FEAT_AUX)
5972 return scalable_mode_support() && info && info->auxd_enabled;
5973
5974 return false;
5975}
5976
Lu Baolu0e8000f2019-03-25 09:30:33 +08005977static int
5978intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
5979{
5980 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5981
5982 return dmar_domain->default_pasid > 0 ?
5983 dmar_domain->default_pasid : -EINVAL;
5984}
5985
Lu Baolu8af46c72019-05-25 13:41:32 +08005986static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
5987 struct device *dev)
5988{
Joerg Roedel1d46159782020-02-17 17:12:37 +01005989 return attach_deferred(dev);
Lu Baolu8af46c72019-05-25 13:41:32 +08005990}
5991
Lu Baolu2cd13112020-01-02 08:18:15 +08005992static int
5993intel_iommu_domain_set_attr(struct iommu_domain *domain,
5994 enum iommu_attr attr, void *data)
5995{
5996 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5997 unsigned long flags;
5998 int ret = 0;
5999
6000 if (domain->type != IOMMU_DOMAIN_UNMANAGED)
6001 return -EINVAL;
6002
6003 switch (attr) {
6004 case DOMAIN_ATTR_NESTING:
6005 spin_lock_irqsave(&device_domain_lock, flags);
6006 if (nested_mode_support() &&
6007 list_empty(&dmar_domain->devices)) {
6008 dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;
6009 dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;
6010 } else {
6011 ret = -ENODEV;
6012 }
6013 spin_unlock_irqrestore(&device_domain_lock, flags);
6014 break;
6015 default:
6016 ret = -EINVAL;
6017 break;
6018 }
6019
6020 return ret;
6021}
6022
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006023/*
6024 * Check that the device does not live on an external facing PCI port that is
6025 * marked as untrusted. Such devices should not be able to apply quirks and
6026 * thus not be able to bypass the IOMMU restrictions.
6027 */
6028static bool risky_device(struct pci_dev *pdev)
6029{
6030 if (pdev->untrusted) {
6031 pci_info(pdev,
6032 "Skipping IOMMU quirk for dev [%04X:%04X] on untrusted PCI link\n",
6033 pdev->vendor, pdev->device);
6034 pci_info(pdev, "Please check with your BIOS/Platform vendor about this\n");
6035 return true;
6036 }
6037 return false;
6038}
6039
Joerg Roedelb0119e82017-02-01 13:23:08 +01006040const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00006041 .capable = intel_iommu_capable,
6042 .domain_alloc = intel_iommu_domain_alloc,
6043 .domain_free = intel_iommu_domain_free,
Lu Baolu2cd13112020-01-02 08:18:15 +08006044 .domain_set_attr = intel_iommu_domain_set_attr,
Eric Auger0659b8d2017-01-19 20:57:53 +00006045 .attach_dev = intel_iommu_attach_device,
6046 .detach_dev = intel_iommu_detach_device,
Lu Baolu67b8e022019-03-25 09:30:32 +08006047 .aux_attach_dev = intel_iommu_aux_attach_device,
6048 .aux_detach_dev = intel_iommu_aux_detach_device,
Lu Baolu0e8000f2019-03-25 09:30:33 +08006049 .aux_get_pasid = intel_iommu_aux_get_pasid,
Eric Auger0659b8d2017-01-19 20:57:53 +00006050 .map = intel_iommu_map,
6051 .unmap = intel_iommu_unmap,
Eric Auger0659b8d2017-01-19 20:57:53 +00006052 .iova_to_phys = intel_iommu_iova_to_phys,
Joerg Roedele5d18412020-04-29 15:36:54 +02006053 .probe_device = intel_iommu_probe_device,
Lu Baolu6fc70202020-05-06 09:59:47 +08006054 .probe_finalize = intel_iommu_probe_finalize,
Joerg Roedele5d18412020-04-29 15:36:54 +02006055 .release_device = intel_iommu_release_device,
Eric Auger0659b8d2017-01-19 20:57:53 +00006056 .get_resv_regions = intel_iommu_get_resv_regions,
Thierry Reding0ecdebb2019-12-18 14:42:04 +01006057 .put_resv_regions = generic_iommu_put_resv_regions,
James Sewart73bcbdc2019-05-25 13:41:23 +08006058 .apply_resv_region = intel_iommu_apply_resv_region,
Patrick Steinhardt4a350a02019-12-27 00:56:18 +01006059 .device_group = intel_iommu_device_group,
Lu Baolu95587a72019-03-25 09:30:30 +08006060 .dev_has_feat = intel_iommu_dev_has_feat,
6061 .dev_feat_enabled = intel_iommu_dev_feat_enabled,
6062 .dev_enable_feat = intel_iommu_dev_enable_feat,
6063 .dev_disable_feat = intel_iommu_dev_disable_feat,
Lu Baolu8af46c72019-05-25 13:41:32 +08006064 .is_attach_deferred = intel_iommu_is_attach_deferred,
Joerg Roedel7039d112020-04-29 15:36:42 +02006065 .def_domain_type = device_def_domain_type,
Eric Auger0659b8d2017-01-19 20:57:53 +00006066 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Jacob Pan56722a42020-05-16 14:20:47 +08006067#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan6ee1b772020-05-16 14:20:49 +08006068 .cache_invalidate = intel_iommu_sva_invalidate,
Jacob Pan56722a42020-05-16 14:20:47 +08006069 .sva_bind_gpasid = intel_svm_bind_gpasid,
6070 .sva_unbind_gpasid = intel_svm_unbind_gpasid,
Jacob Pan064a57d2020-05-16 14:20:54 +08006071 .sva_bind = intel_svm_bind,
6072 .sva_unbind = intel_svm_unbind,
6073 .sva_get_pasid = intel_svm_get_pasid,
Jacob Pan56722a42020-05-16 14:20:47 +08006074#endif
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01006075};
David Woodhouse9af88142009-02-13 23:18:03 +00006076
Chris Wilson1f762492019-09-09 12:00:10 +01006077static void quirk_iommu_igfx(struct pci_dev *dev)
Daniel Vetter94526182013-01-20 23:50:13 +01006078{
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006079 if (risky_device(dev))
6080 return;
6081
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006082 pci_info(dev, "Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01006083 dmar_map_gfx = 0;
6084}
6085
Chris Wilson1f762492019-09-09 12:00:10 +01006086/* G4x/GM45 integrated gfx dmar support is totally busted. */
6087DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
6088DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
6089DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_igfx);
6090DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_igfx);
6091DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
6092DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
6093DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
6094
6095/* Broadwell igfx malfunctions with dmar */
6096DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
6097DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
6098DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160E, quirk_iommu_igfx);
6099DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1602, quirk_iommu_igfx);
6100DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160A, quirk_iommu_igfx);
6101DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160D, quirk_iommu_igfx);
6102DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1616, quirk_iommu_igfx);
6103DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161B, quirk_iommu_igfx);
6104DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161E, quirk_iommu_igfx);
6105DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1612, quirk_iommu_igfx);
6106DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161A, quirk_iommu_igfx);
6107DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161D, quirk_iommu_igfx);
6108DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1626, quirk_iommu_igfx);
6109DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162B, quirk_iommu_igfx);
6110DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162E, quirk_iommu_igfx);
6111DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1622, quirk_iommu_igfx);
6112DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162A, quirk_iommu_igfx);
6113DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162D, quirk_iommu_igfx);
6114DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1636, quirk_iommu_igfx);
6115DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163B, quirk_iommu_igfx);
6116DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163E, quirk_iommu_igfx);
6117DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
6118DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
6119DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
Daniel Vetter94526182013-01-20 23:50:13 +01006120
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006121static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00006122{
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006123 if (risky_device(dev))
6124 return;
6125
David Woodhouse9af88142009-02-13 23:18:03 +00006126 /*
6127 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01006128 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00006129 */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006130 pci_info(dev, "Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00006131 rwbf_quirk = 1;
6132}
6133
6134DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01006135DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
6136DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
6137DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
6138DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
6139DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
6140DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07006141
Adam Jacksoneecfd572010-08-25 21:17:34 +01006142#define GGC 0x52
6143#define GGC_MEMORY_SIZE_MASK (0xf << 8)
6144#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
6145#define GGC_MEMORY_SIZE_1M (0x1 << 8)
6146#define GGC_MEMORY_SIZE_2M (0x3 << 8)
6147#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
6148#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
6149#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
6150#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
6151
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006152static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01006153{
6154 unsigned short ggc;
6155
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006156 if (risky_device(dev))
6157 return;
6158
Adam Jacksoneecfd572010-08-25 21:17:34 +01006159 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01006160 return;
6161
Adam Jacksoneecfd572010-08-25 21:17:34 +01006162 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006163 pci_info(dev, "BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01006164 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006165 } else if (dmar_map_gfx) {
6166 /* we have to ensure the gfx device is idle before we flush */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006167 pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006168 intel_iommu_strict = 1;
6169 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01006170}
6171DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
6172DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
6173DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
6174DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
6175
David Woodhousee0fc7e02009-09-30 09:12:17 -07006176/* On Tylersburg chipsets, some BIOSes have been known to enable the
6177 ISOCH DMAR unit for the Azalia sound device, but not give it any
6178 TLB entries, which causes it to deadlock. Check for that. We do
6179 this in a function called from init_dmars(), instead of in a PCI
6180 quirk, because we don't want to print the obnoxious "BIOS broken"
6181 message if VT-d is actually disabled.
6182*/
6183static void __init check_tylersburg_isoch(void)
6184{
6185 struct pci_dev *pdev;
6186 uint32_t vtisochctrl;
6187
6188 /* If there's no Azalia in the system anyway, forget it. */
6189 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
6190 if (!pdev)
6191 return;
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006192
6193 if (risky_device(pdev)) {
6194 pci_dev_put(pdev);
6195 return;
6196 }
6197
David Woodhousee0fc7e02009-09-30 09:12:17 -07006198 pci_dev_put(pdev);
6199
6200 /* System Management Registers. Might be hidden, in which case
6201 we can't do the sanity check. But that's OK, because the
6202 known-broken BIOSes _don't_ actually hide it, so far. */
6203 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
6204 if (!pdev)
6205 return;
6206
Rajat Jain67e8a5b2020-06-23 07:13:42 +08006207 if (risky_device(pdev)) {
6208 pci_dev_put(pdev);
6209 return;
6210 }
6211
David Woodhousee0fc7e02009-09-30 09:12:17 -07006212 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
6213 pci_dev_put(pdev);
6214 return;
6215 }
6216
6217 pci_dev_put(pdev);
6218
6219 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
6220 if (vtisochctrl & 1)
6221 return;
6222
6223 /* Drop all bits other than the number of TLB entries */
6224 vtisochctrl &= 0x1c;
6225
6226 /* If we have the recommended number of TLB entries (16), fine. */
6227 if (vtisochctrl == 0x10)
6228 return;
6229
6230 /* Zero TLB entries? You get to ride the short bus to school. */
6231 if (!vtisochctrl) {
6232 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
6233 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
6234 dmi_get_system_info(DMI_BIOS_VENDOR),
6235 dmi_get_system_info(DMI_BIOS_VERSION),
6236 dmi_get_system_info(DMI_PRODUCT_VERSION));
6237 iommu_identity_mapping |= IDENTMAP_AZALIA;
6238 return;
6239 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02006240
6241 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07006242 vtisochctrl);
6243}