blob: 7027d6060711c7ad45a47567c4e72b55642d505e [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
Lu Baolua1948f22020-01-02 08:18:14 +0800310/*
311 * When VT-d works in the scalable mode, it allows DMA translation to
312 * happen through either first level or second level page table. This
313 * bit marks that the DMA translation for the domain goes through the
314 * first level page table, otherwise, it goes through the second level.
315 */
316#define DOMAIN_FLAG_USE_FIRST_LEVEL BIT(2)
317
Lu Baolu2cd13112020-01-02 08:18:15 +0800318/*
319 * Domain represents a virtual machine which demands iommu nested
320 * translation mode support.
321 */
322#define DOMAIN_FLAG_NESTING_MODE BIT(3)
323
Joerg Roedel29a27712015-07-21 17:17:12 +0200324#define for_each_domain_iommu(idx, domain) \
325 for (idx = 0; idx < g_num_of_iommus; idx++) \
326 if (domain->iommu_refcnt[idx])
327
Jiang Liub94e4112014-02-19 14:07:25 +0800328struct dmar_rmrr_unit {
329 struct list_head list; /* list of rmrr units */
330 struct acpi_dmar_header *hdr; /* ACPI header */
331 u64 base_address; /* reserved base address*/
332 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000333 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800334 int devices_cnt; /* target device count */
335};
336
337struct dmar_atsr_unit {
338 struct list_head list; /* list of ATSR units */
339 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000340 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800341 int devices_cnt; /* target device count */
342 u8 include_all:1; /* include all ports */
343};
344
345static LIST_HEAD(dmar_atsr_units);
346static LIST_HEAD(dmar_rmrr_units);
347
348#define for_each_rmrr_units(rmrr) \
349 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
350
mark gross5e0d2a62008-03-04 15:22:08 -0800351/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800352static int g_num_of_iommus;
353
Jiang Liu92d03cc2014-02-19 14:07:28 +0800354static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700355static void domain_remove_dev_info(struct dmar_domain *domain);
Bjorn Helgaas71753232019-02-08 16:06:15 -0600356static void dmar_remove_one_dev_info(struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200357static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Lu Baolu0ce4a852019-08-26 16:50:56 +0800358static void domain_context_clear(struct intel_iommu *iommu,
359 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800360static int domain_detach_iommu(struct dmar_domain *domain,
361 struct intel_iommu *iommu);
Lu Baolu4de354e2019-05-25 13:41:27 +0800362static bool device_is_rmrr_locked(struct device *dev);
Lu Baolu8af46c72019-05-25 13:41:32 +0800363static int intel_iommu_attach_device(struct iommu_domain *domain,
364 struct device *dev);
Lu Baolucfb94a32019-09-06 14:14:52 +0800365static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
366 dma_addr_t iova);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700367
Suresh Siddhad3f13812011-08-23 17:05:25 -0700368#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800369int dmar_disabled = 0;
370#else
371int dmar_disabled = 1;
Lu Baolu04618252020-01-02 08:18:02 +0800372#endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800373
Lu Baolu04618252020-01-02 08:18:02 +0800374#ifdef INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
375int intel_iommu_sm = 1;
376#else
Sai Praneeth Prakhyacdd3a242019-05-24 16:40:16 -0700377int intel_iommu_sm;
Lu Baolu04618252020-01-02 08:18:02 +0800378#endif /* INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */
379
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200380int intel_iommu_enabled = 0;
381EXPORT_SYMBOL_GPL(intel_iommu_enabled);
382
David Woodhouse2d9e6672010-06-15 10:57:57 +0100383static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700384static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800385static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100386static int intel_iommu_superpage = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100387static int iommu_identity_mapping;
Lu Baolue5e04d02019-09-06 14:14:49 +0800388static int intel_no_bounce;
David Woodhousec83b2f22015-06-12 10:15:49 +0100389
David Woodhouseae853dd2015-09-09 11:58:59 +0100390#define IDENTMAP_ALL 1
391#define IDENTMAP_GFX 2
392#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100393
David Woodhousec0771df2011-10-14 20:59:46 +0100394int intel_iommu_gfx_mapped;
395EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
396
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700397#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
Lu Baolu8af46c72019-05-25 13:41:32 +0800398#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
Lu Baolue2726da2020-01-02 08:18:22 +0800399DEFINE_SPINLOCK(device_domain_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700400static LIST_HEAD(device_domain_list);
401
Lu Baolue5e04d02019-09-06 14:14:49 +0800402#define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) && \
403 to_pci_dev(d)->untrusted)
404
Lu Baolu85319dc2018-07-14 15:46:58 +0800405/*
406 * Iterate over elements in device_domain_list and call the specified
Lu Baolu0bbeb012018-12-10 09:58:56 +0800407 * callback @fn against each element.
Lu Baolu85319dc2018-07-14 15:46:58 +0800408 */
409int for_each_device_domain(int (*fn)(struct device_domain_info *info,
410 void *data), void *data)
411{
412 int ret = 0;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800413 unsigned long flags;
Lu Baolu85319dc2018-07-14 15:46:58 +0800414 struct device_domain_info *info;
415
Lu Baolu0bbeb012018-12-10 09:58:56 +0800416 spin_lock_irqsave(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800417 list_for_each_entry(info, &device_domain_list, global) {
418 ret = fn(info, data);
Lu Baolu0bbeb012018-12-10 09:58:56 +0800419 if (ret) {
420 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800421 return ret;
Lu Baolu0bbeb012018-12-10 09:58:56 +0800422 }
Lu Baolu85319dc2018-07-14 15:46:58 +0800423 }
Lu Baolu0bbeb012018-12-10 09:58:56 +0800424 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolu85319dc2018-07-14 15:46:58 +0800425
426 return 0;
427}
428
Joerg Roedelb0119e82017-02-01 13:23:08 +0100429const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100430
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200431static bool translation_pre_enabled(struct intel_iommu *iommu)
432{
433 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
434}
435
Joerg Roedel091d42e2015-06-12 11:56:10 +0200436static void clear_translation_pre_enabled(struct intel_iommu *iommu)
437{
438 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
439}
440
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200441static void init_translation_status(struct intel_iommu *iommu)
442{
443 u32 gsts;
444
445 gsts = readl(iommu->reg + DMAR_GSTS_REG);
446 if (gsts & DMA_GSTS_TES)
447 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
448}
449
Joerg Roedel00a77de2015-03-26 13:43:08 +0100450/* Convert generic 'struct iommu_domain to private struct dmar_domain */
451static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
452{
453 return container_of(dom, struct dmar_domain, domain);
454}
455
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700456static int __init intel_iommu_setup(char *str)
457{
458 if (!str)
459 return -EINVAL;
460 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800461 if (!strncmp(str, "on", 2)) {
462 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200463 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800464 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700465 dmar_disabled = 1;
Lu Baolu89a60792018-10-23 15:45:01 +0800466 no_platform_optin = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200467 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700468 } else if (!strncmp(str, "igfx_off", 8)) {
469 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200470 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700471 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200472 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700473 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800474 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200475 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800476 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100477 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200478 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100479 intel_iommu_superpage = 0;
Lu Baolu8950dcd2019-01-24 10:31:32 +0800480 } else if (!strncmp(str, "sm_on", 5)) {
481 pr_info("Intel-IOMMU: scalable mode supported\n");
482 intel_iommu_sm = 1;
Shaohua Libfd20f12017-04-26 09:18:35 -0700483 } else if (!strncmp(str, "tboot_noforce", 13)) {
484 printk(KERN_INFO
485 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
486 intel_iommu_tboot_noforce = 1;
Lu Baolue5e04d02019-09-06 14:14:49 +0800487 } else if (!strncmp(str, "nobounce", 8)) {
488 pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
489 intel_no_bounce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700490 }
491
492 str += strcspn(str, ",");
493 while (*str == ',')
494 str++;
495 }
496 return 0;
497}
498__setup("intel_iommu=", intel_iommu_setup);
499
500static struct kmem_cache *iommu_domain_cache;
501static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700502
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200503static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
504{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200505 struct dmar_domain **domains;
506 int idx = did >> 8;
507
508 domains = iommu->domains[idx];
509 if (!domains)
510 return NULL;
511
512 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200513}
514
515static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
516 struct dmar_domain *domain)
517{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200518 struct dmar_domain **domains;
519 int idx = did >> 8;
520
521 if (!iommu->domains[idx]) {
522 size_t size = 256 * sizeof(struct dmar_domain *);
523 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
524 }
525
526 domains = iommu->domains[idx];
527 if (WARN_ON(!domains))
528 return;
529 else
530 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200531}
532
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800533void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700534{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700535 struct page *page;
536 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700537
Suresh Siddha4c923d42009-10-02 11:01:24 -0700538 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
539 if (page)
540 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700541 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700542}
543
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800544void free_pgtable_page(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700545{
546 free_page((unsigned long)vaddr);
547}
548
549static inline void *alloc_domain_mem(void)
550{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900551 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700552}
553
Kay, Allen M38717942008-09-09 18:37:29 +0300554static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700555{
556 kmem_cache_free(iommu_domain_cache, vaddr);
557}
558
559static inline void * alloc_devinfo_mem(void)
560{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900561 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700562}
563
564static inline void free_devinfo_mem(void *vaddr)
565{
566 kmem_cache_free(iommu_devinfo_cache, vaddr);
567}
568
Joerg Roedel28ccce02015-07-21 14:45:31 +0200569static inline int domain_type_is_si(struct dmar_domain *domain)
570{
571 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
572}
573
Lu Baoluddf09b62020-01-02 08:18:17 +0800574static inline bool domain_use_first_level(struct dmar_domain *domain)
575{
576 return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL;
577}
578
Jiang Liu162d1b12014-07-11 14:19:35 +0800579static inline int domain_pfn_supported(struct dmar_domain *domain,
580 unsigned long pfn)
581{
582 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
583
584 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
585}
586
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700587static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800588{
589 unsigned long sagaw;
590 int agaw = -1;
591
592 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700593 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800594 agaw >= 0; agaw--) {
595 if (test_bit(agaw, &sagaw))
596 break;
597 }
598
599 return agaw;
600}
601
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700602/*
603 * Calculate max SAGAW for each iommu.
604 */
605int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
606{
607 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
608}
609
610/*
611 * calculate agaw for each iommu.
612 * "SAGAW" may be different across iommus, use a default agaw, and
613 * get a supported less agaw for iommus that don't support the default agaw.
614 */
615int iommu_calculate_agaw(struct intel_iommu *iommu)
616{
617 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
618}
619
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700620/* This functionin only returns single iommu in a domain */
Lu Baolu9ddbfb42018-07-14 15:46:57 +0800621struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
Weidong Han8c11e792008-12-08 15:29:22 +0800622{
623 int iommu_id;
624
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700625 /* si_domain and vm domain should not get here. */
Lu Baolufa954e62019-05-25 13:41:28 +0800626 if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
627 return NULL;
628
Joerg Roedel29a27712015-07-21 17:17:12 +0200629 for_each_domain_iommu(iommu_id, domain)
630 break;
631
Weidong Han8c11e792008-12-08 15:29:22 +0800632 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
633 return NULL;
634
635 return g_iommus[iommu_id];
636}
637
Weidong Han8e6040972008-12-08 15:49:06 +0800638static void domain_update_iommu_coherency(struct dmar_domain *domain)
639{
David Woodhoused0501962014-03-11 17:10:29 -0700640 struct dmar_drhd_unit *drhd;
641 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100642 bool found = false;
643 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800644
David Woodhoused0501962014-03-11 17:10:29 -0700645 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800646
Joerg Roedel29a27712015-07-21 17:17:12 +0200647 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100648 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800649 if (!ecap_coherent(g_iommus[i]->ecap)) {
650 domain->iommu_coherency = 0;
651 break;
652 }
Weidong Han8e6040972008-12-08 15:49:06 +0800653 }
David Woodhoused0501962014-03-11 17:10:29 -0700654 if (found)
655 return;
656
657 /* No hardware attached; use lowest common denominator */
658 rcu_read_lock();
659 for_each_active_iommu(iommu, drhd) {
660 if (!ecap_coherent(iommu->ecap)) {
661 domain->iommu_coherency = 0;
662 break;
663 }
664 }
665 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800666}
667
Jiang Liu161f6932014-07-11 14:19:37 +0800668static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100669{
Allen Kay8140a952011-10-14 12:32:17 -0700670 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800671 struct intel_iommu *iommu;
672 int ret = 1;
673
674 rcu_read_lock();
675 for_each_active_iommu(iommu, drhd) {
676 if (iommu != skip) {
677 if (!ecap_sc_support(iommu->ecap)) {
678 ret = 0;
679 break;
680 }
681 }
682 }
683 rcu_read_unlock();
684
685 return ret;
686}
687
Lu Baolu64229e82020-01-02 08:18:20 +0800688static int domain_update_iommu_superpage(struct dmar_domain *domain,
689 struct intel_iommu *skip)
Jiang Liu161f6932014-07-11 14:19:37 +0800690{
691 struct dmar_drhd_unit *drhd;
692 struct intel_iommu *iommu;
Lu Baolu64229e82020-01-02 08:18:20 +0800693 int mask = 0x3;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100694
695 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800696 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100697 }
698
Allen Kay8140a952011-10-14 12:32:17 -0700699 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800700 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700701 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800702 if (iommu != skip) {
Lu Baolu64229e82020-01-02 08:18:20 +0800703 if (domain && domain_use_first_level(domain)) {
704 if (!cap_fl1gp_support(iommu->cap))
705 mask = 0x1;
706 } else {
707 mask &= cap_super_page_val(iommu->cap);
708 }
709
Jiang Liu161f6932014-07-11 14:19:37 +0800710 if (!mask)
711 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100712 }
713 }
Jiang Liu0e242612014-02-19 14:07:34 +0800714 rcu_read_unlock();
715
Jiang Liu161f6932014-07-11 14:19:37 +0800716 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100717}
718
Sheng Yang58c610b2009-03-18 15:33:05 +0800719/* Some capabilities may be different across iommus */
720static void domain_update_iommu_cap(struct dmar_domain *domain)
721{
722 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800723 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
Lu Baolu64229e82020-01-02 08:18:20 +0800724 domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800725}
726
Sohil Mehta26b86092018-09-11 17:11:36 -0700727struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
728 u8 devfn, int alloc)
David Woodhouse03ecc322015-02-13 14:35:21 +0000729{
730 struct root_entry *root = &iommu->root_entry[bus];
731 struct context_entry *context;
732 u64 *entry;
733
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200734 entry = &root->lo;
Lu Baolu765b6a92018-12-10 09:58:55 +0800735 if (sm_supported(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000736 if (devfn >= 0x80) {
737 devfn -= 0x80;
738 entry = &root->hi;
739 }
740 devfn *= 2;
741 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000742 if (*entry & 1)
743 context = phys_to_virt(*entry & VTD_PAGE_MASK);
744 else {
745 unsigned long phy_addr;
746 if (!alloc)
747 return NULL;
748
749 context = alloc_pgtable_page(iommu->node);
750 if (!context)
751 return NULL;
752
753 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
754 phy_addr = virt_to_phys((void *)context);
755 *entry = phy_addr | 1;
756 __iommu_flush_cache(iommu, entry, sizeof(*entry));
757 }
758 return &context[devfn];
759}
760
David Woodhouse4ed6a542015-05-11 14:59:20 +0100761static int iommu_dummy(struct device *dev)
762{
763 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
764}
765
Eric Augerb9a7f982019-06-03 08:53:32 +0200766/**
767 * is_downstream_to_pci_bridge - test if a device belongs to the PCI
768 * sub-hierarchy of a candidate PCI-PCI bridge
769 * @dev: candidate PCI device belonging to @bridge PCI sub-hierarchy
770 * @bridge: the candidate PCI-PCI bridge
771 *
772 * Return: true if @dev belongs to @bridge PCI sub-hierarchy, else false.
773 */
774static bool
775is_downstream_to_pci_bridge(struct device *dev, struct device *bridge)
776{
777 struct pci_dev *pdev, *pbridge;
778
779 if (!dev_is_pci(dev) || !dev_is_pci(bridge))
780 return false;
781
782 pdev = to_pci_dev(dev);
783 pbridge = to_pci_dev(bridge);
784
785 if (pbridge->subordinate &&
786 pbridge->subordinate->number <= pdev->bus->number &&
787 pbridge->subordinate->busn_res.end >= pdev->bus->number)
788 return true;
789
790 return false;
791}
792
David Woodhouse156baca2014-03-09 14:00:57 -0700793static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800794{
795 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800796 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700797 struct device *tmp;
Eric Augerb9a7f982019-06-03 08:53:32 +0200798 struct pci_dev *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800799 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800800 int i;
801
David Woodhouse4ed6a542015-05-11 14:59:20 +0100802 if (iommu_dummy(dev))
803 return NULL;
804
David Woodhouse156baca2014-03-09 14:00:57 -0700805 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700806 struct pci_dev *pf_pdev;
807
David Woodhouse156baca2014-03-09 14:00:57 -0700808 pdev = to_pci_dev(dev);
Jon Derrick5823e332017-08-30 15:05:59 -0600809
810#ifdef CONFIG_X86
811 /* VMD child devices currently cannot be handled individually */
812 if (is_vmd(pdev->bus))
813 return NULL;
814#endif
815
Ashok Raj1c387182016-10-21 15:32:05 -0700816 /* VFs aren't listed in scope tables; we need to look up
817 * the PF instead to find the IOMMU. */
818 pf_pdev = pci_physfn(pdev);
819 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700820 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100821 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700822 dev = &ACPI_COMPANION(dev)->dev;
823
Jiang Liu0e242612014-02-19 14:07:34 +0800824 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800825 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700826 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100827 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800828
Jiang Liub683b232014-02-19 14:07:32 +0800829 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700830 drhd->devices_cnt, i, tmp) {
831 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700832 /* For a VF use its original BDF# not that of the PF
833 * which we used for the IOMMU lookup. Strictly speaking
834 * we could do this for all PCI devices; we only need to
835 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100836 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700837 goto got_pdev;
838
David Woodhouse156baca2014-03-09 14:00:57 -0700839 *bus = drhd->devices[i].bus;
840 *devfn = drhd->devices[i].devfn;
841 goto out;
842 }
843
Eric Augerb9a7f982019-06-03 08:53:32 +0200844 if (is_downstream_to_pci_bridge(dev, tmp))
David Woodhouse156baca2014-03-09 14:00:57 -0700845 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100846 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800847
David Woodhouse156baca2014-03-09 14:00:57 -0700848 if (pdev && drhd->include_all) {
849 got_pdev:
850 *bus = pdev->bus->number;
851 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800852 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700853 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800854 }
Jiang Liub683b232014-02-19 14:07:32 +0800855 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700856 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800857 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800858
Jiang Liub683b232014-02-19 14:07:32 +0800859 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800860}
861
Weidong Han5331fe62008-12-08 23:00:00 +0800862static void domain_flush_cache(struct dmar_domain *domain,
863 void *addr, int size)
864{
865 if (!domain->iommu_coherency)
866 clflush_cache_range(addr, size);
867}
868
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700869static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
870{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700871 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000872 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700873 unsigned long flags;
874
875 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000876 context = iommu_context_addr(iommu, bus, devfn, 0);
877 if (context)
878 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700879 spin_unlock_irqrestore(&iommu->lock, flags);
880 return ret;
881}
882
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700883static void free_context_table(struct intel_iommu *iommu)
884{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700885 int i;
886 unsigned long flags;
887 struct context_entry *context;
888
889 spin_lock_irqsave(&iommu->lock, flags);
890 if (!iommu->root_entry) {
891 goto out;
892 }
893 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000894 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700895 if (context)
896 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000897
Lu Baolu765b6a92018-12-10 09:58:55 +0800898 if (!sm_supported(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000899 continue;
900
901 context = iommu_context_addr(iommu, i, 0x80, 0);
902 if (context)
903 free_pgtable_page(context);
904
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700905 }
906 free_pgtable_page(iommu->root_entry);
907 iommu->root_entry = NULL;
908out:
909 spin_unlock_irqrestore(&iommu->lock, flags);
910}
911
David Woodhouseb026fd22009-06-28 10:37:25 +0100912static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000913 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700914{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600915 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700916 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700917 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700918
919 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200920
Jiang Liu162d1b12014-07-11 14:19:35 +0800921 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200922 /* Address beyond IOMMU's addressing capabilities. */
923 return NULL;
924
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700925 parent = domain->pgd;
926
David Woodhouse5cf0a762014-03-19 16:07:49 +0000927 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700928 void *tmp_page;
929
David Woodhouseb026fd22009-06-28 10:37:25 +0100930 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700931 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +0000932 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100933 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +0000934 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700935 break;
936
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000937 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +0100938 uint64_t pteval;
939
Suresh Siddha4c923d42009-10-02 11:01:24 -0700940 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700941
David Woodhouse206a73c2009-07-01 19:30:28 +0100942 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700943 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +0100944
David Woodhousec85994e2009-07-01 19:21:24 +0100945 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -0400946 pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
Lu Baoluddf09b62020-01-02 08:18:17 +0800947 if (domain_use_first_level(domain))
948 pteval |= DMA_FL_PTE_XD;
Yijing Wangeffad4b2014-05-26 20:13:47 +0800949 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +0100950 /* Someone else set it while we were thinking; use theirs. */
951 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +0800952 else
David Woodhousec85994e2009-07-01 19:21:24 +0100953 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700954 }
David Woodhouse5cf0a762014-03-19 16:07:49 +0000955 if (level == 1)
956 break;
957
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000958 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700959 level--;
960 }
961
David Woodhouse5cf0a762014-03-19 16:07:49 +0000962 if (!*target_level)
963 *target_level = level;
964
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700965 return pte;
966}
967
968/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +0100969static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
970 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100971 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700972{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -0600973 struct dma_pte *parent, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700974 int total = agaw_to_level(domain->agaw);
975 int offset;
976
977 parent = domain->pgd;
978 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +0100979 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700980 pte = &parent[offset];
981 if (level == total)
982 return pte;
983
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100984 if (!dma_pte_present(pte)) {
985 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700986 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100987 }
988
Yijing Wange16922a2014-05-20 20:37:51 +0800989 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100990 *large_page = total;
991 return pte;
992 }
993
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000994 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700995 total--;
996 }
997 return NULL;
998}
999
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001000/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001001static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf52009-06-27 22:09:11 +01001002 unsigned long start_pfn,
1003 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001004{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001005 unsigned int large_page;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001006 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001007
Jiang Liu162d1b12014-07-11 14:19:35 +08001008 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1009 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001010 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001011
David Woodhouse04b18e62009-06-27 19:15:01 +01001012 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001013 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001014 large_page = 1;
1015 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001016 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001017 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001018 continue;
1019 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001020 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001021 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001022 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001023 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001024 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1025
David Woodhouse310a5ab2009-06-28 18:52:20 +01001026 domain_flush_cache(domain, first_pte,
1027 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001028
1029 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001030}
1031
Alex Williamson3269ee02013-06-15 10:27:19 -06001032static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001033 int retain_level, struct dma_pte *pte,
1034 unsigned long pfn, unsigned long start_pfn,
1035 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001036{
1037 pfn = max(start_pfn, pfn);
1038 pte = &pte[pfn_level_offset(pfn, level)];
1039
1040 do {
1041 unsigned long level_pfn;
1042 struct dma_pte *level_pte;
1043
1044 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1045 goto next;
1046
David Dillowf7116e12017-01-30 19:11:11 -08001047 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001048 level_pte = phys_to_virt(dma_pte_addr(pte));
1049
David Dillowbc24c572017-06-28 19:42:23 -07001050 if (level > 2) {
1051 dma_pte_free_level(domain, level - 1, retain_level,
1052 level_pte, level_pfn, start_pfn,
1053 last_pfn);
1054 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001055
David Dillowbc24c572017-06-28 19:42:23 -07001056 /*
1057 * Free the page table if we're below the level we want to
1058 * retain and the range covers the entire table.
1059 */
1060 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001061 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001062 dma_clear_pte(pte);
1063 domain_flush_cache(domain, pte, sizeof(*pte));
1064 free_pgtable_page(level_pte);
1065 }
1066next:
1067 pfn += level_size(level);
1068 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1069}
1070
David Dillowbc24c572017-06-28 19:42:23 -07001071/*
1072 * clear last level (leaf) ptes and free page table pages below the
1073 * level we wish to keep intact.
1074 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001075static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001076 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001077 unsigned long last_pfn,
1078 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001079{
Jiang Liu162d1b12014-07-11 14:19:35 +08001080 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1081 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001082 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001083
Jiang Liud41a4ad2014-07-11 14:19:34 +08001084 dma_pte_clear_range(domain, start_pfn, last_pfn);
1085
David Woodhousef3a0a522009-06-30 03:40:07 +01001086 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001087 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001088 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001089
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001090 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001091 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001092 free_pgtable_page(domain->pgd);
1093 domain->pgd = NULL;
1094 }
1095}
1096
David Woodhouseea8ea462014-03-05 17:09:32 +00001097/* When a page at a given level is being unlinked from its parent, we don't
1098 need to *modify* it at all. All we need to do is make a list of all the
1099 pages which can be freed just as soon as we've flushed the IOTLB and we
1100 know the hardware page-walk will no longer touch them.
1101 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1102 be freed. */
1103static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1104 int level, struct dma_pte *pte,
1105 struct page *freelist)
1106{
1107 struct page *pg;
1108
1109 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1110 pg->freelist = freelist;
1111 freelist = pg;
1112
1113 if (level == 1)
1114 return freelist;
1115
Jiang Liuadeb2592014-04-09 10:20:39 +08001116 pte = page_address(pg);
1117 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001118 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1119 freelist = dma_pte_list_pagetables(domain, level - 1,
1120 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001121 pte++;
1122 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001123
1124 return freelist;
1125}
1126
1127static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1128 struct dma_pte *pte, unsigned long pfn,
1129 unsigned long start_pfn,
1130 unsigned long last_pfn,
1131 struct page *freelist)
1132{
1133 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1134
1135 pfn = max(start_pfn, pfn);
1136 pte = &pte[pfn_level_offset(pfn, level)];
1137
1138 do {
1139 unsigned long level_pfn;
1140
1141 if (!dma_pte_present(pte))
1142 goto next;
1143
1144 level_pfn = pfn & level_mask(level);
1145
1146 /* If range covers entire pagetable, free it */
1147 if (start_pfn <= level_pfn &&
1148 last_pfn >= level_pfn + level_size(level) - 1) {
1149 /* These suborbinate page tables are going away entirely. Don't
1150 bother to clear them; we're just going to *free* them. */
1151 if (level > 1 && !dma_pte_superpage(pte))
1152 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1153
1154 dma_clear_pte(pte);
1155 if (!first_pte)
1156 first_pte = pte;
1157 last_pte = pte;
1158 } else if (level > 1) {
1159 /* Recurse down into a level that isn't *entirely* obsolete */
1160 freelist = dma_pte_clear_level(domain, level - 1,
1161 phys_to_virt(dma_pte_addr(pte)),
1162 level_pfn, start_pfn, last_pfn,
1163 freelist);
1164 }
1165next:
1166 pfn += level_size(level);
1167 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1168
1169 if (first_pte)
1170 domain_flush_cache(domain, first_pte,
1171 (void *)++last_pte - (void *)first_pte);
1172
1173 return freelist;
1174}
1175
1176/* We can't just free the pages because the IOMMU may still be walking
1177 the page tables, and may have cached the intermediate levels. The
1178 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001179static struct page *domain_unmap(struct dmar_domain *domain,
1180 unsigned long start_pfn,
1181 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001182{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001183 struct page *freelist;
David Woodhouseea8ea462014-03-05 17:09:32 +00001184
Jiang Liu162d1b12014-07-11 14:19:35 +08001185 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1186 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001187 BUG_ON(start_pfn > last_pfn);
1188
1189 /* we don't need lock here; nobody else touches the iova range */
1190 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1191 domain->pgd, 0, start_pfn, last_pfn, NULL);
1192
1193 /* free pgd */
1194 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1195 struct page *pgd_page = virt_to_page(domain->pgd);
1196 pgd_page->freelist = freelist;
1197 freelist = pgd_page;
1198
1199 domain->pgd = NULL;
1200 }
1201
1202 return freelist;
1203}
1204
Joerg Roedelb6904202015-08-13 11:32:18 +02001205static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001206{
1207 struct page *pg;
1208
1209 while ((pg = freelist)) {
1210 freelist = pg->freelist;
1211 free_pgtable_page(page_address(pg));
1212 }
1213}
1214
Joerg Roedel13cf0172017-08-11 11:40:10 +02001215static void iova_entry_free(unsigned long data)
1216{
1217 struct page *freelist = (struct page *)data;
1218
1219 dma_free_pagelist(freelist);
1220}
1221
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001222/* iommu handling */
1223static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1224{
1225 struct root_entry *root;
1226 unsigned long flags;
1227
Suresh Siddha4c923d42009-10-02 11:01:24 -07001228 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001229 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001230 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001231 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001232 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001233 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001234
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001235 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001236
1237 spin_lock_irqsave(&iommu->lock, flags);
1238 iommu->root_entry = root;
1239 spin_unlock_irqrestore(&iommu->lock, flags);
1240
1241 return 0;
1242}
1243
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001244static void iommu_set_root_entry(struct intel_iommu *iommu)
1245{
David Woodhouse03ecc322015-02-13 14:35:21 +00001246 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001247 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001248 unsigned long flag;
1249
David Woodhouse03ecc322015-02-13 14:35:21 +00001250 addr = virt_to_phys(iommu->root_entry);
Lu Baolu7373a8c2018-12-10 09:59:03 +08001251 if (sm_supported(iommu))
1252 addr |= DMA_RTADDR_SMT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001253
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001254 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001255 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001256
David Woodhousec416daa2009-05-10 20:30:58 +01001257 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001258
1259 /* Make sure hardware complete it */
1260 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001261 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001262
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001263 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001264}
1265
Lu Baolu6f7db752018-12-10 09:59:00 +08001266void iommu_flush_write_buffer(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001267{
1268 u32 val;
1269 unsigned long flag;
1270
David Woodhouse9af88142009-02-13 23:18:03 +00001271 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001272 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001273
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001274 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001275 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001276
1277 /* Make sure hardware complete it */
1278 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001279 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001280
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001281 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001282}
1283
1284/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001285static void __iommu_flush_context(struct intel_iommu *iommu,
1286 u16 did, u16 source_id, u8 function_mask,
1287 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001288{
1289 u64 val = 0;
1290 unsigned long flag;
1291
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001292 switch (type) {
1293 case DMA_CCMD_GLOBAL_INVL:
1294 val = DMA_CCMD_GLOBAL_INVL;
1295 break;
1296 case DMA_CCMD_DOMAIN_INVL:
1297 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1298 break;
1299 case DMA_CCMD_DEVICE_INVL:
1300 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1301 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1302 break;
1303 default:
1304 BUG();
1305 }
1306 val |= DMA_CCMD_ICC;
1307
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001308 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001309 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1310
1311 /* Make sure hardware complete it */
1312 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1313 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1314
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001315 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001316}
1317
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001318/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001319static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1320 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001321{
1322 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1323 u64 val = 0, val_iva = 0;
1324 unsigned long flag;
1325
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001326 switch (type) {
1327 case DMA_TLB_GLOBAL_FLUSH:
1328 /* global flush doesn't need set IVA_REG */
1329 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1330 break;
1331 case DMA_TLB_DSI_FLUSH:
1332 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1333 break;
1334 case DMA_TLB_PSI_FLUSH:
1335 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001336 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001337 val_iva = size_order | addr;
1338 break;
1339 default:
1340 BUG();
1341 }
1342 /* Note: set drain read/write */
1343#if 0
1344 /*
1345 * This is probably to be super secure.. Looks like we can
1346 * ignore it without any impact.
1347 */
1348 if (cap_read_drain(iommu->cap))
1349 val |= DMA_TLB_READ_DRAIN;
1350#endif
1351 if (cap_write_drain(iommu->cap))
1352 val |= DMA_TLB_WRITE_DRAIN;
1353
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001354 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001355 /* Note: Only uses first TLB reg currently */
1356 if (val_iva)
1357 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1358 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1359
1360 /* Make sure hardware complete it */
1361 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1362 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1363
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001364 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001365
1366 /* check IOTLB invalidation granularity */
1367 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001368 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001369 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001370 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001371 (unsigned long long)DMA_TLB_IIRG(type),
1372 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001373}
1374
David Woodhouse64ae8922014-03-09 12:52:30 -07001375static struct device_domain_info *
1376iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1377 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001378{
Yu Zhao93a23a72009-05-18 13:51:37 +08001379 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001380
Joerg Roedel55d94042015-07-22 16:50:40 +02001381 assert_spin_locked(&device_domain_lock);
1382
Yu Zhao93a23a72009-05-18 13:51:37 +08001383 if (!iommu->qi)
1384 return NULL;
1385
Yu Zhao93a23a72009-05-18 13:51:37 +08001386 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001387 if (info->iommu == iommu && info->bus == bus &&
1388 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001389 if (info->ats_supported && info->dev)
1390 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001391 break;
1392 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001393
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001394 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001395}
1396
Omer Peleg0824c592016-04-20 19:03:35 +03001397static void domain_update_iotlb(struct dmar_domain *domain)
1398{
1399 struct device_domain_info *info;
1400 bool has_iotlb_device = false;
1401
1402 assert_spin_locked(&device_domain_lock);
1403
1404 list_for_each_entry(info, &domain->devices, link) {
1405 struct pci_dev *pdev;
1406
1407 if (!info->dev || !dev_is_pci(info->dev))
1408 continue;
1409
1410 pdev = to_pci_dev(info->dev);
1411 if (pdev->ats_enabled) {
1412 has_iotlb_device = true;
1413 break;
1414 }
1415 }
1416
1417 domain->has_iotlb_device = has_iotlb_device;
1418}
1419
Yu Zhao93a23a72009-05-18 13:51:37 +08001420static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1421{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001422 struct pci_dev *pdev;
1423
Omer Peleg0824c592016-04-20 19:03:35 +03001424 assert_spin_locked(&device_domain_lock);
1425
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001426 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001427 return;
1428
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001429 pdev = to_pci_dev(info->dev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001430 /* For IOMMU that supports device IOTLB throttling (DIT), we assign
1431 * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
1432 * queue depth at PF level. If DIT is not set, PFSID will be treated as
1433 * reserved, which should be set to 0.
1434 */
1435 if (!ecap_dit(info->iommu->ecap))
1436 info->pfsid = 0;
1437 else {
1438 struct pci_dev *pf_pdev;
1439
1440 /* pdev will be returned if device is not a vf */
1441 pf_pdev = pci_physfn(pdev);
Heiner Kallweitcc49baa2019-04-24 21:16:10 +02001442 info->pfsid = pci_dev_id(pf_pdev);
Jacob Pan1c48db42018-06-07 09:57:00 -07001443 }
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001444
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001445#ifdef CONFIG_INTEL_IOMMU_SVM
1446 /* The PCIe spec, in its wisdom, declares that the behaviour of
1447 the device if you enable PASID support after ATS support is
1448 undefined. So always enable PASID support on devices which
1449 have it, even if we can't yet know if we're ever going to
1450 use it. */
1451 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1452 info->pasid_enabled = 1;
1453
Kuppuswamy Sathyanarayanan1b84778a2019-02-19 11:04:52 -08001454 if (info->pri_supported &&
1455 (info->pasid_enabled ? pci_prg_resp_pasid_required(pdev) : 1) &&
1456 !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001457 info->pri_enabled = 1;
1458#endif
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001459 if (!pdev->untrusted && info->ats_supported &&
Kuppuswamy Sathyanarayanan61363c12019-02-19 11:06:10 -08001460 pci_ats_page_aligned(pdev) &&
Mika Westerbergfb58fdc2018-10-29 13:47:08 +03001461 !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001462 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001463 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001464 info->ats_qdep = pci_ats_queue_depth(pdev);
1465 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001466}
1467
1468static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1469{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001470 struct pci_dev *pdev;
1471
Omer Peleg0824c592016-04-20 19:03:35 +03001472 assert_spin_locked(&device_domain_lock);
1473
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001474 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001475 return;
1476
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001477 pdev = to_pci_dev(info->dev);
1478
1479 if (info->ats_enabled) {
1480 pci_disable_ats(pdev);
1481 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001482 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001483 }
1484#ifdef CONFIG_INTEL_IOMMU_SVM
1485 if (info->pri_enabled) {
1486 pci_disable_pri(pdev);
1487 info->pri_enabled = 0;
1488 }
1489 if (info->pasid_enabled) {
1490 pci_disable_pasid(pdev);
1491 info->pasid_enabled = 0;
1492 }
1493#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001494}
1495
1496static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1497 u64 addr, unsigned mask)
1498{
1499 u16 sid, qdep;
1500 unsigned long flags;
1501 struct device_domain_info *info;
1502
Omer Peleg0824c592016-04-20 19:03:35 +03001503 if (!domain->has_iotlb_device)
1504 return;
1505
Yu Zhao93a23a72009-05-18 13:51:37 +08001506 spin_lock_irqsave(&device_domain_lock, flags);
1507 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001508 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001509 continue;
1510
1511 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001512 qdep = info->ats_qdep;
Jacob Pan1c48db42018-06-07 09:57:00 -07001513 qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
1514 qdep, addr, mask);
Yu Zhao93a23a72009-05-18 13:51:37 +08001515 }
1516 spin_unlock_irqrestore(&device_domain_lock, flags);
1517}
1518
Lu Baolu33cd6e62020-01-02 08:18:18 +08001519static void domain_flush_piotlb(struct intel_iommu *iommu,
1520 struct dmar_domain *domain,
1521 u64 addr, unsigned long npages, bool ih)
1522{
1523 u16 did = domain->iommu_did[iommu->seq_id];
1524
1525 if (domain->default_pasid)
1526 qi_flush_piotlb(iommu, did, domain->default_pasid,
1527 addr, npages, ih);
1528
1529 if (!list_empty(&domain->devices))
1530 qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, npages, ih);
1531}
1532
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001533static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1534 struct dmar_domain *domain,
1535 unsigned long pfn, unsigned int pages,
1536 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001537{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001538 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001539 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001540 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001541
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001542 BUG_ON(pages == 0);
1543
David Woodhouseea8ea462014-03-05 17:09:32 +00001544 if (ih)
1545 ih = 1 << 6;
Lu Baolu33cd6e62020-01-02 08:18:18 +08001546
1547 if (domain_use_first_level(domain)) {
1548 domain_flush_piotlb(iommu, domain, addr, pages, ih);
1549 } else {
1550 /*
1551 * Fallback to domain selective flush if no PSI support or
1552 * the size is too big. PSI requires page size to be 2 ^ x,
1553 * and the base address is naturally aligned to the size.
1554 */
1555 if (!cap_pgsel_inv(iommu->cap) ||
1556 mask > cap_max_amask_val(iommu->cap))
1557 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1558 DMA_TLB_DSI_FLUSH);
1559 else
1560 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
1561 DMA_TLB_PSI_FLUSH);
1562 }
Yu Zhaobf92df32009-06-29 11:31:45 +08001563
1564 /*
Nadav Amit82653632010-04-01 13:24:40 +03001565 * In caching mode, changes of pages from non-present to present require
1566 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001567 */
Nadav Amit82653632010-04-01 13:24:40 +03001568 if (!cap_caching_mode(iommu->cap) || !map)
Peter Xu9d2e6502018-01-10 13:51:37 +08001569 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001570}
1571
Peter Xueed91a02018-05-04 10:34:52 +08001572/* Notification for newly created mappings */
1573static inline void __mapping_notify_one(struct intel_iommu *iommu,
1574 struct dmar_domain *domain,
1575 unsigned long pfn, unsigned int pages)
1576{
Lu Baolu33cd6e62020-01-02 08:18:18 +08001577 /*
1578 * It's a non-present to present mapping. Only flush if caching mode
1579 * and second level.
1580 */
1581 if (cap_caching_mode(iommu->cap) && !domain_use_first_level(domain))
Peter Xueed91a02018-05-04 10:34:52 +08001582 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1583 else
1584 iommu_flush_write_buffer(iommu);
1585}
1586
Joerg Roedel13cf0172017-08-11 11:40:10 +02001587static void iommu_flush_iova(struct iova_domain *iovad)
1588{
1589 struct dmar_domain *domain;
1590 int idx;
1591
1592 domain = container_of(iovad, struct dmar_domain, iovad);
1593
1594 for_each_domain_iommu(idx, domain) {
1595 struct intel_iommu *iommu = g_iommus[idx];
1596 u16 did = domain->iommu_did[iommu->seq_id];
1597
Lu Baolu33cd6e62020-01-02 08:18:18 +08001598 if (domain_use_first_level(domain))
1599 domain_flush_piotlb(iommu, domain, 0, -1, 0);
1600 else
1601 iommu->flush.flush_iotlb(iommu, did, 0, 0,
1602 DMA_TLB_DSI_FLUSH);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001603
1604 if (!cap_caching_mode(iommu->cap))
1605 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1606 0, MAX_AGAW_PFN_WIDTH);
1607 }
1608}
1609
mark grossf8bab732008-02-08 04:18:38 -08001610static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1611{
1612 u32 pmen;
1613 unsigned long flags;
1614
Lu Baolu5bb71fc72019-03-20 09:58:33 +08001615 if (!cap_plmr(iommu->cap) && !cap_phmr(iommu->cap))
1616 return;
1617
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001618 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001619 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1620 pmen &= ~DMA_PMEN_EPM;
1621 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1622
1623 /* wait for the protected region status bit to clear */
1624 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1625 readl, !(pmen & DMA_PMEN_PRS), pmen);
1626
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001627 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001628}
1629
Jiang Liu2a41cce2014-07-11 14:19:33 +08001630static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001631{
1632 u32 sts;
1633 unsigned long flags;
1634
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001635 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001636 iommu->gcmd |= DMA_GCMD_TE;
1637 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001638
1639 /* Make sure hardware complete it */
1640 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001641 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001642
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001643 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001644}
1645
Jiang Liu2a41cce2014-07-11 14:19:33 +08001646static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001647{
1648 u32 sts;
1649 unsigned long flag;
1650
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001651 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001652 iommu->gcmd &= ~DMA_GCMD_TE;
1653 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1654
1655 /* Make sure hardware complete it */
1656 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001657 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001658
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001659 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001660}
1661
1662static int iommu_init_domains(struct intel_iommu *iommu)
1663{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001664 u32 ndomains, nlongs;
1665 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001666
1667 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001668 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001669 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001670 nlongs = BITS_TO_LONGS(ndomains);
1671
Donald Dutile94a91b502009-08-20 16:51:34 -04001672 spin_lock_init(&iommu->lock);
1673
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001674 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1675 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001676 pr_err("%s: Allocating domain id array failed\n",
1677 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678 return -ENOMEM;
1679 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001680
Wei Yang86f004c2016-05-21 02:41:51 +00001681 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001682 iommu->domains = kzalloc(size, GFP_KERNEL);
1683
1684 if (iommu->domains) {
1685 size = 256 * sizeof(struct dmar_domain *);
1686 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1687 }
1688
1689 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001690 pr_err("%s: Allocating domain array failed\n",
1691 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001692 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001693 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001694 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001695 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001696 return -ENOMEM;
1697 }
1698
1699 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001700 * If Caching mode is set, then invalid translations are tagged
1701 * with domain-id 0, hence we need to pre-allocate it. We also
1702 * use domain-id 0 as a marker for non-allocated domain-id, so
1703 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001704 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001705 set_bit(0, iommu->domain_ids);
1706
Lu Baolu3b33d4a2018-12-10 09:58:59 +08001707 /*
1708 * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid
1709 * entry for first-level or pass-through translation modes should
1710 * be programmed with a domain id different from those used for
1711 * second-level or nested translation. We reserve a domain id for
1712 * this purpose.
1713 */
1714 if (sm_supported(iommu))
1715 set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
1716
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001717 return 0;
1718}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001719
Jiang Liuffebeb42014-11-09 22:48:02 +08001720static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001721{
Joerg Roedel29a27712015-07-21 17:17:12 +02001722 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001723 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001724
Joerg Roedel29a27712015-07-21 17:17:12 +02001725 if (!iommu->domains || !iommu->domain_ids)
1726 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001727
Joerg Roedel55d94042015-07-22 16:50:40 +02001728 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001729 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
Joerg Roedel29a27712015-07-21 17:17:12 +02001730 if (info->iommu != iommu)
1731 continue;
1732
1733 if (!info->dev || !info->domain)
1734 continue;
1735
Joerg Roedelbea64032016-11-08 15:08:26 +01001736 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001737 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001738 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001739
1740 if (iommu->gcmd & DMA_GCMD_TE)
1741 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001742}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001743
Jiang Liuffebeb42014-11-09 22:48:02 +08001744static void free_dmar_iommu(struct intel_iommu *iommu)
1745{
1746 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001747 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001748 int i;
1749
1750 for (i = 0; i < elems; i++)
1751 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001752 kfree(iommu->domains);
1753 kfree(iommu->domain_ids);
1754 iommu->domains = NULL;
1755 iommu->domain_ids = NULL;
1756 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001757
Weidong Hand9630fe2008-12-08 11:06:32 +08001758 g_iommus[iommu->seq_id] = NULL;
1759
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001760 /* free context mapping */
1761 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001762
1763#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08001764 if (pasid_supported(iommu)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01001765 if (ecap_prs(iommu->ecap))
1766 intel_svm_finish_prq(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001767 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001768#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001769}
1770
Lu Baolua1948f22020-01-02 08:18:14 +08001771/*
1772 * Check and return whether first level is used by default for
Lu Baolub802d072020-01-02 08:18:21 +08001773 * DMA translation.
Lu Baolua1948f22020-01-02 08:18:14 +08001774 */
1775static bool first_level_by_default(void)
1776{
1777 struct dmar_drhd_unit *drhd;
1778 struct intel_iommu *iommu;
Lu Baolub802d072020-01-02 08:18:21 +08001779 static int first_level_support = -1;
Lu Baolua1948f22020-01-02 08:18:14 +08001780
1781 if (likely(first_level_support != -1))
1782 return first_level_support;
1783
1784 first_level_support = 1;
1785
1786 rcu_read_lock();
1787 for_each_active_iommu(iommu, drhd) {
1788 if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
1789 first_level_support = 0;
1790 break;
1791 }
1792 }
1793 rcu_read_unlock();
1794
1795 return first_level_support;
1796}
1797
Jiang Liuab8dfe22014-07-11 14:19:27 +08001798static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001799{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001801
1802 domain = alloc_domain_mem();
1803 if (!domain)
1804 return NULL;
1805
Jiang Liuab8dfe22014-07-11 14:19:27 +08001806 memset(domain, 0, sizeof(*domain));
Anshuman Khandual98fa15f2019-03-05 15:42:58 -08001807 domain->nid = NUMA_NO_NODE;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001808 domain->flags = flags;
Lu Baolua1948f22020-01-02 08:18:14 +08001809 if (first_level_by_default())
1810 domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
Omer Peleg0824c592016-04-20 19:03:35 +03001811 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001812 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001813
1814 return domain;
1815}
1816
Joerg Roedeld160aca2015-07-22 11:52:53 +02001817/* Must be called with iommu->lock */
1818static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001819 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001820{
Jiang Liu44bde612014-07-11 14:19:29 +08001821 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001822 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001823
Joerg Roedel55d94042015-07-22 16:50:40 +02001824 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001825 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001826
Joerg Roedel29a27712015-07-21 17:17:12 +02001827 domain->iommu_refcnt[iommu->seq_id] += 1;
1828 domain->iommu_count += 1;
1829 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001830 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001831 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1832
1833 if (num >= ndomains) {
1834 pr_err("%s: No free domain ids\n", iommu->name);
1835 domain->iommu_refcnt[iommu->seq_id] -= 1;
1836 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001837 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001838 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001839
Joerg Roedeld160aca2015-07-22 11:52:53 +02001840 set_bit(num, iommu->domain_ids);
1841 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001842
Joerg Roedeld160aca2015-07-22 11:52:53 +02001843 domain->iommu_did[iommu->seq_id] = num;
1844 domain->nid = iommu->node;
1845
Jiang Liufb170fb2014-07-11 14:19:28 +08001846 domain_update_iommu_cap(domain);
1847 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001848
Joerg Roedel55d94042015-07-22 16:50:40 +02001849 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001850}
1851
1852static int domain_detach_iommu(struct dmar_domain *domain,
1853 struct intel_iommu *iommu)
1854{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06001855 int num, count;
Jiang Liufb170fb2014-07-11 14:19:28 +08001856
Joerg Roedel55d94042015-07-22 16:50:40 +02001857 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001858 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001859
Joerg Roedel29a27712015-07-21 17:17:12 +02001860 domain->iommu_refcnt[iommu->seq_id] -= 1;
1861 count = --domain->iommu_count;
1862 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001863 num = domain->iommu_did[iommu->seq_id];
1864 clear_bit(num, iommu->domain_ids);
1865 set_iommu_domain(iommu, num, NULL);
1866
Jiang Liufb170fb2014-07-11 14:19:28 +08001867 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001868 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001869 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001870
1871 return count;
1872}
1873
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001874static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001875static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001876
Joseph Cihula51a63e62011-03-21 11:04:24 -07001877static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001878{
1879 struct pci_dev *pdev = NULL;
1880 struct iova *iova;
1881 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001882
Zhen Leiaa3ac942017-09-21 16:52:45 +01001883 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001884
Mark Gross8a443df2008-03-04 14:59:31 -08001885 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1886 &reserved_rbtree_key);
1887
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001888 /* IOAPIC ranges shouldn't be accessed by DMA */
1889 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1890 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001891 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001892 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001893 return -ENODEV;
1894 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001895
1896 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1897 for_each_pci_dev(pdev) {
1898 struct resource *r;
1899
1900 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1901 r = &pdev->resource[i];
1902 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1903 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001904 iova = reserve_iova(&reserved_iova_list,
1905 IOVA_PFN(r->start),
1906 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001907 if (!iova) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06001908 pci_err(pdev, "Reserve iova for %pR failed\n", r);
Joseph Cihula51a63e62011-03-21 11:04:24 -07001909 return -ENODEV;
1910 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001911 }
1912 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001913 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001914}
1915
1916static void domain_reserve_special_ranges(struct dmar_domain *domain)
1917{
1918 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1919}
1920
1921static inline int guestwidth_to_adjustwidth(int gaw)
1922{
1923 int agaw;
1924 int r = (gaw - 12) % 9;
1925
1926 if (r == 0)
1927 agaw = gaw;
1928 else
1929 agaw = gaw + 9 - r;
1930 if (agaw > 64)
1931 agaw = 64;
1932 return agaw;
1933}
1934
Joerg Roedel301e7ee2019-07-22 16:21:05 +02001935static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1936 int guest_width)
1937{
1938 int adjust_width, agaw;
1939 unsigned long sagaw;
Lu Baolu8e3391c2020-01-02 08:18:13 +08001940 int ret;
Joerg Roedel301e7ee2019-07-22 16:21:05 +02001941
1942 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
1943
Lu Baolu10f80082020-01-02 08:18:12 +08001944 if (!intel_iommu_strict) {
Lu Baolu8e3391c2020-01-02 08:18:13 +08001945 ret = init_iova_flush_queue(&domain->iovad,
Lu Baolu10f80082020-01-02 08:18:12 +08001946 iommu_flush_iova, iova_entry_free);
Lu Baolu8e3391c2020-01-02 08:18:13 +08001947 if (ret)
1948 pr_info("iova flush queue initialization failed\n");
Lu Baolu10f80082020-01-02 08:18:12 +08001949 }
Joerg Roedel301e7ee2019-07-22 16:21:05 +02001950
1951 domain_reserve_special_ranges(domain);
1952
1953 /* calculate AGAW */
1954 if (guest_width > cap_mgaw(iommu->cap))
1955 guest_width = cap_mgaw(iommu->cap);
1956 domain->gaw = guest_width;
1957 adjust_width = guestwidth_to_adjustwidth(guest_width);
1958 agaw = width_to_agaw(adjust_width);
1959 sagaw = cap_sagaw(iommu->cap);
1960 if (!test_bit(agaw, &sagaw)) {
1961 /* hardware doesn't support it, choose a bigger one */
1962 pr_debug("Hardware doesn't support agaw %d\n", agaw);
1963 agaw = find_next_bit(&sagaw, 5, agaw);
1964 if (agaw >= 5)
1965 return -ENODEV;
1966 }
1967 domain->agaw = agaw;
1968
1969 if (ecap_coherent(iommu->ecap))
1970 domain->iommu_coherency = 1;
1971 else
1972 domain->iommu_coherency = 0;
1973
1974 if (ecap_sc_support(iommu->ecap))
1975 domain->iommu_snooping = 1;
1976 else
1977 domain->iommu_snooping = 0;
1978
1979 if (intel_iommu_superpage)
1980 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1981 else
1982 domain->iommu_superpage = 0;
1983
1984 domain->nid = iommu->node;
1985
1986 /* always allocate the top pgd */
1987 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
1988 if (!domain->pgd)
1989 return -ENOMEM;
1990 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
1991 return 0;
1992}
1993
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001994static void domain_exit(struct dmar_domain *domain)
1995{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001996
Joerg Roedeld160aca2015-07-22 11:52:53 +02001997 /* Remove associated devices and clear attached or cached domains */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001998 domain_remove_dev_info(domain);
Jiang Liu92d03cc2014-02-19 14:07:28 +08001999
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002000 /* destroy iovas */
2001 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01002003 if (domain->pgd) {
2004 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002005
Dmitry Safonov3ee9eca2019-07-16 22:38:06 +01002006 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
2007 dma_free_pagelist(freelist);
2008 }
David Woodhouseea8ea462014-03-05 17:09:32 +00002009
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002010 free_domain_mem(domain);
2011}
2012
Lu Baolu7373a8c2018-12-10 09:59:03 +08002013/*
2014 * Get the PASID directory size for scalable mode context entry.
2015 * Value of X in the PDTS field of a scalable mode context entry
2016 * indicates PASID directory with 2^(X + 7) entries.
2017 */
2018static inline unsigned long context_get_sm_pds(struct pasid_table *table)
2019{
2020 int pds, max_pde;
2021
2022 max_pde = table->max_pasid >> PASID_PDE_SHIFT;
2023 pds = find_first_bit((unsigned long *)&max_pde, MAX_NR_PASID_BITS);
2024 if (pds < 7)
2025 return 0;
2026
2027 return pds - 7;
2028}
2029
2030/*
2031 * Set the RID_PASID field of a scalable mode context entry. The
2032 * IOMMU hardware will use the PASID value set in this field for
2033 * DMA translations of DMA requests without PASID.
2034 */
2035static inline void
2036context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasid)
2037{
2038 context->hi |= pasid & ((1 << 20) - 1);
2039 context->hi |= (1 << 20);
2040}
2041
2042/*
2043 * Set the DTE(Device-TLB Enable) field of a scalable mode context
2044 * entry.
2045 */
2046static inline void context_set_sm_dte(struct context_entry *context)
2047{
2048 context->lo |= (1 << 2);
2049}
2050
2051/*
2052 * Set the PRE(Page Request Enable) field of a scalable mode context
2053 * entry.
2054 */
2055static inline void context_set_sm_pre(struct context_entry *context)
2056{
2057 context->lo |= (1 << 4);
2058}
2059
2060/* Convert value to context PASID directory size field coding. */
2061#define context_pdts(pds) (((pds) & 0x7) << 9)
2062
David Woodhouse64ae8922014-03-09 12:52:30 -07002063static int domain_context_mapping_one(struct dmar_domain *domain,
2064 struct intel_iommu *iommu,
Lu Baoluca6e3222018-12-10 09:59:02 +08002065 struct pasid_table *table,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002066 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002067{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002068 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002069 int translation = CONTEXT_TT_MULTI_LEVEL;
2070 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002071 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002072 unsigned long flags;
Lu Baolu7373a8c2018-12-10 09:59:03 +08002073 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002074
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002075 WARN_ON(did == 0);
2076
Joerg Roedel28ccce02015-07-21 14:45:31 +02002077 if (hw_pass_through && domain_type_is_si(domain))
2078 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002079
2080 pr_debug("Set context mapping for %02x:%02x.%d\n",
2081 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002082
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002083 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002084
Joerg Roedel55d94042015-07-22 16:50:40 +02002085 spin_lock_irqsave(&device_domain_lock, flags);
2086 spin_lock(&iommu->lock);
2087
2088 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002089 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002090 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002091 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002092
Joerg Roedel55d94042015-07-22 16:50:40 +02002093 ret = 0;
2094 if (context_present(context))
2095 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002096
Xunlei Pangaec0e862016-12-05 20:09:07 +08002097 /*
2098 * For kdump cases, old valid entries may be cached due to the
2099 * in-flight DMA and copied pgtable, but there is no unmapping
2100 * behaviour for them, thus we need an explicit cache flush for
2101 * the newly-mapped device. For kdump, at this point, the device
2102 * is supposed to finish reset at its driver probe stage, so no
2103 * in-flight DMA will exist, and we don't need to worry anymore
2104 * hereafter.
2105 */
2106 if (context_copied(context)) {
2107 u16 did_old = context_domain_id(context);
2108
Christos Gkekasb117e032017-10-08 23:33:31 +01002109 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002110 iommu->flush.flush_context(iommu, did_old,
2111 (((u16)bus) << 8) | devfn,
2112 DMA_CCMD_MASK_NOBIT,
2113 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002114 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2115 DMA_TLB_DSI_FLUSH);
2116 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002117 }
2118
Joerg Roedelde24e552015-07-21 14:53:04 +02002119 context_clear_entry(context);
Weidong Hanea6606b2008-12-08 23:08:15 +08002120
Lu Baolu7373a8c2018-12-10 09:59:03 +08002121 if (sm_supported(iommu)) {
2122 unsigned long pds;
Joerg Roedelde24e552015-07-21 14:53:04 +02002123
Lu Baolu7373a8c2018-12-10 09:59:03 +08002124 WARN_ON(!table);
2125
2126 /* Setup the PASID DIR pointer: */
2127 pds = context_get_sm_pds(table);
2128 context->lo = (u64)virt_to_phys(table->table) |
2129 context_pdts(pds);
2130
2131 /* Setup the RID_PASID field: */
2132 context_set_sm_rid2pasid(context, PASID_RID2PASID);
2133
2134 /*
2135 * Setup the Device-TLB enable bit and Page request
2136 * Enable bit:
2137 */
David Woodhouse64ae8922014-03-09 12:52:30 -07002138 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002139 if (info && info->ats_supported)
Lu Baolu7373a8c2018-12-10 09:59:03 +08002140 context_set_sm_dte(context);
2141 if (info && info->pri_supported)
2142 context_set_sm_pre(context);
Joerg Roedelde24e552015-07-21 14:53:04 +02002143 } else {
Lu Baolu7373a8c2018-12-10 09:59:03 +08002144 struct dma_pte *pgd = domain->pgd;
2145 int agaw;
2146
2147 context_set_domain_id(context, did);
Lu Baolu7373a8c2018-12-10 09:59:03 +08002148
2149 if (translation != CONTEXT_TT_PASS_THROUGH) {
2150 /*
2151 * Skip top levels of page tables for iommu which has
2152 * less agaw than default. Unnecessary for PT mode.
2153 */
2154 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2155 ret = -ENOMEM;
2156 pgd = phys_to_virt(dma_pte_addr(pgd));
2157 if (!dma_pte_present(pgd))
2158 goto out_unlock;
2159 }
2160
2161 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
2162 if (info && info->ats_supported)
2163 translation = CONTEXT_TT_DEV_IOTLB;
2164 else
2165 translation = CONTEXT_TT_MULTI_LEVEL;
2166
2167 context_set_address_root(context, virt_to_phys(pgd));
2168 context_set_address_width(context, agaw);
2169 } else {
2170 /*
2171 * In pass through mode, AW must be programmed to
2172 * indicate the largest AGAW value supported by
2173 * hardware. And ASR is ignored by hardware.
2174 */
2175 context_set_address_width(context, iommu->msagaw);
2176 }
Lu Baolu41b80db2019-03-01 11:23:11 +08002177
2178 context_set_translation_type(context, translation);
Yu Zhao93a23a72009-05-18 13:51:37 +08002179 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002180
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002181 context_set_fault_enable(context);
2182 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002183 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002184
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002185 /*
2186 * It's a non-present to present mapping. If hardware doesn't cache
2187 * non-present entry we only need to flush the write-buffer. If the
2188 * _does_ cache non-present entries, then it does so in the special
2189 * domain #0, which we have to flush:
2190 */
2191 if (cap_caching_mode(iommu->cap)) {
2192 iommu->flush.flush_context(iommu, 0,
2193 (((u16)bus) << 8) | devfn,
2194 DMA_CCMD_MASK_NOBIT,
2195 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002196 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002197 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002198 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002199 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002200 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002201
Joerg Roedel55d94042015-07-22 16:50:40 +02002202 ret = 0;
2203
2204out_unlock:
2205 spin_unlock(&iommu->lock);
2206 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002207
Wei Yang5c365d12016-07-13 13:53:21 +00002208 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002209}
2210
Lu Baolu0ce4a852019-08-26 16:50:56 +08002211struct domain_context_mapping_data {
2212 struct dmar_domain *domain;
2213 struct intel_iommu *iommu;
2214 struct pasid_table *table;
2215};
2216
2217static int domain_context_mapping_cb(struct pci_dev *pdev,
2218 u16 alias, void *opaque)
2219{
2220 struct domain_context_mapping_data *data = opaque;
2221
2222 return domain_context_mapping_one(data->domain, data->iommu,
2223 data->table, PCI_BUS_NUM(alias),
2224 alias & 0xff);
2225}
2226
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002227static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002228domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002229{
Lu Baolu0ce4a852019-08-26 16:50:56 +08002230 struct domain_context_mapping_data data;
Lu Baoluca6e3222018-12-10 09:59:02 +08002231 struct pasid_table *table;
David Woodhouse64ae8922014-03-09 12:52:30 -07002232 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002233 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002234
David Woodhousee1f167f2014-03-09 15:24:46 -07002235 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002236 if (!iommu)
2237 return -ENODEV;
2238
Lu Baoluca6e3222018-12-10 09:59:02 +08002239 table = intel_pasid_get_table(dev);
Lu Baolu0ce4a852019-08-26 16:50:56 +08002240
2241 if (!dev_is_pci(dev))
2242 return domain_context_mapping_one(domain, iommu, table,
2243 bus, devfn);
2244
2245 data.domain = domain;
2246 data.iommu = iommu;
2247 data.table = table;
2248
2249 return pci_for_each_dma_alias(to_pci_dev(dev),
2250 &domain_context_mapping_cb, &data);
Alex Williamson579305f2014-07-03 09:51:43 -06002251}
2252
2253static int domain_context_mapped_cb(struct pci_dev *pdev,
2254 u16 alias, void *opaque)
2255{
2256 struct intel_iommu *iommu = opaque;
2257
2258 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002259}
2260
David Woodhousee1f167f2014-03-09 15:24:46 -07002261static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002262{
Weidong Han5331fe62008-12-08 23:00:00 +08002263 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002264 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002265
David Woodhousee1f167f2014-03-09 15:24:46 -07002266 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002267 if (!iommu)
2268 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002269
Alex Williamson579305f2014-07-03 09:51:43 -06002270 if (!dev_is_pci(dev))
2271 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002272
Alex Williamson579305f2014-07-03 09:51:43 -06002273 return !pci_for_each_dma_alias(to_pci_dev(dev),
2274 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002275}
2276
Fenghua Yuf5329592009-08-04 15:09:37 -07002277/* Returns a number of VTD pages, but aligned to MM page size */
2278static inline unsigned long aligned_nrpages(unsigned long host_addr,
2279 size_t size)
2280{
2281 host_addr &= ~PAGE_MASK;
2282 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2283}
2284
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002285/* Return largest possible superpage level for a given mapping */
2286static inline int hardware_largepage_caps(struct dmar_domain *domain,
2287 unsigned long iov_pfn,
2288 unsigned long phy_pfn,
2289 unsigned long pages)
2290{
2291 int support, level = 1;
2292 unsigned long pfnmerge;
2293
2294 support = domain->iommu_superpage;
2295
2296 /* To use a large page, the virtual *and* physical addresses
2297 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2298 of them will mean we have to use smaller pages. So just
2299 merge them and check both at once. */
2300 pfnmerge = iov_pfn | phy_pfn;
2301
2302 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2303 pages >>= VTD_STRIDE_SHIFT;
2304 if (!pages)
2305 break;
2306 pfnmerge >>= VTD_STRIDE_SHIFT;
2307 level++;
2308 support--;
2309 }
2310 return level;
2311}
2312
David Woodhouse9051aa02009-06-29 12:30:54 +01002313static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2314 struct scatterlist *sg, unsigned long phys_pfn,
2315 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002316{
2317 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002318 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002319 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002320 unsigned int largepage_lvl = 0;
2321 unsigned long lvl_pages = 0;
Lu Baoluddf09b62020-01-02 08:18:17 +08002322 u64 attr;
David Woodhousee1605492009-06-29 11:17:38 +01002323
Jiang Liu162d1b12014-07-11 14:19:35 +08002324 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002325
2326 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2327 return -EINVAL;
2328
Lu Baoluddf09b62020-01-02 08:18:17 +08002329 attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
2330 if (domain_use_first_level(domain))
2331 attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD;
David Woodhousee1605492009-06-29 11:17:38 +01002332
Jiang Liucc4f14a2014-11-26 09:42:10 +08002333 if (!sg) {
2334 sg_res = nr_pages;
Lu Baoluddf09b62020-01-02 08:18:17 +08002335 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
David Woodhouse9051aa02009-06-29 12:30:54 +01002336 }
2337
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002338 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002339 uint64_t tmp;
2340
David Woodhousee1605492009-06-29 11:17:38 +01002341 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002342 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2343
Fenghua Yuf5329592009-08-04 15:09:37 -07002344 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002345 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002346 sg->dma_length = sg->length;
Lu Baoluddf09b62020-01-02 08:18:17 +08002347 pteval = (sg_phys(sg) - pgoff) | attr;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002348 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002349 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002350
David Woodhousee1605492009-06-29 11:17:38 +01002351 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002352 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2353
David Woodhouse5cf0a762014-03-19 16:07:49 +00002354 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002355 if (!pte)
2356 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002357 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002358 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002359 unsigned long nr_superpages, end_pfn;
2360
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002361 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002362 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002363
2364 nr_superpages = sg_res / lvl_pages;
2365 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2366
Jiang Liud41a4ad2014-07-11 14:19:34 +08002367 /*
2368 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002369 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002370 * We're adding new large pages, so make sure
2371 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002372 */
David Dillowbc24c572017-06-28 19:42:23 -07002373 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2374 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002375 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002376 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002377 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002378
David Woodhousee1605492009-06-29 11:17:38 +01002379 }
2380 /* We don't need lock here, nobody else
2381 * touches the iova range
2382 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002383 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002384 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002385 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002386 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2387 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002388 if (dumps) {
2389 dumps--;
2390 debug_dma_dump_mappings(NULL);
2391 }
2392 WARN_ON(1);
2393 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002394
2395 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2396
2397 BUG_ON(nr_pages < lvl_pages);
2398 BUG_ON(sg_res < lvl_pages);
2399
2400 nr_pages -= lvl_pages;
2401 iov_pfn += lvl_pages;
2402 phys_pfn += lvl_pages;
2403 pteval += lvl_pages * VTD_PAGE_SIZE;
2404 sg_res -= lvl_pages;
2405
2406 /* If the next PTE would be the first in a new page, then we
2407 need to flush the cache on the entries we've just written.
2408 And then we'll need to recalculate 'pte', so clear it and
2409 let it get set again in the if (!pte) block above.
2410
2411 If we're done (!nr_pages) we need to flush the cache too.
2412
2413 Also if we've been setting superpages, we may need to
2414 recalculate 'pte' and switch back to smaller pages for the
2415 end of the mapping, if the trailing size is not enough to
2416 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002417 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002418 if (!nr_pages || first_pte_in_page(pte) ||
2419 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002420 domain_flush_cache(domain, first_pte,
2421 (void *)pte - (void *)first_pte);
2422 pte = NULL;
2423 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002424
2425 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002426 sg = sg_next(sg);
2427 }
2428 return 0;
2429}
2430
Peter Xu87684fd2018-05-04 10:34:53 +08002431static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
Lu Baolu095303e2019-04-29 09:16:02 +08002432 struct scatterlist *sg, unsigned long phys_pfn,
2433 unsigned long nr_pages, int prot)
Peter Xu87684fd2018-05-04 10:34:53 +08002434{
Lu Baolufa954e62019-05-25 13:41:28 +08002435 int iommu_id, ret;
Lu Baolu095303e2019-04-29 09:16:02 +08002436 struct intel_iommu *iommu;
Peter Xu87684fd2018-05-04 10:34:53 +08002437
Lu Baolu095303e2019-04-29 09:16:02 +08002438 /* Do the real mapping first */
2439 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2440 if (ret)
2441 return ret;
Peter Xu87684fd2018-05-04 10:34:53 +08002442
Lu Baolufa954e62019-05-25 13:41:28 +08002443 for_each_domain_iommu(iommu_id, domain) {
2444 iommu = g_iommus[iommu_id];
Lu Baolu095303e2019-04-29 09:16:02 +08002445 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2446 }
2447
2448 return 0;
Peter Xu87684fd2018-05-04 10:34:53 +08002449}
2450
David Woodhouse9051aa02009-06-29 12:30:54 +01002451static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2452 struct scatterlist *sg, unsigned long nr_pages,
2453 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002454{
Peter Xu87684fd2018-05-04 10:34:53 +08002455 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002456}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002457
David Woodhouse9051aa02009-06-29 12:30:54 +01002458static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2459 unsigned long phys_pfn, unsigned long nr_pages,
2460 int prot)
2461{
Peter Xu87684fd2018-05-04 10:34:53 +08002462 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002463}
2464
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002465static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002466{
Filippo Sironi50822192017-08-31 10:58:11 +02002467 unsigned long flags;
2468 struct context_entry *context;
2469 u16 did_old;
2470
Weidong Hanc7151a82008-12-08 22:51:37 +08002471 if (!iommu)
2472 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002473
Filippo Sironi50822192017-08-31 10:58:11 +02002474 spin_lock_irqsave(&iommu->lock, flags);
2475 context = iommu_context_addr(iommu, bus, devfn, 0);
2476 if (!context) {
2477 spin_unlock_irqrestore(&iommu->lock, flags);
2478 return;
2479 }
2480 did_old = context_domain_id(context);
2481 context_clear_entry(context);
2482 __iommu_flush_cache(iommu, context, sizeof(*context));
2483 spin_unlock_irqrestore(&iommu->lock, flags);
2484 iommu->flush.flush_context(iommu,
2485 did_old,
2486 (((u16)bus) << 8) | devfn,
2487 DMA_CCMD_MASK_NOBIT,
2488 DMA_CCMD_DEVICE_INVL);
2489 iommu->flush.flush_iotlb(iommu,
2490 did_old,
2491 0,
2492 0,
2493 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002494}
2495
David Woodhouse109b9b02012-05-25 17:43:02 +01002496static inline void unlink_domain_info(struct device_domain_info *info)
2497{
2498 assert_spin_locked(&device_domain_lock);
2499 list_del(&info->link);
2500 list_del(&info->global);
2501 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002502 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002503}
2504
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002505static void domain_remove_dev_info(struct dmar_domain *domain)
2506{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002507 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002508 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002509
2510 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002511 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002512 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002513 spin_unlock_irqrestore(&device_domain_lock, flags);
2514}
2515
Lu Baolue2726da2020-01-02 08:18:22 +08002516struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002517{
2518 struct device_domain_info *info;
2519
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002520 if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO ||
2521 dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO))
2522 return NULL;
2523
2524 /* No lock here, assumes no domain exit in normal case */
2525 info = dev->archdata.iommu;
2526 if (likely(info))
2527 return info->domain;
2528
2529 return NULL;
2530}
2531
2532static struct dmar_domain *deferred_attach_domain(struct device *dev)
2533{
Lu Baolu8af46c72019-05-25 13:41:32 +08002534 if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) {
2535 struct iommu_domain *domain;
2536
2537 dev->archdata.iommu = NULL;
2538 domain = iommu_get_domain_for_dev(dev);
2539 if (domain)
2540 intel_iommu_attach_device(domain, dev);
2541 }
2542
Lu Baolu1ee0186b2019-09-21 15:06:44 +08002543 return find_domain(dev);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002544}
2545
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002546static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002547dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2548{
2549 struct device_domain_info *info;
2550
2551 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002552 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002553 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002554 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002555
2556 return NULL;
2557}
2558
Lu Baoluddf09b62020-01-02 08:18:17 +08002559static int domain_setup_first_level(struct intel_iommu *iommu,
2560 struct dmar_domain *domain,
2561 struct device *dev,
2562 int pasid)
2563{
2564 int flags = PASID_FLAG_SUPERVISOR_MODE;
2565 struct dma_pte *pgd = domain->pgd;
2566 int agaw, level;
2567
2568 /*
2569 * Skip top levels of page tables for iommu which has
2570 * less agaw than default. Unnecessary for PT mode.
2571 */
2572 for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
2573 pgd = phys_to_virt(dma_pte_addr(pgd));
2574 if (!dma_pte_present(pgd))
2575 return -ENOMEM;
2576 }
2577
2578 level = agaw_to_level(agaw);
2579 if (level != 4 && level != 5)
2580 return -EINVAL;
2581
2582 flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;
2583
2584 return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,
2585 domain->iommu_did[iommu->seq_id],
2586 flags);
2587}
2588
Joerg Roedel5db31562015-07-22 12:40:43 +02002589static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2590 int bus, int devfn,
2591 struct device *dev,
2592 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002593{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002594 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002595 struct device_domain_info *info;
2596 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002597 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002598
2599 info = alloc_devinfo_mem();
2600 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002601 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002602
Jiang Liu745f2582014-02-19 14:07:26 +08002603 info->bus = bus;
2604 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002605 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2606 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2607 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002608 info->dev = dev;
2609 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002610 info->iommu = iommu;
Lu Baolucc580e42018-07-14 15:46:59 +08002611 info->pasid_table = NULL;
Lu Baolu95587a72019-03-25 09:30:30 +08002612 info->auxd_enabled = 0;
Lu Baolu67b8e022019-03-25 09:30:32 +08002613 INIT_LIST_HEAD(&info->auxiliary_domains);
Jiang Liu745f2582014-02-19 14:07:26 +08002614
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002615 if (dev && dev_is_pci(dev)) {
2616 struct pci_dev *pdev = to_pci_dev(info->dev);
2617
Lu Baolud8b85912019-03-01 11:23:10 +08002618 if (!pdev->untrusted &&
2619 !pci_ats_disabled() &&
Gil Kupfercef74402018-05-10 17:56:02 -05002620 ecap_dev_iotlb_support(iommu->ecap) &&
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002621 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2622 dmar_find_matched_atsr_unit(pdev))
2623 info->ats_supported = 1;
2624
Lu Baolu765b6a92018-12-10 09:58:55 +08002625 if (sm_supported(iommu)) {
2626 if (pasid_supported(iommu)) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002627 int features = pci_pasid_features(pdev);
2628 if (features >= 0)
2629 info->pasid_supported = features | 1;
2630 }
2631
2632 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2633 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2634 info->pri_supported = 1;
2635 }
2636 }
2637
Jiang Liu745f2582014-02-19 14:07:26 +08002638 spin_lock_irqsave(&device_domain_lock, flags);
2639 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002640 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002641
2642 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002643 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002644 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002645 if (info2) {
2646 found = info2->domain;
2647 info2->dev = dev;
2648 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002649 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002650
Jiang Liu745f2582014-02-19 14:07:26 +08002651 if (found) {
2652 spin_unlock_irqrestore(&device_domain_lock, flags);
2653 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002654 /* Caller must free the original domain */
2655 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002656 }
2657
Joerg Roedeld160aca2015-07-22 11:52:53 +02002658 spin_lock(&iommu->lock);
2659 ret = domain_attach_iommu(domain, iommu);
2660 spin_unlock(&iommu->lock);
2661
2662 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002663 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302664 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002665 return NULL;
2666 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002667
David Woodhouseb718cd32014-03-09 13:11:33 -07002668 list_add(&info->link, &domain->devices);
2669 list_add(&info->global, &device_domain_list);
2670 if (dev)
2671 dev->archdata.iommu = info;
Lu Baolu0bbeb012018-12-10 09:58:56 +08002672 spin_unlock_irqrestore(&device_domain_lock, flags);
Lu Baolua7fc93f2018-07-14 15:47:00 +08002673
Lu Baolu0bbeb012018-12-10 09:58:56 +08002674 /* PASID table is mandatory for a PCI device in scalable mode. */
2675 if (dev && dev_is_pci(dev) && sm_supported(iommu)) {
Lu Baolua7fc93f2018-07-14 15:47:00 +08002676 ret = intel_pasid_alloc_table(dev);
2677 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002678 dev_err(dev, "PASID table allocation failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002679 dmar_remove_one_dev_info(dev);
Lu Baolu0bbeb012018-12-10 09:58:56 +08002680 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002681 }
Lu Baoluef848b72018-12-10 09:59:01 +08002682
2683 /* Setup the PASID entry for requests without PASID: */
2684 spin_lock(&iommu->lock);
2685 if (hw_pass_through && domain_type_is_si(domain))
2686 ret = intel_pasid_setup_pass_through(iommu, domain,
2687 dev, PASID_RID2PASID);
Lu Baoluddf09b62020-01-02 08:18:17 +08002688 else if (domain_use_first_level(domain))
2689 ret = domain_setup_first_level(iommu, domain, dev,
2690 PASID_RID2PASID);
Lu Baoluef848b72018-12-10 09:59:01 +08002691 else
2692 ret = intel_pasid_setup_second_level(iommu, domain,
2693 dev, PASID_RID2PASID);
2694 spin_unlock(&iommu->lock);
2695 if (ret) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002696 dev_err(dev, "Setup RID2PASID failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002697 dmar_remove_one_dev_info(dev);
Lu Baoluef848b72018-12-10 09:59:01 +08002698 return NULL;
Lu Baolua7fc93f2018-07-14 15:47:00 +08002699 }
2700 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002701
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002702 if (dev && domain_context_mapping(domain, dev)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002703 dev_err(dev, "Domain context map failed\n");
Bjorn Helgaas71753232019-02-08 16:06:15 -06002704 dmar_remove_one_dev_info(dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002705 return NULL;
2706 }
2707
David Woodhouseb718cd32014-03-09 13:11:33 -07002708 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002709}
2710
Alex Williamson579305f2014-07-03 09:51:43 -06002711static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2712{
2713 *(u16 *)opaque = alias;
2714 return 0;
2715}
2716
Joerg Roedel76208352016-08-25 14:25:12 +02002717static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002718{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06002719 struct device_domain_info *info;
Joerg Roedel76208352016-08-25 14:25:12 +02002720 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002721 struct intel_iommu *iommu;
Lu Baolufcc35c62018-05-04 13:08:17 +08002722 u16 dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002723 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002724 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002725
David Woodhouse146922e2014-03-09 15:44:17 -07002726 iommu = device_to_iommu(dev, &bus, &devfn);
2727 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002728 return NULL;
2729
2730 if (dev_is_pci(dev)) {
2731 struct pci_dev *pdev = to_pci_dev(dev);
2732
2733 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2734
2735 spin_lock_irqsave(&device_domain_lock, flags);
2736 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2737 PCI_BUS_NUM(dma_alias),
2738 dma_alias & 0xff);
2739 if (info) {
2740 iommu = info->iommu;
2741 domain = info->domain;
2742 }
2743 spin_unlock_irqrestore(&device_domain_lock, flags);
2744
Joerg Roedel76208352016-08-25 14:25:12 +02002745 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002746 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002747 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002748 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002749
David Woodhouse146922e2014-03-09 15:44:17 -07002750 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002751 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002752 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002753 return NULL;
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002754 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002755 domain_exit(domain);
2756 return NULL;
2757 }
2758
Joerg Roedel76208352016-08-25 14:25:12 +02002759out:
Joerg Roedel76208352016-08-25 14:25:12 +02002760 return domain;
2761}
2762
2763static struct dmar_domain *set_domain_for_dev(struct device *dev,
2764 struct dmar_domain *domain)
2765{
2766 struct intel_iommu *iommu;
2767 struct dmar_domain *tmp;
2768 u16 req_id, dma_alias;
2769 u8 bus, devfn;
2770
2771 iommu = device_to_iommu(dev, &bus, &devfn);
2772 if (!iommu)
2773 return NULL;
2774
2775 req_id = ((u16)bus << 8) | devfn;
2776
2777 if (dev_is_pci(dev)) {
2778 struct pci_dev *pdev = to_pci_dev(dev);
2779
2780 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2781
2782 /* register PCI DMA alias device */
2783 if (req_id != dma_alias) {
2784 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2785 dma_alias & 0xff, NULL, domain);
2786
2787 if (!tmp || tmp != domain)
2788 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002789 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002790 }
2791
Joerg Roedel5db31562015-07-22 12:40:43 +02002792 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002793 if (!tmp || tmp != domain)
2794 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002795
Joerg Roedel76208352016-08-25 14:25:12 +02002796 return domain;
2797}
2798
David Woodhouseb2132032009-06-26 18:50:28 +01002799static int iommu_domain_identity_map(struct dmar_domain *domain,
2800 unsigned long long start,
2801 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002802{
David Woodhousec5395d52009-06-28 16:35:56 +01002803 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2804 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002805
David Woodhousec5395d52009-06-28 16:35:56 +01002806 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2807 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002808 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002809 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002810 }
2811
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002812 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002813 /*
2814 * RMRR range might have overlap with physical memory range,
2815 * clear it first
2816 */
David Woodhousec5395d52009-06-28 16:35:56 +01002817 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002818
Peter Xu87684fd2018-05-04 10:34:53 +08002819 return __domain_mapping(domain, first_vpfn, NULL,
2820 first_vpfn, last_vpfn - first_vpfn + 1,
2821 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002822}
2823
Joerg Roedeld66ce542015-09-23 19:00:10 +02002824static int domain_prepare_identity_map(struct device *dev,
2825 struct dmar_domain *domain,
2826 unsigned long long start,
2827 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002828{
David Woodhouse19943b02009-08-04 16:19:20 +01002829 /* For _hardware_ passthrough, don't bother. But for software
2830 passthrough, we do it anyway -- it may indicate a memory
2831 range which is reserved in E820, so which didn't get set
2832 up to start with in si_domain */
2833 if (domain == si_domain && hw_pass_through) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002834 dev_warn(dev, "Ignoring identity map for HW passthrough [0x%Lx - 0x%Lx]\n",
2835 start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002836 return 0;
2837 }
2838
Bjorn Helgaas932a6522019-02-08 16:06:00 -06002839 dev_info(dev, "Setting identity map [0x%Lx - 0x%Lx]\n", start, end);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002840
David Woodhouse5595b522009-12-02 09:21:55 +00002841 if (end < start) {
2842 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2843 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2844 dmi_get_system_info(DMI_BIOS_VENDOR),
2845 dmi_get_system_info(DMI_BIOS_VERSION),
2846 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002847 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002848 }
2849
David Woodhouse2ff729f2009-08-26 14:25:41 +01002850 if (end >> agaw_to_width(domain->agaw)) {
2851 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2852 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2853 agaw_to_width(domain->agaw),
2854 dmi_get_system_info(DMI_BIOS_VENDOR),
2855 dmi_get_system_info(DMI_BIOS_VERSION),
2856 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002857 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002858 }
David Woodhouse19943b02009-08-04 16:19:20 +01002859
Joerg Roedeld66ce542015-09-23 19:00:10 +02002860 return iommu_domain_identity_map(domain, start, end);
2861}
2862
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002863static int md_domain_init(struct dmar_domain *domain, int guest_width);
2864
Matt Kraai071e1372009-08-23 22:30:22 -07002865static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002866{
Lu Baolu4de354e2019-05-25 13:41:27 +08002867 struct dmar_rmrr_unit *rmrr;
2868 struct device *dev;
2869 int i, nid, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002870
Jiang Liuab8dfe22014-07-11 14:19:27 +08002871 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002872 if (!si_domain)
2873 return -EFAULT;
2874
Joerg Roedel301e7ee2019-07-22 16:21:05 +02002875 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002876 domain_exit(si_domain);
2877 return -EFAULT;
2878 }
2879
David Woodhouse19943b02009-08-04 16:19:20 +01002880 if (hw)
2881 return 0;
2882
David Woodhousec7ab48d2009-06-26 19:10:36 +01002883 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002884 unsigned long start_pfn, end_pfn;
2885 int i;
2886
2887 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2888 ret = iommu_domain_identity_map(si_domain,
2889 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2890 if (ret)
2891 return ret;
2892 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002893 }
2894
Lu Baolu4de354e2019-05-25 13:41:27 +08002895 /*
2896 * Normally we use DMA domains for devices which have RMRRs. But we
2897 * loose this requirement for graphic and usb devices. Identity map
2898 * the RMRRs for graphic and USB devices so that they could use the
2899 * si_domain.
2900 */
2901 for_each_rmrr_units(rmrr) {
2902 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
2903 i, dev) {
2904 unsigned long long start = rmrr->base_address;
2905 unsigned long long end = rmrr->end_address;
2906
2907 if (device_is_rmrr_locked(dev))
2908 continue;
2909
2910 if (WARN_ON(end < start ||
2911 end >> agaw_to_width(si_domain->agaw)))
2912 continue;
2913
2914 ret = iommu_domain_identity_map(si_domain, start, end);
2915 if (ret)
2916 return ret;
2917 }
2918 }
2919
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002920 return 0;
2921}
2922
David Woodhouse9b226622014-03-09 14:03:28 -07002923static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002924{
2925 struct device_domain_info *info;
2926
David Woodhouse9b226622014-03-09 14:03:28 -07002927 info = dev->archdata.iommu;
John Donnelly160c63f2019-10-21 21:48:10 -05002928 if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO)
Mike Traviscb452a42011-05-28 13:15:03 -05002929 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002930
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002931 return 0;
2932}
2933
Joerg Roedel28ccce02015-07-21 14:45:31 +02002934static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002935{
David Woodhouse0ac72662014-03-09 13:19:22 -07002936 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002937 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002938 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002939
David Woodhouse5913c9b2014-03-09 16:27:31 -07002940 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002941 if (!iommu)
2942 return -ENODEV;
2943
Joerg Roedel5db31562015-07-22 12:40:43 +02002944 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002945 if (ndomain != domain)
2946 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002947
2948 return 0;
2949}
2950
David Woodhouse0b9d9752014-03-09 15:48:15 -07002951static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002952{
2953 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002954 struct device *tmp;
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002955 int i;
2956
Jiang Liu0e242612014-02-19 14:07:34 +08002957 rcu_read_lock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002958 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002959 /*
2960 * Return TRUE if this RMRR contains the device that
2961 * is passed in.
2962 */
2963 for_each_active_dev_scope(rmrr->devices,
2964 rmrr->devices_cnt, i, tmp)
Eric Augere143fd42019-06-03 08:53:33 +02002965 if (tmp == dev ||
2966 is_downstream_to_pci_bridge(dev, tmp)) {
Jiang Liu0e242612014-02-19 14:07:34 +08002967 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002968 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002969 }
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002970 }
Jiang Liu0e242612014-02-19 14:07:34 +08002971 rcu_read_unlock();
Tom Mingarelliea2447f72012-11-20 19:43:17 +00002972 return false;
2973}
2974
Eric Auger1c5c59f2019-06-03 08:53:36 +02002975/**
2976 * device_rmrr_is_relaxable - Test whether the RMRR of this device
2977 * is relaxable (ie. is allowed to be not enforced under some conditions)
2978 * @dev: device handle
2979 *
2980 * We assume that PCI USB devices with RMRRs have them largely
2981 * for historical reasons and that the RMRR space is not actively used post
2982 * boot. This exclusion may change if vendors begin to abuse it.
2983 *
2984 * The same exception is made for graphics devices, with the requirement that
2985 * any use of the RMRR regions will be torn down before assigning the device
2986 * to a guest.
2987 *
2988 * Return: true if the RMRR is relaxable, false otherwise
2989 */
2990static bool device_rmrr_is_relaxable(struct device *dev)
2991{
2992 struct pci_dev *pdev;
2993
2994 if (!dev_is_pci(dev))
2995 return false;
2996
2997 pdev = to_pci_dev(dev);
2998 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
2999 return true;
3000 else
3001 return false;
3002}
3003
Alex Williamsonc875d2c2014-07-03 09:57:02 -06003004/*
3005 * There are a couple cases where we need to restrict the functionality of
3006 * devices associated with RMRRs. The first is when evaluating a device for
3007 * identity mapping because problems exist when devices are moved in and out
3008 * of domains and their respective RMRR information is lost. This means that
3009 * a device with associated RMRRs will never be in a "passthrough" domain.
3010 * The second is use of the device through the IOMMU API. This interface
3011 * expects to have full control of the IOVA space for the device. We cannot
3012 * satisfy both the requirement that RMRR access is maintained and have an
3013 * unencumbered IOVA space. We also have no ability to quiesce the device's
3014 * use of the RMRR space or even inform the IOMMU API user of the restriction.
3015 * We therefore prevent devices associated with an RMRR from participating in
3016 * the IOMMU API, which eliminates them from device assignment.
3017 *
Eric Auger1c5c59f2019-06-03 08:53:36 +02003018 * In both cases, devices which have relaxable RMRRs are not concerned by this
3019 * restriction. See device_rmrr_is_relaxable comment.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06003020 */
3021static bool device_is_rmrr_locked(struct device *dev)
3022{
3023 if (!device_has_rmrr(dev))
3024 return false;
3025
Eric Auger1c5c59f2019-06-03 08:53:36 +02003026 if (device_rmrr_is_relaxable(dev))
3027 return false;
Alex Williamsonc875d2c2014-07-03 09:57:02 -06003028
3029 return true;
3030}
3031
Lu Baoluf273a452019-05-25 13:41:26 +08003032/*
3033 * Return the required default domain type for a specific device.
3034 *
3035 * @dev: the device in query
3036 * @startup: true if this is during early boot
3037 *
3038 * Returns:
3039 * - IOMMU_DOMAIN_DMA: device requires a dynamic mapping domain
3040 * - IOMMU_DOMAIN_IDENTITY: device requires an identical mapping domain
3041 * - 0: both identity and dynamic domains work for this device
3042 */
Lu Baolu0e31a722019-05-25 13:41:34 +08003043static int device_def_domain_type(struct device *dev)
David Woodhouse6941af22009-07-04 18:24:27 +01003044{
David Woodhouse3bdb2592014-03-09 16:03:08 -07003045 if (dev_is_pci(dev)) {
3046 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f72012-11-20 19:43:17 +00003047
Alex Williamsonc875d2c2014-07-03 09:57:02 -06003048 if (device_is_rmrr_locked(dev))
Lu Baoluf273a452019-05-25 13:41:26 +08003049 return IOMMU_DOMAIN_DMA;
David Woodhousee0fc7e02009-09-30 09:12:17 -07003050
Lu Baolu89a60792018-10-23 15:45:01 +08003051 /*
3052 * Prevent any device marked as untrusted from getting
3053 * placed into the statically identity mapping domain.
3054 */
3055 if (pdev->untrusted)
Lu Baoluf273a452019-05-25 13:41:26 +08003056 return IOMMU_DOMAIN_DMA;
Lu Baolu89a60792018-10-23 15:45:01 +08003057
David Woodhouse3bdb2592014-03-09 16:03:08 -07003058 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08003059 return IOMMU_DOMAIN_IDENTITY;
David Woodhousee0fc7e02009-09-30 09:12:17 -07003060
David Woodhouse3bdb2592014-03-09 16:03:08 -07003061 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
Lu Baoluf273a452019-05-25 13:41:26 +08003062 return IOMMU_DOMAIN_IDENTITY;
David Woodhouse3bdb2592014-03-09 16:03:08 -07003063
3064 /*
3065 * We want to start off with all devices in the 1:1 domain, and
3066 * take them out later if we find they can't access all of memory.
3067 *
3068 * However, we can't do this for PCI devices behind bridges,
3069 * because all PCI devices behind the same bridge will end up
3070 * with the same source-id on their transactions.
3071 *
3072 * Practically speaking, we can't change things around for these
3073 * devices at run-time, because we can't be sure there'll be no
3074 * DMA transactions in flight for any of their siblings.
3075 *
3076 * So PCI devices (unless they're on the root bus) as well as
3077 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
3078 * the 1:1 domain, just in _case_ one of their siblings turns out
3079 * not to be able to map all of memory.
3080 */
3081 if (!pci_is_pcie(pdev)) {
3082 if (!pci_is_root_bus(pdev->bus))
Lu Baoluf273a452019-05-25 13:41:26 +08003083 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07003084 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
Lu Baoluf273a452019-05-25 13:41:26 +08003085 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07003086 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
Lu Baoluf273a452019-05-25 13:41:26 +08003087 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07003088 } else {
3089 if (device_has_rmrr(dev))
Lu Baoluf273a452019-05-25 13:41:26 +08003090 return IOMMU_DOMAIN_DMA;
David Woodhouse3bdb2592014-03-09 16:03:08 -07003091 }
David Woodhouse6941af22009-07-04 18:24:27 +01003092
Lu Baoluf273a452019-05-25 13:41:26 +08003093 return (iommu_identity_mapping & IDENTMAP_ALL) ?
3094 IOMMU_DOMAIN_IDENTITY : 0;
3095}
3096
Jiang Liuffebeb42014-11-09 22:48:02 +08003097static void intel_iommu_init_qi(struct intel_iommu *iommu)
3098{
3099 /*
3100 * Start from the sane iommu hardware state.
3101 * If the queued invalidation is already initialized by us
3102 * (for example, while enabling interrupt-remapping) then
3103 * we got the things already rolling from a sane state.
3104 */
3105 if (!iommu->qi) {
3106 /*
3107 * Clear any previous faults.
3108 */
3109 dmar_fault(-1, iommu);
3110 /*
3111 * Disable queued invalidation if supported and already enabled
3112 * before OS handover.
3113 */
3114 dmar_disable_qi(iommu);
3115 }
3116
3117 if (dmar_enable_qi(iommu)) {
3118 /*
3119 * Queued Invalidate not enabled, use Register Based Invalidate
3120 */
3121 iommu->flush.flush_context = __iommu_flush_context;
3122 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003123 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003124 iommu->name);
3125 } else {
3126 iommu->flush.flush_context = qi_flush_context;
3127 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003128 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003129 }
3130}
3131
Joerg Roedel091d42e2015-06-12 11:56:10 +02003132static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb962015-10-09 18:16:46 -04003133 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003134 struct context_entry **tbl,
3135 int bus, bool ext)
3136{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003137 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003138 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb962015-10-09 18:16:46 -04003139 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003140 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003141 phys_addr_t old_ce_phys;
3142
3143 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb962015-10-09 18:16:46 -04003144 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003145
3146 for (devfn = 0; devfn < 256; devfn++) {
3147 /* First calculate the correct index */
3148 idx = (ext ? devfn * 2 : devfn) % 256;
3149
3150 if (idx == 0) {
3151 /* First save what we may have and clean up */
3152 if (new_ce) {
3153 tbl[tbl_idx] = new_ce;
3154 __iommu_flush_cache(iommu, new_ce,
3155 VTD_PAGE_SIZE);
3156 pos = 1;
3157 }
3158
3159 if (old_ce)
Pan Bian829383e2018-11-21 17:53:47 +08003160 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003161
3162 ret = 0;
3163 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003164 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003165 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003166 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003167
3168 if (!old_ce_phys) {
3169 if (ext && devfn == 0) {
3170 /* No LCTP, try UCTP */
3171 devfn = 0x7f;
3172 continue;
3173 } else {
3174 goto out;
3175 }
3176 }
3177
3178 ret = -ENOMEM;
Dan Williamsdfddb962015-10-09 18:16:46 -04003179 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3180 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003181 if (!old_ce)
3182 goto out;
3183
3184 new_ce = alloc_pgtable_page(iommu->node);
3185 if (!new_ce)
3186 goto out_unmap;
3187
3188 ret = 0;
3189 }
3190
3191 /* Now copy the context entry */
Dan Williamsdfddb962015-10-09 18:16:46 -04003192 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003193
Joerg Roedelcf484d02015-06-12 12:21:46 +02003194 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003195 continue;
3196
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003197 did = context_domain_id(&ce);
3198 if (did >= 0 && did < cap_ndoms(iommu->cap))
3199 set_bit(did, iommu->domain_ids);
3200
Joerg Roedelcf484d02015-06-12 12:21:46 +02003201 /*
3202 * We need a marker for copied context entries. This
3203 * marker needs to work for the old format as well as
3204 * for extended context entries.
3205 *
3206 * Bit 67 of the context entry is used. In the old
3207 * format this bit is available to software, in the
3208 * extended format it is the PGE bit, but PGE is ignored
3209 * by HW if PASIDs are disabled (and thus still
3210 * available).
3211 *
3212 * So disable PASIDs first and then mark the entry
3213 * copied. This means that we don't copy PASID
3214 * translations from the old kernel, but this is fine as
3215 * faults there are not fatal.
3216 */
3217 context_clear_pasid_enable(&ce);
3218 context_set_copied(&ce);
3219
Joerg Roedel091d42e2015-06-12 11:56:10 +02003220 new_ce[idx] = ce;
3221 }
3222
3223 tbl[tbl_idx + pos] = new_ce;
3224
3225 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3226
3227out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003228 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003229
3230out:
3231 return ret;
3232}
3233
3234static int copy_translation_tables(struct intel_iommu *iommu)
3235{
3236 struct context_entry **ctxt_tbls;
Dan Williamsdfddb962015-10-09 18:16:46 -04003237 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003238 phys_addr_t old_rt_phys;
3239 int ctxt_table_entries;
3240 unsigned long flags;
3241 u64 rtaddr_reg;
3242 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003243 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003244
3245 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3246 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003247 new_ext = !!ecap_ecs(iommu->ecap);
3248
3249 /*
3250 * The RTT bit can only be changed when translation is disabled,
3251 * but disabling translation means to open a window for data
3252 * corruption. So bail out and don't copy anything if we would
3253 * have to change the bit.
3254 */
3255 if (new_ext != ext)
3256 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003257
3258 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3259 if (!old_rt_phys)
3260 return -EINVAL;
3261
Dan Williamsdfddb962015-10-09 18:16:46 -04003262 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003263 if (!old_rt)
3264 return -ENOMEM;
3265
3266 /* This is too big for the stack - allocate it from slab */
3267 ctxt_table_entries = ext ? 512 : 256;
3268 ret = -ENOMEM;
Kees Cook6396bb22018-06-12 14:03:40 -07003269 ctxt_tbls = kcalloc(ctxt_table_entries, sizeof(void *), GFP_KERNEL);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003270 if (!ctxt_tbls)
3271 goto out_unmap;
3272
3273 for (bus = 0; bus < 256; bus++) {
3274 ret = copy_context_table(iommu, &old_rt[bus],
3275 ctxt_tbls, bus, ext);
3276 if (ret) {
3277 pr_err("%s: Failed to copy context table for bus %d\n",
3278 iommu->name, bus);
3279 continue;
3280 }
3281 }
3282
3283 spin_lock_irqsave(&iommu->lock, flags);
3284
3285 /* Context tables are copied, now write them to the root_entry table */
3286 for (bus = 0; bus < 256; bus++) {
3287 int idx = ext ? bus * 2 : bus;
3288 u64 val;
3289
3290 if (ctxt_tbls[idx]) {
3291 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3292 iommu->root_entry[bus].lo = val;
3293 }
3294
3295 if (!ext || !ctxt_tbls[idx + 1])
3296 continue;
3297
3298 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3299 iommu->root_entry[bus].hi = val;
3300 }
3301
3302 spin_unlock_irqrestore(&iommu->lock, flags);
3303
3304 kfree(ctxt_tbls);
3305
3306 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3307
3308 ret = 0;
3309
3310out_unmap:
Dan Williamsdfddb962015-10-09 18:16:46 -04003311 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003312
3313 return ret;
3314}
3315
Joseph Cihulab7792602011-05-03 00:08:37 -07003316static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003317{
3318 struct dmar_drhd_unit *drhd;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003319 struct intel_iommu *iommu;
Lu Baoludf4f3c62019-05-25 13:41:36 +08003320 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003321
3322 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003323 * for each drhd
3324 * allocate root
3325 * initialize and program root entry to not present
3326 * endfor
3327 */
3328 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003329 /*
3330 * lock not needed as this is only incremented in the single
3331 * threaded kernel __init code path all other access are read
3332 * only
3333 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003334 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003335 g_num_of_iommus++;
3336 continue;
3337 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003338 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003339 }
3340
Jiang Liuffebeb42014-11-09 22:48:02 +08003341 /* Preallocate enough resources for IOMMU hot-addition */
3342 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3343 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3344
Weidong Hand9630fe2008-12-08 11:06:32 +08003345 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3346 GFP_KERNEL);
3347 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003348 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003349 ret = -ENOMEM;
3350 goto error;
3351 }
3352
Lu Baolu6a8c6742019-06-12 08:28:47 +08003353 for_each_iommu(iommu, drhd) {
3354 if (drhd->ignored) {
3355 iommu_disable_translation(iommu);
3356 continue;
3357 }
3358
Lu Baolu56283172018-07-14 15:46:54 +08003359 /*
3360 * Find the max pasid size of all IOMMU's in the system.
3361 * We need to ensure the system pasid table is no bigger
3362 * than the smallest supported.
3363 */
Lu Baolu765b6a92018-12-10 09:58:55 +08003364 if (pasid_supported(iommu)) {
Lu Baolu56283172018-07-14 15:46:54 +08003365 u32 temp = 2 << ecap_pss(iommu->ecap);
3366
3367 intel_pasid_max_id = min_t(u32, temp,
3368 intel_pasid_max_id);
3369 }
3370
Weidong Hand9630fe2008-12-08 11:06:32 +08003371 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003372
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003373 intel_iommu_init_qi(iommu);
3374
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003375 ret = iommu_init_domains(iommu);
3376 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003377 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003378
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003379 init_translation_status(iommu);
3380
Joerg Roedel091d42e2015-06-12 11:56:10 +02003381 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3382 iommu_disable_translation(iommu);
3383 clear_translation_pre_enabled(iommu);
3384 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3385 iommu->name);
3386 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003387
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003388 /*
3389 * TBD:
3390 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003391 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003392 */
3393 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003394 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003395 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003396
Joerg Roedel091d42e2015-06-12 11:56:10 +02003397 if (translation_pre_enabled(iommu)) {
3398 pr_info("Translation already enabled - trying to copy translation structures\n");
3399
3400 ret = copy_translation_tables(iommu);
3401 if (ret) {
3402 /*
3403 * We found the IOMMU with translation
3404 * enabled - but failed to copy over the
3405 * old root-entry table. Try to proceed
3406 * by disabling translation now and
3407 * allocating a clean root-entry table.
3408 * This might cause DMAR faults, but
3409 * probably the dump will still succeed.
3410 */
3411 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3412 iommu->name);
3413 iommu_disable_translation(iommu);
3414 clear_translation_pre_enabled(iommu);
3415 } else {
3416 pr_info("Copied translation tables from previous kernel for %s\n",
3417 iommu->name);
3418 }
3419 }
3420
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003421 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003422 hw_pass_through = 0;
Jacob Panff3dc652020-01-02 08:18:03 +08003423 intel_svm_check(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003424 }
3425
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003426 /*
3427 * Now that qi is enabled on all iommus, set the root entry and flush
3428 * caches. This is required on some Intel X58 chipsets, otherwise the
3429 * flush_context function will loop forever and the boot hangs.
3430 */
3431 for_each_active_iommu(iommu, drhd) {
3432 iommu_flush_write_buffer(iommu);
3433 iommu_set_root_entry(iommu);
3434 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3435 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3436 }
3437
Joerg Roedel6b9a7d32019-08-19 15:22:50 +02003438 if (iommu_default_passthrough())
David Woodhousee0fc7e02009-09-30 09:12:17 -07003439 iommu_identity_mapping |= IDENTMAP_ALL;
3440
Suresh Siddhad3f13812011-08-23 17:05:25 -07003441#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
Lu Baolu5daab582019-05-02 09:34:26 +08003442 dmar_map_gfx = 0;
David Woodhouse19943b02009-08-04 16:19:20 +01003443#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003444
Lu Baolu5daab582019-05-02 09:34:26 +08003445 if (!dmar_map_gfx)
3446 iommu_identity_mapping |= IDENTMAP_GFX;
3447
Ashok Raj21e722c2017-01-30 09:39:53 -08003448 check_tylersburg_isoch();
3449
Lu Baolu4de354e2019-05-25 13:41:27 +08003450 ret = si_domain_init(hw_pass_through);
3451 if (ret)
3452 goto free_iommu;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003453
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003454 /*
3455 * for each drhd
3456 * enable fault log
3457 * global invalidate context cache
3458 * global invalidate iotlb
3459 * enable translation
3460 */
Jiang Liu7c919772014-01-06 14:18:18 +08003461 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003462 if (drhd->ignored) {
3463 /*
3464 * we always have to disable PMRs or DMA may fail on
3465 * this device
3466 */
3467 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003468 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003469 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003470 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003471
3472 iommu_flush_write_buffer(iommu);
3473
David Woodhousea222a7f2015-10-07 23:35:18 +01003474#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08003475 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
Lu Baolua7755c32019-04-19 14:43:29 +08003476 /*
3477 * Call dmar_alloc_hwirq() with dmar_global_lock held,
3478 * could cause possible lock race condition.
3479 */
3480 up_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003481 ret = intel_svm_enable_prq(iommu);
Lu Baolua7755c32019-04-19 14:43:29 +08003482 down_write(&dmar_global_lock);
David Woodhousea222a7f2015-10-07 23:35:18 +01003483 if (ret)
3484 goto free_iommu;
3485 }
3486#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003487 ret = dmar_set_interrupt(iommu);
3488 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003489 goto free_iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003490 }
3491
3492 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003493
3494free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003495 for_each_active_iommu(iommu, drhd) {
3496 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003497 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003498 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003499
Weidong Hand9630fe2008-12-08 11:06:32 +08003500 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003501
Jiang Liu989d51f2014-02-19 14:07:21 +08003502error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003503 return ret;
3504}
3505
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003506/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003507static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003508 struct dmar_domain *domain,
3509 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003510{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06003511 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003512
Lu Baolucb8b8922020-01-02 08:18:19 +08003513 /*
3514 * Restrict dma_mask to the width that the iommu can handle.
3515 * First-level translation restricts the input-address to a
3516 * canonical address (i.e., address bits 63:N have the same
3517 * value as address bit [N-1], where N is 48-bits with 4-level
3518 * paging and 57-bits with 5-level paging). Hence, skip bit
3519 * [N-1].
3520 */
3521 if (domain_use_first_level(domain))
3522 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw - 1),
3523 dma_mask);
3524 else
3525 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw),
3526 dma_mask);
3527
Robin Murphy8f6429c2015-07-16 19:40:12 +01003528 /* Ensure we reserve the whole size-aligned region */
3529 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003530
3531 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003532 /*
3533 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003534 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003535 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003536 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003537 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003538 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003539 if (iova_pfn)
3540 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003541 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003542 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3543 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003544 if (unlikely(!iova_pfn)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003545 dev_err(dev, "Allocating %ld-page iova failed", nrpages);
Omer Peleg2aac6302016-04-20 11:33:57 +03003546 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003547 }
3548
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003549 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003550}
3551
Lu Baolu4ec066c2019-05-25 13:41:33 +08003552static struct dmar_domain *get_private_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003553{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003554 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003555 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003556 struct device *i_dev;
3557 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003558
Lu Baolu4ec066c2019-05-25 13:41:33 +08003559 /* Device shouldn't be attached by any domains. */
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003560 domain = find_domain(dev);
3561 if (domain)
Lu Baolu4ec066c2019-05-25 13:41:33 +08003562 return NULL;
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003563
3564 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3565 if (!domain)
3566 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003567
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003568 /* We have a new domain - setup possible RMRRs for the device */
3569 rcu_read_lock();
3570 for_each_rmrr_units(rmrr) {
3571 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3572 i, i_dev) {
3573 if (i_dev != dev)
3574 continue;
3575
3576 ret = domain_prepare_identity_map(dev, domain,
3577 rmrr->base_address,
3578 rmrr->end_address);
3579 if (ret)
3580 dev_err(dev, "Mapping reserved region failed\n");
3581 }
3582 }
3583 rcu_read_unlock();
3584
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003585 tmp = set_domain_for_dev(dev, domain);
3586 if (!tmp || domain != tmp) {
3587 domain_exit(domain);
3588 domain = tmp;
3589 }
3590
3591out:
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003592 if (!domain)
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003593 dev_err(dev, "Allocating domain failed\n");
Lu Baoluc57b2602019-06-12 08:28:46 +08003594 else
3595 domain->domain.type = IOMMU_DOMAIN_DMA;
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003596
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003597 return domain;
3598}
3599
David Woodhouseecb509e2014-03-09 16:29:55 -07003600/* Check if the dev needs to go through non-identity map and unmap process.*/
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003601static bool iommu_need_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003602{
Lu Baolu98b2fff2019-05-25 13:41:30 +08003603 int ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003604
David Woodhouse3d891942014-03-06 15:59:26 +00003605 if (iommu_dummy(dev))
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003606 return false;
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003607
Lu Baolu98b2fff2019-05-25 13:41:30 +08003608 ret = identity_mapping(dev);
3609 if (ret) {
3610 u64 dma_mask = *dev->dma_mask;
3611
3612 if (dev->coherent_dma_mask && dev->coherent_dma_mask < dma_mask)
3613 dma_mask = dev->coherent_dma_mask;
3614
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003615 if (dma_mask >= dma_direct_get_required_mask(dev))
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003616 return false;
3617
3618 /*
3619 * 32 bit DMA is removed from si_domain and fall back to
3620 * non-identity mapping.
3621 */
3622 dmar_remove_one_dev_info(dev);
Lu Baolu98b2fff2019-05-25 13:41:30 +08003623 ret = iommu_request_dma_domain_for_dev(dev);
3624 if (ret) {
3625 struct iommu_domain *domain;
3626 struct dmar_domain *dmar_domain;
3627
3628 domain = iommu_get_domain_for_dev(dev);
3629 if (domain) {
3630 dmar_domain = to_dmar_domain(domain);
3631 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
3632 }
Lu Baoluae23bfb62019-08-06 08:14:08 +08003633 dmar_remove_one_dev_info(dev);
Lu Baolu4ec066c2019-05-25 13:41:33 +08003634 get_private_domain_for_dev(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003635 }
Lu Baolu98b2fff2019-05-25 13:41:30 +08003636
3637 dev_info(dev, "32bit DMA uses non-identity mapping\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003638 }
3639
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003640 return true;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003641}
3642
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003643static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
3644 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003645{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003646 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003647 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003648 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003649 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003650 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003651 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003652 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003653
3654 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003655
Lu Baolu1ee0186b2019-09-21 15:06:44 +08003656 domain = deferred_attach_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003657 if (!domain)
Christoph Hellwig524a6692018-11-21 19:34:10 +01003658 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003659
Weidong Han8c11e792008-12-08 15:29:22 +08003660 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003661 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003662
Omer Peleg2aac6302016-04-20 11:33:57 +03003663 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3664 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003665 goto error;
3666
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003667 /*
3668 * Check if DMAR supports zero-length reads on write only
3669 * mappings..
3670 */
3671 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003672 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003673 prot |= DMA_PTE_READ;
3674 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3675 prot |= DMA_PTE_WRITE;
3676 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003677 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003678 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003679 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003680 * is not a big problem
3681 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003682 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003683 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003684 if (ret)
3685 goto error;
3686
Omer Peleg2aac6302016-04-20 11:33:57 +03003687 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003688 start_paddr += paddr & ~PAGE_MASK;
Lu Baolu3b530342019-09-06 14:14:51 +08003689
3690 trace_map_single(dev, start_paddr, paddr, size << VTD_PAGE_SHIFT);
3691
David Woodhouse03d6a242009-06-28 15:33:46 +01003692 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003693
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003694error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003695 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003696 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Bjorn Helgaas932a6522019-02-08 16:06:00 -06003697 dev_err(dev, "Device request: %zx@%llx dir %d --- failed\n",
3698 size, (unsigned long long)paddr, dir);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003699 return DMA_MAPPING_ERROR;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003700}
3701
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003702static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3703 unsigned long offset, size_t size,
3704 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003705 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003706{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003707 if (iommu_need_mapping(dev))
3708 return __intel_map_single(dev, page_to_phys(page) + offset,
3709 size, dir, *dev->dma_mask);
3710 return dma_direct_map_page(dev, page, offset, size, dir, attrs);
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003711}
3712
3713static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
3714 size_t size, enum dma_data_direction dir,
3715 unsigned long attrs)
3716{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003717 if (iommu_need_mapping(dev))
3718 return __intel_map_single(dev, phys_addr, size, dir,
3719 *dev->dma_mask);
3720 return dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003721}
3722
Omer Peleg769530e2016-04-20 11:33:25 +03003723static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003724{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003725 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003726 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003727 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003728 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003729 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003730 struct page *freelist;
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003731 struct pci_dev *pdev = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003732
David Woodhouse1525a292014-03-06 16:19:30 +00003733 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003734 BUG_ON(!domain);
3735
Weidong Han8c11e792008-12-08 15:29:22 +08003736 iommu = domain_get_iommu(domain);
3737
Omer Peleg2aac6302016-04-20 11:33:57 +03003738 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003739
Omer Peleg769530e2016-04-20 11:33:25 +03003740 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003741 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003742 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003743
Lu Baoluf7b0c4c2019-04-12 12:26:13 +08003744 if (dev_is_pci(dev))
3745 pdev = to_pci_dev(dev);
3746
David Woodhouseea8ea462014-03-05 17:09:32 +00003747 freelist = domain_unmap(domain, start_pfn, last_pfn);
Dmitry Safonoveffa4672019-07-16 22:38:05 +01003748 if (intel_iommu_strict || (pdev && pdev->untrusted) ||
3749 !has_iova_flush_queue(&domain->iovad)) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003750 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003751 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003752 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003753 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003754 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003755 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003756 queue_iova(&domain->iovad, iova_pfn, nrpages,
3757 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003758 /*
3759 * queue up the release of the unmap to save the 1/6th of the
3760 * cpu used up by the iotlb flush operation...
3761 */
mark gross5e0d2a62008-03-04 15:22:08 -08003762 }
Lu Baolu3b530342019-09-06 14:14:51 +08003763
3764 trace_unmap_single(dev, dev_addr, size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003765}
3766
Jiang Liud41a4ad2014-07-11 14:19:34 +08003767static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3768 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003769 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003770{
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003771 if (iommu_need_mapping(dev))
3772 intel_unmap(dev, dev_addr, size);
3773 else
3774 dma_direct_unmap_page(dev, dev_addr, size, dir, attrs);
3775}
3776
3777static void intel_unmap_resource(struct device *dev, dma_addr_t dev_addr,
3778 size_t size, enum dma_data_direction dir, unsigned long attrs)
3779{
3780 if (iommu_need_mapping(dev))
3781 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003782}
3783
David Woodhouse5040a912014-03-09 16:14:00 -07003784static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003785 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003786 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003787{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003788 struct page *page = NULL;
3789 int order;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003790
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003791 if (!iommu_need_mapping(dev))
3792 return dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3793
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003794 size = PAGE_ALIGN(size);
3795 order = get_order(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003796
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003797 if (gfpflags_allow_blocking(flags)) {
3798 unsigned int count = size >> PAGE_SHIFT;
3799
Marek Szyprowskid834c5a2018-08-17 15:49:00 -07003800 page = dma_alloc_from_contiguous(dev, count, order,
3801 flags & __GFP_NOWARN);
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003802 }
3803
3804 if (!page)
3805 page = alloc_pages(flags, order);
3806 if (!page)
3807 return NULL;
3808 memset(page_address(page), 0, size);
3809
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003810 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
3811 DMA_BIDIRECTIONAL,
3812 dev->coherent_dma_mask);
Christoph Hellwig524a6692018-11-21 19:34:10 +01003813 if (*dma_handle != DMA_MAPPING_ERROR)
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003814 return page_address(page);
3815 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3816 __free_pages(page, order);
3817
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003818 return NULL;
3819}
3820
David Woodhouse5040a912014-03-09 16:14:00 -07003821static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003822 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003823{
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003824 int order;
3825 struct page *page = virt_to_page(vaddr);
3826
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003827 if (!iommu_need_mapping(dev))
3828 return dma_direct_free(dev, size, vaddr, dma_handle, attrs);
3829
Christoph Hellwig7ec916f2018-07-05 13:29:55 -06003830 size = PAGE_ALIGN(size);
3831 order = get_order(size);
3832
3833 intel_unmap(dev, dma_handle, size);
3834 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3835 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003836}
3837
David Woodhouse5040a912014-03-09 16:14:00 -07003838static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003839 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003840 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003841{
Omer Peleg769530e2016-04-20 11:33:25 +03003842 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3843 unsigned long nrpages = 0;
3844 struct scatterlist *sg;
3845 int i;
3846
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003847 if (!iommu_need_mapping(dev))
3848 return dma_direct_unmap_sg(dev, sglist, nelems, dir, attrs);
3849
Omer Peleg769530e2016-04-20 11:33:25 +03003850 for_each_sg(sglist, sg, nelems, i) {
3851 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3852 }
3853
3854 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Lu Baolu3b530342019-09-06 14:14:51 +08003855
3856 trace_unmap_sg(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003857}
3858
David Woodhouse5040a912014-03-09 16:14:00 -07003859static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003860 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003861{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003862 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003863 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003864 size_t size = 0;
3865 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003866 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003867 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003868 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003869 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003870 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003871
3872 BUG_ON(dir == DMA_NONE);
Christoph Hellwig48b2c932019-04-10 18:14:06 +02003873 if (!iommu_need_mapping(dev))
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003874 return dma_direct_map_sg(dev, sglist, nelems, dir, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003875
Lu Baolu1ee0186b2019-09-21 15:06:44 +08003876 domain = deferred_attach_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003877 if (!domain)
3878 return 0;
3879
Weidong Han8c11e792008-12-08 15:29:22 +08003880 iommu = domain_get_iommu(domain);
3881
David Woodhouseb536d242009-06-28 14:49:31 +01003882 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003883 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003884
Omer Peleg2aac6302016-04-20 11:33:57 +03003885 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003886 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003887 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003888 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003889 return 0;
3890 }
3891
3892 /*
3893 * Check if DMAR supports zero-length reads on write only
3894 * mappings..
3895 */
3896 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003897 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003898 prot |= DMA_PTE_READ;
3899 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3900 prot |= DMA_PTE_WRITE;
3901
Omer Peleg2aac6302016-04-20 11:33:57 +03003902 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003903
Fenghua Yuf5329592009-08-04 15:09:37 -07003904 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003905 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003906 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003907 start_vpfn + size - 1,
3908 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003909 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003910 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003911 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003912
Lu Baolu984d03a2020-01-02 08:18:11 +08003913 for_each_sg(sglist, sg, nelems, i)
3914 trace_map_sg(dev, i + 1, nelems, sg);
Lu Baolu3b530342019-09-06 14:14:51 +08003915
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003916 return nelems;
3917}
3918
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003919static u64 intel_get_required_mask(struct device *dev)
3920{
3921 if (!iommu_need_mapping(dev))
3922 return dma_direct_get_required_mask(dev);
3923 return DMA_BIT_MASK(32);
3924}
3925
Christoph Hellwig02b4da52018-09-17 19:10:31 +02003926static const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003927 .alloc = intel_alloc_coherent,
3928 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003929 .map_sg = intel_map_sg,
3930 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003931 .map_page = intel_map_page,
3932 .unmap_page = intel_unmap_page,
Logan Gunthorpe21d5d272019-01-22 14:30:45 -07003933 .map_resource = intel_map_resource,
Christoph Hellwig9cc0c2a2019-04-10 18:14:07 +02003934 .unmap_resource = intel_unmap_resource,
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003935 .dma_supported = dma_direct_supported,
Christoph Hellwigf9f32322019-08-06 15:01:50 +03003936 .mmap = dma_common_mmap,
3937 .get_sgtable = dma_common_get_sgtable,
Arvind Sankar9c24eaf2019-10-08 10:33:57 -04003938 .get_required_mask = intel_get_required_mask,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003939};
3940
Lu Baolucfb94a32019-09-06 14:14:52 +08003941static void
3942bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size,
3943 enum dma_data_direction dir, enum dma_sync_target target)
3944{
3945 struct dmar_domain *domain;
3946 phys_addr_t tlb_addr;
3947
3948 domain = find_domain(dev);
3949 if (WARN_ON(!domain))
3950 return;
3951
3952 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr);
3953 if (is_swiotlb_buffer(tlb_addr))
3954 swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target);
3955}
3956
3957static dma_addr_t
3958bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
3959 enum dma_data_direction dir, unsigned long attrs,
3960 u64 dma_mask)
3961{
3962 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
3963 struct dmar_domain *domain;
3964 struct intel_iommu *iommu;
3965 unsigned long iova_pfn;
3966 unsigned long nrpages;
3967 phys_addr_t tlb_addr;
3968 int prot = 0;
3969 int ret;
3970
Lu Baolu1ee0186b2019-09-21 15:06:44 +08003971 domain = deferred_attach_domain(dev);
Lu Baolucfb94a32019-09-06 14:14:52 +08003972 if (WARN_ON(dir == DMA_NONE || !domain))
3973 return DMA_MAPPING_ERROR;
3974
3975 iommu = domain_get_iommu(domain);
3976 if (WARN_ON(!iommu))
3977 return DMA_MAPPING_ERROR;
3978
3979 nrpages = aligned_nrpages(0, size);
3980 iova_pfn = intel_alloc_iova(dev, domain,
3981 dma_to_mm_pfn(nrpages), dma_mask);
3982 if (!iova_pfn)
3983 return DMA_MAPPING_ERROR;
3984
3985 /*
3986 * Check if DMAR supports zero-length reads on write only
3987 * mappings..
3988 */
3989 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ||
3990 !cap_zlr(iommu->cap))
3991 prot |= DMA_PTE_READ;
3992 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3993 prot |= DMA_PTE_WRITE;
3994
3995 /*
3996 * If both the physical buffer start address and size are
3997 * page aligned, we don't need to use a bounce page.
3998 */
3999 if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
4000 tlb_addr = swiotlb_tbl_map_single(dev,
4001 __phys_to_dma(dev, io_tlb_start),
4002 paddr, size, aligned_size, dir, attrs);
4003 if (tlb_addr == DMA_MAPPING_ERROR) {
4004 goto swiotlb_error;
4005 } else {
4006 /* Cleanup the padding area. */
4007 void *padding_start = phys_to_virt(tlb_addr);
4008 size_t padding_size = aligned_size;
4009
4010 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
4011 (dir == DMA_TO_DEVICE ||
4012 dir == DMA_BIDIRECTIONAL)) {
4013 padding_start += size;
4014 padding_size -= size;
4015 }
4016
4017 memset(padding_start, 0, padding_size);
4018 }
4019 } else {
4020 tlb_addr = paddr;
4021 }
4022
4023 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
4024 tlb_addr >> VTD_PAGE_SHIFT, nrpages, prot);
4025 if (ret)
4026 goto mapping_error;
4027
4028 trace_bounce_map_single(dev, iova_pfn << PAGE_SHIFT, paddr, size);
4029
4030 return (phys_addr_t)iova_pfn << PAGE_SHIFT;
4031
4032mapping_error:
4033 if (is_swiotlb_buffer(tlb_addr))
4034 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
4035 aligned_size, dir, attrs);
4036swiotlb_error:
4037 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
4038 dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n",
4039 size, (unsigned long long)paddr, dir);
4040
4041 return DMA_MAPPING_ERROR;
4042}
4043
4044static void
4045bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
4046 enum dma_data_direction dir, unsigned long attrs)
4047{
4048 size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
4049 struct dmar_domain *domain;
4050 phys_addr_t tlb_addr;
4051
4052 domain = find_domain(dev);
4053 if (WARN_ON(!domain))
4054 return;
4055
4056 tlb_addr = intel_iommu_iova_to_phys(&domain->domain, dev_addr);
4057 if (WARN_ON(!tlb_addr))
4058 return;
4059
4060 intel_unmap(dev, dev_addr, size);
4061 if (is_swiotlb_buffer(tlb_addr))
4062 swiotlb_tbl_unmap_single(dev, tlb_addr, size,
4063 aligned_size, dir, attrs);
4064
4065 trace_bounce_unmap_single(dev, dev_addr, size);
4066}
4067
4068static dma_addr_t
4069bounce_map_page(struct device *dev, struct page *page, unsigned long offset,
4070 size_t size, enum dma_data_direction dir, unsigned long attrs)
4071{
4072 return bounce_map_single(dev, page_to_phys(page) + offset,
4073 size, dir, attrs, *dev->dma_mask);
4074}
4075
4076static dma_addr_t
4077bounce_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
4078 enum dma_data_direction dir, unsigned long attrs)
4079{
4080 return bounce_map_single(dev, phys_addr, size,
4081 dir, attrs, *dev->dma_mask);
4082}
4083
4084static void
4085bounce_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size,
4086 enum dma_data_direction dir, unsigned long attrs)
4087{
4088 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
4089}
4090
4091static void
4092bounce_unmap_resource(struct device *dev, dma_addr_t dev_addr, size_t size,
4093 enum dma_data_direction dir, unsigned long attrs)
4094{
4095 bounce_unmap_single(dev, dev_addr, size, dir, attrs);
4096}
4097
4098static void
4099bounce_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems,
4100 enum dma_data_direction dir, unsigned long attrs)
4101{
4102 struct scatterlist *sg;
4103 int i;
4104
4105 for_each_sg(sglist, sg, nelems, i)
4106 bounce_unmap_page(dev, sg->dma_address,
4107 sg_dma_len(sg), dir, attrs);
4108}
4109
4110static int
4111bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
4112 enum dma_data_direction dir, unsigned long attrs)
4113{
4114 int i;
4115 struct scatterlist *sg;
4116
4117 for_each_sg(sglist, sg, nelems, i) {
4118 sg->dma_address = bounce_map_page(dev, sg_page(sg),
4119 sg->offset, sg->length,
4120 dir, attrs);
4121 if (sg->dma_address == DMA_MAPPING_ERROR)
4122 goto out_unmap;
4123 sg_dma_len(sg) = sg->length;
4124 }
4125
Lu Baolu984d03a2020-01-02 08:18:11 +08004126 for_each_sg(sglist, sg, nelems, i)
4127 trace_bounce_map_sg(dev, i + 1, nelems, sg);
4128
Lu Baolucfb94a32019-09-06 14:14:52 +08004129 return nelems;
4130
4131out_unmap:
4132 bounce_unmap_sg(dev, sglist, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
4133 return 0;
4134}
4135
4136static void
4137bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
4138 size_t size, enum dma_data_direction dir)
4139{
4140 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU);
4141}
4142
4143static void
4144bounce_sync_single_for_device(struct device *dev, dma_addr_t addr,
4145 size_t size, enum dma_data_direction dir)
4146{
4147 bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE);
4148}
4149
4150static void
4151bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
4152 int nelems, enum dma_data_direction dir)
4153{
4154 struct scatterlist *sg;
4155 int i;
4156
4157 for_each_sg(sglist, sg, nelems, i)
4158 bounce_sync_single(dev, sg_dma_address(sg),
4159 sg_dma_len(sg), dir, SYNC_FOR_CPU);
4160}
4161
4162static void
4163bounce_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
4164 int nelems, enum dma_data_direction dir)
4165{
4166 struct scatterlist *sg;
4167 int i;
4168
4169 for_each_sg(sglist, sg, nelems, i)
4170 bounce_sync_single(dev, sg_dma_address(sg),
4171 sg_dma_len(sg), dir, SYNC_FOR_DEVICE);
4172}
4173
4174static const struct dma_map_ops bounce_dma_ops = {
4175 .alloc = intel_alloc_coherent,
4176 .free = intel_free_coherent,
4177 .map_sg = bounce_map_sg,
4178 .unmap_sg = bounce_unmap_sg,
4179 .map_page = bounce_map_page,
4180 .unmap_page = bounce_unmap_page,
4181 .sync_single_for_cpu = bounce_sync_single_for_cpu,
4182 .sync_single_for_device = bounce_sync_single_for_device,
4183 .sync_sg_for_cpu = bounce_sync_sg_for_cpu,
4184 .sync_sg_for_device = bounce_sync_sg_for_device,
4185 .map_resource = bounce_map_resource,
4186 .unmap_resource = bounce_unmap_resource,
4187 .dma_supported = dma_direct_supported,
4188};
4189
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004190static inline int iommu_domain_cache_init(void)
4191{
4192 int ret = 0;
4193
4194 iommu_domain_cache = kmem_cache_create("iommu_domain",
4195 sizeof(struct dmar_domain),
4196 0,
4197 SLAB_HWCACHE_ALIGN,
4198
4199 NULL);
4200 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004201 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004202 ret = -ENOMEM;
4203 }
4204
4205 return ret;
4206}
4207
4208static inline int iommu_devinfo_cache_init(void)
4209{
4210 int ret = 0;
4211
4212 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
4213 sizeof(struct device_domain_info),
4214 0,
4215 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004216 NULL);
4217 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004218 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004219 ret = -ENOMEM;
4220 }
4221
4222 return ret;
4223}
4224
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004225static int __init iommu_init_mempool(void)
4226{
4227 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004228 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004229 if (ret)
4230 return ret;
4231
4232 ret = iommu_domain_cache_init();
4233 if (ret)
4234 goto domain_error;
4235
4236 ret = iommu_devinfo_cache_init();
4237 if (!ret)
4238 return ret;
4239
4240 kmem_cache_destroy(iommu_domain_cache);
4241domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004242 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004243
4244 return -ENOMEM;
4245}
4246
4247static void __init iommu_exit_mempool(void)
4248{
4249 kmem_cache_destroy(iommu_devinfo_cache);
4250 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004251 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004252}
4253
Dan Williams556ab452010-07-23 15:47:56 -07004254static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
4255{
4256 struct dmar_drhd_unit *drhd;
4257 u32 vtbar;
4258 int rc;
4259
4260 /* We know that this device on this chipset has its own IOMMU.
4261 * If we find it under a different IOMMU, then the BIOS is lying
4262 * to us. Hope that the IOMMU for this device is actually
4263 * disabled, and it needs no translation...
4264 */
4265 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
4266 if (rc) {
4267 /* "can't" happen */
4268 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
4269 return;
4270 }
4271 vtbar &= 0xffff0000;
4272
4273 /* we know that the this iommu should be at offset 0xa000 from vtbar */
4274 drhd = dmar_find_matched_drhd_unit(pdev);
4275 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
4276 TAINT_FIRMWARE_WORKAROUND,
4277 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
4278 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
4279}
4280DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
4281
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004282static void __init init_no_remapping_devices(void)
4283{
4284 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00004285 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08004286 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004287
4288 for_each_drhd_unit(drhd) {
4289 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08004290 for_each_active_dev_scope(drhd->devices,
4291 drhd->devices_cnt, i, dev)
4292 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004293 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004294 if (i == drhd->devices_cnt)
4295 drhd->ignored = 1;
4296 }
4297 }
4298
Jiang Liu7c919772014-01-06 14:18:18 +08004299 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004300 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004301 continue;
4302
Jiang Liub683b232014-02-19 14:07:32 +08004303 for_each_active_dev_scope(drhd->devices,
4304 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004305 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004306 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004307 if (i < drhd->devices_cnt)
4308 continue;
4309
David Woodhousec0771df2011-10-14 20:59:46 +01004310 /* This IOMMU has *only* gfx devices. Either bypass it or
4311 set the gfx_mapped flag, as appropriate */
Lu Baolucf1ec452019-05-02 09:34:25 +08004312 if (!dmar_map_gfx) {
David Woodhousec0771df2011-10-14 20:59:46 +01004313 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004314 for_each_active_dev_scope(drhd->devices,
4315 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004316 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004317 }
4318 }
4319}
4320
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004321#ifdef CONFIG_SUSPEND
4322static int init_iommu_hw(void)
4323{
4324 struct dmar_drhd_unit *drhd;
4325 struct intel_iommu *iommu = NULL;
4326
4327 for_each_active_iommu(iommu, drhd)
4328 if (iommu->qi)
4329 dmar_reenable_qi(iommu);
4330
Joseph Cihulab7792602011-05-03 00:08:37 -07004331 for_each_iommu(iommu, drhd) {
4332 if (drhd->ignored) {
4333 /*
4334 * we always have to disable PMRs or DMA may fail on
4335 * this device
4336 */
4337 if (force_on)
4338 iommu_disable_protect_mem_regions(iommu);
4339 continue;
4340 }
Lu Baolu095303e2019-04-29 09:16:02 +08004341
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004342 iommu_flush_write_buffer(iommu);
4343
4344 iommu_set_root_entry(iommu);
4345
4346 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004347 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004348 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4349 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004350 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004351 }
4352
4353 return 0;
4354}
4355
4356static void iommu_flush_all(void)
4357{
4358 struct dmar_drhd_unit *drhd;
4359 struct intel_iommu *iommu;
4360
4361 for_each_active_iommu(iommu, drhd) {
4362 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004363 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004364 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004365 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004366 }
4367}
4368
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004369static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004370{
4371 struct dmar_drhd_unit *drhd;
4372 struct intel_iommu *iommu = NULL;
4373 unsigned long flag;
4374
4375 for_each_active_iommu(iommu, drhd) {
Kees Cook6396bb22018-06-12 14:03:40 -07004376 iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004377 GFP_ATOMIC);
4378 if (!iommu->iommu_state)
4379 goto nomem;
4380 }
4381
4382 iommu_flush_all();
4383
4384 for_each_active_iommu(iommu, drhd) {
4385 iommu_disable_translation(iommu);
4386
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004387 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004388
4389 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4390 readl(iommu->reg + DMAR_FECTL_REG);
4391 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4392 readl(iommu->reg + DMAR_FEDATA_REG);
4393 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4394 readl(iommu->reg + DMAR_FEADDR_REG);
4395 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4396 readl(iommu->reg + DMAR_FEUADDR_REG);
4397
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004398 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004399 }
4400 return 0;
4401
4402nomem:
4403 for_each_active_iommu(iommu, drhd)
4404 kfree(iommu->iommu_state);
4405
4406 return -ENOMEM;
4407}
4408
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004409static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004410{
4411 struct dmar_drhd_unit *drhd;
4412 struct intel_iommu *iommu = NULL;
4413 unsigned long flag;
4414
4415 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004416 if (force_on)
4417 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4418 else
4419 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004420 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004421 }
4422
4423 for_each_active_iommu(iommu, drhd) {
4424
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004425 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004426
4427 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4428 iommu->reg + DMAR_FECTL_REG);
4429 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4430 iommu->reg + DMAR_FEDATA_REG);
4431 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4432 iommu->reg + DMAR_FEADDR_REG);
4433 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4434 iommu->reg + DMAR_FEUADDR_REG);
4435
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004436 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004437 }
4438
4439 for_each_active_iommu(iommu, drhd)
4440 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004441}
4442
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004443static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004444 .resume = iommu_resume,
4445 .suspend = iommu_suspend,
4446};
4447
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004448static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004449{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004450 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004451}
4452
4453#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004454static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004455#endif /* CONFIG_PM */
4456
Jiang Liuc2a0b532014-11-09 22:47:56 +08004457int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004458{
4459 struct acpi_dmar_reserved_memory *rmrr;
4460 struct dmar_rmrr_unit *rmrru;
Yian Chenf036c7f2019-10-17 04:39:19 -07004461
4462 rmrr = (struct acpi_dmar_reserved_memory *)header;
Barret Rhodenf5a68bb2020-01-15 11:03:56 +08004463 if (arch_rmrr_sanity_check(rmrr))
4464 WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
4465 "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
4466 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
4467 rmrr->base_address, rmrr->end_address,
4468 dmi_get_system_info(DMI_BIOS_VENDOR),
4469 dmi_get_system_info(DMI_BIOS_VERSION),
4470 dmi_get_system_info(DMI_PRODUCT_VERSION));
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004471
4472 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4473 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004474 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004475
4476 rmrru->hdr = header;
Yian Chenf036c7f2019-10-17 04:39:19 -07004477
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004478 rmrru->base_address = rmrr->base_address;
4479 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004480
Jiang Liu2e455282014-02-19 14:07:36 +08004481 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4482 ((void *)rmrr) + rmrr->header.length,
4483 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004484 if (rmrru->devices_cnt && rmrru->devices == NULL)
Eric Auger5f64ce52019-06-03 08:53:31 +02004485 goto free_rmrru;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004486
Jiang Liu2e455282014-02-19 14:07:36 +08004487 list_add(&rmrru->list, &dmar_rmrr_units);
4488
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004489 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004490free_rmrru:
4491 kfree(rmrru);
4492out:
4493 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004494}
4495
Jiang Liu6b197242014-11-09 22:47:58 +08004496static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4497{
4498 struct dmar_atsr_unit *atsru;
4499 struct acpi_dmar_atsr *tmp;
4500
4501 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4502 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4503 if (atsr->segment != tmp->segment)
4504 continue;
4505 if (atsr->header.length != tmp->header.length)
4506 continue;
4507 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4508 return atsru;
4509 }
4510
4511 return NULL;
4512}
4513
4514int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004515{
4516 struct acpi_dmar_atsr *atsr;
4517 struct dmar_atsr_unit *atsru;
4518
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004519 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004520 return 0;
4521
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004522 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004523 atsru = dmar_find_atsr(atsr);
4524 if (atsru)
4525 return 0;
4526
4527 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004528 if (!atsru)
4529 return -ENOMEM;
4530
Jiang Liu6b197242014-11-09 22:47:58 +08004531 /*
4532 * If memory is allocated from slab by ACPI _DSM method, we need to
4533 * copy the memory content because the memory buffer will be freed
4534 * on return.
4535 */
4536 atsru->hdr = (void *)(atsru + 1);
4537 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004538 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004539 if (!atsru->include_all) {
4540 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4541 (void *)atsr + atsr->header.length,
4542 &atsru->devices_cnt);
4543 if (atsru->devices_cnt && atsru->devices == NULL) {
4544 kfree(atsru);
4545 return -ENOMEM;
4546 }
4547 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004548
Jiang Liu0e242612014-02-19 14:07:34 +08004549 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004550
4551 return 0;
4552}
4553
Jiang Liu9bdc5312014-01-06 14:18:27 +08004554static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4555{
4556 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4557 kfree(atsru);
4558}
4559
Jiang Liu6b197242014-11-09 22:47:58 +08004560int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4561{
4562 struct acpi_dmar_atsr *atsr;
4563 struct dmar_atsr_unit *atsru;
4564
4565 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4566 atsru = dmar_find_atsr(atsr);
4567 if (atsru) {
4568 list_del_rcu(&atsru->list);
4569 synchronize_rcu();
4570 intel_iommu_free_atsr(atsru);
4571 }
4572
4573 return 0;
4574}
4575
4576int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4577{
4578 int i;
4579 struct device *dev;
4580 struct acpi_dmar_atsr *atsr;
4581 struct dmar_atsr_unit *atsru;
4582
4583 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4584 atsru = dmar_find_atsr(atsr);
4585 if (!atsru)
4586 return 0;
4587
Linus Torvalds194dc872016-07-27 20:03:31 -07004588 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004589 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4590 i, dev)
4591 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004592 }
Jiang Liu6b197242014-11-09 22:47:58 +08004593
4594 return 0;
4595}
4596
Jiang Liuffebeb42014-11-09 22:48:02 +08004597static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4598{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004599 int sp, ret;
Jiang Liuffebeb42014-11-09 22:48:02 +08004600 struct intel_iommu *iommu = dmaru->iommu;
4601
4602 if (g_iommus[iommu->seq_id])
4603 return 0;
4604
4605 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004606 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004607 iommu->name);
4608 return -ENXIO;
4609 }
4610 if (!ecap_sc_support(iommu->ecap) &&
4611 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004612 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004613 iommu->name);
4614 return -ENXIO;
4615 }
Lu Baolu64229e82020-01-02 08:18:20 +08004616 sp = domain_update_iommu_superpage(NULL, iommu) - 1;
Jiang Liuffebeb42014-11-09 22:48:02 +08004617 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004618 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004619 iommu->name);
4620 return -ENXIO;
4621 }
4622
4623 /*
4624 * Disable translation if already enabled prior to OS handover.
4625 */
4626 if (iommu->gcmd & DMA_GCMD_TE)
4627 iommu_disable_translation(iommu);
4628
4629 g_iommus[iommu->seq_id] = iommu;
4630 ret = iommu_init_domains(iommu);
4631 if (ret == 0)
4632 ret = iommu_alloc_root_entry(iommu);
4633 if (ret)
4634 goto out;
4635
Jacob Panff3dc652020-01-02 08:18:03 +08004636 intel_svm_check(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00004637
Jiang Liuffebeb42014-11-09 22:48:02 +08004638 if (dmaru->ignored) {
4639 /*
4640 * we always have to disable PMRs or DMA may fail on this device
4641 */
4642 if (force_on)
4643 iommu_disable_protect_mem_regions(iommu);
4644 return 0;
4645 }
4646
4647 intel_iommu_init_qi(iommu);
4648 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004649
4650#ifdef CONFIG_INTEL_IOMMU_SVM
Lu Baolu765b6a92018-12-10 09:58:55 +08004651 if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
David Woodhousea222a7f2015-10-07 23:35:18 +01004652 ret = intel_svm_enable_prq(iommu);
4653 if (ret)
4654 goto disable_iommu;
4655 }
4656#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004657 ret = dmar_set_interrupt(iommu);
4658 if (ret)
4659 goto disable_iommu;
4660
4661 iommu_set_root_entry(iommu);
4662 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4663 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4664 iommu_enable_translation(iommu);
4665
Jiang Liuffebeb42014-11-09 22:48:02 +08004666 iommu_disable_protect_mem_regions(iommu);
4667 return 0;
4668
4669disable_iommu:
4670 disable_dmar_iommu(iommu);
4671out:
4672 free_dmar_iommu(iommu);
4673 return ret;
4674}
4675
Jiang Liu6b197242014-11-09 22:47:58 +08004676int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4677{
Jiang Liuffebeb42014-11-09 22:48:02 +08004678 int ret = 0;
4679 struct intel_iommu *iommu = dmaru->iommu;
4680
4681 if (!intel_iommu_enabled)
4682 return 0;
4683 if (iommu == NULL)
4684 return -EINVAL;
4685
4686 if (insert) {
4687 ret = intel_iommu_add(dmaru);
4688 } else {
4689 disable_dmar_iommu(iommu);
4690 free_dmar_iommu(iommu);
4691 }
4692
4693 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004694}
4695
Jiang Liu9bdc5312014-01-06 14:18:27 +08004696static void intel_iommu_free_dmars(void)
4697{
4698 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4699 struct dmar_atsr_unit *atsru, *atsr_n;
4700
4701 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4702 list_del(&rmrru->list);
4703 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
4704 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004705 }
4706
Jiang Liu9bdc5312014-01-06 14:18:27 +08004707 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4708 list_del(&atsru->list);
4709 intel_iommu_free_atsr(atsru);
4710 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004711}
4712
4713int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4714{
Jiang Liub683b232014-02-19 14:07:32 +08004715 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004716 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004717 struct pci_dev *bridge = NULL;
4718 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004719 struct acpi_dmar_atsr *atsr;
4720 struct dmar_atsr_unit *atsru;
4721
4722 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004723 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004724 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004725 /* If it's an integrated device, allow ATS */
4726 if (!bridge)
4727 return 1;
4728 /* Connected via non-PCIe: no ATS */
4729 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004730 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004731 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004732 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004733 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004734 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004735 }
4736
Jiang Liu0e242612014-02-19 14:07:34 +08004737 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004738 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4739 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4740 if (atsr->segment != pci_domain_nr(dev->bus))
4741 continue;
4742
Jiang Liub683b232014-02-19 14:07:32 +08004743 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004744 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004745 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004746
4747 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004748 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004749 }
Jiang Liub683b232014-02-19 14:07:32 +08004750 ret = 0;
4751out:
Jiang Liu0e242612014-02-19 14:07:34 +08004752 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004753
Jiang Liub683b232014-02-19 14:07:32 +08004754 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004755}
4756
Jiang Liu59ce0512014-02-19 14:07:35 +08004757int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4758{
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004759 int ret;
Jiang Liu59ce0512014-02-19 14:07:35 +08004760 struct dmar_rmrr_unit *rmrru;
4761 struct dmar_atsr_unit *atsru;
4762 struct acpi_dmar_atsr *atsr;
4763 struct acpi_dmar_reserved_memory *rmrr;
4764
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004765 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004766 return 0;
4767
4768 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4769 rmrr = container_of(rmrru->hdr,
4770 struct acpi_dmar_reserved_memory, header);
4771 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4772 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4773 ((void *)rmrr) + rmrr->header.length,
4774 rmrr->segment, rmrru->devices,
4775 rmrru->devices_cnt);
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004776 if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004777 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004778 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004779 dmar_remove_dev_scope(info, rmrr->segment,
4780 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004781 }
4782 }
4783
4784 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4785 if (atsru->include_all)
4786 continue;
4787
4788 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4789 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4790 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4791 (void *)atsr + atsr->header.length,
4792 atsr->segment, atsru->devices,
4793 atsru->devices_cnt);
4794 if (ret > 0)
4795 break;
Bjorn Helgaase083ea5b2019-02-08 16:06:08 -06004796 else if (ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004797 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004798 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004799 if (dmar_remove_dev_scope(info, atsr->segment,
4800 atsru->devices, atsru->devices_cnt))
4801 break;
4802 }
4803 }
4804
4805 return 0;
4806}
4807
Jiang Liu75f05562014-02-19 14:07:37 +08004808static int intel_iommu_memory_notifier(struct notifier_block *nb,
4809 unsigned long val, void *v)
4810{
4811 struct memory_notify *mhp = v;
4812 unsigned long long start, end;
4813 unsigned long start_vpfn, last_vpfn;
4814
4815 switch (val) {
4816 case MEM_GOING_ONLINE:
4817 start = mhp->start_pfn << PAGE_SHIFT;
4818 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4819 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004820 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004821 start, end);
4822 return NOTIFY_BAD;
4823 }
4824 break;
4825
4826 case MEM_OFFLINE:
4827 case MEM_CANCEL_ONLINE:
4828 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4829 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4830 while (start_vpfn <= last_vpfn) {
4831 struct iova *iova;
4832 struct dmar_drhd_unit *drhd;
4833 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004834 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004835
4836 iova = find_iova(&si_domain->iovad, start_vpfn);
4837 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004838 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004839 start_vpfn);
4840 break;
4841 }
4842
4843 iova = split_and_remove_iova(&si_domain->iovad, iova,
4844 start_vpfn, last_vpfn);
4845 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004846 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004847 start_vpfn, last_vpfn);
4848 return NOTIFY_BAD;
4849 }
4850
David Woodhouseea8ea462014-03-05 17:09:32 +00004851 freelist = domain_unmap(si_domain, iova->pfn_lo,
4852 iova->pfn_hi);
4853
Jiang Liu75f05562014-02-19 14:07:37 +08004854 rcu_read_lock();
4855 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004856 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004857 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004858 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004859 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004860 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004861
4862 start_vpfn = iova->pfn_hi + 1;
4863 free_iova_mem(iova);
4864 }
4865 break;
4866 }
4867
4868 return NOTIFY_OK;
4869}
4870
4871static struct notifier_block intel_iommu_memory_nb = {
4872 .notifier_call = intel_iommu_memory_notifier,
4873 .priority = 0
4874};
4875
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004876static void free_all_cpu_cached_iovas(unsigned int cpu)
4877{
4878 int i;
4879
4880 for (i = 0; i < g_num_of_iommus; i++) {
4881 struct intel_iommu *iommu = g_iommus[i];
4882 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004883 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004884
4885 if (!iommu)
4886 continue;
4887
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004888 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004889 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004890
4891 if (!domain)
4892 continue;
4893 free_cpu_cached_iovas(cpu, &domain->iovad);
4894 }
4895 }
4896}
4897
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004898static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004899{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004900 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004901 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004902}
4903
Joerg Roedel161b28a2017-03-28 17:04:52 +02004904static void intel_disable_iommus(void)
4905{
4906 struct intel_iommu *iommu = NULL;
4907 struct dmar_drhd_unit *drhd;
4908
4909 for_each_iommu(iommu, drhd)
4910 iommu_disable_translation(iommu);
4911}
4912
Deepa Dinamani6c3a44e2019-11-10 09:27:44 -08004913void intel_iommu_shutdown(void)
4914{
4915 struct dmar_drhd_unit *drhd;
4916 struct intel_iommu *iommu = NULL;
4917
4918 if (no_iommu || dmar_disabled)
4919 return;
4920
4921 down_write(&dmar_global_lock);
4922
4923 /* Disable PMRs explicitly here. */
4924 for_each_iommu(iommu, drhd)
4925 iommu_disable_protect_mem_regions(iommu);
4926
4927 /* Make sure the IOMMUs are switched off */
4928 intel_disable_iommus();
4929
4930 up_write(&dmar_global_lock);
4931}
4932
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004933static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4934{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004935 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4936
4937 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004938}
4939
Alex Williamsona5459cf2014-06-12 16:12:31 -06004940static ssize_t intel_iommu_show_version(struct device *dev,
4941 struct device_attribute *attr,
4942 char *buf)
4943{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004944 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004945 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4946 return sprintf(buf, "%d:%d\n",
4947 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4948}
4949static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4950
4951static ssize_t intel_iommu_show_address(struct device *dev,
4952 struct device_attribute *attr,
4953 char *buf)
4954{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004955 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004956 return sprintf(buf, "%llx\n", iommu->reg_phys);
4957}
4958static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4959
4960static ssize_t intel_iommu_show_cap(struct device *dev,
4961 struct device_attribute *attr,
4962 char *buf)
4963{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004964 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004965 return sprintf(buf, "%llx\n", iommu->cap);
4966}
4967static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4968
4969static ssize_t intel_iommu_show_ecap(struct device *dev,
4970 struct device_attribute *attr,
4971 char *buf)
4972{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004973 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004974 return sprintf(buf, "%llx\n", iommu->ecap);
4975}
4976static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4977
Alex Williamson2238c082015-07-14 15:24:53 -06004978static ssize_t intel_iommu_show_ndoms(struct device *dev,
4979 struct device_attribute *attr,
4980 char *buf)
4981{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004982 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004983 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4984}
4985static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4986
4987static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4988 struct device_attribute *attr,
4989 char *buf)
4990{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004991 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004992 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4993 cap_ndoms(iommu->cap)));
4994}
4995static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4996
Alex Williamsona5459cf2014-06-12 16:12:31 -06004997static struct attribute *intel_iommu_attrs[] = {
4998 &dev_attr_version.attr,
4999 &dev_attr_address.attr,
5000 &dev_attr_cap.attr,
5001 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06005002 &dev_attr_domains_supported.attr,
5003 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06005004 NULL,
5005};
5006
5007static struct attribute_group intel_iommu_group = {
5008 .name = "intel-iommu",
5009 .attrs = intel_iommu_attrs,
5010};
5011
5012const struct attribute_group *intel_iommu_groups[] = {
5013 &intel_iommu_group,
5014 NULL,
5015};
5016
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005017static inline bool has_untrusted_dev(void)
Lu Baolu89a60792018-10-23 15:45:01 +08005018{
5019 struct pci_dev *pdev = NULL;
Lu Baolu89a60792018-10-23 15:45:01 +08005020
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005021 for_each_pci_dev(pdev)
5022 if (pdev->untrusted)
5023 return true;
Lu Baolu89a60792018-10-23 15:45:01 +08005024
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005025 return false;
5026}
Lu Baolu89a60792018-10-23 15:45:01 +08005027
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005028static int __init platform_optin_force_iommu(void)
5029{
5030 if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
Lu Baolu89a60792018-10-23 15:45:01 +08005031 return 0;
5032
5033 if (no_iommu || dmar_disabled)
5034 pr_info("Intel-IOMMU force enabled due to platform opt in\n");
5035
5036 /*
5037 * If Intel-IOMMU is disabled by default, we will apply identity
5038 * map for all devices except those marked as being untrusted.
5039 */
5040 if (dmar_disabled)
5041 iommu_identity_mapping |= IDENTMAP_ALL;
5042
5043 dmar_disabled = 0;
Lu Baolu89a60792018-10-23 15:45:01 +08005044 no_iommu = 0;
5045
5046 return 1;
5047}
5048
Lu Baolufa212a92019-05-25 13:41:31 +08005049static int __init probe_acpi_namespace_devices(void)
5050{
5051 struct dmar_drhd_unit *drhd;
Qian Caiaf88ec32019-06-03 10:05:19 -04005052 /* To avoid a -Wunused-but-set-variable warning. */
5053 struct intel_iommu *iommu __maybe_unused;
Lu Baolufa212a92019-05-25 13:41:31 +08005054 struct device *dev;
5055 int i, ret = 0;
5056
5057 for_each_active_iommu(iommu, drhd) {
5058 for_each_active_dev_scope(drhd->devices,
5059 drhd->devices_cnt, i, dev) {
5060 struct acpi_device_physical_node *pn;
5061 struct iommu_group *group;
5062 struct acpi_device *adev;
5063
5064 if (dev->bus != &acpi_bus_type)
5065 continue;
5066
5067 adev = to_acpi_device(dev);
5068 mutex_lock(&adev->physical_node_lock);
5069 list_for_each_entry(pn,
5070 &adev->physical_node_list, node) {
5071 group = iommu_group_get(pn->dev);
5072 if (group) {
5073 iommu_group_put(group);
5074 continue;
5075 }
5076
5077 pn->dev->bus->iommu_ops = &intel_iommu_ops;
5078 ret = iommu_probe_device(pn->dev);
5079 if (ret)
5080 break;
5081 }
5082 mutex_unlock(&adev->physical_node_lock);
5083
5084 if (ret)
5085 return ret;
5086 }
5087 }
5088
5089 return 0;
5090}
5091
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005092int __init intel_iommu_init(void)
5093{
Jiang Liu9bdc5312014-01-06 14:18:27 +08005094 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09005095 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08005096 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005097
Lu Baolu89a60792018-10-23 15:45:01 +08005098 /*
5099 * Intel IOMMU is required for a TXT/tboot launch or platform
5100 * opt in, so enforce that.
5101 */
5102 force_on = tboot_force_iommu() || platform_optin_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005103
Jiang Liu3a5670e2014-02-19 14:07:33 +08005104 if (iommu_init_mempool()) {
5105 if (force_on)
5106 panic("tboot: Failed to initialize iommu memory\n");
5107 return -ENOMEM;
5108 }
5109
5110 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07005111 if (dmar_table_init()) {
5112 if (force_on)
5113 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08005114 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07005115 }
5116
Suresh Siddhac2c72862011-08-23 17:05:19 -07005117 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07005118 if (force_on)
5119 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08005120 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07005121 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07005122
Joerg Roedelec154bf2017-10-06 15:00:53 +02005123 up_write(&dmar_global_lock);
5124
5125 /*
5126 * The bus notifier takes the dmar_global_lock, so lockdep will
5127 * complain later when we register it under the lock.
5128 */
5129 dmar_register_bus_notifier();
5130
5131 down_write(&dmar_global_lock);
5132
Joerg Roedel161b28a2017-03-28 17:04:52 +02005133 if (no_iommu || dmar_disabled) {
5134 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07005135 * We exit the function here to ensure IOMMU's remapping and
5136 * mempool aren't setup, which means that the IOMMU's PMRs
5137 * won't be disabled via the call to init_dmars(). So disable
5138 * it explicitly here. The PMRs were setup by tboot prior to
5139 * calling SENTER, but the kernel is expected to reset/tear
5140 * down the PMRs.
5141 */
5142 if (intel_iommu_tboot_noforce) {
5143 for_each_iommu(iommu, drhd)
5144 iommu_disable_protect_mem_regions(iommu);
5145 }
5146
5147 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02005148 * Make sure the IOMMUs are switched off, even when we
5149 * boot into a kexec kernel and the previous kernel left
5150 * them enabled
5151 */
5152 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08005153 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02005154 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07005155
Suresh Siddha318fe7d2011-08-23 17:05:20 -07005156 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005157 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07005158
5159 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005160 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07005161
Joseph Cihula51a63e62011-03-21 11:04:24 -07005162 if (dmar_init_reserved_ranges()) {
5163 if (force_on)
5164 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08005165 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07005166 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005167
Lu Baolucf1ec452019-05-02 09:34:25 +08005168 if (dmar_map_gfx)
5169 intel_iommu_gfx_mapped = 1;
5170
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005171 init_no_remapping_devices();
5172
Joseph Cihulab7792602011-05-03 00:08:37 -07005173 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005174 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07005175 if (force_on)
5176 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005177 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08005178 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005179 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08005180 up_write(&dmar_global_lock);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005181
Christoph Hellwig4fac8072017-12-24 13:57:08 +01005182#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
Lu Baoluc5a5dc42019-09-06 14:14:50 +08005183 /*
5184 * If the system has no untrusted device or the user has decided
5185 * to disable the bounce page mechanisms, we don't need swiotlb.
5186 * Mark this and the pre-allocated bounce pages will be released
5187 * later.
5188 */
5189 if (!has_untrusted_dev() || intel_no_bounce)
5190 swiotlb = 0;
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09005191#endif
David Woodhouse19943b02009-08-04 16:19:20 +01005192 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07005193
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01005194 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005195
Joerg Roedel39ab9552017-02-01 16:56:46 +01005196 for_each_active_iommu(iommu, drhd) {
5197 iommu_device_sysfs_add(&iommu->iommu, NULL,
5198 intel_iommu_groups,
5199 "%s", iommu->name);
5200 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
5201 iommu_device_register(&iommu->iommu);
5202 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06005203
Joerg Roedel4236d97d2011-09-06 17:56:07 +02005204 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Jiang Liu75f05562014-02-19 14:07:37 +08005205 if (si_domain && !hw_pass_through)
5206 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01005207 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
5208 intel_iommu_cpu_dead);
Lu Baolud8190dc2019-05-25 13:41:25 +08005209
Lu Baolud5692d42019-06-12 08:28:49 +08005210 down_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08005211 if (probe_acpi_namespace_devices())
5212 pr_warn("ACPI name space devices didn't probe correctly\n");
Lu Baolud5692d42019-06-12 08:28:49 +08005213 up_read(&dmar_global_lock);
Lu Baolufa212a92019-05-25 13:41:31 +08005214
Lu Baolud8190dc2019-05-25 13:41:25 +08005215 /* Finally, we enable the DMA remapping hardware. */
5216 for_each_iommu(iommu, drhd) {
Lu Baolu6a8c6742019-06-12 08:28:47 +08005217 if (!drhd->ignored && !translation_pre_enabled(iommu))
Lu Baolud8190dc2019-05-25 13:41:25 +08005218 iommu_enable_translation(iommu);
5219
5220 iommu_disable_protect_mem_regions(iommu);
5221 }
5222 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
5223
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02005224 intel_iommu_enabled = 1;
Sohil Mehtaee2636b2018-09-11 17:11:38 -07005225 intel_iommu_debugfs_init();
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02005226
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005227 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08005228
5229out_free_reserved_range:
5230 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08005231out_free_dmar:
5232 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08005233 up_write(&dmar_global_lock);
5234 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08005235 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07005236}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07005237
Lu Baolu0ce4a852019-08-26 16:50:56 +08005238static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
5239{
5240 struct intel_iommu *iommu = opaque;
5241
5242 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
5243 return 0;
5244}
5245
5246/*
5247 * NB - intel-iommu lacks any sort of reference counting for the users of
5248 * dependent devices. If multiple endpoints have intersecting dependent
5249 * devices, unbinding the driver from any one of them will possibly leave
5250 * the others unable to operate.
5251 */
5252static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
5253{
5254 if (!iommu || !dev || !dev_is_pci(dev))
5255 return;
5256
5257 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
5258}
5259
Joerg Roedel127c7612015-07-23 17:44:46 +02005260static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08005261{
Lu Baolu942067f2019-05-25 13:41:29 +08005262 struct dmar_domain *domain;
Weidong Hanc7151a82008-12-08 22:51:37 +08005263 struct intel_iommu *iommu;
5264 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08005265
Joerg Roedel55d94042015-07-22 16:50:40 +02005266 assert_spin_locked(&device_domain_lock);
5267
Joerg Roedelb608ac32015-07-21 18:19:08 +02005268 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08005269 return;
5270
Joerg Roedel127c7612015-07-23 17:44:46 +02005271 iommu = info->iommu;
Lu Baolu942067f2019-05-25 13:41:29 +08005272 domain = info->domain;
Joerg Roedel127c7612015-07-23 17:44:46 +02005273
5274 if (info->dev) {
Lu Baoluef848b72018-12-10 09:59:01 +08005275 if (dev_is_pci(info->dev) && sm_supported(iommu))
5276 intel_pasid_tear_down_entry(iommu, info->dev,
5277 PASID_RID2PASID);
5278
Joerg Roedel127c7612015-07-23 17:44:46 +02005279 iommu_disable_dev_iotlb(info);
Lu Baolu0ce4a852019-08-26 16:50:56 +08005280 domain_context_clear(iommu, info->dev);
Lu Baolua7fc93f2018-07-14 15:47:00 +08005281 intel_pasid_free_table(info->dev);
Joerg Roedel127c7612015-07-23 17:44:46 +02005282 }
5283
Joerg Roedelb608ac32015-07-21 18:19:08 +02005284 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07005285
Joerg Roedeld160aca2015-07-22 11:52:53 +02005286 spin_lock_irqsave(&iommu->lock, flags);
Lu Baolu942067f2019-05-25 13:41:29 +08005287 domain_detach_iommu(domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02005288 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005289
Lu Baolu942067f2019-05-25 13:41:29 +08005290 /* free the private domain */
5291 if (domain->flags & DOMAIN_FLAG_LOSE_CHILDREN &&
Lu Baolu3a18844d2019-08-06 08:14:09 +08005292 !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
5293 list_empty(&domain->devices))
Lu Baolu942067f2019-05-25 13:41:29 +08005294 domain_exit(info->domain);
5295
Joerg Roedel127c7612015-07-23 17:44:46 +02005296 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08005297}
5298
Bjorn Helgaas71753232019-02-08 16:06:15 -06005299static void dmar_remove_one_dev_info(struct device *dev)
Joerg Roedel55d94042015-07-22 16:50:40 +02005300{
Joerg Roedel127c7612015-07-23 17:44:46 +02005301 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02005302 unsigned long flags;
5303
Weidong Hanc7151a82008-12-08 22:51:37 +08005304 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02005305 info = dev->archdata.iommu;
Lu Baoluae23bfb62019-08-06 08:14:08 +08005306 if (info)
5307 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005308 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005309}
5310
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005311static int md_domain_init(struct dmar_domain *domain, int guest_width)
5312{
5313 int adjust_width;
5314
5315 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
5316 domain_reserve_special_ranges(domain);
5317
5318 /* calculate AGAW */
5319 domain->gaw = guest_width;
5320 adjust_width = guestwidth_to_adjustwidth(guest_width);
5321 domain->agaw = width_to_agaw(adjust_width);
5322
5323 domain->iommu_coherency = 0;
5324 domain->iommu_snooping = 0;
5325 domain->iommu_superpage = 0;
5326 domain->max_addr = 0;
5327
5328 /* always allocate the top pgd */
5329 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
5330 if (!domain->pgd)
5331 return -ENOMEM;
5332 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5333 return 0;
5334}
5335
Joerg Roedel00a77de2015-03-26 13:43:08 +01005336static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03005337{
Joerg Roedel5d450802008-12-03 14:52:32 +01005338 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005339 struct iommu_domain *domain;
Lu Baolu10f80082020-01-02 08:18:12 +08005340 int ret;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005341
Lu Baolu4de354e2019-05-25 13:41:27 +08005342 switch (type) {
Lu Baolufa954e62019-05-25 13:41:28 +08005343 case IOMMU_DOMAIN_DMA:
5344 /* fallthrough */
Lu Baolu4de354e2019-05-25 13:41:27 +08005345 case IOMMU_DOMAIN_UNMANAGED:
Lu Baolufa954e62019-05-25 13:41:28 +08005346 dmar_domain = alloc_domain(0);
Lu Baolu4de354e2019-05-25 13:41:27 +08005347 if (!dmar_domain) {
5348 pr_err("Can't allocate dmar_domain\n");
5349 return NULL;
5350 }
Joerg Roedel301e7ee2019-07-22 16:21:05 +02005351 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Lu Baolu4de354e2019-05-25 13:41:27 +08005352 pr_err("Domain initialization failed\n");
5353 domain_exit(dmar_domain);
5354 return NULL;
5355 }
Lu Baolufa954e62019-05-25 13:41:28 +08005356
Lu Baolu10f80082020-01-02 08:18:12 +08005357 if (!intel_iommu_strict && type == IOMMU_DOMAIN_DMA) {
5358 ret = init_iova_flush_queue(&dmar_domain->iovad,
5359 iommu_flush_iova,
5360 iova_entry_free);
Lu Baolu8e3391c2020-01-02 08:18:13 +08005361 if (ret)
5362 pr_info("iova flush queue initialization failed\n");
Lu Baolufa954e62019-05-25 13:41:28 +08005363 }
5364
Lu Baolu4de354e2019-05-25 13:41:27 +08005365 domain_update_iommu_cap(dmar_domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005366
Lu Baolu4de354e2019-05-25 13:41:27 +08005367 domain = &dmar_domain->domain;
5368 domain->geometry.aperture_start = 0;
5369 domain->geometry.aperture_end =
5370 __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5371 domain->geometry.force_aperture = true;
5372
5373 return domain;
5374 case IOMMU_DOMAIN_IDENTITY:
5375 return &si_domain->domain;
5376 default:
Joerg Roedel00a77de2015-03-26 13:43:08 +01005377 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005378 }
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005379
Lu Baolu4de354e2019-05-25 13:41:27 +08005380 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005381}
Kay, Allen M38717942008-09-09 18:37:29 +03005382
Joerg Roedel00a77de2015-03-26 13:43:08 +01005383static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005384{
Lu Baolu4de354e2019-05-25 13:41:27 +08005385 if (domain != &si_domain->domain)
5386 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005387}
Kay, Allen M38717942008-09-09 18:37:29 +03005388
Lu Baolu67b8e022019-03-25 09:30:32 +08005389/*
5390 * Check whether a @domain could be attached to the @dev through the
5391 * aux-domain attach/detach APIs.
5392 */
5393static inline bool
5394is_aux_domain(struct device *dev, struct iommu_domain *domain)
5395{
5396 struct device_domain_info *info = dev->archdata.iommu;
5397
5398 return info && info->auxd_enabled &&
5399 domain->type == IOMMU_DOMAIN_UNMANAGED;
5400}
5401
5402static void auxiliary_link_device(struct dmar_domain *domain,
5403 struct device *dev)
5404{
5405 struct device_domain_info *info = dev->archdata.iommu;
5406
5407 assert_spin_locked(&device_domain_lock);
5408 if (WARN_ON(!info))
5409 return;
5410
5411 domain->auxd_refcnt++;
5412 list_add(&domain->auxd, &info->auxiliary_domains);
5413}
5414
5415static void auxiliary_unlink_device(struct dmar_domain *domain,
5416 struct device *dev)
5417{
5418 struct device_domain_info *info = dev->archdata.iommu;
5419
5420 assert_spin_locked(&device_domain_lock);
5421 if (WARN_ON(!info))
5422 return;
5423
5424 list_del(&domain->auxd);
5425 domain->auxd_refcnt--;
5426
5427 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005428 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005429}
5430
5431static int aux_domain_add_dev(struct dmar_domain *domain,
5432 struct device *dev)
5433{
5434 int ret;
5435 u8 bus, devfn;
5436 unsigned long flags;
5437 struct intel_iommu *iommu;
5438
5439 iommu = device_to_iommu(dev, &bus, &devfn);
5440 if (!iommu)
5441 return -ENODEV;
5442
5443 if (domain->default_pasid <= 0) {
5444 int pasid;
5445
Jacob Pan59a62332020-01-02 08:18:08 +08005446 /* No private data needed for the default pasid */
5447 pasid = ioasid_alloc(NULL, PASID_MIN,
5448 pci_max_pasids(to_pci_dev(dev)) - 1,
5449 NULL);
5450 if (pasid == INVALID_IOASID) {
Lu Baolu67b8e022019-03-25 09:30:32 +08005451 pr_err("Can't allocate default pasid\n");
5452 return -ENODEV;
5453 }
5454 domain->default_pasid = pasid;
5455 }
5456
5457 spin_lock_irqsave(&device_domain_lock, flags);
5458 /*
5459 * iommu->lock must be held to attach domain to iommu and setup the
5460 * pasid entry for second level translation.
5461 */
5462 spin_lock(&iommu->lock);
5463 ret = domain_attach_iommu(domain, iommu);
5464 if (ret)
5465 goto attach_failed;
5466
5467 /* Setup the PASID entry for mediated devices: */
Lu Baoluddf09b62020-01-02 08:18:17 +08005468 if (domain_use_first_level(domain))
5469 ret = domain_setup_first_level(iommu, domain, dev,
5470 domain->default_pasid);
5471 else
5472 ret = intel_pasid_setup_second_level(iommu, domain, dev,
5473 domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005474 if (ret)
5475 goto table_failed;
5476 spin_unlock(&iommu->lock);
5477
5478 auxiliary_link_device(domain, dev);
5479
5480 spin_unlock_irqrestore(&device_domain_lock, flags);
5481
5482 return 0;
5483
5484table_failed:
5485 domain_detach_iommu(domain, iommu);
5486attach_failed:
5487 spin_unlock(&iommu->lock);
5488 spin_unlock_irqrestore(&device_domain_lock, flags);
5489 if (!domain->auxd_refcnt && domain->default_pasid > 0)
Jacob Pan59a62332020-01-02 08:18:08 +08005490 ioasid_free(domain->default_pasid);
Lu Baolu67b8e022019-03-25 09:30:32 +08005491
5492 return ret;
5493}
5494
5495static void aux_domain_remove_dev(struct dmar_domain *domain,
5496 struct device *dev)
5497{
5498 struct device_domain_info *info;
5499 struct intel_iommu *iommu;
5500 unsigned long flags;
5501
5502 if (!is_aux_domain(dev, &domain->domain))
5503 return;
5504
5505 spin_lock_irqsave(&device_domain_lock, flags);
5506 info = dev->archdata.iommu;
5507 iommu = info->iommu;
5508
5509 auxiliary_unlink_device(domain, dev);
5510
5511 spin_lock(&iommu->lock);
5512 intel_pasid_tear_down_entry(iommu, dev, domain->default_pasid);
5513 domain_detach_iommu(domain, iommu);
5514 spin_unlock(&iommu->lock);
5515
5516 spin_unlock_irqrestore(&device_domain_lock, flags);
5517}
5518
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005519static int prepare_domain_attach_device(struct iommu_domain *domain,
5520 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005521{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005522 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005523 struct intel_iommu *iommu;
5524 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005525 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005526
David Woodhouse156baca2014-03-09 14:00:57 -07005527 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005528 if (!iommu)
5529 return -ENODEV;
5530
5531 /* check if this iommu agaw is sufficient for max mapped address */
5532 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005533 if (addr_width > cap_mgaw(iommu->cap))
5534 addr_width = cap_mgaw(iommu->cap);
5535
5536 if (dmar_domain->max_addr > (1LL << addr_width)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06005537 dev_err(dev, "%s: iommu width (%d) is not "
5538 "sufficient for the mapped address (%llx)\n",
5539 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005540 return -EFAULT;
5541 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005542 dmar_domain->gaw = addr_width;
5543
5544 /*
5545 * Knock out extra levels of page tables if necessary
5546 */
5547 while (iommu->agaw < dmar_domain->agaw) {
5548 struct dma_pte *pte;
5549
5550 pte = dmar_domain->pgd;
5551 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005552 dmar_domain->pgd = (struct dma_pte *)
5553 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005554 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005555 }
5556 dmar_domain->agaw--;
5557 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005558
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005559 return 0;
5560}
5561
5562static int intel_iommu_attach_device(struct iommu_domain *domain,
5563 struct device *dev)
5564{
5565 int ret;
5566
Lu Baolu56795822019-06-12 08:28:48 +08005567 if (domain->type == IOMMU_DOMAIN_UNMANAGED &&
5568 device_is_rmrr_locked(dev)) {
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005569 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5570 return -EPERM;
5571 }
5572
Lu Baolu67b8e022019-03-25 09:30:32 +08005573 if (is_aux_domain(dev, domain))
5574 return -EPERM;
5575
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005576 /* normally dev is not mapped */
5577 if (unlikely(domain_context_mapped(dev))) {
5578 struct dmar_domain *old_domain;
5579
5580 old_domain = find_domain(dev);
Lu Baolufa954e62019-05-25 13:41:28 +08005581 if (old_domain)
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005582 dmar_remove_one_dev_info(dev);
Lu Baolu8cc3759a2019-03-25 09:30:31 +08005583 }
5584
5585 ret = prepare_domain_attach_device(domain, dev);
5586 if (ret)
5587 return ret;
5588
5589 return domain_add_dev_info(to_dmar_domain(domain), dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005590}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005591
Lu Baolu67b8e022019-03-25 09:30:32 +08005592static int intel_iommu_aux_attach_device(struct iommu_domain *domain,
5593 struct device *dev)
5594{
5595 int ret;
5596
5597 if (!is_aux_domain(dev, domain))
5598 return -EPERM;
5599
5600 ret = prepare_domain_attach_device(domain, dev);
5601 if (ret)
5602 return ret;
5603
5604 return aux_domain_add_dev(to_dmar_domain(domain), dev);
5605}
5606
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005607static void intel_iommu_detach_device(struct iommu_domain *domain,
5608 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005609{
Bjorn Helgaas71753232019-02-08 16:06:15 -06005610 dmar_remove_one_dev_info(dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005611}
Kay, Allen M38717942008-09-09 18:37:29 +03005612
Lu Baolu67b8e022019-03-25 09:30:32 +08005613static void intel_iommu_aux_detach_device(struct iommu_domain *domain,
5614 struct device *dev)
5615{
5616 aux_domain_remove_dev(to_dmar_domain(domain), dev);
5617}
5618
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005619static int intel_iommu_map(struct iommu_domain *domain,
5620 unsigned long iova, phys_addr_t hpa,
Tom Murphy781ca2d2019-09-08 09:56:38 -07005621 size_t size, int iommu_prot, gfp_t gfp)
Kay, Allen M38717942008-09-09 18:37:29 +03005622{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005623 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005624 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005625 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005626 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005627
Joerg Roedeldde57a22008-12-03 15:04:09 +01005628 if (iommu_prot & IOMMU_READ)
5629 prot |= DMA_PTE_READ;
5630 if (iommu_prot & IOMMU_WRITE)
5631 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005632 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5633 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005634
David Woodhouse163cc522009-06-28 00:51:17 +01005635 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005636 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005637 u64 end;
5638
5639 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005640 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005641 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005642 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005643 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005644 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005645 return -EFAULT;
5646 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005647 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005648 }
David Woodhousead051222009-06-28 14:22:28 +01005649 /* Round up size to next multiple of PAGE_SIZE, if it and
5650 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005651 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005652 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5653 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005654 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005655}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005656
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005657static size_t intel_iommu_unmap(struct iommu_domain *domain,
Will Deacon56f8af52019-07-02 16:44:06 +01005658 unsigned long iova, size_t size,
5659 struct iommu_iotlb_gather *gather)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005660{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005661 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005662 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005663 unsigned long start_pfn, last_pfn;
5664 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005665 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005666
David Woodhouse5cf0a762014-03-19 16:07:49 +00005667 /* Cope with horrid API which requires us to unmap more than the
5668 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005669 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005670
5671 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5672 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5673
David Woodhouseea8ea462014-03-05 17:09:32 +00005674 start_pfn = iova >> VTD_PAGE_SHIFT;
5675 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5676
5677 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5678
5679 npages = last_pfn - start_pfn + 1;
5680
Shaokun Zhangf746a022018-03-22 18:18:06 +08005681 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005682 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5683 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005684
5685 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005686
David Woodhouse163cc522009-06-28 00:51:17 +01005687 if (dmar_domain->max_addr == iova + size)
5688 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005689
David Woodhouse5cf0a762014-03-19 16:07:49 +00005690 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005691}
Kay, Allen M38717942008-09-09 18:37:29 +03005692
Joerg Roedeld14d6572008-12-03 15:06:57 +01005693static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305694 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005695{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005696 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005697 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005698 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005699 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005700
David Woodhouse5cf0a762014-03-19 16:07:49 +00005701 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005702 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005703 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005704
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005705 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005706}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005707
Lu Baolu95587a72019-03-25 09:30:30 +08005708static inline bool scalable_mode_support(void)
5709{
5710 struct dmar_drhd_unit *drhd;
5711 struct intel_iommu *iommu;
5712 bool ret = true;
5713
5714 rcu_read_lock();
5715 for_each_active_iommu(iommu, drhd) {
5716 if (!sm_supported(iommu)) {
5717 ret = false;
5718 break;
5719 }
5720 }
5721 rcu_read_unlock();
5722
5723 return ret;
5724}
5725
5726static inline bool iommu_pasid_support(void)
5727{
5728 struct dmar_drhd_unit *drhd;
5729 struct intel_iommu *iommu;
5730 bool ret = true;
5731
5732 rcu_read_lock();
5733 for_each_active_iommu(iommu, drhd) {
5734 if (!pasid_supported(iommu)) {
5735 ret = false;
5736 break;
5737 }
5738 }
5739 rcu_read_unlock();
5740
5741 return ret;
5742}
5743
Lu Baolu2cd13112020-01-02 08:18:15 +08005744static inline bool nested_mode_support(void)
5745{
5746 struct dmar_drhd_unit *drhd;
5747 struct intel_iommu *iommu;
5748 bool ret = true;
5749
5750 rcu_read_lock();
5751 for_each_active_iommu(iommu, drhd) {
5752 if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
5753 ret = false;
5754 break;
5755 }
5756 }
5757 rcu_read_unlock();
5758
5759 return ret;
5760}
5761
Joerg Roedel5d587b82014-09-05 10:50:45 +02005762static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005763{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005764 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005765 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005766 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005767 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005768
Joerg Roedel5d587b82014-09-05 10:50:45 +02005769 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005770}
5771
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005772static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005773{
Lu Baolu942067f2019-05-25 13:41:29 +08005774 struct dmar_domain *dmar_domain;
5775 struct iommu_domain *domain;
Alex Williamsona5459cf2014-06-12 16:12:31 -06005776 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005777 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005778 u8 bus, devfn;
Lu Baolu942067f2019-05-25 13:41:29 +08005779 int ret;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005780
Alex Williamsona5459cf2014-06-12 16:12:31 -06005781 iommu = device_to_iommu(dev, &bus, &devfn);
5782 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005783 return -ENODEV;
5784
Joerg Roedele3d10af2017-02-01 17:23:22 +01005785 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005786
Lu Baolu8af46c72019-05-25 13:41:32 +08005787 if (translation_pre_enabled(iommu))
5788 dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
5789
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005790 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005791
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005792 if (IS_ERR(group))
5793 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005794
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005795 iommu_group_put(group);
Lu Baolu942067f2019-05-25 13:41:29 +08005796
5797 domain = iommu_get_domain_for_dev(dev);
5798 dmar_domain = to_dmar_domain(domain);
5799 if (domain->type == IOMMU_DOMAIN_DMA) {
Lu Baolu0e31a722019-05-25 13:41:34 +08005800 if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) {
Lu Baolu942067f2019-05-25 13:41:29 +08005801 ret = iommu_request_dm_for_dev(dev);
5802 if (ret) {
Lu Baoluae23bfb62019-08-06 08:14:08 +08005803 dmar_remove_one_dev_info(dev);
Lu Baolu942067f2019-05-25 13:41:29 +08005804 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
5805 domain_add_dev_info(si_domain, dev);
5806 dev_info(dev,
5807 "Device uses a private identity domain.\n");
Lu Baolu942067f2019-05-25 13:41:29 +08005808 }
Lu Baolu942067f2019-05-25 13:41:29 +08005809 }
5810 } else {
Lu Baolu0e31a722019-05-25 13:41:34 +08005811 if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) {
Lu Baolu942067f2019-05-25 13:41:29 +08005812 ret = iommu_request_dma_domain_for_dev(dev);
5813 if (ret) {
Lu Baoluae23bfb62019-08-06 08:14:08 +08005814 dmar_remove_one_dev_info(dev);
Lu Baolu942067f2019-05-25 13:41:29 +08005815 dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN;
Lu Baolu4ec066c2019-05-25 13:41:33 +08005816 if (!get_private_domain_for_dev(dev)) {
Lu Baolu942067f2019-05-25 13:41:29 +08005817 dev_warn(dev,
5818 "Failed to get a private domain.\n");
5819 return -ENOMEM;
5820 }
5821
5822 dev_info(dev,
5823 "Device uses a private dma domain.\n");
Lu Baolu942067f2019-05-25 13:41:29 +08005824 }
Lu Baolu942067f2019-05-25 13:41:29 +08005825 }
5826 }
5827
Lu Baolucfb94a32019-09-06 14:14:52 +08005828 if (device_needs_bounce(dev)) {
5829 dev_info(dev, "Use Intel IOMMU bounce page dma_ops\n");
5830 set_dma_ops(dev, &bounce_dma_ops);
5831 }
5832
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005833 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005834}
5835
5836static void intel_iommu_remove_device(struct device *dev)
5837{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005838 struct intel_iommu *iommu;
5839 u8 bus, devfn;
5840
5841 iommu = device_to_iommu(dev, &bus, &devfn);
5842 if (!iommu)
5843 return;
5844
Lu Baolu458b7c82019-08-01 11:14:58 +08005845 dmar_remove_one_dev_info(dev);
5846
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005847 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005848
Joerg Roedele3d10af2017-02-01 17:23:22 +01005849 iommu_device_unlink(&iommu->iommu, dev);
Lu Baolucfb94a32019-09-06 14:14:52 +08005850
5851 if (device_needs_bounce(dev))
5852 set_dma_ops(dev, NULL);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005853}
5854
Eric Auger0659b8d2017-01-19 20:57:53 +00005855static void intel_iommu_get_resv_regions(struct device *device,
5856 struct list_head *head)
5857{
Eric Auger5f64ce52019-06-03 08:53:31 +02005858 int prot = DMA_PTE_READ | DMA_PTE_WRITE;
Eric Auger0659b8d2017-01-19 20:57:53 +00005859 struct iommu_resv_region *reg;
5860 struct dmar_rmrr_unit *rmrr;
5861 struct device *i_dev;
5862 int i;
5863
Eric Auger5f64ce52019-06-03 08:53:31 +02005864 down_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005865 for_each_rmrr_units(rmrr) {
5866 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5867 i, i_dev) {
Eric Auger5f64ce52019-06-03 08:53:31 +02005868 struct iommu_resv_region *resv;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005869 enum iommu_resv_type type;
Eric Auger5f64ce52019-06-03 08:53:31 +02005870 size_t length;
5871
Eric Auger3855ba22019-06-03 08:53:34 +02005872 if (i_dev != device &&
5873 !is_downstream_to_pci_bridge(device, i_dev))
Eric Auger0659b8d2017-01-19 20:57:53 +00005874 continue;
5875
Eric Auger5f64ce52019-06-03 08:53:31 +02005876 length = rmrr->end_address - rmrr->base_address + 1;
Eric Auger1c5c59f2019-06-03 08:53:36 +02005877
5878 type = device_rmrr_is_relaxable(device) ?
5879 IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;
5880
Eric Auger5f64ce52019-06-03 08:53:31 +02005881 resv = iommu_alloc_resv_region(rmrr->base_address,
Eric Auger1c5c59f2019-06-03 08:53:36 +02005882 length, prot, type);
Eric Auger5f64ce52019-06-03 08:53:31 +02005883 if (!resv)
5884 break;
5885
5886 list_add_tail(&resv->list, head);
Eric Auger0659b8d2017-01-19 20:57:53 +00005887 }
5888 }
Eric Auger5f64ce52019-06-03 08:53:31 +02005889 up_read(&dmar_global_lock);
Eric Auger0659b8d2017-01-19 20:57:53 +00005890
Lu Baolud850c2e2019-05-25 13:41:24 +08005891#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
5892 if (dev_is_pci(device)) {
5893 struct pci_dev *pdev = to_pci_dev(device);
5894
5895 if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) {
Jerry Snitselaarcde93192019-12-12 22:36:42 -07005896 reg = iommu_alloc_resv_region(0, 1UL << 24, prot,
Alex Williamsond8018a02019-12-11 13:28:29 -07005897 IOMMU_RESV_DIRECT_RELAXABLE);
Lu Baolud850c2e2019-05-25 13:41:24 +08005898 if (reg)
5899 list_add_tail(&reg->list, head);
5900 }
5901 }
5902#endif /* CONFIG_INTEL_IOMMU_FLOPPY_WA */
5903
Eric Auger0659b8d2017-01-19 20:57:53 +00005904 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5905 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005906 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005907 if (!reg)
5908 return;
5909 list_add_tail(&reg->list, head);
5910}
5911
5912static void intel_iommu_put_resv_regions(struct device *dev,
5913 struct list_head *head)
5914{
5915 struct iommu_resv_region *entry, *next;
5916
Eric Auger5f64ce52019-06-03 08:53:31 +02005917 list_for_each_entry_safe(entry, next, head, list)
5918 kfree(entry);
Kay, Allen M38717942008-09-09 18:37:29 +03005919}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005920
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005921int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005922{
5923 struct device_domain_info *info;
5924 struct context_entry *context;
5925 struct dmar_domain *domain;
5926 unsigned long flags;
5927 u64 ctx_lo;
5928 int ret;
5929
Lu Baolu4ec066c2019-05-25 13:41:33 +08005930 domain = find_domain(dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005931 if (!domain)
5932 return -EINVAL;
5933
5934 spin_lock_irqsave(&device_domain_lock, flags);
5935 spin_lock(&iommu->lock);
5936
5937 ret = -EINVAL;
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005938 info = dev->archdata.iommu;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005939 if (!info || !info->pasid_supported)
5940 goto out;
5941
5942 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5943 if (WARN_ON(!context))
5944 goto out;
5945
5946 ctx_lo = context[0].lo;
5947
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005948 if (!(ctx_lo & CONTEXT_PASIDE)) {
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005949 ctx_lo |= CONTEXT_PASIDE;
5950 context[0].lo = ctx_lo;
5951 wmb();
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005952 iommu->flush.flush_context(iommu,
5953 domain->iommu_did[iommu->seq_id],
5954 PCI_DEVID(info->bus, info->devfn),
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005955 DMA_CCMD_MASK_NOBIT,
5956 DMA_CCMD_DEVICE_INVL);
5957 }
5958
5959 /* Enable PASID support in the device, if it wasn't already */
5960 if (!info->pasid_enabled)
5961 iommu_enable_dev_iotlb(info);
5962
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005963 ret = 0;
5964
5965 out:
5966 spin_unlock(&iommu->lock);
5967 spin_unlock_irqrestore(&device_domain_lock, flags);
5968
5969 return ret;
5970}
5971
James Sewart73bcbdc2019-05-25 13:41:23 +08005972static void intel_iommu_apply_resv_region(struct device *dev,
5973 struct iommu_domain *domain,
5974 struct iommu_resv_region *region)
5975{
5976 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
5977 unsigned long start, end;
5978
5979 start = IOVA_PFN(region->start);
5980 end = IOVA_PFN(region->start + region->length - 1);
5981
5982 WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end));
5983}
5984
Lu Baolud7cbc0f2019-03-25 09:30:29 +08005985#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005986struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5987{
5988 struct intel_iommu *iommu;
5989 u8 bus, devfn;
5990
5991 if (iommu_dummy(dev)) {
5992 dev_warn(dev,
5993 "No IOMMU translation for device; cannot enable SVM\n");
5994 return NULL;
5995 }
5996
5997 iommu = device_to_iommu(dev, &bus, &devfn);
5998 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005999 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01006000 return NULL;
6001 }
6002
David Woodhouse2f26e0a2015-09-09 11:40:47 +01006003 return iommu;
6004}
6005#endif /* CONFIG_INTEL_IOMMU_SVM */
6006
Lu Baolu95587a72019-03-25 09:30:30 +08006007static int intel_iommu_enable_auxd(struct device *dev)
6008{
6009 struct device_domain_info *info;
6010 struct intel_iommu *iommu;
6011 unsigned long flags;
6012 u8 bus, devfn;
6013 int ret;
6014
6015 iommu = device_to_iommu(dev, &bus, &devfn);
6016 if (!iommu || dmar_disabled)
6017 return -EINVAL;
6018
6019 if (!sm_supported(iommu) || !pasid_supported(iommu))
6020 return -EINVAL;
6021
6022 ret = intel_iommu_enable_pasid(iommu, dev);
6023 if (ret)
6024 return -ENODEV;
6025
6026 spin_lock_irqsave(&device_domain_lock, flags);
6027 info = dev->archdata.iommu;
6028 info->auxd_enabled = 1;
6029 spin_unlock_irqrestore(&device_domain_lock, flags);
6030
6031 return 0;
6032}
6033
6034static int intel_iommu_disable_auxd(struct device *dev)
6035{
6036 struct device_domain_info *info;
6037 unsigned long flags;
6038
6039 spin_lock_irqsave(&device_domain_lock, flags);
6040 info = dev->archdata.iommu;
6041 if (!WARN_ON(!info))
6042 info->auxd_enabled = 0;
6043 spin_unlock_irqrestore(&device_domain_lock, flags);
6044
6045 return 0;
6046}
6047
6048/*
6049 * A PCI express designated vendor specific extended capability is defined
6050 * in the section 3.7 of Intel scalable I/O virtualization technical spec
6051 * for system software and tools to detect endpoint devices supporting the
6052 * Intel scalable IO virtualization without host driver dependency.
6053 *
6054 * Returns the address of the matching extended capability structure within
6055 * the device's PCI configuration space or 0 if the device does not support
6056 * it.
6057 */
6058static int siov_find_pci_dvsec(struct pci_dev *pdev)
6059{
6060 int pos;
6061 u16 vendor, id;
6062
6063 pos = pci_find_next_ext_capability(pdev, 0, 0x23);
6064 while (pos) {
6065 pci_read_config_word(pdev, pos + 4, &vendor);
6066 pci_read_config_word(pdev, pos + 8, &id);
6067 if (vendor == PCI_VENDOR_ID_INTEL && id == 5)
6068 return pos;
6069
6070 pos = pci_find_next_ext_capability(pdev, pos, 0x23);
6071 }
6072
6073 return 0;
6074}
6075
6076static bool
6077intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)
6078{
6079 if (feat == IOMMU_DEV_FEAT_AUX) {
6080 int ret;
6081
6082 if (!dev_is_pci(dev) || dmar_disabled ||
6083 !scalable_mode_support() || !iommu_pasid_support())
6084 return false;
6085
6086 ret = pci_pasid_features(to_pci_dev(dev));
6087 if (ret < 0)
6088 return false;
6089
6090 return !!siov_find_pci_dvsec(to_pci_dev(dev));
6091 }
6092
6093 return false;
6094}
6095
6096static int
6097intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
6098{
6099 if (feat == IOMMU_DEV_FEAT_AUX)
6100 return intel_iommu_enable_auxd(dev);
6101
6102 return -ENODEV;
6103}
6104
6105static int
6106intel_iommu_dev_disable_feat(struct device *dev, enum iommu_dev_features feat)
6107{
6108 if (feat == IOMMU_DEV_FEAT_AUX)
6109 return intel_iommu_disable_auxd(dev);
6110
6111 return -ENODEV;
6112}
6113
6114static bool
6115intel_iommu_dev_feat_enabled(struct device *dev, enum iommu_dev_features feat)
6116{
6117 struct device_domain_info *info = dev->archdata.iommu;
6118
6119 if (feat == IOMMU_DEV_FEAT_AUX)
6120 return scalable_mode_support() && info && info->auxd_enabled;
6121
6122 return false;
6123}
6124
Lu Baolu0e8000f2019-03-25 09:30:33 +08006125static int
6126intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
6127{
6128 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
6129
6130 return dmar_domain->default_pasid > 0 ?
6131 dmar_domain->default_pasid : -EINVAL;
6132}
6133
Lu Baolu8af46c72019-05-25 13:41:32 +08006134static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
6135 struct device *dev)
6136{
6137 return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
6138}
6139
Lu Baolu2cd13112020-01-02 08:18:15 +08006140static int
6141intel_iommu_domain_set_attr(struct iommu_domain *domain,
6142 enum iommu_attr attr, void *data)
6143{
6144 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
6145 unsigned long flags;
6146 int ret = 0;
6147
6148 if (domain->type != IOMMU_DOMAIN_UNMANAGED)
6149 return -EINVAL;
6150
6151 switch (attr) {
6152 case DOMAIN_ATTR_NESTING:
6153 spin_lock_irqsave(&device_domain_lock, flags);
6154 if (nested_mode_support() &&
6155 list_empty(&dmar_domain->devices)) {
6156 dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;
6157 dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;
6158 } else {
6159 ret = -ENODEV;
6160 }
6161 spin_unlock_irqrestore(&device_domain_lock, flags);
6162 break;
6163 default:
6164 ret = -EINVAL;
6165 break;
6166 }
6167
6168 return ret;
6169}
6170
Joerg Roedelb0119e82017-02-01 13:23:08 +01006171const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00006172 .capable = intel_iommu_capable,
6173 .domain_alloc = intel_iommu_domain_alloc,
6174 .domain_free = intel_iommu_domain_free,
Lu Baolu2cd13112020-01-02 08:18:15 +08006175 .domain_set_attr = intel_iommu_domain_set_attr,
Eric Auger0659b8d2017-01-19 20:57:53 +00006176 .attach_dev = intel_iommu_attach_device,
6177 .detach_dev = intel_iommu_detach_device,
Lu Baolu67b8e022019-03-25 09:30:32 +08006178 .aux_attach_dev = intel_iommu_aux_attach_device,
6179 .aux_detach_dev = intel_iommu_aux_detach_device,
Lu Baolu0e8000f2019-03-25 09:30:33 +08006180 .aux_get_pasid = intel_iommu_aux_get_pasid,
Eric Auger0659b8d2017-01-19 20:57:53 +00006181 .map = intel_iommu_map,
6182 .unmap = intel_iommu_unmap,
Eric Auger0659b8d2017-01-19 20:57:53 +00006183 .iova_to_phys = intel_iommu_iova_to_phys,
6184 .add_device = intel_iommu_add_device,
6185 .remove_device = intel_iommu_remove_device,
6186 .get_resv_regions = intel_iommu_get_resv_regions,
6187 .put_resv_regions = intel_iommu_put_resv_regions,
James Sewart73bcbdc2019-05-25 13:41:23 +08006188 .apply_resv_region = intel_iommu_apply_resv_region,
Eric Auger0659b8d2017-01-19 20:57:53 +00006189 .device_group = pci_device_group,
Lu Baolu95587a72019-03-25 09:30:30 +08006190 .dev_has_feat = intel_iommu_dev_has_feat,
6191 .dev_feat_enabled = intel_iommu_dev_feat_enabled,
6192 .dev_enable_feat = intel_iommu_dev_enable_feat,
6193 .dev_disable_feat = intel_iommu_dev_disable_feat,
Lu Baolu8af46c72019-05-25 13:41:32 +08006194 .is_attach_deferred = intel_iommu_is_attach_deferred,
Eric Auger0659b8d2017-01-19 20:57:53 +00006195 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01006196};
David Woodhouse9af88142009-02-13 23:18:03 +00006197
Chris Wilson1f762492019-09-09 12:00:10 +01006198static void quirk_iommu_igfx(struct pci_dev *dev)
Daniel Vetter94526182013-01-20 23:50:13 +01006199{
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006200 pci_info(dev, "Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01006201 dmar_map_gfx = 0;
6202}
6203
Chris Wilson1f762492019-09-09 12:00:10 +01006204/* G4x/GM45 integrated gfx dmar support is totally busted. */
6205DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
6206DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
6207DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_igfx);
6208DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_igfx);
6209DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
6210DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
6211DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
6212
6213/* Broadwell igfx malfunctions with dmar */
6214DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
6215DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
6216DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160E, quirk_iommu_igfx);
6217DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1602, quirk_iommu_igfx);
6218DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160A, quirk_iommu_igfx);
6219DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160D, quirk_iommu_igfx);
6220DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1616, quirk_iommu_igfx);
6221DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161B, quirk_iommu_igfx);
6222DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161E, quirk_iommu_igfx);
6223DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1612, quirk_iommu_igfx);
6224DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161A, quirk_iommu_igfx);
6225DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161D, quirk_iommu_igfx);
6226DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1626, quirk_iommu_igfx);
6227DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162B, quirk_iommu_igfx);
6228DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162E, quirk_iommu_igfx);
6229DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1622, quirk_iommu_igfx);
6230DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162A, quirk_iommu_igfx);
6231DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162D, quirk_iommu_igfx);
6232DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1636, quirk_iommu_igfx);
6233DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163B, quirk_iommu_igfx);
6234DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163E, quirk_iommu_igfx);
6235DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
6236DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
6237DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
Daniel Vetter94526182013-01-20 23:50:13 +01006238
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006239static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00006240{
6241 /*
6242 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01006243 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00006244 */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006245 pci_info(dev, "Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00006246 rwbf_quirk = 1;
6247}
6248
6249DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01006250DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
6251DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
6252DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
6253DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
6254DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
6255DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07006256
Adam Jacksoneecfd572010-08-25 21:17:34 +01006257#define GGC 0x52
6258#define GGC_MEMORY_SIZE_MASK (0xf << 8)
6259#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
6260#define GGC_MEMORY_SIZE_1M (0x1 << 8)
6261#define GGC_MEMORY_SIZE_2M (0x3 << 8)
6262#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
6263#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
6264#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
6265#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
6266
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08006267static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01006268{
6269 unsigned short ggc;
6270
Adam Jacksoneecfd572010-08-25 21:17:34 +01006271 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01006272 return;
6273
Adam Jacksoneecfd572010-08-25 21:17:34 +01006274 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006275 pci_info(dev, "BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01006276 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006277 } else if (dmar_map_gfx) {
6278 /* we have to ensure the gfx device is idle before we flush */
Bjorn Helgaas932a6522019-02-08 16:06:00 -06006279 pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07006280 intel_iommu_strict = 1;
6281 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01006282}
6283DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
6284DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
6285DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
6286DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
6287
David Woodhousee0fc7e02009-09-30 09:12:17 -07006288/* On Tylersburg chipsets, some BIOSes have been known to enable the
6289 ISOCH DMAR unit for the Azalia sound device, but not give it any
6290 TLB entries, which causes it to deadlock. Check for that. We do
6291 this in a function called from init_dmars(), instead of in a PCI
6292 quirk, because we don't want to print the obnoxious "BIOS broken"
6293 message if VT-d is actually disabled.
6294*/
6295static void __init check_tylersburg_isoch(void)
6296{
6297 struct pci_dev *pdev;
6298 uint32_t vtisochctrl;
6299
6300 /* If there's no Azalia in the system anyway, forget it. */
6301 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
6302 if (!pdev)
6303 return;
6304 pci_dev_put(pdev);
6305
6306 /* System Management Registers. Might be hidden, in which case
6307 we can't do the sanity check. But that's OK, because the
6308 known-broken BIOSes _don't_ actually hide it, so far. */
6309 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
6310 if (!pdev)
6311 return;
6312
6313 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
6314 pci_dev_put(pdev);
6315 return;
6316 }
6317
6318 pci_dev_put(pdev);
6319
6320 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
6321 if (vtisochctrl & 1)
6322 return;
6323
6324 /* Drop all bits other than the number of TLB entries */
6325 vtisochctrl &= 0x1c;
6326
6327 /* If we have the recommended number of TLB entries (16), fine. */
6328 if (vtisochctrl == 0x10)
6329 return;
6330
6331 /* Zero TLB entries? You get to ride the short bus to school. */
6332 if (!vtisochctrl) {
6333 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
6334 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
6335 dmi_get_system_info(DMI_BIOS_VENDOR),
6336 dmi_get_system_info(DMI_BIOS_VERSION),
6337 dmi_get_system_info(DMI_PRODUCT_VERSION));
6338 iommu_identity_mapping |= IDENTMAP_AZALIA;
6339 return;
6340 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02006341
6342 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07006343 vtisochctrl);
6344}