blob: 80d0bd561bdd302bb78750f9ad3872433959453d [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 Roedel078e1ee2012-09-26 12:44:43 +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 Baolue2726da2020-01-02 08:18:22 +0800368DEFINE_SPINLOCK(device_domain_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700369static LIST_HEAD(device_domain_list);
370
Lu Baolue5e04d02019-09-06 14:14:49 +0800371#define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) && \
372 to_pci_dev(d)->untrusted)
373
Lu Baolu85319dc2018-07-14 15:46:58 +0800374/*
375 * Iterate over elements in device_domain_list and call the specified
Lu Baolu0bbeb012018-12-10 09:58:56 +0800376 * callback @fn against each element.
Lu Baolu85319dc2018-07-14 15:46:58 +0800377 */
378int for_each_device_domain(int (*fn)(struct device_domain_info *info,
379 void *data), void *data)
380{
381 int ret = 0;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800382 unsigned long flags;
Lu Baolu85319dc2018-07-14 15:46:58 +0800383 struct device_domain_info *info;
384
Lu Baolu0bbeb012018-12-10 09:58:56 +0800385 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800386 list_for_each_entry(info, &device_domain_list, global) {
387 ret = fn(info, data);
Lu Baolu0bbeb012018-12-10 09:58:56 +0800388 if (ret) {
389 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800390 return ret;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800391 }
Lu Baolu85319dc2018-07-14 15:46:58 +0800392 }
Lu Baolu0bbeb012018-12-10 09:58:56 +0800393 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800394
395 return 0;
396}
397
Joerg Roedelb0119e82017-02-01 13:23:08 +0100398const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100399
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200400static bool translation_pre_enabled(struct intel_iommu *iommu)
401{
402 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
403}
404
Joerg Roedel091d42e2015-06-12 11:56:10 +0200405static void clear_translation_pre_enabled(struct intel_iommu *iommu)
406{
407 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
408}
409
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200410static void init_translation_status(struct intel_iommu *iommu)
411{
412 u32 gsts;
413
414 gsts = readl(iommu->reg + DMAR_GSTS_REG);
415 if (gsts & DMA_GSTS_TES)
416 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
417}
418
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700419static int __init intel_iommu_setup(char *str)
420{
421 if (!str)
422 return -EINVAL;
423 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800424 if (!strncmp(str, "on", 2)) {
425 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200426 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800427 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700428 dmar_disabled = 1;
Lu Baolu89a60792018-10-23 15:45:01 +0800429 no_platform_optin = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200430 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700431 } else if (!strncmp(str, "igfx_off", 8)) {
432 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200433 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700434 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200435 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700436 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800437 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200438 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800439 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100440 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200441 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100442 intel_iommu_superpage = 0;
Lu Baolu8950dcd2019-01-24 10:31:32 +0800443 } else if (!strncmp(str, "sm_on", 5)) {
444 pr_info("Intel-IOMMU: scalable mode supported\n");
445 intel_iommu_sm = 1;
Shaohua Libfd20f12017-04-26 09:18:35 -0700446 } else if (!strncmp(str, "tboot_noforce", 13)) {
Andy Shevchenko86278922020-05-07 19:18:02 +0300447 pr_info("Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
Shaohua Libfd20f12017-04-26 09:18:35 -0700448 intel_iommu_tboot_noforce = 1;
Lu Baolue5e04d02019-09-06 14:14:49 +0800449 } else if (!strncmp(str, "nobounce", 8)) {
450 pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
451 intel_no_bounce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700452 }
453
454 str += strcspn(str, ",");
455 while (*str == ',')
456 str++;
457 }
458 return 0;
459}
460__setup("intel_iommu=", intel_iommu_setup);
461
462static struct kmem_cache *iommu_domain_cache;
463static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700464
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200465static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
466{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200467 struct dmar_domain **domains;
468 int idx = did >> 8;
469
470 domains = iommu->domains[idx];
471 if (!domains)
472 return NULL;
473
474 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200475}
476
477static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
478 struct dmar_domain *domain)
479{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200480 struct dmar_domain **domains;
481 int idx = did >> 8;
482
483 if (!iommu->domains[idx]) {
484 size_t size = 256 * sizeof(struct dmar_domain *);
485 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
486 }
487
488 domains = iommu->domains[idx];
489 if (WARN_ON(!domains))
490 return;
491 else
492 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200493}
494
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800495void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700496{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700497 struct page *page;
498 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700499
Suresh Siddha4c923d42009-10-02 11:01:24 -0700500 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
501 if (page)
502 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700503 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700504}
505
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800506void free_pgtable_page(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700507{
508 free_page((unsigned long)vaddr);
509}
510
511static inline void *alloc_domain_mem(void)
512{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900513 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700514}
515
Kay, Allen M38717942008-09-09 18:37:29 +0300516static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700517{
518 kmem_cache_free(iommu_domain_cache, vaddr);
519}
520
521static inline void * alloc_devinfo_mem(void)
522{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900523 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700524}
525
526static inline void free_devinfo_mem(void *vaddr)
527{
528 kmem_cache_free(iommu_devinfo_cache, vaddr);
529}
530
Joerg Roedel28ccce02015-07-21 14:45:31 +0200531static inline int domain_type_is_si(struct dmar_domain *domain)
532{
533 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
534}
535
Lu Baoluddf09b62020-01-02 08:18:17 +0800536static inline bool domain_use_first_level(struct dmar_domain *domain)
537{
538 return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL;
539}
540
Jiang Liu162d1b12014-07-11 14:19:35 +0800541static inline int domain_pfn_supported(struct dmar_domain *domain,
542 unsigned long pfn)
543{
544 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
545
546 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
547}
548
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700549static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800550{
551 unsigned long sagaw;
552 int agaw = -1;
553
554 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700555 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800556 agaw >= 0; agaw--) {
557 if (test_bit(agaw, &sagaw))
558 break;
559 }
560
561 return agaw;
562}
563
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700564/*
565 * Calculate max SAGAW for each iommu.
566 */
567int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
568{
569 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
570}
571
572/*
573 * calculate agaw for each iommu.
574 * "SAGAW" may be different across iommus, use a default agaw, and
575 * get a supported less agaw for iommus that don't support the default agaw.
576 */
577int iommu_calculate_agaw(struct intel_iommu *iommu)
578{
579 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
580}
581
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700582/* This functionin only returns single iommu in a domain */
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800583struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
Weidong Han8c11e792008-12-08 15:29:22 +0800584{
585 int iommu_id;
586
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700587 /* si_domain and vm domain should not get here. */
Lu Baolufa954e62019-05-25 13:41:28 +0800588 if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
589 return NULL;
590
Joerg Roedel29a27712015-07-21 17:17:12 +0200591 for_each_domain_iommu(iommu_id, domain)
592 break;
593
Weidong Han8c11e792008-12-08 15:29:22 +0800594 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
595 return NULL;
596
597 return g_iommus[iommu_id];
598}
599
Weidong Han8e6040972008-12-08 15:49:06 +0800600static void domain_update_iommu_coherency(struct dmar_domain *domain)
601{
David Woodhoused0501962014-03-11 17:10:29 -0700602 struct dmar_drhd_unit *drhd;
603 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100604 bool found = false;
605 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800606
David Woodhoused0501962014-03-11 17:10:29 -0700607 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800608
Joerg Roedel29a27712015-07-21 17:17:12 +0200609 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100610 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800611 if (!ecap_coherent(g_iommus[i]->ecap)) {
612 domain->iommu_coherency = 0;
613 break;
614 }
Weidong Han8e6040972008-12-08 15:49:06 +0800615 }
David Woodhoused0501962014-03-11 17:10:29 -0700616 if (found)
617 return;
618
619 /* No hardware attached; use lowest common denominator */
620 rcu_read_lock();
621 for_each_active_iommu(iommu, drhd) {
622 if (!ecap_coherent(iommu->ecap)) {
623 domain->iommu_coherency = 0;
624 break;
625 }
626 }
627 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800628}
629
Jiang Liu161f6932014-07-11 14:19:37 +0800630static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100631{
Allen Kay8140a952011-10-14 12:32:17 -0700632 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800633 struct intel_iommu *iommu;
634 int ret = 1;
635
636 rcu_read_lock();
637 for_each_active_iommu(iommu, drhd) {
638 if (iommu != skip) {
639 if (!ecap_sc_support(iommu->ecap)) {
640 ret = 0;
641 break;
642 }
643 }
644 }
645 rcu_read_unlock();
646
647 return ret;
648}
649
Lu Baolu64229e82020-01-02 08:18:20 +0800650static int domain_update_iommu_superpage(struct dmar_domain *domain,
651 struct intel_iommu *skip)
Jiang Liu161f6932014-07-11 14:19:37 +0800652{
653 struct dmar_drhd_unit *drhd;
654 struct intel_iommu *iommu;
Lu Baolu64229e82020-01-02 08:18:20 +0800655 int mask = 0x3;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100656
657 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800658 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100659 }
660
Allen Kay8140a952011-10-14 12:32:17 -0700661 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800662 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700663 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800664 if (iommu != skip) {
Lu Baolu64229e82020-01-02 08:18:20 +0800665 if (domain && domain_use_first_level(domain)) {
666 if (!cap_fl1gp_support(iommu->cap))
667 mask = 0x1;
668 } else {
669 mask &= cap_super_page_val(iommu->cap);
670 }
671
Jiang Liu161f6932014-07-11 14:19:37 +0800672 if (!mask)
673 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100674 }
675 }
Jiang Liu0e242612014-02-19 14:07:34 +0800676 rcu_read_unlock();
677
Jiang Liu161f6932014-07-11 14:19:37 +0800678 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100679}
680
Sheng Yang58c610b2009-03-18 15:33:05 +0800681/* Some capabilities may be different across iommus */
682static void domain_update_iommu_cap(struct dmar_domain *domain)
683{
684 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800685 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
Lu Baolu64229e82020-01-02 08:18:20 +0800686 domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800687}
688
Sohil Mehta26b86092018-09-11 17:11:36 -0700689struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
690 u8 devfn, int alloc)
David Woodhouse03ecc322015-02-13 14:35:21 +0000691{
692 struct root_entry *root = &iommu->root_entry[bus];
693 struct context_entry *context;
694 u64 *entry;
695
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200696 entry = &root->lo;
Lu Baolu765b6a92018-12-10 09:58:55 +0800697 if (sm_supported(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000698 if (devfn >= 0x80) {
699 devfn -= 0x80;
700 entry = &root->hi;
701 }
702 devfn *= 2;
703 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000704 if (*entry & 1)
705 context = phys_to_virt(*entry & VTD_PAGE_MASK);
706 else {
707 unsigned long phy_addr;
708 if (!alloc)
709 return NULL;
710
711 context = alloc_pgtable_page(iommu->node);
712 if (!context)
713 return NULL;
714
715 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
716 phy_addr = virt_to_phys((void *)context);
717 *entry = phy_addr | 1;
718 __iommu_flush_cache(iommu, entry, sizeof(*entry));
719 }
720 return &context[devfn];
721}
722
David Woodhouse4ed6a542015-05-11 14:59:20 +0100723static int iommu_dummy(struct device *dev)
724{
725 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
726}
727
Joerg Roedel1d46159782020-02-17 17:12:37 +0100728static bool attach_deferred(struct device *dev)
729{
730 return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
731}
732
Eric Augerb9a7f982019-06-03 08:53:32 +0200733/**
734 * is_downstream_to_pci_bridge - test if a device belongs to the PCI
735 * sub-hierarchy of a candidate PCI-PCI bridge
736 * @dev: candidate PCI device belonging to @bridge PCI sub-hierarchy
737 * @bridge: the candidate PCI-PCI bridge
738 *
739 * Return: true if @dev belongs to @bridge PCI sub-hierarchy, else false.
740 */
741static bool
742is_downstream_to_pci_bridge(struct device *dev, struct device *bridge)
743{
744 struct pci_dev *pdev, *pbridge;
745
746 if (!dev_is_pci(dev) || !dev_is_pci(bridge))
747 return false;
748
749 pdev = to_pci_dev(dev);
750 pbridge = to_pci_dev(bridge);
751
752 if (pbridge->subordinate &&
753 pbridge->subordinate->number <= pdev->bus->number &&
754 pbridge->subordinate->busn_res.end >= pdev->bus->number)
755 return true;
756
757 return false;
758}
759
David Woodhouse156baca2014-03-09 14:00:57 -0700760static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800761{
762 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800763 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700764 struct device *tmp;
Eric Augerb9a7f982019-06-03 08:53:32 +0200765 struct pci_dev *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800766 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800767 int i;
768
David Woodhouse4ed6a542015-05-11 14:59:20 +0100769 if (iommu_dummy(dev))
770 return NULL;
771
David Woodhouse156baca2014-03-09 14:00:57 -0700772 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700773 struct pci_dev *pf_pdev;
774
Jon Derricke3560ee2020-01-21 06:37:49 -0700775 pdev = pci_real_dma_dev(to_pci_dev(dev));
Jon Derrick5823e332017-08-30 15:05:59 -0600776
Ashok Raj1c387182016-10-21 15:32:05 -0700777 /* VFs aren't listed in scope tables; we need to look up
778 * the PF instead to find the IOMMU. */
779 pf_pdev = pci_physfn(pdev);
780 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700781 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100782 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700783 dev = &ACPI_COMPANION(dev)->dev;
784
Jiang Liu0e242612014-02-19 14:07:34 +0800785 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800786 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700787 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100788 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800789
Jiang Liub683b232014-02-19 14:07:32 +0800790 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700791 drhd->devices_cnt, i, tmp) {
792 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700793 /* For a VF use its original BDF# not that of the PF
794 * which we used for the IOMMU lookup. Strictly speaking
795 * we could do this for all PCI devices; we only need to
796 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100797 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700798 goto got_pdev;
799
David Woodhouse156baca2014-03-09 14:00:57 -0700800 *bus = drhd->devices[i].bus;
801 *devfn = drhd->devices[i].devfn;
802 goto out;
803 }
804
Eric Augerb9a7f982019-06-03 08:53:32 +0200805 if (is_downstream_to_pci_bridge(dev, tmp))
David Woodhouse156baca2014-03-09 14:00:57 -0700806 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100807 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800808
David Woodhouse156baca2014-03-09 14:00:57 -0700809 if (pdev && drhd->include_all) {
810 got_pdev:
811 *bus = pdev->bus->number;
812 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800813 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700814 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800815 }
Jiang Liub683b232014-02-19 14:07:32 +0800816 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700817 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800818 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800819
Jiang Liub683b232014-02-19 14:07:32 +0800820 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800821}
822
Weidong Han5331fe62008-12-08 23:00:00 +0800823static void domain_flush_cache(struct dmar_domain *domain,
824 void *addr, int size)
825{
826 if (!domain->iommu_coherency)
827 clflush_cache_range(addr, size);
828}
829
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700830static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
831{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700832 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000833 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700834 unsigned long flags;
835
836 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000837 context = iommu_context_addr(iommu, bus, devfn, 0);
838 if (context)
839 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700840 spin_unlock_irqrestore(&iommu->lock, flags);
841 return ret;
842}
843
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700844static void free_context_table(struct intel_iommu *iommu)
845{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700846 int i;
847 unsigned long flags;
848 struct context_entry *context;
849
850 spin_lock_irqsave(&iommu->lock, flags);
851 if (!iommu->root_entry) {
852 goto out;
853 }
854 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000855 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700856 if (context)
857 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000858
Lu Baolu765b6a92018-12-10 09:58:55 +0800859 if (!sm_supported(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000860 continue;
861
862 context = iommu_context_addr(iommu, i, 0x80, 0);
863 if (context)
864 free_pgtable_page(context);
865
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700866 }
867 free_pgtable_page(iommu->root_entry);
868 iommu->root_entry = NULL;
869out:
870 spin_unlock_irqrestore(&iommu->lock, flags);
871}
872
David Woodhouseb026fd22009-06-28 10:37:25 +0100873static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000874 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700875{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600876 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700877 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700878 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700879
880 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200881
Jiang Liu162d1b12014-07-11 14:19:35 +0800882 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200883 /* Address beyond IOMMU's addressing capabilities. */
884 return NULL;
885
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700886 parent = domain->pgd;
887
David Woodhouse5cf0a762014-03-19 16:07:49 +0000888 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700889 void *tmp_page;
890
David Woodhouseb026fd22009-06-28 10:37:25 +0100891 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700892 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000893 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100894 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000895 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700896 break;
897
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000898 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100899 uint64_t pteval;
900
Suresh Siddha4c923d42009-10-02 11:01:24 -0700901 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700902
David Woodhouse206a73c2009-07-01 19:30:28 +0100903 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700904 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100905
David Woodhousec85994e2009-07-01 19:21:24 +0100906 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400907 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 +0800908 if (domain_use_first_level(domain))
909 pteval |= DMA_FL_PTE_XD;
Yijing Wangeffad4b2014-05-26 20:13:47 +0800910 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100911 /* Someone else set it while we were thinking; use theirs. */
912 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800913 else
David Woodhousec85994e2009-07-01 19:21:24 +0100914 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700915 }
David Woodhouse5cf0a762014-03-19 16:07:49 +0000916 if (level == 1)
917 break;
918
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000919 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700920 level--;
921 }
922
David Woodhouse5cf0a762014-03-19 16:07:49 +0000923 if (!*target_level)
924 *target_level = level;
925
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700926 return pte;
927}
928
929/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +0100930static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
931 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100932 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700933{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600934 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700935 int total = agaw_to_level(domain->agaw);
936 int offset;
937
938 parent = domain->pgd;
939 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +0100940 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700941 pte = &parent[offset];
942 if (level == total)
943 return pte;
944
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100945 if (!dma_pte_present(pte)) {
946 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700947 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100948 }
949
Yijing Wange16922a2014-05-20 20:37:51 +0800950 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100951 *large_page = total;
952 return pte;
953 }
954
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000955 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700956 total--;
957 }
958 return NULL;
959}
960
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700961/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +0000962static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf52009-06-27 22:09:11 +0100963 unsigned long start_pfn,
964 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700965{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600966 unsigned int large_page;
David Woodhouse310a5ab2009-06-28 18:52:20 +0100967 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700968
Jiang Liu162d1b12014-07-11 14:19:35 +0800969 BUG_ON(!domain_pfn_supported(domain, start_pfn));
970 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -0700971 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +0100972
David Woodhouse04b18e62009-06-27 19:15:01 +0100973 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -0700974 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100975 large_page = 1;
976 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100977 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100978 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100979 continue;
980 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100981 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +0100982 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100983 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100984 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +0100985 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
986
David Woodhouse310a5ab2009-06-28 18:52:20 +0100987 domain_flush_cache(domain, first_pte,
988 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -0700989
990 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700991}
992
Alex Williamson3269ee02013-06-15 10:27:19 -0600993static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -0700994 int retain_level, struct dma_pte *pte,
995 unsigned long pfn, unsigned long start_pfn,
996 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -0600997{
998 pfn = max(start_pfn, pfn);
999 pte = &pte[pfn_level_offset(pfn, level)];
1000
1001 do {
1002 unsigned long level_pfn;
1003 struct dma_pte *level_pte;
1004
1005 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1006 goto next;
1007
David Dillowf7116e12017-01-30 19:11:11 -08001008 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001009 level_pte = phys_to_virt(dma_pte_addr(pte));
1010
David Dillowbc24c572017-06-28 19:42:23 -07001011 if (level > 2) {
1012 dma_pte_free_level(domain, level - 1, retain_level,
1013 level_pte, level_pfn, start_pfn,
1014 last_pfn);
1015 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001016
David Dillowbc24c572017-06-28 19:42:23 -07001017 /*
1018 * Free the page table if we're below the level we want to
1019 * retain and the range covers the entire table.
1020 */
1021 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001022 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001023 dma_clear_pte(pte);
1024 domain_flush_cache(domain, pte, sizeof(*pte));
1025 free_pgtable_page(level_pte);
1026 }
1027next:
1028 pfn += level_size(level);
1029 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1030}
1031
David Dillowbc24c572017-06-28 19:42:23 -07001032/*
1033 * clear last level (leaf) ptes and free page table pages below the
1034 * level we wish to keep intact.
1035 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001036static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001037 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001038 unsigned long last_pfn,
1039 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001040{
Jiang Liu162d1b12014-07-11 14:19:35 +08001041 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1042 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001043 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001044
Jiang Liud41a4ad2014-07-11 14:19:34 +08001045 dma_pte_clear_range(domain, start_pfn, last_pfn);
1046
David Woodhousef3a0a522009-06-30 03:40:07 +01001047 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001048 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001049 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001050
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001051 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001052 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001053 free_pgtable_page(domain->pgd);
1054 domain->pgd = NULL;
1055 }
1056}
1057
David Woodhouseea8ea462014-03-05 17:09:32 +00001058/* When a page at a given level is being unlinked from its parent, we don't
1059 need to *modify* it at all. All we need to do is make a list of all the
1060 pages which can be freed just as soon as we've flushed the IOTLB and we
1061 know the hardware page-walk will no longer touch them.
1062 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1063 be freed. */
1064static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1065 int level, struct dma_pte *pte,
1066 struct page *freelist)
1067{
1068 struct page *pg;
1069
1070 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1071 pg->freelist = freelist;
1072 freelist = pg;
1073
1074 if (level == 1)
1075 return freelist;
1076
Jiang Liuadeb2592014-04-09 10:20:39 +08001077 pte = page_address(pg);
1078 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001079 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1080 freelist = dma_pte_list_pagetables(domain, level - 1,
1081 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001082 pte++;
1083 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001084
1085 return freelist;
1086}
1087
1088static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1089 struct dma_pte *pte, unsigned long pfn,
1090 unsigned long start_pfn,
1091 unsigned long last_pfn,
1092 struct page *freelist)
1093{
1094 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1095
1096 pfn = max(start_pfn, pfn);
1097 pte = &pte[pfn_level_offset(pfn, level)];
1098
1099 do {
1100 unsigned long level_pfn;
1101
1102 if (!dma_pte_present(pte))
1103 goto next;
1104
1105 level_pfn = pfn & level_mask(level);
1106
1107 /* If range covers entire pagetable, free it */
1108 if (start_pfn <= level_pfn &&
1109 last_pfn >= level_pfn + level_size(level) - 1) {
1110 /* These suborbinate page tables are going away entirely. Don't
1111 bother to clear them; we're just going to *free* them. */
1112 if (level > 1 && !dma_pte_superpage(pte))
1113 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1114
1115 dma_clear_pte(pte);
1116 if (!first_pte)
1117 first_pte = pte;
1118 last_pte = pte;
1119 } else if (level > 1) {
1120 /* Recurse down into a level that isn't *entirely* obsolete */
1121 freelist = dma_pte_clear_level(domain, level - 1,
1122 phys_to_virt(dma_pte_addr(pte)),
1123 level_pfn, start_pfn, last_pfn,
1124 freelist);
1125 }
1126next:
1127 pfn += level_size(level);
1128 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1129
1130 if (first_pte)
1131 domain_flush_cache(domain, first_pte,
1132 (void *)++last_pte - (void *)first_pte);
1133
1134 return freelist;
1135}
1136
1137/* We can't just free the pages because the IOMMU may still be walking
1138 the page tables, and may have cached the intermediate levels. The
1139 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001140static struct page *domain_unmap(struct dmar_domain *domain,
1141 unsigned long start_pfn,
1142 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001143{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001144 struct page *freelist;
David Woodhouseea8ea462014-03-05 17:09:32 +00001145
Jiang Liu162d1b12014-07-11 14:19:35 +08001146 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1147 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001148 BUG_ON(start_pfn > last_pfn);
1149
1150 /* we don't need lock here; nobody else touches the iova range */
1151 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1152 domain->pgd, 0, start_pfn, last_pfn, NULL);
1153
1154 /* free pgd */
1155 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1156 struct page *pgd_page = virt_to_page(domain->pgd);
1157 pgd_page->freelist = freelist;
1158 freelist = pgd_page;
1159
1160 domain->pgd = NULL;
1161 }
1162
1163 return freelist;
1164}
1165
Joerg Roedelb6904202015-08-13 11:32:18 +02001166static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001167{
1168 struct page *pg;
1169
1170 while ((pg = freelist)) {
1171 freelist = pg->freelist;
1172 free_pgtable_page(page_address(pg));
1173 }
1174}
1175
Joerg Roedel13cf0172017-08-11 11:40:10 +02001176static void iova_entry_free(unsigned long data)
1177{
1178 struct page *freelist = (struct page *)data;
1179
1180 dma_free_pagelist(freelist);
1181}
1182
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001183/* iommu handling */
1184static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1185{
1186 struct root_entry *root;
1187 unsigned long flags;
1188
Suresh Siddha4c923d42009-10-02 11:01:24 -07001189 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001190 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001191 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001192 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001193 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001194 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001195
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001196 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001197
1198 spin_lock_irqsave(&iommu->lock, flags);
1199 iommu->root_entry = root;
1200 spin_unlock_irqrestore(&iommu->lock, flags);
1201
1202 return 0;
1203}
1204
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001205static void iommu_set_root_entry(struct intel_iommu *iommu)
1206{
David Woodhouse03ecc322015-02-13 14:35:21 +00001207 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001208 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001209 unsigned long flag;
1210
David Woodhouse03ecc322015-02-13 14:35:21 +00001211 addr = virt_to_phys(iommu->root_entry);
Lu Baolu7373a8c2018-12-10 09:59:03 +08001212 if (sm_supported(iommu))
1213 addr |= DMA_RTADDR_SMT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001214
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001215 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001216 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001217
David Woodhousec416daa2009-05-10 20:30:58 +01001218 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001219
1220 /* Make sure hardware complete it */
1221 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001222 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001223
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001224 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001225}
1226
Lu Baolu6f7db752018-12-10 09:59:00 +08001227void iommu_flush_write_buffer(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001228{
1229 u32 val;
1230 unsigned long flag;
1231
David Woodhouse9af88142009-02-13 23:18:03 +00001232 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001233 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001234
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001235 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001236 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001237
1238 /* Make sure hardware complete it */
1239 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001240 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001241
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001242 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001243}
1244
1245/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001246static void __iommu_flush_context(struct intel_iommu *iommu,
1247 u16 did, u16 source_id, u8 function_mask,
1248 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001249{
1250 u64 val = 0;
1251 unsigned long flag;
1252
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001253 switch (type) {
1254 case DMA_CCMD_GLOBAL_INVL:
1255 val = DMA_CCMD_GLOBAL_INVL;
1256 break;
1257 case DMA_CCMD_DOMAIN_INVL:
1258 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1259 break;
1260 case DMA_CCMD_DEVICE_INVL:
1261 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1262 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1263 break;
1264 default:
1265 BUG();
1266 }
1267 val |= DMA_CCMD_ICC;
1268
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001269 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001270 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1271
1272 /* Make sure hardware complete it */
1273 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1274 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1275
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001276 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001277}
1278
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001279/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001280static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1281 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001282{
1283 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1284 u64 val = 0, val_iva = 0;
1285 unsigned long flag;
1286
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001287 switch (type) {
1288 case DMA_TLB_GLOBAL_FLUSH:
1289 /* global flush doesn't need set IVA_REG */
1290 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1291 break;
1292 case DMA_TLB_DSI_FLUSH:
1293 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1294 break;
1295 case DMA_TLB_PSI_FLUSH:
1296 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001297 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001298 val_iva = size_order | addr;
1299 break;
1300 default:
1301 BUG();
1302 }
1303 /* Note: set drain read/write */
1304#if 0
1305 /*
1306 * This is probably to be super secure.. Looks like we can
1307 * ignore it without any impact.
1308 */
1309 if (cap_read_drain(iommu->cap))
1310 val |= DMA_TLB_READ_DRAIN;
1311#endif
1312 if (cap_write_drain(iommu->cap))
1313 val |= DMA_TLB_WRITE_DRAIN;
1314
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001315 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001316 /* Note: Only uses first TLB reg currently */
1317 if (val_iva)
1318 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1319 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1320
1321 /* Make sure hardware complete it */
1322 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1323 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1324
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001325 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001326
1327 /* check IOTLB invalidation granularity */
1328 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001329 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001330 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001331 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001332 (unsigned long long)DMA_TLB_IIRG(type),
1333 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001334}
1335
David Woodhouse64ae8922014-03-09 12:52:30 -07001336static struct device_domain_info *
1337iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1338 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001339{
Yu Zhao93a23a72009-05-18 13:51:37 +08001340 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001341
Joerg Roedel55d94042015-07-22 16:50:40 +02001342 assert_spin_locked(&device_domain_lock);
1343
Yu Zhao93a23a72009-05-18 13:51:37 +08001344 if (!iommu->qi)
1345 return NULL;
1346
Yu Zhao93a23a72009-05-18 13:51:37 +08001347 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001348 if (info->iommu == iommu && info->bus == bus &&
1349 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001350 if (info->ats_supported && info->dev)
1351 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001352 break;
1353 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001354
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001355 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001356}
1357
Omer Peleg0824c592016-04-20 19:03:35 +03001358static void domain_update_iotlb(struct dmar_domain *domain)
1359{
1360 struct device_domain_info *info;
1361 bool has_iotlb_device = false;
1362
1363 assert_spin_locked(&device_domain_lock);
1364
1365 list_for_each_entry(info, &domain->devices, link) {
1366 struct pci_dev *pdev;
1367
1368 if (!info->dev || !dev_is_pci(info->dev))
1369 continue;
1370
1371 pdev = to_pci_dev(info->dev);
1372 if (pdev->ats_enabled) {
1373 has_iotlb_device = true;
1374 break;
1375 }
1376 }
1377
1378 domain->has_iotlb_device = has_iotlb_device;
1379}
1380
Yu Zhao93a23a72009-05-18 13:51:37 +08001381static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1382{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001383 struct pci_dev *pdev;
1384
Omer Peleg0824c592016-04-20 19:03:35 +03001385 assert_spin_locked(&device_domain_lock);
1386
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001387 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001388 return;
1389
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001390 pdev = to_pci_dev(info->dev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001391 /* For IOMMU that supports device IOTLB throttling (DIT), we assign
1392 * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
1393 * queue depth at PF level. If DIT is not set, PFSID will be treated as
1394 * reserved, which should be set to 0.
1395 */
1396 if (!ecap_dit(info->iommu->ecap))
1397 info->pfsid = 0;
1398 else {
1399 struct pci_dev *pf_pdev;
1400
1401 /* pdev will be returned if device is not a vf */
1402 pf_pdev = pci_physfn(pdev);
Heiner Kallweitcc49baa2019-04-24 21:16:10 +02001403 info->pfsid = pci_dev_id(pf_pdev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001404 }
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001405
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001406#ifdef CONFIG_INTEL_IOMMU_SVM
1407 /* The PCIe spec, in its wisdom, declares that the behaviour of
1408 the device if you enable PASID support after ATS support is
1409 undefined. So always enable PASID support on devices which
1410 have it, even if we can't yet know if we're ever going to
1411 use it. */
1412 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1413 info->pasid_enabled = 1;
1414
Kuppuswamy Sathyanarayanan1b84778a2019-02-19 11:04:52 -08001415 if (info->pri_supported &&
1416 (info->pasid_enabled ? pci_prg_resp_pasid_required(pdev) : 1) &&
1417 !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001418 info->pri_enabled = 1;
1419#endif
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001420 if (!pdev->untrusted && info->ats_supported &&
Kuppuswamy Sathyanarayanan61363c12019-02-19 11:06:10 -08001421 pci_ats_page_aligned(pdev) &&
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001422 !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001423 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001424 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001425 info->ats_qdep = pci_ats_queue_depth(pdev);
1426 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001427}
1428
1429static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1430{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001431 struct pci_dev *pdev;
1432
Omer Peleg0824c592016-04-20 19:03:35 +03001433 assert_spin_locked(&device_domain_lock);
1434
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001435 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001436 return;
1437
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001438 pdev = to_pci_dev(info->dev);
1439
1440 if (info->ats_enabled) {
1441 pci_disable_ats(pdev);
1442 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001443 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001444 }
1445#ifdef CONFIG_INTEL_IOMMU_SVM
1446 if (info->pri_enabled) {
1447 pci_disable_pri(pdev);
1448 info->pri_enabled = 0;
1449 }
1450 if (info->pasid_enabled) {
1451 pci_disable_pasid(pdev);
1452 info->pasid_enabled = 0;
1453 }
1454#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001455}
1456
1457static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1458 u64 addr, unsigned mask)
1459{
1460 u16 sid, qdep;
1461 unsigned long flags;
1462 struct device_domain_info *info;
1463
Omer Peleg0824c592016-04-20 19:03:35 +03001464 if (!domain->has_iotlb_device)
1465 return;
1466
Yu Zhao93a23a72009-05-18 13:51:37 +08001467 spin_lock_irqsave(&device_domain_lock, flags);
1468 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001469 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001470 continue;
1471
1472 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001473 qdep = info->ats_qdep;
Jacob Pan1c48db42018-06-07 09:57:00 -07001474 qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
1475 qdep, addr, mask);
Yu Zhao93a23a72009-05-18 13:51:37 +08001476 }
1477 spin_unlock_irqrestore(&device_domain_lock, flags);
1478}
1479
Lu Baolu33cd6e62020-01-02 08:18:18 +08001480static void domain_flush_piotlb(struct intel_iommu *iommu,
1481 struct dmar_domain *domain,
1482 u64 addr, unsigned long npages, bool ih)
1483{
1484 u16 did = domain->iommu_did[iommu->seq_id];
1485
1486 if (domain->default_pasid)
1487 qi_flush_piotlb(iommu, did, domain->default_pasid,
1488 addr, npages, ih);
1489
1490 if (!list_empty(&domain->devices))
1491 qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, npages, ih);
1492}
1493
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001494static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1495 struct dmar_domain *domain,
1496 unsigned long pfn, unsigned int pages,
1497 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001498{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001499 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001500 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001501 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001502
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001503 BUG_ON(pages == 0);
1504
David Woodhouseea8ea462014-03-05 17:09:32 +00001505 if (ih)
1506 ih = 1 << 6;
Lu Baolu33cd6e62020-01-02 08:18:18 +08001507
1508 if (domain_use_first_level(domain)) {
1509 domain_flush_piotlb(iommu, domain, addr, pages, ih);
1510 } else {
1511 /*
1512 * Fallback to domain selective flush if no PSI support or
1513 * the size is too big. PSI requires page size to be 2 ^ x,
1514 * and the base address is naturally aligned to the size.
1515 */
1516 if (!cap_pgsel_inv(iommu->cap) ||
1517 mask > cap_max_amask_val(iommu->cap))
1518 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1519 DMA_TLB_DSI_FLUSH);
1520 else
1521 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
1522 DMA_TLB_PSI_FLUSH);
1523 }
Yu Zhaobf92df32009-06-29 11:31:45 +08001524
1525 /*
Nadav Amit82653632010-04-01 13:24:40 +03001526 * In caching mode, changes of pages from non-present to present require
1527 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001528 */
Nadav Amit82653632010-04-01 13:24:40 +03001529 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001530 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001531}
1532
Peter Xueed91a02018-05-04 10:34:52 +08001533/* Notification for newly created mappings */
1534static inline void __mapping_notify_one(struct intel_iommu *iommu,
1535 struct dmar_domain *domain,
1536 unsigned long pfn, unsigned int pages)
1537{
Lu Baolu33cd6e62020-01-02 08:18:18 +08001538 /*
1539 * It's a non-present to present mapping. Only flush if caching mode
1540 * and second level.
1541 */
1542 if (cap_caching_mode(iommu->cap) && !domain_use_first_level(domain))
Peter Xueed91a02018-05-04 10:34:52 +08001543 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1544 else
1545 iommu_flush_write_buffer(iommu);
1546}
1547
Joerg Roedel13cf0172017-08-11 11:40:10 +02001548static void iommu_flush_iova(struct iova_domain *iovad)
1549{
1550 struct dmar_domain *domain;
1551 int idx;
1552
1553 domain = container_of(iovad, struct dmar_domain, iovad);
1554
1555 for_each_domain_iommu(idx, domain) {
1556 struct intel_iommu *iommu = g_iommus[idx];
1557 u16 did = domain->iommu_did[iommu->seq_id];
1558
Lu Baolu33cd6e62020-01-02 08:18:18 +08001559 if (domain_use_first_level(domain))
1560 domain_flush_piotlb(iommu, domain, 0, -1, 0);
1561 else
1562 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1563 DMA_TLB_DSI_FLUSH);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001564
1565 if (!cap_caching_mode(iommu->cap))
1566 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1567 0, MAX_AGAW_PFN_WIDTH);
1568 }
1569}
1570
mark grossf8bab732008-02-08 04:18:38 -08001571static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1572{
1573 u32 pmen;
1574 unsigned long flags;
1575
Lu Baolu5bb71fc72019-03-20 09:58:33 +08001576 if (!cap_plmr(iommu->cap) && !cap_phmr(iommu->cap))
1577 return;
1578
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001579 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001580 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1581 pmen &= ~DMA_PMEN_EPM;
1582 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1583
1584 /* wait for the protected region status bit to clear */
1585 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1586 readl, !(pmen & DMA_PMEN_PRS), pmen);
1587
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001588 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001589}
1590
Jiang Liu2a41cce2014-07-11 14:19:33 +08001591static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001592{
1593 u32 sts;
1594 unsigned long flags;
1595
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001596 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001597 iommu->gcmd |= DMA_GCMD_TE;
1598 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001599
1600 /* Make sure hardware complete it */
1601 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001602 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001603
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001604 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001605}
1606
Jiang Liu2a41cce2014-07-11 14:19:33 +08001607static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001608{
1609 u32 sts;
1610 unsigned long flag;
1611
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001612 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001613 iommu->gcmd &= ~DMA_GCMD_TE;
1614 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1615
1616 /* Make sure hardware complete it */
1617 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001618 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001619
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001620 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001621}
1622
1623static int iommu_init_domains(struct intel_iommu *iommu)
1624{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001625 u32 ndomains, nlongs;
1626 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001627
1628 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001629 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001630 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001631 nlongs = BITS_TO_LONGS(ndomains);
1632
Donald Dutile94a91b502009-08-20 16:51:34 -04001633 spin_lock_init(&iommu->lock);
1634
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001635 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1636 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001637 pr_err("%s: Allocating domain id array failed\n",
1638 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001639 return -ENOMEM;
1640 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001641
Wei Yang86f004c2016-05-21 02:41:51 +00001642 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001643 iommu->domains = kzalloc(size, GFP_KERNEL);
1644
1645 if (iommu->domains) {
1646 size = 256 * sizeof(struct dmar_domain *);
1647 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1648 }
1649
1650 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001651 pr_err("%s: Allocating domain array failed\n",
1652 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001653 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001654 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001655 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001656 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001657 return -ENOMEM;
1658 }
1659
1660 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001661 * If Caching mode is set, then invalid translations are tagged
1662 * with domain-id 0, hence we need to pre-allocate it. We also
1663 * use domain-id 0 as a marker for non-allocated domain-id, so
1664 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001665 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001666 set_bit(0, iommu->domain_ids);
1667
Lu Baolu3b33d4a2018-12-10 09:58:59 +08001668 /*
1669 * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid
1670 * entry for first-level or pass-through translation modes should
1671 * be programmed with a domain id different from those used for
1672 * second-level or nested translation. We reserve a domain id for
1673 * this purpose.
1674 */
1675 if (sm_supported(iommu))
1676 set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
1677
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678 return 0;
1679}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001680
Jiang Liuffebeb42014-11-09 22:48:02 +08001681static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001682{
Joerg Roedel29a27712015-07-21 17:17:12 +02001683 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001684 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001685
Joerg Roedel29a27712015-07-21 17:17:12 +02001686 if (!iommu->domains || !iommu->domain_ids)
1687 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001688
Joerg Roedel55d94042015-07-22 16:50:40 +02001689 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001690 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
Joerg Roedel29a27712015-07-21 17:17:12 +02001691 if (info->iommu != iommu)
1692 continue;
1693
1694 if (!info->dev || !info->domain)
1695 continue;
1696
Joerg Roedelbea64032016-11-08 15:08:26 +01001697 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001698 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001699 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001700
1701 if (iommu->gcmd & DMA_GCMD_TE)
1702 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001703}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001704
Jiang Liuffebeb42014-11-09 22:48:02 +08001705static void free_dmar_iommu(struct intel_iommu *iommu)
1706{
1707 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001708 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001709 int i;
1710
1711 for (i = 0; i < elems; i++)
1712 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001713 kfree(iommu->domains);
1714 kfree(iommu->domain_ids);
1715 iommu->domains = NULL;
1716 iommu->domain_ids = NULL;
1717 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001718
Weidong Hand9630fe2008-12-08 11:06:32 +08001719 g_iommus[iommu->seq_id] = NULL;
1720
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001721 /* free context mapping */
1722 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001723
1724#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08001725 if (pasid_supported(iommu)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01001726 if (ecap_prs(iommu->ecap))
1727 intel_svm_finish_prq(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001728 }
Jacob Pan33753032020-05-16 14:20:51 +08001729 if (ecap_vcs(iommu->ecap) && vccap_pasid(iommu->vccap))
1730 ioasid_unregister_allocator(&iommu->pasid_allocator);
1731
David Woodhouse8a94ade2015-03-24 14:54:56 +00001732#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001733}
1734
Lu Baolua1948f22020-01-02 08:18:14 +08001735/*
1736 * Check and return whether first level is used by default for
Lu Baolub802d072020-01-02 08:18:21 +08001737 * DMA translation.
Lu Baolua1948f22020-01-02 08:18:14 +08001738 */
1739static bool first_level_by_default(void)
1740{
1741 struct dmar_drhd_unit *drhd;
1742 struct intel_iommu *iommu;
Lu Baolub802d072020-01-02 08:18:21 +08001743 static int first_level_support = -1;
Lu Baolua1948f22020-01-02 08:18:14 +08001744
1745 if (likely(first_level_support != -1))
1746 return first_level_support;
1747
1748 first_level_support = 1;
1749
1750 rcu_read_lock();
1751 for_each_active_iommu(iommu, drhd) {
1752 if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
1753 first_level_support = 0;
1754 break;
1755 }
1756 }
1757 rcu_read_unlock();
1758
1759 return first_level_support;
1760}
1761
Jiang Liuab8dfe22014-07-11 14:19:27 +08001762static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001763{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001764 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001765
1766 domain = alloc_domain_mem();
1767 if (!domain)
1768 return NULL;
1769
Jiang Liuab8dfe22014-07-11 14:19:27 +08001770 memset(domain, 0, sizeof(*domain));
Anshuman Khandual98fa15f2019-03-05 15:42:58 -08001771 domain->nid = NUMA_NO_NODE;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001772 domain->flags = flags;
Lu Baolua1948f22020-01-02 08:18:14 +08001773 if (first_level_by_default())
1774 domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
Omer Peleg0824c592016-04-20 19:03:35 +03001775 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001776 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001777
1778 return domain;
1779}
1780
Joerg Roedeld160aca2015-07-22 11:52:53 +02001781/* Must be called with iommu->lock */
1782static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001783 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001784{
Jiang Liu44bde612014-07-11 14:19:29 +08001785 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001786 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001787
Joerg Roedel55d94042015-07-22 16:50:40 +02001788 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001789 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001790
Joerg Roedel29a27712015-07-21 17:17:12 +02001791 domain->iommu_refcnt[iommu->seq_id] += 1;
1792 domain->iommu_count += 1;
1793 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001794 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001795 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1796
1797 if (num >= ndomains) {
1798 pr_err("%s: No free domain ids\n", iommu->name);
1799 domain->iommu_refcnt[iommu->seq_id] -= 1;
1800 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001801 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001802 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001803
Joerg Roedeld160aca2015-07-22 11:52:53 +02001804 set_bit(num, iommu->domain_ids);
1805 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001806
Joerg Roedeld160aca2015-07-22 11:52:53 +02001807 domain->iommu_did[iommu->seq_id] = num;
1808 domain->nid = iommu->node;
1809
Jiang Liufb170fb2014-07-11 14:19:28 +08001810 domain_update_iommu_cap(domain);
1811 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001812
Joerg Roedel55d94042015-07-22 16:50:40 +02001813 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001814}
1815
1816static int domain_detach_iommu(struct dmar_domain *domain,
1817 struct intel_iommu *iommu)
1818{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001819 int num, count;
Jiang Liufb170fb2014-07-11 14:19:28 +08001820
Joerg Roedel55d94042015-07-22 16:50:40 +02001821 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001822 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001823
Joerg Roedel29a27712015-07-21 17:17:12 +02001824 domain->iommu_refcnt[iommu->seq_id] -= 1;
1825 count = --domain->iommu_count;
1826 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001827 num = domain->iommu_did[iommu->seq_id];
1828 clear_bit(num, iommu->domain_ids);
1829 set_iommu_domain(iommu, num, NULL);
1830
Jiang Liufb170fb2014-07-11 14:19:28 +08001831 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001832 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001833 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001834
1835 return count;
1836}
1837
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001838static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001839static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001840
Joseph Cihula51a63e62011-03-21 11:04:24 -07001841static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001842{
1843 struct pci_dev *pdev = NULL;
1844 struct iova *iova;
1845 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001846
Zhen Leiaa3ac942017-09-21 16:52:45 +01001847 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001848
Mark Gross8a443df2008-03-04 14:59:31 -08001849 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1850 &reserved_rbtree_key);
1851
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001852 /* IOAPIC ranges shouldn't be accessed by DMA */
1853 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1854 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001855 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001856 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001857 return -ENODEV;
1858 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001859
1860 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1861 for_each_pci_dev(pdev) {
1862 struct resource *r;
1863
1864 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1865 r = &pdev->resource[i];
1866 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1867 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001868 iova = reserve_iova(&reserved_iova_list,
1869 IOVA_PFN(r->start),
1870 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001871 if (!iova) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06001872 pci_err(pdev, "Reserve iova for %pR failed\n", r);
Joseph Cihula51a63e62011-03-21 11:04:24 -07001873 return -ENODEV;
1874 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875 }
1876 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001877 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001878}
1879
1880static void domain_reserve_special_ranges(struct dmar_domain *domain)
1881{
1882 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1883}
1884
1885static inline int guestwidth_to_adjustwidth(int gaw)
1886{
1887 int agaw;
1888 int r = (gaw - 12) % 9;
1889
1890 if (r == 0)
1891 agaw = gaw;
1892 else
1893 agaw = gaw + 9 - r;
1894 if (agaw > 64)
1895 agaw = 64;
1896 return agaw;
1897}
1898
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001899static void domain_exit(struct dmar_domain *domain)
1900{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001901
Joerg Roedeld160aca2015-07-22 11:52:53 +02001902 /* Remove associated devices and clear attached or cached domains */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001903 domain_remove_dev_info(domain);
Jiang Liu92d03cc2014-02-19 14:07:28 +08001904
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001905 /* destroy iovas */
1906 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001907
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001908 if (domain->pgd) {
1909 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001910
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001911 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
1912 dma_free_pagelist(freelist);
1913 }
David Woodhouseea8ea462014-03-05 17:09:32 +00001914
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001915 free_domain_mem(domain);
1916}
1917
Lu Baolu7373a8c2018-12-10 09:59:03 +08001918/*
1919 * Get the PASID directory size for scalable mode context entry.
1920 * Value of X in the PDTS field of a scalable mode context entry
1921 * indicates PASID directory with 2^(X + 7) entries.
1922 */
1923static inline unsigned long context_get_sm_pds(struct pasid_table *table)
1924{
1925 int pds, max_pde;
1926
1927 max_pde = table->max_pasid >> PASID_PDE_SHIFT;
1928 pds = find_first_bit((unsigned long *)&max_pde, MAX_NR_PASID_BITS);
1929 if (pds < 7)
1930 return 0;
1931
1932 return pds - 7;
1933}
1934
1935/*
1936 * Set the RID_PASID field of a scalable mode context entry. The
1937 * IOMMU hardware will use the PASID value set in this field for
1938 * DMA translations of DMA requests without PASID.
1939 */
1940static inline void
1941context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
1942{
1943 context->hi |= pasid & ((1 << 20) - 1);
1944 context->hi |= (1 << 20);
1945}
1946
1947/*
1948 * Set the DTE(Device-TLB Enable) field of a scalable mode context
1949 * entry.
1950 */
1951static inline void context_set_sm_dte(struct context_entry *context)
1952{
1953 context->lo |= (1 << 2);
1954}
1955
1956/*
1957 * Set the PRE(Page Request Enable) field of a scalable mode context
1958 * entry.
1959 */
1960static inline void context_set_sm_pre(struct context_entry *context)
1961{
1962 context->lo |= (1 << 4);
1963}
1964
1965/* Convert value to context PASID directory size field coding. */
1966#define context_pdts(pds) (((pds) & 0x7) << 9)
1967
David Woodhouse64ae8922014-03-09 12:52:30 -07001968static int domain_context_mapping_one(struct dmar_domain *domain,
1969 struct intel_iommu *iommu,
Lu Baoluca6e3222018-12-10 09:59:02 +08001970 struct pasid_table *table,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001971 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001972{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001973 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02001974 int translation = CONTEXT_TT_MULTI_LEVEL;
1975 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001976 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001977 unsigned long flags;
Lu Baolu7373a8c2018-12-10 09:59:03 +08001978 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02001979
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001980 WARN_ON(did == 0);
1981
Joerg Roedel28ccce02015-07-21 14:45:31 +02001982 if (hw_pass_through && domain_type_is_si(domain))
1983 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001984
1985 pr_debug("Set context mapping for %02x:%02x.%d\n",
1986 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07001987
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001988 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08001989
Joerg Roedel55d94042015-07-22 16:50:40 +02001990 spin_lock_irqsave(&device_domain_lock, flags);
1991 spin_lock(&iommu->lock);
1992
1993 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00001994 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001995 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02001996 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001997
Joerg Roedel55d94042015-07-22 16:50:40 +02001998 ret = 0;
1999 if (context_present(context))
2000 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002001
Xunlei Pangaec0e862016-12-05 20:09:07 +08002002 /*
2003 * For kdump cases, old valid entries may be cached due to the
2004 * in-flight DMA and copied pgtable, but there is no unmapping
2005 * behaviour for them, thus we need an explicit cache flush for
2006 * the newly-mapped device. For kdump, at this point, the device
2007 * is supposed to finish reset at its driver probe stage, so no
2008 * in-flight DMA will exist, and we don't need to worry anymore
2009 * hereafter.
2010 */
2011 if (context_copied(context)) {
2012 u16 did_old = context_domain_id(context);
2013
Christos Gkekasb117e032017-10-08 23:33:31 +01002014 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002015 iommu->flush.flush_context(iommu, did_old,
2016 (((u16)bus) << 8) | devfn,
2017 DMA_CCMD_MASK_NOBIT,
2018 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002019 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2020 DMA_TLB_DSI_FLUSH);
2021 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002022 }
2023
Joerg Roedelde24e552015-07-21 14:53:04 +02002024 context_clear_entry(context);
Weidong Hanea6606b2008-12-08 23:08:15 +08002025
Lu Baolu7373a8c2018-12-10 09:59:03 +08002026 if (sm_supported(iommu)) {
2027 unsigned long pds;
Joerg Roedelde24e552015-07-21 14:53:04 +02002028
Lu Baolu7373a8c2018-12-10 09:59:03 +08002029 WARN_ON(!table);
2030
2031 /* Setup the PASID DIR pointer: */
2032 pds = context_get_sm_pds(table);
2033 context->lo = (u64)virt_to_phys(table->table) |
2034 context_pdts(pds);
2035
2036 /* Setup the RID_PASID field: */
2037 context_set_sm_rid2pasid(context, PASID_RID2PASID);
2038
2039 /*
2040 * Setup the Device-TLB enable bit and Page request
2041 * Enable bit:
2042 */
David Woodhouse64ae8922014-03-09 12:52:30 -07002043 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002044 if (info && info->ats_supported)
Lu Baolu7373a8c2018-12-10 09:59:03 +08002045 context_set_sm_dte(context);
2046 if (info && info->pri_supported)
2047 context_set_sm_pre(context);
Joerg Roedelde24e552015-07-21 14:53:04 +02002048 } else {
Lu Baolu7373a8c2018-12-10 09:59:03 +08002049 struct dma_pte *pgd = domain->pgd;
2050 int agaw;
2051
2052 context_set_domain_id(context, did);
Lu Baolu7373a8c2018-12-10 09:59:03 +08002053
2054 if (translation != CONTEXT_TT_PASS_THROUGH) {
2055 /*
2056 * Skip top levels of page tables for iommu which has
2057 * less agaw than default. Unnecessary for PT mode.
2058 */
2059 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2060 ret = -ENOMEM;
2061 pgd = phys_to_virt(dma_pte_addr(pgd));
2062 if (!dma_pte_present(pgd))
2063 goto out_unlock;
2064 }
2065
2066 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
2067 if (info && info->ats_supported)
2068 translation = CONTEXT_TT_DEV_IOTLB;
2069 else
2070 translation = CONTEXT_TT_MULTI_LEVEL;
2071
2072 context_set_address_root(context, virt_to_phys(pgd));
2073 context_set_address_width(context, agaw);
2074 } else {
2075 /*
2076 * In pass through mode, AW must be programmed to
2077 * indicate the largest AGAW value supported by
2078 * hardware. And ASR is ignored by hardware.
2079 */
2080 context_set_address_width(context, iommu->msagaw);
2081 }
Lu Baolu41b80db2019-03-01 11:23:11 +08002082
2083 context_set_translation_type(context, translation);
Yu Zhao93a23a72009-05-18 13:51:37 +08002084 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002085
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002086 context_set_fault_enable(context);
2087 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002088 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002089
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002090 /*
2091 * It's a non-present to present mapping. If hardware doesn't cache
2092 * non-present entry we only need to flush the write-buffer. If the
2093 * _does_ cache non-present entries, then it does so in the special
2094 * domain #0, which we have to flush:
2095 */
2096 if (cap_caching_mode(iommu->cap)) {
2097 iommu->flush.flush_context(iommu, 0,
2098 (((u16)bus) << 8) | devfn,
2099 DMA_CCMD_MASK_NOBIT,
2100 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002101 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002102 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002103 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002104 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002105 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002106
Joerg Roedel55d94042015-07-22 16:50:40 +02002107 ret = 0;
2108
2109out_unlock:
2110 spin_unlock(&iommu->lock);
2111 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002112
Wei Yang5c365d12016-07-13 13:53:21 +00002113 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002114}
2115
Lu Baolu0ce4a852019-08-26 16:50:56 +08002116struct domain_context_mapping_data {
2117 struct dmar_domain *domain;
2118 struct intel_iommu *iommu;
2119 struct pasid_table *table;
2120};
2121
2122static int domain_context_mapping_cb(struct pci_dev *pdev,
2123 u16 alias, void *opaque)
2124{
2125 struct domain_context_mapping_data *data = opaque;
2126
2127 return domain_context_mapping_one(data->domain, data->iommu,
2128 data->table, PCI_BUS_NUM(alias),
2129 alias & 0xff);
2130}
2131
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002132static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002133domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002134{
Lu Baolu0ce4a852019-08-26 16:50:56 +08002135 struct domain_context_mapping_data data;
Lu Baoluca6e3222018-12-10 09:59:02 +08002136 struct pasid_table *table;
David Woodhouse64ae8922014-03-09 12:52:30 -07002137 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002138 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002139
David Woodhousee1f167f2014-03-09 15:24:46 -07002140 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002141 if (!iommu)
2142 return -ENODEV;
2143
Lu Baoluca6e3222018-12-10 09:59:02 +08002144 table = intel_pasid_get_table(dev);
Lu Baolu0ce4a852019-08-26 16:50:56 +08002145
2146 if (!dev_is_pci(dev))
2147 return domain_context_mapping_one(domain, iommu, table,
2148 bus, devfn);
2149
2150 data.domain = domain;
2151 data.iommu = iommu;
2152 data.table = table;
2153
2154 return pci_for_each_dma_alias(to_pci_dev(dev),
2155 &domain_context_mapping_cb, &data);
Alex Williamson579305f2014-07-03 09:51:43 -06002156}
2157
2158static int domain_context_mapped_cb(struct pci_dev *pdev,
2159 u16 alias, void *opaque)
2160{
2161 struct intel_iommu *iommu = opaque;
2162
2163 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002164}
2165
David Woodhousee1f167f2014-03-09 15:24:46 -07002166static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002167{
Weidong Han5331fe62008-12-08 23:00:00 +08002168 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002169 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002170
David Woodhousee1f167f2014-03-09 15:24:46 -07002171 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002172 if (!iommu)
2173 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002174
Alex Williamson579305f2014-07-03 09:51:43 -06002175 if (!dev_is_pci(dev))
2176 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002177
Alex Williamson579305f2014-07-03 09:51:43 -06002178 return !pci_for_each_dma_alias(to_pci_dev(dev),
2179 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002180}
2181
Fenghua Yuf5329592009-08-04 15:09:37 -07002182/* Returns a number of VTD pages, but aligned to MM page size */
2183static inline unsigned long aligned_nrpages(unsigned long host_addr,
2184 size_t size)
2185{
2186 host_addr &= ~PAGE_MASK;
2187 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2188}
2189
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002190/* Return largest possible superpage level for a given mapping */
2191static inline int hardware_largepage_caps(struct dmar_domain *domain,
2192 unsigned long iov_pfn,
2193 unsigned long phy_pfn,
2194 unsigned long pages)
2195{
2196 int support, level = 1;
2197 unsigned long pfnmerge;
2198
2199 support = domain->iommu_superpage;
2200
2201 /* To use a large page, the virtual *and* physical addresses
2202 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2203 of them will mean we have to use smaller pages. So just
2204 merge them and check both at once. */
2205 pfnmerge = iov_pfn | phy_pfn;
2206
2207 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2208 pages >>= VTD_STRIDE_SHIFT;
2209 if (!pages)
2210 break;
2211 pfnmerge >>= VTD_STRIDE_SHIFT;
2212 level++;
2213 support--;
2214 }
2215 return level;
2216}
2217
David Woodhouse9051aa02009-06-29 12:30:54 +01002218static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2219 struct scatterlist *sg, unsigned long phys_pfn,
2220 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002221{
2222 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002223 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002224 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002225 unsigned int largepage_lvl = 0;
2226 unsigned long lvl_pages = 0;
Lu Baoluddf09b62020-01-02 08:18:17 +08002227 u64 attr;
David Woodhousee1605492009-06-29 11:17:38 +01002228
Jiang Liu162d1b12014-07-11 14:19:35 +08002229 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002230
2231 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2232 return -EINVAL;
2233
Lu Baoluddf09b62020-01-02 08:18:17 +08002234 attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
2235 if (domain_use_first_level(domain))
2236 attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD;
David Woodhousee1605492009-06-29 11:17:38 +01002237
Jiang Liucc4f14a2014-11-26 09:42:10 +08002238 if (!sg) {
2239 sg_res = nr_pages;
Lu Baoluddf09b62020-01-02 08:18:17 +08002240 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
David Woodhouse9051aa02009-06-29 12:30:54 +01002241 }
2242
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002243 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002244 uint64_t tmp;
2245
David Woodhousee1605492009-06-29 11:17:38 +01002246 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002247 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2248
Fenghua Yuf5329592009-08-04 15:09:37 -07002249 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002250 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002251 sg->dma_length = sg->length;
Lu Baoluddf09b62020-01-02 08:18:17 +08002252 pteval = (sg_phys(sg) - pgoff) | attr;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002253 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002254 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002255
David Woodhousee1605492009-06-29 11:17:38 +01002256 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002257 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2258
David Woodhouse5cf0a762014-03-19 16:07:49 +00002259 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002260 if (!pte)
2261 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002263 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002264 unsigned long nr_superpages, end_pfn;
2265
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002266 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002267 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002268
2269 nr_superpages = sg_res / lvl_pages;
2270 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2271
Jiang Liud41a4ad2014-07-11 14:19:34 +08002272 /*
2273 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002274 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002275 * We're adding new large pages, so make sure
2276 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002277 */
David Dillowbc24c572017-06-28 19:42:23 -07002278 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2279 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002280 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002281 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002282 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002283
David Woodhousee1605492009-06-29 11:17:38 +01002284 }
2285 /* We don't need lock here, nobody else
2286 * touches the iova range
2287 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002288 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002289 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002290 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002291 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2292 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002293 if (dumps) {
2294 dumps--;
2295 debug_dma_dump_mappings(NULL);
2296 }
2297 WARN_ON(1);
2298 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002299
2300 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2301
2302 BUG_ON(nr_pages < lvl_pages);
2303 BUG_ON(sg_res < lvl_pages);
2304
2305 nr_pages -= lvl_pages;
2306 iov_pfn += lvl_pages;
2307 phys_pfn += lvl_pages;
2308 pteval += lvl_pages * VTD_PAGE_SIZE;
2309 sg_res -= lvl_pages;
2310
2311 /* If the next PTE would be the first in a new page, then we
2312 need to flush the cache on the entries we've just written.
2313 And then we'll need to recalculate 'pte', so clear it and
2314 let it get set again in the if (!pte) block above.
2315
2316 If we're done (!nr_pages) we need to flush the cache too.
2317
2318 Also if we've been setting superpages, we may need to
2319 recalculate 'pte' and switch back to smaller pages for the
2320 end of the mapping, if the trailing size is not enough to
2321 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002322 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002323 if (!nr_pages || first_pte_in_page(pte) ||
2324 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002325 domain_flush_cache(domain, first_pte,
2326 (void *)pte - (void *)first_pte);
2327 pte = NULL;
2328 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002329
2330 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002331 sg = sg_next(sg);
2332 }
2333 return 0;
2334}
2335
Peter Xu87684fd2018-05-04 10:34:53 +08002336static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
Lu Baolu095303e2019-04-29 09:16:02 +08002337 struct scatterlist *sg, unsigned long phys_pfn,
2338 unsigned long nr_pages, int prot)
Peter Xu87684fd2018-05-04 10:34:53 +08002339{
Lu Baolufa954e62019-05-25 13:41:28 +08002340 int iommu_id, ret;
Lu Baolu095303e2019-04-29 09:16:02 +08002341 struct intel_iommu *iommu;
Peter Xu87684fd2018-05-04 10:34:53 +08002342
Lu Baolu095303e2019-04-29 09:16:02 +08002343 /* Do the real mapping first */
2344 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2345 if (ret)
2346 return ret;
Peter Xu87684fd2018-05-04 10:34:53 +08002347
Lu Baolufa954e62019-05-25 13:41:28 +08002348 for_each_domain_iommu(iommu_id, domain) {
2349 iommu = g_iommus[iommu_id];
Lu Baolu095303e2019-04-29 09:16:02 +08002350 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2351 }
2352
2353 return 0;
Peter Xu87684fd2018-05-04 10:34:53 +08002354}
2355
David Woodhouse9051aa02009-06-29 12:30:54 +01002356static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2357 struct scatterlist *sg, unsigned long nr_pages,
2358 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002359{
Peter Xu87684fd2018-05-04 10:34:53 +08002360 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002361}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002362
David Woodhouse9051aa02009-06-29 12:30:54 +01002363static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2364 unsigned long phys_pfn, unsigned long nr_pages,
2365 int prot)
2366{
Peter Xu87684fd2018-05-04 10:34:53 +08002367 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002368}
2369
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002370static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002371{
Filippo Sironi50822192017-08-31 10:58:11 +02002372 unsigned long flags;
2373 struct context_entry *context;
2374 u16 did_old;
2375
Weidong Hanc7151a82008-12-08 22:51:37 +08002376 if (!iommu)
2377 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002378
Filippo Sironi50822192017-08-31 10:58:11 +02002379 spin_lock_irqsave(&iommu->lock, flags);
2380 context = iommu_context_addr(iommu, bus, devfn, 0);
2381 if (!context) {
2382 spin_unlock_irqrestore(&iommu->lock, flags);
2383 return;
2384 }
2385 did_old = context_domain_id(context);
2386 context_clear_entry(context);
2387 __iommu_flush_cache(iommu, context, sizeof(*context));
2388 spin_unlock_irqrestore(&iommu->lock, flags);
2389 iommu->flush.flush_context(iommu,
2390 did_old,
2391 (((u16)bus) << 8) | devfn,
2392 DMA_CCMD_MASK_NOBIT,
2393 DMA_CCMD_DEVICE_INVL);
2394 iommu->flush.flush_iotlb(iommu,
2395 did_old,
2396 0,
2397 0,
2398 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002399}
2400
David Woodhouse109b9b02012-05-25 17:43:02 +01002401static inline void unlink_domain_info(struct device_domain_info *info)
2402{
2403 assert_spin_locked(&device_domain_lock);
2404 list_del(&info->link);
2405 list_del(&info->global);
2406 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002407 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002408}
2409
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002410static void domain_remove_dev_info(struct dmar_domain *domain)
2411{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002412 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002413 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002414
2415 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002416 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002417 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002418 spin_unlock_irqrestore(&device_domain_lock, flags);
2419}
2420
Lu Baolue2726da2020-01-02 08:18:22 +08002421struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002422{
2423 struct device_domain_info *info;
2424
Joerg Roedel1d46159782020-02-17 17:12:37 +01002425 if (unlikely(attach_deferred(dev) || iommu_dummy(dev)))
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002426 return NULL;
2427
Jon Derrick2b0140c2020-01-21 06:37:48 -07002428 if (dev_is_pci(dev))
2429 dev = &pci_real_dma_dev(to_pci_dev(dev))->dev;
2430
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002431 /* No lock here, assumes no domain exit in normal case */
2432 info = dev->archdata.iommu;
2433 if (likely(info))
2434 return info->domain;
2435
2436 return NULL;
2437}
2438
Joerg Roedel034d98c2020-02-17 17:16:19 +01002439static void do_deferred_attach(struct device *dev)
2440{
2441 struct iommu_domain *domain;
2442
2443 dev->archdata.iommu = NULL;
2444 domain = iommu_get_domain_for_dev(dev);
2445 if (domain)
2446 intel_iommu_attach_device(domain, dev);
2447}
2448
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002449static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002450dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2451{
2452 struct device_domain_info *info;
2453
2454 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002455 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002456 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002457 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002458
2459 return NULL;
2460}
2461
Lu Baoluddf09b62020-01-02 08:18:17 +08002462static int domain_setup_first_level(struct intel_iommu *iommu,
2463 struct dmar_domain *domain,
2464 struct device *dev,
2465 int pasid)
2466{
2467 int flags = PASID_FLAG_SUPERVISOR_MODE;
2468 struct dma_pte *pgd = domain->pgd;
2469 int agaw, level;
2470
2471 /*
2472 * Skip top levels of page tables for iommu which has
2473 * less agaw than default. Unnecessary for PT mode.
2474 */
2475 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2476 pgd = phys_to_virt(dma_pte_addr(pgd));
2477 if (!dma_pte_present(pgd))
2478 return -ENOMEM;
2479 }
2480
2481 level = agaw_to_level(agaw);
2482 if (level != 4 && level != 5)
2483 return -EINVAL;
2484
2485 flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;
2486
2487 return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,
2488 domain->iommu_did[iommu->seq_id],
2489 flags);
2490}
2491
Joerg Roedel5db31562015-07-22 12:40:43 +02002492static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2493 int bus, int devfn,
2494 struct device *dev,
2495 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002496{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002497 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002498 struct device_domain_info *info;
2499 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002500 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002501
2502 info = alloc_devinfo_mem();
2503 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002504 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002505
Jiang Liu745f2582014-02-19 14:07:26 +08002506 info->bus = bus;
2507 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002508 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2509 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2510 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002511 info->dev = dev;
2512 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002513 info->iommu = iommu;
Lu Baolucc580e42018-07-14 15:46:59 +08002514 info->pasid_table = NULL;
Lu Baolu95587a72019-03-25 09:30:30 +08002515 info->auxd_enabled = 0;
Lu Baolu67b8e022019-03-25 09:30:32 +08002516 INIT_LIST_HEAD(&info->auxiliary_domains);
Jiang Liu745f2582014-02-19 14:07:26 +08002517
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002518 if (dev && dev_is_pci(dev)) {
2519 struct pci_dev *pdev = to_pci_dev(info->dev);
2520
Lu Baolud8b85912019-03-01 11:23:10 +08002521 if (!pdev->untrusted &&
2522 !pci_ats_disabled() &&
Gil Kupfercef74402018-05-10 17:56:02 -05002523 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002524 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2525 dmar_find_matched_atsr_unit(pdev))
2526 info->ats_supported = 1;
2527
Lu Baolu765b6a92018-12-10 09:58:55 +08002528 if (sm_supported(iommu)) {
2529 if (pasid_supported(iommu)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002530 int features = pci_pasid_features(pdev);
2531 if (features >= 0)
2532 info->pasid_supported = features | 1;
2533 }
2534
2535 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2536 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2537 info->pri_supported = 1;
2538 }
2539 }
2540
Jiang Liu745f2582014-02-19 14:07:26 +08002541 spin_lock_irqsave(&device_domain_lock, flags);
2542 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002543 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002544
2545 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002546 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002547 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002548 if (info2) {
2549 found = info2->domain;
2550 info2->dev = dev;
2551 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002552 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002553
Jiang Liu745f2582014-02-19 14:07:26 +08002554 if (found) {
2555 spin_unlock_irqrestore(&device_domain_lock, flags);
2556 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002557 /* Caller must free the original domain */
2558 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002559 }
2560
Joerg Roedeld160aca2015-07-22 11:52:53 +02002561 spin_lock(&iommu->lock);
2562 ret = domain_attach_iommu(domain, iommu);
2563 spin_unlock(&iommu->lock);
2564
2565 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002566 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302567 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002568 return NULL;
2569 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002570
David Woodhouseb718cd32014-03-09 13:11:33 -07002571 list_add(&info->link, &domain->devices);
2572 list_add(&info->global, &device_domain_list);
2573 if (dev)
2574 dev->archdata.iommu = info;
Lu Baolu0bbeb012018-12-10 09:58:56 +08002575 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolua7fc93f2018-07-14 15:47:00 +08002576
Lu Baolu0bbeb012018-12-10 09:58:56 +08002577 /* PASID table is mandatory for a PCI device in scalable mode. */
2578 if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
Lu Baolua7fc93f2018-07-14 15:47:00 +08002579 ret = intel_pasid_alloc_table(dev);
2580 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002581 dev_err(dev, "PASID table allocation failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002582 dmar_remove_one_dev_info(dev);
Lu Baolu0bbeb012018-12-10 09:58:56 +08002583 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002584 }
Lu Baoluef848b72018-12-10 09:59:01 +08002585
2586 /* Setup the PASID entry for requests without PASID: */
2587 spin_lock(&iommu->lock);
2588 if (hw_pass_through && domain_type_is_si(domain))
2589 ret = intel_pasid_setup_pass_through(iommu, domain,
2590 dev, PASID_RID2PASID);
Lu Baoluddf09b62020-01-02 08:18:17 +08002591 else if (domain_use_first_level(domain))
2592 ret = domain_setup_first_level(iommu, domain, dev,
2593 PASID_RID2PASID);
Lu Baoluef848b72018-12-10 09:59:01 +08002594 else
2595 ret = intel_pasid_setup_second_level(iommu, domain,
2596 dev, PASID_RID2PASID);
2597 spin_unlock(&iommu->lock);
2598 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002599 dev_err(dev, "Setup RID2PASID failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002600 dmar_remove_one_dev_info(dev);
Lu Baoluef848b72018-12-10 09:59:01 +08002601 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002602 }
2603 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002604
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002605 if (dev && domain_context_mapping(domain, dev)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002606 dev_err(dev, "Domain context map failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002607 dmar_remove_one_dev_info(dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002608 return NULL;
2609 }
2610
David Woodhouseb718cd32014-03-09 13:11:33 -07002611 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002612}
2613
David Woodhouseb2132032009-06-26 18:50:28 +01002614static int iommu_domain_identity_map(struct dmar_domain *domain,
2615 unsigned long long start,
2616 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002617{
David Woodhousec5395d52009-06-28 16:35:56 +01002618 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2619 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002620
David Woodhousec5395d52009-06-28 16:35:56 +01002621 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2622 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002623 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002624 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002625 }
2626
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002627 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002628 /*
2629 * RMRR range might have overlap with physical memory range,
2630 * clear it first
2631 */
David Woodhousec5395d52009-06-28 16:35:56 +01002632 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002633
Peter Xu87684fd2018-05-04 10:34:53 +08002634 return __domain_mapping(domain, first_vpfn, NULL,
2635 first_vpfn, last_vpfn - first_vpfn + 1,
2636 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002637}
2638
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002639static int md_domain_init(struct dmar_domain *domain, int guest_width);
2640
Matt Kraai071e1372009-08-23 22:30:22 -07002641static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002642{
Lu Baolu4de354e2019-05-25 13:41:27 +08002643 struct dmar_rmrr_unit *rmrr;
2644 struct device *dev;
2645 int i, nid, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002646
Jiang Liuab8dfe22014-07-11 14:19:27 +08002647 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002648 if (!si_domain)
2649 return -EFAULT;
2650
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002651 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002652 domain_exit(si_domain);
2653 return -EFAULT;
2654 }
2655
David Woodhouse19943b02009-08-04 16:19:20 +01002656 if (hw)
2657 return 0;
2658
David Woodhousec7ab48d2009-06-26 19:10:36 +01002659 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002660 unsigned long start_pfn, end_pfn;
2661 int i;
2662
2663 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2664 ret = iommu_domain_identity_map(si_domain,
2665 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2666 if (ret)
2667 return ret;
2668 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002669 }
2670
Lu Baolu4de354e2019-05-25 13:41:27 +08002671 /*
Lu Baolu9235cb132020-01-15 11:03:58 +08002672 * Identity map the RMRRs so that devices with RMRRs could also use
2673 * the si_domain.
Lu Baolu4de354e2019-05-25 13:41:27 +08002674 */
2675 for_each_rmrr_units(rmrr) {
2676 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
2677 i, dev) {
2678 unsigned long long start = rmrr->base_address;
2679 unsigned long long end = rmrr->end_address;
2680
Lu Baolu4de354e2019-05-25 13:41:27 +08002681 if (WARN_ON(end < start ||
2682 end >> agaw_to_width(si_domain->agaw)))
2683 continue;
2684
2685 ret = iommu_domain_identity_map(si_domain, start, end);
2686 if (ret)
2687 return ret;
2688 }
2689 }
2690
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002691 return 0;
2692}
2693
Joerg Roedel28ccce02015-07-21 14:45:31 +02002694static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002695{
David Woodhouse0ac72662014-03-09 13:19:22 -07002696 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002697 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002698 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002699
David Woodhouse5913c9b2014-03-09 16:27:31 -07002700 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002701 if (!iommu)
2702 return -ENODEV;
2703
Joerg Roedel5db31562015-07-22 12:40:43 +02002704 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002705 if (ndomain != domain)
2706 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002707
2708 return 0;
2709}
2710
David Woodhouse0b9d9752014-03-09 15:48:15 -07002711static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002712{
2713 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002714 struct device *tmp;
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002715 int i;
2716
Jiang Liu0e242612014-02-19 14:07:34 +08002717 rcu_read_lock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002718 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002719 /*
2720 * Return TRUE if this RMRR contains the device that
2721 * is passed in.
2722 */
2723 for_each_active_dev_scope(rmrr->devices,
2724 rmrr->devices_cnt, i, tmp)
Eric Augere143fd42019-06-03 08:53:33 +02002725 if (tmp == dev ||
2726 is_downstream_to_pci_bridge(dev, tmp)) {
Jiang Liu0e242612014-02-19 14:07:34 +08002727 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002728 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002729 }
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002730 }
Jiang Liu0e242612014-02-19 14:07:34 +08002731 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002732 return false;
2733}
2734
Eric Auger1c5c59f2019-06-03 08:53:36 +02002735/**
2736 * device_rmrr_is_relaxable - Test whether the RMRR of this device
2737 * is relaxable (ie. is allowed to be not enforced under some conditions)
2738 * @dev: device handle
2739 *
2740 * We assume that PCI USB devices with RMRRs have them largely
2741 * for historical reasons and that the RMRR space is not actively used post
2742 * boot. This exclusion may change if vendors begin to abuse it.
2743 *
2744 * The same exception is made for graphics devices, with the requirement that
2745 * any use of the RMRR regions will be torn down before assigning the device
2746 * to a guest.
2747 *
2748 * Return: true if the RMRR is relaxable, false otherwise
2749 */
2750static bool device_rmrr_is_relaxable(struct device *dev)
2751{
2752 struct pci_dev *pdev;
2753
2754 if (!dev_is_pci(dev))
2755 return false;
2756
2757 pdev = to_pci_dev(dev);
2758 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
2759 return true;
2760 else
2761 return false;
2762}
2763
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002764/*
2765 * There are a couple cases where we need to restrict the functionality of
2766 * devices associated with RMRRs. The first is when evaluating a device for
2767 * identity mapping because problems exist when devices are moved in and out
2768 * of domains and their respective RMRR information is lost. This means that
2769 * a device with associated RMRRs will never be in a "passthrough" domain.
2770 * The second is use of the device through the IOMMU API. This interface
2771 * expects to have full control of the IOVA space for the device. We cannot
2772 * satisfy both the requirement that RMRR access is maintained and have an
2773 * unencumbered IOVA space. We also have no ability to quiesce the device's
2774 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2775 * We therefore prevent devices associated with an RMRR from participating in
2776 * the IOMMU API, which eliminates them from device assignment.
2777 *
Eric Auger1c5c59f2019-06-03 08:53:36 +02002778 * In both cases, devices which have relaxable RMRRs are not concerned by this
2779 * restriction. See device_rmrr_is_relaxable comment.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002780 */
2781static bool device_is_rmrr_locked(struct device *dev)
2782{
2783 if (!device_has_rmrr(dev))
2784 return false;
2785
Eric Auger1c5c59f2019-06-03 08:53:36 +02002786 if (device_rmrr_is_relaxable(dev))
2787 return false;
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002788
2789 return true;
2790}
2791
Lu Baoluf273a452019-05-25 13:41:26 +08002792/*
2793 * Return the required default domain type for a specific device.
2794 *
2795 * @dev: the device in query
2796 * @startup: true if this is during early boot
2797 *
2798 * Returns:
2799 * - IOMMU_DOMAIN_DMA: device requires a dynamic mapping domain
2800 * - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
2801 * - 0: both identity and dynamic domains work for this device
2802 */
Lu Baolu0e31a722019-05-25 13:41:34 +08002803static int device_def_domain_type(struct device *dev)
David Woodhouse6941af22009-07-04 18:24:27 +01002804{
David Woodhouse3bdb2592014-03-09 16:03:08 -07002805 if (dev_is_pci(dev)) {
2806 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002807
Lu Baolu89a60792018-10-23 15:45:01 +08002808 /*
2809 * Prevent any device marked as untrusted from getting
2810 * placed into the statically identity mapping domain.
2811 */
2812 if (pdev->untrusted)
Lu Baoluf273a452019-05-25 13:41:26 +08002813 return IOMMU_DOMAIN_DMA;
Lu Baolu89a60792018-10-23 15:45:01 +08002814
David Woodhouse3bdb2592014-03-09 16:03:08 -07002815 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002816 return IOMMU_DOMAIN_IDENTITY;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002817
David Woodhouse3bdb2592014-03-09 16:03:08 -07002818 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002819 return IOMMU_DOMAIN_IDENTITY;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002820 }
David Woodhouse6941af22009-07-04 18:24:27 +01002821
Lu Baolub89b6602020-01-15 11:03:59 +08002822 return 0;
Lu Baoluf273a452019-05-25 13:41:26 +08002823}
2824
Jiang Liuffebeb42014-11-09 22:48:02 +08002825static void intel_iommu_init_qi(struct intel_iommu *iommu)
2826{
2827 /*
2828 * Start from the sane iommu hardware state.
2829 * If the queued invalidation is already initialized by us
2830 * (for example, while enabling interrupt-remapping) then
2831 * we got the things already rolling from a sane state.
2832 */
2833 if (!iommu->qi) {
2834 /*
2835 * Clear any previous faults.
2836 */
2837 dmar_fault(-1, iommu);
2838 /*
2839 * Disable queued invalidation if supported and already enabled
2840 * before OS handover.
2841 */
2842 dmar_disable_qi(iommu);
2843 }
2844
2845 if (dmar_enable_qi(iommu)) {
2846 /*
2847 * Queued Invalidate not enabled, use Register Based Invalidate
2848 */
2849 iommu->flush.flush_context = __iommu_flush_context;
2850 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002851 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08002852 iommu->name);
2853 } else {
2854 iommu->flush.flush_context = qi_flush_context;
2855 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002856 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08002857 }
2858}
2859
Joerg Roedel091d42e2015-06-12 11:56:10 +02002860static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb962015-10-09 18:16:46 -04002861 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02002862 struct context_entry **tbl,
2863 int bus, bool ext)
2864{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02002865 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002866 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb962015-10-09 18:16:46 -04002867 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002868 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002869 phys_addr_t old_ce_phys;
2870
2871 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb962015-10-09 18:16:46 -04002872 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02002873
2874 for (devfn = 0; devfn < 256; devfn++) {
2875 /* First calculate the correct index */
2876 idx = (ext ? devfn * 2 : devfn) % 256;
2877
2878 if (idx == 0) {
2879 /* First save what we may have and clean up */
2880 if (new_ce) {
2881 tbl[tbl_idx] = new_ce;
2882 __iommu_flush_cache(iommu, new_ce,
2883 VTD_PAGE_SIZE);
2884 pos = 1;
2885 }
2886
2887 if (old_ce)
Pan Bian829383e2018-11-21 17:53:47 +08002888 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002889
2890 ret = 0;
2891 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002892 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002893 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02002894 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002895
2896 if (!old_ce_phys) {
2897 if (ext && devfn == 0) {
2898 /* No LCTP, try UCTP */
2899 devfn = 0x7f;
2900 continue;
2901 } else {
2902 goto out;
2903 }
2904 }
2905
2906 ret = -ENOMEM;
Dan Williamsdfddb962015-10-09 18:16:46 -04002907 old_ce = memremap(old_ce_phys, PAGE_SIZE,
2908 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002909 if (!old_ce)
2910 goto out;
2911
2912 new_ce = alloc_pgtable_page(iommu->node);
2913 if (!new_ce)
2914 goto out_unmap;
2915
2916 ret = 0;
2917 }
2918
2919 /* Now copy the context entry */
Dan Williamsdfddb962015-10-09 18:16:46 -04002920 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02002921
Joerg Roedelcf484d02015-06-12 12:21:46 +02002922 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02002923 continue;
2924
Joerg Roedeldbcd8612015-06-12 12:02:09 +02002925 did = context_domain_id(&ce);
2926 if (did >= 0 && did < cap_ndoms(iommu->cap))
2927 set_bit(did, iommu->domain_ids);
2928
Joerg Roedelcf484d02015-06-12 12:21:46 +02002929 /*
2930 * We need a marker for copied context entries. This
2931 * marker needs to work for the old format as well as
2932 * for extended context entries.
2933 *
2934 * Bit 67 of the context entry is used. In the old
2935 * format this bit is available to software, in the
2936 * extended format it is the PGE bit, but PGE is ignored
2937 * by HW if PASIDs are disabled (and thus still
2938 * available).
2939 *
2940 * So disable PASIDs first and then mark the entry
2941 * copied. This means that we don't copy PASID
2942 * translations from the old kernel, but this is fine as
2943 * faults there are not fatal.
2944 */
2945 context_clear_pasid_enable(&ce);
2946 context_set_copied(&ce);
2947
Joerg Roedel091d42e2015-06-12 11:56:10 +02002948 new_ce[idx] = ce;
2949 }
2950
2951 tbl[tbl_idx + pos] = new_ce;
2952
2953 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
2954
2955out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04002956 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002957
2958out:
2959 return ret;
2960}
2961
2962static int copy_translation_tables(struct intel_iommu *iommu)
2963{
2964 struct context_entry **ctxt_tbls;
Dan Williamsdfddb962015-10-09 18:16:46 -04002965 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002966 phys_addr_t old_rt_phys;
2967 int ctxt_table_entries;
2968 unsigned long flags;
2969 u64 rtaddr_reg;
2970 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02002971 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002972
2973 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
2974 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02002975 new_ext = !!ecap_ecs(iommu->ecap);
2976
2977 /*
2978 * The RTT bit can only be changed when translation is disabled,
2979 * but disabling translation means to open a window for data
2980 * corruption. So bail out and don't copy anything if we would
2981 * have to change the bit.
2982 */
2983 if (new_ext != ext)
2984 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02002985
2986 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
2987 if (!old_rt_phys)
2988 return -EINVAL;
2989
Dan Williamsdfddb962015-10-09 18:16:46 -04002990 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002991 if (!old_rt)
2992 return -ENOMEM;
2993
2994 /* This is too big for the stack - allocate it from slab */
2995 ctxt_table_entries = ext ? 512 : 256;
2996 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07002997 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02002998 if (!ctxt_tbls)
2999 goto out_unmap;
3000
3001 for (bus = 0; bus < 256; bus++) {
3002 ret = copy_context_table(iommu, &old_rt[bus],
3003 ctxt_tbls, bus, ext);
3004 if (ret) {
3005 pr_err("%s: Failed to copy context table for bus %d\n",
3006 iommu->name, bus);
3007 continue;
3008 }
3009 }
3010
3011 spin_lock_irqsave(&iommu->lock, flags);
3012
3013 /* Context tables are copied, now write them to the root_entry table */
3014 for (bus = 0; bus < 256; bus++) {
3015 int idx = ext ? bus * 2 : bus;
3016 u64 val;
3017
3018 if (ctxt_tbls[idx]) {
3019 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3020 iommu->root_entry[bus].lo = val;
3021 }
3022
3023 if (!ext || !ctxt_tbls[idx + 1])
3024 continue;
3025
3026 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3027 iommu->root_entry[bus].hi = val;
3028 }
3029
3030 spin_unlock_irqrestore(&iommu->lock, flags);
3031
3032 kfree(ctxt_tbls);
3033
3034 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3035
3036 ret = 0;
3037
3038out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003039 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003040
3041 return ret;
3042}
3043
Jacob Pan33753032020-05-16 14:20:51 +08003044#ifdef CONFIG_INTEL_IOMMU_SVM
3045static ioasid_t intel_vcmd_ioasid_alloc(ioasid_t min, ioasid_t max, void *data)
3046{
3047 struct intel_iommu *iommu = data;
3048 ioasid_t ioasid;
3049
3050 if (!iommu)
3051 return INVALID_IOASID;
3052 /*
3053 * VT-d virtual command interface always uses the full 20 bit
3054 * PASID range. Host can partition guest PASID range based on
3055 * policies but it is out of guest's control.
3056 */
3057 if (min < PASID_MIN || max > intel_pasid_max_id)
3058 return INVALID_IOASID;
3059
3060 if (vcmd_alloc_pasid(iommu, &ioasid))
3061 return INVALID_IOASID;
3062
3063 return ioasid;
3064}
3065
3066static void intel_vcmd_ioasid_free(ioasid_t ioasid, void *data)
3067{
3068 struct intel_iommu *iommu = data;
3069
3070 if (!iommu)
3071 return;
3072 /*
3073 * Sanity check the ioasid owner is done at upper layer, e.g. VFIO
3074 * We can only free the PASID when all the devices are unbound.
3075 */
3076 if (ioasid_find(NULL, ioasid, NULL)) {
3077 pr_alert("Cannot free active IOASID %d\n", ioasid);
3078 return;
3079 }
3080 vcmd_free_pasid(iommu, ioasid);
3081}
3082
3083static void register_pasid_allocator(struct intel_iommu *iommu)
3084{
3085 /*
3086 * If we are running in the host, no need for custom allocator
3087 * in that PASIDs are allocated from the host system-wide.
3088 */
3089 if (!cap_caching_mode(iommu->cap))
3090 return;
3091
3092 if (!sm_supported(iommu)) {
3093 pr_warn("VT-d Scalable Mode not enabled, no PASID allocation\n");
3094 return;
3095 }
3096
3097 /*
3098 * Register a custom PASID allocator if we are running in a guest,
3099 * guest PASID must be obtained via virtual command interface.
3100 * There can be multiple vIOMMUs in each guest but only one allocator
3101 * is active. All vIOMMU allocators will eventually be calling the same
3102 * host allocator.
3103 */
3104 if (!ecap_vcs(iommu->ecap) || !vccap_pasid(iommu->vccap))
3105 return;
3106
3107 pr_info("Register custom PASID allocator\n");
3108 iommu->pasid_allocator.alloc = intel_vcmd_ioasid_alloc;
3109 iommu->pasid_allocator.free = intel_vcmd_ioasid_free;
3110 iommu->pasid_allocator.pdata = (void *)iommu;
3111 if (ioasid_register_allocator(&iommu->pasid_allocator)) {
3112 pr_warn("Custom PASID allocator failed, scalable mode disabled\n");
3113 /*
3114 * Disable scalable mode on this IOMMU if there
3115 * is no custom allocator. Mixing SM capable vIOMMU
3116 * and non-SM vIOMMU are not supported.
3117 */
3118 intel_iommu_sm = 0;
3119 }
3120}
3121#endif
3122
Joseph Cihulab7792602011-05-03 00:08:37 -07003123static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003124{
3125 struct dmar_drhd_unit *drhd;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003126 struct intel_iommu *iommu;
Lu Baoludf4f3c62019-05-25 13:41:36 +08003127 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003128
3129 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003130 * for each drhd
3131 * allocate root
3132 * initialize and program root entry to not present
3133 * endfor
3134 */
3135 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003136 /*
3137 * lock not needed as this is only incremented in the single
3138 * threaded kernel __init code path all other access are read
3139 * only
3140 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003141 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003142 g_num_of_iommus++;
3143 continue;
3144 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003145 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003146 }
3147
Jiang Liuffebeb42014-11-09 22:48:02 +08003148 /* Preallocate enough resources for IOMMU hot-addition */
3149 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3150 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3151
Weidong Hand9630fe2008-12-08 11:06:32 +08003152 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3153 GFP_KERNEL);
3154 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003155 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003156 ret = -ENOMEM;
3157 goto error;
3158 }
3159
Lu Baolu6a8c6742019-06-12 08:28:47 +08003160 for_each_iommu(iommu, drhd) {
3161 if (drhd->ignored) {
3162 iommu_disable_translation(iommu);
3163 continue;
3164 }
3165
Lu Baolu56283172018-07-14 15:46:54 +08003166 /*
3167 * Find the max pasid size of all IOMMU's in the system.
3168 * We need to ensure the system pasid table is no bigger
3169 * than the smallest supported.
3170 */
Lu Baolu765b6a92018-12-10 09:58:55 +08003171 if (pasid_supported(iommu)) {
Lu Baolu56283172018-07-14 15:46:54 +08003172 u32 temp = 2 << ecap_pss(iommu->ecap);
3173
3174 intel_pasid_max_id = min_t(u32, temp,
3175 intel_pasid_max_id);
3176 }
3177
Weidong Hand9630fe2008-12-08 11:06:32 +08003178 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003179
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003180 intel_iommu_init_qi(iommu);
3181
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003182 ret = iommu_init_domains(iommu);
3183 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003184 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003185
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003186 init_translation_status(iommu);
3187
Joerg Roedel091d42e2015-06-12 11:56:10 +02003188 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3189 iommu_disable_translation(iommu);
3190 clear_translation_pre_enabled(iommu);
3191 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3192 iommu->name);
3193 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003194
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003195 /*
3196 * TBD:
3197 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003198 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003199 */
3200 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003201 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003202 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003203
Joerg Roedel091d42e2015-06-12 11:56:10 +02003204 if (translation_pre_enabled(iommu)) {
3205 pr_info("Translation already enabled - trying to copy translation structures\n");
3206
3207 ret = copy_translation_tables(iommu);
3208 if (ret) {
3209 /*
3210 * We found the IOMMU with translation
3211 * enabled - but failed to copy over the
3212 * old root-entry table. Try to proceed
3213 * by disabling translation now and
3214 * allocating a clean root-entry table.
3215 * This might cause DMAR faults, but
3216 * probably the dump will still succeed.
3217 */
3218 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3219 iommu->name);
3220 iommu_disable_translation(iommu);
3221 clear_translation_pre_enabled(iommu);
3222 } else {
3223 pr_info("Copied translation tables from previous kernel for %s\n",
3224 iommu->name);
3225 }
3226 }
3227
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003228 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003229 hw_pass_through = 0;
Jacob Panff3dc652020-01-02 08:18:03 +08003230 intel_svm_check(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003231 }
3232
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003233 /*
3234 * Now that qi is enabled on all iommus, set the root entry and flush
3235 * caches. This is required on some Intel X58 chipsets, otherwise the
3236 * flush_context function will loop forever and the boot hangs.
3237 */
3238 for_each_active_iommu(iommu, drhd) {
3239 iommu_flush_write_buffer(iommu);
Jacob Pan33753032020-05-16 14:20:51 +08003240#ifdef CONFIG_INTEL_IOMMU_SVM
3241 register_pasid_allocator(iommu);
3242#endif
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003243 iommu_set_root_entry(iommu);
3244 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3245 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3246 }
3247
Suresh Siddhad3f13812011-08-23 17:05:25 -07003248#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
Lu Baolu5daab582019-05-02 09:34:26 +08003249 dmar_map_gfx = 0;
David Woodhouse19943b02009-08-04 16:19:20 +01003250#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003251
Lu Baolu5daab582019-05-02 09:34:26 +08003252 if (!dmar_map_gfx)
3253 iommu_identity_mapping |= IDENTMAP_GFX;
3254
Ashok Raj21e722c2017-01-30 09:39:53 -08003255 check_tylersburg_isoch();
3256
Lu Baolu4de354e2019-05-25 13:41:27 +08003257 ret = si_domain_init(hw_pass_through);
3258 if (ret)
3259 goto free_iommu;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003260
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003261 /*
3262 * for each drhd
3263 * enable fault log
3264 * global invalidate context cache
3265 * global invalidate iotlb
3266 * enable translation
3267 */
Jiang Liu7c919772014-01-06 14:18:18 +08003268 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003269 if (drhd->ignored) {
3270 /*
3271 * we always have to disable PMRs or DMA may fail on
3272 * this device
3273 */
3274 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003275 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003276 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003277 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003278
3279 iommu_flush_write_buffer(iommu);
3280
David Woodhousea222a7f2015-10-07 23:35:18 +01003281#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003282 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
Lu Baolua7755c32019-04-19 14:43:29 +08003283 /*
3284 * Call dmar_alloc_hwirq() with dmar_global_lock held,
3285 * could cause possible lock race condition.
3286 */
3287 up_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003288 ret = intel_svm_enable_prq(iommu);
Lu Baolua7755c32019-04-19 14:43:29 +08003289 down_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003290 if (ret)
3291 goto free_iommu;
3292 }
3293#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003294 ret = dmar_set_interrupt(iommu);
3295 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003296 goto free_iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003297 }
3298
3299 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003300
3301free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003302 for_each_active_iommu(iommu, drhd) {
3303 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003304 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003305 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003306
Weidong Hand9630fe2008-12-08 11:06:32 +08003307 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003308
Jiang Liu989d51f2014-02-19 14:07:21 +08003309error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003310 return ret;
3311}
3312
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003313/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003314static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003315 struct dmar_domain *domain,
3316 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003317{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06003318 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003319
Lu Baolucb8b8922020-01-02 08:18:19 +08003320 /*
3321 * Restrict dma_mask to the width that the iommu can handle.
3322 * First-level translation restricts the input-address to a
3323 * canonical address (i.e., address bits 63:N have the same
3324 * value as address bit [N-1], where N is 48-bits with 4-level
3325 * paging and 57-bits with 5-level paging). Hence, skip bit
3326 * [N-1].
3327 */
3328 if (domain_use_first_level(domain))
3329 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw - 1),
3330 dma_mask);
3331 else
3332 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw),
3333 dma_mask);
3334
Robin Murphy8f6429c2015-07-16 19:40:12 +01003335 /* Ensure we reserve the whole size-aligned region */
3336 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003337
3338 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003339 /*
3340 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003341 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003342 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003343 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003344 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003345 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003346 if (iova_pfn)
3347 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003348 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003349 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3350 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003351 if (unlikely(!iova_pfn)) {
Qian Cai944c9172019-11-22 14:16:54 -05003352 dev_err_once(dev, "Allocating %ld-page iova failed\n",
3353 nrpages);
Omer Peleg2aac6302016-04-20 11:33:57 +03003354 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003355 }
3356
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003357 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003358}
3359
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003360static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
3361 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003362{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003363 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003364 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003365 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003366 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003367 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003368 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003369 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003370
3371 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003372
Lu Baolu6fc70202020-05-06 09:59:47 +08003373 if (unlikely(attach_deferred(dev)))
3374 do_deferred_attach(dev);
3375
Joerg Roedel96d170f2020-02-17 17:27:44 +01003376 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003377 if (!domain)
Christoph Hellwig524a6692018-11-21 19:34:10 +01003378 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003379
Weidong Han8c11e792008-12-08 15:29:22 +08003380 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003381 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003382
Omer Peleg2aac6302016-04-20 11:33:57 +03003383 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3384 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003385 goto error;
3386
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003387 /*
3388 * Check if DMAR supports zero-length reads on write only
3389 * mappings..
3390 */
3391 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003392 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003393 prot |= DMA_PTE_READ;
3394 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3395 prot |= DMA_PTE_WRITE;
3396 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003397 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003398 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003399 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003400 * is not a big problem
3401 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003402 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003403 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003404 if (ret)
3405 goto error;
3406
Omer Peleg2aac6302016-04-20 11:33:57 +03003407 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003408 start_paddr += paddr & ~PAGE_MASK;
Lu Baolu3b530342019-09-06 14:14:51 +08003409
3410 trace_map_single(dev, start_paddr, paddr, size << VTD_PAGE_SHIFT);
3411
David Woodhouse03d6a242009-06-28 15:33:46 +01003412 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003413
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003414error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003415 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003416 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003417 dev_err(dev, "Device request: %zx@%llx dir %d --- failed\n",
3418 size, (unsigned long long)paddr, dir);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003419 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003420}
3421
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003422static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3423 unsigned long offset, size_t size,
3424 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003425 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003426{
Lu Baolu6fc70202020-05-06 09:59:47 +08003427 return __intel_map_single(dev, page_to_phys(page) + offset,
3428 size, dir, *dev->dma_mask);
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003429}
3430
3431static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
3432 size_t size, enum dma_data_direction dir,
3433 unsigned long attrs)
3434{
Lu Baolu6fc70202020-05-06 09:59:47 +08003435 return __intel_map_single(dev, phys_addr, size, dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003436}
3437
Omer Peleg769530e2016-04-20 11:33:25 +03003438static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003439{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003440 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003441 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003442 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003443 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003444 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003445 struct page *freelist;
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003446 struct pci_dev *pdev = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003447
David Woodhouse1525a292014-03-06 16:19:30 +00003448 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003449 BUG_ON(!domain);
3450
Weidong Han8c11e792008-12-08 15:29:22 +08003451 iommu = domain_get_iommu(domain);
3452
Omer Peleg2aac6302016-04-20 11:33:57 +03003453 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003454
Omer Peleg769530e2016-04-20 11:33:25 +03003455 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003456 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003457 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003458
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003459 if (dev_is_pci(dev))
3460 pdev = to_pci_dev(dev);
3461
David Woodhouseea8ea462014-03-05 17:09:32 +00003462 freelist = domain_unmap(domain, start_pfn, last_pfn);
Dmitry Safonoveffa4672019-07-16 22:38:05 +01003463 if (intel_iommu_strict || (pdev && pdev->untrusted) ||
3464 !has_iova_flush_queue(&domain->iovad)) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003465 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003466 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003467 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003468 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003469 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003470 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003471 queue_iova(&domain->iovad, iova_pfn, nrpages,
3472 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003473 /*
3474 * queue up the release of the unmap to save the 1/6th of the
3475 * cpu used up by the iotlb flush operation...
3476 */
mark gross5e0d2a62008-03-04 15:22:08 -08003477 }
Lu Baolu3b530342019-09-06 14:14:51 +08003478
3479 trace_unmap_single(dev, dev_addr, size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003480}
3481
Jiang Liud41a4ad2014-07-11 14:19:34 +08003482static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3483 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003484 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003485{
Lu Baolu6fc70202020-05-06 09:59:47 +08003486 intel_unmap(dev, dev_addr, size);
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003487}
3488
3489static void intel_unmap_resource(struct device *dev, dma_addr_t dev_addr,
3490 size_t size, enum dma_data_direction dir, unsigned long attrs)
3491{
Lu Baolu6fc70202020-05-06 09:59:47 +08003492 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003493}
3494
David Woodhouse5040a912014-03-09 16:14:00 -07003495static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003496 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003497 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003498{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003499 struct page *page = NULL;
3500 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003501
Lu Baolu6fc70202020-05-06 09:59:47 +08003502 if (unlikely(attach_deferred(dev)))
3503 do_deferred_attach(dev);
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003504
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003505 size = PAGE_ALIGN(size);
3506 order = get_order(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003507
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003508 if (gfpflags_allow_blocking(flags)) {
3509 unsigned int count = size >> PAGE_SHIFT;
3510
Marek Szyprowskid834c5a2018-08-17 15:49:00 -07003511 page = dma_alloc_from_contiguous(dev, count, order,
3512 flags & __GFP_NOWARN);
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003513 }
3514
3515 if (!page)
3516 page = alloc_pages(flags, order);
3517 if (!page)
3518 return NULL;
3519 memset(page_address(page), 0, size);
3520
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003521 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3522 DMA_BIDIRECTIONAL,
3523 dev->coherent_dma_mask);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003524 if (*dma_handle != DMA_MAPPING_ERROR)
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003525 return page_address(page);
3526 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3527 __free_pages(page, order);
3528
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003529 return NULL;
3530}
3531
David Woodhouse5040a912014-03-09 16:14:00 -07003532static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003533 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003534{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003535 int order;
3536 struct page *page = virt_to_page(vaddr);
3537
3538 size = PAGE_ALIGN(size);
3539 order = get_order(size);
3540
3541 intel_unmap(dev, dma_handle, size);
3542 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3543 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003544}
3545
David Woodhouse5040a912014-03-09 16:14:00 -07003546static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003547 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003548 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003549{
Omer Peleg769530e2016-04-20 11:33:25 +03003550 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3551 unsigned long nrpages = 0;
3552 struct scatterlist *sg;
3553 int i;
3554
3555 for_each_sg(sglist, sg, nelems, i) {
3556 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3557 }
3558
3559 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Lu Baolu3b530342019-09-06 14:14:51 +08003560
3561 trace_unmap_sg(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003562}
3563
David Woodhouse5040a912014-03-09 16:14:00 -07003564static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003565 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003566{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003567 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003568 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003569 size_t size = 0;
3570 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003571 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003572 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003573 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003574 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003575 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003576
3577 BUG_ON(dir == DMA_NONE);
Lu Baolu6fc70202020-05-06 09:59:47 +08003578
3579 if (unlikely(attach_deferred(dev)))
3580 do_deferred_attach(dev);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003581
Joerg Roedel96d170f2020-02-17 17:27:44 +01003582 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003583 if (!domain)
3584 return 0;
3585
Weidong Han8c11e792008-12-08 15:29:22 +08003586 iommu = domain_get_iommu(domain);
3587
David Woodhouseb536d242009-06-28 14:49:31 +01003588 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003589 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003590
Omer Peleg2aac6302016-04-20 11:33:57 +03003591 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003592 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003593 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003594 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003595 return 0;
3596 }
3597
3598 /*
3599 * Check if DMAR supports zero-length reads on write only
3600 * mappings..
3601 */
3602 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003603 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003604 prot |= DMA_PTE_READ;
3605 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3606 prot |= DMA_PTE_WRITE;
3607
Omer Peleg2aac6302016-04-20 11:33:57 +03003608 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003609
Fenghua Yuf5329592009-08-04 15:09:37 -07003610 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003611 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003612 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003613 start_vpfn + size - 1,
3614 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003615 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003616 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003617 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003618
Lu Baolu984d03a2020-01-02 08:18:11 +08003619 for_each_sg(sglist, sg, nelems, i)
3620 trace_map_sg(dev, i + 1, nelems, sg);
Lu Baolu3b530342019-09-06 14:14:51 +08003621
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003622 return nelems;
3623}
3624
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003625static u64 intel_get_required_mask(struct device *dev)
3626{
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003627 return DMA_BIT_MASK(32);
3628}
3629
Christoph Hellwig02b4da52018-09-17 19:10:31 +02003630static const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003631 .alloc = intel_alloc_coherent,
3632 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003633 .map_sg = intel_map_sg,
3634 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003635 .map_page = intel_map_page,
3636 .unmap_page = intel_unmap_page,
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003637 .map_resource = intel_map_resource,
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003638 .unmap_resource = intel_unmap_resource,
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003639 .dma_supported = dma_direct_supported,
Christoph Hellwigf9f32322019-08-06 15:01:50 +03003640 .mmap = dma_common_mmap,
3641 .get_sgtable = dma_common_get_sgtable,
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003642 .get_required_mask = intel_get_required_mask,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003643};
3644
Lu Baolucfb94a32019-09-06 14:14:52 +08003645static void
3646bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size,
3647 enum dma_data_direction dir, enum dma_sync_target target)
3648{
3649 struct dmar_domain *domain;
3650 phys_addr_t tlb_addr;
3651
3652 domain = find_domain(dev);
3653 if (WARN_ON(!domain))
3654 return;
3655
3656 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr);
3657 if (is_swiotlb_buffer(tlb_addr))
3658 swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target);
3659}
3660
3661static dma_addr_t
3662bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
3663 enum dma_data_direction dir, unsigned long attrs,
3664 u64 dma_mask)
3665{
3666 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3667 struct dmar_domain *domain;
3668 struct intel_iommu *iommu;
3669 unsigned long iova_pfn;
3670 unsigned long nrpages;
3671 phys_addr_t tlb_addr;
3672 int prot = 0;
3673 int ret;
3674
Joerg Roedela11bfde2020-02-17 17:20:59 +01003675 if (unlikely(attach_deferred(dev)))
3676 do_deferred_attach(dev);
3677
Joerg Roedel96d170f2020-02-17 17:27:44 +01003678 domain = find_domain(dev);
Joerg Roedela11bfde2020-02-17 17:20:59 +01003679
Lu Baolucfb94a32019-09-06 14:14:52 +08003680 if (WARN_ON(dir == DMA_NONE || !domain))
3681 return DMA_MAPPING_ERROR;
3682
3683 iommu = domain_get_iommu(domain);
3684 if (WARN_ON(!iommu))
3685 return DMA_MAPPING_ERROR;
3686
3687 nrpages = aligned_nrpages(0, size);
3688 iova_pfn = intel_alloc_iova(dev, domain,
3689 dma_to_mm_pfn(nrpages), dma_mask);
3690 if (!iova_pfn)
3691 return DMA_MAPPING_ERROR;
3692
3693 /*
3694 * Check if DMAR supports zero-length reads on write only
3695 * mappings..
3696 */
3697 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ||
3698 !cap_zlr(iommu->cap))
3699 prot |= DMA_PTE_READ;
3700 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3701 prot |= DMA_PTE_WRITE;
3702
3703 /*
3704 * If both the physical buffer start address and size are
3705 * page aligned, we don't need to use a bounce page.
3706 */
3707 if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
3708 tlb_addr = swiotlb_tbl_map_single(dev,
3709 __phys_to_dma(dev, io_tlb_start),
3710 paddr, size, aligned_size, dir, attrs);
3711 if (tlb_addr == DMA_MAPPING_ERROR) {
3712 goto swiotlb_error;
3713 } else {
3714 /* Cleanup the padding area. */
3715 void *padding_start = phys_to_virt(tlb_addr);
3716 size_t padding_size = aligned_size;
3717
3718 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
3719 (dir == DMA_TO_DEVICE ||
3720 dir == DMA_BIDIRECTIONAL)) {
3721 padding_start += size;
3722 padding_size -= size;
3723 }
3724
3725 memset(padding_start, 0, padding_size);
3726 }
3727 } else {
3728 tlb_addr = paddr;
3729 }
3730
3731 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
3732 tlb_addr >> VTD_PAGE_SHIFT, nrpages, prot);
3733 if (ret)
3734 goto mapping_error;
3735
3736 trace_bounce_map_single(dev, iova_pfn << PAGE_SHIFT, paddr, size);
3737
3738 return (phys_addr_t)iova_pfn << PAGE_SHIFT;
3739
3740mapping_error:
3741 if (is_swiotlb_buffer(tlb_addr))
3742 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3743 aligned_size, dir, attrs);
3744swiotlb_error:
3745 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
3746 dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n",
3747 size, (unsigned long long)paddr, dir);
3748
3749 return DMA_MAPPING_ERROR;
3750}
3751
3752static void
3753bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
3754 enum dma_data_direction dir, unsigned long attrs)
3755{
3756 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3757 struct dmar_domain *domain;
3758 phys_addr_t tlb_addr;
3759
3760 domain = find_domain(dev);
3761 if (WARN_ON(!domain))
3762 return;
3763
3764 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, dev_addr);
3765 if (WARN_ON(!tlb_addr))
3766 return;
3767
3768 intel_unmap(dev, dev_addr, size);
3769 if (is_swiotlb_buffer(tlb_addr))
3770 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3771 aligned_size, dir, attrs);
3772
3773 trace_bounce_unmap_single(dev, dev_addr, size);
3774}
3775
3776static dma_addr_t
3777bounce_map_page(struct device *dev, struct page *page, unsigned long offset,
3778 size_t size, enum dma_data_direction dir, unsigned long attrs)
3779{
3780 return bounce_map_single(dev, page_to_phys(page) + offset,
3781 size, dir, attrs, *dev->dma_mask);
3782}
3783
3784static dma_addr_t
3785bounce_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
3786 enum dma_data_direction dir, unsigned long attrs)
3787{
3788 return bounce_map_single(dev, phys_addr, size,
3789 dir, attrs, *dev->dma_mask);
3790}
3791
3792static void
3793bounce_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size,
3794 enum dma_data_direction dir, unsigned long attrs)
3795{
3796 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3797}
3798
3799static void
3800bounce_unmap_resource(struct device *dev, dma_addr_t dev_addr, size_t size,
3801 enum dma_data_direction dir, unsigned long attrs)
3802{
3803 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3804}
3805
3806static void
3807bounce_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3808 enum dma_data_direction dir, unsigned long attrs)
3809{
3810 struct scatterlist *sg;
3811 int i;
3812
3813 for_each_sg(sglist, sg, nelems, i)
3814 bounce_unmap_page(dev, sg->dma_address,
3815 sg_dma_len(sg), dir, attrs);
3816}
3817
3818static int
3819bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3820 enum dma_data_direction dir, unsigned long attrs)
3821{
3822 int i;
3823 struct scatterlist *sg;
3824
3825 for_each_sg(sglist, sg, nelems, i) {
3826 sg->dma_address = bounce_map_page(dev, sg_page(sg),
3827 sg->offset, sg->length,
3828 dir, attrs);
3829 if (sg->dma_address == DMA_MAPPING_ERROR)
3830 goto out_unmap;
3831 sg_dma_len(sg) = sg->length;
3832 }
3833
Lu Baolu984d03a2020-01-02 08:18:11 +08003834 for_each_sg(sglist, sg, nelems, i)
3835 trace_bounce_map_sg(dev, i + 1, nelems, sg);
3836
Lu Baolucfb94a32019-09-06 14:14:52 +08003837 return nelems;
3838
3839out_unmap:
3840 bounce_unmap_sg(dev, sglist, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
3841 return 0;
3842}
3843
3844static void
3845bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
3846 size_t size, enum dma_data_direction dir)
3847{
3848 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU);
3849}
3850
3851static void
3852bounce_sync_single_for_device(struct device *dev, dma_addr_t addr,
3853 size_t size, enum dma_data_direction dir)
3854{
3855 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE);
3856}
3857
3858static void
3859bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
3860 int nelems, enum dma_data_direction dir)
3861{
3862 struct scatterlist *sg;
3863 int i;
3864
3865 for_each_sg(sglist, sg, nelems, i)
3866 bounce_sync_single(dev, sg_dma_address(sg),
3867 sg_dma_len(sg), dir, SYNC_FOR_CPU);
3868}
3869
3870static void
3871bounce_sync_sg_for_device(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_DEVICE);
3880}
3881
3882static const struct dma_map_ops bounce_dma_ops = {
3883 .alloc = intel_alloc_coherent,
3884 .free = intel_free_coherent,
3885 .map_sg = bounce_map_sg,
3886 .unmap_sg = bounce_unmap_sg,
3887 .map_page = bounce_map_page,
3888 .unmap_page = bounce_unmap_page,
3889 .sync_single_for_cpu = bounce_sync_single_for_cpu,
3890 .sync_single_for_device = bounce_sync_single_for_device,
3891 .sync_sg_for_cpu = bounce_sync_sg_for_cpu,
3892 .sync_sg_for_device = bounce_sync_sg_for_device,
3893 .map_resource = bounce_map_resource,
3894 .unmap_resource = bounce_unmap_resource,
3895 .dma_supported = dma_direct_supported,
3896};
3897
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003898static inline int iommu_domain_cache_init(void)
3899{
3900 int ret = 0;
3901
3902 iommu_domain_cache = kmem_cache_create("iommu_domain",
3903 sizeof(struct dmar_domain),
3904 0,
3905 SLAB_HWCACHE_ALIGN,
3906
3907 NULL);
3908 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003909 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003910 ret = -ENOMEM;
3911 }
3912
3913 return ret;
3914}
3915
3916static inline int iommu_devinfo_cache_init(void)
3917{
3918 int ret = 0;
3919
3920 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3921 sizeof(struct device_domain_info),
3922 0,
3923 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003924 NULL);
3925 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003926 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003927 ret = -ENOMEM;
3928 }
3929
3930 return ret;
3931}
3932
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003933static int __init iommu_init_mempool(void)
3934{
3935 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003936 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003937 if (ret)
3938 return ret;
3939
3940 ret = iommu_domain_cache_init();
3941 if (ret)
3942 goto domain_error;
3943
3944 ret = iommu_devinfo_cache_init();
3945 if (!ret)
3946 return ret;
3947
3948 kmem_cache_destroy(iommu_domain_cache);
3949domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003950 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003951
3952 return -ENOMEM;
3953}
3954
3955static void __init iommu_exit_mempool(void)
3956{
3957 kmem_cache_destroy(iommu_devinfo_cache);
3958 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003959 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003960}
3961
Dan Williams556ab452010-07-23 15:47:56 -07003962static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3963{
3964 struct dmar_drhd_unit *drhd;
3965 u32 vtbar;
3966 int rc;
3967
3968 /* We know that this device on this chipset has its own IOMMU.
3969 * If we find it under a different IOMMU, then the BIOS is lying
3970 * to us. Hope that the IOMMU for this device is actually
3971 * disabled, and it needs no translation...
3972 */
3973 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3974 if (rc) {
3975 /* "can't" happen */
3976 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3977 return;
3978 }
3979 vtbar &= 0xffff0000;
3980
3981 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3982 drhd = dmar_find_matched_drhd_unit(pdev);
Hans de Goede81ee85d2020-03-09 19:25:10 +01003983 if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
3984 pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
3985 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
Dan Williams556ab452010-07-23 15:47:56 -07003986 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Hans de Goede81ee85d2020-03-09 19:25:10 +01003987 }
Dan Williams556ab452010-07-23 15:47:56 -07003988}
3989DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3990
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003991static void __init init_no_remapping_devices(void)
3992{
3993 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003994 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003995 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003996
3997 for_each_drhd_unit(drhd) {
3998 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003999 for_each_active_dev_scope(drhd->devices,
4000 drhd->devices_cnt, i, dev)
4001 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004002 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004003 if (i == drhd->devices_cnt)
4004 drhd->ignored = 1;
4005 }
4006 }
4007
Jiang Liu7c919772014-01-06 14:18:18 +08004008 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004009 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004010 continue;
4011
Jiang Liub683b232014-02-19 14:07:32 +08004012 for_each_active_dev_scope(drhd->devices,
4013 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004014 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004015 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004016 if (i < drhd->devices_cnt)
4017 continue;
4018
David Woodhousec0771df2011-10-14 20:59:46 +01004019 /* This IOMMU has *only* gfx devices. Either bypass it or
4020 set the gfx_mapped flag, as appropriate */
Lu Baolucf1ec452019-05-02 09:34:25 +08004021 if (!dmar_map_gfx) {
David Woodhousec0771df2011-10-14 20:59:46 +01004022 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004023 for_each_active_dev_scope(drhd->devices,
4024 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004025 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004026 }
4027 }
4028}
4029
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004030#ifdef CONFIG_SUSPEND
4031static int init_iommu_hw(void)
4032{
4033 struct dmar_drhd_unit *drhd;
4034 struct intel_iommu *iommu = NULL;
4035
4036 for_each_active_iommu(iommu, drhd)
4037 if (iommu->qi)
4038 dmar_reenable_qi(iommu);
4039
Joseph Cihulab7792602011-05-03 00:08:37 -07004040 for_each_iommu(iommu, drhd) {
4041 if (drhd->ignored) {
4042 /*
4043 * we always have to disable PMRs or DMA may fail on
4044 * this device
4045 */
4046 if (force_on)
4047 iommu_disable_protect_mem_regions(iommu);
4048 continue;
4049 }
Lu Baolu095303e2019-04-29 09:16:02 +08004050
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004051 iommu_flush_write_buffer(iommu);
4052
4053 iommu_set_root_entry(iommu);
4054
4055 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004056 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004057 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4058 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004059 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004060 }
4061
4062 return 0;
4063}
4064
4065static void iommu_flush_all(void)
4066{
4067 struct dmar_drhd_unit *drhd;
4068 struct intel_iommu *iommu;
4069
4070 for_each_active_iommu(iommu, drhd) {
4071 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004072 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004073 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004074 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004075 }
4076}
4077
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004078static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004079{
4080 struct dmar_drhd_unit *drhd;
4081 struct intel_iommu *iommu = NULL;
4082 unsigned long flag;
4083
4084 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004085 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004086 GFP_ATOMIC);
4087 if (!iommu->iommu_state)
4088 goto nomem;
4089 }
4090
4091 iommu_flush_all();
4092
4093 for_each_active_iommu(iommu, drhd) {
4094 iommu_disable_translation(iommu);
4095
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004096 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004097
4098 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4099 readl(iommu->reg + DMAR_FECTL_REG);
4100 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4101 readl(iommu->reg + DMAR_FEDATA_REG);
4102 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4103 readl(iommu->reg + DMAR_FEADDR_REG);
4104 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4105 readl(iommu->reg + DMAR_FEUADDR_REG);
4106
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004107 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004108 }
4109 return 0;
4110
4111nomem:
4112 for_each_active_iommu(iommu, drhd)
4113 kfree(iommu->iommu_state);
4114
4115 return -ENOMEM;
4116}
4117
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004118static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004119{
4120 struct dmar_drhd_unit *drhd;
4121 struct intel_iommu *iommu = NULL;
4122 unsigned long flag;
4123
4124 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004125 if (force_on)
4126 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4127 else
4128 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004129 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004130 }
4131
4132 for_each_active_iommu(iommu, drhd) {
4133
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004134 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004135
4136 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4137 iommu->reg + DMAR_FECTL_REG);
4138 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4139 iommu->reg + DMAR_FEDATA_REG);
4140 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4141 iommu->reg + DMAR_FEADDR_REG);
4142 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4143 iommu->reg + DMAR_FEUADDR_REG);
4144
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004145 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004146 }
4147
4148 for_each_active_iommu(iommu, drhd)
4149 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004150}
4151
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004152static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004153 .resume = iommu_resume,
4154 .suspend = iommu_suspend,
4155};
4156
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004157static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004158{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004159 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004160}
4161
4162#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004163static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004164#endif /* CONFIG_PM */
4165
Barret Rhodence4cc52b2020-01-15 11:03:57 +08004166static int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
4167{
4168 if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) ||
4169 !IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) ||
4170 rmrr->end_address <= rmrr->base_address ||
4171 arch_rmrr_sanity_check(rmrr))
4172 return -EINVAL;
4173
4174 return 0;
4175}
4176
Jiang Liuc2a0b532014-11-09 22:47:56 +08004177int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004178{
4179 struct acpi_dmar_reserved_memory *rmrr;
4180 struct dmar_rmrr_unit *rmrru;
Yian Chenf036c7f2019-10-17 04:39:19 -07004181
4182 rmrr = (struct acpi_dmar_reserved_memory *)header;
Hans de Goede96788c72020-03-09 15:01:38 +01004183 if (rmrr_sanity_check(rmrr)) {
4184 pr_warn(FW_BUG
Barret Rhodenf5a68bb2020-01-15 11:03:56 +08004185 "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
4186 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
4187 rmrr->base_address, rmrr->end_address,
4188 dmi_get_system_info(DMI_BIOS_VENDOR),
4189 dmi_get_system_info(DMI_BIOS_VERSION),
4190 dmi_get_system_info(DMI_PRODUCT_VERSION));
Hans de Goede96788c72020-03-09 15:01:38 +01004191 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
4192 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004193
4194 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4195 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004196 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004197
4198 rmrru->hdr = header;
Yian Chenf036c7f2019-10-17 04:39:19 -07004199
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004200 rmrru->base_address = rmrr->base_address;
4201 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004202
Jiang Liu2e455282014-02-19 14:07:36 +08004203 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4204 ((void *)rmrr) + rmrr->header.length,
4205 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004206 if (rmrru->devices_cnt && rmrru->devices == NULL)
Eric Auger5f64ce52019-06-03 08:53:31 +02004207 goto free_rmrru;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004208
Jiang Liu2e455282014-02-19 14:07:36 +08004209 list_add(&rmrru->list, &dmar_rmrr_units);
4210
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004211 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004212free_rmrru:
4213 kfree(rmrru);
4214out:
4215 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004216}
4217
Jiang Liu6b197242014-11-09 22:47:58 +08004218static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4219{
4220 struct dmar_atsr_unit *atsru;
4221 struct acpi_dmar_atsr *tmp;
4222
Qian Caic6f4ebd2020-03-17 11:03:26 -04004223 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list,
4224 dmar_rcu_check()) {
Jiang Liu6b197242014-11-09 22:47:58 +08004225 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4226 if (atsr->segment != tmp->segment)
4227 continue;
4228 if (atsr->header.length != tmp->header.length)
4229 continue;
4230 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4231 return atsru;
4232 }
4233
4234 return NULL;
4235}
4236
4237int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004238{
4239 struct acpi_dmar_atsr *atsr;
4240 struct dmar_atsr_unit *atsru;
4241
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004242 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004243 return 0;
4244
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004245 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004246 atsru = dmar_find_atsr(atsr);
4247 if (atsru)
4248 return 0;
4249
4250 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004251 if (!atsru)
4252 return -ENOMEM;
4253
Jiang Liu6b197242014-11-09 22:47:58 +08004254 /*
4255 * If memory is allocated from slab by ACPI _DSM method, we need to
4256 * copy the memory content because the memory buffer will be freed
4257 * on return.
4258 */
4259 atsru->hdr = (void *)(atsru + 1);
4260 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004261 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004262 if (!atsru->include_all) {
4263 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4264 (void *)atsr + atsr->header.length,
4265 &atsru->devices_cnt);
4266 if (atsru->devices_cnt && atsru->devices == NULL) {
4267 kfree(atsru);
4268 return -ENOMEM;
4269 }
4270 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004271
Jiang Liu0e242612014-02-19 14:07:34 +08004272 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004273
4274 return 0;
4275}
4276
Jiang Liu9bdc5312014-01-06 14:18:27 +08004277static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4278{
4279 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4280 kfree(atsru);
4281}
4282
Jiang Liu6b197242014-11-09 22:47:58 +08004283int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4284{
4285 struct acpi_dmar_atsr *atsr;
4286 struct dmar_atsr_unit *atsru;
4287
4288 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4289 atsru = dmar_find_atsr(atsr);
4290 if (atsru) {
4291 list_del_rcu(&atsru->list);
4292 synchronize_rcu();
4293 intel_iommu_free_atsr(atsru);
4294 }
4295
4296 return 0;
4297}
4298
4299int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4300{
4301 int i;
4302 struct device *dev;
4303 struct acpi_dmar_atsr *atsr;
4304 struct dmar_atsr_unit *atsru;
4305
4306 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4307 atsru = dmar_find_atsr(atsr);
4308 if (!atsru)
4309 return 0;
4310
Linus Torvalds194dc872016-07-27 20:03:31 -07004311 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004312 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4313 i, dev)
4314 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004315 }
Jiang Liu6b197242014-11-09 22:47:58 +08004316
4317 return 0;
4318}
4319
Jiang Liuffebeb42014-11-09 22:48:02 +08004320static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4321{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004322 int sp, ret;
Jiang Liuffebeb42014-11-09 22:48:02 +08004323 struct intel_iommu *iommu = dmaru->iommu;
4324
4325 if (g_iommus[iommu->seq_id])
4326 return 0;
4327
4328 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004329 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004330 iommu->name);
4331 return -ENXIO;
4332 }
4333 if (!ecap_sc_support(iommu->ecap) &&
4334 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004335 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004336 iommu->name);
4337 return -ENXIO;
4338 }
Lu Baolu64229e82020-01-02 08:18:20 +08004339 sp = domain_update_iommu_superpage(NULL, iommu) - 1;
Jiang Liuffebeb42014-11-09 22:48:02 +08004340 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004341 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004342 iommu->name);
4343 return -ENXIO;
4344 }
4345
4346 /*
4347 * Disable translation if already enabled prior to OS handover.
4348 */
4349 if (iommu->gcmd & DMA_GCMD_TE)
4350 iommu_disable_translation(iommu);
4351
4352 g_iommus[iommu->seq_id] = iommu;
4353 ret = iommu_init_domains(iommu);
4354 if (ret == 0)
4355 ret = iommu_alloc_root_entry(iommu);
4356 if (ret)
4357 goto out;
4358
Jacob Panff3dc652020-01-02 08:18:03 +08004359 intel_svm_check(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00004360
Jiang Liuffebeb42014-11-09 22:48:02 +08004361 if (dmaru->ignored) {
4362 /*
4363 * we always have to disable PMRs or DMA may fail on this device
4364 */
4365 if (force_on)
4366 iommu_disable_protect_mem_regions(iommu);
4367 return 0;
4368 }
4369
4370 intel_iommu_init_qi(iommu);
4371 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004372
4373#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004374 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01004375 ret = intel_svm_enable_prq(iommu);
4376 if (ret)
4377 goto disable_iommu;
4378 }
4379#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004380 ret = dmar_set_interrupt(iommu);
4381 if (ret)
4382 goto disable_iommu;
4383
4384 iommu_set_root_entry(iommu);
4385 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4386 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4387 iommu_enable_translation(iommu);
4388
Jiang Liuffebeb42014-11-09 22:48:02 +08004389 iommu_disable_protect_mem_regions(iommu);
4390 return 0;
4391
4392disable_iommu:
4393 disable_dmar_iommu(iommu);
4394out:
4395 free_dmar_iommu(iommu);
4396 return ret;
4397}
4398
Jiang Liu6b197242014-11-09 22:47:58 +08004399int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4400{
Jiang Liuffebeb42014-11-09 22:48:02 +08004401 int ret = 0;
4402 struct intel_iommu *iommu = dmaru->iommu;
4403
4404 if (!intel_iommu_enabled)
4405 return 0;
4406 if (iommu == NULL)
4407 return -EINVAL;
4408
4409 if (insert) {
4410 ret = intel_iommu_add(dmaru);
4411 } else {
4412 disable_dmar_iommu(iommu);
4413 free_dmar_iommu(iommu);
4414 }
4415
4416 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004417}
4418
Jiang Liu9bdc5312014-01-06 14:18:27 +08004419static void intel_iommu_free_dmars(void)
4420{
4421 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4422 struct dmar_atsr_unit *atsru, *atsr_n;
4423
4424 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4425 list_del(&rmrru->list);
4426 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
4427 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004428 }
4429
Jiang Liu9bdc5312014-01-06 14:18:27 +08004430 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4431 list_del(&atsru->list);
4432 intel_iommu_free_atsr(atsru);
4433 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004434}
4435
4436int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4437{
Jiang Liub683b232014-02-19 14:07:32 +08004438 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004439 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004440 struct pci_dev *bridge = NULL;
4441 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004442 struct acpi_dmar_atsr *atsr;
4443 struct dmar_atsr_unit *atsru;
4444
4445 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004446 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004447 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004448 /* If it's an integrated device, allow ATS */
4449 if (!bridge)
4450 return 1;
4451 /* Connected via non-PCIe: no ATS */
4452 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004453 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004454 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004455 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004456 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004457 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004458 }
4459
Jiang Liu0e242612014-02-19 14:07:34 +08004460 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004461 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4462 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4463 if (atsr->segment != pci_domain_nr(dev->bus))
4464 continue;
4465
Jiang Liub683b232014-02-19 14:07:32 +08004466 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004467 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004468 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004469
4470 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004471 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004472 }
Jiang Liub683b232014-02-19 14:07:32 +08004473 ret = 0;
4474out:
Jiang Liu0e242612014-02-19 14:07:34 +08004475 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004476
Jiang Liub683b232014-02-19 14:07:32 +08004477 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004478}
4479
Jiang Liu59ce0512014-02-19 14:07:35 +08004480int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4481{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004482 int ret;
Jiang Liu59ce0512014-02-19 14:07:35 +08004483 struct dmar_rmrr_unit *rmrru;
4484 struct dmar_atsr_unit *atsru;
4485 struct acpi_dmar_atsr *atsr;
4486 struct acpi_dmar_reserved_memory *rmrr;
4487
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004488 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004489 return 0;
4490
4491 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4492 rmrr = container_of(rmrru->hdr,
4493 struct acpi_dmar_reserved_memory, header);
4494 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4495 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4496 ((void *)rmrr) + rmrr->header.length,
4497 rmrr->segment, rmrru->devices,
4498 rmrru->devices_cnt);
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004499 if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004500 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004501 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004502 dmar_remove_dev_scope(info, rmrr->segment,
4503 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004504 }
4505 }
4506
4507 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4508 if (atsru->include_all)
4509 continue;
4510
4511 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4512 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4513 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4514 (void *)atsr + atsr->header.length,
4515 atsr->segment, atsru->devices,
4516 atsru->devices_cnt);
4517 if (ret > 0)
4518 break;
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004519 else if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004520 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004521 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004522 if (dmar_remove_dev_scope(info, atsr->segment,
4523 atsru->devices, atsru->devices_cnt))
4524 break;
4525 }
4526 }
4527
4528 return 0;
4529}
4530
Jiang Liu75f05562014-02-19 14:07:37 +08004531static int intel_iommu_memory_notifier(struct notifier_block *nb,
4532 unsigned long val, void *v)
4533{
4534 struct memory_notify *mhp = v;
4535 unsigned long long start, end;
4536 unsigned long start_vpfn, last_vpfn;
4537
4538 switch (val) {
4539 case MEM_GOING_ONLINE:
4540 start = mhp->start_pfn << PAGE_SHIFT;
4541 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4542 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004543 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004544 start, end);
4545 return NOTIFY_BAD;
4546 }
4547 break;
4548
4549 case MEM_OFFLINE:
4550 case MEM_CANCEL_ONLINE:
4551 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4552 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4553 while (start_vpfn <= last_vpfn) {
4554 struct iova *iova;
4555 struct dmar_drhd_unit *drhd;
4556 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004557 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004558
4559 iova = find_iova(&si_domain->iovad, start_vpfn);
4560 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004561 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004562 start_vpfn);
4563 break;
4564 }
4565
4566 iova = split_and_remove_iova(&si_domain->iovad, iova,
4567 start_vpfn, last_vpfn);
4568 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004569 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004570 start_vpfn, last_vpfn);
4571 return NOTIFY_BAD;
4572 }
4573
David Woodhouseea8ea462014-03-05 17:09:32 +00004574 freelist = domain_unmap(si_domain, iova->pfn_lo,
4575 iova->pfn_hi);
4576
Jiang Liu75f05562014-02-19 14:07:37 +08004577 rcu_read_lock();
4578 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004579 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004580 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004581 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004582 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004583 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004584
4585 start_vpfn = iova->pfn_hi + 1;
4586 free_iova_mem(iova);
4587 }
4588 break;
4589 }
4590
4591 return NOTIFY_OK;
4592}
4593
4594static struct notifier_block intel_iommu_memory_nb = {
4595 .notifier_call = intel_iommu_memory_notifier,
4596 .priority = 0
4597};
4598
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004599static void free_all_cpu_cached_iovas(unsigned int cpu)
4600{
4601 int i;
4602
4603 for (i = 0; i < g_num_of_iommus; i++) {
4604 struct intel_iommu *iommu = g_iommus[i];
4605 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004606 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004607
4608 if (!iommu)
4609 continue;
4610
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004611 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004612 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004613
4614 if (!domain)
4615 continue;
4616 free_cpu_cached_iovas(cpu, &domain->iovad);
4617 }
4618 }
4619}
4620
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004621static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004622{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004623 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004624 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004625}
4626
Joerg Roedel161b28a2017-03-28 17:04:52 +02004627static void intel_disable_iommus(void)
4628{
4629 struct intel_iommu *iommu = NULL;
4630 struct dmar_drhd_unit *drhd;
4631
4632 for_each_iommu(iommu, drhd)
4633 iommu_disable_translation(iommu);
4634}
4635
Deepa Dinamani6c3a44e2019-11-10 09:27:44 -08004636void intel_iommu_shutdown(void)
4637{
4638 struct dmar_drhd_unit *drhd;
4639 struct intel_iommu *iommu = NULL;
4640
4641 if (no_iommu || dmar_disabled)
4642 return;
4643
4644 down_write(&dmar_global_lock);
4645
4646 /* Disable PMRs explicitly here. */
4647 for_each_iommu(iommu, drhd)
4648 iommu_disable_protect_mem_regions(iommu);
4649
4650 /* Make sure the IOMMUs are switched off */
4651 intel_disable_iommus();
4652
4653 up_write(&dmar_global_lock);
4654}
4655
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004656static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4657{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004658 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4659
4660 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004661}
4662
Alex Williamsona5459cf2014-06-12 16:12:31 -06004663static ssize_t intel_iommu_show_version(struct device *dev,
4664 struct device_attribute *attr,
4665 char *buf)
4666{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004667 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004668 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4669 return sprintf(buf, "%d:%d\n",
4670 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4671}
4672static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4673
4674static ssize_t intel_iommu_show_address(struct device *dev,
4675 struct device_attribute *attr,
4676 char *buf)
4677{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004678 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004679 return sprintf(buf, "%llx\n", iommu->reg_phys);
4680}
4681static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4682
4683static ssize_t intel_iommu_show_cap(struct device *dev,
4684 struct device_attribute *attr,
4685 char *buf)
4686{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004687 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004688 return sprintf(buf, "%llx\n", iommu->cap);
4689}
4690static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4691
4692static ssize_t intel_iommu_show_ecap(struct device *dev,
4693 struct device_attribute *attr,
4694 char *buf)
4695{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004696 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004697 return sprintf(buf, "%llx\n", iommu->ecap);
4698}
4699static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4700
Alex Williamson2238c082015-07-14 15:24:53 -06004701static ssize_t intel_iommu_show_ndoms(struct device *dev,
4702 struct device_attribute *attr,
4703 char *buf)
4704{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004705 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004706 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4707}
4708static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4709
4710static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4711 struct device_attribute *attr,
4712 char *buf)
4713{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004714 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004715 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4716 cap_ndoms(iommu->cap)));
4717}
4718static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4719
Alex Williamsona5459cf2014-06-12 16:12:31 -06004720static struct attribute *intel_iommu_attrs[] = {
4721 &dev_attr_version.attr,
4722 &dev_attr_address.attr,
4723 &dev_attr_cap.attr,
4724 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004725 &dev_attr_domains_supported.attr,
4726 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004727 NULL,
4728};
4729
4730static struct attribute_group intel_iommu_group = {
4731 .name = "intel-iommu",
4732 .attrs = intel_iommu_attrs,
4733};
4734
4735const struct attribute_group *intel_iommu_groups[] = {
4736 &intel_iommu_group,
4737 NULL,
4738};
4739
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004740static inline bool has_untrusted_dev(void)
Lu Baolu89a60792018-10-23 15:45:01 +08004741{
4742 struct pci_dev *pdev = NULL;
Lu Baolu89a60792018-10-23 15:45:01 +08004743
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004744 for_each_pci_dev(pdev)
4745 if (pdev->untrusted)
4746 return true;
Lu Baolu89a60792018-10-23 15:45:01 +08004747
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004748 return false;
4749}
Lu Baolu89a60792018-10-23 15:45:01 +08004750
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004751static int __init platform_optin_force_iommu(void)
4752{
4753 if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
Lu Baolu89a60792018-10-23 15:45:01 +08004754 return 0;
4755
4756 if (no_iommu || dmar_disabled)
4757 pr_info("Intel-IOMMU force enabled due to platform opt in\n");
4758
4759 /*
4760 * If Intel-IOMMU is disabled by default, we will apply identity
4761 * map for all devices except those marked as being untrusted.
4762 */
4763 if (dmar_disabled)
Lu Baolub89b6602020-01-15 11:03:59 +08004764 iommu_set_default_passthrough(false);
Lu Baolu89a60792018-10-23 15:45:01 +08004765
4766 dmar_disabled = 0;
Lu Baolu89a60792018-10-23 15:45:01 +08004767 no_iommu = 0;
4768
4769 return 1;
4770}
4771
Lu Baolufa212a92019-05-25 13:41:31 +08004772static int __init probe_acpi_namespace_devices(void)
4773{
4774 struct dmar_drhd_unit *drhd;
Qian Caiaf88ec32019-06-03 10:05:19 -04004775 /* To avoid a -Wunused-but-set-variable warning. */
4776 struct intel_iommu *iommu __maybe_unused;
Lu Baolufa212a92019-05-25 13:41:31 +08004777 struct device *dev;
4778 int i, ret = 0;
4779
4780 for_each_active_iommu(iommu, drhd) {
4781 for_each_active_dev_scope(drhd->devices,
4782 drhd->devices_cnt, i, dev) {
4783 struct acpi_device_physical_node *pn;
4784 struct iommu_group *group;
4785 struct acpi_device *adev;
4786
4787 if (dev->bus != &acpi_bus_type)
4788 continue;
4789
4790 adev = to_acpi_device(dev);
4791 mutex_lock(&adev->physical_node_lock);
4792 list_for_each_entry(pn,
4793 &adev->physical_node_list, node) {
4794 group = iommu_group_get(pn->dev);
4795 if (group) {
4796 iommu_group_put(group);
4797 continue;
4798 }
4799
4800 pn->dev->bus->iommu_ops = &intel_iommu_ops;
4801 ret = iommu_probe_device(pn->dev);
4802 if (ret)
4803 break;
4804 }
4805 mutex_unlock(&adev->physical_node_lock);
4806
4807 if (ret)
4808 return ret;
4809 }
4810 }
4811
4812 return 0;
4813}
4814
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004815int __init intel_iommu_init(void)
4816{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004817 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004818 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004819 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004820
Lu Baolu89a60792018-10-23 15:45:01 +08004821 /*
4822 * Intel IOMMU is required for a TXT/tboot launch or platform
4823 * opt in, so enforce that.
4824 */
4825 force_on = tboot_force_iommu() || platform_optin_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004826
Jiang Liu3a5670e2014-02-19 14:07:33 +08004827 if (iommu_init_mempool()) {
4828 if (force_on)
4829 panic("tboot: Failed to initialize iommu memory\n");
4830 return -ENOMEM;
4831 }
4832
4833 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004834 if (dmar_table_init()) {
4835 if (force_on)
4836 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004837 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004838 }
4839
Suresh Siddhac2c72862011-08-23 17:05:19 -07004840 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004841 if (force_on)
4842 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004843 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004844 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004845
Joerg Roedelec154bf2017-10-06 15:00:53 +02004846 up_write(&dmar_global_lock);
4847
4848 /*
4849 * The bus notifier takes the dmar_global_lock, so lockdep will
4850 * complain later when we register it under the lock.
4851 */
4852 dmar_register_bus_notifier();
4853
4854 down_write(&dmar_global_lock);
4855
Megha Dey1da83472020-03-14 11:39:59 +08004856 if (!no_iommu)
4857 intel_iommu_debugfs_init();
4858
Joerg Roedel161b28a2017-03-28 17:04:52 +02004859 if (no_iommu || dmar_disabled) {
4860 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004861 * We exit the function here to ensure IOMMU's remapping and
4862 * mempool aren't setup, which means that the IOMMU's PMRs
4863 * won't be disabled via the call to init_dmars(). So disable
4864 * it explicitly here. The PMRs were setup by tboot prior to
4865 * calling SENTER, but the kernel is expected to reset/tear
4866 * down the PMRs.
4867 */
4868 if (intel_iommu_tboot_noforce) {
4869 for_each_iommu(iommu, drhd)
4870 iommu_disable_protect_mem_regions(iommu);
4871 }
4872
4873 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004874 * Make sure the IOMMUs are switched off, even when we
4875 * boot into a kexec kernel and the previous kernel left
4876 * them enabled
4877 */
4878 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004879 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004880 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004881
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004882 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004883 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004884
4885 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004886 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004887
Joseph Cihula51a63e62011-03-21 11:04:24 -07004888 if (dmar_init_reserved_ranges()) {
4889 if (force_on)
4890 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004891 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004892 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004893
Lu Baolucf1ec452019-05-02 09:34:25 +08004894 if (dmar_map_gfx)
4895 intel_iommu_gfx_mapped = 1;
4896
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004897 init_no_remapping_devices();
4898
Joseph Cihulab7792602011-05-03 00:08:37 -07004899 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004900 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004901 if (force_on)
4902 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004903 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004904 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004905 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004906 up_write(&dmar_global_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004907
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004908 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004909
Qian Cai2d48ea02020-03-05 15:00:46 -05004910 down_read(&dmar_global_lock);
Joerg Roedel39ab9552017-02-01 16:56:46 +01004911 for_each_active_iommu(iommu, drhd) {
4912 iommu_device_sysfs_add(&iommu->iommu, NULL,
4913 intel_iommu_groups,
4914 "%s", iommu->name);
4915 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4916 iommu_device_register(&iommu->iommu);
4917 }
Qian Cai2d48ea02020-03-05 15:00:46 -05004918 up_read(&dmar_global_lock);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004919
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004920 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Jiang Liu75f05562014-02-19 14:07:37 +08004921 if (si_domain && !hw_pass_through)
4922 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004923 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4924 intel_iommu_cpu_dead);
Lu Baolud8190dc2019-05-25 13:41:25 +08004925
Lu Baolud5692d42019-06-12 08:28:49 +08004926 down_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08004927 if (probe_acpi_namespace_devices())
4928 pr_warn("ACPI name space devices didn't probe correctly\n");
4929
Lu Baolud8190dc2019-05-25 13:41:25 +08004930 /* Finally, we enable the DMA remapping hardware. */
4931 for_each_iommu(iommu, drhd) {
Lu Baolu6a8c6742019-06-12 08:28:47 +08004932 if (!drhd->ignored && !translation_pre_enabled(iommu))
Lu Baolud8190dc2019-05-25 13:41:25 +08004933 iommu_enable_translation(iommu);
4934
4935 iommu_disable_protect_mem_regions(iommu);
4936 }
Qian Cai2d48ea02020-03-05 15:00:46 -05004937 up_read(&dmar_global_lock);
4938
Lu Baolud8190dc2019-05-25 13:41:25 +08004939 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
4940
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004941 intel_iommu_enabled = 1;
4942
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004943 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004944
4945out_free_reserved_range:
4946 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004947out_free_dmar:
4948 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004949 up_write(&dmar_global_lock);
4950 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004951 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004952}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004953
Lu Baolu0ce4a852019-08-26 16:50:56 +08004954static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
4955{
4956 struct intel_iommu *iommu = opaque;
4957
4958 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
4959 return 0;
4960}
4961
4962/*
4963 * NB - intel-iommu lacks any sort of reference counting for the users of
4964 * dependent devices. If multiple endpoints have intersecting dependent
4965 * devices, unbinding the driver from any one of them will possibly leave
4966 * the others unable to operate.
4967 */
4968static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
4969{
4970 if (!iommu || !dev || !dev_is_pci(dev))
4971 return;
4972
4973 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
4974}
4975
Joerg Roedel127c7612015-07-23 17:44:46 +02004976static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004977{
Lu Baolu942067f2019-05-25 13:41:29 +08004978 struct dmar_domain *domain;
Weidong Hanc7151a82008-12-08 22:51:37 +08004979 struct intel_iommu *iommu;
4980 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004981
Joerg Roedel55d94042015-07-22 16:50:40 +02004982 assert_spin_locked(&device_domain_lock);
4983
Joerg Roedelb608ac32015-07-21 18:19:08 +02004984 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004985 return;
4986
Joerg Roedel127c7612015-07-23 17:44:46 +02004987 iommu = info->iommu;
Lu Baolu942067f2019-05-25 13:41:29 +08004988 domain = info->domain;
Joerg Roedel127c7612015-07-23 17:44:46 +02004989
4990 if (info->dev) {
Lu Baoluef848b72018-12-10 09:59:01 +08004991 if (dev_is_pci(info->dev) && sm_supported(iommu))
4992 intel_pasid_tear_down_entry(iommu, info->dev,
4993 PASID_RID2PASID);
4994
Joerg Roedel127c7612015-07-23 17:44:46 +02004995 iommu_disable_dev_iotlb(info);
Lu Baolu0ce4a852019-08-26 16:50:56 +08004996 domain_context_clear(iommu, info->dev);
Lu Baolua7fc93f2018-07-14 15:47:00 +08004997 intel_pasid_free_table(info->dev);
Joerg Roedel127c7612015-07-23 17:44:46 +02004998 }
4999
Joerg Roedelb608ac32015-07-21 18:19:08 +02005000 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07005001
Joerg Roedeld160aca2015-07-22 11:52:53 +02005002 spin_lock_irqsave(&iommu->lock, flags);
Lu Baolu942067f2019-05-25 13:41:29 +08005003 domain_detach_iommu(domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02005004 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005005
5006 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08005007}
5008
Bjorn Helgaas71753232019-02-08 16:06:15 -06005009static void dmar_remove_one_dev_info(struct device *dev)
Joerg Roedel55d94042015-07-22 16:50:40 +02005010{
Joerg Roedel127c7612015-07-23 17:44:46 +02005011 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02005012 unsigned long flags;
5013
Weidong Hanc7151a82008-12-08 22:51:37 +08005014 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005015 info = dev->archdata.iommu;
Jerry Snitselaarbf708cf2020-01-21 17:34:26 -07005016 if (info && info != DEFER_DEVICE_DOMAIN_INFO
5017 && info != DUMMY_DEVICE_DOMAIN_INFO)
Lu Baoluae23bfb62019-08-06 08:14:08 +08005018 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005019 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005020}
5021
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005022static int md_domain_init(struct dmar_domain *domain, int guest_width)
5023{
5024 int adjust_width;
5025
5026 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
5027 domain_reserve_special_ranges(domain);
5028
5029 /* calculate AGAW */
5030 domain->gaw = guest_width;
5031 adjust_width = guestwidth_to_adjustwidth(guest_width);
5032 domain->agaw = width_to_agaw(adjust_width);
5033
5034 domain->iommu_coherency = 0;
5035 domain->iommu_snooping = 0;
5036 domain->iommu_superpage = 0;
5037 domain->max_addr = 0;
5038
5039 /* always allocate the top pgd */
5040 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
5041 if (!domain->pgd)
5042 return -ENOMEM;
5043 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5044 return 0;
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;
Lu Baolu10f80082020-01-02 08:18:12 +08005051 int ret;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005052
Lu Baolu4de354e2019-05-25 13:41:27 +08005053 switch (type) {
Lu Baolufa954e62019-05-25 13:41:28 +08005054 case IOMMU_DOMAIN_DMA:
5055 /* fallthrough */
Lu Baolu4de354e2019-05-25 13:41:27 +08005056 case IOMMU_DOMAIN_UNMANAGED:
Lu Baolufa954e62019-05-25 13:41:28 +08005057 dmar_domain = alloc_domain(0);
Lu Baolu4de354e2019-05-25 13:41:27 +08005058 if (!dmar_domain) {
5059 pr_err("Can't allocate dmar_domain\n");
5060 return NULL;
5061 }
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005062 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Lu Baolu4de354e2019-05-25 13:41:27 +08005063 pr_err("Domain initialization failed\n");
5064 domain_exit(dmar_domain);
5065 return NULL;
5066 }
Lu Baolufa954e62019-05-25 13:41:28 +08005067
Lu Baolu10f80082020-01-02 08:18:12 +08005068 if (!intel_iommu_strict && type == IOMMU_DOMAIN_DMA) {
5069 ret = init_iova_flush_queue(&dmar_domain->iovad,
5070 iommu_flush_iova,
5071 iova_entry_free);
Lu Baolu8e3391c2020-01-02 08:18:13 +08005072 if (ret)
5073 pr_info("iova flush queue initialization failed\n");
Lu Baolufa954e62019-05-25 13:41:28 +08005074 }
5075
Lu Baolu4de354e2019-05-25 13:41:27 +08005076 domain_update_iommu_cap(dmar_domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005077
Lu Baolu4de354e2019-05-25 13:41:27 +08005078 domain = &dmar_domain->domain;
5079 domain->geometry.aperture_start = 0;
5080 domain->geometry.aperture_end =
5081 __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5082 domain->geometry.force_aperture = true;
5083
5084 return domain;
5085 case IOMMU_DOMAIN_IDENTITY:
5086 return &si_domain->domain;
5087 default:
Joerg Roedel00a77de2015-03-26 13:43:08 +01005088 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005089 }
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005090
Lu Baolu4de354e2019-05-25 13:41:27 +08005091 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005092}
Kay, Allen M38717942008-09-09 18:37:29 +03005093
Joerg Roedel00a77de2015-03-26 13:43:08 +01005094static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005095{
Lu Baolu4de354e2019-05-25 13:41:27 +08005096 if (domain != &si_domain->domain)
5097 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005098}
Kay, Allen M38717942008-09-09 18:37:29 +03005099
Lu Baolu67b8e022019-03-25 09:30:32 +08005100/*
5101 * Check whether a @domain could be attached to the @dev through the
5102 * aux-domain attach/detach APIs.
5103 */
5104static inline bool
5105is_aux_domain(struct device *dev, struct iommu_domain *domain)
5106{
5107 struct device_domain_info *info = dev->archdata.iommu;
5108
5109 return info && info->auxd_enabled &&
5110 domain->type == IOMMU_DOMAIN_UNMANAGED;
5111}
5112
5113static void auxiliary_link_device(struct dmar_domain *domain,
5114 struct device *dev)
5115{
5116 struct device_domain_info *info = dev->archdata.iommu;
5117
5118 assert_spin_locked(&device_domain_lock);
5119 if (WARN_ON(!info))
5120 return;
5121
5122 domain->auxd_refcnt++;
5123 list_add(&domain->auxd, &info->auxiliary_domains);
5124}
5125
5126static void auxiliary_unlink_device(struct dmar_domain *domain,
5127 struct device *dev)
5128{
5129 struct device_domain_info *info = dev->archdata.iommu;
5130
5131 assert_spin_locked(&device_domain_lock);
5132 if (WARN_ON(!info))
5133 return;
5134
5135 list_del(&domain->auxd);
5136 domain->auxd_refcnt--;
5137
5138 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005139 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005140}
5141
5142static int aux_domain_add_dev(struct dmar_domain *domain,
5143 struct device *dev)
5144{
5145 int ret;
5146 u8 bus, devfn;
5147 unsigned long flags;
5148 struct intel_iommu *iommu;
5149
5150 iommu = device_to_iommu(dev, &bus, &devfn);
5151 if (!iommu)
5152 return -ENODEV;
5153
5154 if (domain->default_pasid <= 0) {
5155 int pasid;
5156
Jacob Pan59a62332020-01-02 08:18:08 +08005157 /* No private data needed for the default pasid */
5158 pasid = ioasid_alloc(NULL, PASID_MIN,
5159 pci_max_pasids(to_pci_dev(dev)) - 1,
5160 NULL);
5161 if (pasid == INVALID_IOASID) {
Lu Baolu67b8e022019-03-25 09:30:32 +08005162 pr_err("Can't allocate default pasid\n");
5163 return -ENODEV;
5164 }
5165 domain->default_pasid = pasid;
5166 }
5167
5168 spin_lock_irqsave(&device_domain_lock, flags);
5169 /*
5170 * iommu->lock must be held to attach domain to iommu and setup the
5171 * pasid entry for second level translation.
5172 */
5173 spin_lock(&iommu->lock);
5174 ret = domain_attach_iommu(domain, iommu);
5175 if (ret)
5176 goto attach_failed;
5177
5178 /* Setup the PASID entry for mediated devices: */
Lu Baoluddf09b62020-01-02 08:18:17 +08005179 if (domain_use_first_level(domain))
5180 ret = domain_setup_first_level(iommu, domain, dev,
5181 domain->default_pasid);
5182 else
5183 ret = intel_pasid_setup_second_level(iommu, domain, dev,
5184 domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005185 if (ret)
5186 goto table_failed;
5187 spin_unlock(&iommu->lock);
5188
5189 auxiliary_link_device(domain, dev);
5190
5191 spin_unlock_irqrestore(&device_domain_lock, flags);
5192
5193 return 0;
5194
5195table_failed:
5196 domain_detach_iommu(domain, iommu);
5197attach_failed:
5198 spin_unlock(&iommu->lock);
5199 spin_unlock_irqrestore(&device_domain_lock, flags);
5200 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005201 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005202
5203 return ret;
5204}
5205
5206static void aux_domain_remove_dev(struct dmar_domain *domain,
5207 struct device *dev)
5208{
5209 struct device_domain_info *info;
5210 struct intel_iommu *iommu;
5211 unsigned long flags;
5212
5213 if (!is_aux_domain(dev, &domain->domain))
5214 return;
5215
5216 spin_lock_irqsave(&device_domain_lock, flags);
5217 info = dev->archdata.iommu;
5218 iommu = info->iommu;
5219
5220 auxiliary_unlink_device(domain, dev);
5221
5222 spin_lock(&iommu->lock);
5223 intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid);
5224 domain_detach_iommu(domain, iommu);
5225 spin_unlock(&iommu->lock);
5226
5227 spin_unlock_irqrestore(&device_domain_lock, flags);
5228}
5229
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005230static int prepare_domain_attach_device(struct iommu_domain *domain,
5231 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005232{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005233 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005234 struct intel_iommu *iommu;
5235 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005236 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005237
David Woodhouse156baca2014-03-09 14:00:57 -07005238 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005239 if (!iommu)
5240 return -ENODEV;
5241
5242 /* check if this iommu agaw is sufficient for max mapped address */
5243 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005244 if (addr_width > cap_mgaw(iommu->cap))
5245 addr_width = cap_mgaw(iommu->cap);
5246
5247 if (dmar_domain->max_addr > (1LL << addr_width)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06005248 dev_err(dev, "%s: iommu width (%d) is not "
5249 "sufficient for the mapped address (%llx)\n",
5250 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005251 return -EFAULT;
5252 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005253 dmar_domain->gaw = addr_width;
5254
5255 /*
5256 * Knock out extra levels of page tables if necessary
5257 */
5258 while (iommu->agaw < dmar_domain->agaw) {
5259 struct dma_pte *pte;
5260
5261 pte = dmar_domain->pgd;
5262 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005263 dmar_domain->pgd = (struct dma_pte *)
5264 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005265 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005266 }
5267 dmar_domain->agaw--;
5268 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005269
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005270 return 0;
5271}
5272
5273static int intel_iommu_attach_device(struct iommu_domain *domain,
5274 struct device *dev)
5275{
5276 int ret;
5277
Lu Baolu56795822019-06-12 08:28:48 +08005278 if (domain->type == IOMMU_DOMAIN_UNMANAGED &&
5279 device_is_rmrr_locked(dev)) {
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005280 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5281 return -EPERM;
5282 }
5283
Lu Baolu67b8e022019-03-25 09:30:32 +08005284 if (is_aux_domain(dev, domain))
5285 return -EPERM;
5286
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005287 /* normally dev is not mapped */
5288 if (unlikely(domain_context_mapped(dev))) {
5289 struct dmar_domain *old_domain;
5290
5291 old_domain = find_domain(dev);
Lu Baolufa954e62019-05-25 13:41:28 +08005292 if (old_domain)
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005293 dmar_remove_one_dev_info(dev);
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005294 }
5295
5296 ret = prepare_domain_attach_device(domain, dev);
5297 if (ret)
5298 return ret;
5299
5300 return domain_add_dev_info(to_dmar_domain(domain), dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005301}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005302
Lu Baolu67b8e022019-03-25 09:30:32 +08005303static int intel_iommu_aux_attach_device(struct iommu_domain *domain,
5304 struct device *dev)
5305{
5306 int ret;
5307
5308 if (!is_aux_domain(dev, domain))
5309 return -EPERM;
5310
5311 ret = prepare_domain_attach_device(domain, dev);
5312 if (ret)
5313 return ret;
5314
5315 return aux_domain_add_dev(to_dmar_domain(domain), dev);
5316}
5317
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005318static void intel_iommu_detach_device(struct iommu_domain *domain,
5319 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005320{
Bjorn Helgaas71753232019-02-08 16:06:15 -06005321 dmar_remove_one_dev_info(dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005322}
Kay, Allen M38717942008-09-09 18:37:29 +03005323
Lu Baolu67b8e022019-03-25 09:30:32 +08005324static void intel_iommu_aux_detach_device(struct iommu_domain *domain,
5325 struct device *dev)
5326{
5327 aux_domain_remove_dev(to_dmar_domain(domain), dev);
5328}
5329
Jacob Pan6ee1b772020-05-16 14:20:49 +08005330/*
5331 * 2D array for converting and sanitizing IOMMU generic TLB granularity to
5332 * VT-d granularity. Invalidation is typically included in the unmap operation
5333 * as a result of DMA or VFIO unmap. However, for assigned devices guest
5334 * owns the first level page tables. Invalidations of translation caches in the
5335 * guest are trapped and passed down to the host.
5336 *
5337 * vIOMMU in the guest will only expose first level page tables, therefore
5338 * we do not support IOTLB granularity for request without PASID (second level).
5339 *
5340 * For example, to find the VT-d granularity encoding for IOTLB
5341 * type and page selective granularity within PASID:
5342 * X: indexed by iommu cache type
5343 * Y: indexed by enum iommu_inv_granularity
5344 * [IOMMU_CACHE_INV_TYPE_IOTLB][IOMMU_INV_GRANU_ADDR]
5345 */
5346
5347const static int
5348inv_type_granu_table[IOMMU_CACHE_INV_TYPE_NR][IOMMU_INV_GRANU_NR] = {
5349 /*
5350 * PASID based IOTLB invalidation: PASID selective (per PASID),
5351 * page selective (address granularity)
5352 */
5353 {-EINVAL, QI_GRAN_NONG_PASID, QI_GRAN_PSI_PASID},
5354 /* PASID based dev TLBs */
5355 {-EINVAL, -EINVAL, QI_DEV_IOTLB_GRAN_PASID_SEL},
5356 /* PASID cache */
5357 {-EINVAL, -EINVAL, -EINVAL}
5358};
5359
5360static inline int to_vtd_granularity(int type, int granu)
5361{
5362 return inv_type_granu_table[type][granu];
5363}
5364
5365static inline u64 to_vtd_size(u64 granu_size, u64 nr_granules)
5366{
5367 u64 nr_pages = (granu_size * nr_granules) >> VTD_PAGE_SHIFT;
5368
5369 /* VT-d size is encoded as 2^size of 4K pages, 0 for 4k, 9 for 2MB, etc.
5370 * IOMMU cache invalidate API passes granu_size in bytes, and number of
5371 * granu size in contiguous memory.
5372 */
5373 return order_base_2(nr_pages);
5374}
5375
5376#ifdef CONFIG_INTEL_IOMMU_SVM
5377static int
5378intel_iommu_sva_invalidate(struct iommu_domain *domain, struct device *dev,
5379 struct iommu_cache_invalidate_info *inv_info)
5380{
5381 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5382 struct device_domain_info *info;
5383 struct intel_iommu *iommu;
5384 unsigned long flags;
5385 int cache_type;
5386 u8 bus, devfn;
5387 u16 did, sid;
5388 int ret = 0;
5389 u64 size = 0;
5390
5391 if (!inv_info || !dmar_domain ||
5392 inv_info->version != IOMMU_CACHE_INVALIDATE_INFO_VERSION_1)
5393 return -EINVAL;
5394
5395 if (!dev || !dev_is_pci(dev))
5396 return -ENODEV;
5397
5398 iommu = device_to_iommu(dev, &bus, &devfn);
5399 if (!iommu)
5400 return -ENODEV;
5401
5402 if (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE))
5403 return -EINVAL;
5404
5405 spin_lock_irqsave(&device_domain_lock, flags);
5406 spin_lock(&iommu->lock);
5407 info = dev->archdata.iommu;
5408 if (!info) {
5409 ret = -EINVAL;
5410 goto out_unlock;
5411 }
5412 did = dmar_domain->iommu_did[iommu->seq_id];
5413 sid = PCI_DEVID(bus, devfn);
5414
5415 /* Size is only valid in address selective invalidation */
5416 if (inv_info->granularity != IOMMU_INV_GRANU_PASID)
5417 size = to_vtd_size(inv_info->addr_info.granule_size,
5418 inv_info->addr_info.nb_granules);
5419
5420 for_each_set_bit(cache_type,
5421 (unsigned long *)&inv_info->cache,
5422 IOMMU_CACHE_INV_TYPE_NR) {
5423 int granu = 0;
5424 u64 pasid = 0;
5425
5426 granu = to_vtd_granularity(cache_type, inv_info->granularity);
5427 if (granu == -EINVAL) {
5428 pr_err_ratelimited("Invalid cache type and granu combination %d/%d\n",
5429 cache_type, inv_info->granularity);
5430 break;
5431 }
5432
5433 /*
5434 * PASID is stored in different locations based on the
5435 * granularity.
5436 */
5437 if (inv_info->granularity == IOMMU_INV_GRANU_PASID &&
5438 (inv_info->pasid_info.flags & IOMMU_INV_PASID_FLAGS_PASID))
5439 pasid = inv_info->pasid_info.pasid;
5440 else if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
5441 (inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_PASID))
5442 pasid = inv_info->addr_info.pasid;
5443
5444 switch (BIT(cache_type)) {
5445 case IOMMU_CACHE_INV_TYPE_IOTLB:
5446 if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
5447 size &&
5448 (inv_info->addr_info.addr & ((BIT(VTD_PAGE_SHIFT + size)) - 1))) {
5449 pr_err_ratelimited("Address out of range, 0x%llx, size order %llu\n",
5450 inv_info->addr_info.addr, size);
5451 ret = -ERANGE;
5452 goto out_unlock;
5453 }
5454
5455 /*
5456 * If granu is PASID-selective, address is ignored.
5457 * We use npages = -1 to indicate that.
5458 */
5459 qi_flush_piotlb(iommu, did, pasid,
5460 mm_to_dma_pfn(inv_info->addr_info.addr),
5461 (granu == QI_GRAN_NONG_PASID) ? -1 : 1 << size,
5462 inv_info->addr_info.flags & IOMMU_INV_ADDR_FLAGS_LEAF);
5463
5464 /*
5465 * Always flush device IOTLB if ATS is enabled. vIOMMU
5466 * in the guest may assume IOTLB flush is inclusive,
5467 * which is more efficient.
5468 */
5469 if (info->ats_enabled)
5470 qi_flush_dev_iotlb_pasid(iommu, sid,
5471 info->pfsid, pasid,
5472 info->ats_qdep,
5473 inv_info->addr_info.addr,
5474 size, granu);
5475 break;
5476 case IOMMU_CACHE_INV_TYPE_DEV_IOTLB:
5477 if (info->ats_enabled)
5478 qi_flush_dev_iotlb_pasid(iommu, sid,
5479 info->pfsid, pasid,
5480 info->ats_qdep,
5481 inv_info->addr_info.addr,
5482 size, granu);
5483 else
5484 pr_warn_ratelimited("Passdown device IOTLB flush w/o ATS!\n");
5485 break;
5486 default:
5487 dev_err_ratelimited(dev, "Unsupported IOMMU invalidation type %d\n",
5488 cache_type);
5489 ret = -EINVAL;
5490 }
5491 }
5492out_unlock:
5493 spin_unlock(&iommu->lock);
5494 spin_unlock_irqrestore(&device_domain_lock, flags);
5495
5496 return ret;
5497}
5498#endif
5499
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005500static int intel_iommu_map(struct iommu_domain *domain,
5501 unsigned long iova, phys_addr_t hpa,
Tom Murphy781ca2d2019-09-08 09:56:38 -07005502 size_t size, int iommu_prot, gfp_t gfp)
Kay, Allen M38717942008-09-09 18:37:29 +03005503{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005504 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005505 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005506 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005507 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005508
Joerg Roedeldde57a22008-12-03 15:04:09 +01005509 if (iommu_prot & IOMMU_READ)
5510 prot |= DMA_PTE_READ;
5511 if (iommu_prot & IOMMU_WRITE)
5512 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005513 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5514 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005515
David Woodhouse163cc522009-06-28 00:51:17 +01005516 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005517 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005518 u64 end;
5519
5520 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005521 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005522 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005523 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005524 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005525 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005526 return -EFAULT;
5527 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005528 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005529 }
David Woodhousead051222009-06-28 14:22:28 +01005530 /* Round up size to next multiple of PAGE_SIZE, if it and
5531 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005532 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005533 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5534 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005535 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005536}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005537
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005538static size_t intel_iommu_unmap(struct iommu_domain *domain,
Will Deacon56f8af52019-07-02 16:44:06 +01005539 unsigned long iova, size_t size,
5540 struct iommu_iotlb_gather *gather)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005541{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005542 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005543 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005544 unsigned long start_pfn, last_pfn;
5545 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005546 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005547
David Woodhouse5cf0a762014-03-19 16:07:49 +00005548 /* Cope with horrid API which requires us to unmap more than the
5549 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005550 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005551
5552 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5553 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5554
David Woodhouseea8ea462014-03-05 17:09:32 +00005555 start_pfn = iova >> VTD_PAGE_SHIFT;
5556 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5557
5558 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5559
5560 npages = last_pfn - start_pfn + 1;
5561
Shaokun Zhangf746a022018-03-22 18:18:06 +08005562 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005563 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5564 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005565
5566 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005567
David Woodhouse163cc522009-06-28 00:51:17 +01005568 if (dmar_domain->max_addr == iova + size)
5569 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005570
David Woodhouse5cf0a762014-03-19 16:07:49 +00005571 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005572}
Kay, Allen M38717942008-09-09 18:37:29 +03005573
Joerg Roedeld14d6572008-12-03 15:06:57 +01005574static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305575 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005576{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005577 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005578 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005579 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005580 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005581
David Woodhouse5cf0a762014-03-19 16:07:49 +00005582 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Yonghyun Hwang77a1bce2020-02-26 12:30:06 -08005583 if (pte && dma_pte_present(pte))
5584 phys = dma_pte_addr(pte) +
5585 (iova & (BIT_MASK(level_to_offset_bits(level) +
5586 VTD_PAGE_SHIFT) - 1));
Kay, Allen M38717942008-09-09 18:37:29 +03005587
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005588 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005589}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005590
Lu Baolu95587a72019-03-25 09:30:30 +08005591static inline bool scalable_mode_support(void)
5592{
5593 struct dmar_drhd_unit *drhd;
5594 struct intel_iommu *iommu;
5595 bool ret = true;
5596
5597 rcu_read_lock();
5598 for_each_active_iommu(iommu, drhd) {
5599 if (!sm_supported(iommu)) {
5600 ret = false;
5601 break;
5602 }
5603 }
5604 rcu_read_unlock();
5605
5606 return ret;
5607}
5608
5609static inline bool iommu_pasid_support(void)
5610{
5611 struct dmar_drhd_unit *drhd;
5612 struct intel_iommu *iommu;
5613 bool ret = true;
5614
5615 rcu_read_lock();
5616 for_each_active_iommu(iommu, drhd) {
5617 if (!pasid_supported(iommu)) {
5618 ret = false;
5619 break;
5620 }
5621 }
5622 rcu_read_unlock();
5623
5624 return ret;
5625}
5626
Lu Baolu2cd13112020-01-02 08:18:15 +08005627static inline bool nested_mode_support(void)
5628{
5629 struct dmar_drhd_unit *drhd;
5630 struct intel_iommu *iommu;
5631 bool ret = true;
5632
5633 rcu_read_lock();
5634 for_each_active_iommu(iommu, drhd) {
5635 if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
5636 ret = false;
5637 break;
5638 }
5639 }
5640 rcu_read_unlock();
5641
5642 return ret;
5643}
5644
Joerg Roedel5d587b82014-09-05 10:50:45 +02005645static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005646{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005647 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005648 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005649 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005650 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005651
Joerg Roedel5d587b82014-09-05 10:50:45 +02005652 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005653}
5654
Joerg Roedele5d18412020-04-29 15:36:54 +02005655static struct iommu_device *intel_iommu_probe_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005656{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005657 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07005658 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005659
Alex Williamsona5459cf2014-06-12 16:12:31 -06005660 iommu = device_to_iommu(dev, &bus, &devfn);
5661 if (!iommu)
Joerg Roedele5d18412020-04-29 15:36:54 +02005662 return ERR_PTR(-ENODEV);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005663
Lu Baolu8af46c72019-05-25 13:41:32 +08005664 if (translation_pre_enabled(iommu))
5665 dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
5666
Joerg Roedele5d18412020-04-29 15:36:54 +02005667 return &iommu->iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005668}
5669
Joerg Roedele5d18412020-04-29 15:36:54 +02005670static void intel_iommu_release_device(struct device *dev)
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005671{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005672 struct intel_iommu *iommu;
5673 u8 bus, devfn;
5674
5675 iommu = device_to_iommu(dev, &bus, &devfn);
5676 if (!iommu)
5677 return;
5678
Lu Baolu458b7c82019-08-01 11:14:58 +08005679 dmar_remove_one_dev_info(dev);
5680
Lu Baolu6fc70202020-05-06 09:59:47 +08005681 set_dma_ops(dev, NULL);
5682}
5683
5684static void intel_iommu_probe_finalize(struct device *dev)
5685{
5686 struct iommu_domain *domain;
5687
5688 domain = iommu_get_domain_for_dev(dev);
Lu Baolucfb94a32019-09-06 14:14:52 +08005689 if (device_needs_bounce(dev))
Lu Baolu6fc70202020-05-06 09:59:47 +08005690 set_dma_ops(dev, &bounce_dma_ops);
5691 else if (domain && domain->type == IOMMU_DOMAIN_DMA)
5692 set_dma_ops(dev, &intel_dma_ops);
5693 else
Lu Baolucfb94a32019-09-06 14:14:52 +08005694 set_dma_ops(dev, NULL);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005695}
5696
Eric Auger0659b8d2017-01-19 20:57:53 +00005697static void intel_iommu_get_resv_regions(struct device *device,
5698 struct list_head *head)
5699{
Eric Auger5f64ce52019-06-03 08:53:31 +02005700 int prot = DMA_PTE_READ | DMA_PTE_WRITE;
Eric Auger0659b8d2017-01-19 20:57:53 +00005701 struct iommu_resv_region *reg;
5702 struct dmar_rmrr_unit *rmrr;
5703 struct device *i_dev;
5704 int i;
5705
Eric Auger5f64ce52019-06-03 08:53:31 +02005706 down_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005707 for_each_rmrr_units(rmrr) {
5708 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5709 i, i_dev) {
Eric Auger5f64ce52019-06-03 08:53:31 +02005710 struct iommu_resv_region *resv;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005711 enum iommu_resv_type type;
Eric Auger5f64ce52019-06-03 08:53:31 +02005712 size_t length;
5713
Eric Auger3855ba22019-06-03 08:53:34 +02005714 if (i_dev != device &&
5715 !is_downstream_to_pci_bridge(device, i_dev))
Eric Auger0659b8d2017-01-19 20:57:53 +00005716 continue;
5717
Eric Auger5f64ce52019-06-03 08:53:31 +02005718 length = rmrr->end_address - rmrr->base_address + 1;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005719
5720 type = device_rmrr_is_relaxable(device) ?
5721 IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;
5722
Eric Auger5f64ce52019-06-03 08:53:31 +02005723 resv = iommu_alloc_resv_region(rmrr->base_address,
Eric Auger1c5c59f2019-06-03 08:53:36 +02005724 length, prot, type);
Eric Auger5f64ce52019-06-03 08:53:31 +02005725 if (!resv)
5726 break;
5727
5728 list_add_tail(&resv->list, head);
Eric Auger0659b8d2017-01-19 20:57:53 +00005729 }
5730 }
Eric Auger5f64ce52019-06-03 08:53:31 +02005731 up_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005732
Lu Baolud850c2e2019-05-25 13:41:24 +08005733#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
5734 if (dev_is_pci(device)) {
5735 struct pci_dev *pdev = to_pci_dev(device);
5736
5737 if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) {
Jerry Snitselaarcde93192019-12-12 22:36:42 -07005738 reg = iommu_alloc_resv_region(0, 1UL << 24, prot,
Alex Williamsond8018a02019-12-11 13:28:29 -07005739 IOMMU_RESV_DIRECT_RELAXABLE);
Lu Baolud850c2e2019-05-25 13:41:24 +08005740 if (reg)
5741 list_add_tail(&reg->list, head);
5742 }
5743 }
5744#endif /* CONFIG_INTEL_IOMMU_FLOPPY_WA */
5745
Eric Auger0659b8d2017-01-19 20:57:53 +00005746 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5747 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005748 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005749 if (!reg)
5750 return;
5751 list_add_tail(&reg->list, head);
5752}
5753
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005754int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005755{
5756 struct device_domain_info *info;
5757 struct context_entry *context;
5758 struct dmar_domain *domain;
5759 unsigned long flags;
5760 u64 ctx_lo;
5761 int ret;
5762
Lu Baolu4ec066c2019-05-25 13:41:33 +08005763 domain = find_domain(dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005764 if (!domain)
5765 return -EINVAL;
5766
5767 spin_lock_irqsave(&device_domain_lock, flags);
5768 spin_lock(&iommu->lock);
5769
5770 ret = -EINVAL;
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005771 info = dev->archdata.iommu;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005772 if (!info || !info->pasid_supported)
5773 goto out;
5774
5775 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5776 if (WARN_ON(!context))
5777 goto out;
5778
5779 ctx_lo = context[0].lo;
5780
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005781 if (!(ctx_lo & CONTEXT_PASIDE)) {
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005782 ctx_lo |= CONTEXT_PASIDE;
5783 context[0].lo = ctx_lo;
5784 wmb();
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005785 iommu->flush.flush_context(iommu,
5786 domain->iommu_did[iommu->seq_id],
5787 PCI_DEVID(info->bus, info->devfn),
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005788 DMA_CCMD_MASK_NOBIT,
5789 DMA_CCMD_DEVICE_INVL);
5790 }
5791
5792 /* Enable PASID support in the device, if it wasn't already */
5793 if (!info->pasid_enabled)
5794 iommu_enable_dev_iotlb(info);
5795
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005796 ret = 0;
5797
5798 out:
5799 spin_unlock(&iommu->lock);
5800 spin_unlock_irqrestore(&device_domain_lock, flags);
5801
5802 return ret;
5803}
5804
James Sewart73bcbdc2019-05-25 13:41:23 +08005805static void intel_iommu_apply_resv_region(struct device *dev,
5806 struct iommu_domain *domain,
5807 struct iommu_resv_region *region)
5808{
5809 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5810 unsigned long start, end;
5811
5812 start = IOVA_PFN(region->start);
5813 end = IOVA_PFN(region->start + region->length - 1);
5814
5815 WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end));
5816}
5817
Patrick Steinhardt4a350a02019-12-27 00:56:18 +01005818static struct iommu_group *intel_iommu_device_group(struct device *dev)
5819{
5820 if (dev_is_pci(dev))
5821 return pci_device_group(dev);
5822 return generic_device_group(dev);
5823}
5824
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005825#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005826struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5827{
5828 struct intel_iommu *iommu;
5829 u8 bus, devfn;
5830
5831 if (iommu_dummy(dev)) {
5832 dev_warn(dev,
5833 "No IOMMU translation for device; cannot enable SVM\n");
5834 return NULL;
5835 }
5836
5837 iommu = device_to_iommu(dev, &bus, &devfn);
5838 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005839 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005840 return NULL;
5841 }
5842
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005843 return iommu;
5844}
5845#endif /* CONFIG_INTEL_IOMMU_SVM */
5846
Lu Baolu95587a72019-03-25 09:30:30 +08005847static int intel_iommu_enable_auxd(struct device *dev)
5848{
5849 struct device_domain_info *info;
5850 struct intel_iommu *iommu;
5851 unsigned long flags;
5852 u8 bus, devfn;
5853 int ret;
5854
5855 iommu = device_to_iommu(dev, &bus, &devfn);
5856 if (!iommu || dmar_disabled)
5857 return -EINVAL;
5858
5859 if (!sm_supported(iommu) || !pasid_supported(iommu))
5860 return -EINVAL;
5861
5862 ret = intel_iommu_enable_pasid(iommu, dev);
5863 if (ret)
5864 return -ENODEV;
5865
5866 spin_lock_irqsave(&device_domain_lock, flags);
5867 info = dev->archdata.iommu;
5868 info->auxd_enabled = 1;
5869 spin_unlock_irqrestore(&device_domain_lock, flags);
5870
5871 return 0;
5872}
5873
5874static int intel_iommu_disable_auxd(struct device *dev)
5875{
5876 struct device_domain_info *info;
5877 unsigned long flags;
5878
5879 spin_lock_irqsave(&device_domain_lock, flags);
5880 info = dev->archdata.iommu;
5881 if (!WARN_ON(!info))
5882 info->auxd_enabled = 0;
5883 spin_unlock_irqrestore(&device_domain_lock, flags);
5884
5885 return 0;
5886}
5887
5888/*
5889 * A PCI express designated vendor specific extended capability is defined
5890 * in the section 3.7 of Intel scalable I/O virtualization technical spec
5891 * for system software and tools to detect endpoint devices supporting the
5892 * Intel scalable IO virtualization without host driver dependency.
5893 *
5894 * Returns the address of the matching extended capability structure within
5895 * the device's PCI configuration space or 0 if the device does not support
5896 * it.
5897 */
5898static int siov_find_pci_dvsec(struct pci_dev *pdev)
5899{
5900 int pos;
5901 u16 vendor, id;
5902
5903 pos = pci_find_next_ext_capability(pdev, 0, 0x23);
5904 while (pos) {
5905 pci_read_config_word(pdev, pos + 4, &vendor);
5906 pci_read_config_word(pdev, pos + 8, &id);
5907 if (vendor == PCI_VENDOR_ID_INTEL && id == 5)
5908 return pos;
5909
5910 pos = pci_find_next_ext_capability(pdev, pos, 0x23);
5911 }
5912
5913 return 0;
5914}
5915
5916static bool
5917intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
5918{
5919 if (feat == IOMMU_DEV_FEAT_AUX) {
5920 int ret;
5921
5922 if (!dev_is_pci(dev) || dmar_disabled ||
5923 !scalable_mode_support() || !iommu_pasid_support())
5924 return false;
5925
5926 ret = pci_pasid_features(to_pci_dev(dev));
5927 if (ret < 0)
5928 return false;
5929
5930 return !!siov_find_pci_dvsec(to_pci_dev(dev));
5931 }
5932
5933 return false;
5934}
5935
5936static int
5937intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
5938{
5939 if (feat == IOMMU_DEV_FEAT_AUX)
5940 return intel_iommu_enable_auxd(dev);
5941
5942 return -ENODEV;
5943}
5944
5945static int
5946intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
5947{
5948 if (feat == IOMMU_DEV_FEAT_AUX)
5949 return intel_iommu_disable_auxd(dev);
5950
5951 return -ENODEV;
5952}
5953
5954static bool
5955intel_iommu_dev_feat_enabled(struct device *dev, enum iommu_dev_features feat)
5956{
5957 struct device_domain_info *info = dev->archdata.iommu;
5958
5959 if (feat == IOMMU_DEV_FEAT_AUX)
5960 return scalable_mode_support() && info && info->auxd_enabled;
5961
5962 return false;
5963}
5964
Lu Baolu0e8000f2019-03-25 09:30:33 +08005965static int
5966intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
5967{
5968 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5969
5970 return dmar_domain->default_pasid > 0 ?
5971 dmar_domain->default_pasid : -EINVAL;
5972}
5973
Lu Baolu8af46c72019-05-25 13:41:32 +08005974static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
5975 struct device *dev)
5976{
Joerg Roedel1d46159782020-02-17 17:12:37 +01005977 return attach_deferred(dev);
Lu Baolu8af46c72019-05-25 13:41:32 +08005978}
5979
Lu Baolu2cd13112020-01-02 08:18:15 +08005980static int
5981intel_iommu_domain_set_attr(struct iommu_domain *domain,
5982 enum iommu_attr attr, void *data)
5983{
5984 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5985 unsigned long flags;
5986 int ret = 0;
5987
5988 if (domain->type != IOMMU_DOMAIN_UNMANAGED)
5989 return -EINVAL;
5990
5991 switch (attr) {
5992 case DOMAIN_ATTR_NESTING:
5993 spin_lock_irqsave(&device_domain_lock, flags);
5994 if (nested_mode_support() &&
5995 list_empty(&dmar_domain->devices)) {
5996 dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;
5997 dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;
5998 } else {
5999 ret = -ENODEV;
6000 }
6001 spin_unlock_irqrestore(&device_domain_lock, flags);
6002 break;
6003 default:
6004 ret = -EINVAL;
6005 break;
6006 }
6007
6008 return ret;
6009}
6010
Joerg Roedelb0119e82017-02-01 13:23:08 +01006011const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00006012 .capable = intel_iommu_capable,
6013 .domain_alloc = intel_iommu_domain_alloc,
6014 .domain_free = intel_iommu_domain_free,
Lu Baolu2cd13112020-01-02 08:18:15 +08006015 .domain_set_attr = intel_iommu_domain_set_attr,
Eric Auger0659b8d2017-01-19 20:57:53 +00006016 .attach_dev = intel_iommu_attach_device,
6017 .detach_dev = intel_iommu_detach_device,
Lu Baolu67b8e022019-03-25 09:30:32 +08006018 .aux_attach_dev = intel_iommu_aux_attach_device,
6019 .aux_detach_dev = intel_iommu_aux_detach_device,
Lu Baolu0e8000f2019-03-25 09:30:33 +08006020 .aux_get_pasid = intel_iommu_aux_get_pasid,
Eric Auger0659b8d2017-01-19 20:57:53 +00006021 .map = intel_iommu_map,
6022 .unmap = intel_iommu_unmap,
Eric Auger0659b8d2017-01-19 20:57:53 +00006023 .iova_to_phys = intel_iommu_iova_to_phys,
Joerg Roedele5d18412020-04-29 15:36:54 +02006024 .probe_device = intel_iommu_probe_device,
Lu Baolu6fc70202020-05-06 09:59:47 +08006025 .probe_finalize = intel_iommu_probe_finalize,
Joerg Roedele5d18412020-04-29 15:36:54 +02006026 .release_device = intel_iommu_release_device,
Eric Auger0659b8d2017-01-19 20:57:53 +00006027 .get_resv_regions = intel_iommu_get_resv_regions,
Thierry Reding0ecdebb2019-12-18 14:42:04 +01006028 .put_resv_regions = generic_iommu_put_resv_regions,
James Sewart73bcbdc2019-05-25 13:41:23 +08006029 .apply_resv_region = intel_iommu_apply_resv_region,
Patrick Steinhardt4a350a02019-12-27 00:56:18 +01006030 .device_group = intel_iommu_device_group,
Lu Baolu95587a72019-03-25 09:30:30 +08006031 .dev_has_feat = intel_iommu_dev_has_feat,
6032 .dev_feat_enabled = intel_iommu_dev_feat_enabled,
6033 .dev_enable_feat = intel_iommu_dev_enable_feat,
6034 .dev_disable_feat = intel_iommu_dev_disable_feat,
Lu Baolu8af46c72019-05-25 13:41:32 +08006035 .is_attach_deferred = intel_iommu_is_attach_deferred,
Joerg Roedel7039d112020-04-29 15:36:42 +02006036 .def_domain_type = device_def_domain_type,
Eric Auger0659b8d2017-01-19 20:57:53 +00006037 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Jacob Pan56722a42020-05-16 14:20:47 +08006038#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan6ee1b772020-05-16 14:20:49 +08006039 .cache_invalidate = intel_iommu_sva_invalidate,
Jacob Pan56722a42020-05-16 14:20:47 +08006040 .sva_bind_gpasid = intel_svm_bind_gpasid,
6041 .sva_unbind_gpasid = intel_svm_unbind_gpasid,
6042#endif
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01006043};
David Woodhouse9af88142009-02-13 23:18:03 +00006044
Chris Wilson1f762492019-09-09 12:00:10 +01006045static void quirk_iommu_igfx(struct pci_dev *dev)
Daniel Vetter94526182013-01-20 23:50:13 +01006046{
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006047 pci_info(dev, "Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01006048 dmar_map_gfx = 0;
6049}
6050
Chris Wilson1f762492019-09-09 12:00:10 +01006051/* G4x/GM45 integrated gfx dmar support is totally busted. */
6052DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
6053DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
6054DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_igfx);
6055DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_igfx);
6056DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
6057DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
6058DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
6059
6060/* Broadwell igfx malfunctions with dmar */
6061DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
6062DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
6063DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160E, quirk_iommu_igfx);
6064DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1602, quirk_iommu_igfx);
6065DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160A, quirk_iommu_igfx);
6066DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160D, quirk_iommu_igfx);
6067DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1616, quirk_iommu_igfx);
6068DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161B, quirk_iommu_igfx);
6069DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161E, quirk_iommu_igfx);
6070DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1612, quirk_iommu_igfx);
6071DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161A, quirk_iommu_igfx);
6072DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161D, quirk_iommu_igfx);
6073DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1626, quirk_iommu_igfx);
6074DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162B, quirk_iommu_igfx);
6075DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162E, quirk_iommu_igfx);
6076DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1622, quirk_iommu_igfx);
6077DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162A, quirk_iommu_igfx);
6078DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162D, quirk_iommu_igfx);
6079DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1636, quirk_iommu_igfx);
6080DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163B, quirk_iommu_igfx);
6081DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163E, quirk_iommu_igfx);
6082DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
6083DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
6084DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
Daniel Vetter94526182013-01-20 23:50:13 +01006085
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006086static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00006087{
6088 /*
6089 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01006090 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00006091 */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006092 pci_info(dev, "Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00006093 rwbf_quirk = 1;
6094}
6095
6096DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01006097DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
6098DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
6099DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
6100DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
6101DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
6102DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07006103
Adam Jacksoneecfd572010-08-25 21:17:34 +01006104#define GGC 0x52
6105#define GGC_MEMORY_SIZE_MASK (0xf << 8)
6106#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
6107#define GGC_MEMORY_SIZE_1M (0x1 << 8)
6108#define GGC_MEMORY_SIZE_2M (0x3 << 8)
6109#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
6110#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
6111#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
6112#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
6113
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006114static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01006115{
6116 unsigned short ggc;
6117
Adam Jacksoneecfd572010-08-25 21:17:34 +01006118 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01006119 return;
6120
Adam Jacksoneecfd572010-08-25 21:17:34 +01006121 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006122 pci_info(dev, "BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01006123 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006124 } else if (dmar_map_gfx) {
6125 /* we have to ensure the gfx device is idle before we flush */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006126 pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006127 intel_iommu_strict = 1;
6128 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01006129}
6130DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
6131DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
6132DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
6133DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
6134
David Woodhousee0fc7e02009-09-30 09:12:17 -07006135/* On Tylersburg chipsets, some BIOSes have been known to enable the
6136 ISOCH DMAR unit for the Azalia sound device, but not give it any
6137 TLB entries, which causes it to deadlock. Check for that. We do
6138 this in a function called from init_dmars(), instead of in a PCI
6139 quirk, because we don't want to print the obnoxious "BIOS broken"
6140 message if VT-d is actually disabled.
6141*/
6142static void __init check_tylersburg_isoch(void)
6143{
6144 struct pci_dev *pdev;
6145 uint32_t vtisochctrl;
6146
6147 /* If there's no Azalia in the system anyway, forget it. */
6148 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
6149 if (!pdev)
6150 return;
6151 pci_dev_put(pdev);
6152
6153 /* System Management Registers. Might be hidden, in which case
6154 we can't do the sanity check. But that's OK, because the
6155 known-broken BIOSes _don't_ actually hide it, so far. */
6156 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
6157 if (!pdev)
6158 return;
6159
6160 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
6161 pci_dev_put(pdev);
6162 return;
6163 }
6164
6165 pci_dev_put(pdev);
6166
6167 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
6168 if (vtisochctrl & 1)
6169 return;
6170
6171 /* Drop all bits other than the number of TLB entries */
6172 vtisochctrl &= 0x1c;
6173
6174 /* If we have the recommended number of TLB entries (16), fine. */
6175 if (vtisochctrl == 0x10)
6176 return;
6177
6178 /* Zero TLB entries? You get to ride the short bus to school. */
6179 if (!vtisochctrl) {
6180 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
6181 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
6182 dmi_get_system_info(DMI_BIOS_VENDOR),
6183 dmi_get_system_info(DMI_BIOS_VERSION),
6184 dmi_get_system_info(DMI_PRODUCT_VERSION));
6185 iommu_identity_mapping |= IDENTMAP_AZALIA;
6186 return;
6187 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02006188
6189 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07006190 vtisochctrl);
6191}