blob: 3f974919d3bdb4c7ee78adc091f585c4cc7a6da7 [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
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700299/* si_domain contains mulitple devices */
Lu Baolufa954e62019-05-25 13:41:28 +0800300#define DOMAIN_FLAG_STATIC_IDENTITY BIT(0)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700301
Lu Baolu942067f2019-05-25 13:41:29 +0800302/*
303 * This is a DMA domain allocated through the iommu domain allocation
304 * interface. But one or more devices belonging to this domain have
305 * been chosen to use a private domain. We should avoid to use the
306 * map/unmap/iova_to_phys APIs on it.
307 */
308#define DOMAIN_FLAG_LOSE_CHILDREN BIT(1)
309
Joerg Roedel29a27712015-07-21 17:17:12 +0200310#define for_each_domain_iommu(idx, domain) \
311 for (idx = 0; idx < g_num_of_iommus; idx++) \
312 if (domain->iommu_refcnt[idx])
313
Jiang Liub94e4112014-02-19 14:07:25 +0800314struct dmar_rmrr_unit {
315 struct list_head list; /* list of rmrr units */
316 struct acpi_dmar_header *hdr; /* ACPI header */
317 u64 base_address; /* reserved base address*/
318 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000319 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800320 int devices_cnt; /* target device count */
321};
322
323struct dmar_atsr_unit {
324 struct list_head list; /* list of ATSR units */
325 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000326 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800327 int devices_cnt; /* target device count */
328 u8 include_all:1; /* include all ports */
329};
330
331static LIST_HEAD(dmar_atsr_units);
332static LIST_HEAD(dmar_rmrr_units);
333
334#define for_each_rmrr_units(rmrr) \
335 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
336
mark gross5e0d2a62008-03-04 15:22:08 -0800337/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800338static int g_num_of_iommus;
339
Jiang Liu92d03cc2014-02-19 14:07:28 +0800340static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700341static void domain_remove_dev_info(struct dmar_domain *domain);
Bjorn Helgaas71753232019-02-08 16:06:15 -0600342static void dmar_remove_one_dev_info(struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200343static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Lu Baolu0ce4a852019-08-26 16:50:56 +0800344static void domain_context_clear(struct intel_iommu *iommu,
345 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800346static int domain_detach_iommu(struct dmar_domain *domain,
347 struct intel_iommu *iommu);
Lu Baolu4de354e2019-05-25 13:41:27 +0800348static bool device_is_rmrr_locked(struct device *dev);
Lu Baolu8af46c72019-05-25 13:41:32 +0800349static int intel_iommu_attach_device(struct iommu_domain *domain,
350 struct device *dev);
Lu Baolucfb94a32019-09-06 14:14:52 +0800351static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
352 dma_addr_t iova);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700353
Suresh Siddhad3f13812011-08-23 17:05:25 -0700354#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800355int dmar_disabled = 0;
356#else
357int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700358#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800359
Sai Praneeth Prakhyacdd3a242019-05-24 16:40:16 -0700360int intel_iommu_sm;
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200361int intel_iommu_enabled = 0;
362EXPORT_SYMBOL_GPL(intel_iommu_enabled);
363
David Woodhouse2d9e6672010-06-15 10:57:57 +0100364static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700365static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800366static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100367static int intel_iommu_superpage = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100368static int iommu_identity_mapping;
Lu Baolue5e04d02019-09-06 14:14:49 +0800369static int intel_no_bounce;
David Woodhousec83b2f22015-06-12 10:15:49 +0100370
David Woodhouseae853dd2015-09-09 11:58:59 +0100371#define IDENTMAP_ALL 1
372#define IDENTMAP_GFX 2
373#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100374
David Woodhousec0771df2011-10-14 20:59:46 +0100375int intel_iommu_gfx_mapped;
376EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
377
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700378#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
Lu Baolu8af46c72019-05-25 13:41:32 +0800379#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700380static DEFINE_SPINLOCK(device_domain_lock);
381static LIST_HEAD(device_domain_list);
382
Lu Baolue5e04d02019-09-06 14:14:49 +0800383#define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) && \
384 to_pci_dev(d)->untrusted)
385
Lu Baolu85319dc2018-07-14 15:46:58 +0800386/*
387 * Iterate over elements in device_domain_list and call the specified
Lu Baolu0bbeb012018-12-10 09:58:56 +0800388 * callback @fn against each element.
Lu Baolu85319dc2018-07-14 15:46:58 +0800389 */
390int for_each_device_domain(int (*fn)(struct device_domain_info *info,
391 void *data), void *data)
392{
393 int ret = 0;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800394 unsigned long flags;
Lu Baolu85319dc2018-07-14 15:46:58 +0800395 struct device_domain_info *info;
396
Lu Baolu0bbeb012018-12-10 09:58:56 +0800397 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800398 list_for_each_entry(info, &device_domain_list, global) {
399 ret = fn(info, data);
Lu Baolu0bbeb012018-12-10 09:58:56 +0800400 if (ret) {
401 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800402 return ret;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800403 }
Lu Baolu85319dc2018-07-14 15:46:58 +0800404 }
Lu Baolu0bbeb012018-12-10 09:58:56 +0800405 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800406
407 return 0;
408}
409
Joerg Roedelb0119e82017-02-01 13:23:08 +0100410const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100411
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200412static bool translation_pre_enabled(struct intel_iommu *iommu)
413{
414 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
415}
416
Joerg Roedel091d42e2015-06-12 11:56:10 +0200417static void clear_translation_pre_enabled(struct intel_iommu *iommu)
418{
419 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
420}
421
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200422static void init_translation_status(struct intel_iommu *iommu)
423{
424 u32 gsts;
425
426 gsts = readl(iommu->reg + DMAR_GSTS_REG);
427 if (gsts & DMA_GSTS_TES)
428 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
429}
430
Joerg Roedel00a77de2015-03-26 13:43:08 +0100431/* Convert generic 'struct iommu_domain to private struct dmar_domain */
432static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
433{
434 return container_of(dom, struct dmar_domain, domain);
435}
436
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700437static int __init intel_iommu_setup(char *str)
438{
439 if (!str)
440 return -EINVAL;
441 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800442 if (!strncmp(str, "on", 2)) {
443 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200444 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800445 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700446 dmar_disabled = 1;
Lu Baolu89a60792018-10-23 15:45:01 +0800447 no_platform_optin = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200448 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700449 } else if (!strncmp(str, "igfx_off", 8)) {
450 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200451 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700452 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200453 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700454 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800455 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200456 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800457 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100458 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200459 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100460 intel_iommu_superpage = 0;
Lu Baolu8950dcd2019-01-24 10:31:32 +0800461 } else if (!strncmp(str, "sm_on", 5)) {
462 pr_info("Intel-IOMMU: scalable mode supported\n");
463 intel_iommu_sm = 1;
Shaohua Libfd20f12017-04-26 09:18:35 -0700464 } else if (!strncmp(str, "tboot_noforce", 13)) {
465 printk(KERN_INFO
466 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
467 intel_iommu_tboot_noforce = 1;
Lu Baolue5e04d02019-09-06 14:14:49 +0800468 } else if (!strncmp(str, "nobounce", 8)) {
469 pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
470 intel_no_bounce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700471 }
472
473 str += strcspn(str, ",");
474 while (*str == ',')
475 str++;
476 }
477 return 0;
478}
479__setup("intel_iommu=", intel_iommu_setup);
480
481static struct kmem_cache *iommu_domain_cache;
482static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700483
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200484static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
485{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200486 struct dmar_domain **domains;
487 int idx = did >> 8;
488
489 domains = iommu->domains[idx];
490 if (!domains)
491 return NULL;
492
493 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200494}
495
496static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
497 struct dmar_domain *domain)
498{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200499 struct dmar_domain **domains;
500 int idx = did >> 8;
501
502 if (!iommu->domains[idx]) {
503 size_t size = 256 * sizeof(struct dmar_domain *);
504 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
505 }
506
507 domains = iommu->domains[idx];
508 if (WARN_ON(!domains))
509 return;
510 else
511 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200512}
513
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800514void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700515{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700516 struct page *page;
517 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700518
Suresh Siddha4c923d42009-10-02 11:01:24 -0700519 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
520 if (page)
521 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700522 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700523}
524
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800525void free_pgtable_page(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700526{
527 free_page((unsigned long)vaddr);
528}
529
530static inline void *alloc_domain_mem(void)
531{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900532 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700533}
534
Kay, Allen M38717942008-09-09 18:37:29 +0300535static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700536{
537 kmem_cache_free(iommu_domain_cache, vaddr);
538}
539
540static inline void * alloc_devinfo_mem(void)
541{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900542 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700543}
544
545static inline void free_devinfo_mem(void *vaddr)
546{
547 kmem_cache_free(iommu_devinfo_cache, vaddr);
548}
549
Joerg Roedel28ccce02015-07-21 14:45:31 +0200550static inline int domain_type_is_si(struct dmar_domain *domain)
551{
552 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
553}
554
Jiang Liu162d1b12014-07-11 14:19:35 +0800555static inline int domain_pfn_supported(struct dmar_domain *domain,
556 unsigned long pfn)
557{
558 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
559
560 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
561}
562
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700563static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800564{
565 unsigned long sagaw;
566 int agaw = -1;
567
568 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700569 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800570 agaw >= 0; agaw--) {
571 if (test_bit(agaw, &sagaw))
572 break;
573 }
574
575 return agaw;
576}
577
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700578/*
579 * Calculate max SAGAW for each iommu.
580 */
581int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
582{
583 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
584}
585
586/*
587 * calculate agaw for each iommu.
588 * "SAGAW" may be different across iommus, use a default agaw, and
589 * get a supported less agaw for iommus that don't support the default agaw.
590 */
591int iommu_calculate_agaw(struct intel_iommu *iommu)
592{
593 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
594}
595
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700596/* This functionin only returns single iommu in a domain */
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800597struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
Weidong Han8c11e792008-12-08 15:29:22 +0800598{
599 int iommu_id;
600
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700601 /* si_domain and vm domain should not get here. */
Lu Baolufa954e62019-05-25 13:41:28 +0800602 if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
603 return NULL;
604
Joerg Roedel29a27712015-07-21 17:17:12 +0200605 for_each_domain_iommu(iommu_id, domain)
606 break;
607
Weidong Han8c11e792008-12-08 15:29:22 +0800608 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
609 return NULL;
610
611 return g_iommus[iommu_id];
612}
613
Weidong Han8e6040972008-12-08 15:49:06 +0800614static void domain_update_iommu_coherency(struct dmar_domain *domain)
615{
David Woodhoused0501962014-03-11 17:10:29 -0700616 struct dmar_drhd_unit *drhd;
617 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100618 bool found = false;
619 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800620
David Woodhoused0501962014-03-11 17:10:29 -0700621 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800622
Joerg Roedel29a27712015-07-21 17:17:12 +0200623 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100624 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800625 if (!ecap_coherent(g_iommus[i]->ecap)) {
626 domain->iommu_coherency = 0;
627 break;
628 }
Weidong Han8e6040972008-12-08 15:49:06 +0800629 }
David Woodhoused0501962014-03-11 17:10:29 -0700630 if (found)
631 return;
632
633 /* No hardware attached; use lowest common denominator */
634 rcu_read_lock();
635 for_each_active_iommu(iommu, drhd) {
636 if (!ecap_coherent(iommu->ecap)) {
637 domain->iommu_coherency = 0;
638 break;
639 }
640 }
641 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800642}
643
Jiang Liu161f6932014-07-11 14:19:37 +0800644static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100645{
Allen Kay8140a952011-10-14 12:32:17 -0700646 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800647 struct intel_iommu *iommu;
648 int ret = 1;
649
650 rcu_read_lock();
651 for_each_active_iommu(iommu, drhd) {
652 if (iommu != skip) {
653 if (!ecap_sc_support(iommu->ecap)) {
654 ret = 0;
655 break;
656 }
657 }
658 }
659 rcu_read_unlock();
660
661 return ret;
662}
663
664static int domain_update_iommu_superpage(struct intel_iommu *skip)
665{
666 struct dmar_drhd_unit *drhd;
667 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700668 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100669
670 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800671 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100672 }
673
Allen Kay8140a952011-10-14 12:32:17 -0700674 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800675 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700676 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800677 if (iommu != skip) {
678 mask &= cap_super_page_val(iommu->cap);
679 if (!mask)
680 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100681 }
682 }
Jiang Liu0e242612014-02-19 14:07:34 +0800683 rcu_read_unlock();
684
Jiang Liu161f6932014-07-11 14:19:37 +0800685 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100686}
687
Sheng Yang58c610b2009-03-18 15:33:05 +0800688/* Some capabilities may be different across iommus */
689static void domain_update_iommu_cap(struct dmar_domain *domain)
690{
691 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800692 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
693 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800694}
695
Sohil Mehta26b86092018-09-11 17:11:36 -0700696struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
697 u8 devfn, int alloc)
David Woodhouse03ecc322015-02-13 14:35:21 +0000698{
699 struct root_entry *root = &iommu->root_entry[bus];
700 struct context_entry *context;
701 u64 *entry;
702
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200703 entry = &root->lo;
Lu Baolu765b6a92018-12-10 09:58:55 +0800704 if (sm_supported(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000705 if (devfn >= 0x80) {
706 devfn -= 0x80;
707 entry = &root->hi;
708 }
709 devfn *= 2;
710 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000711 if (*entry & 1)
712 context = phys_to_virt(*entry & VTD_PAGE_MASK);
713 else {
714 unsigned long phy_addr;
715 if (!alloc)
716 return NULL;
717
718 context = alloc_pgtable_page(iommu->node);
719 if (!context)
720 return NULL;
721
722 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
723 phy_addr = virt_to_phys((void *)context);
724 *entry = phy_addr | 1;
725 __iommu_flush_cache(iommu, entry, sizeof(*entry));
726 }
727 return &context[devfn];
728}
729
David Woodhouse4ed6a542015-05-11 14:59:20 +0100730static int iommu_dummy(struct device *dev)
731{
732 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
733}
734
Eric Augerb9a7f982019-06-03 08:53:32 +0200735/**
736 * is_downstream_to_pci_bridge - test if a device belongs to the PCI
737 * sub-hierarchy of a candidate PCI-PCI bridge
738 * @dev: candidate PCI device belonging to @bridge PCI sub-hierarchy
739 * @bridge: the candidate PCI-PCI bridge
740 *
741 * Return: true if @dev belongs to @bridge PCI sub-hierarchy, else false.
742 */
743static bool
744is_downstream_to_pci_bridge(struct device *dev, struct device *bridge)
745{
746 struct pci_dev *pdev, *pbridge;
747
748 if (!dev_is_pci(dev) || !dev_is_pci(bridge))
749 return false;
750
751 pdev = to_pci_dev(dev);
752 pbridge = to_pci_dev(bridge);
753
754 if (pbridge->subordinate &&
755 pbridge->subordinate->number <= pdev->bus->number &&
756 pbridge->subordinate->busn_res.end >= pdev->bus->number)
757 return true;
758
759 return false;
760}
761
David Woodhouse156baca2014-03-09 14:00:57 -0700762static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800763{
764 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800765 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700766 struct device *tmp;
Eric Augerb9a7f982019-06-03 08:53:32 +0200767 struct pci_dev *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800768 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800769 int i;
770
David Woodhouse4ed6a542015-05-11 14:59:20 +0100771 if (iommu_dummy(dev))
772 return NULL;
773
David Woodhouse156baca2014-03-09 14:00:57 -0700774 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700775 struct pci_dev *pf_pdev;
776
David Woodhouse156baca2014-03-09 14:00:57 -0700777 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600778
779#ifdef CONFIG_X86
780 /* VMD child devices currently cannot be handled individually */
781 if (is_vmd(pdev->bus))
782 return NULL;
783#endif
784
Ashok Raj1c387182016-10-21 15:32:05 -0700785 /* VFs aren't listed in scope tables; we need to look up
786 * the PF instead to find the IOMMU. */
787 pf_pdev = pci_physfn(pdev);
788 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700789 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100790 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700791 dev = &ACPI_COMPANION(dev)->dev;
792
Jiang Liu0e242612014-02-19 14:07:34 +0800793 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800794 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700795 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100796 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800797
Jiang Liub683b232014-02-19 14:07:32 +0800798 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700799 drhd->devices_cnt, i, tmp) {
800 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700801 /* For a VF use its original BDF# not that of the PF
802 * which we used for the IOMMU lookup. Strictly speaking
803 * we could do this for all PCI devices; we only need to
804 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100805 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700806 goto got_pdev;
807
David Woodhouse156baca2014-03-09 14:00:57 -0700808 *bus = drhd->devices[i].bus;
809 *devfn = drhd->devices[i].devfn;
810 goto out;
811 }
812
Eric Augerb9a7f982019-06-03 08:53:32 +0200813 if (is_downstream_to_pci_bridge(dev, tmp))
David Woodhouse156baca2014-03-09 14:00:57 -0700814 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100815 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800816
David Woodhouse156baca2014-03-09 14:00:57 -0700817 if (pdev && drhd->include_all) {
818 got_pdev:
819 *bus = pdev->bus->number;
820 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800821 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700822 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800823 }
Jiang Liub683b232014-02-19 14:07:32 +0800824 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700825 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800826 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800827
Jiang Liub683b232014-02-19 14:07:32 +0800828 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800829}
830
Weidong Han5331fe62008-12-08 23:00:00 +0800831static void domain_flush_cache(struct dmar_domain *domain,
832 void *addr, int size)
833{
834 if (!domain->iommu_coherency)
835 clflush_cache_range(addr, size);
836}
837
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700838static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
839{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700840 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000841 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700842 unsigned long flags;
843
844 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000845 context = iommu_context_addr(iommu, bus, devfn, 0);
846 if (context)
847 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700848 spin_unlock_irqrestore(&iommu->lock, flags);
849 return ret;
850}
851
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700852static void free_context_table(struct intel_iommu *iommu)
853{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700854 int i;
855 unsigned long flags;
856 struct context_entry *context;
857
858 spin_lock_irqsave(&iommu->lock, flags);
859 if (!iommu->root_entry) {
860 goto out;
861 }
862 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000863 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700864 if (context)
865 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000866
Lu Baolu765b6a92018-12-10 09:58:55 +0800867 if (!sm_supported(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000868 continue;
869
870 context = iommu_context_addr(iommu, i, 0x80, 0);
871 if (context)
872 free_pgtable_page(context);
873
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700874 }
875 free_pgtable_page(iommu->root_entry);
876 iommu->root_entry = NULL;
877out:
878 spin_unlock_irqrestore(&iommu->lock, flags);
879}
880
David Woodhouseb026fd22009-06-28 10:37:25 +0100881static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000882 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700883{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600884 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700885 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700886 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700887
888 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200889
Jiang Liu162d1b12014-07-11 14:19:35 +0800890 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200891 /* Address beyond IOMMU's addressing capabilities. */
892 return NULL;
893
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700894 parent = domain->pgd;
895
David Woodhouse5cf0a762014-03-19 16:07:49 +0000896 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700897 void *tmp_page;
898
David Woodhouseb026fd22009-06-28 10:37:25 +0100899 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700900 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000901 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100902 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000903 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700904 break;
905
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000906 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100907 uint64_t pteval;
908
Suresh Siddha4c923d42009-10-02 11:01:24 -0700909 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700910
David Woodhouse206a73c2009-07-01 19:30:28 +0100911 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700912 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100913
David Woodhousec85994e2009-07-01 19:21:24 +0100914 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400915 pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
Yijing Wangeffad4b2014-05-26 20:13:47 +0800916 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100917 /* Someone else set it while we were thinking; use theirs. */
918 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800919 else
David Woodhousec85994e2009-07-01 19:21:24 +0100920 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700921 }
David Woodhouse5cf0a762014-03-19 16:07:49 +0000922 if (level == 1)
923 break;
924
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000925 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700926 level--;
927 }
928
David Woodhouse5cf0a762014-03-19 16:07:49 +0000929 if (!*target_level)
930 *target_level = level;
931
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700932 return pte;
933}
934
935/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +0100936static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
937 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100938 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700939{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600940 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700941 int total = agaw_to_level(domain->agaw);
942 int offset;
943
944 parent = domain->pgd;
945 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +0100946 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700947 pte = &parent[offset];
948 if (level == total)
949 return pte;
950
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100951 if (!dma_pte_present(pte)) {
952 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700953 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100954 }
955
Yijing Wange16922a2014-05-20 20:37:51 +0800956 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100957 *large_page = total;
958 return pte;
959 }
960
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000961 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700962 total--;
963 }
964 return NULL;
965}
966
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700967/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +0000968static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf52009-06-27 22:09:11 +0100969 unsigned long start_pfn,
970 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700971{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600972 unsigned int large_page;
David Woodhouse310a5ab2009-06-28 18:52:20 +0100973 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700974
Jiang Liu162d1b12014-07-11 14:19:35 +0800975 BUG_ON(!domain_pfn_supported(domain, start_pfn));
976 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -0700977 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +0100978
David Woodhouse04b18e62009-06-27 19:15:01 +0100979 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -0700980 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100981 large_page = 1;
982 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100983 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100984 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100985 continue;
986 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100987 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +0100988 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100989 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +0100990 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +0100991 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
992
David Woodhouse310a5ab2009-06-28 18:52:20 +0100993 domain_flush_cache(domain, first_pte,
994 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -0700995
996 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700997}
998
Alex Williamson3269ee02013-06-15 10:27:19 -0600999static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001000 int retain_level, struct dma_pte *pte,
1001 unsigned long pfn, unsigned long start_pfn,
1002 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001003{
1004 pfn = max(start_pfn, pfn);
1005 pte = &pte[pfn_level_offset(pfn, level)];
1006
1007 do {
1008 unsigned long level_pfn;
1009 struct dma_pte *level_pte;
1010
1011 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1012 goto next;
1013
David Dillowf7116e12017-01-30 19:11:11 -08001014 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001015 level_pte = phys_to_virt(dma_pte_addr(pte));
1016
David Dillowbc24c572017-06-28 19:42:23 -07001017 if (level > 2) {
1018 dma_pte_free_level(domain, level - 1, retain_level,
1019 level_pte, level_pfn, start_pfn,
1020 last_pfn);
1021 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001022
David Dillowbc24c572017-06-28 19:42:23 -07001023 /*
1024 * Free the page table if we're below the level we want to
1025 * retain and the range covers the entire table.
1026 */
1027 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001028 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001029 dma_clear_pte(pte);
1030 domain_flush_cache(domain, pte, sizeof(*pte));
1031 free_pgtable_page(level_pte);
1032 }
1033next:
1034 pfn += level_size(level);
1035 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1036}
1037
David Dillowbc24c572017-06-28 19:42:23 -07001038/*
1039 * clear last level (leaf) ptes and free page table pages below the
1040 * level we wish to keep intact.
1041 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001042static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001043 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001044 unsigned long last_pfn,
1045 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001046{
Jiang Liu162d1b12014-07-11 14:19:35 +08001047 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1048 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001049 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001050
Jiang Liud41a4ad2014-07-11 14:19:34 +08001051 dma_pte_clear_range(domain, start_pfn, last_pfn);
1052
David Woodhousef3a0a522009-06-30 03:40:07 +01001053 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001054 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001055 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001056
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001057 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001058 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001059 free_pgtable_page(domain->pgd);
1060 domain->pgd = NULL;
1061 }
1062}
1063
David Woodhouseea8ea462014-03-05 17:09:32 +00001064/* When a page at a given level is being unlinked from its parent, we don't
1065 need to *modify* it at all. All we need to do is make a list of all the
1066 pages which can be freed just as soon as we've flushed the IOTLB and we
1067 know the hardware page-walk will no longer touch them.
1068 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1069 be freed. */
1070static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1071 int level, struct dma_pte *pte,
1072 struct page *freelist)
1073{
1074 struct page *pg;
1075
1076 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1077 pg->freelist = freelist;
1078 freelist = pg;
1079
1080 if (level == 1)
1081 return freelist;
1082
Jiang Liuadeb2592014-04-09 10:20:39 +08001083 pte = page_address(pg);
1084 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001085 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1086 freelist = dma_pte_list_pagetables(domain, level - 1,
1087 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001088 pte++;
1089 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001090
1091 return freelist;
1092}
1093
1094static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1095 struct dma_pte *pte, unsigned long pfn,
1096 unsigned long start_pfn,
1097 unsigned long last_pfn,
1098 struct page *freelist)
1099{
1100 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1101
1102 pfn = max(start_pfn, pfn);
1103 pte = &pte[pfn_level_offset(pfn, level)];
1104
1105 do {
1106 unsigned long level_pfn;
1107
1108 if (!dma_pte_present(pte))
1109 goto next;
1110
1111 level_pfn = pfn & level_mask(level);
1112
1113 /* If range covers entire pagetable, free it */
1114 if (start_pfn <= level_pfn &&
1115 last_pfn >= level_pfn + level_size(level) - 1) {
1116 /* These suborbinate page tables are going away entirely. Don't
1117 bother to clear them; we're just going to *free* them. */
1118 if (level > 1 && !dma_pte_superpage(pte))
1119 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1120
1121 dma_clear_pte(pte);
1122 if (!first_pte)
1123 first_pte = pte;
1124 last_pte = pte;
1125 } else if (level > 1) {
1126 /* Recurse down into a level that isn't *entirely* obsolete */
1127 freelist = dma_pte_clear_level(domain, level - 1,
1128 phys_to_virt(dma_pte_addr(pte)),
1129 level_pfn, start_pfn, last_pfn,
1130 freelist);
1131 }
1132next:
1133 pfn += level_size(level);
1134 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1135
1136 if (first_pte)
1137 domain_flush_cache(domain, first_pte,
1138 (void *)++last_pte - (void *)first_pte);
1139
1140 return freelist;
1141}
1142
1143/* We can't just free the pages because the IOMMU may still be walking
1144 the page tables, and may have cached the intermediate levels. The
1145 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001146static struct page *domain_unmap(struct dmar_domain *domain,
1147 unsigned long start_pfn,
1148 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001149{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001150 struct page *freelist;
David Woodhouseea8ea462014-03-05 17:09:32 +00001151
Jiang Liu162d1b12014-07-11 14:19:35 +08001152 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1153 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001154 BUG_ON(start_pfn > last_pfn);
1155
1156 /* we don't need lock here; nobody else touches the iova range */
1157 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1158 domain->pgd, 0, start_pfn, last_pfn, NULL);
1159
1160 /* free pgd */
1161 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1162 struct page *pgd_page = virt_to_page(domain->pgd);
1163 pgd_page->freelist = freelist;
1164 freelist = pgd_page;
1165
1166 domain->pgd = NULL;
1167 }
1168
1169 return freelist;
1170}
1171
Joerg Roedelb6904202015-08-13 11:32:18 +02001172static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001173{
1174 struct page *pg;
1175
1176 while ((pg = freelist)) {
1177 freelist = pg->freelist;
1178 free_pgtable_page(page_address(pg));
1179 }
1180}
1181
Joerg Roedel13cf0172017-08-11 11:40:10 +02001182static void iova_entry_free(unsigned long data)
1183{
1184 struct page *freelist = (struct page *)data;
1185
1186 dma_free_pagelist(freelist);
1187}
1188
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001189/* iommu handling */
1190static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1191{
1192 struct root_entry *root;
1193 unsigned long flags;
1194
Suresh Siddha4c923d42009-10-02 11:01:24 -07001195 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001196 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001197 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001198 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001199 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001200 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001201
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001202 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001203
1204 spin_lock_irqsave(&iommu->lock, flags);
1205 iommu->root_entry = root;
1206 spin_unlock_irqrestore(&iommu->lock, flags);
1207
1208 return 0;
1209}
1210
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001211static void iommu_set_root_entry(struct intel_iommu *iommu)
1212{
David Woodhouse03ecc322015-02-13 14:35:21 +00001213 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001214 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001215 unsigned long flag;
1216
David Woodhouse03ecc322015-02-13 14:35:21 +00001217 addr = virt_to_phys(iommu->root_entry);
Lu Baolu7373a8c2018-12-10 09:59:03 +08001218 if (sm_supported(iommu))
1219 addr |= DMA_RTADDR_SMT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001220
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001221 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001222 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001223
David Woodhousec416daa2009-05-10 20:30:58 +01001224 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001225
1226 /* Make sure hardware complete it */
1227 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001228 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001229
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001230 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001231}
1232
Lu Baolu6f7db752018-12-10 09:59:00 +08001233void iommu_flush_write_buffer(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001234{
1235 u32 val;
1236 unsigned long flag;
1237
David Woodhouse9af88142009-02-13 23:18:03 +00001238 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001239 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001240
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001241 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001242 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001243
1244 /* Make sure hardware complete it */
1245 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001246 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001247
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001248 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001249}
1250
1251/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001252static void __iommu_flush_context(struct intel_iommu *iommu,
1253 u16 did, u16 source_id, u8 function_mask,
1254 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001255{
1256 u64 val = 0;
1257 unsigned long flag;
1258
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001259 switch (type) {
1260 case DMA_CCMD_GLOBAL_INVL:
1261 val = DMA_CCMD_GLOBAL_INVL;
1262 break;
1263 case DMA_CCMD_DOMAIN_INVL:
1264 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1265 break;
1266 case DMA_CCMD_DEVICE_INVL:
1267 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1268 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1269 break;
1270 default:
1271 BUG();
1272 }
1273 val |= DMA_CCMD_ICC;
1274
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001275 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001276 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1277
1278 /* Make sure hardware complete it */
1279 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1280 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1281
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001282 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001283}
1284
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001285/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001286static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1287 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001288{
1289 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1290 u64 val = 0, val_iva = 0;
1291 unsigned long flag;
1292
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001293 switch (type) {
1294 case DMA_TLB_GLOBAL_FLUSH:
1295 /* global flush doesn't need set IVA_REG */
1296 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1297 break;
1298 case DMA_TLB_DSI_FLUSH:
1299 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1300 break;
1301 case DMA_TLB_PSI_FLUSH:
1302 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001303 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001304 val_iva = size_order | addr;
1305 break;
1306 default:
1307 BUG();
1308 }
1309 /* Note: set drain read/write */
1310#if 0
1311 /*
1312 * This is probably to be super secure.. Looks like we can
1313 * ignore it without any impact.
1314 */
1315 if (cap_read_drain(iommu->cap))
1316 val |= DMA_TLB_READ_DRAIN;
1317#endif
1318 if (cap_write_drain(iommu->cap))
1319 val |= DMA_TLB_WRITE_DRAIN;
1320
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001321 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001322 /* Note: Only uses first TLB reg currently */
1323 if (val_iva)
1324 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1325 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1326
1327 /* Make sure hardware complete it */
1328 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1329 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1330
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001331 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001332
1333 /* check IOTLB invalidation granularity */
1334 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001335 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001336 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001337 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001338 (unsigned long long)DMA_TLB_IIRG(type),
1339 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001340}
1341
David Woodhouse64ae8922014-03-09 12:52:30 -07001342static struct device_domain_info *
1343iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1344 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001345{
Yu Zhao93a23a72009-05-18 13:51:37 +08001346 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001347
Joerg Roedel55d94042015-07-22 16:50:40 +02001348 assert_spin_locked(&device_domain_lock);
1349
Yu Zhao93a23a72009-05-18 13:51:37 +08001350 if (!iommu->qi)
1351 return NULL;
1352
Yu Zhao93a23a72009-05-18 13:51:37 +08001353 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001354 if (info->iommu == iommu && info->bus == bus &&
1355 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001356 if (info->ats_supported && info->dev)
1357 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001358 break;
1359 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001360
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001361 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001362}
1363
Omer Peleg0824c592016-04-20 19:03:35 +03001364static void domain_update_iotlb(struct dmar_domain *domain)
1365{
1366 struct device_domain_info *info;
1367 bool has_iotlb_device = false;
1368
1369 assert_spin_locked(&device_domain_lock);
1370
1371 list_for_each_entry(info, &domain->devices, link) {
1372 struct pci_dev *pdev;
1373
1374 if (!info->dev || !dev_is_pci(info->dev))
1375 continue;
1376
1377 pdev = to_pci_dev(info->dev);
1378 if (pdev->ats_enabled) {
1379 has_iotlb_device = true;
1380 break;
1381 }
1382 }
1383
1384 domain->has_iotlb_device = has_iotlb_device;
1385}
1386
Yu Zhao93a23a72009-05-18 13:51:37 +08001387static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1388{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001389 struct pci_dev *pdev;
1390
Omer Peleg0824c592016-04-20 19:03:35 +03001391 assert_spin_locked(&device_domain_lock);
1392
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001393 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001394 return;
1395
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001396 pdev = to_pci_dev(info->dev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001397 /* For IOMMU that supports device IOTLB throttling (DIT), we assign
1398 * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
1399 * queue depth at PF level. If DIT is not set, PFSID will be treated as
1400 * reserved, which should be set to 0.
1401 */
1402 if (!ecap_dit(info->iommu->ecap))
1403 info->pfsid = 0;
1404 else {
1405 struct pci_dev *pf_pdev;
1406
1407 /* pdev will be returned if device is not a vf */
1408 pf_pdev = pci_physfn(pdev);
Heiner Kallweitcc49baa2019-04-24 21:16:10 +02001409 info->pfsid = pci_dev_id(pf_pdev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001410 }
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001411
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001412#ifdef CONFIG_INTEL_IOMMU_SVM
1413 /* The PCIe spec, in its wisdom, declares that the behaviour of
1414 the device if you enable PASID support after ATS support is
1415 undefined. So always enable PASID support on devices which
1416 have it, even if we can't yet know if we're ever going to
1417 use it. */
1418 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1419 info->pasid_enabled = 1;
1420
Kuppuswamy Sathyanarayanan1b84778a2019-02-19 11:04:52 -08001421 if (info->pri_supported &&
1422 (info->pasid_enabled ? pci_prg_resp_pasid_required(pdev) : 1) &&
1423 !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001424 info->pri_enabled = 1;
1425#endif
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001426 if (!pdev->untrusted && info->ats_supported &&
Kuppuswamy Sathyanarayanan61363c12019-02-19 11:06:10 -08001427 pci_ats_page_aligned(pdev) &&
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001428 !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001429 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001430 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001431 info->ats_qdep = pci_ats_queue_depth(pdev);
1432 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001433}
1434
1435static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1436{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001437 struct pci_dev *pdev;
1438
Omer Peleg0824c592016-04-20 19:03:35 +03001439 assert_spin_locked(&device_domain_lock);
1440
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001441 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001442 return;
1443
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001444 pdev = to_pci_dev(info->dev);
1445
1446 if (info->ats_enabled) {
1447 pci_disable_ats(pdev);
1448 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001449 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001450 }
1451#ifdef CONFIG_INTEL_IOMMU_SVM
1452 if (info->pri_enabled) {
1453 pci_disable_pri(pdev);
1454 info->pri_enabled = 0;
1455 }
1456 if (info->pasid_enabled) {
1457 pci_disable_pasid(pdev);
1458 info->pasid_enabled = 0;
1459 }
1460#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001461}
1462
1463static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1464 u64 addr, unsigned mask)
1465{
1466 u16 sid, qdep;
1467 unsigned long flags;
1468 struct device_domain_info *info;
1469
Omer Peleg0824c592016-04-20 19:03:35 +03001470 if (!domain->has_iotlb_device)
1471 return;
1472
Yu Zhao93a23a72009-05-18 13:51:37 +08001473 spin_lock_irqsave(&device_domain_lock, flags);
1474 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001475 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001476 continue;
1477
1478 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001479 qdep = info->ats_qdep;
Jacob Pan1c48db42018-06-07 09:57:00 -07001480 qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
1481 qdep, addr, mask);
Yu Zhao93a23a72009-05-18 13:51:37 +08001482 }
1483 spin_unlock_irqrestore(&device_domain_lock, flags);
1484}
1485
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001486static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1487 struct dmar_domain *domain,
1488 unsigned long pfn, unsigned int pages,
1489 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001490{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001491 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001492 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001493 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001494
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001495 BUG_ON(pages == 0);
1496
David Woodhouseea8ea462014-03-05 17:09:32 +00001497 if (ih)
1498 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001499 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001500 * Fallback to domain selective flush if no PSI support or the size is
1501 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001502 * PSI requires page size to be 2 ^ x, and the base address is naturally
1503 * aligned to the size
1504 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001505 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1506 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001507 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001508 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001509 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001510 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001511
1512 /*
Nadav Amit82653632010-04-01 13:24:40 +03001513 * In caching mode, changes of pages from non-present to present require
1514 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001515 */
Nadav Amit82653632010-04-01 13:24:40 +03001516 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001517 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001518}
1519
Peter Xueed91a02018-05-04 10:34:52 +08001520/* Notification for newly created mappings */
1521static inline void __mapping_notify_one(struct intel_iommu *iommu,
1522 struct dmar_domain *domain,
1523 unsigned long pfn, unsigned int pages)
1524{
1525 /* It's a non-present to present mapping. Only flush if caching mode */
1526 if (cap_caching_mode(iommu->cap))
1527 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1528 else
1529 iommu_flush_write_buffer(iommu);
1530}
1531
Joerg Roedel13cf0172017-08-11 11:40:10 +02001532static void iommu_flush_iova(struct iova_domain *iovad)
1533{
1534 struct dmar_domain *domain;
1535 int idx;
1536
1537 domain = container_of(iovad, struct dmar_domain, iovad);
1538
1539 for_each_domain_iommu(idx, domain) {
1540 struct intel_iommu *iommu = g_iommus[idx];
1541 u16 did = domain->iommu_did[iommu->seq_id];
1542
1543 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1544
1545 if (!cap_caching_mode(iommu->cap))
1546 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1547 0, MAX_AGAW_PFN_WIDTH);
1548 }
1549}
1550
mark grossf8bab732008-02-08 04:18:38 -08001551static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1552{
1553 u32 pmen;
1554 unsigned long flags;
1555
Lu Baolu5bb71fc72019-03-20 09:58:33 +08001556 if (!cap_plmr(iommu->cap) && !cap_phmr(iommu->cap))
1557 return;
1558
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001559 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001560 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1561 pmen &= ~DMA_PMEN_EPM;
1562 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1563
1564 /* wait for the protected region status bit to clear */
1565 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1566 readl, !(pmen & DMA_PMEN_PRS), pmen);
1567
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001568 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001569}
1570
Jiang Liu2a41cce2014-07-11 14:19:33 +08001571static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001572{
1573 u32 sts;
1574 unsigned long flags;
1575
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001576 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001577 iommu->gcmd |= DMA_GCMD_TE;
1578 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001579
1580 /* Make sure hardware complete it */
1581 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001582 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001583
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001584 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001585}
1586
Jiang Liu2a41cce2014-07-11 14:19:33 +08001587static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001588{
1589 u32 sts;
1590 unsigned long flag;
1591
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001592 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001593 iommu->gcmd &= ~DMA_GCMD_TE;
1594 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1595
1596 /* Make sure hardware complete it */
1597 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001598 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001599
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001600 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001601}
1602
1603static int iommu_init_domains(struct intel_iommu *iommu)
1604{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001605 u32 ndomains, nlongs;
1606 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001607
1608 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001609 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001610 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001611 nlongs = BITS_TO_LONGS(ndomains);
1612
Donald Dutile94a91b502009-08-20 16:51:34 -04001613 spin_lock_init(&iommu->lock);
1614
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001615 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1616 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001617 pr_err("%s: Allocating domain id array failed\n",
1618 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001619 return -ENOMEM;
1620 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001621
Wei Yang86f004c2016-05-21 02:41:51 +00001622 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001623 iommu->domains = kzalloc(size, GFP_KERNEL);
1624
1625 if (iommu->domains) {
1626 size = 256 * sizeof(struct dmar_domain *);
1627 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1628 }
1629
1630 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001631 pr_err("%s: Allocating domain array failed\n",
1632 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001633 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001634 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001635 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001636 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001637 return -ENOMEM;
1638 }
1639
1640 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001641 * If Caching mode is set, then invalid translations are tagged
1642 * with domain-id 0, hence we need to pre-allocate it. We also
1643 * use domain-id 0 as a marker for non-allocated domain-id, so
1644 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001645 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001646 set_bit(0, iommu->domain_ids);
1647
Lu Baolu3b33d4a2018-12-10 09:58:59 +08001648 /*
1649 * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid
1650 * entry for first-level or pass-through translation modes should
1651 * be programmed with a domain id different from those used for
1652 * second-level or nested translation. We reserve a domain id for
1653 * this purpose.
1654 */
1655 if (sm_supported(iommu))
1656 set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
1657
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001658 return 0;
1659}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001660
Jiang Liuffebeb42014-11-09 22:48:02 +08001661static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001662{
Joerg Roedel29a27712015-07-21 17:17:12 +02001663 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001664 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001665
Joerg Roedel29a27712015-07-21 17:17:12 +02001666 if (!iommu->domains || !iommu->domain_ids)
1667 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001668
Joerg Roedel55d94042015-07-22 16:50:40 +02001669 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001670 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
Joerg Roedel29a27712015-07-21 17:17:12 +02001671 if (info->iommu != iommu)
1672 continue;
1673
1674 if (!info->dev || !info->domain)
1675 continue;
1676
Joerg Roedelbea64032016-11-08 15:08:26 +01001677 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001679 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001680
1681 if (iommu->gcmd & DMA_GCMD_TE)
1682 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001683}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001684
Jiang Liuffebeb42014-11-09 22:48:02 +08001685static void free_dmar_iommu(struct intel_iommu *iommu)
1686{
1687 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001688 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001689 int i;
1690
1691 for (i = 0; i < elems; i++)
1692 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001693 kfree(iommu->domains);
1694 kfree(iommu->domain_ids);
1695 iommu->domains = NULL;
1696 iommu->domain_ids = NULL;
1697 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001698
Weidong Hand9630fe2008-12-08 11:06:32 +08001699 g_iommus[iommu->seq_id] = NULL;
1700
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001701 /* free context mapping */
1702 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001703
1704#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08001705 if (pasid_supported(iommu)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01001706 if (ecap_prs(iommu->ecap))
1707 intel_svm_finish_prq(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001708 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001709#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001710}
1711
Jiang Liuab8dfe22014-07-11 14:19:27 +08001712static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001713{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001714 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001715
1716 domain = alloc_domain_mem();
1717 if (!domain)
1718 return NULL;
1719
Jiang Liuab8dfe22014-07-11 14:19:27 +08001720 memset(domain, 0, sizeof(*domain));
Anshuman Khandual98fa15f2019-03-05 15:42:58 -08001721 domain->nid = NUMA_NO_NODE;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001722 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001723 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001724 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001725
1726 return domain;
1727}
1728
Joerg Roedeld160aca2015-07-22 11:52:53 +02001729/* Must be called with iommu->lock */
1730static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001731 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001732{
Jiang Liu44bde612014-07-11 14:19:29 +08001733 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001734 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001735
Joerg Roedel55d94042015-07-22 16:50:40 +02001736 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001737 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001738
Joerg Roedel29a27712015-07-21 17:17:12 +02001739 domain->iommu_refcnt[iommu->seq_id] += 1;
1740 domain->iommu_count += 1;
1741 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001742 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001743 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1744
1745 if (num >= ndomains) {
1746 pr_err("%s: No free domain ids\n", iommu->name);
1747 domain->iommu_refcnt[iommu->seq_id] -= 1;
1748 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001749 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001750 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001751
Joerg Roedeld160aca2015-07-22 11:52:53 +02001752 set_bit(num, iommu->domain_ids);
1753 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001754
Joerg Roedeld160aca2015-07-22 11:52:53 +02001755 domain->iommu_did[iommu->seq_id] = num;
1756 domain->nid = iommu->node;
1757
Jiang Liufb170fb2014-07-11 14:19:28 +08001758 domain_update_iommu_cap(domain);
1759 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001760
Joerg Roedel55d94042015-07-22 16:50:40 +02001761 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001762}
1763
1764static int domain_detach_iommu(struct dmar_domain *domain,
1765 struct intel_iommu *iommu)
1766{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001767 int num, count;
Jiang Liufb170fb2014-07-11 14:19:28 +08001768
Joerg Roedel55d94042015-07-22 16:50:40 +02001769 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001770 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001771
Joerg Roedel29a27712015-07-21 17:17:12 +02001772 domain->iommu_refcnt[iommu->seq_id] -= 1;
1773 count = --domain->iommu_count;
1774 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001775 num = domain->iommu_did[iommu->seq_id];
1776 clear_bit(num, iommu->domain_ids);
1777 set_iommu_domain(iommu, num, NULL);
1778
Jiang Liufb170fb2014-07-11 14:19:28 +08001779 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001780 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001781 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001782
1783 return count;
1784}
1785
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001786static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001787static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001788
Joseph Cihula51a63e62011-03-21 11:04:24 -07001789static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001790{
1791 struct pci_dev *pdev = NULL;
1792 struct iova *iova;
1793 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001794
Zhen Leiaa3ac942017-09-21 16:52:45 +01001795 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001796
Mark Gross8a443df2008-03-04 14:59:31 -08001797 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1798 &reserved_rbtree_key);
1799
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800 /* IOAPIC ranges shouldn't be accessed by DMA */
1801 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1802 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001803 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001804 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001805 return -ENODEV;
1806 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001807
1808 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1809 for_each_pci_dev(pdev) {
1810 struct resource *r;
1811
1812 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1813 r = &pdev->resource[i];
1814 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1815 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001816 iova = reserve_iova(&reserved_iova_list,
1817 IOVA_PFN(r->start),
1818 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001819 if (!iova) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06001820 pci_err(pdev, "Reserve iova for %pR failed\n", r);
Joseph Cihula51a63e62011-03-21 11:04:24 -07001821 return -ENODEV;
1822 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001823 }
1824 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001825 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001826}
1827
1828static void domain_reserve_special_ranges(struct dmar_domain *domain)
1829{
1830 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1831}
1832
1833static inline int guestwidth_to_adjustwidth(int gaw)
1834{
1835 int agaw;
1836 int r = (gaw - 12) % 9;
1837
1838 if (r == 0)
1839 agaw = gaw;
1840 else
1841 agaw = gaw + 9 - r;
1842 if (agaw > 64)
1843 agaw = 64;
1844 return agaw;
1845}
1846
Joerg Roedel301e7ee2019-07-22 16:21:05 +02001847static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1848 int guest_width)
1849{
1850 int adjust_width, agaw;
1851 unsigned long sagaw;
1852 int err;
1853
1854 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
1855
1856 err = init_iova_flush_queue(&domain->iovad,
1857 iommu_flush_iova, iova_entry_free);
1858 if (err)
1859 return err;
1860
1861 domain_reserve_special_ranges(domain);
1862
1863 /* calculate AGAW */
1864 if (guest_width > cap_mgaw(iommu->cap))
1865 guest_width = cap_mgaw(iommu->cap);
1866 domain->gaw = guest_width;
1867 adjust_width = guestwidth_to_adjustwidth(guest_width);
1868 agaw = width_to_agaw(adjust_width);
1869 sagaw = cap_sagaw(iommu->cap);
1870 if (!test_bit(agaw, &sagaw)) {
1871 /* hardware doesn't support it, choose a bigger one */
1872 pr_debug("Hardware doesn't support agaw %d\n", agaw);
1873 agaw = find_next_bit(&sagaw, 5, agaw);
1874 if (agaw >= 5)
1875 return -ENODEV;
1876 }
1877 domain->agaw = agaw;
1878
1879 if (ecap_coherent(iommu->ecap))
1880 domain->iommu_coherency = 1;
1881 else
1882 domain->iommu_coherency = 0;
1883
1884 if (ecap_sc_support(iommu->ecap))
1885 domain->iommu_snooping = 1;
1886 else
1887 domain->iommu_snooping = 0;
1888
1889 if (intel_iommu_superpage)
1890 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1891 else
1892 domain->iommu_superpage = 0;
1893
1894 domain->nid = iommu->node;
1895
1896 /* always allocate the top pgd */
1897 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
1898 if (!domain->pgd)
1899 return -ENOMEM;
1900 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
1901 return 0;
1902}
1903
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001904static void domain_exit(struct dmar_domain *domain)
1905{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001906
Joerg Roedeld160aca2015-07-22 11:52:53 +02001907 /* Remove associated devices and clear attached or cached domains */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001908 domain_remove_dev_info(domain);
Jiang Liu92d03cc2014-02-19 14:07:28 +08001909
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001910 /* destroy iovas */
1911 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001912
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001913 if (domain->pgd) {
1914 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001915
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01001916 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
1917 dma_free_pagelist(freelist);
1918 }
David Woodhouseea8ea462014-03-05 17:09:32 +00001919
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001920 free_domain_mem(domain);
1921}
1922
Lu Baolu7373a8c2018-12-10 09:59:03 +08001923/*
1924 * Get the PASID directory size for scalable mode context entry.
1925 * Value of X in the PDTS field of a scalable mode context entry
1926 * indicates PASID directory with 2^(X + 7) entries.
1927 */
1928static inline unsigned long context_get_sm_pds(struct pasid_table *table)
1929{
1930 int pds, max_pde;
1931
1932 max_pde = table->max_pasid >> PASID_PDE_SHIFT;
1933 pds = find_first_bit((unsigned long *)&max_pde, MAX_NR_PASID_BITS);
1934 if (pds < 7)
1935 return 0;
1936
1937 return pds - 7;
1938}
1939
1940/*
1941 * Set the RID_PASID field of a scalable mode context entry. The
1942 * IOMMU hardware will use the PASID value set in this field for
1943 * DMA translations of DMA requests without PASID.
1944 */
1945static inline void
1946context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
1947{
1948 context->hi |= pasid & ((1 << 20) - 1);
1949 context->hi |= (1 << 20);
1950}
1951
1952/*
1953 * Set the DTE(Device-TLB Enable) field of a scalable mode context
1954 * entry.
1955 */
1956static inline void context_set_sm_dte(struct context_entry *context)
1957{
1958 context->lo |= (1 << 2);
1959}
1960
1961/*
1962 * Set the PRE(Page Request Enable) field of a scalable mode context
1963 * entry.
1964 */
1965static inline void context_set_sm_pre(struct context_entry *context)
1966{
1967 context->lo |= (1 << 4);
1968}
1969
1970/* Convert value to context PASID directory size field coding. */
1971#define context_pdts(pds) (((pds) & 0x7) << 9)
1972
David Woodhouse64ae8922014-03-09 12:52:30 -07001973static int domain_context_mapping_one(struct dmar_domain *domain,
1974 struct intel_iommu *iommu,
Lu Baoluca6e3222018-12-10 09:59:02 +08001975 struct pasid_table *table,
Joerg Roedel28ccce02015-07-21 14:45:31 +02001976 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001977{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001978 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02001979 int translation = CONTEXT_TT_MULTI_LEVEL;
1980 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001982 unsigned long flags;
Lu Baolu7373a8c2018-12-10 09:59:03 +08001983 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02001984
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02001985 WARN_ON(did == 0);
1986
Joerg Roedel28ccce02015-07-21 14:45:31 +02001987 if (hw_pass_through && domain_type_is_si(domain))
1988 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001989
1990 pr_debug("Set context mapping for %02x:%02x.%d\n",
1991 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07001992
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001993 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08001994
Joerg Roedel55d94042015-07-22 16:50:40 +02001995 spin_lock_irqsave(&device_domain_lock, flags);
1996 spin_lock(&iommu->lock);
1997
1998 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00001999 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002000 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002001 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002
Joerg Roedel55d94042015-07-22 16:50:40 +02002003 ret = 0;
2004 if (context_present(context))
2005 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002006
Xunlei Pangaec0e862016-12-05 20:09:07 +08002007 /*
2008 * For kdump cases, old valid entries may be cached due to the
2009 * in-flight DMA and copied pgtable, but there is no unmapping
2010 * behaviour for them, thus we need an explicit cache flush for
2011 * the newly-mapped device. For kdump, at this point, the device
2012 * is supposed to finish reset at its driver probe stage, so no
2013 * in-flight DMA will exist, and we don't need to worry anymore
2014 * hereafter.
2015 */
2016 if (context_copied(context)) {
2017 u16 did_old = context_domain_id(context);
2018
Christos Gkekasb117e032017-10-08 23:33:31 +01002019 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002020 iommu->flush.flush_context(iommu, did_old,
2021 (((u16)bus) << 8) | devfn,
2022 DMA_CCMD_MASK_NOBIT,
2023 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002024 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2025 DMA_TLB_DSI_FLUSH);
2026 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002027 }
2028
Joerg Roedelde24e552015-07-21 14:53:04 +02002029 context_clear_entry(context);
Weidong Hanea6606b2008-12-08 23:08:15 +08002030
Lu Baolu7373a8c2018-12-10 09:59:03 +08002031 if (sm_supported(iommu)) {
2032 unsigned long pds;
Joerg Roedelde24e552015-07-21 14:53:04 +02002033
Lu Baolu7373a8c2018-12-10 09:59:03 +08002034 WARN_ON(!table);
2035
2036 /* Setup the PASID DIR pointer: */
2037 pds = context_get_sm_pds(table);
2038 context->lo = (u64)virt_to_phys(table->table) |
2039 context_pdts(pds);
2040
2041 /* Setup the RID_PASID field: */
2042 context_set_sm_rid2pasid(context, PASID_RID2PASID);
2043
2044 /*
2045 * Setup the Device-TLB enable bit and Page request
2046 * Enable bit:
2047 */
David Woodhouse64ae8922014-03-09 12:52:30 -07002048 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002049 if (info && info->ats_supported)
Lu Baolu7373a8c2018-12-10 09:59:03 +08002050 context_set_sm_dte(context);
2051 if (info && info->pri_supported)
2052 context_set_sm_pre(context);
Joerg Roedelde24e552015-07-21 14:53:04 +02002053 } else {
Lu Baolu7373a8c2018-12-10 09:59:03 +08002054 struct dma_pte *pgd = domain->pgd;
2055 int agaw;
2056
2057 context_set_domain_id(context, did);
Lu Baolu7373a8c2018-12-10 09:59:03 +08002058
2059 if (translation != CONTEXT_TT_PASS_THROUGH) {
2060 /*
2061 * Skip top levels of page tables for iommu which has
2062 * less agaw than default. Unnecessary for PT mode.
2063 */
2064 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2065 ret = -ENOMEM;
2066 pgd = phys_to_virt(dma_pte_addr(pgd));
2067 if (!dma_pte_present(pgd))
2068 goto out_unlock;
2069 }
2070
2071 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
2072 if (info && info->ats_supported)
2073 translation = CONTEXT_TT_DEV_IOTLB;
2074 else
2075 translation = CONTEXT_TT_MULTI_LEVEL;
2076
2077 context_set_address_root(context, virt_to_phys(pgd));
2078 context_set_address_width(context, agaw);
2079 } else {
2080 /*
2081 * In pass through mode, AW must be programmed to
2082 * indicate the largest AGAW value supported by
2083 * hardware. And ASR is ignored by hardware.
2084 */
2085 context_set_address_width(context, iommu->msagaw);
2086 }
Lu Baolu41b80db2019-03-01 11:23:11 +08002087
2088 context_set_translation_type(context, translation);
Yu Zhao93a23a72009-05-18 13:51:37 +08002089 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002090
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002091 context_set_fault_enable(context);
2092 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002093 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002094
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002095 /*
2096 * It's a non-present to present mapping. If hardware doesn't cache
2097 * non-present entry we only need to flush the write-buffer. If the
2098 * _does_ cache non-present entries, then it does so in the special
2099 * domain #0, which we have to flush:
2100 */
2101 if (cap_caching_mode(iommu->cap)) {
2102 iommu->flush.flush_context(iommu, 0,
2103 (((u16)bus) << 8) | devfn,
2104 DMA_CCMD_MASK_NOBIT,
2105 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002106 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002107 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002108 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002109 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002110 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002111
Joerg Roedel55d94042015-07-22 16:50:40 +02002112 ret = 0;
2113
2114out_unlock:
2115 spin_unlock(&iommu->lock);
2116 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002117
Wei Yang5c365d12016-07-13 13:53:21 +00002118 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002119}
2120
Lu Baolu0ce4a852019-08-26 16:50:56 +08002121struct domain_context_mapping_data {
2122 struct dmar_domain *domain;
2123 struct intel_iommu *iommu;
2124 struct pasid_table *table;
2125};
2126
2127static int domain_context_mapping_cb(struct pci_dev *pdev,
2128 u16 alias, void *opaque)
2129{
2130 struct domain_context_mapping_data *data = opaque;
2131
2132 return domain_context_mapping_one(data->domain, data->iommu,
2133 data->table, PCI_BUS_NUM(alias),
2134 alias & 0xff);
2135}
2136
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002137static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002138domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002139{
Lu Baolu0ce4a852019-08-26 16:50:56 +08002140 struct domain_context_mapping_data data;
Lu Baoluca6e3222018-12-10 09:59:02 +08002141 struct pasid_table *table;
David Woodhouse64ae8922014-03-09 12:52:30 -07002142 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002143 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002144
David Woodhousee1f167f2014-03-09 15:24:46 -07002145 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002146 if (!iommu)
2147 return -ENODEV;
2148
Lu Baoluca6e3222018-12-10 09:59:02 +08002149 table = intel_pasid_get_table(dev);
Lu Baolu0ce4a852019-08-26 16:50:56 +08002150
2151 if (!dev_is_pci(dev))
2152 return domain_context_mapping_one(domain, iommu, table,
2153 bus, devfn);
2154
2155 data.domain = domain;
2156 data.iommu = iommu;
2157 data.table = table;
2158
2159 return pci_for_each_dma_alias(to_pci_dev(dev),
2160 &domain_context_mapping_cb, &data);
Alex Williamson579305f2014-07-03 09:51:43 -06002161}
2162
2163static int domain_context_mapped_cb(struct pci_dev *pdev,
2164 u16 alias, void *opaque)
2165{
2166 struct intel_iommu *iommu = opaque;
2167
2168 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002169}
2170
David Woodhousee1f167f2014-03-09 15:24:46 -07002171static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002172{
Weidong Han5331fe62008-12-08 23:00:00 +08002173 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002174 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002175
David Woodhousee1f167f2014-03-09 15:24:46 -07002176 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002177 if (!iommu)
2178 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002179
Alex Williamson579305f2014-07-03 09:51:43 -06002180 if (!dev_is_pci(dev))
2181 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002182
Alex Williamson579305f2014-07-03 09:51:43 -06002183 return !pci_for_each_dma_alias(to_pci_dev(dev),
2184 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002185}
2186
Fenghua Yuf5329592009-08-04 15:09:37 -07002187/* Returns a number of VTD pages, but aligned to MM page size */
2188static inline unsigned long aligned_nrpages(unsigned long host_addr,
2189 size_t size)
2190{
2191 host_addr &= ~PAGE_MASK;
2192 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2193}
2194
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002195/* Return largest possible superpage level for a given mapping */
2196static inline int hardware_largepage_caps(struct dmar_domain *domain,
2197 unsigned long iov_pfn,
2198 unsigned long phy_pfn,
2199 unsigned long pages)
2200{
2201 int support, level = 1;
2202 unsigned long pfnmerge;
2203
2204 support = domain->iommu_superpage;
2205
2206 /* To use a large page, the virtual *and* physical addresses
2207 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2208 of them will mean we have to use smaller pages. So just
2209 merge them and check both at once. */
2210 pfnmerge = iov_pfn | phy_pfn;
2211
2212 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2213 pages >>= VTD_STRIDE_SHIFT;
2214 if (!pages)
2215 break;
2216 pfnmerge >>= VTD_STRIDE_SHIFT;
2217 level++;
2218 support--;
2219 }
2220 return level;
2221}
2222
David Woodhouse9051aa02009-06-29 12:30:54 +01002223static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2224 struct scatterlist *sg, unsigned long phys_pfn,
2225 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002226{
2227 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002228 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002229 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002230 unsigned int largepage_lvl = 0;
2231 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002232
Jiang Liu162d1b12014-07-11 14:19:35 +08002233 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002234
2235 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2236 return -EINVAL;
2237
2238 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2239
Jiang Liucc4f14a2014-11-26 09:42:10 +08002240 if (!sg) {
2241 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002242 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2243 }
2244
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002245 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002246 uint64_t tmp;
2247
David Woodhousee1605492009-06-29 11:17:38 +01002248 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002249 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2250
Fenghua Yuf5329592009-08-04 15:09:37 -07002251 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002252 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002253 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002254 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002255 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002256 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002257
David Woodhousee1605492009-06-29 11:17:38 +01002258 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002259 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2260
David Woodhouse5cf0a762014-03-19 16:07:49 +00002261 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002262 if (!pte)
2263 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002264 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002265 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002266 unsigned long nr_superpages, end_pfn;
2267
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002268 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002269 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002270
2271 nr_superpages = sg_res / lvl_pages;
2272 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2273
Jiang Liud41a4ad2014-07-11 14:19:34 +08002274 /*
2275 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002276 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002277 * We're adding new large pages, so make sure
2278 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002279 */
David Dillowbc24c572017-06-28 19:42:23 -07002280 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2281 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002282 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002283 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002284 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002285
David Woodhousee1605492009-06-29 11:17:38 +01002286 }
2287 /* We don't need lock here, nobody else
2288 * touches the iova range
2289 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002290 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002291 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002292 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002293 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2294 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002295 if (dumps) {
2296 dumps--;
2297 debug_dma_dump_mappings(NULL);
2298 }
2299 WARN_ON(1);
2300 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002301
2302 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2303
2304 BUG_ON(nr_pages < lvl_pages);
2305 BUG_ON(sg_res < lvl_pages);
2306
2307 nr_pages -= lvl_pages;
2308 iov_pfn += lvl_pages;
2309 phys_pfn += lvl_pages;
2310 pteval += lvl_pages * VTD_PAGE_SIZE;
2311 sg_res -= lvl_pages;
2312
2313 /* If the next PTE would be the first in a new page, then we
2314 need to flush the cache on the entries we've just written.
2315 And then we'll need to recalculate 'pte', so clear it and
2316 let it get set again in the if (!pte) block above.
2317
2318 If we're done (!nr_pages) we need to flush the cache too.
2319
2320 Also if we've been setting superpages, we may need to
2321 recalculate 'pte' and switch back to smaller pages for the
2322 end of the mapping, if the trailing size is not enough to
2323 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002324 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002325 if (!nr_pages || first_pte_in_page(pte) ||
2326 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002327 domain_flush_cache(domain, first_pte,
2328 (void *)pte - (void *)first_pte);
2329 pte = NULL;
2330 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002331
2332 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002333 sg = sg_next(sg);
2334 }
2335 return 0;
2336}
2337
Peter Xu87684fd2018-05-04 10:34:53 +08002338static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
Lu Baolu095303e2019-04-29 09:16:02 +08002339 struct scatterlist *sg, unsigned long phys_pfn,
2340 unsigned long nr_pages, int prot)
Peter Xu87684fd2018-05-04 10:34:53 +08002341{
Lu Baolufa954e62019-05-25 13:41:28 +08002342 int iommu_id, ret;
Lu Baolu095303e2019-04-29 09:16:02 +08002343 struct intel_iommu *iommu;
Peter Xu87684fd2018-05-04 10:34:53 +08002344
Lu Baolu095303e2019-04-29 09:16:02 +08002345 /* Do the real mapping first */
2346 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2347 if (ret)
2348 return ret;
Peter Xu87684fd2018-05-04 10:34:53 +08002349
Lu Baolufa954e62019-05-25 13:41:28 +08002350 for_each_domain_iommu(iommu_id, domain) {
2351 iommu = g_iommus[iommu_id];
Lu Baolu095303e2019-04-29 09:16:02 +08002352 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2353 }
2354
2355 return 0;
Peter Xu87684fd2018-05-04 10:34:53 +08002356}
2357
David Woodhouse9051aa02009-06-29 12:30:54 +01002358static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2359 struct scatterlist *sg, unsigned long nr_pages,
2360 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002361{
Peter Xu87684fd2018-05-04 10:34:53 +08002362 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002363}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002364
David Woodhouse9051aa02009-06-29 12:30:54 +01002365static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2366 unsigned long phys_pfn, unsigned long nr_pages,
2367 int prot)
2368{
Peter Xu87684fd2018-05-04 10:34:53 +08002369 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002370}
2371
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002372static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002373{
Filippo Sironi50822192017-08-31 10:58:11 +02002374 unsigned long flags;
2375 struct context_entry *context;
2376 u16 did_old;
2377
Weidong Hanc7151a82008-12-08 22:51:37 +08002378 if (!iommu)
2379 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002380
Filippo Sironi50822192017-08-31 10:58:11 +02002381 spin_lock_irqsave(&iommu->lock, flags);
2382 context = iommu_context_addr(iommu, bus, devfn, 0);
2383 if (!context) {
2384 spin_unlock_irqrestore(&iommu->lock, flags);
2385 return;
2386 }
2387 did_old = context_domain_id(context);
2388 context_clear_entry(context);
2389 __iommu_flush_cache(iommu, context, sizeof(*context));
2390 spin_unlock_irqrestore(&iommu->lock, flags);
2391 iommu->flush.flush_context(iommu,
2392 did_old,
2393 (((u16)bus) << 8) | devfn,
2394 DMA_CCMD_MASK_NOBIT,
2395 DMA_CCMD_DEVICE_INVL);
2396 iommu->flush.flush_iotlb(iommu,
2397 did_old,
2398 0,
2399 0,
2400 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002401}
2402
David Woodhouse109b9b02012-05-25 17:43:02 +01002403static inline void unlink_domain_info(struct device_domain_info *info)
2404{
2405 assert_spin_locked(&device_domain_lock);
2406 list_del(&info->link);
2407 list_del(&info->global);
2408 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002409 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002410}
2411
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002412static void domain_remove_dev_info(struct dmar_domain *domain)
2413{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002414 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002415 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002416
2417 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002418 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002419 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002420 spin_unlock_irqrestore(&device_domain_lock, flags);
2421}
2422
2423/*
2424 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002425 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002426 */
David Woodhouse1525a292014-03-06 16:19:30 +00002427static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002428{
2429 struct device_domain_info *info;
2430
Lu Baolu8af46c72019-05-25 13:41:32 +08002431 if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) {
2432 struct iommu_domain *domain;
2433
2434 dev->archdata.iommu = NULL;
2435 domain = iommu_get_domain_for_dev(dev);
2436 if (domain)
2437 intel_iommu_attach_device(domain, dev);
2438 }
2439
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002440 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002441 info = dev->archdata.iommu;
Lu Baolu8af46c72019-05-25 13:41:32 +08002442
Peter Xub316d022017-05-22 18:28:51 +08002443 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002444 return info->domain;
2445 return NULL;
2446}
2447
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002448static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002449dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2450{
2451 struct device_domain_info *info;
2452
2453 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002454 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002455 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002456 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002457
2458 return NULL;
2459}
2460
Joerg Roedel5db31562015-07-22 12:40:43 +02002461static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2462 int bus, int devfn,
2463 struct device *dev,
2464 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002465{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002466 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002467 struct device_domain_info *info;
2468 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002469 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002470
2471 info = alloc_devinfo_mem();
2472 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002473 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002474
Jiang Liu745f2582014-02-19 14:07:26 +08002475 info->bus = bus;
2476 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002477 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2478 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2479 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002480 info->dev = dev;
2481 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002482 info->iommu = iommu;
Lu Baolucc580e42018-07-14 15:46:59 +08002483 info->pasid_table = NULL;
Lu Baolu95587a72019-03-25 09:30:30 +08002484 info->auxd_enabled = 0;
Lu Baolu67b8e022019-03-25 09:30:32 +08002485 INIT_LIST_HEAD(&info->auxiliary_domains);
Jiang Liu745f2582014-02-19 14:07:26 +08002486
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002487 if (dev && dev_is_pci(dev)) {
2488 struct pci_dev *pdev = to_pci_dev(info->dev);
2489
Lu Baolud8b85912019-03-01 11:23:10 +08002490 if (!pdev->untrusted &&
2491 !pci_ats_disabled() &&
Gil Kupfercef74402018-05-10 17:56:02 -05002492 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002493 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2494 dmar_find_matched_atsr_unit(pdev))
2495 info->ats_supported = 1;
2496
Lu Baolu765b6a92018-12-10 09:58:55 +08002497 if (sm_supported(iommu)) {
2498 if (pasid_supported(iommu)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002499 int features = pci_pasid_features(pdev);
2500 if (features >= 0)
2501 info->pasid_supported = features | 1;
2502 }
2503
2504 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2505 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2506 info->pri_supported = 1;
2507 }
2508 }
2509
Jiang Liu745f2582014-02-19 14:07:26 +08002510 spin_lock_irqsave(&device_domain_lock, flags);
2511 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002512 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002513
2514 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002515 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002516 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002517 if (info2) {
2518 found = info2->domain;
2519 info2->dev = dev;
2520 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002521 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002522
Jiang Liu745f2582014-02-19 14:07:26 +08002523 if (found) {
2524 spin_unlock_irqrestore(&device_domain_lock, flags);
2525 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002526 /* Caller must free the original domain */
2527 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002528 }
2529
Joerg Roedeld160aca2015-07-22 11:52:53 +02002530 spin_lock(&iommu->lock);
2531 ret = domain_attach_iommu(domain, iommu);
2532 spin_unlock(&iommu->lock);
2533
2534 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002535 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302536 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002537 return NULL;
2538 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002539
David Woodhouseb718cd32014-03-09 13:11:33 -07002540 list_add(&info->link, &domain->devices);
2541 list_add(&info->global, &device_domain_list);
2542 if (dev)
2543 dev->archdata.iommu = info;
Lu Baolu0bbeb012018-12-10 09:58:56 +08002544 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolua7fc93f2018-07-14 15:47:00 +08002545
Lu Baolu0bbeb012018-12-10 09:58:56 +08002546 /* PASID table is mandatory for a PCI device in scalable mode. */
2547 if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
Lu Baolua7fc93f2018-07-14 15:47:00 +08002548 ret = intel_pasid_alloc_table(dev);
2549 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002550 dev_err(dev, "PASID table allocation failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002551 dmar_remove_one_dev_info(dev);
Lu Baolu0bbeb012018-12-10 09:58:56 +08002552 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002553 }
Lu Baoluef848b72018-12-10 09:59:01 +08002554
2555 /* Setup the PASID entry for requests without PASID: */
2556 spin_lock(&iommu->lock);
2557 if (hw_pass_through && domain_type_is_si(domain))
2558 ret = intel_pasid_setup_pass_through(iommu, domain,
2559 dev, PASID_RID2PASID);
2560 else
2561 ret = intel_pasid_setup_second_level(iommu, domain,
2562 dev, PASID_RID2PASID);
2563 spin_unlock(&iommu->lock);
2564 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002565 dev_err(dev, "Setup RID2PASID failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002566 dmar_remove_one_dev_info(dev);
Lu Baoluef848b72018-12-10 09:59:01 +08002567 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002568 }
2569 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002570
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002571 if (dev && domain_context_mapping(domain, dev)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002572 dev_err(dev, "Domain context map failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002573 dmar_remove_one_dev_info(dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002574 return NULL;
2575 }
2576
David Woodhouseb718cd32014-03-09 13:11:33 -07002577 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002578}
2579
Alex Williamson579305f2014-07-03 09:51:43 -06002580static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2581{
2582 *(u16 *)opaque = alias;
2583 return 0;
2584}
2585
Joerg Roedel76208352016-08-25 14:25:12 +02002586static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002587{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06002588 struct device_domain_info *info;
Joerg Roedel76208352016-08-25 14:25:12 +02002589 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002590 struct intel_iommu *iommu;
Lu Baolufcc35c62018-05-04 13:08:17 +08002591 u16 dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002592 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002593 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002594
David Woodhouse146922e2014-03-09 15:44:17 -07002595 iommu = device_to_iommu(dev, &bus, &devfn);
2596 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002597 return NULL;
2598
2599 if (dev_is_pci(dev)) {
2600 struct pci_dev *pdev = to_pci_dev(dev);
2601
2602 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2603
2604 spin_lock_irqsave(&device_domain_lock, flags);
2605 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2606 PCI_BUS_NUM(dma_alias),
2607 dma_alias & 0xff);
2608 if (info) {
2609 iommu = info->iommu;
2610 domain = info->domain;
2611 }
2612 spin_unlock_irqrestore(&device_domain_lock, flags);
2613
Joerg Roedel76208352016-08-25 14:25:12 +02002614 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002615 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002616 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002617 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002618
David Woodhouse146922e2014-03-09 15:44:17 -07002619 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002620 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002621 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002622 return NULL;
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002623 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002624 domain_exit(domain);
2625 return NULL;
2626 }
2627
Joerg Roedel76208352016-08-25 14:25:12 +02002628out:
Joerg Roedel76208352016-08-25 14:25:12 +02002629 return domain;
2630}
2631
2632static struct dmar_domain *set_domain_for_dev(struct device *dev,
2633 struct dmar_domain *domain)
2634{
2635 struct intel_iommu *iommu;
2636 struct dmar_domain *tmp;
2637 u16 req_id, dma_alias;
2638 u8 bus, devfn;
2639
2640 iommu = device_to_iommu(dev, &bus, &devfn);
2641 if (!iommu)
2642 return NULL;
2643
2644 req_id = ((u16)bus << 8) | devfn;
2645
2646 if (dev_is_pci(dev)) {
2647 struct pci_dev *pdev = to_pci_dev(dev);
2648
2649 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2650
2651 /* register PCI DMA alias device */
2652 if (req_id != dma_alias) {
2653 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2654 dma_alias & 0xff, NULL, domain);
2655
2656 if (!tmp || tmp != domain)
2657 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002658 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002659 }
2660
Joerg Roedel5db31562015-07-22 12:40:43 +02002661 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002662 if (!tmp || tmp != domain)
2663 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002664
Joerg Roedel76208352016-08-25 14:25:12 +02002665 return domain;
2666}
2667
David Woodhouseb2132032009-06-26 18:50:28 +01002668static int iommu_domain_identity_map(struct dmar_domain *domain,
2669 unsigned long long start,
2670 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002671{
David Woodhousec5395d52009-06-28 16:35:56 +01002672 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2673 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002674
David Woodhousec5395d52009-06-28 16:35:56 +01002675 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2676 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002677 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002678 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002679 }
2680
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002681 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002682 /*
2683 * RMRR range might have overlap with physical memory range,
2684 * clear it first
2685 */
David Woodhousec5395d52009-06-28 16:35:56 +01002686 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002687
Peter Xu87684fd2018-05-04 10:34:53 +08002688 return __domain_mapping(domain, first_vpfn, NULL,
2689 first_vpfn, last_vpfn - first_vpfn + 1,
2690 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002691}
2692
Joerg Roedeld66ce542015-09-23 19:00:10 +02002693static int domain_prepare_identity_map(struct device *dev,
2694 struct dmar_domain *domain,
2695 unsigned long long start,
2696 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002697{
David Woodhouse19943b02009-08-04 16:19:20 +01002698 /* For _hardware_ passthrough, don't bother. But for software
2699 passthrough, we do it anyway -- it may indicate a memory
2700 range which is reserved in E820, so which didn't get set
2701 up to start with in si_domain */
2702 if (domain == si_domain && hw_pass_through) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002703 dev_warn(dev, "Ignoring identity map for HW passthrough [0x%Lx - 0x%Lx]\n",
2704 start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002705 return 0;
2706 }
2707
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002708 dev_info(dev, "Setting identity map [0x%Lx - 0x%Lx]\n", start, end);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002709
David Woodhouse5595b522009-12-02 09:21:55 +00002710 if (end < start) {
2711 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2712 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2713 dmi_get_system_info(DMI_BIOS_VENDOR),
2714 dmi_get_system_info(DMI_BIOS_VERSION),
2715 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002716 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002717 }
2718
David Woodhouse2ff729f2009-08-26 14:25:41 +01002719 if (end >> agaw_to_width(domain->agaw)) {
2720 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2721 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2722 agaw_to_width(domain->agaw),
2723 dmi_get_system_info(DMI_BIOS_VENDOR),
2724 dmi_get_system_info(DMI_BIOS_VERSION),
2725 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002726 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002727 }
David Woodhouse19943b02009-08-04 16:19:20 +01002728
Joerg Roedeld66ce542015-09-23 19:00:10 +02002729 return iommu_domain_identity_map(domain, start, end);
2730}
2731
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002732static int md_domain_init(struct dmar_domain *domain, int guest_width);
2733
Matt Kraai071e1372009-08-23 22:30:22 -07002734static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002735{
Lu Baolu4de354e2019-05-25 13:41:27 +08002736 struct dmar_rmrr_unit *rmrr;
2737 struct device *dev;
2738 int i, nid, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002739
Jiang Liuab8dfe22014-07-11 14:19:27 +08002740 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002741 if (!si_domain)
2742 return -EFAULT;
2743
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002744 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002745 domain_exit(si_domain);
2746 return -EFAULT;
2747 }
2748
David Woodhouse19943b02009-08-04 16:19:20 +01002749 if (hw)
2750 return 0;
2751
David Woodhousec7ab48d2009-06-26 19:10:36 +01002752 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002753 unsigned long start_pfn, end_pfn;
2754 int i;
2755
2756 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2757 ret = iommu_domain_identity_map(si_domain,
2758 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2759 if (ret)
2760 return ret;
2761 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002762 }
2763
Lu Baolu4de354e2019-05-25 13:41:27 +08002764 /*
2765 * Normally we use DMA domains for devices which have RMRRs. But we
2766 * loose this requirement for graphic and usb devices. Identity map
2767 * the RMRRs for graphic and USB devices so that they could use the
2768 * si_domain.
2769 */
2770 for_each_rmrr_units(rmrr) {
2771 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
2772 i, dev) {
2773 unsigned long long start = rmrr->base_address;
2774 unsigned long long end = rmrr->end_address;
2775
2776 if (device_is_rmrr_locked(dev))
2777 continue;
2778
2779 if (WARN_ON(end < start ||
2780 end >> agaw_to_width(si_domain->agaw)))
2781 continue;
2782
2783 ret = iommu_domain_identity_map(si_domain, start, end);
2784 if (ret)
2785 return ret;
2786 }
2787 }
2788
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002789 return 0;
2790}
2791
David Woodhouse9b226622014-03-09 14:03:28 -07002792static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002793{
2794 struct device_domain_info *info;
2795
David Woodhouse9b226622014-03-09 14:03:28 -07002796 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002797 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2798 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002799
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002800 return 0;
2801}
2802
Joerg Roedel28ccce02015-07-21 14:45:31 +02002803static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002804{
David Woodhouse0ac72662014-03-09 13:19:22 -07002805 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002806 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002807 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002808
David Woodhouse5913c9b2014-03-09 16:27:31 -07002809 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002810 if (!iommu)
2811 return -ENODEV;
2812
Joerg Roedel5db31562015-07-22 12:40:43 +02002813 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002814 if (ndomain != domain)
2815 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002816
2817 return 0;
2818}
2819
David Woodhouse0b9d9752014-03-09 15:48:15 -07002820static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002821{
2822 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002823 struct device *tmp;
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002824 int i;
2825
Jiang Liu0e242612014-02-19 14:07:34 +08002826 rcu_read_lock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002827 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002828 /*
2829 * Return TRUE if this RMRR contains the device that
2830 * is passed in.
2831 */
2832 for_each_active_dev_scope(rmrr->devices,
2833 rmrr->devices_cnt, i, tmp)
Eric Augere143fd42019-06-03 08:53:33 +02002834 if (tmp == dev ||
2835 is_downstream_to_pci_bridge(dev, tmp)) {
Jiang Liu0e242612014-02-19 14:07:34 +08002836 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002837 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002838 }
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002839 }
Jiang Liu0e242612014-02-19 14:07:34 +08002840 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002841 return false;
2842}
2843
Eric Auger1c5c59f2019-06-03 08:53:36 +02002844/**
2845 * device_rmrr_is_relaxable - Test whether the RMRR of this device
2846 * is relaxable (ie. is allowed to be not enforced under some conditions)
2847 * @dev: device handle
2848 *
2849 * We assume that PCI USB devices with RMRRs have them largely
2850 * for historical reasons and that the RMRR space is not actively used post
2851 * boot. This exclusion may change if vendors begin to abuse it.
2852 *
2853 * The same exception is made for graphics devices, with the requirement that
2854 * any use of the RMRR regions will be torn down before assigning the device
2855 * to a guest.
2856 *
2857 * Return: true if the RMRR is relaxable, false otherwise
2858 */
2859static bool device_rmrr_is_relaxable(struct device *dev)
2860{
2861 struct pci_dev *pdev;
2862
2863 if (!dev_is_pci(dev))
2864 return false;
2865
2866 pdev = to_pci_dev(dev);
2867 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
2868 return true;
2869 else
2870 return false;
2871}
2872
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002873/*
2874 * There are a couple cases where we need to restrict the functionality of
2875 * devices associated with RMRRs. The first is when evaluating a device for
2876 * identity mapping because problems exist when devices are moved in and out
2877 * of domains and their respective RMRR information is lost. This means that
2878 * a device with associated RMRRs will never be in a "passthrough" domain.
2879 * The second is use of the device through the IOMMU API. This interface
2880 * expects to have full control of the IOVA space for the device. We cannot
2881 * satisfy both the requirement that RMRR access is maintained and have an
2882 * unencumbered IOVA space. We also have no ability to quiesce the device's
2883 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2884 * We therefore prevent devices associated with an RMRR from participating in
2885 * the IOMMU API, which eliminates them from device assignment.
2886 *
Eric Auger1c5c59f2019-06-03 08:53:36 +02002887 * In both cases, devices which have relaxable RMRRs are not concerned by this
2888 * restriction. See device_rmrr_is_relaxable comment.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002889 */
2890static bool device_is_rmrr_locked(struct device *dev)
2891{
2892 if (!device_has_rmrr(dev))
2893 return false;
2894
Eric Auger1c5c59f2019-06-03 08:53:36 +02002895 if (device_rmrr_is_relaxable(dev))
2896 return false;
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002897
2898 return true;
2899}
2900
Lu Baoluf273a452019-05-25 13:41:26 +08002901/*
2902 * Return the required default domain type for a specific device.
2903 *
2904 * @dev: the device in query
2905 * @startup: true if this is during early boot
2906 *
2907 * Returns:
2908 * - IOMMU_DOMAIN_DMA: device requires a dynamic mapping domain
2909 * - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
2910 * - 0: both identity and dynamic domains work for this device
2911 */
Lu Baolu0e31a722019-05-25 13:41:34 +08002912static int device_def_domain_type(struct device *dev)
David Woodhouse6941af22009-07-04 18:24:27 +01002913{
David Woodhouse3bdb2592014-03-09 16:03:08 -07002914 if (dev_is_pci(dev)) {
2915 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002916
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002917 if (device_is_rmrr_locked(dev))
Lu Baoluf273a452019-05-25 13:41:26 +08002918 return IOMMU_DOMAIN_DMA;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002919
Lu Baolu89a60792018-10-23 15:45:01 +08002920 /*
2921 * Prevent any device marked as untrusted from getting
2922 * placed into the statically identity mapping domain.
2923 */
2924 if (pdev->untrusted)
Lu Baoluf273a452019-05-25 13:41:26 +08002925 return IOMMU_DOMAIN_DMA;
Lu Baolu89a60792018-10-23 15:45:01 +08002926
David Woodhouse3bdb2592014-03-09 16:03:08 -07002927 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002928 return IOMMU_DOMAIN_IDENTITY;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002929
David Woodhouse3bdb2592014-03-09 16:03:08 -07002930 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08002931 return IOMMU_DOMAIN_IDENTITY;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002932
2933 /*
2934 * We want to start off with all devices in the 1:1 domain, and
2935 * take them out later if we find they can't access all of memory.
2936 *
2937 * However, we can't do this for PCI devices behind bridges,
2938 * because all PCI devices behind the same bridge will end up
2939 * with the same source-id on their transactions.
2940 *
2941 * Practically speaking, we can't change things around for these
2942 * devices at run-time, because we can't be sure there'll be no
2943 * DMA transactions in flight for any of their siblings.
2944 *
2945 * So PCI devices (unless they're on the root bus) as well as
2946 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2947 * the 1:1 domain, just in _case_ one of their siblings turns out
2948 * not to be able to map all of memory.
2949 */
2950 if (!pci_is_pcie(pdev)) {
2951 if (!pci_is_root_bus(pdev->bus))
Lu Baoluf273a452019-05-25 13:41:26 +08002952 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002953 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
Lu Baoluf273a452019-05-25 13:41:26 +08002954 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002955 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
Lu Baoluf273a452019-05-25 13:41:26 +08002956 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002957 } else {
2958 if (device_has_rmrr(dev))
Lu Baoluf273a452019-05-25 13:41:26 +08002959 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07002960 }
David Woodhouse6941af22009-07-04 18:24:27 +01002961
Lu Baoluf273a452019-05-25 13:41:26 +08002962 return (iommu_identity_mapping & IDENTMAP_ALL) ?
2963 IOMMU_DOMAIN_IDENTITY : 0;
2964}
2965
Jiang Liuffebeb42014-11-09 22:48:02 +08002966static void intel_iommu_init_qi(struct intel_iommu *iommu)
2967{
2968 /*
2969 * Start from the sane iommu hardware state.
2970 * If the queued invalidation is already initialized by us
2971 * (for example, while enabling interrupt-remapping) then
2972 * we got the things already rolling from a sane state.
2973 */
2974 if (!iommu->qi) {
2975 /*
2976 * Clear any previous faults.
2977 */
2978 dmar_fault(-1, iommu);
2979 /*
2980 * Disable queued invalidation if supported and already enabled
2981 * before OS handover.
2982 */
2983 dmar_disable_qi(iommu);
2984 }
2985
2986 if (dmar_enable_qi(iommu)) {
2987 /*
2988 * Queued Invalidate not enabled, use Register Based Invalidate
2989 */
2990 iommu->flush.flush_context = __iommu_flush_context;
2991 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002992 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08002993 iommu->name);
2994 } else {
2995 iommu->flush.flush_context = qi_flush_context;
2996 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002997 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08002998 }
2999}
3000
Joerg Roedel091d42e2015-06-12 11:56:10 +02003001static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb962015-10-09 18:16:46 -04003002 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003003 struct context_entry **tbl,
3004 int bus, bool ext)
3005{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003006 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003007 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb962015-10-09 18:16:46 -04003008 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003009 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003010 phys_addr_t old_ce_phys;
3011
3012 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb962015-10-09 18:16:46 -04003013 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003014
3015 for (devfn = 0; devfn < 256; devfn++) {
3016 /* First calculate the correct index */
3017 idx = (ext ? devfn * 2 : devfn) % 256;
3018
3019 if (idx == 0) {
3020 /* First save what we may have and clean up */
3021 if (new_ce) {
3022 tbl[tbl_idx] = new_ce;
3023 __iommu_flush_cache(iommu, new_ce,
3024 VTD_PAGE_SIZE);
3025 pos = 1;
3026 }
3027
3028 if (old_ce)
Pan Bian829383e2018-11-21 17:53:47 +08003029 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003030
3031 ret = 0;
3032 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003033 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003034 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003035 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003036
3037 if (!old_ce_phys) {
3038 if (ext && devfn == 0) {
3039 /* No LCTP, try UCTP */
3040 devfn = 0x7f;
3041 continue;
3042 } else {
3043 goto out;
3044 }
3045 }
3046
3047 ret = -ENOMEM;
Dan Williamsdfddb962015-10-09 18:16:46 -04003048 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3049 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003050 if (!old_ce)
3051 goto out;
3052
3053 new_ce = alloc_pgtable_page(iommu->node);
3054 if (!new_ce)
3055 goto out_unmap;
3056
3057 ret = 0;
3058 }
3059
3060 /* Now copy the context entry */
Dan Williamsdfddb962015-10-09 18:16:46 -04003061 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003062
Joerg Roedelcf484d02015-06-12 12:21:46 +02003063 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003064 continue;
3065
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003066 did = context_domain_id(&ce);
3067 if (did >= 0 && did < cap_ndoms(iommu->cap))
3068 set_bit(did, iommu->domain_ids);
3069
Joerg Roedelcf484d02015-06-12 12:21:46 +02003070 /*
3071 * We need a marker for copied context entries. This
3072 * marker needs to work for the old format as well as
3073 * for extended context entries.
3074 *
3075 * Bit 67 of the context entry is used. In the old
3076 * format this bit is available to software, in the
3077 * extended format it is the PGE bit, but PGE is ignored
3078 * by HW if PASIDs are disabled (and thus still
3079 * available).
3080 *
3081 * So disable PASIDs first and then mark the entry
3082 * copied. This means that we don't copy PASID
3083 * translations from the old kernel, but this is fine as
3084 * faults there are not fatal.
3085 */
3086 context_clear_pasid_enable(&ce);
3087 context_set_copied(&ce);
3088
Joerg Roedel091d42e2015-06-12 11:56:10 +02003089 new_ce[idx] = ce;
3090 }
3091
3092 tbl[tbl_idx + pos] = new_ce;
3093
3094 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3095
3096out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003097 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003098
3099out:
3100 return ret;
3101}
3102
3103static int copy_translation_tables(struct intel_iommu *iommu)
3104{
3105 struct context_entry **ctxt_tbls;
Dan Williamsdfddb962015-10-09 18:16:46 -04003106 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003107 phys_addr_t old_rt_phys;
3108 int ctxt_table_entries;
3109 unsigned long flags;
3110 u64 rtaddr_reg;
3111 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003112 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003113
3114 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3115 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003116 new_ext = !!ecap_ecs(iommu->ecap);
3117
3118 /*
3119 * The RTT bit can only be changed when translation is disabled,
3120 * but disabling translation means to open a window for data
3121 * corruption. So bail out and don't copy anything if we would
3122 * have to change the bit.
3123 */
3124 if (new_ext != ext)
3125 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003126
3127 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3128 if (!old_rt_phys)
3129 return -EINVAL;
3130
Dan Williamsdfddb962015-10-09 18:16:46 -04003131 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003132 if (!old_rt)
3133 return -ENOMEM;
3134
3135 /* This is too big for the stack - allocate it from slab */
3136 ctxt_table_entries = ext ? 512 : 256;
3137 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003138 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003139 if (!ctxt_tbls)
3140 goto out_unmap;
3141
3142 for (bus = 0; bus < 256; bus++) {
3143 ret = copy_context_table(iommu, &old_rt[bus],
3144 ctxt_tbls, bus, ext);
3145 if (ret) {
3146 pr_err("%s: Failed to copy context table for bus %d\n",
3147 iommu->name, bus);
3148 continue;
3149 }
3150 }
3151
3152 spin_lock_irqsave(&iommu->lock, flags);
3153
3154 /* Context tables are copied, now write them to the root_entry table */
3155 for (bus = 0; bus < 256; bus++) {
3156 int idx = ext ? bus * 2 : bus;
3157 u64 val;
3158
3159 if (ctxt_tbls[idx]) {
3160 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3161 iommu->root_entry[bus].lo = val;
3162 }
3163
3164 if (!ext || !ctxt_tbls[idx + 1])
3165 continue;
3166
3167 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3168 iommu->root_entry[bus].hi = val;
3169 }
3170
3171 spin_unlock_irqrestore(&iommu->lock, flags);
3172
3173 kfree(ctxt_tbls);
3174
3175 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3176
3177 ret = 0;
3178
3179out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003180 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003181
3182 return ret;
3183}
3184
Joseph Cihulab7792602011-05-03 00:08:37 -07003185static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003186{
3187 struct dmar_drhd_unit *drhd;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003188 struct intel_iommu *iommu;
Lu Baoludf4f3c62019-05-25 13:41:36 +08003189 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003190
3191 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003192 * for each drhd
3193 * allocate root
3194 * initialize and program root entry to not present
3195 * endfor
3196 */
3197 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003198 /*
3199 * lock not needed as this is only incremented in the single
3200 * threaded kernel __init code path all other access are read
3201 * only
3202 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003203 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003204 g_num_of_iommus++;
3205 continue;
3206 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003207 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003208 }
3209
Jiang Liuffebeb42014-11-09 22:48:02 +08003210 /* Preallocate enough resources for IOMMU hot-addition */
3211 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3212 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3213
Weidong Hand9630fe2008-12-08 11:06:32 +08003214 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3215 GFP_KERNEL);
3216 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003217 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003218 ret = -ENOMEM;
3219 goto error;
3220 }
3221
Lu Baolu6a8c6742019-06-12 08:28:47 +08003222 for_each_iommu(iommu, drhd) {
3223 if (drhd->ignored) {
3224 iommu_disable_translation(iommu);
3225 continue;
3226 }
3227
Lu Baolu56283172018-07-14 15:46:54 +08003228 /*
3229 * Find the max pasid size of all IOMMU's in the system.
3230 * We need to ensure the system pasid table is no bigger
3231 * than the smallest supported.
3232 */
Lu Baolu765b6a92018-12-10 09:58:55 +08003233 if (pasid_supported(iommu)) {
Lu Baolu56283172018-07-14 15:46:54 +08003234 u32 temp = 2 << ecap_pss(iommu->ecap);
3235
3236 intel_pasid_max_id = min_t(u32, temp,
3237 intel_pasid_max_id);
3238 }
3239
Weidong Hand9630fe2008-12-08 11:06:32 +08003240 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003241
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003242 intel_iommu_init_qi(iommu);
3243
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003244 ret = iommu_init_domains(iommu);
3245 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003246 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003247
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003248 init_translation_status(iommu);
3249
Joerg Roedel091d42e2015-06-12 11:56:10 +02003250 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3251 iommu_disable_translation(iommu);
3252 clear_translation_pre_enabled(iommu);
3253 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3254 iommu->name);
3255 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003256
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003257 /*
3258 * TBD:
3259 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003260 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003261 */
3262 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003263 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003264 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003265
Joerg Roedel091d42e2015-06-12 11:56:10 +02003266 if (translation_pre_enabled(iommu)) {
3267 pr_info("Translation already enabled - trying to copy translation structures\n");
3268
3269 ret = copy_translation_tables(iommu);
3270 if (ret) {
3271 /*
3272 * We found the IOMMU with translation
3273 * enabled - but failed to copy over the
3274 * old root-entry table. Try to proceed
3275 * by disabling translation now and
3276 * allocating a clean root-entry table.
3277 * This might cause DMAR faults, but
3278 * probably the dump will still succeed.
3279 */
3280 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3281 iommu->name);
3282 iommu_disable_translation(iommu);
3283 clear_translation_pre_enabled(iommu);
3284 } else {
3285 pr_info("Copied translation tables from previous kernel for %s\n",
3286 iommu->name);
3287 }
3288 }
3289
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003290 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003291 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003292#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003293 if (pasid_supported(iommu))
Lu Baolud9737952018-07-14 15:47:02 +08003294 intel_svm_init(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00003295#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003296 }
3297
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003298 /*
3299 * Now that qi is enabled on all iommus, set the root entry and flush
3300 * caches. This is required on some Intel X58 chipsets, otherwise the
3301 * flush_context function will loop forever and the boot hangs.
3302 */
3303 for_each_active_iommu(iommu, drhd) {
3304 iommu_flush_write_buffer(iommu);
3305 iommu_set_root_entry(iommu);
3306 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3307 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3308 }
3309
Joerg Roedel6b9a7d32019-08-19 15:22:50 +02003310 if (iommu_default_passthrough())
David Woodhousee0fc7e02009-09-30 09:12:17 -07003311 iommu_identity_mapping |= IDENTMAP_ALL;
3312
Suresh Siddhad3f13812011-08-23 17:05:25 -07003313#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
Lu Baolu5daab582019-05-02 09:34:26 +08003314 dmar_map_gfx = 0;
David Woodhouse19943b02009-08-04 16:19:20 +01003315#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003316
Lu Baolu5daab582019-05-02 09:34:26 +08003317 if (!dmar_map_gfx)
3318 iommu_identity_mapping |= IDENTMAP_GFX;
3319
Ashok Raj21e722c2017-01-30 09:39:53 -08003320 check_tylersburg_isoch();
3321
Lu Baolu4de354e2019-05-25 13:41:27 +08003322 ret = si_domain_init(hw_pass_through);
3323 if (ret)
3324 goto free_iommu;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003325
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003326 /*
3327 * for each drhd
3328 * enable fault log
3329 * global invalidate context cache
3330 * global invalidate iotlb
3331 * enable translation
3332 */
Jiang Liu7c919772014-01-06 14:18:18 +08003333 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003334 if (drhd->ignored) {
3335 /*
3336 * we always have to disable PMRs or DMA may fail on
3337 * this device
3338 */
3339 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003340 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003341 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003342 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003343
3344 iommu_flush_write_buffer(iommu);
3345
David Woodhousea222a7f2015-10-07 23:35:18 +01003346#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003347 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
Lu Baolua7755c32019-04-19 14:43:29 +08003348 /*
3349 * Call dmar_alloc_hwirq() with dmar_global_lock held,
3350 * could cause possible lock race condition.
3351 */
3352 up_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003353 ret = intel_svm_enable_prq(iommu);
Lu Baolua7755c32019-04-19 14:43:29 +08003354 down_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003355 if (ret)
3356 goto free_iommu;
3357 }
3358#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003359 ret = dmar_set_interrupt(iommu);
3360 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003361 goto free_iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003362 }
3363
3364 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003365
3366free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003367 for_each_active_iommu(iommu, drhd) {
3368 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003369 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003370 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003371
Weidong Hand9630fe2008-12-08 11:06:32 +08003372 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003373
Jiang Liu989d51f2014-02-19 14:07:21 +08003374error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003375 return ret;
3376}
3377
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003378/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003379static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003380 struct dmar_domain *domain,
3381 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003382{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06003383 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003384
David Woodhouse875764d2009-06-28 21:20:51 +01003385 /* Restrict dma_mask to the width that the iommu can handle */
3386 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003387 /* Ensure we reserve the whole size-aligned region */
3388 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003389
3390 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003391 /*
3392 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003393 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003394 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003395 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003396 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003397 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003398 if (iova_pfn)
3399 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003400 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003401 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3402 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003403 if (unlikely(!iova_pfn)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003404 dev_err(dev, "Allocating %ld-page iova failed", nrpages);
Omer Peleg2aac6302016-04-20 11:33:57 +03003405 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003406 }
3407
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003408 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003409}
3410
Lu Baolu4ec066c2019-05-25 13:41:33 +08003411static struct dmar_domain *get_private_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003412{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003413 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003414 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003415 struct device *i_dev;
3416 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003417
Lu Baolu4ec066c2019-05-25 13:41:33 +08003418 /* Device shouldn't be attached by any domains. */
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003419 domain = find_domain(dev);
3420 if (domain)
Lu Baolu4ec066c2019-05-25 13:41:33 +08003421 return NULL;
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003422
3423 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3424 if (!domain)
3425 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003426
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003427 /* We have a new domain - setup possible RMRRs for the device */
3428 rcu_read_lock();
3429 for_each_rmrr_units(rmrr) {
3430 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3431 i, i_dev) {
3432 if (i_dev != dev)
3433 continue;
3434
3435 ret = domain_prepare_identity_map(dev, domain,
3436 rmrr->base_address,
3437 rmrr->end_address);
3438 if (ret)
3439 dev_err(dev, "Mapping reserved region failed\n");
3440 }
3441 }
3442 rcu_read_unlock();
3443
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003444 tmp = set_domain_for_dev(dev, domain);
3445 if (!tmp || domain != tmp) {
3446 domain_exit(domain);
3447 domain = tmp;
3448 }
3449
3450out:
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003451 if (!domain)
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003452 dev_err(dev, "Allocating domain failed\n");
Lu Baoluc57b2602019-06-12 08:28:46 +08003453 else
3454 domain->domain.type = IOMMU_DOMAIN_DMA;
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003455
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003456 return domain;
3457}
3458
David Woodhouseecb509e2014-03-09 16:29:55 -07003459/* Check if the dev needs to go through non-identity map and unmap process.*/
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003460static bool iommu_need_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003461{
Lu Baolu98b2fff2019-05-25 13:41:30 +08003462 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003463
David Woodhouse3d891942014-03-06 15:59:26 +00003464 if (iommu_dummy(dev))
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003465 return false;
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003466
Lu Baolu98b2fff2019-05-25 13:41:30 +08003467 ret = identity_mapping(dev);
3468 if (ret) {
3469 u64 dma_mask = *dev->dma_mask;
3470
3471 if (dev->coherent_dma_mask && dev->coherent_dma_mask < dma_mask)
3472 dma_mask = dev->coherent_dma_mask;
3473
3474 if (dma_mask >= dma_get_required_mask(dev))
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003475 return false;
3476
3477 /*
3478 * 32 bit DMA is removed from si_domain and fall back to
3479 * non-identity mapping.
3480 */
3481 dmar_remove_one_dev_info(dev);
Lu Baolu98b2fff2019-05-25 13:41:30 +08003482 ret = iommu_request_dma_domain_for_dev(dev);
3483 if (ret) {
3484 struct iommu_domain *domain;
3485 struct dmar_domain *dmar_domain;
3486
3487 domain = iommu_get_domain_for_dev(dev);
3488 if (domain) {
3489 dmar_domain = to_dmar_domain(domain);
3490 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
3491 }
Lu Baoluae23bfb62019-08-06 08:14:08 +08003492 dmar_remove_one_dev_info(dev);
Lu Baolu4ec066c2019-05-25 13:41:33 +08003493 get_private_domain_for_dev(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003494 }
Lu Baolu98b2fff2019-05-25 13:41:30 +08003495
3496 dev_info(dev, "32bit DMA uses non-identity mapping\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003497 }
3498
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003499 return true;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003500}
3501
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003502static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
3503 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003504{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003505 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003506 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003507 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003508 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003509 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003510 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003511 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003512
3513 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003514
Lu Baolu4ec066c2019-05-25 13:41:33 +08003515 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003516 if (!domain)
Christoph Hellwig524a6692018-11-21 19:34:10 +01003517 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003518
Weidong Han8c11e792008-12-08 15:29:22 +08003519 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003520 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003521
Omer Peleg2aac6302016-04-20 11:33:57 +03003522 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3523 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003524 goto error;
3525
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003526 /*
3527 * Check if DMAR supports zero-length reads on write only
3528 * mappings..
3529 */
3530 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003531 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003532 prot |= DMA_PTE_READ;
3533 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3534 prot |= DMA_PTE_WRITE;
3535 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003536 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003537 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003538 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003539 * is not a big problem
3540 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003541 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003542 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003543 if (ret)
3544 goto error;
3545
Omer Peleg2aac6302016-04-20 11:33:57 +03003546 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003547 start_paddr += paddr & ~PAGE_MASK;
Lu Baolu3b530342019-09-06 14:14:51 +08003548
3549 trace_map_single(dev, start_paddr, paddr, size << VTD_PAGE_SHIFT);
3550
David Woodhouse03d6a242009-06-28 15:33:46 +01003551 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003552
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003553error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003554 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003555 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003556 dev_err(dev, "Device request: %zx@%llx dir %d --- failed\n",
3557 size, (unsigned long long)paddr, dir);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003558 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003559}
3560
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003561static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3562 unsigned long offset, size_t size,
3563 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003564 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003565{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003566 if (iommu_need_mapping(dev))
3567 return __intel_map_single(dev, page_to_phys(page) + offset,
3568 size, dir, *dev->dma_mask);
3569 return dma_direct_map_page(dev, page, offset, size, dir, attrs);
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003570}
3571
3572static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
3573 size_t size, enum dma_data_direction dir,
3574 unsigned long attrs)
3575{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003576 if (iommu_need_mapping(dev))
3577 return __intel_map_single(dev, phys_addr, size, dir,
3578 *dev->dma_mask);
3579 return dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003580}
3581
Omer Peleg769530e2016-04-20 11:33:25 +03003582static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003583{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003584 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003585 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003586 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003587 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003588 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003589 struct page *freelist;
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003590 struct pci_dev *pdev = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003591
David Woodhouse1525a292014-03-06 16:19:30 +00003592 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003593 BUG_ON(!domain);
3594
Weidong Han8c11e792008-12-08 15:29:22 +08003595 iommu = domain_get_iommu(domain);
3596
Omer Peleg2aac6302016-04-20 11:33:57 +03003597 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003598
Omer Peleg769530e2016-04-20 11:33:25 +03003599 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003600 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003601 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003602
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003603 if (dev_is_pci(dev))
3604 pdev = to_pci_dev(dev);
3605
David Woodhouseea8ea462014-03-05 17:09:32 +00003606 freelist = domain_unmap(domain, start_pfn, last_pfn);
Dmitry Safonoveffa4672019-07-16 22:38:05 +01003607 if (intel_iommu_strict || (pdev && pdev->untrusted) ||
3608 !has_iova_flush_queue(&domain->iovad)) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003609 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003610 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003611 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003612 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003613 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003614 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003615 queue_iova(&domain->iovad, iova_pfn, nrpages,
3616 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003617 /*
3618 * queue up the release of the unmap to save the 1/6th of the
3619 * cpu used up by the iotlb flush operation...
3620 */
mark gross5e0d2a62008-03-04 15:22:08 -08003621 }
Lu Baolu3b530342019-09-06 14:14:51 +08003622
3623 trace_unmap_single(dev, dev_addr, size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003624}
3625
Jiang Liud41a4ad2014-07-11 14:19:34 +08003626static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3627 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003628 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003629{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003630 if (iommu_need_mapping(dev))
3631 intel_unmap(dev, dev_addr, size);
3632 else
3633 dma_direct_unmap_page(dev, dev_addr, size, dir, attrs);
3634}
3635
3636static void intel_unmap_resource(struct device *dev, dma_addr_t dev_addr,
3637 size_t size, enum dma_data_direction dir, unsigned long attrs)
3638{
3639 if (iommu_need_mapping(dev))
3640 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003641}
3642
David Woodhouse5040a912014-03-09 16:14:00 -07003643static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003644 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003645 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003646{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003647 struct page *page = NULL;
3648 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003649
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003650 if (!iommu_need_mapping(dev))
3651 return dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3652
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003653 size = PAGE_ALIGN(size);
3654 order = get_order(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003655
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003656 if (gfpflags_allow_blocking(flags)) {
3657 unsigned int count = size >> PAGE_SHIFT;
3658
Marek Szyprowskid834c5a2018-08-17 15:49:00 -07003659 page = dma_alloc_from_contiguous(dev, count, order,
3660 flags & __GFP_NOWARN);
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003661 }
3662
3663 if (!page)
3664 page = alloc_pages(flags, order);
3665 if (!page)
3666 return NULL;
3667 memset(page_address(page), 0, size);
3668
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003669 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3670 DMA_BIDIRECTIONAL,
3671 dev->coherent_dma_mask);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003672 if (*dma_handle != DMA_MAPPING_ERROR)
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003673 return page_address(page);
3674 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3675 __free_pages(page, order);
3676
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003677 return NULL;
3678}
3679
David Woodhouse5040a912014-03-09 16:14:00 -07003680static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003681 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003682{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003683 int order;
3684 struct page *page = virt_to_page(vaddr);
3685
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003686 if (!iommu_need_mapping(dev))
3687 return dma_direct_free(dev, size, vaddr, dma_handle, attrs);
3688
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003689 size = PAGE_ALIGN(size);
3690 order = get_order(size);
3691
3692 intel_unmap(dev, dma_handle, size);
3693 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3694 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003695}
3696
David Woodhouse5040a912014-03-09 16:14:00 -07003697static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003698 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003699 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003700{
Omer Peleg769530e2016-04-20 11:33:25 +03003701 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3702 unsigned long nrpages = 0;
3703 struct scatterlist *sg;
3704 int i;
3705
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003706 if (!iommu_need_mapping(dev))
3707 return dma_direct_unmap_sg(dev, sglist, nelems, dir, attrs);
3708
Omer Peleg769530e2016-04-20 11:33:25 +03003709 for_each_sg(sglist, sg, nelems, i) {
3710 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3711 }
3712
3713 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Lu Baolu3b530342019-09-06 14:14:51 +08003714
3715 trace_unmap_sg(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003716}
3717
David Woodhouse5040a912014-03-09 16:14:00 -07003718static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003719 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003720{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003721 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003722 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003723 size_t size = 0;
3724 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003725 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003726 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003727 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003728 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003729 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003730
3731 BUG_ON(dir == DMA_NONE);
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003732 if (!iommu_need_mapping(dev))
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003733 return dma_direct_map_sg(dev, sglist, nelems, dir, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003734
Lu Baolu4ec066c2019-05-25 13:41:33 +08003735 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003736 if (!domain)
3737 return 0;
3738
Weidong Han8c11e792008-12-08 15:29:22 +08003739 iommu = domain_get_iommu(domain);
3740
David Woodhouseb536d242009-06-28 14:49:31 +01003741 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003742 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003743
Omer Peleg2aac6302016-04-20 11:33:57 +03003744 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003745 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003746 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003747 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003748 return 0;
3749 }
3750
3751 /*
3752 * Check if DMAR supports zero-length reads on write only
3753 * mappings..
3754 */
3755 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003756 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003757 prot |= DMA_PTE_READ;
3758 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3759 prot |= DMA_PTE_WRITE;
3760
Omer Peleg2aac6302016-04-20 11:33:57 +03003761 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003762
Fenghua Yuf5329592009-08-04 15:09:37 -07003763 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003764 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003765 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003766 start_vpfn + size - 1,
3767 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003768 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003769 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003770 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003771
Lu Baolu3b530342019-09-06 14:14:51 +08003772 trace_map_sg(dev, iova_pfn << PAGE_SHIFT,
3773 sg_phys(sglist), size << VTD_PAGE_SHIFT);
3774
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003775 return nelems;
3776}
3777
Christoph Hellwig02b4da52018-09-17 19:10:31 +02003778static const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003779 .alloc = intel_alloc_coherent,
3780 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003781 .map_sg = intel_map_sg,
3782 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003783 .map_page = intel_map_page,
3784 .unmap_page = intel_unmap_page,
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003785 .map_resource = intel_map_resource,
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003786 .unmap_resource = intel_unmap_resource,
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003787 .dma_supported = dma_direct_supported,
Christoph Hellwigf9f32322019-08-06 15:01:50 +03003788 .mmap = dma_common_mmap,
3789 .get_sgtable = dma_common_get_sgtable,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003790};
3791
Lu Baolucfb94a32019-09-06 14:14:52 +08003792static void
3793bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size,
3794 enum dma_data_direction dir, enum dma_sync_target target)
3795{
3796 struct dmar_domain *domain;
3797 phys_addr_t tlb_addr;
3798
3799 domain = find_domain(dev);
3800 if (WARN_ON(!domain))
3801 return;
3802
3803 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr);
3804 if (is_swiotlb_buffer(tlb_addr))
3805 swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target);
3806}
3807
3808static dma_addr_t
3809bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
3810 enum dma_data_direction dir, unsigned long attrs,
3811 u64 dma_mask)
3812{
3813 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3814 struct dmar_domain *domain;
3815 struct intel_iommu *iommu;
3816 unsigned long iova_pfn;
3817 unsigned long nrpages;
3818 phys_addr_t tlb_addr;
3819 int prot = 0;
3820 int ret;
3821
3822 domain = find_domain(dev);
3823 if (WARN_ON(dir == DMA_NONE || !domain))
3824 return DMA_MAPPING_ERROR;
3825
3826 iommu = domain_get_iommu(domain);
3827 if (WARN_ON(!iommu))
3828 return DMA_MAPPING_ERROR;
3829
3830 nrpages = aligned_nrpages(0, size);
3831 iova_pfn = intel_alloc_iova(dev, domain,
3832 dma_to_mm_pfn(nrpages), dma_mask);
3833 if (!iova_pfn)
3834 return DMA_MAPPING_ERROR;
3835
3836 /*
3837 * Check if DMAR supports zero-length reads on write only
3838 * mappings..
3839 */
3840 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ||
3841 !cap_zlr(iommu->cap))
3842 prot |= DMA_PTE_READ;
3843 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3844 prot |= DMA_PTE_WRITE;
3845
3846 /*
3847 * If both the physical buffer start address and size are
3848 * page aligned, we don't need to use a bounce page.
3849 */
3850 if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
3851 tlb_addr = swiotlb_tbl_map_single(dev,
3852 __phys_to_dma(dev, io_tlb_start),
3853 paddr, size, aligned_size, dir, attrs);
3854 if (tlb_addr == DMA_MAPPING_ERROR) {
3855 goto swiotlb_error;
3856 } else {
3857 /* Cleanup the padding area. */
3858 void *padding_start = phys_to_virt(tlb_addr);
3859 size_t padding_size = aligned_size;
3860
3861 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
3862 (dir == DMA_TO_DEVICE ||
3863 dir == DMA_BIDIRECTIONAL)) {
3864 padding_start += size;
3865 padding_size -= size;
3866 }
3867
3868 memset(padding_start, 0, padding_size);
3869 }
3870 } else {
3871 tlb_addr = paddr;
3872 }
3873
3874 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
3875 tlb_addr >> VTD_PAGE_SHIFT, nrpages, prot);
3876 if (ret)
3877 goto mapping_error;
3878
3879 trace_bounce_map_single(dev, iova_pfn << PAGE_SHIFT, paddr, size);
3880
3881 return (phys_addr_t)iova_pfn << PAGE_SHIFT;
3882
3883mapping_error:
3884 if (is_swiotlb_buffer(tlb_addr))
3885 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3886 aligned_size, dir, attrs);
3887swiotlb_error:
3888 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
3889 dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n",
3890 size, (unsigned long long)paddr, dir);
3891
3892 return DMA_MAPPING_ERROR;
3893}
3894
3895static void
3896bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
3897 enum dma_data_direction dir, unsigned long attrs)
3898{
3899 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3900 struct dmar_domain *domain;
3901 phys_addr_t tlb_addr;
3902
3903 domain = find_domain(dev);
3904 if (WARN_ON(!domain))
3905 return;
3906
3907 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, dev_addr);
3908 if (WARN_ON(!tlb_addr))
3909 return;
3910
3911 intel_unmap(dev, dev_addr, size);
3912 if (is_swiotlb_buffer(tlb_addr))
3913 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
3914 aligned_size, dir, attrs);
3915
3916 trace_bounce_unmap_single(dev, dev_addr, size);
3917}
3918
3919static dma_addr_t
3920bounce_map_page(struct device *dev, struct page *page, unsigned long offset,
3921 size_t size, enum dma_data_direction dir, unsigned long attrs)
3922{
3923 return bounce_map_single(dev, page_to_phys(page) + offset,
3924 size, dir, attrs, *dev->dma_mask);
3925}
3926
3927static dma_addr_t
3928bounce_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
3929 enum dma_data_direction dir, unsigned long attrs)
3930{
3931 return bounce_map_single(dev, phys_addr, size,
3932 dir, attrs, *dev->dma_mask);
3933}
3934
3935static void
3936bounce_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size,
3937 enum dma_data_direction dir, unsigned long attrs)
3938{
3939 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3940}
3941
3942static void
3943bounce_unmap_resource(struct device *dev, dma_addr_t dev_addr, size_t size,
3944 enum dma_data_direction dir, unsigned long attrs)
3945{
3946 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
3947}
3948
3949static void
3950bounce_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3951 enum dma_data_direction dir, unsigned long attrs)
3952{
3953 struct scatterlist *sg;
3954 int i;
3955
3956 for_each_sg(sglist, sg, nelems, i)
3957 bounce_unmap_page(dev, sg->dma_address,
3958 sg_dma_len(sg), dir, attrs);
3959}
3960
3961static int
3962bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
3963 enum dma_data_direction dir, unsigned long attrs)
3964{
3965 int i;
3966 struct scatterlist *sg;
3967
3968 for_each_sg(sglist, sg, nelems, i) {
3969 sg->dma_address = bounce_map_page(dev, sg_page(sg),
3970 sg->offset, sg->length,
3971 dir, attrs);
3972 if (sg->dma_address == DMA_MAPPING_ERROR)
3973 goto out_unmap;
3974 sg_dma_len(sg) = sg->length;
3975 }
3976
3977 return nelems;
3978
3979out_unmap:
3980 bounce_unmap_sg(dev, sglist, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
3981 return 0;
3982}
3983
3984static void
3985bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
3986 size_t size, enum dma_data_direction dir)
3987{
3988 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU);
3989}
3990
3991static void
3992bounce_sync_single_for_device(struct device *dev, dma_addr_t addr,
3993 size_t size, enum dma_data_direction dir)
3994{
3995 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE);
3996}
3997
3998static void
3999bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
4000 int nelems, enum dma_data_direction dir)
4001{
4002 struct scatterlist *sg;
4003 int i;
4004
4005 for_each_sg(sglist, sg, nelems, i)
4006 bounce_sync_single(dev, sg_dma_address(sg),
4007 sg_dma_len(sg), dir, SYNC_FOR_CPU);
4008}
4009
4010static void
4011bounce_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
4012 int nelems, enum dma_data_direction dir)
4013{
4014 struct scatterlist *sg;
4015 int i;
4016
4017 for_each_sg(sglist, sg, nelems, i)
4018 bounce_sync_single(dev, sg_dma_address(sg),
4019 sg_dma_len(sg), dir, SYNC_FOR_DEVICE);
4020}
4021
4022static const struct dma_map_ops bounce_dma_ops = {
4023 .alloc = intel_alloc_coherent,
4024 .free = intel_free_coherent,
4025 .map_sg = bounce_map_sg,
4026 .unmap_sg = bounce_unmap_sg,
4027 .map_page = bounce_map_page,
4028 .unmap_page = bounce_unmap_page,
4029 .sync_single_for_cpu = bounce_sync_single_for_cpu,
4030 .sync_single_for_device = bounce_sync_single_for_device,
4031 .sync_sg_for_cpu = bounce_sync_sg_for_cpu,
4032 .sync_sg_for_device = bounce_sync_sg_for_device,
4033 .map_resource = bounce_map_resource,
4034 .unmap_resource = bounce_unmap_resource,
4035 .dma_supported = dma_direct_supported,
4036};
4037
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004038static inline int iommu_domain_cache_init(void)
4039{
4040 int ret = 0;
4041
4042 iommu_domain_cache = kmem_cache_create("iommu_domain",
4043 sizeof(struct dmar_domain),
4044 0,
4045 SLAB_HWCACHE_ALIGN,
4046
4047 NULL);
4048 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004049 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004050 ret = -ENOMEM;
4051 }
4052
4053 return ret;
4054}
4055
4056static inline int iommu_devinfo_cache_init(void)
4057{
4058 int ret = 0;
4059
4060 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
4061 sizeof(struct device_domain_info),
4062 0,
4063 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004064 NULL);
4065 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004066 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004067 ret = -ENOMEM;
4068 }
4069
4070 return ret;
4071}
4072
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004073static int __init iommu_init_mempool(void)
4074{
4075 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004076 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004077 if (ret)
4078 return ret;
4079
4080 ret = iommu_domain_cache_init();
4081 if (ret)
4082 goto domain_error;
4083
4084 ret = iommu_devinfo_cache_init();
4085 if (!ret)
4086 return ret;
4087
4088 kmem_cache_destroy(iommu_domain_cache);
4089domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004090 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004091
4092 return -ENOMEM;
4093}
4094
4095static void __init iommu_exit_mempool(void)
4096{
4097 kmem_cache_destroy(iommu_devinfo_cache);
4098 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004099 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004100}
4101
Dan Williams556ab452010-07-23 15:47:56 -07004102static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
4103{
4104 struct dmar_drhd_unit *drhd;
4105 u32 vtbar;
4106 int rc;
4107
4108 /* We know that this device on this chipset has its own IOMMU.
4109 * If we find it under a different IOMMU, then the BIOS is lying
4110 * to us. Hope that the IOMMU for this device is actually
4111 * disabled, and it needs no translation...
4112 */
4113 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
4114 if (rc) {
4115 /* "can't" happen */
4116 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
4117 return;
4118 }
4119 vtbar &= 0xffff0000;
4120
4121 /* we know that the this iommu should be at offset 0xa000 from vtbar */
4122 drhd = dmar_find_matched_drhd_unit(pdev);
4123 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
4124 TAINT_FIRMWARE_WORKAROUND,
4125 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
4126 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
4127}
4128DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
4129
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004130static void __init init_no_remapping_devices(void)
4131{
4132 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00004133 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08004134 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004135
4136 for_each_drhd_unit(drhd) {
4137 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08004138 for_each_active_dev_scope(drhd->devices,
4139 drhd->devices_cnt, i, dev)
4140 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004141 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004142 if (i == drhd->devices_cnt)
4143 drhd->ignored = 1;
4144 }
4145 }
4146
Jiang Liu7c919772014-01-06 14:18:18 +08004147 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004148 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004149 continue;
4150
Jiang Liub683b232014-02-19 14:07:32 +08004151 for_each_active_dev_scope(drhd->devices,
4152 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004153 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004154 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004155 if (i < drhd->devices_cnt)
4156 continue;
4157
David Woodhousec0771df2011-10-14 20:59:46 +01004158 /* This IOMMU has *only* gfx devices. Either bypass it or
4159 set the gfx_mapped flag, as appropriate */
Lu Baolucf1ec452019-05-02 09:34:25 +08004160 if (!dmar_map_gfx) {
David Woodhousec0771df2011-10-14 20:59:46 +01004161 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004162 for_each_active_dev_scope(drhd->devices,
4163 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004164 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004165 }
4166 }
4167}
4168
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004169#ifdef CONFIG_SUSPEND
4170static int init_iommu_hw(void)
4171{
4172 struct dmar_drhd_unit *drhd;
4173 struct intel_iommu *iommu = NULL;
4174
4175 for_each_active_iommu(iommu, drhd)
4176 if (iommu->qi)
4177 dmar_reenable_qi(iommu);
4178
Joseph Cihulab7792602011-05-03 00:08:37 -07004179 for_each_iommu(iommu, drhd) {
4180 if (drhd->ignored) {
4181 /*
4182 * we always have to disable PMRs or DMA may fail on
4183 * this device
4184 */
4185 if (force_on)
4186 iommu_disable_protect_mem_regions(iommu);
4187 continue;
4188 }
Lu Baolu095303e2019-04-29 09:16:02 +08004189
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004190 iommu_flush_write_buffer(iommu);
4191
4192 iommu_set_root_entry(iommu);
4193
4194 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004195 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004196 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4197 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004198 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004199 }
4200
4201 return 0;
4202}
4203
4204static void iommu_flush_all(void)
4205{
4206 struct dmar_drhd_unit *drhd;
4207 struct intel_iommu *iommu;
4208
4209 for_each_active_iommu(iommu, drhd) {
4210 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004211 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004212 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004213 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004214 }
4215}
4216
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004217static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004218{
4219 struct dmar_drhd_unit *drhd;
4220 struct intel_iommu *iommu = NULL;
4221 unsigned long flag;
4222
4223 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004224 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004225 GFP_ATOMIC);
4226 if (!iommu->iommu_state)
4227 goto nomem;
4228 }
4229
4230 iommu_flush_all();
4231
4232 for_each_active_iommu(iommu, drhd) {
4233 iommu_disable_translation(iommu);
4234
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004235 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004236
4237 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4238 readl(iommu->reg + DMAR_FECTL_REG);
4239 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4240 readl(iommu->reg + DMAR_FEDATA_REG);
4241 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4242 readl(iommu->reg + DMAR_FEADDR_REG);
4243 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4244 readl(iommu->reg + DMAR_FEUADDR_REG);
4245
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004246 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004247 }
4248 return 0;
4249
4250nomem:
4251 for_each_active_iommu(iommu, drhd)
4252 kfree(iommu->iommu_state);
4253
4254 return -ENOMEM;
4255}
4256
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004257static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004258{
4259 struct dmar_drhd_unit *drhd;
4260 struct intel_iommu *iommu = NULL;
4261 unsigned long flag;
4262
4263 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004264 if (force_on)
4265 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4266 else
4267 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004268 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004269 }
4270
4271 for_each_active_iommu(iommu, drhd) {
4272
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004273 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004274
4275 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4276 iommu->reg + DMAR_FECTL_REG);
4277 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4278 iommu->reg + DMAR_FEDATA_REG);
4279 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4280 iommu->reg + DMAR_FEADDR_REG);
4281 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4282 iommu->reg + DMAR_FEUADDR_REG);
4283
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004284 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004285 }
4286
4287 for_each_active_iommu(iommu, drhd)
4288 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004289}
4290
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004291static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004292 .resume = iommu_resume,
4293 .suspend = iommu_suspend,
4294};
4295
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004296static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004297{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004298 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004299}
4300
4301#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004302static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004303#endif /* CONFIG_PM */
4304
Jiang Liuc2a0b532014-11-09 22:47:56 +08004305int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004306{
4307 struct acpi_dmar_reserved_memory *rmrr;
4308 struct dmar_rmrr_unit *rmrru;
4309
4310 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4311 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004312 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004313
4314 rmrru->hdr = header;
4315 rmrr = (struct acpi_dmar_reserved_memory *)header;
4316 rmrru->base_address = rmrr->base_address;
4317 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004318
Jiang Liu2e455282014-02-19 14:07:36 +08004319 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4320 ((void *)rmrr) + rmrr->header.length,
4321 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004322 if (rmrru->devices_cnt && rmrru->devices == NULL)
Eric Auger5f64ce52019-06-03 08:53:31 +02004323 goto free_rmrru;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004324
Jiang Liu2e455282014-02-19 14:07:36 +08004325 list_add(&rmrru->list, &dmar_rmrr_units);
4326
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004327 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004328free_rmrru:
4329 kfree(rmrru);
4330out:
4331 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004332}
4333
Jiang Liu6b197242014-11-09 22:47:58 +08004334static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4335{
4336 struct dmar_atsr_unit *atsru;
4337 struct acpi_dmar_atsr *tmp;
4338
4339 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4340 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4341 if (atsr->segment != tmp->segment)
4342 continue;
4343 if (atsr->header.length != tmp->header.length)
4344 continue;
4345 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4346 return atsru;
4347 }
4348
4349 return NULL;
4350}
4351
4352int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004353{
4354 struct acpi_dmar_atsr *atsr;
4355 struct dmar_atsr_unit *atsru;
4356
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004357 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004358 return 0;
4359
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004360 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004361 atsru = dmar_find_atsr(atsr);
4362 if (atsru)
4363 return 0;
4364
4365 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004366 if (!atsru)
4367 return -ENOMEM;
4368
Jiang Liu6b197242014-11-09 22:47:58 +08004369 /*
4370 * If memory is allocated from slab by ACPI _DSM method, we need to
4371 * copy the memory content because the memory buffer will be freed
4372 * on return.
4373 */
4374 atsru->hdr = (void *)(atsru + 1);
4375 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004376 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004377 if (!atsru->include_all) {
4378 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4379 (void *)atsr + atsr->header.length,
4380 &atsru->devices_cnt);
4381 if (atsru->devices_cnt && atsru->devices == NULL) {
4382 kfree(atsru);
4383 return -ENOMEM;
4384 }
4385 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004386
Jiang Liu0e242612014-02-19 14:07:34 +08004387 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004388
4389 return 0;
4390}
4391
Jiang Liu9bdc5312014-01-06 14:18:27 +08004392static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4393{
4394 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4395 kfree(atsru);
4396}
4397
Jiang Liu6b197242014-11-09 22:47:58 +08004398int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4399{
4400 struct acpi_dmar_atsr *atsr;
4401 struct dmar_atsr_unit *atsru;
4402
4403 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4404 atsru = dmar_find_atsr(atsr);
4405 if (atsru) {
4406 list_del_rcu(&atsru->list);
4407 synchronize_rcu();
4408 intel_iommu_free_atsr(atsru);
4409 }
4410
4411 return 0;
4412}
4413
4414int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4415{
4416 int i;
4417 struct device *dev;
4418 struct acpi_dmar_atsr *atsr;
4419 struct dmar_atsr_unit *atsru;
4420
4421 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4422 atsru = dmar_find_atsr(atsr);
4423 if (!atsru)
4424 return 0;
4425
Linus Torvalds194dc872016-07-27 20:03:31 -07004426 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004427 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4428 i, dev)
4429 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004430 }
Jiang Liu6b197242014-11-09 22:47:58 +08004431
4432 return 0;
4433}
4434
Jiang Liuffebeb42014-11-09 22:48:02 +08004435static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4436{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004437 int sp, ret;
Jiang Liuffebeb42014-11-09 22:48:02 +08004438 struct intel_iommu *iommu = dmaru->iommu;
4439
4440 if (g_iommus[iommu->seq_id])
4441 return 0;
4442
4443 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004444 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004445 iommu->name);
4446 return -ENXIO;
4447 }
4448 if (!ecap_sc_support(iommu->ecap) &&
4449 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004450 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004451 iommu->name);
4452 return -ENXIO;
4453 }
4454 sp = domain_update_iommu_superpage(iommu) - 1;
4455 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004456 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004457 iommu->name);
4458 return -ENXIO;
4459 }
4460
4461 /*
4462 * Disable translation if already enabled prior to OS handover.
4463 */
4464 if (iommu->gcmd & DMA_GCMD_TE)
4465 iommu_disable_translation(iommu);
4466
4467 g_iommus[iommu->seq_id] = iommu;
4468 ret = iommu_init_domains(iommu);
4469 if (ret == 0)
4470 ret = iommu_alloc_root_entry(iommu);
4471 if (ret)
4472 goto out;
4473
David Woodhouse8a94ade2015-03-24 14:54:56 +00004474#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004475 if (pasid_supported(iommu))
Lu Baolud9737952018-07-14 15:47:02 +08004476 intel_svm_init(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00004477#endif
4478
Jiang Liuffebeb42014-11-09 22:48:02 +08004479 if (dmaru->ignored) {
4480 /*
4481 * we always have to disable PMRs or DMA may fail on this device
4482 */
4483 if (force_on)
4484 iommu_disable_protect_mem_regions(iommu);
4485 return 0;
4486 }
4487
4488 intel_iommu_init_qi(iommu);
4489 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004490
4491#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004492 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01004493 ret = intel_svm_enable_prq(iommu);
4494 if (ret)
4495 goto disable_iommu;
4496 }
4497#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004498 ret = dmar_set_interrupt(iommu);
4499 if (ret)
4500 goto disable_iommu;
4501
4502 iommu_set_root_entry(iommu);
4503 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4504 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4505 iommu_enable_translation(iommu);
4506
Jiang Liuffebeb42014-11-09 22:48:02 +08004507 iommu_disable_protect_mem_regions(iommu);
4508 return 0;
4509
4510disable_iommu:
4511 disable_dmar_iommu(iommu);
4512out:
4513 free_dmar_iommu(iommu);
4514 return ret;
4515}
4516
Jiang Liu6b197242014-11-09 22:47:58 +08004517int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4518{
Jiang Liuffebeb42014-11-09 22:48:02 +08004519 int ret = 0;
4520 struct intel_iommu *iommu = dmaru->iommu;
4521
4522 if (!intel_iommu_enabled)
4523 return 0;
4524 if (iommu == NULL)
4525 return -EINVAL;
4526
4527 if (insert) {
4528 ret = intel_iommu_add(dmaru);
4529 } else {
4530 disable_dmar_iommu(iommu);
4531 free_dmar_iommu(iommu);
4532 }
4533
4534 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004535}
4536
Jiang Liu9bdc5312014-01-06 14:18:27 +08004537static void intel_iommu_free_dmars(void)
4538{
4539 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4540 struct dmar_atsr_unit *atsru, *atsr_n;
4541
4542 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4543 list_del(&rmrru->list);
4544 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
4545 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004546 }
4547
Jiang Liu9bdc5312014-01-06 14:18:27 +08004548 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4549 list_del(&atsru->list);
4550 intel_iommu_free_atsr(atsru);
4551 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004552}
4553
4554int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4555{
Jiang Liub683b232014-02-19 14:07:32 +08004556 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004557 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004558 struct pci_dev *bridge = NULL;
4559 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004560 struct acpi_dmar_atsr *atsr;
4561 struct dmar_atsr_unit *atsru;
4562
4563 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004564 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004565 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004566 /* If it's an integrated device, allow ATS */
4567 if (!bridge)
4568 return 1;
4569 /* Connected via non-PCIe: no ATS */
4570 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004571 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004572 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004573 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004574 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004575 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004576 }
4577
Jiang Liu0e242612014-02-19 14:07:34 +08004578 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004579 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4580 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4581 if (atsr->segment != pci_domain_nr(dev->bus))
4582 continue;
4583
Jiang Liub683b232014-02-19 14:07:32 +08004584 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004585 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004586 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004587
4588 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004589 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004590 }
Jiang Liub683b232014-02-19 14:07:32 +08004591 ret = 0;
4592out:
Jiang Liu0e242612014-02-19 14:07:34 +08004593 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004594
Jiang Liub683b232014-02-19 14:07:32 +08004595 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004596}
4597
Jiang Liu59ce0512014-02-19 14:07:35 +08004598int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4599{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004600 int ret;
Jiang Liu59ce0512014-02-19 14:07:35 +08004601 struct dmar_rmrr_unit *rmrru;
4602 struct dmar_atsr_unit *atsru;
4603 struct acpi_dmar_atsr *atsr;
4604 struct acpi_dmar_reserved_memory *rmrr;
4605
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004606 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004607 return 0;
4608
4609 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4610 rmrr = container_of(rmrru->hdr,
4611 struct acpi_dmar_reserved_memory, header);
4612 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4613 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4614 ((void *)rmrr) + rmrr->header.length,
4615 rmrr->segment, rmrru->devices,
4616 rmrru->devices_cnt);
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004617 if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004618 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004619 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004620 dmar_remove_dev_scope(info, rmrr->segment,
4621 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004622 }
4623 }
4624
4625 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4626 if (atsru->include_all)
4627 continue;
4628
4629 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4630 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4631 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4632 (void *)atsr + atsr->header.length,
4633 atsr->segment, atsru->devices,
4634 atsru->devices_cnt);
4635 if (ret > 0)
4636 break;
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004637 else if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004638 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004639 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004640 if (dmar_remove_dev_scope(info, atsr->segment,
4641 atsru->devices, atsru->devices_cnt))
4642 break;
4643 }
4644 }
4645
4646 return 0;
4647}
4648
Jiang Liu75f05562014-02-19 14:07:37 +08004649static int intel_iommu_memory_notifier(struct notifier_block *nb,
4650 unsigned long val, void *v)
4651{
4652 struct memory_notify *mhp = v;
4653 unsigned long long start, end;
4654 unsigned long start_vpfn, last_vpfn;
4655
4656 switch (val) {
4657 case MEM_GOING_ONLINE:
4658 start = mhp->start_pfn << PAGE_SHIFT;
4659 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4660 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004661 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004662 start, end);
4663 return NOTIFY_BAD;
4664 }
4665 break;
4666
4667 case MEM_OFFLINE:
4668 case MEM_CANCEL_ONLINE:
4669 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4670 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4671 while (start_vpfn <= last_vpfn) {
4672 struct iova *iova;
4673 struct dmar_drhd_unit *drhd;
4674 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004675 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004676
4677 iova = find_iova(&si_domain->iovad, start_vpfn);
4678 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004679 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004680 start_vpfn);
4681 break;
4682 }
4683
4684 iova = split_and_remove_iova(&si_domain->iovad, iova,
4685 start_vpfn, last_vpfn);
4686 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004687 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004688 start_vpfn, last_vpfn);
4689 return NOTIFY_BAD;
4690 }
4691
David Woodhouseea8ea462014-03-05 17:09:32 +00004692 freelist = domain_unmap(si_domain, iova->pfn_lo,
4693 iova->pfn_hi);
4694
Jiang Liu75f05562014-02-19 14:07:37 +08004695 rcu_read_lock();
4696 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004697 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004698 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004699 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004700 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004701 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004702
4703 start_vpfn = iova->pfn_hi + 1;
4704 free_iova_mem(iova);
4705 }
4706 break;
4707 }
4708
4709 return NOTIFY_OK;
4710}
4711
4712static struct notifier_block intel_iommu_memory_nb = {
4713 .notifier_call = intel_iommu_memory_notifier,
4714 .priority = 0
4715};
4716
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004717static void free_all_cpu_cached_iovas(unsigned int cpu)
4718{
4719 int i;
4720
4721 for (i = 0; i < g_num_of_iommus; i++) {
4722 struct intel_iommu *iommu = g_iommus[i];
4723 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004724 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004725
4726 if (!iommu)
4727 continue;
4728
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004729 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004730 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004731
4732 if (!domain)
4733 continue;
4734 free_cpu_cached_iovas(cpu, &domain->iovad);
4735 }
4736 }
4737}
4738
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004739static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004740{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004741 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004742 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004743}
4744
Joerg Roedel161b28a2017-03-28 17:04:52 +02004745static void intel_disable_iommus(void)
4746{
4747 struct intel_iommu *iommu = NULL;
4748 struct dmar_drhd_unit *drhd;
4749
4750 for_each_iommu(iommu, drhd)
4751 iommu_disable_translation(iommu);
4752}
4753
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004754static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4755{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004756 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4757
4758 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004759}
4760
Alex Williamsona5459cf2014-06-12 16:12:31 -06004761static ssize_t intel_iommu_show_version(struct device *dev,
4762 struct device_attribute *attr,
4763 char *buf)
4764{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004765 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004766 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4767 return sprintf(buf, "%d:%d\n",
4768 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4769}
4770static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4771
4772static ssize_t intel_iommu_show_address(struct device *dev,
4773 struct device_attribute *attr,
4774 char *buf)
4775{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004776 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004777 return sprintf(buf, "%llx\n", iommu->reg_phys);
4778}
4779static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4780
4781static ssize_t intel_iommu_show_cap(struct device *dev,
4782 struct device_attribute *attr,
4783 char *buf)
4784{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004785 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004786 return sprintf(buf, "%llx\n", iommu->cap);
4787}
4788static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4789
4790static ssize_t intel_iommu_show_ecap(struct device *dev,
4791 struct device_attribute *attr,
4792 char *buf)
4793{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004794 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004795 return sprintf(buf, "%llx\n", iommu->ecap);
4796}
4797static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4798
Alex Williamson2238c082015-07-14 15:24:53 -06004799static ssize_t intel_iommu_show_ndoms(struct device *dev,
4800 struct device_attribute *attr,
4801 char *buf)
4802{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004803 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004804 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4805}
4806static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4807
4808static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4809 struct device_attribute *attr,
4810 char *buf)
4811{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004812 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004813 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4814 cap_ndoms(iommu->cap)));
4815}
4816static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4817
Alex Williamsona5459cf2014-06-12 16:12:31 -06004818static struct attribute *intel_iommu_attrs[] = {
4819 &dev_attr_version.attr,
4820 &dev_attr_address.attr,
4821 &dev_attr_cap.attr,
4822 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004823 &dev_attr_domains_supported.attr,
4824 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004825 NULL,
4826};
4827
4828static struct attribute_group intel_iommu_group = {
4829 .name = "intel-iommu",
4830 .attrs = intel_iommu_attrs,
4831};
4832
4833const struct attribute_group *intel_iommu_groups[] = {
4834 &intel_iommu_group,
4835 NULL,
4836};
4837
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004838static inline bool has_untrusted_dev(void)
Lu Baolu89a60792018-10-23 15:45:01 +08004839{
4840 struct pci_dev *pdev = NULL;
Lu Baolu89a60792018-10-23 15:45:01 +08004841
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004842 for_each_pci_dev(pdev)
4843 if (pdev->untrusted)
4844 return true;
Lu Baolu89a60792018-10-23 15:45:01 +08004845
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004846 return false;
4847}
Lu Baolu89a60792018-10-23 15:45:01 +08004848
Lu Baoluc5a5dc42019-09-06 14:14:50 +08004849static int __init platform_optin_force_iommu(void)
4850{
4851 if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
Lu Baolu89a60792018-10-23 15:45:01 +08004852 return 0;
4853
4854 if (no_iommu || dmar_disabled)
4855 pr_info("Intel-IOMMU force enabled due to platform opt in\n");
4856
4857 /*
4858 * If Intel-IOMMU is disabled by default, we will apply identity
4859 * map for all devices except those marked as being untrusted.
4860 */
4861 if (dmar_disabled)
4862 iommu_identity_mapping |= IDENTMAP_ALL;
4863
4864 dmar_disabled = 0;
Lu Baolu89a60792018-10-23 15:45:01 +08004865 no_iommu = 0;
4866
4867 return 1;
4868}
4869
Lu Baolufa212a92019-05-25 13:41:31 +08004870static int __init probe_acpi_namespace_devices(void)
4871{
4872 struct dmar_drhd_unit *drhd;
Qian Caiaf88ec32019-06-03 10:05:19 -04004873 /* To avoid a -Wunused-but-set-variable warning. */
4874 struct intel_iommu *iommu __maybe_unused;
Lu Baolufa212a92019-05-25 13:41:31 +08004875 struct device *dev;
4876 int i, ret = 0;
4877
4878 for_each_active_iommu(iommu, drhd) {
4879 for_each_active_dev_scope(drhd->devices,
4880 drhd->devices_cnt, i, dev) {
4881 struct acpi_device_physical_node *pn;
4882 struct iommu_group *group;
4883 struct acpi_device *adev;
4884
4885 if (dev->bus != &acpi_bus_type)
4886 continue;
4887
4888 adev = to_acpi_device(dev);
4889 mutex_lock(&adev->physical_node_lock);
4890 list_for_each_entry(pn,
4891 &adev->physical_node_list, node) {
4892 group = iommu_group_get(pn->dev);
4893 if (group) {
4894 iommu_group_put(group);
4895 continue;
4896 }
4897
4898 pn->dev->bus->iommu_ops = &intel_iommu_ops;
4899 ret = iommu_probe_device(pn->dev);
4900 if (ret)
4901 break;
4902 }
4903 mutex_unlock(&adev->physical_node_lock);
4904
4905 if (ret)
4906 return ret;
4907 }
4908 }
4909
4910 return 0;
4911}
4912
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004913int __init intel_iommu_init(void)
4914{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004915 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004916 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004917 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004918
Lu Baolu89a60792018-10-23 15:45:01 +08004919 /*
4920 * Intel IOMMU is required for a TXT/tboot launch or platform
4921 * opt in, so enforce that.
4922 */
4923 force_on = tboot_force_iommu() || platform_optin_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004924
Jiang Liu3a5670e2014-02-19 14:07:33 +08004925 if (iommu_init_mempool()) {
4926 if (force_on)
4927 panic("tboot: Failed to initialize iommu memory\n");
4928 return -ENOMEM;
4929 }
4930
4931 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004932 if (dmar_table_init()) {
4933 if (force_on)
4934 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004935 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004936 }
4937
Suresh Siddhac2c72862011-08-23 17:05:19 -07004938 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004939 if (force_on)
4940 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004941 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004942 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004943
Joerg Roedelec154bf2017-10-06 15:00:53 +02004944 up_write(&dmar_global_lock);
4945
4946 /*
4947 * The bus notifier takes the dmar_global_lock, so lockdep will
4948 * complain later when we register it under the lock.
4949 */
4950 dmar_register_bus_notifier();
4951
4952 down_write(&dmar_global_lock);
4953
Joerg Roedel161b28a2017-03-28 17:04:52 +02004954 if (no_iommu || dmar_disabled) {
4955 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004956 * We exit the function here to ensure IOMMU's remapping and
4957 * mempool aren't setup, which means that the IOMMU's PMRs
4958 * won't be disabled via the call to init_dmars(). So disable
4959 * it explicitly here. The PMRs were setup by tboot prior to
4960 * calling SENTER, but the kernel is expected to reset/tear
4961 * down the PMRs.
4962 */
4963 if (intel_iommu_tboot_noforce) {
4964 for_each_iommu(iommu, drhd)
4965 iommu_disable_protect_mem_regions(iommu);
4966 }
4967
4968 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004969 * Make sure the IOMMUs are switched off, even when we
4970 * boot into a kexec kernel and the previous kernel left
4971 * them enabled
4972 */
4973 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004974 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004975 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004976
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004977 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004978 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004979
4980 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004981 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004982
Joseph Cihula51a63e62011-03-21 11:04:24 -07004983 if (dmar_init_reserved_ranges()) {
4984 if (force_on)
4985 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004986 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004987 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004988
Lu Baolucf1ec452019-05-02 09:34:25 +08004989 if (dmar_map_gfx)
4990 intel_iommu_gfx_mapped = 1;
4991
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004992 init_no_remapping_devices();
4993
Joseph Cihulab7792602011-05-03 00:08:37 -07004994 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004995 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004996 if (force_on)
4997 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004998 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004999 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005000 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08005001 up_write(&dmar_global_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005002
Christoph Hellwig4fac8072017-12-24 13:57:08 +01005003#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005004 /*
5005 * If the system has no untrusted device or the user has decided
5006 * to disable the bounce page mechanisms, we don't need swiotlb.
5007 * Mark this and the pre-allocated bounce pages will be released
5008 * later.
5009 */
5010 if (!has_untrusted_dev() || intel_no_bounce)
5011 swiotlb = 0;
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09005012#endif
David Woodhouse19943b02009-08-04 16:19:20 +01005013 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07005014
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01005015 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005016
Joerg Roedel39ab9552017-02-01 16:56:46 +01005017 for_each_active_iommu(iommu, drhd) {
5018 iommu_device_sysfs_add(&iommu->iommu, NULL,
5019 intel_iommu_groups,
5020 "%s", iommu->name);
5021 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
5022 iommu_device_register(&iommu->iommu);
5023 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06005024
Joerg Roedel4236d97d2011-09-06 17:56:07 +02005025 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Jiang Liu75f05562014-02-19 14:07:37 +08005026 if (si_domain && !hw_pass_through)
5027 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01005028 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
5029 intel_iommu_cpu_dead);
Lu Baolud8190dc2019-05-25 13:41:25 +08005030
Lu Baolud5692d42019-06-12 08:28:49 +08005031 down_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08005032 if (probe_acpi_namespace_devices())
5033 pr_warn("ACPI name space devices didn't probe correctly\n");
Lu Baolud5692d42019-06-12 08:28:49 +08005034 up_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08005035
Lu Baolud8190dc2019-05-25 13:41:25 +08005036 /* Finally, we enable the DMA remapping hardware. */
5037 for_each_iommu(iommu, drhd) {
Lu Baolu6a8c6742019-06-12 08:28:47 +08005038 if (!drhd->ignored && !translation_pre_enabled(iommu))
Lu Baolud8190dc2019-05-25 13:41:25 +08005039 iommu_enable_translation(iommu);
5040
5041 iommu_disable_protect_mem_regions(iommu);
5042 }
5043 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
5044
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02005045 intel_iommu_enabled = 1;
Sohil Mehtaee2636b2018-09-11 17:11:38 -07005046 intel_iommu_debugfs_init();
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02005047
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005048 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08005049
5050out_free_reserved_range:
5051 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08005052out_free_dmar:
5053 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08005054 up_write(&dmar_global_lock);
5055 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08005056 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005057}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07005058
Lu Baolu0ce4a852019-08-26 16:50:56 +08005059static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
5060{
5061 struct intel_iommu *iommu = opaque;
5062
5063 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
5064 return 0;
5065}
5066
5067/*
5068 * NB - intel-iommu lacks any sort of reference counting for the users of
5069 * dependent devices. If multiple endpoints have intersecting dependent
5070 * devices, unbinding the driver from any one of them will possibly leave
5071 * the others unable to operate.
5072 */
5073static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
5074{
5075 if (!iommu || !dev || !dev_is_pci(dev))
5076 return;
5077
5078 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
5079}
5080
Joerg Roedel127c7612015-07-23 17:44:46 +02005081static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08005082{
Lu Baolu942067f2019-05-25 13:41:29 +08005083 struct dmar_domain *domain;
Weidong Hanc7151a82008-12-08 22:51:37 +08005084 struct intel_iommu *iommu;
5085 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08005086
Joerg Roedel55d94042015-07-22 16:50:40 +02005087 assert_spin_locked(&device_domain_lock);
5088
Joerg Roedelb608ac32015-07-21 18:19:08 +02005089 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08005090 return;
5091
Joerg Roedel127c7612015-07-23 17:44:46 +02005092 iommu = info->iommu;
Lu Baolu942067f2019-05-25 13:41:29 +08005093 domain = info->domain;
Joerg Roedel127c7612015-07-23 17:44:46 +02005094
5095 if (info->dev) {
Lu Baoluef848b72018-12-10 09:59:01 +08005096 if (dev_is_pci(info->dev) && sm_supported(iommu))
5097 intel_pasid_tear_down_entry(iommu, info->dev,
5098 PASID_RID2PASID);
5099
Joerg Roedel127c7612015-07-23 17:44:46 +02005100 iommu_disable_dev_iotlb(info);
Lu Baolu0ce4a852019-08-26 16:50:56 +08005101 domain_context_clear(iommu, info->dev);
Lu Baolua7fc93f2018-07-14 15:47:00 +08005102 intel_pasid_free_table(info->dev);
Joerg Roedel127c7612015-07-23 17:44:46 +02005103 }
5104
Joerg Roedelb608ac32015-07-21 18:19:08 +02005105 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07005106
Joerg Roedeld160aca2015-07-22 11:52:53 +02005107 spin_lock_irqsave(&iommu->lock, flags);
Lu Baolu942067f2019-05-25 13:41:29 +08005108 domain_detach_iommu(domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02005109 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005110
Lu Baolu942067f2019-05-25 13:41:29 +08005111 /* free the private domain */
5112 if (domain->flags & DOMAIN_FLAG_LOSE_CHILDREN &&
Lu Baolu3a18844d2019-08-06 08:14:09 +08005113 !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
5114 list_empty(&domain->devices))
Lu Baolu942067f2019-05-25 13:41:29 +08005115 domain_exit(info->domain);
5116
Joerg Roedel127c7612015-07-23 17:44:46 +02005117 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08005118}
5119
Bjorn Helgaas71753232019-02-08 16:06:15 -06005120static void dmar_remove_one_dev_info(struct device *dev)
Joerg Roedel55d94042015-07-22 16:50:40 +02005121{
Joerg Roedel127c7612015-07-23 17:44:46 +02005122 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02005123 unsigned long flags;
5124
Weidong Hanc7151a82008-12-08 22:51:37 +08005125 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005126 info = dev->archdata.iommu;
Lu Baoluae23bfb62019-08-06 08:14:08 +08005127 if (info)
5128 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005129 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005130}
5131
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005132static int md_domain_init(struct dmar_domain *domain, int guest_width)
5133{
5134 int adjust_width;
5135
5136 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
5137 domain_reserve_special_ranges(domain);
5138
5139 /* calculate AGAW */
5140 domain->gaw = guest_width;
5141 adjust_width = guestwidth_to_adjustwidth(guest_width);
5142 domain->agaw = width_to_agaw(adjust_width);
5143
5144 domain->iommu_coherency = 0;
5145 domain->iommu_snooping = 0;
5146 domain->iommu_superpage = 0;
5147 domain->max_addr = 0;
5148
5149 /* always allocate the top pgd */
5150 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
5151 if (!domain->pgd)
5152 return -ENOMEM;
5153 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5154 return 0;
5155}
5156
Joerg Roedel00a77de2015-03-26 13:43:08 +01005157static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03005158{
Joerg Roedel5d450802008-12-03 14:52:32 +01005159 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005160 struct iommu_domain *domain;
5161
Lu Baolu4de354e2019-05-25 13:41:27 +08005162 switch (type) {
Lu Baolufa954e62019-05-25 13:41:28 +08005163 case IOMMU_DOMAIN_DMA:
5164 /* fallthrough */
Lu Baolu4de354e2019-05-25 13:41:27 +08005165 case IOMMU_DOMAIN_UNMANAGED:
Lu Baolufa954e62019-05-25 13:41:28 +08005166 dmar_domain = alloc_domain(0);
Lu Baolu4de354e2019-05-25 13:41:27 +08005167 if (!dmar_domain) {
5168 pr_err("Can't allocate dmar_domain\n");
5169 return NULL;
5170 }
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005171 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Lu Baolu4de354e2019-05-25 13:41:27 +08005172 pr_err("Domain initialization failed\n");
5173 domain_exit(dmar_domain);
5174 return NULL;
5175 }
Lu Baolufa954e62019-05-25 13:41:28 +08005176
5177 if (type == IOMMU_DOMAIN_DMA &&
5178 init_iova_flush_queue(&dmar_domain->iovad,
5179 iommu_flush_iova, iova_entry_free)) {
5180 pr_warn("iova flush queue initialization failed\n");
5181 intel_iommu_strict = 1;
5182 }
5183
Lu Baolu4de354e2019-05-25 13:41:27 +08005184 domain_update_iommu_cap(dmar_domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005185
Lu Baolu4de354e2019-05-25 13:41:27 +08005186 domain = &dmar_domain->domain;
5187 domain->geometry.aperture_start = 0;
5188 domain->geometry.aperture_end =
5189 __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5190 domain->geometry.force_aperture = true;
5191
5192 return domain;
5193 case IOMMU_DOMAIN_IDENTITY:
5194 return &si_domain->domain;
5195 default:
Joerg Roedel00a77de2015-03-26 13:43:08 +01005196 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005197 }
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005198
Lu Baolu4de354e2019-05-25 13:41:27 +08005199 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005200}
Kay, Allen M38717942008-09-09 18:37:29 +03005201
Joerg Roedel00a77de2015-03-26 13:43:08 +01005202static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005203{
Lu Baolu4de354e2019-05-25 13:41:27 +08005204 if (domain != &si_domain->domain)
5205 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005206}
Kay, Allen M38717942008-09-09 18:37:29 +03005207
Lu Baolu67b8e022019-03-25 09:30:32 +08005208/*
5209 * Check whether a @domain could be attached to the @dev through the
5210 * aux-domain attach/detach APIs.
5211 */
5212static inline bool
5213is_aux_domain(struct device *dev, struct iommu_domain *domain)
5214{
5215 struct device_domain_info *info = dev->archdata.iommu;
5216
5217 return info && info->auxd_enabled &&
5218 domain->type == IOMMU_DOMAIN_UNMANAGED;
5219}
5220
5221static void auxiliary_link_device(struct dmar_domain *domain,
5222 struct device *dev)
5223{
5224 struct device_domain_info *info = dev->archdata.iommu;
5225
5226 assert_spin_locked(&device_domain_lock);
5227 if (WARN_ON(!info))
5228 return;
5229
5230 domain->auxd_refcnt++;
5231 list_add(&domain->auxd, &info->auxiliary_domains);
5232}
5233
5234static void auxiliary_unlink_device(struct dmar_domain *domain,
5235 struct device *dev)
5236{
5237 struct device_domain_info *info = dev->archdata.iommu;
5238
5239 assert_spin_locked(&device_domain_lock);
5240 if (WARN_ON(!info))
5241 return;
5242
5243 list_del(&domain->auxd);
5244 domain->auxd_refcnt--;
5245
5246 if (!domain->auxd_refcnt && domain->default_pasid > 0)
5247 intel_pasid_free_id(domain->default_pasid);
5248}
5249
5250static int aux_domain_add_dev(struct dmar_domain *domain,
5251 struct device *dev)
5252{
5253 int ret;
5254 u8 bus, devfn;
5255 unsigned long flags;
5256 struct intel_iommu *iommu;
5257
5258 iommu = device_to_iommu(dev, &bus, &devfn);
5259 if (!iommu)
5260 return -ENODEV;
5261
5262 if (domain->default_pasid <= 0) {
5263 int pasid;
5264
5265 pasid = intel_pasid_alloc_id(domain, PASID_MIN,
5266 pci_max_pasids(to_pci_dev(dev)),
5267 GFP_KERNEL);
5268 if (pasid <= 0) {
5269 pr_err("Can't allocate default pasid\n");
5270 return -ENODEV;
5271 }
5272 domain->default_pasid = pasid;
5273 }
5274
5275 spin_lock_irqsave(&device_domain_lock, flags);
5276 /*
5277 * iommu->lock must be held to attach domain to iommu and setup the
5278 * pasid entry for second level translation.
5279 */
5280 spin_lock(&iommu->lock);
5281 ret = domain_attach_iommu(domain, iommu);
5282 if (ret)
5283 goto attach_failed;
5284
5285 /* Setup the PASID entry for mediated devices: */
5286 ret = intel_pasid_setup_second_level(iommu, domain, dev,
5287 domain->default_pasid);
5288 if (ret)
5289 goto table_failed;
5290 spin_unlock(&iommu->lock);
5291
5292 auxiliary_link_device(domain, dev);
5293
5294 spin_unlock_irqrestore(&device_domain_lock, flags);
5295
5296 return 0;
5297
5298table_failed:
5299 domain_detach_iommu(domain, iommu);
5300attach_failed:
5301 spin_unlock(&iommu->lock);
5302 spin_unlock_irqrestore(&device_domain_lock, flags);
5303 if (!domain->auxd_refcnt && domain->default_pasid > 0)
5304 intel_pasid_free_id(domain->default_pasid);
5305
5306 return ret;
5307}
5308
5309static void aux_domain_remove_dev(struct dmar_domain *domain,
5310 struct device *dev)
5311{
5312 struct device_domain_info *info;
5313 struct intel_iommu *iommu;
5314 unsigned long flags;
5315
5316 if (!is_aux_domain(dev, &domain->domain))
5317 return;
5318
5319 spin_lock_irqsave(&device_domain_lock, flags);
5320 info = dev->archdata.iommu;
5321 iommu = info->iommu;
5322
5323 auxiliary_unlink_device(domain, dev);
5324
5325 spin_lock(&iommu->lock);
5326 intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid);
5327 domain_detach_iommu(domain, iommu);
5328 spin_unlock(&iommu->lock);
5329
5330 spin_unlock_irqrestore(&device_domain_lock, flags);
5331}
5332
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005333static int prepare_domain_attach_device(struct iommu_domain *domain,
5334 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005335{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005336 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005337 struct intel_iommu *iommu;
5338 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005339 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005340
David Woodhouse156baca2014-03-09 14:00:57 -07005341 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005342 if (!iommu)
5343 return -ENODEV;
5344
5345 /* check if this iommu agaw is sufficient for max mapped address */
5346 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005347 if (addr_width > cap_mgaw(iommu->cap))
5348 addr_width = cap_mgaw(iommu->cap);
5349
5350 if (dmar_domain->max_addr > (1LL << addr_width)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06005351 dev_err(dev, "%s: iommu width (%d) is not "
5352 "sufficient for the mapped address (%llx)\n",
5353 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005354 return -EFAULT;
5355 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005356 dmar_domain->gaw = addr_width;
5357
5358 /*
5359 * Knock out extra levels of page tables if necessary
5360 */
5361 while (iommu->agaw < dmar_domain->agaw) {
5362 struct dma_pte *pte;
5363
5364 pte = dmar_domain->pgd;
5365 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005366 dmar_domain->pgd = (struct dma_pte *)
5367 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005368 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005369 }
5370 dmar_domain->agaw--;
5371 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005372
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005373 return 0;
5374}
5375
5376static int intel_iommu_attach_device(struct iommu_domain *domain,
5377 struct device *dev)
5378{
5379 int ret;
5380
Lu Baolu56795822019-06-12 08:28:48 +08005381 if (domain->type == IOMMU_DOMAIN_UNMANAGED &&
5382 device_is_rmrr_locked(dev)) {
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005383 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5384 return -EPERM;
5385 }
5386
Lu Baolu67b8e022019-03-25 09:30:32 +08005387 if (is_aux_domain(dev, domain))
5388 return -EPERM;
5389
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005390 /* normally dev is not mapped */
5391 if (unlikely(domain_context_mapped(dev))) {
5392 struct dmar_domain *old_domain;
5393
5394 old_domain = find_domain(dev);
Lu Baolufa954e62019-05-25 13:41:28 +08005395 if (old_domain)
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005396 dmar_remove_one_dev_info(dev);
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005397 }
5398
5399 ret = prepare_domain_attach_device(domain, dev);
5400 if (ret)
5401 return ret;
5402
5403 return domain_add_dev_info(to_dmar_domain(domain), dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005404}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005405
Lu Baolu67b8e022019-03-25 09:30:32 +08005406static int intel_iommu_aux_attach_device(struct iommu_domain *domain,
5407 struct device *dev)
5408{
5409 int ret;
5410
5411 if (!is_aux_domain(dev, domain))
5412 return -EPERM;
5413
5414 ret = prepare_domain_attach_device(domain, dev);
5415 if (ret)
5416 return ret;
5417
5418 return aux_domain_add_dev(to_dmar_domain(domain), dev);
5419}
5420
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005421static void intel_iommu_detach_device(struct iommu_domain *domain,
5422 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005423{
Bjorn Helgaas71753232019-02-08 16:06:15 -06005424 dmar_remove_one_dev_info(dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005425}
Kay, Allen M38717942008-09-09 18:37:29 +03005426
Lu Baolu67b8e022019-03-25 09:30:32 +08005427static void intel_iommu_aux_detach_device(struct iommu_domain *domain,
5428 struct device *dev)
5429{
5430 aux_domain_remove_dev(to_dmar_domain(domain), dev);
5431}
5432
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005433static int intel_iommu_map(struct iommu_domain *domain,
5434 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005435 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005436{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005437 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005438 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005439 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005440 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005441
Lu Baolu942067f2019-05-25 13:41:29 +08005442 if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN)
5443 return -EINVAL;
5444
Joerg Roedeldde57a22008-12-03 15:04:09 +01005445 if (iommu_prot & IOMMU_READ)
5446 prot |= DMA_PTE_READ;
5447 if (iommu_prot & IOMMU_WRITE)
5448 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005449 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5450 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005451
David Woodhouse163cc522009-06-28 00:51:17 +01005452 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005453 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005454 u64 end;
5455
5456 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005457 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005458 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005459 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005460 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005461 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005462 return -EFAULT;
5463 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005464 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005465 }
David Woodhousead051222009-06-28 14:22:28 +01005466 /* Round up size to next multiple of PAGE_SIZE, if it and
5467 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005468 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005469 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5470 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005471 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005472}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005473
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005474static size_t intel_iommu_unmap(struct iommu_domain *domain,
Will Deacon56f8af52019-07-02 16:44:06 +01005475 unsigned long iova, size_t size,
5476 struct iommu_iotlb_gather *gather)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005477{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005478 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005479 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005480 unsigned long start_pfn, last_pfn;
5481 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005482 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005483
David Woodhouse5cf0a762014-03-19 16:07:49 +00005484 /* Cope with horrid API which requires us to unmap more than the
5485 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005486 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
Lu Baolu942067f2019-05-25 13:41:29 +08005487 if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN)
5488 return 0;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005489
5490 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5491 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5492
David Woodhouseea8ea462014-03-05 17:09:32 +00005493 start_pfn = iova >> VTD_PAGE_SHIFT;
5494 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5495
5496 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5497
5498 npages = last_pfn - start_pfn + 1;
5499
Shaokun Zhangf746a022018-03-22 18:18:06 +08005500 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005501 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5502 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005503
5504 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005505
David Woodhouse163cc522009-06-28 00:51:17 +01005506 if (dmar_domain->max_addr == iova + size)
5507 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005508
David Woodhouse5cf0a762014-03-19 16:07:49 +00005509 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005510}
Kay, Allen M38717942008-09-09 18:37:29 +03005511
Joerg Roedeld14d6572008-12-03 15:06:57 +01005512static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305513 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005514{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005515 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005516 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005517 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005518 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005519
Lu Baolu942067f2019-05-25 13:41:29 +08005520 if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN)
5521 return 0;
5522
David Woodhouse5cf0a762014-03-19 16:07:49 +00005523 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005524 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005525 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005526
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005527 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005528}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005529
Lu Baolu95587a72019-03-25 09:30:30 +08005530static inline bool scalable_mode_support(void)
5531{
5532 struct dmar_drhd_unit *drhd;
5533 struct intel_iommu *iommu;
5534 bool ret = true;
5535
5536 rcu_read_lock();
5537 for_each_active_iommu(iommu, drhd) {
5538 if (!sm_supported(iommu)) {
5539 ret = false;
5540 break;
5541 }
5542 }
5543 rcu_read_unlock();
5544
5545 return ret;
5546}
5547
5548static inline bool iommu_pasid_support(void)
5549{
5550 struct dmar_drhd_unit *drhd;
5551 struct intel_iommu *iommu;
5552 bool ret = true;
5553
5554 rcu_read_lock();
5555 for_each_active_iommu(iommu, drhd) {
5556 if (!pasid_supported(iommu)) {
5557 ret = false;
5558 break;
5559 }
5560 }
5561 rcu_read_unlock();
5562
5563 return ret;
5564}
5565
Joerg Roedel5d587b82014-09-05 10:50:45 +02005566static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005567{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005568 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005569 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005570 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005571 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005572
Joerg Roedel5d587b82014-09-05 10:50:45 +02005573 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005574}
5575
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005576static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005577{
Lu Baolu942067f2019-05-25 13:41:29 +08005578 struct dmar_domain *dmar_domain;
5579 struct iommu_domain *domain;
Alex Williamsona5459cf2014-06-12 16:12:31 -06005580 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005581 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005582 u8 bus, devfn;
Lu Baolu942067f2019-05-25 13:41:29 +08005583 int ret;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005584
Alex Williamsona5459cf2014-06-12 16:12:31 -06005585 iommu = device_to_iommu(dev, &bus, &devfn);
5586 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005587 return -ENODEV;
5588
Joerg Roedele3d10af2017-02-01 17:23:22 +01005589 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005590
Lu Baolu8af46c72019-05-25 13:41:32 +08005591 if (translation_pre_enabled(iommu))
5592 dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
5593
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005594 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005595
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005596 if (IS_ERR(group))
5597 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005598
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005599 iommu_group_put(group);
Lu Baolu942067f2019-05-25 13:41:29 +08005600
5601 domain = iommu_get_domain_for_dev(dev);
5602 dmar_domain = to_dmar_domain(domain);
5603 if (domain->type == IOMMU_DOMAIN_DMA) {
Lu Baolu0e31a722019-05-25 13:41:34 +08005604 if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) {
Lu Baolu942067f2019-05-25 13:41:29 +08005605 ret = iommu_request_dm_for_dev(dev);
5606 if (ret) {
Lu Baoluae23bfb62019-08-06 08:14:08 +08005607 dmar_remove_one_dev_info(dev);
Lu Baolu942067f2019-05-25 13:41:29 +08005608 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
5609 domain_add_dev_info(si_domain, dev);
5610 dev_info(dev,
5611 "Device uses a private identity domain.\n");
Lu Baolu942067f2019-05-25 13:41:29 +08005612 }
Lu Baolu942067f2019-05-25 13:41:29 +08005613 }
5614 } else {
Lu Baolu0e31a722019-05-25 13:41:34 +08005615 if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
Lu Baolu942067f2019-05-25 13:41:29 +08005616 ret = iommu_request_dma_domain_for_dev(dev);
5617 if (ret) {
Lu Baoluae23bfb62019-08-06 08:14:08 +08005618 dmar_remove_one_dev_info(dev);
Lu Baolu942067f2019-05-25 13:41:29 +08005619 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
Lu Baolu4ec066c2019-05-25 13:41:33 +08005620 if (!get_private_domain_for_dev(dev)) {
Lu Baolu942067f2019-05-25 13:41:29 +08005621 dev_warn(dev,
5622 "Failed to get a private domain.\n");
5623 return -ENOMEM;
5624 }
5625
5626 dev_info(dev,
5627 "Device uses a private dma domain.\n");
Lu Baolu942067f2019-05-25 13:41:29 +08005628 }
Lu Baolu942067f2019-05-25 13:41:29 +08005629 }
5630 }
5631
Lu Baolucfb94a32019-09-06 14:14:52 +08005632 if (device_needs_bounce(dev)) {
5633 dev_info(dev, "Use Intel IOMMU bounce page dma_ops\n");
5634 set_dma_ops(dev, &bounce_dma_ops);
5635 }
5636
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005637 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005638}
5639
5640static void intel_iommu_remove_device(struct device *dev)
5641{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005642 struct intel_iommu *iommu;
5643 u8 bus, devfn;
5644
5645 iommu = device_to_iommu(dev, &bus, &devfn);
5646 if (!iommu)
5647 return;
5648
Lu Baolu458b7c82019-08-01 11:14:58 +08005649 dmar_remove_one_dev_info(dev);
5650
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005651 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005652
Joerg Roedele3d10af2017-02-01 17:23:22 +01005653 iommu_device_unlink(&iommu->iommu, dev);
Lu Baolucfb94a32019-09-06 14:14:52 +08005654
5655 if (device_needs_bounce(dev))
5656 set_dma_ops(dev, NULL);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005657}
5658
Eric Auger0659b8d2017-01-19 20:57:53 +00005659static void intel_iommu_get_resv_regions(struct device *device,
5660 struct list_head *head)
5661{
Eric Auger5f64ce52019-06-03 08:53:31 +02005662 int prot = DMA_PTE_READ | DMA_PTE_WRITE;
Eric Auger0659b8d2017-01-19 20:57:53 +00005663 struct iommu_resv_region *reg;
5664 struct dmar_rmrr_unit *rmrr;
5665 struct device *i_dev;
5666 int i;
5667
Eric Auger5f64ce52019-06-03 08:53:31 +02005668 down_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005669 for_each_rmrr_units(rmrr) {
5670 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5671 i, i_dev) {
Eric Auger5f64ce52019-06-03 08:53:31 +02005672 struct iommu_resv_region *resv;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005673 enum iommu_resv_type type;
Eric Auger5f64ce52019-06-03 08:53:31 +02005674 size_t length;
5675
Eric Auger3855ba22019-06-03 08:53:34 +02005676 if (i_dev != device &&
5677 !is_downstream_to_pci_bridge(device, i_dev))
Eric Auger0659b8d2017-01-19 20:57:53 +00005678 continue;
5679
Eric Auger5f64ce52019-06-03 08:53:31 +02005680 length = rmrr->end_address - rmrr->base_address + 1;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005681
5682 type = device_rmrr_is_relaxable(device) ?
5683 IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;
5684
Eric Auger5f64ce52019-06-03 08:53:31 +02005685 resv = iommu_alloc_resv_region(rmrr->base_address,
Eric Auger1c5c59f2019-06-03 08:53:36 +02005686 length, prot, type);
Eric Auger5f64ce52019-06-03 08:53:31 +02005687 if (!resv)
5688 break;
5689
5690 list_add_tail(&resv->list, head);
Eric Auger0659b8d2017-01-19 20:57:53 +00005691 }
5692 }
Eric Auger5f64ce52019-06-03 08:53:31 +02005693 up_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005694
Lu Baolud850c2e2019-05-25 13:41:24 +08005695#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
5696 if (dev_is_pci(device)) {
5697 struct pci_dev *pdev = to_pci_dev(device);
5698
5699 if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) {
5700 reg = iommu_alloc_resv_region(0, 1UL << 24, 0,
5701 IOMMU_RESV_DIRECT);
5702 if (reg)
5703 list_add_tail(&reg->list, head);
5704 }
5705 }
5706#endif /* CONFIG_INTEL_IOMMU_FLOPPY_WA */
5707
Eric Auger0659b8d2017-01-19 20:57:53 +00005708 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5709 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005710 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005711 if (!reg)
5712 return;
5713 list_add_tail(&reg->list, head);
5714}
5715
5716static void intel_iommu_put_resv_regions(struct device *dev,
5717 struct list_head *head)
5718{
5719 struct iommu_resv_region *entry, *next;
5720
Eric Auger5f64ce52019-06-03 08:53:31 +02005721 list_for_each_entry_safe(entry, next, head, list)
5722 kfree(entry);
Kay, Allen M38717942008-09-09 18:37:29 +03005723}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005724
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005725int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005726{
5727 struct device_domain_info *info;
5728 struct context_entry *context;
5729 struct dmar_domain *domain;
5730 unsigned long flags;
5731 u64 ctx_lo;
5732 int ret;
5733
Lu Baolu4ec066c2019-05-25 13:41:33 +08005734 domain = find_domain(dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005735 if (!domain)
5736 return -EINVAL;
5737
5738 spin_lock_irqsave(&device_domain_lock, flags);
5739 spin_lock(&iommu->lock);
5740
5741 ret = -EINVAL;
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005742 info = dev->archdata.iommu;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005743 if (!info || !info->pasid_supported)
5744 goto out;
5745
5746 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5747 if (WARN_ON(!context))
5748 goto out;
5749
5750 ctx_lo = context[0].lo;
5751
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005752 if (!(ctx_lo & CONTEXT_PASIDE)) {
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005753 ctx_lo |= CONTEXT_PASIDE;
5754 context[0].lo = ctx_lo;
5755 wmb();
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005756 iommu->flush.flush_context(iommu,
5757 domain->iommu_did[iommu->seq_id],
5758 PCI_DEVID(info->bus, info->devfn),
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005759 DMA_CCMD_MASK_NOBIT,
5760 DMA_CCMD_DEVICE_INVL);
5761 }
5762
5763 /* Enable PASID support in the device, if it wasn't already */
5764 if (!info->pasid_enabled)
5765 iommu_enable_dev_iotlb(info);
5766
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005767 ret = 0;
5768
5769 out:
5770 spin_unlock(&iommu->lock);
5771 spin_unlock_irqrestore(&device_domain_lock, flags);
5772
5773 return ret;
5774}
5775
James Sewart73bcbdc2019-05-25 13:41:23 +08005776static void intel_iommu_apply_resv_region(struct device *dev,
5777 struct iommu_domain *domain,
5778 struct iommu_resv_region *region)
5779{
5780 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5781 unsigned long start, end;
5782
5783 start = IOVA_PFN(region->start);
5784 end = IOVA_PFN(region->start + region->length - 1);
5785
5786 WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end));
5787}
5788
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005789#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005790struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5791{
5792 struct intel_iommu *iommu;
5793 u8 bus, devfn;
5794
5795 if (iommu_dummy(dev)) {
5796 dev_warn(dev,
5797 "No IOMMU translation for device; cannot enable SVM\n");
5798 return NULL;
5799 }
5800
5801 iommu = device_to_iommu(dev, &bus, &devfn);
5802 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005803 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005804 return NULL;
5805 }
5806
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005807 return iommu;
5808}
5809#endif /* CONFIG_INTEL_IOMMU_SVM */
5810
Lu Baolu95587a72019-03-25 09:30:30 +08005811static int intel_iommu_enable_auxd(struct device *dev)
5812{
5813 struct device_domain_info *info;
5814 struct intel_iommu *iommu;
5815 unsigned long flags;
5816 u8 bus, devfn;
5817 int ret;
5818
5819 iommu = device_to_iommu(dev, &bus, &devfn);
5820 if (!iommu || dmar_disabled)
5821 return -EINVAL;
5822
5823 if (!sm_supported(iommu) || !pasid_supported(iommu))
5824 return -EINVAL;
5825
5826 ret = intel_iommu_enable_pasid(iommu, dev);
5827 if (ret)
5828 return -ENODEV;
5829
5830 spin_lock_irqsave(&device_domain_lock, flags);
5831 info = dev->archdata.iommu;
5832 info->auxd_enabled = 1;
5833 spin_unlock_irqrestore(&device_domain_lock, flags);
5834
5835 return 0;
5836}
5837
5838static int intel_iommu_disable_auxd(struct device *dev)
5839{
5840 struct device_domain_info *info;
5841 unsigned long flags;
5842
5843 spin_lock_irqsave(&device_domain_lock, flags);
5844 info = dev->archdata.iommu;
5845 if (!WARN_ON(!info))
5846 info->auxd_enabled = 0;
5847 spin_unlock_irqrestore(&device_domain_lock, flags);
5848
5849 return 0;
5850}
5851
5852/*
5853 * A PCI express designated vendor specific extended capability is defined
5854 * in the section 3.7 of Intel scalable I/O virtualization technical spec
5855 * for system software and tools to detect endpoint devices supporting the
5856 * Intel scalable IO virtualization without host driver dependency.
5857 *
5858 * Returns the address of the matching extended capability structure within
5859 * the device's PCI configuration space or 0 if the device does not support
5860 * it.
5861 */
5862static int siov_find_pci_dvsec(struct pci_dev *pdev)
5863{
5864 int pos;
5865 u16 vendor, id;
5866
5867 pos = pci_find_next_ext_capability(pdev, 0, 0x23);
5868 while (pos) {
5869 pci_read_config_word(pdev, pos + 4, &vendor);
5870 pci_read_config_word(pdev, pos + 8, &id);
5871 if (vendor == PCI_VENDOR_ID_INTEL && id == 5)
5872 return pos;
5873
5874 pos = pci_find_next_ext_capability(pdev, pos, 0x23);
5875 }
5876
5877 return 0;
5878}
5879
5880static bool
5881intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
5882{
5883 if (feat == IOMMU_DEV_FEAT_AUX) {
5884 int ret;
5885
5886 if (!dev_is_pci(dev) || dmar_disabled ||
5887 !scalable_mode_support() || !iommu_pasid_support())
5888 return false;
5889
5890 ret = pci_pasid_features(to_pci_dev(dev));
5891 if (ret < 0)
5892 return false;
5893
5894 return !!siov_find_pci_dvsec(to_pci_dev(dev));
5895 }
5896
5897 return false;
5898}
5899
5900static int
5901intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
5902{
5903 if (feat == IOMMU_DEV_FEAT_AUX)
5904 return intel_iommu_enable_auxd(dev);
5905
5906 return -ENODEV;
5907}
5908
5909static int
5910intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
5911{
5912 if (feat == IOMMU_DEV_FEAT_AUX)
5913 return intel_iommu_disable_auxd(dev);
5914
5915 return -ENODEV;
5916}
5917
5918static bool
5919intel_iommu_dev_feat_enabled(struct device *dev, enum iommu_dev_features feat)
5920{
5921 struct device_domain_info *info = dev->archdata.iommu;
5922
5923 if (feat == IOMMU_DEV_FEAT_AUX)
5924 return scalable_mode_support() && info && info->auxd_enabled;
5925
5926 return false;
5927}
5928
Lu Baolu0e8000f2019-03-25 09:30:33 +08005929static int
5930intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
5931{
5932 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5933
5934 return dmar_domain->default_pasid > 0 ?
5935 dmar_domain->default_pasid : -EINVAL;
5936}
5937
Lu Baolu8af46c72019-05-25 13:41:32 +08005938static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
5939 struct device *dev)
5940{
5941 return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
5942}
5943
Joerg Roedelb0119e82017-02-01 13:23:08 +01005944const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005945 .capable = intel_iommu_capable,
5946 .domain_alloc = intel_iommu_domain_alloc,
5947 .domain_free = intel_iommu_domain_free,
5948 .attach_dev = intel_iommu_attach_device,
5949 .detach_dev = intel_iommu_detach_device,
Lu Baolu67b8e022019-03-25 09:30:32 +08005950 .aux_attach_dev = intel_iommu_aux_attach_device,
5951 .aux_detach_dev = intel_iommu_aux_detach_device,
Lu Baolu0e8000f2019-03-25 09:30:33 +08005952 .aux_get_pasid = intel_iommu_aux_get_pasid,
Eric Auger0659b8d2017-01-19 20:57:53 +00005953 .map = intel_iommu_map,
5954 .unmap = intel_iommu_unmap,
Eric Auger0659b8d2017-01-19 20:57:53 +00005955 .iova_to_phys = intel_iommu_iova_to_phys,
5956 .add_device = intel_iommu_add_device,
5957 .remove_device = intel_iommu_remove_device,
5958 .get_resv_regions = intel_iommu_get_resv_regions,
5959 .put_resv_regions = intel_iommu_put_resv_regions,
James Sewart73bcbdc2019-05-25 13:41:23 +08005960 .apply_resv_region = intel_iommu_apply_resv_region,
Eric Auger0659b8d2017-01-19 20:57:53 +00005961 .device_group = pci_device_group,
Lu Baolu95587a72019-03-25 09:30:30 +08005962 .dev_has_feat = intel_iommu_dev_has_feat,
5963 .dev_feat_enabled = intel_iommu_dev_feat_enabled,
5964 .dev_enable_feat = intel_iommu_dev_enable_feat,
5965 .dev_disable_feat = intel_iommu_dev_disable_feat,
Lu Baolu8af46c72019-05-25 13:41:32 +08005966 .is_attach_deferred = intel_iommu_is_attach_deferred,
Eric Auger0659b8d2017-01-19 20:57:53 +00005967 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005968};
David Woodhouse9af88142009-02-13 23:18:03 +00005969
Chris Wilson1f762492019-09-09 12:00:10 +01005970static void quirk_iommu_igfx(struct pci_dev *dev)
Daniel Vetter94526182013-01-20 23:50:13 +01005971{
Bjorn Helgaas932a6522019-02-08 16:06:00 -06005972 pci_info(dev, "Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005973 dmar_map_gfx = 0;
5974}
5975
Chris Wilson1f762492019-09-09 12:00:10 +01005976/* G4x/GM45 integrated gfx dmar support is totally busted. */
5977DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
5978DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
5979DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_igfx);
5980DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_igfx);
5981DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
5982DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
5983DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
5984
5985/* Broadwell igfx malfunctions with dmar */
5986DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
5987DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
5988DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160E, quirk_iommu_igfx);
5989DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1602, quirk_iommu_igfx);
5990DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160A, quirk_iommu_igfx);
5991DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160D, quirk_iommu_igfx);
5992DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1616, quirk_iommu_igfx);
5993DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161B, quirk_iommu_igfx);
5994DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161E, quirk_iommu_igfx);
5995DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1612, quirk_iommu_igfx);
5996DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161A, quirk_iommu_igfx);
5997DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161D, quirk_iommu_igfx);
5998DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1626, quirk_iommu_igfx);
5999DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162B, quirk_iommu_igfx);
6000DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162E, quirk_iommu_igfx);
6001DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1622, quirk_iommu_igfx);
6002DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162A, quirk_iommu_igfx);
6003DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162D, quirk_iommu_igfx);
6004DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1636, quirk_iommu_igfx);
6005DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163B, quirk_iommu_igfx);
6006DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163E, quirk_iommu_igfx);
6007DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
6008DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
6009DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
Daniel Vetter94526182013-01-20 23:50:13 +01006010
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006011static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00006012{
6013 /*
6014 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01006015 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00006016 */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006017 pci_info(dev, "Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00006018 rwbf_quirk = 1;
6019}
6020
6021DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01006022DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
6023DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
6024DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
6025DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
6026DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
6027DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07006028
Adam Jacksoneecfd572010-08-25 21:17:34 +01006029#define GGC 0x52
6030#define GGC_MEMORY_SIZE_MASK (0xf << 8)
6031#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
6032#define GGC_MEMORY_SIZE_1M (0x1 << 8)
6033#define GGC_MEMORY_SIZE_2M (0x3 << 8)
6034#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
6035#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
6036#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
6037#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
6038
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006039static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01006040{
6041 unsigned short ggc;
6042
Adam Jacksoneecfd572010-08-25 21:17:34 +01006043 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01006044 return;
6045
Adam Jacksoneecfd572010-08-25 21:17:34 +01006046 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006047 pci_info(dev, "BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01006048 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006049 } else if (dmar_map_gfx) {
6050 /* we have to ensure the gfx device is idle before we flush */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006051 pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006052 intel_iommu_strict = 1;
6053 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01006054}
6055DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
6056DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
6057DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
6058DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
6059
David Woodhousee0fc7e02009-09-30 09:12:17 -07006060/* On Tylersburg chipsets, some BIOSes have been known to enable the
6061 ISOCH DMAR unit for the Azalia sound device, but not give it any
6062 TLB entries, which causes it to deadlock. Check for that. We do
6063 this in a function called from init_dmars(), instead of in a PCI
6064 quirk, because we don't want to print the obnoxious "BIOS broken"
6065 message if VT-d is actually disabled.
6066*/
6067static void __init check_tylersburg_isoch(void)
6068{
6069 struct pci_dev *pdev;
6070 uint32_t vtisochctrl;
6071
6072 /* If there's no Azalia in the system anyway, forget it. */
6073 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
6074 if (!pdev)
6075 return;
6076 pci_dev_put(pdev);
6077
6078 /* System Management Registers. Might be hidden, in which case
6079 we can't do the sanity check. But that's OK, because the
6080 known-broken BIOSes _don't_ actually hide it, so far. */
6081 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
6082 if (!pdev)
6083 return;
6084
6085 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
6086 pci_dev_put(pdev);
6087 return;
6088 }
6089
6090 pci_dev_put(pdev);
6091
6092 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
6093 if (vtisochctrl & 1)
6094 return;
6095
6096 /* Drop all bits other than the number of TLB entries */
6097 vtisochctrl &= 0x1c;
6098
6099 /* If we have the recommended number of TLB entries (16), fine. */
6100 if (vtisochctrl == 0x10)
6101 return;
6102
6103 /* Zero TLB entries? You get to ride the short bus to school. */
6104 if (!vtisochctrl) {
6105 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
6106 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
6107 dmi_get_system_info(DMI_BIOS_VENDOR),
6108 dmi_get_system_info(DMI_BIOS_VERSION),
6109 dmi_get_system_info(DMI_PRODUCT_VERSION));
6110 iommu_identity_mapping |= IDENTMAP_AZALIA;
6111 return;
6112 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02006113
6114 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07006115 vtisochctrl);
6116}