blob: bb0448c91f672b75a552075de5d27659ed396eea [file] [log] [blame]
Joerg Roedelb6c02712008-06-26 21:27:53 +02001/*
Joerg Roedel5d0d7152010-10-13 11:13:21 +02002 * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
Joerg Roedel63ce3ae2015-02-04 16:12:55 +01003 * Author: Joerg Roedel <jroedel@suse.de>
Joerg Roedelb6c02712008-06-26 21:27:53 +02004 * Leo Duran <leo.duran@amd.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
Joerg Roedel72e1dcc2011-11-10 19:13:51 +010020#include <linux/ratelimit.h>
Joerg Roedelb6c02712008-06-26 21:27:53 +020021#include <linux/pci.h>
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -040022#include <linux/acpi.h>
Wan Zongshun9a4d3bf52016-04-01 09:06:05 -040023#include <linux/amba/bus.h>
Wan Zongshun0076cd32016-05-10 09:21:01 -040024#include <linux/platform_device.h>
Joerg Roedelcb41ed82011-04-05 11:00:53 +020025#include <linux/pci-ats.h>
Akinobu Mitaa66022c2009-12-15 16:48:28 -080026#include <linux/bitmap.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090027#include <linux/slab.h>
Joerg Roedel7f265082008-12-12 13:50:21 +010028#include <linux/debugfs.h>
Joerg Roedelb6c02712008-06-26 21:27:53 +020029#include <linux/scatterlist.h>
FUJITA Tomonori51491362009-01-05 23:47:25 +090030#include <linux/dma-mapping.h>
Joerg Roedelb6c02712008-06-26 21:27:53 +020031#include <linux/iommu-helper.h>
Joerg Roedelc156e342008-12-02 18:13:27 +010032#include <linux/iommu.h>
Joerg Roedel815b33f2011-04-06 17:26:49 +020033#include <linux/delay.h>
Joerg Roedel403f81d2011-06-14 16:44:25 +020034#include <linux/amd-iommu.h>
Joerg Roedel72e1dcc2011-11-10 19:13:51 +010035#include <linux/notifier.h>
36#include <linux/export.h>
Joerg Roedel2b324502012-06-21 16:29:10 +020037#include <linux/irq.h>
38#include <linux/msi.h>
Joerg Roedel3b839a52015-04-01 14:58:47 +020039#include <linux/dma-contiguous.h>
Jiang Liu7c71d302015-04-13 14:11:33 +080040#include <linux/irqdomain.h>
Joerg Roedel5f6bed52015-12-22 13:34:22 +010041#include <linux/percpu.h>
Joerg Roedel307d5852016-07-05 11:54:04 +020042#include <linux/iova.h>
Joerg Roedel2b324502012-06-21 16:29:10 +020043#include <asm/irq_remapping.h>
44#include <asm/io_apic.h>
45#include <asm/apic.h>
46#include <asm/hw_irq.h>
Joerg Roedel17f5b562011-07-06 17:14:44 +020047#include <asm/msidef.h>
Joerg Roedelb6c02712008-06-26 21:27:53 +020048#include <asm/proto.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090049#include <asm/iommu.h>
Joerg Roedel1d9b16d2008-11-27 18:39:15 +010050#include <asm/gart.h>
Joerg Roedel27c21272011-05-30 15:56:24 +020051#include <asm/dma.h>
Joerg Roedel403f81d2011-06-14 16:44:25 +020052
53#include "amd_iommu_proto.h"
54#include "amd_iommu_types.h"
Joerg Roedel6b474b82012-06-26 16:46:04 +020055#include "irq_remapping.h"
Joerg Roedelb6c02712008-06-26 21:27:53 +020056
57#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
58
Joerg Roedel815b33f2011-04-06 17:26:49 +020059#define LOOP_TIMEOUT 100000
Joerg Roedel136f78a2008-07-11 17:14:27 +020060
Joerg Roedel307d5852016-07-05 11:54:04 +020061/* IO virtual address start page frame number */
62#define IOVA_START_PFN (1)
63#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
64#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
65
Joerg Roedel81cd07b2016-07-07 18:01:10 +020066/* Reserved IOVA ranges */
67#define MSI_RANGE_START (0xfee00000)
68#define MSI_RANGE_END (0xfeefffff)
69#define HT_RANGE_START (0xfd00000000ULL)
70#define HT_RANGE_END (0xffffffffffULL)
71
Ohad Ben-Cohenaa3de9c2011-11-10 11:32:29 +020072/*
73 * This bitmap is used to advertise the page sizes our hardware support
74 * to the IOMMU core, which will then use this information to split
75 * physically contiguous memory regions it is mapping into page sizes
76 * that we support.
77 *
Joerg Roedel954e3dd2012-12-02 15:35:37 +010078 * 512GB Pages are not supported due to a hardware bug
Ohad Ben-Cohenaa3de9c2011-11-10 11:32:29 +020079 */
Joerg Roedel954e3dd2012-12-02 15:35:37 +010080#define AMD_IOMMU_PGSIZES ((~0xFFFUL) & ~(2ULL << 38))
Ohad Ben-Cohenaa3de9c2011-11-10 11:32:29 +020081
Joerg Roedelb6c02712008-06-26 21:27:53 +020082static DEFINE_RWLOCK(amd_iommu_devtable_lock);
83
Joerg Roedel8fa5f802011-06-09 12:24:45 +020084/* List of all available dev_data structures */
85static LIST_HEAD(dev_data_list);
86static DEFINE_SPINLOCK(dev_data_list_lock);
87
Joerg Roedel6efed632012-06-14 15:52:58 +020088LIST_HEAD(ioapic_map);
89LIST_HEAD(hpet_map);
Wan Zongshun2a0cb4e2016-04-01 09:06:00 -040090LIST_HEAD(acpihid_map);
Joerg Roedel6efed632012-06-14 15:52:58 +020091
Joerg Roedelc5b5da92016-07-06 11:55:37 +020092#define FLUSH_QUEUE_SIZE 256
93
94struct flush_queue_entry {
95 unsigned long iova_pfn;
96 unsigned long pages;
97 struct dma_ops_domain *dma_dom;
98};
99
100struct flush_queue {
101 spinlock_t lock;
102 unsigned next;
103 struct flush_queue_entry *entries;
104};
105
Wei Yongjuna5604f22016-07-28 02:09:53 +0000106static DEFINE_PER_CPU(struct flush_queue, flush_queue);
Joerg Roedelc5b5da92016-07-06 11:55:37 +0200107
Joerg Roedelbb279472016-07-06 13:56:36 +0200108static atomic_t queue_timer_on;
109static struct timer_list queue_timer;
110
Joerg Roedel0feae532009-08-26 15:26:30 +0200111/*
112 * Domain for untranslated devices - only allocated
113 * if iommu=pt passed on kernel cmd line.
114 */
Thierry Redingb22f6432014-06-27 09:03:12 +0200115static const struct iommu_ops amd_iommu_ops;
Joerg Roedel26961ef2008-12-03 17:00:17 +0100116
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100117static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
Joerg Roedel52815b72011-11-17 17:24:28 +0100118int amd_iommu_max_glx_val = -1;
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100119
Joerg Roedelac1534a2012-06-21 14:52:40 +0200120static struct dma_map_ops amd_iommu_dma_ops;
121
Joerg Roedel431b2a22008-07-11 17:14:22 +0200122/*
Joerg Roedel50917e22014-08-05 16:38:38 +0200123 * This struct contains device specific data for the IOMMU
124 */
125struct iommu_dev_data {
126 struct list_head list; /* For domain->dev_list */
127 struct list_head dev_data_list; /* For global dev_data_list */
Joerg Roedel50917e22014-08-05 16:38:38 +0200128 struct protection_domain *domain; /* Domain the device is bound to */
Joerg Roedel50917e22014-08-05 16:38:38 +0200129 u16 devid; /* PCI Device ID */
Joerg Roedele3156042016-04-08 15:12:24 +0200130 u16 alias; /* Alias Device ID */
Joerg Roedel50917e22014-08-05 16:38:38 +0200131 bool iommu_v2; /* Device can make use of IOMMUv2 */
Joerg Roedel1e6a7b02015-07-28 16:58:48 +0200132 bool passthrough; /* Device is identity mapped */
Joerg Roedel50917e22014-08-05 16:38:38 +0200133 struct {
134 bool enabled;
135 int qdep;
136 } ats; /* ATS state */
137 bool pri_tlp; /* PASID TLB required for
138 PPR completions */
139 u32 errata; /* Bitmap for errata to apply */
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -0500140 bool use_vapic; /* Enable device to use vapic mode */
Joerg Roedel50917e22014-08-05 16:38:38 +0200141};
142
143/*
Joerg Roedel431b2a22008-07-11 17:14:22 +0200144 * general struct to manage commands send to an IOMMU
145 */
Joerg Roedeld6449532008-07-11 17:14:28 +0200146struct iommu_cmd {
Joerg Roedelb6c02712008-06-26 21:27:53 +0200147 u32 data[4];
148};
149
Joerg Roedel05152a02012-06-15 16:53:51 +0200150struct kmem_cache *amd_iommu_irq_cache;
151
Joerg Roedel04bfdd82009-09-02 16:00:23 +0200152static void update_domain(struct protection_domain *domain);
Joerg Roedel7a5a5662015-06-30 08:56:11 +0200153static int protection_domain_init(struct protection_domain *domain);
Joerg Roedelb6809ee2016-02-26 16:48:59 +0100154static void detach_device(struct device *dev);
Chris Wrightc1eee672009-05-21 00:56:58 -0700155
Joerg Roedel007b74b2015-12-21 12:53:54 +0100156/*
Joerg Roedel007b74b2015-12-21 12:53:54 +0100157 * Data container for a dma_ops specific protection domain
158 */
159struct dma_ops_domain {
160 /* generic protection domain information */
161 struct protection_domain domain;
162
Joerg Roedel307d5852016-07-05 11:54:04 +0200163 /* IOVA RB-Tree */
164 struct iova_domain iovad;
Joerg Roedel007b74b2015-12-21 12:53:54 +0100165};
166
Joerg Roedel81cd07b2016-07-07 18:01:10 +0200167static struct iova_domain reserved_iova_ranges;
168static struct lock_class_key reserved_rbtree_key;
169
Joerg Roedel15898bb2009-11-24 15:39:42 +0100170/****************************************************************************
171 *
172 * Helper functions
173 *
174 ****************************************************************************/
175
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400176static inline int match_hid_uid(struct device *dev,
177 struct acpihid_map_entry *entry)
Joerg Roedel3f4b87b2015-03-26 13:43:07 +0100178{
Aaron Ma08713022019-03-13 21:53:24 +0800179 struct acpi_device *adev = ACPI_COMPANION(dev);
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400180 const char *hid, *uid;
181
Aaron Ma08713022019-03-13 21:53:24 +0800182 if (!adev)
183 return -ENODEV;
184
185 hid = acpi_device_hid(adev);
186 uid = acpi_device_uid(adev);
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400187
188 if (!hid || !(*hid))
189 return -ENODEV;
190
191 if (!uid || !(*uid))
192 return strcmp(hid, entry->hid);
193
194 if (!(*entry->uid))
195 return strcmp(hid, entry->hid);
196
197 return (strcmp(hid, entry->hid) || strcmp(uid, entry->uid));
Joerg Roedel3f4b87b2015-03-26 13:43:07 +0100198}
199
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400200static inline u16 get_pci_device_id(struct device *dev)
Joerg Roedele3156042016-04-08 15:12:24 +0200201{
202 struct pci_dev *pdev = to_pci_dev(dev);
203
204 return PCI_DEVID(pdev->bus->number, pdev->devfn);
205}
206
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400207static inline int get_acpihid_device_id(struct device *dev,
208 struct acpihid_map_entry **entry)
209{
210 struct acpihid_map_entry *p;
211
212 list_for_each_entry(p, &acpihid_map, list) {
213 if (!match_hid_uid(dev, p)) {
214 if (entry)
215 *entry = p;
216 return p->devid;
217 }
218 }
219 return -EINVAL;
220}
221
222static inline int get_device_id(struct device *dev)
223{
224 int devid;
225
226 if (dev_is_pci(dev))
227 devid = get_pci_device_id(dev);
228 else
229 devid = get_acpihid_device_id(dev, NULL);
230
231 return devid;
232}
233
Joerg Roedel15898bb2009-11-24 15:39:42 +0100234static struct protection_domain *to_pdomain(struct iommu_domain *dom)
235{
236 return container_of(dom, struct protection_domain, domain);
237}
238
Joerg Roedelb3311b02016-07-08 13:31:31 +0200239static struct dma_ops_domain* to_dma_ops_domain(struct protection_domain *domain)
240{
241 BUG_ON(domain->flags != PD_DMA_OPS_MASK);
242 return container_of(domain, struct dma_ops_domain, domain);
243}
244
Joerg Roedelf62dda62011-06-09 12:55:35 +0200245static struct iommu_dev_data *alloc_dev_data(u16 devid)
Joerg Roedel8fa5f802011-06-09 12:24:45 +0200246{
247 struct iommu_dev_data *dev_data;
248 unsigned long flags;
249
250 dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
251 if (!dev_data)
252 return NULL;
253
Joerg Roedelf62dda62011-06-09 12:55:35 +0200254 dev_data->devid = devid;
Joerg Roedel8fa5f802011-06-09 12:24:45 +0200255
256 spin_lock_irqsave(&dev_data_list_lock, flags);
257 list_add_tail(&dev_data->dev_data_list, &dev_data_list);
258 spin_unlock_irqrestore(&dev_data_list_lock, flags);
259
260 return dev_data;
261}
262
Joerg Roedel3b03bb72011-06-09 18:53:25 +0200263static struct iommu_dev_data *search_dev_data(u16 devid)
264{
265 struct iommu_dev_data *dev_data;
266 unsigned long flags;
267
268 spin_lock_irqsave(&dev_data_list_lock, flags);
269 list_for_each_entry(dev_data, &dev_data_list, dev_data_list) {
270 if (dev_data->devid == devid)
271 goto out_unlock;
272 }
273
274 dev_data = NULL;
275
276out_unlock:
277 spin_unlock_irqrestore(&dev_data_list_lock, flags);
278
279 return dev_data;
280}
281
Joerg Roedele3156042016-04-08 15:12:24 +0200282static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
283{
284 *(u16 *)data = alias;
285 return 0;
286}
287
288static u16 get_alias(struct device *dev)
289{
290 struct pci_dev *pdev = to_pci_dev(dev);
291 u16 devid, ivrs_alias, pci_alias;
292
Joerg Roedel6c0b43d2016-05-09 19:39:17 +0200293 /* The callers make sure that get_device_id() does not fail here */
Joerg Roedele3156042016-04-08 15:12:24 +0200294 devid = get_device_id(dev);
Arindam Nath792a9642018-09-18 15:40:58 +0530295
296 /* For ACPI HID devices, we simply return the devid as such */
297 if (!dev_is_pci(dev))
298 return devid;
299
Joerg Roedele3156042016-04-08 15:12:24 +0200300 ivrs_alias = amd_iommu_alias_table[devid];
Arindam Nath792a9642018-09-18 15:40:58 +0530301
Joerg Roedele3156042016-04-08 15:12:24 +0200302 pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
303
304 if (ivrs_alias == pci_alias)
305 return ivrs_alias;
306
307 /*
308 * DMA alias showdown
309 *
310 * The IVRS is fairly reliable in telling us about aliases, but it
311 * can't know about every screwy device. If we don't have an IVRS
312 * reported alias, use the PCI reported alias. In that case we may
313 * still need to initialize the rlookup and dev_table entries if the
314 * alias is to a non-existent device.
315 */
316 if (ivrs_alias == devid) {
317 if (!amd_iommu_rlookup_table[pci_alias]) {
318 amd_iommu_rlookup_table[pci_alias] =
319 amd_iommu_rlookup_table[devid];
320 memcpy(amd_iommu_dev_table[pci_alias].data,
321 amd_iommu_dev_table[devid].data,
322 sizeof(amd_iommu_dev_table[pci_alias].data));
323 }
324
325 return pci_alias;
326 }
327
328 pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "
329 "for device %s[%04x:%04x], kernel reported alias "
330 "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
331 PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
332 PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
333 PCI_FUNC(pci_alias));
334
335 /*
336 * If we don't have a PCI DMA alias and the IVRS alias is on the same
337 * bus, then the IVRS table may know about a quirk that we don't.
338 */
339 if (pci_alias == devid &&
340 PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
Linus Torvalds7afd16f2016-05-19 13:10:54 -0700341 pci_add_dma_alias(pdev, ivrs_alias & 0xff);
Joerg Roedele3156042016-04-08 15:12:24 +0200342 pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",
343 PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
344 dev_name(dev));
345 }
346
347 return ivrs_alias;
348}
349
Joerg Roedel3b03bb72011-06-09 18:53:25 +0200350static struct iommu_dev_data *find_dev_data(u16 devid)
351{
352 struct iommu_dev_data *dev_data;
353
354 dev_data = search_dev_data(devid);
355
356 if (dev_data == NULL)
357 dev_data = alloc_dev_data(devid);
358
359 return dev_data;
360}
361
Joerg Roedel657cbb62009-11-23 15:26:46 +0100362static struct iommu_dev_data *get_dev_data(struct device *dev)
363{
364 return dev->archdata.iommu;
365}
366
Wan Zongshunb097d112016-04-01 09:06:04 -0400367/*
368* Find or create an IOMMU group for a acpihid device.
369*/
370static struct iommu_group *acpihid_device_group(struct device *dev)
371{
372 struct acpihid_map_entry *p, *entry = NULL;
Dan Carpenter2d8e1f02016-04-11 10:14:46 +0300373 int devid;
Wan Zongshunb097d112016-04-01 09:06:04 -0400374
375 devid = get_acpihid_device_id(dev, &entry);
376 if (devid < 0)
377 return ERR_PTR(devid);
378
379 list_for_each_entry(p, &acpihid_map, list) {
380 if ((devid == p->devid) && p->group)
381 entry->group = p->group;
382 }
383
384 if (!entry->group)
385 entry->group = generic_device_group(dev);
386
387 return entry->group;
388}
389
Joerg Roedel5abcdba2011-12-01 15:49:45 +0100390static bool pci_iommuv2_capable(struct pci_dev *pdev)
391{
392 static const int caps[] = {
393 PCI_EXT_CAP_ID_ATS,
Joerg Roedel46277b72011-12-07 14:34:02 +0100394 PCI_EXT_CAP_ID_PRI,
395 PCI_EXT_CAP_ID_PASID,
Joerg Roedel5abcdba2011-12-01 15:49:45 +0100396 };
397 int i, pos;
398
399 for (i = 0; i < 3; ++i) {
400 pos = pci_find_ext_capability(pdev, caps[i]);
401 if (pos == 0)
402 return false;
403 }
404
405 return true;
406}
407
Joerg Roedel6a113dd2011-12-01 12:04:58 +0100408static bool pdev_pri_erratum(struct pci_dev *pdev, u32 erratum)
409{
410 struct iommu_dev_data *dev_data;
411
412 dev_data = get_dev_data(&pdev->dev);
413
414 return dev_data->errata & (1 << erratum) ? true : false;
415}
416
Joerg Roedel71c70982009-11-24 16:43:06 +0100417/*
Joerg Roedel98fc5a62009-11-24 17:19:23 +0100418 * This function checks if the driver got a valid device from the caller to
419 * avoid dereferencing invalid pointers.
420 */
421static bool check_device(struct device *dev)
422{
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400423 int devid;
Joerg Roedel98fc5a62009-11-24 17:19:23 +0100424
425 if (!dev || !dev->dma_mask)
426 return false;
427
Joerg Roedel98fc5a62009-11-24 17:19:23 +0100428 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +0200429 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400430 return false;
Joerg Roedel98fc5a62009-11-24 17:19:23 +0100431
432 /* Out of our scope? */
433 if (devid > amd_iommu_last_bdf)
434 return false;
435
436 if (amd_iommu_rlookup_table[devid] == NULL)
437 return false;
438
439 return true;
440}
441
Alex Williamson25b11ce2014-09-19 10:03:13 -0600442static void init_iommu_group(struct device *dev)
Alex Williamson2851db22012-10-08 22:49:41 -0600443{
Alex Williamson2851db22012-10-08 22:49:41 -0600444 struct iommu_group *group;
Alex Williamson2851db22012-10-08 22:49:41 -0600445
Alex Williamson65d53522014-07-03 09:51:30 -0600446 group = iommu_group_get_for_dev(dev);
Joerg Roedel0bb6e242015-05-28 18:41:40 +0200447 if (IS_ERR(group))
448 return;
449
Joerg Roedel0bb6e242015-05-28 18:41:40 +0200450 iommu_group_put(group);
Alex Williamsoneb9c9522012-10-08 22:49:35 -0600451}
452
453static int iommu_init_device(struct device *dev)
454{
Alex Williamsoneb9c9522012-10-08 22:49:35 -0600455 struct iommu_dev_data *dev_data;
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400456 int devid;
Alex Williamsoneb9c9522012-10-08 22:49:35 -0600457
458 if (dev->archdata.iommu)
459 return 0;
460
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400461 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +0200462 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400463 return devid;
464
465 dev_data = find_dev_data(devid);
Alex Williamsoneb9c9522012-10-08 22:49:35 -0600466 if (!dev_data)
467 return -ENOMEM;
468
Joerg Roedele3156042016-04-08 15:12:24 +0200469 dev_data->alias = get_alias(dev);
470
Yu Zhaod4ccfce2018-12-06 14:39:15 -0700471 /*
472 * By default we use passthrough mode for IOMMUv2 capable device.
473 * But if amd_iommu=force_isolation is set (e.g. to debug DMA to
474 * invalid address), we ignore the capability for the device so
475 * it'll be forced to go into translation mode.
476 */
477 if ((iommu_pass_through || !amd_iommu_force_isolation) &&
478 dev_is_pci(dev) && pci_iommuv2_capable(to_pci_dev(dev))) {
Joerg Roedel5abcdba2011-12-01 15:49:45 +0100479 struct amd_iommu *iommu;
480
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -0400481 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedel5abcdba2011-12-01 15:49:45 +0100482 dev_data->iommu_v2 = iommu->is_iommu_v2;
483 }
484
Joerg Roedel657cbb62009-11-23 15:26:46 +0100485 dev->archdata.iommu = dev_data;
486
Alex Williamson066f2e92014-06-12 16:12:37 -0600487 iommu_device_link(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
488 dev);
489
Joerg Roedel657cbb62009-11-23 15:26:46 +0100490 return 0;
491}
492
Joerg Roedel26018872011-06-06 16:50:14 +0200493static void iommu_ignore_device(struct device *dev)
494{
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400495 u16 alias;
496 int devid;
Joerg Roedel26018872011-06-06 16:50:14 +0200497
498 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +0200499 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400500 return;
501
Joerg Roedele3156042016-04-08 15:12:24 +0200502 alias = get_alias(dev);
Joerg Roedel26018872011-06-06 16:50:14 +0200503
504 memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry));
505 memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry));
506
507 amd_iommu_rlookup_table[devid] = NULL;
508 amd_iommu_rlookup_table[alias] = NULL;
509}
510
Joerg Roedel657cbb62009-11-23 15:26:46 +0100511static void iommu_uninit_device(struct device *dev)
512{
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400513 int devid;
514 struct iommu_dev_data *dev_data;
Alex Williamsonc1931092014-07-03 09:51:24 -0600515
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400516 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +0200517 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -0400518 return;
519
520 dev_data = search_dev_data(devid);
Alex Williamsonc1931092014-07-03 09:51:24 -0600521 if (!dev_data)
522 return;
523
Joerg Roedelb6809ee2016-02-26 16:48:59 +0100524 if (dev_data->domain)
525 detach_device(dev);
526
Alex Williamson066f2e92014-06-12 16:12:37 -0600527 iommu_device_unlink(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
528 dev);
529
Alex Williamson9dcd6132012-05-30 14:19:07 -0600530 iommu_group_remove_device(dev);
531
Joerg Roedelaafd8ba2015-05-28 18:41:39 +0200532 /* Remove dma-ops */
533 dev->archdata.dma_ops = NULL;
534
Joerg Roedel8fa5f802011-06-09 12:24:45 +0200535 /*
Alex Williamsonc1931092014-07-03 09:51:24 -0600536 * We keep dev_data around for unplugged devices and reuse it when the
537 * device is re-plugged - not doing so would introduce a ton of races.
Joerg Roedel8fa5f802011-06-09 12:24:45 +0200538 */
Joerg Roedel657cbb62009-11-23 15:26:46 +0100539}
Joerg Roedelb7cc9552009-12-10 11:03:39 +0100540
Joerg Roedel431b2a22008-07-11 17:14:22 +0200541/****************************************************************************
542 *
Joerg Roedela80dc3e2008-09-11 16:51:41 +0200543 * Interrupt handling functions
544 *
545 ****************************************************************************/
546
Joerg Roedele3e59872009-09-03 14:02:10 +0200547static void dump_dte_entry(u16 devid)
548{
549 int i;
550
Joerg Roedelee6c2862011-11-09 12:06:03 +0100551 for (i = 0; i < 4; ++i)
552 pr_err("AMD-Vi: DTE[%d]: %016llx\n", i,
Joerg Roedele3e59872009-09-03 14:02:10 +0200553 amd_iommu_dev_table[devid].data[i]);
554}
555
Joerg Roedel945b4ac2009-09-03 14:25:02 +0200556static void dump_command(unsigned long phys_addr)
557{
558 struct iommu_cmd *cmd = phys_to_virt(phys_addr);
559 int i;
560
561 for (i = 0; i < 4; ++i)
562 pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
563}
564
Joerg Roedela345b232009-09-03 15:01:43 +0200565static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
Joerg Roedel90008ee2008-09-09 16:41:05 +0200566{
Joerg Roedel3d06fca2012-04-12 14:12:00 +0200567 int type, devid, domid, flags;
568 volatile u32 *event = __evt;
569 int count = 0;
570 u64 address;
571
572retry:
573 type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
574 devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
575 domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
576 flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
577 address = (u64)(((u64)event[3]) << 32) | event[2];
578
579 if (type == 0) {
580 /* Did we hit the erratum? */
581 if (++count == LOOP_TIMEOUT) {
582 pr_err("AMD-Vi: No event written to event log\n");
583 return;
584 }
585 udelay(1);
586 goto retry;
587 }
Joerg Roedel90008ee2008-09-09 16:41:05 +0200588
Joerg Roedel4c6f40d2009-09-01 16:43:58 +0200589 printk(KERN_ERR "AMD-Vi: Event logged [");
Joerg Roedel90008ee2008-09-09 16:41:05 +0200590
591 switch (type) {
592 case EVENT_TYPE_ILL_DEV:
593 printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
594 "address=0x%016llx flags=0x%04x]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700595 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200596 address, flags);
Joerg Roedele3e59872009-09-03 14:02:10 +0200597 dump_dte_entry(devid);
Joerg Roedel90008ee2008-09-09 16:41:05 +0200598 break;
599 case EVENT_TYPE_IO_FAULT:
600 printk("IO_PAGE_FAULT device=%02x:%02x.%x "
601 "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700602 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200603 domid, address, flags);
604 break;
605 case EVENT_TYPE_DEV_TAB_ERR:
606 printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
607 "address=0x%016llx flags=0x%04x]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700608 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200609 address, flags);
610 break;
611 case EVENT_TYPE_PAGE_TAB_ERR:
612 printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
613 "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700614 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200615 domid, address, flags);
616 break;
617 case EVENT_TYPE_ILL_CMD:
618 printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
Joerg Roedel945b4ac2009-09-03 14:25:02 +0200619 dump_command(address);
Joerg Roedel90008ee2008-09-09 16:41:05 +0200620 break;
621 case EVENT_TYPE_CMD_HARD_ERR:
622 printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
623 "flags=0x%04x]\n", address, flags);
624 break;
625 case EVENT_TYPE_IOTLB_INV_TO:
626 printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
627 "address=0x%016llx]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700628 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200629 address);
630 break;
631 case EVENT_TYPE_INV_DEV_REQ:
632 printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
633 "address=0x%016llx flags=0x%04x]\n",
Shuah Khanc5081cd2013-02-27 17:07:19 -0700634 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
Joerg Roedel90008ee2008-09-09 16:41:05 +0200635 address, flags);
636 break;
637 default:
638 printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
639 }
Joerg Roedel3d06fca2012-04-12 14:12:00 +0200640
641 memset(__evt, 0, 4 * sizeof(u32));
Joerg Roedel90008ee2008-09-09 16:41:05 +0200642}
643
644static void iommu_poll_events(struct amd_iommu *iommu)
645{
646 u32 head, tail;
Joerg Roedel90008ee2008-09-09 16:41:05 +0200647
648 head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
649 tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
650
651 while (head != tail) {
Joerg Roedela345b232009-09-03 15:01:43 +0200652 iommu_print_event(iommu, iommu->evt_buf + head);
Joerg Roedeldeba4bc2015-10-20 17:33:41 +0200653 head = (head + EVENT_ENTRY_SIZE) % EVT_BUFFER_SIZE;
Joerg Roedel90008ee2008-09-09 16:41:05 +0200654 }
655
656 writel(head, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
Joerg Roedel90008ee2008-09-09 16:41:05 +0200657}
658
Joerg Roedeleee53532012-06-01 15:20:23 +0200659static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u64 *raw)
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100660{
661 struct amd_iommu_fault fault;
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100662
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100663 if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) {
664 pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n");
665 return;
666 }
667
668 fault.address = raw[1];
669 fault.pasid = PPR_PASID(raw[0]);
670 fault.device_id = PPR_DEVID(raw[0]);
671 fault.tag = PPR_TAG(raw[0]);
672 fault.flags = PPR_FLAGS(raw[0]);
673
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100674 atomic_notifier_call_chain(&ppr_notifier, 0, &fault);
675}
676
677static void iommu_poll_ppr_log(struct amd_iommu *iommu)
678{
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100679 u32 head, tail;
680
681 if (iommu->ppr_log == NULL)
682 return;
683
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100684 head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
685 tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
686
687 while (head != tail) {
Joerg Roedeleee53532012-06-01 15:20:23 +0200688 volatile u64 *raw;
689 u64 entry[2];
690 int i;
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100691
Joerg Roedeleee53532012-06-01 15:20:23 +0200692 raw = (u64 *)(iommu->ppr_log + head);
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100693
Joerg Roedeleee53532012-06-01 15:20:23 +0200694 /*
695 * Hardware bug: Interrupt may arrive before the entry is
696 * written to memory. If this happens we need to wait for the
697 * entry to arrive.
698 */
699 for (i = 0; i < LOOP_TIMEOUT; ++i) {
700 if (PPR_REQ_TYPE(raw[0]) != 0)
701 break;
702 udelay(1);
703 }
704
705 /* Avoid memcpy function-call overhead */
706 entry[0] = raw[0];
707 entry[1] = raw[1];
708
709 /*
710 * To detect the hardware bug we need to clear the entry
711 * back to zero.
712 */
713 raw[0] = raw[1] = 0UL;
714
715 /* Update head pointer of hardware ring-buffer */
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100716 head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE;
717 writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
Joerg Roedeleee53532012-06-01 15:20:23 +0200718
Joerg Roedeleee53532012-06-01 15:20:23 +0200719 /* Handle PPR entry */
720 iommu_handle_ppr_entry(iommu, entry);
721
Joerg Roedeleee53532012-06-01 15:20:23 +0200722 /* Refresh ring-buffer information */
723 head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100724 tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
725 }
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100726}
727
Suravee Suthikulpanitbd6fcef2016-08-23 13:52:37 -0500728#ifdef CONFIG_IRQ_REMAP
729static int (*iommu_ga_log_notifier)(u32);
730
731int amd_iommu_register_ga_log_notifier(int (*notifier)(u32))
732{
733 iommu_ga_log_notifier = notifier;
734
735 return 0;
736}
737EXPORT_SYMBOL(amd_iommu_register_ga_log_notifier);
738
739static void iommu_poll_ga_log(struct amd_iommu *iommu)
740{
741 u32 head, tail, cnt = 0;
742
743 if (iommu->ga_log == NULL)
744 return;
745
746 head = readl(iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
747 tail = readl(iommu->mmio_base + MMIO_GA_TAIL_OFFSET);
748
749 while (head != tail) {
750 volatile u64 *raw;
751 u64 log_entry;
752
753 raw = (u64 *)(iommu->ga_log + head);
754 cnt++;
755
756 /* Avoid memcpy function-call overhead */
757 log_entry = *raw;
758
759 /* Update head pointer of hardware ring-buffer */
760 head = (head + GA_ENTRY_SIZE) % GA_LOG_SIZE;
761 writel(head, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
762
763 /* Handle GA entry */
764 switch (GA_REQ_TYPE(log_entry)) {
765 case GA_GUEST_NR:
766 if (!iommu_ga_log_notifier)
767 break;
768
769 pr_debug("AMD-Vi: %s: devid=%#x, ga_tag=%#x\n",
770 __func__, GA_DEVID(log_entry),
771 GA_TAG(log_entry));
772
773 if (iommu_ga_log_notifier(GA_TAG(log_entry)) != 0)
774 pr_err("AMD-Vi: GA log notifier failed.\n");
775 break;
776 default:
777 break;
778 }
779 }
780}
781#endif /* CONFIG_IRQ_REMAP */
782
783#define AMD_IOMMU_INT_MASK \
784 (MMIO_STATUS_EVT_INT_MASK | \
785 MMIO_STATUS_PPR_INT_MASK | \
786 MMIO_STATUS_GALOG_INT_MASK)
787
Joerg Roedel72fe00f2011-05-10 10:50:42 +0200788irqreturn_t amd_iommu_int_thread(int irq, void *data)
Joerg Roedela80dc3e2008-09-11 16:51:41 +0200789{
Suravee Suthikulpanit3f398bc2013-04-22 16:32:34 -0500790 struct amd_iommu *iommu = (struct amd_iommu *) data;
791 u32 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
Joerg Roedel90008ee2008-09-09 16:41:05 +0200792
Suravee Suthikulpanitbd6fcef2016-08-23 13:52:37 -0500793 while (status & AMD_IOMMU_INT_MASK) {
794 /* Enable EVT and PPR and GA interrupts again */
795 writel(AMD_IOMMU_INT_MASK,
Suravee Suthikulpanit3f398bc2013-04-22 16:32:34 -0500796 iommu->mmio_base + MMIO_STATUS_OFFSET);
797
798 if (status & MMIO_STATUS_EVT_INT_MASK) {
799 pr_devel("AMD-Vi: Processing IOMMU Event Log\n");
800 iommu_poll_events(iommu);
801 }
802
803 if (status & MMIO_STATUS_PPR_INT_MASK) {
804 pr_devel("AMD-Vi: Processing IOMMU PPR Log\n");
805 iommu_poll_ppr_log(iommu);
806 }
807
Suravee Suthikulpanitbd6fcef2016-08-23 13:52:37 -0500808#ifdef CONFIG_IRQ_REMAP
809 if (status & MMIO_STATUS_GALOG_INT_MASK) {
810 pr_devel("AMD-Vi: Processing IOMMU GA Log\n");
811 iommu_poll_ga_log(iommu);
812 }
813#endif
814
Suravee Suthikulpanit3f398bc2013-04-22 16:32:34 -0500815 /*
816 * Hardware bug: ERBT1312
817 * When re-enabling interrupt (by writing 1
818 * to clear the bit), the hardware might also try to set
819 * the interrupt bit in the event status register.
820 * In this scenario, the bit will be set, and disable
821 * subsequent interrupts.
822 *
823 * Workaround: The IOMMU driver should read back the
824 * status register and check if the interrupt bits are cleared.
825 * If not, driver will need to go through the interrupt handler
826 * again and re-clear the bits
827 */
828 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
Joerg Roedel72e1dcc2011-11-10 19:13:51 +0100829 }
Joerg Roedel90008ee2008-09-09 16:41:05 +0200830 return IRQ_HANDLED;
Joerg Roedela80dc3e2008-09-11 16:51:41 +0200831}
832
Joerg Roedel72fe00f2011-05-10 10:50:42 +0200833irqreturn_t amd_iommu_int_handler(int irq, void *data)
834{
835 return IRQ_WAKE_THREAD;
836}
837
Joerg Roedela80dc3e2008-09-11 16:51:41 +0200838/****************************************************************************
839 *
Joerg Roedel431b2a22008-07-11 17:14:22 +0200840 * IOMMU command queuing functions
841 *
842 ****************************************************************************/
843
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200844static int wait_on_sem(volatile u64 *sem)
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200845{
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200846 int i = 0;
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200847
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200848 while (*sem == 0 && i < LOOP_TIMEOUT) {
849 udelay(1);
850 i += 1;
851 }
852
853 if (i == LOOP_TIMEOUT) {
854 pr_alert("AMD-Vi: Completion-Wait loop timed out\n");
855 return -EIO;
856 }
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200857
858 return 0;
859}
860
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200861static void copy_cmd_to_buffer(struct amd_iommu *iommu,
862 struct iommu_cmd *cmd,
863 u32 tail)
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200864{
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200865 u8 *target;
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200866
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200867 target = iommu->cmd_buf + tail;
Joerg Roedeldeba4bc2015-10-20 17:33:41 +0200868 tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;
Joerg Roedela19ae1e2008-06-26 21:27:55 +0200869
Joerg Roedelac0ea6e2011-04-06 18:38:20 +0200870 /* Copy command to buffer */
871 memcpy(target, cmd, sizeof(*cmd));
872
873 /* Tell the IOMMU about it */
874 writel(tail, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
875}
876
Joerg Roedel815b33f2011-04-06 17:26:49 +0200877static void build_completion_wait(struct iommu_cmd *cmd, u64 address)
Joerg Roedelded46732011-04-06 10:53:48 +0200878{
Joerg Roedel815b33f2011-04-06 17:26:49 +0200879 WARN_ON(address & 0x7ULL);
880
Joerg Roedelded46732011-04-06 10:53:48 +0200881 memset(cmd, 0, sizeof(*cmd));
Joerg Roedel815b33f2011-04-06 17:26:49 +0200882 cmd->data[0] = lower_32_bits(__pa(address)) | CMD_COMPL_WAIT_STORE_MASK;
883 cmd->data[1] = upper_32_bits(__pa(address));
884 cmd->data[2] = 1;
Joerg Roedelded46732011-04-06 10:53:48 +0200885 CMD_SET_TYPE(cmd, CMD_COMPL_WAIT);
886}
887
Joerg Roedel94fe79e2011-04-06 11:07:21 +0200888static void build_inv_dte(struct iommu_cmd *cmd, u16 devid)
889{
890 memset(cmd, 0, sizeof(*cmd));
891 cmd->data[0] = devid;
892 CMD_SET_TYPE(cmd, CMD_INV_DEV_ENTRY);
893}
894
Joerg Roedel11b64022011-04-06 11:49:28 +0200895static void build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
896 size_t size, u16 domid, int pde)
897{
898 u64 pages;
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100899 bool s;
Joerg Roedel11b64022011-04-06 11:49:28 +0200900
901 pages = iommu_num_pages(address, size, PAGE_SIZE);
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100902 s = false;
Joerg Roedel11b64022011-04-06 11:49:28 +0200903
904 if (pages > 1) {
905 /*
906 * If we have to flush more than one page, flush all
907 * TLB entries for this domain
908 */
909 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100910 s = true;
Joerg Roedel11b64022011-04-06 11:49:28 +0200911 }
912
913 address &= PAGE_MASK;
914
915 memset(cmd, 0, sizeof(*cmd));
916 cmd->data[1] |= domid;
917 cmd->data[2] = lower_32_bits(address);
918 cmd->data[3] = upper_32_bits(address);
919 CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
920 if (s) /* size bit - we flush more than one 4kb page */
921 cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
Frank Arnolddf805ab2012-08-27 19:21:04 +0200922 if (pde) /* PDE bit - we want to flush everything, not only the PTEs */
Joerg Roedel11b64022011-04-06 11:49:28 +0200923 cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
924}
925
Joerg Roedelcb41ed82011-04-05 11:00:53 +0200926static void build_inv_iotlb_pages(struct iommu_cmd *cmd, u16 devid, int qdep,
927 u64 address, size_t size)
928{
929 u64 pages;
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100930 bool s;
Joerg Roedelcb41ed82011-04-05 11:00:53 +0200931
932 pages = iommu_num_pages(address, size, PAGE_SIZE);
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100933 s = false;
Joerg Roedelcb41ed82011-04-05 11:00:53 +0200934
935 if (pages > 1) {
936 /*
937 * If we have to flush more than one page, flush all
938 * TLB entries for this domain
939 */
940 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
Quentin Lambertae0cbbb2015-02-04 11:40:07 +0100941 s = true;
Joerg Roedelcb41ed82011-04-05 11:00:53 +0200942 }
943
944 address &= PAGE_MASK;
945
946 memset(cmd, 0, sizeof(*cmd));
947 cmd->data[0] = devid;
948 cmd->data[0] |= (qdep & 0xff) << 24;
949 cmd->data[1] = devid;
950 cmd->data[2] = lower_32_bits(address);
951 cmd->data[3] = upper_32_bits(address);
952 CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);
953 if (s)
954 cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
955}
956
Joerg Roedel22e266c2011-11-21 15:59:08 +0100957static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,
958 u64 address, bool size)
959{
960 memset(cmd, 0, sizeof(*cmd));
961
962 address &= ~(0xfffULL);
963
Suravee Suthikulpanita919a012014-03-05 18:54:18 -0600964 cmd->data[0] = pasid;
Joerg Roedel22e266c2011-11-21 15:59:08 +0100965 cmd->data[1] = domid;
966 cmd->data[2] = lower_32_bits(address);
967 cmd->data[3] = upper_32_bits(address);
968 cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
969 cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
970 if (size)
971 cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
972 CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
973}
974
975static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid,
976 int qdep, u64 address, bool size)
977{
978 memset(cmd, 0, sizeof(*cmd));
979
980 address &= ~(0xfffULL);
981
982 cmd->data[0] = devid;
Jay Cornwalle8d2d822014-02-26 15:49:31 -0600983 cmd->data[0] |= ((pasid >> 8) & 0xff) << 16;
Joerg Roedel22e266c2011-11-21 15:59:08 +0100984 cmd->data[0] |= (qdep & 0xff) << 24;
985 cmd->data[1] = devid;
Jay Cornwalle8d2d822014-02-26 15:49:31 -0600986 cmd->data[1] |= (pasid & 0xff) << 16;
Joerg Roedel22e266c2011-11-21 15:59:08 +0100987 cmd->data[2] = lower_32_bits(address);
988 cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;
989 cmd->data[3] = upper_32_bits(address);
990 if (size)
991 cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
992 CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);
993}
994
Joerg Roedelc99afa22011-11-21 18:19:25 +0100995static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid,
996 int status, int tag, bool gn)
997{
998 memset(cmd, 0, sizeof(*cmd));
999
1000 cmd->data[0] = devid;
1001 if (gn) {
Suravee Suthikulpanita919a012014-03-05 18:54:18 -06001002 cmd->data[1] = pasid;
Joerg Roedelc99afa22011-11-21 18:19:25 +01001003 cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK;
1004 }
1005 cmd->data[3] = tag & 0x1ff;
1006 cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT;
1007
1008 CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR);
1009}
1010
Joerg Roedel58fc7f12011-04-11 11:13:24 +02001011static void build_inv_all(struct iommu_cmd *cmd)
1012{
1013 memset(cmd, 0, sizeof(*cmd));
1014 CMD_SET_TYPE(cmd, CMD_INV_ALL);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001015}
1016
Joerg Roedel7ef27982012-06-21 16:46:04 +02001017static void build_inv_irt(struct iommu_cmd *cmd, u16 devid)
1018{
1019 memset(cmd, 0, sizeof(*cmd));
1020 cmd->data[0] = devid;
1021 CMD_SET_TYPE(cmd, CMD_INV_IRT);
1022}
1023
Joerg Roedel431b2a22008-07-11 17:14:22 +02001024/*
Joerg Roedelb6c02712008-06-26 21:27:53 +02001025 * Writes the command to the IOMMUs command buffer and informs the
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001026 * hardware about the new command.
Joerg Roedel431b2a22008-07-11 17:14:22 +02001027 */
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001028static int __iommu_queue_command_sync(struct amd_iommu *iommu,
1029 struct iommu_cmd *cmd,
1030 bool sync)
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001031{
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001032 u32 left, tail, head, next_tail;
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001033
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001034again:
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001035
1036 head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
1037 tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
Joerg Roedeldeba4bc2015-10-20 17:33:41 +02001038 next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;
1039 left = (head - next_tail) % CMD_BUFFER_SIZE;
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001040
Huang Rui21488352016-12-12 07:28:26 -05001041 if (left <= 0x20) {
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001042 struct iommu_cmd sync_cmd;
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001043 int ret;
1044
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001045 iommu->cmd_sem = 0;
1046
1047 build_completion_wait(&sync_cmd, (u64)&iommu->cmd_sem);
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001048 copy_cmd_to_buffer(iommu, &sync_cmd, tail);
1049
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001050 if ((ret = wait_on_sem(&iommu->cmd_sem)) != 0)
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001051 return ret;
1052
1053 goto again;
Joerg Roedel136f78a2008-07-11 17:14:27 +02001054 }
1055
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001056 copy_cmd_to_buffer(iommu, cmd, tail);
Joerg Roedel519c31b2008-08-14 19:55:15 +02001057
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001058 /* We need to sync now to make sure all commands are processed */
Joerg Roedelf1ca1512011-09-02 14:10:32 +02001059 iommu->need_sync = sync;
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001060
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001061 return 0;
1062}
1063
1064static int iommu_queue_command_sync(struct amd_iommu *iommu,
1065 struct iommu_cmd *cmd,
1066 bool sync)
1067{
1068 unsigned long flags;
1069 int ret;
1070
1071 spin_lock_irqsave(&iommu->lock, flags);
1072 ret = __iommu_queue_command_sync(iommu, cmd, sync);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001073 spin_unlock_irqrestore(&iommu->lock, flags);
1074
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001075 return ret;
Joerg Roedel8d201962008-12-02 20:34:41 +01001076}
1077
Joerg Roedelf1ca1512011-09-02 14:10:32 +02001078static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
1079{
1080 return iommu_queue_command_sync(iommu, cmd, true);
1081}
1082
Joerg Roedel8d201962008-12-02 20:34:41 +01001083/*
1084 * This function queues a completion wait command into the command
1085 * buffer of an IOMMU
1086 */
Joerg Roedel8d201962008-12-02 20:34:41 +01001087static int iommu_completion_wait(struct amd_iommu *iommu)
1088{
Joerg Roedel815b33f2011-04-06 17:26:49 +02001089 struct iommu_cmd cmd;
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001090 unsigned long flags;
Joerg Roedelac0ea6e2011-04-06 18:38:20 +02001091 int ret;
Joerg Roedel8d201962008-12-02 20:34:41 +01001092
1093 if (!iommu->need_sync)
Joerg Roedel815b33f2011-04-06 17:26:49 +02001094 return 0;
Joerg Roedel8d201962008-12-02 20:34:41 +01001095
Joerg Roedel8d201962008-12-02 20:34:41 +01001096
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001097 build_completion_wait(&cmd, (u64)&iommu->cmd_sem);
1098
1099 spin_lock_irqsave(&iommu->lock, flags);
1100
1101 iommu->cmd_sem = 0;
1102
1103 ret = __iommu_queue_command_sync(iommu, &cmd, false);
Joerg Roedel8d201962008-12-02 20:34:41 +01001104 if (ret)
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001105 goto out_unlock;
Joerg Roedel8d201962008-12-02 20:34:41 +01001106
Joerg Roedel4bf5bee2016-09-14 11:41:59 +02001107 ret = wait_on_sem(&iommu->cmd_sem);
1108
1109out_unlock:
1110 spin_unlock_irqrestore(&iommu->lock, flags);
1111
1112 return ret;
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001113}
1114
Joerg Roedeld8c13082011-04-06 18:51:26 +02001115static int iommu_flush_dte(struct amd_iommu *iommu, u16 devid)
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001116{
1117 struct iommu_cmd cmd;
1118
Joerg Roedeld8c13082011-04-06 18:51:26 +02001119 build_inv_dte(&cmd, devid);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001120
Joerg Roedeld8c13082011-04-06 18:51:26 +02001121 return iommu_queue_command(iommu, &cmd);
1122}
1123
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001124static void iommu_flush_dte_all(struct amd_iommu *iommu)
1125{
1126 u32 devid;
1127
1128 for (devid = 0; devid <= 0xffff; ++devid)
1129 iommu_flush_dte(iommu, devid);
1130
1131 iommu_completion_wait(iommu);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001132}
1133
1134/*
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001135 * This function uses heavy locking and may disable irqs for some time. But
1136 * this is no issue because it is only called during resume.
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001137 */
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001138static void iommu_flush_tlb_all(struct amd_iommu *iommu)
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001139{
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001140 u32 dom_id;
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001141
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001142 for (dom_id = 0; dom_id <= 0xffff; ++dom_id) {
1143 struct iommu_cmd cmd;
1144 build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
1145 dom_id, 1);
1146 iommu_queue_command(iommu, &cmd);
1147 }
Joerg Roedel431b2a22008-07-11 17:14:22 +02001148
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001149 iommu_completion_wait(iommu);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001150}
1151
Joerg Roedel58fc7f12011-04-11 11:13:24 +02001152static void iommu_flush_all(struct amd_iommu *iommu)
1153{
1154 struct iommu_cmd cmd;
1155
1156 build_inv_all(&cmd);
1157
1158 iommu_queue_command(iommu, &cmd);
1159 iommu_completion_wait(iommu);
1160}
1161
Joerg Roedel7ef27982012-06-21 16:46:04 +02001162static void iommu_flush_irt(struct amd_iommu *iommu, u16 devid)
1163{
1164 struct iommu_cmd cmd;
1165
1166 build_inv_irt(&cmd, devid);
1167
1168 iommu_queue_command(iommu, &cmd);
1169}
1170
1171static void iommu_flush_irt_all(struct amd_iommu *iommu)
1172{
1173 u32 devid;
1174
1175 for (devid = 0; devid <= MAX_DEV_TABLE_ENTRIES; devid++)
1176 iommu_flush_irt(iommu, devid);
1177
1178 iommu_completion_wait(iommu);
1179}
1180
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001181void iommu_flush_all_caches(struct amd_iommu *iommu)
1182{
Joerg Roedel58fc7f12011-04-11 11:13:24 +02001183 if (iommu_feature(iommu, FEATURE_IA)) {
1184 iommu_flush_all(iommu);
1185 } else {
1186 iommu_flush_dte_all(iommu);
Joerg Roedel7ef27982012-06-21 16:46:04 +02001187 iommu_flush_irt_all(iommu);
Joerg Roedel58fc7f12011-04-11 11:13:24 +02001188 iommu_flush_tlb_all(iommu);
1189 }
Joerg Roedel7d0c5cc2011-04-07 08:16:10 +02001190}
1191
Joerg Roedel431b2a22008-07-11 17:14:22 +02001192/*
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001193 * Command send function for flushing on-device TLB
1194 */
Joerg Roedel6c542042011-06-09 17:07:31 +02001195static int device_flush_iotlb(struct iommu_dev_data *dev_data,
1196 u64 address, size_t size)
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001197{
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001198 struct amd_iommu *iommu;
1199 struct iommu_cmd cmd;
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001200 int qdep;
1201
Joerg Roedelea61cdd2011-06-09 12:56:30 +02001202 qdep = dev_data->ats.qdep;
1203 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001204
Joerg Roedelea61cdd2011-06-09 12:56:30 +02001205 build_inv_iotlb_pages(&cmd, dev_data->devid, qdep, address, size);
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001206
1207 return iommu_queue_command(iommu, &cmd);
1208}
1209
1210/*
Joerg Roedel431b2a22008-07-11 17:14:22 +02001211 * Command send function for invalidating a device table entry
1212 */
Joerg Roedel6c542042011-06-09 17:07:31 +02001213static int device_flush_dte(struct iommu_dev_data *dev_data)
Joerg Roedel3fa43652009-11-26 15:04:38 +01001214{
1215 struct amd_iommu *iommu;
Joerg Roedele25bfb52015-10-20 17:33:38 +02001216 u16 alias;
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001217 int ret;
Joerg Roedel3fa43652009-11-26 15:04:38 +01001218
Joerg Roedel6c542042011-06-09 17:07:31 +02001219 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedele3156042016-04-08 15:12:24 +02001220 alias = dev_data->alias;
Joerg Roedel3fa43652009-11-26 15:04:38 +01001221
Joerg Roedelf62dda62011-06-09 12:55:35 +02001222 ret = iommu_flush_dte(iommu, dev_data->devid);
Joerg Roedele25bfb52015-10-20 17:33:38 +02001223 if (!ret && alias != dev_data->devid)
1224 ret = iommu_flush_dte(iommu, alias);
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001225 if (ret)
1226 return ret;
1227
Joerg Roedelea61cdd2011-06-09 12:56:30 +02001228 if (dev_data->ats.enabled)
Joerg Roedel6c542042011-06-09 17:07:31 +02001229 ret = device_flush_iotlb(dev_data, 0, ~0UL);
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001230
1231 return ret;
Joerg Roedel3fa43652009-11-26 15:04:38 +01001232}
1233
Joerg Roedel431b2a22008-07-11 17:14:22 +02001234/*
1235 * TLB invalidation function which is called from the mapping functions.
1236 * It invalidates a single PTE if the range to flush is within a single
1237 * page. Otherwise it flushes the whole TLB of the IOMMU.
1238 */
Joerg Roedel17b124b2011-04-06 18:01:35 +02001239static void __domain_flush_pages(struct protection_domain *domain,
1240 u64 address, size_t size, int pde)
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001241{
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001242 struct iommu_dev_data *dev_data;
Joerg Roedel11b64022011-04-06 11:49:28 +02001243 struct iommu_cmd cmd;
1244 int ret = 0, i;
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001245
Joerg Roedel11b64022011-04-06 11:49:28 +02001246 build_inv_iommu_pages(&cmd, address, size, domain->id, pde);
Joerg Roedel999ba412008-07-03 19:35:08 +02001247
Joerg Roedel6de8ad92009-11-23 18:30:32 +01001248 for (i = 0; i < amd_iommus_present; ++i) {
1249 if (!domain->dev_iommu[i])
1250 continue;
1251
1252 /*
1253 * Devices of this domain are behind this IOMMU
1254 * We need a TLB flush
1255 */
Joerg Roedel11b64022011-04-06 11:49:28 +02001256 ret |= iommu_queue_command(amd_iommus[i], &cmd);
Joerg Roedel6de8ad92009-11-23 18:30:32 +01001257 }
1258
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001259 list_for_each_entry(dev_data, &domain->dev_list, list) {
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001260
Joerg Roedelea61cdd2011-06-09 12:56:30 +02001261 if (!dev_data->ats.enabled)
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001262 continue;
1263
Joerg Roedel6c542042011-06-09 17:07:31 +02001264 ret |= device_flush_iotlb(dev_data, address, size);
Joerg Roedelcb41ed82011-04-05 11:00:53 +02001265 }
1266
Joerg Roedel11b64022011-04-06 11:49:28 +02001267 WARN_ON(ret);
Joerg Roedel6de8ad92009-11-23 18:30:32 +01001268}
1269
Joerg Roedel17b124b2011-04-06 18:01:35 +02001270static void domain_flush_pages(struct protection_domain *domain,
1271 u64 address, size_t size)
Joerg Roedel6de8ad92009-11-23 18:30:32 +01001272{
Joerg Roedel17b124b2011-04-06 18:01:35 +02001273 __domain_flush_pages(domain, address, size, 0);
Joerg Roedela19ae1e2008-06-26 21:27:55 +02001274}
Joerg Roedelb6c02712008-06-26 21:27:53 +02001275
Joerg Roedel1c655772008-09-04 18:40:05 +02001276/* Flush the whole IO/TLB for a given protection domain */
Joerg Roedel17b124b2011-04-06 18:01:35 +02001277static void domain_flush_tlb(struct protection_domain *domain)
Joerg Roedel1c655772008-09-04 18:40:05 +02001278{
Joerg Roedel17b124b2011-04-06 18:01:35 +02001279 __domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
Joerg Roedel1c655772008-09-04 18:40:05 +02001280}
1281
Chris Wright42a49f92009-06-15 15:42:00 +02001282/* Flush the whole IO/TLB for a given protection domain - including PDE */
Joerg Roedel17b124b2011-04-06 18:01:35 +02001283static void domain_flush_tlb_pde(struct protection_domain *domain)
Chris Wright42a49f92009-06-15 15:42:00 +02001284{
Joerg Roedel17b124b2011-04-06 18:01:35 +02001285 __domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
1286}
1287
1288static void domain_flush_complete(struct protection_domain *domain)
Joerg Roedelb6c02712008-06-26 21:27:53 +02001289{
1290 int i;
1291
1292 for (i = 0; i < amd_iommus_present; ++i) {
Joerg Roedelf1eae7c2016-07-06 12:50:35 +02001293 if (domain && !domain->dev_iommu[i])
Joerg Roedelb6c02712008-06-26 21:27:53 +02001294 continue;
1295
1296 /*
1297 * Devices of this domain are behind this IOMMU
1298 * We need to wait for completion of all commands.
1299 */
1300 iommu_completion_wait(amd_iommus[i]);
1301 }
1302}
1303
Joerg Roedelb00d3bc2009-11-26 15:35:33 +01001304
Joerg Roedel43f49602008-12-02 21:01:12 +01001305/*
Joerg Roedelb00d3bc2009-11-26 15:35:33 +01001306 * This function flushes the DTEs for all devices in domain
Joerg Roedel43f49602008-12-02 21:01:12 +01001307 */
Joerg Roedel17b124b2011-04-06 18:01:35 +02001308static void domain_flush_devices(struct protection_domain *domain)
Joerg Roedelbfd1be12009-05-05 15:33:57 +02001309{
Joerg Roedelb00d3bc2009-11-26 15:35:33 +01001310 struct iommu_dev_data *dev_data;
Joerg Roedelb00d3bc2009-11-26 15:35:33 +01001311
1312 list_for_each_entry(dev_data, &domain->dev_list, list)
Joerg Roedel6c542042011-06-09 17:07:31 +02001313 device_flush_dte(dev_data);
Joerg Roedelb00d3bc2009-11-26 15:35:33 +01001314}
1315
Joerg Roedel431b2a22008-07-11 17:14:22 +02001316/****************************************************************************
1317 *
1318 * The functions below are used the create the page table mappings for
1319 * unity mapped regions.
1320 *
1321 ****************************************************************************/
1322
1323/*
Joerg Roedel308973d2009-11-24 17:43:32 +01001324 * This function is used to add another level to an IO page table. Adding
1325 * another level increases the size of the address space by 9 bits to a size up
1326 * to 64 bits.
1327 */
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001328static void increase_address_space(struct protection_domain *domain,
Joerg Roedel308973d2009-11-24 17:43:32 +01001329 gfp_t gfp)
1330{
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001331 unsigned long flags;
Joerg Roedel308973d2009-11-24 17:43:32 +01001332 u64 *pte;
1333
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001334 spin_lock_irqsave(&domain->lock, flags);
1335
1336 if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL))
Joerg Roedel308973d2009-11-24 17:43:32 +01001337 /* address space already 64 bit large */
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001338 goto out;
Joerg Roedel308973d2009-11-24 17:43:32 +01001339
1340 pte = (void *)get_zeroed_page(gfp);
1341 if (!pte)
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001342 goto out;
Joerg Roedel308973d2009-11-24 17:43:32 +01001343
1344 *pte = PM_LEVEL_PDE(domain->mode,
1345 virt_to_phys(domain->pt_root));
1346 domain->pt_root = pte;
1347 domain->mode += 1;
1348 domain->updated = true;
1349
Joerg Roedel6fb92f12019-09-06 10:39:54 +02001350out:
1351 spin_unlock_irqrestore(&domain->lock, flags);
1352
1353 return;
Joerg Roedel308973d2009-11-24 17:43:32 +01001354}
1355
1356static u64 *alloc_pte(struct protection_domain *domain,
1357 unsigned long address,
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001358 unsigned long page_size,
Joerg Roedel308973d2009-11-24 17:43:32 +01001359 u64 **pte_page,
1360 gfp_t gfp)
1361{
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001362 int level, end_lvl;
Joerg Roedel308973d2009-11-24 17:43:32 +01001363 u64 *pte, *page;
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001364
1365 BUG_ON(!is_power_of_2(page_size));
Joerg Roedel308973d2009-11-24 17:43:32 +01001366
1367 while (address > PM_LEVEL_SIZE(domain->mode))
1368 increase_address_space(domain, gfp);
1369
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001370 level = domain->mode - 1;
1371 pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
1372 address = PAGE_SIZE_ALIGN(address, page_size);
1373 end_lvl = PAGE_SIZE_LEVEL(page_size);
Joerg Roedel308973d2009-11-24 17:43:32 +01001374
1375 while (level > end_lvl) {
Joerg Roedel7bfa5bd2015-12-21 19:07:50 +01001376 u64 __pte, __npte;
1377
1378 __pte = *pte;
1379
1380 if (!IOMMU_PTE_PRESENT(__pte)) {
Joerg Roedel308973d2009-11-24 17:43:32 +01001381 page = (u64 *)get_zeroed_page(gfp);
1382 if (!page)
1383 return NULL;
Joerg Roedel7bfa5bd2015-12-21 19:07:50 +01001384
1385 __npte = PM_LEVEL_PDE(level, virt_to_phys(page));
1386
Baoquan He134414f2016-09-15 16:50:50 +08001387 /* pte could have been changed somewhere. */
1388 if (cmpxchg64(pte, __pte, __npte) != __pte) {
Joerg Roedel7bfa5bd2015-12-21 19:07:50 +01001389 free_page((unsigned long)page);
1390 continue;
1391 }
Joerg Roedel308973d2009-11-24 17:43:32 +01001392 }
1393
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001394 /* No level skipping support yet */
1395 if (PM_PTE_LEVEL(*pte) != level)
1396 return NULL;
1397
Joerg Roedel308973d2009-11-24 17:43:32 +01001398 level -= 1;
1399
1400 pte = IOMMU_PTE_PAGE(*pte);
1401
1402 if (pte_page && level == end_lvl)
1403 *pte_page = pte;
1404
1405 pte = &pte[PM_LEVEL_INDEX(level, address)];
1406 }
1407
1408 return pte;
1409}
1410
1411/*
1412 * This function checks if there is a PTE for a given dma address. If
1413 * there is one, it returns the pointer to it.
1414 */
Joerg Roedel3039ca12015-04-01 14:58:48 +02001415static u64 *fetch_pte(struct protection_domain *domain,
1416 unsigned long address,
1417 unsigned long *page_size)
Joerg Roedel308973d2009-11-24 17:43:32 +01001418{
1419 int level;
1420 u64 *pte;
1421
Joerg Roedel24cd7722010-01-19 17:27:39 +01001422 if (address > PM_LEVEL_SIZE(domain->mode))
1423 return NULL;
Joerg Roedel308973d2009-11-24 17:43:32 +01001424
Joerg Roedel3039ca12015-04-01 14:58:48 +02001425 level = domain->mode - 1;
1426 pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
1427 *page_size = PTE_LEVEL_PAGE_SIZE(level);
Joerg Roedel24cd7722010-01-19 17:27:39 +01001428
1429 while (level > 0) {
1430
1431 /* Not Present */
Joerg Roedel308973d2009-11-24 17:43:32 +01001432 if (!IOMMU_PTE_PRESENT(*pte))
1433 return NULL;
1434
Joerg Roedel24cd7722010-01-19 17:27:39 +01001435 /* Large PTE */
Joerg Roedel3039ca12015-04-01 14:58:48 +02001436 if (PM_PTE_LEVEL(*pte) == 7 ||
1437 PM_PTE_LEVEL(*pte) == 0)
1438 break;
Joerg Roedel24cd7722010-01-19 17:27:39 +01001439
1440 /* No level skipping support yet */
1441 if (PM_PTE_LEVEL(*pte) != level)
1442 return NULL;
1443
Joerg Roedel308973d2009-11-24 17:43:32 +01001444 level -= 1;
1445
Joerg Roedel24cd7722010-01-19 17:27:39 +01001446 /* Walk to the next level */
Joerg Roedel3039ca12015-04-01 14:58:48 +02001447 pte = IOMMU_PTE_PAGE(*pte);
1448 pte = &pte[PM_LEVEL_INDEX(level, address)];
1449 *page_size = PTE_LEVEL_PAGE_SIZE(level);
1450 }
1451
1452 if (PM_PTE_LEVEL(*pte) == 0x07) {
1453 unsigned long pte_mask;
1454
1455 /*
1456 * If we have a series of large PTEs, make
1457 * sure to return a pointer to the first one.
1458 */
1459 *page_size = pte_mask = PTE_PAGE_SIZE(*pte);
1460 pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
1461 pte = (u64 *)(((unsigned long)pte) & pte_mask);
Joerg Roedel308973d2009-11-24 17:43:32 +01001462 }
1463
1464 return pte;
1465}
1466
1467/*
Joerg Roedel431b2a22008-07-11 17:14:22 +02001468 * Generic mapping functions. It maps a physical address into a DMA
1469 * address space. It allocates the page table pages if necessary.
1470 * In the future it can be extended to a generic mapping function
1471 * supporting all features of AMD IOMMU page tables like level skipping
1472 * and full 64 bit address spaces.
1473 */
Joerg Roedel38e817f2008-12-02 17:27:52 +01001474static int iommu_map_page(struct protection_domain *dom,
1475 unsigned long bus_addr,
1476 unsigned long phys_addr,
Joerg Roedelb911b892016-07-05 14:29:11 +02001477 unsigned long page_size,
Joerg Roedelabdc5eb2009-09-03 11:33:51 +02001478 int prot,
Joerg Roedelb911b892016-07-05 14:29:11 +02001479 gfp_t gfp)
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001480{
Joerg Roedel8bda3092009-05-12 12:02:46 +02001481 u64 __pte, *pte;
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001482 int i, count;
Joerg Roedelabdc5eb2009-09-03 11:33:51 +02001483
Joerg Roedeld4b03662015-04-01 14:58:52 +02001484 BUG_ON(!IS_ALIGNED(bus_addr, page_size));
1485 BUG_ON(!IS_ALIGNED(phys_addr, page_size));
1486
Joerg Roedelbad1cac2009-09-02 16:52:23 +02001487 if (!(prot & IOMMU_PROT_MASK))
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001488 return -EINVAL;
1489
Joerg Roedeld4b03662015-04-01 14:58:52 +02001490 count = PAGE_SIZE_PTE_COUNT(page_size);
Joerg Roedelb911b892016-07-05 14:29:11 +02001491 pte = alloc_pte(dom, bus_addr, page_size, NULL, gfp);
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001492
Maurizio Lombardi63eaa752014-09-11 12:28:03 +02001493 if (!pte)
1494 return -ENOMEM;
1495
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001496 for (i = 0; i < count; ++i)
1497 if (IOMMU_PTE_PRESENT(pte[i]))
1498 return -EBUSY;
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001499
Joerg Roedeld4b03662015-04-01 14:58:52 +02001500 if (count > 1) {
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001501 __pte = PAGE_SIZE_PTE(phys_addr, page_size);
1502 __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
1503 } else
1504 __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC;
1505
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001506 if (prot & IOMMU_PROT_IR)
1507 __pte |= IOMMU_PTE_IR;
1508 if (prot & IOMMU_PROT_IW)
1509 __pte |= IOMMU_PTE_IW;
1510
Joerg Roedelcbb9d722010-01-15 14:41:15 +01001511 for (i = 0; i < count; ++i)
1512 pte[i] = __pte;
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001513
Joerg Roedel04bfdd82009-09-02 16:00:23 +02001514 update_domain(dom);
1515
Joerg Roedelbd0e5212008-06-26 21:27:56 +02001516 return 0;
1517}
1518
Joerg Roedel24cd7722010-01-19 17:27:39 +01001519static unsigned long iommu_unmap_page(struct protection_domain *dom,
1520 unsigned long bus_addr,
1521 unsigned long page_size)
Joerg Roedeleb74ff62008-12-02 19:59:10 +01001522{
Joerg Roedel71b390e2015-04-01 14:58:49 +02001523 unsigned long long unmapped;
1524 unsigned long unmap_size;
Joerg Roedel24cd7722010-01-19 17:27:39 +01001525 u64 *pte;
Joerg Roedeleb74ff62008-12-02 19:59:10 +01001526
Joerg Roedel24cd7722010-01-19 17:27:39 +01001527 BUG_ON(!is_power_of_2(page_size));
1528
1529 unmapped = 0;
1530
1531 while (unmapped < page_size) {
1532
Joerg Roedel71b390e2015-04-01 14:58:49 +02001533 pte = fetch_pte(dom, bus_addr, &unmap_size);
Joerg Roedel24cd7722010-01-19 17:27:39 +01001534
Joerg Roedel71b390e2015-04-01 14:58:49 +02001535 if (pte) {
1536 int i, count;
Joerg Roedel24cd7722010-01-19 17:27:39 +01001537
Joerg Roedel71b390e2015-04-01 14:58:49 +02001538 count = PAGE_SIZE_PTE_COUNT(unmap_size);
Joerg Roedel24cd7722010-01-19 17:27:39 +01001539 for (i = 0; i < count; i++)
1540 pte[i] = 0ULL;
1541 }
1542
1543 bus_addr = (bus_addr & ~(unmap_size - 1)) + unmap_size;
1544 unmapped += unmap_size;
1545 }
1546
Alex Williamson60d0ca32013-06-21 14:33:19 -06001547 BUG_ON(unmapped && !is_power_of_2(unmapped));
Joerg Roedel24cd7722010-01-19 17:27:39 +01001548
1549 return unmapped;
Joerg Roedeleb74ff62008-12-02 19:59:10 +01001550}
Joerg Roedeleb74ff62008-12-02 19:59:10 +01001551
Joerg Roedel431b2a22008-07-11 17:14:22 +02001552/****************************************************************************
1553 *
1554 * The next functions belong to the address allocator for the dma_ops
Joerg Roedel2d4c5152016-07-05 16:21:32 +02001555 * interface functions.
Joerg Roedel431b2a22008-07-11 17:14:22 +02001556 *
1557 ****************************************************************************/
Joerg Roedeld3086442008-06-26 21:27:57 +02001558
Joerg Roedel9cabe892009-05-18 16:38:55 +02001559
Joerg Roedel256e4622016-07-05 14:23:01 +02001560static unsigned long dma_ops_alloc_iova(struct device *dev,
1561 struct dma_ops_domain *dma_dom,
1562 unsigned int pages, u64 dma_mask)
Joerg Roedela0f51442015-12-21 16:20:09 +01001563{
Joerg Roedel256e4622016-07-05 14:23:01 +02001564 unsigned long pfn = 0;
Joerg Roedela0f51442015-12-21 16:20:09 +01001565
Joerg Roedel256e4622016-07-05 14:23:01 +02001566 pages = __roundup_pow_of_two(pages);
Joerg Roedela0f51442015-12-21 16:20:09 +01001567
Joerg Roedel256e4622016-07-05 14:23:01 +02001568 if (dma_mask > DMA_BIT_MASK(32))
1569 pfn = alloc_iova_fast(&dma_dom->iovad, pages,
1570 IOVA_PFN(DMA_BIT_MASK(32)));
Joerg Roedel7b5e25b2015-12-22 13:38:12 +01001571
Joerg Roedel256e4622016-07-05 14:23:01 +02001572 if (!pfn)
1573 pfn = alloc_iova_fast(&dma_dom->iovad, pages, IOVA_PFN(dma_mask));
Joerg Roedel60e6a7c2015-12-21 16:53:17 +01001574
Joerg Roedel256e4622016-07-05 14:23:01 +02001575 return (pfn << PAGE_SHIFT);
Joerg Roedela0f51442015-12-21 16:20:09 +01001576}
1577
Joerg Roedel256e4622016-07-05 14:23:01 +02001578static void dma_ops_free_iova(struct dma_ops_domain *dma_dom,
1579 unsigned long address,
1580 unsigned int pages)
Joerg Roedel384de722009-05-15 12:30:05 +02001581{
Joerg Roedel256e4622016-07-05 14:23:01 +02001582 pages = __roundup_pow_of_two(pages);
1583 address >>= PAGE_SHIFT;
Joerg Roedel5f6bed52015-12-22 13:34:22 +01001584
Joerg Roedel256e4622016-07-05 14:23:01 +02001585 free_iova_fast(&dma_dom->iovad, address, pages);
Joerg Roedeld3086442008-06-26 21:27:57 +02001586}
1587
Joerg Roedel431b2a22008-07-11 17:14:22 +02001588/****************************************************************************
1589 *
1590 * The next functions belong to the domain allocation. A domain is
1591 * allocated for every IOMMU as the default domain. If device isolation
1592 * is enabled, every device get its own domain. The most important thing
1593 * about domains is the page table mapping the DMA address space they
1594 * contain.
1595 *
1596 ****************************************************************************/
1597
Joerg Roedelaeb26f52009-11-20 16:44:01 +01001598/*
1599 * This function adds a protection domain to the global protection domain list
1600 */
1601static void add_domain_to_list(struct protection_domain *domain)
1602{
1603 unsigned long flags;
1604
1605 spin_lock_irqsave(&amd_iommu_pd_lock, flags);
1606 list_add(&domain->list, &amd_iommu_pd_list);
1607 spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
1608}
1609
1610/*
1611 * This function removes a protection domain to the global
1612 * protection domain list
1613 */
1614static void del_domain_from_list(struct protection_domain *domain)
1615{
1616 unsigned long flags;
1617
1618 spin_lock_irqsave(&amd_iommu_pd_lock, flags);
1619 list_del(&domain->list);
1620 spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
1621}
1622
Joerg Roedelec487d12008-06-26 21:27:58 +02001623static u16 domain_id_alloc(void)
1624{
1625 unsigned long flags;
1626 int id;
1627
1628 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1629 id = find_first_zero_bit(amd_iommu_pd_alloc_bitmap, MAX_DOMAIN_ID);
1630 BUG_ON(id == 0);
1631 if (id > 0 && id < MAX_DOMAIN_ID)
1632 __set_bit(id, amd_iommu_pd_alloc_bitmap);
1633 else
1634 id = 0;
1635 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1636
1637 return id;
1638}
1639
Joerg Roedela2acfb72008-12-02 18:28:53 +01001640static void domain_id_free(int id)
1641{
1642 unsigned long flags;
1643
1644 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
1645 if (id > 0 && id < MAX_DOMAIN_ID)
1646 __clear_bit(id, amd_iommu_pd_alloc_bitmap);
1647 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
1648}
Joerg Roedela2acfb72008-12-02 18:28:53 +01001649
Joerg Roedel5c34c402013-06-20 20:22:58 +02001650#define DEFINE_FREE_PT_FN(LVL, FN) \
1651static void free_pt_##LVL (unsigned long __pt) \
1652{ \
1653 unsigned long p; \
1654 u64 *pt; \
1655 int i; \
1656 \
1657 pt = (u64 *)__pt; \
1658 \
1659 for (i = 0; i < 512; ++i) { \
Joerg Roedel0b3fff52015-06-18 10:48:34 +02001660 /* PTE present? */ \
Joerg Roedel5c34c402013-06-20 20:22:58 +02001661 if (!IOMMU_PTE_PRESENT(pt[i])) \
1662 continue; \
1663 \
Joerg Roedel0b3fff52015-06-18 10:48:34 +02001664 /* Large PTE? */ \
1665 if (PM_PTE_LEVEL(pt[i]) == 0 || \
1666 PM_PTE_LEVEL(pt[i]) == 7) \
1667 continue; \
1668 \
Joerg Roedel5c34c402013-06-20 20:22:58 +02001669 p = (unsigned long)IOMMU_PTE_PAGE(pt[i]); \
1670 FN(p); \
1671 } \
1672 free_page((unsigned long)pt); \
1673}
1674
1675DEFINE_FREE_PT_FN(l2, free_page)
1676DEFINE_FREE_PT_FN(l3, free_pt_l2)
1677DEFINE_FREE_PT_FN(l4, free_pt_l3)
1678DEFINE_FREE_PT_FN(l5, free_pt_l4)
1679DEFINE_FREE_PT_FN(l6, free_pt_l5)
1680
Joerg Roedel86db2e52008-12-02 18:20:21 +01001681static void free_pagetable(struct protection_domain *domain)
Joerg Roedelec487d12008-06-26 21:27:58 +02001682{
Joerg Roedel5c34c402013-06-20 20:22:58 +02001683 unsigned long root = (unsigned long)domain->pt_root;
Joerg Roedelec487d12008-06-26 21:27:58 +02001684
Joerg Roedel5c34c402013-06-20 20:22:58 +02001685 switch (domain->mode) {
1686 case PAGE_MODE_NONE:
1687 break;
1688 case PAGE_MODE_1_LEVEL:
1689 free_page(root);
1690 break;
1691 case PAGE_MODE_2_LEVEL:
1692 free_pt_l2(root);
1693 break;
1694 case PAGE_MODE_3_LEVEL:
1695 free_pt_l3(root);
1696 break;
1697 case PAGE_MODE_4_LEVEL:
1698 free_pt_l4(root);
1699 break;
1700 case PAGE_MODE_5_LEVEL:
1701 free_pt_l5(root);
1702 break;
1703 case PAGE_MODE_6_LEVEL:
1704 free_pt_l6(root);
1705 break;
1706 default:
1707 BUG();
Joerg Roedelec487d12008-06-26 21:27:58 +02001708 }
Joerg Roedelec487d12008-06-26 21:27:58 +02001709}
1710
Joerg Roedelb16137b2011-11-21 16:50:23 +01001711static void free_gcr3_tbl_level1(u64 *tbl)
1712{
1713 u64 *ptr;
1714 int i;
1715
1716 for (i = 0; i < 512; ++i) {
1717 if (!(tbl[i] & GCR3_VALID))
1718 continue;
1719
1720 ptr = __va(tbl[i] & PAGE_MASK);
1721
1722 free_page((unsigned long)ptr);
1723 }
1724}
1725
1726static void free_gcr3_tbl_level2(u64 *tbl)
1727{
1728 u64 *ptr;
1729 int i;
1730
1731 for (i = 0; i < 512; ++i) {
1732 if (!(tbl[i] & GCR3_VALID))
1733 continue;
1734
1735 ptr = __va(tbl[i] & PAGE_MASK);
1736
1737 free_gcr3_tbl_level1(ptr);
1738 }
1739}
1740
Joerg Roedel52815b72011-11-17 17:24:28 +01001741static void free_gcr3_table(struct protection_domain *domain)
1742{
Joerg Roedelb16137b2011-11-21 16:50:23 +01001743 if (domain->glx == 2)
1744 free_gcr3_tbl_level2(domain->gcr3_tbl);
1745 else if (domain->glx == 1)
1746 free_gcr3_tbl_level1(domain->gcr3_tbl);
Joerg Roedel23d3a982015-08-13 11:15:13 +02001747 else
1748 BUG_ON(domain->glx != 0);
Joerg Roedelb16137b2011-11-21 16:50:23 +01001749
Joerg Roedel52815b72011-11-17 17:24:28 +01001750 free_page((unsigned long)domain->gcr3_tbl);
1751}
1752
Joerg Roedel431b2a22008-07-11 17:14:22 +02001753/*
1754 * Free a domain, only used if something went wrong in the
1755 * allocation path and we need to free an already allocated page table
1756 */
Joerg Roedelec487d12008-06-26 21:27:58 +02001757static void dma_ops_domain_free(struct dma_ops_domain *dom)
1758{
1759 if (!dom)
1760 return;
1761
Joerg Roedelaeb26f52009-11-20 16:44:01 +01001762 del_domain_from_list(&dom->domain);
1763
Joerg Roedel2d4c5152016-07-05 16:21:32 +02001764 put_iova_domain(&dom->iovad);
1765
Joerg Roedel86db2e52008-12-02 18:20:21 +01001766 free_pagetable(&dom->domain);
Joerg Roedelec487d12008-06-26 21:27:58 +02001767
Baoquan Hec3db9012016-09-15 16:50:52 +08001768 if (dom->domain.id)
1769 domain_id_free(dom->domain.id);
1770
Joerg Roedelec487d12008-06-26 21:27:58 +02001771 kfree(dom);
1772}
1773
Joerg Roedel431b2a22008-07-11 17:14:22 +02001774/*
1775 * Allocates a new protection domain usable for the dma_ops functions.
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04001776 * It also initializes the page table and the address allocator data
Joerg Roedel431b2a22008-07-11 17:14:22 +02001777 * structures required for the dma_ops interface
1778 */
Joerg Roedel87a64d52009-11-24 17:26:43 +01001779static struct dma_ops_domain *dma_ops_domain_alloc(void)
Joerg Roedelec487d12008-06-26 21:27:58 +02001780{
1781 struct dma_ops_domain *dma_dom;
Joerg Roedelec487d12008-06-26 21:27:58 +02001782
1783 dma_dom = kzalloc(sizeof(struct dma_ops_domain), GFP_KERNEL);
1784 if (!dma_dom)
1785 return NULL;
1786
Joerg Roedel7a5a5662015-06-30 08:56:11 +02001787 if (protection_domain_init(&dma_dom->domain))
Joerg Roedelec487d12008-06-26 21:27:58 +02001788 goto free_dma_dom;
Joerg Roedel7a5a5662015-06-30 08:56:11 +02001789
Joerg Roedelffec2192016-07-26 15:31:23 +02001790 dma_dom->domain.mode = PAGE_MODE_3_LEVEL;
Joerg Roedelec487d12008-06-26 21:27:58 +02001791 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
Joerg Roedel9fdb19d2008-12-02 17:46:25 +01001792 dma_dom->domain.flags = PD_DMA_OPS_MASK;
Joerg Roedelec487d12008-06-26 21:27:58 +02001793 if (!dma_dom->domain.pt_root)
1794 goto free_dma_dom;
Joerg Roedelec487d12008-06-26 21:27:58 +02001795
Joerg Roedel307d5852016-07-05 11:54:04 +02001796 init_iova_domain(&dma_dom->iovad, PAGE_SIZE,
1797 IOVA_START_PFN, DMA_32BIT_PFN);
1798
Joerg Roedel81cd07b2016-07-07 18:01:10 +02001799 /* Initialize reserved ranges */
1800 copy_reserved_iova(&reserved_iova_ranges, &dma_dom->iovad);
1801
Joerg Roedel2d4c5152016-07-05 16:21:32 +02001802 add_domain_to_list(&dma_dom->domain);
1803
Joerg Roedelec487d12008-06-26 21:27:58 +02001804 return dma_dom;
1805
1806free_dma_dom:
1807 dma_ops_domain_free(dma_dom);
1808
1809 return NULL;
1810}
1811
Joerg Roedel431b2a22008-07-11 17:14:22 +02001812/*
Joerg Roedel5b28df62008-12-02 17:49:42 +01001813 * little helper function to check whether a given protection domain is a
1814 * dma_ops domain
1815 */
1816static bool dma_ops_domain(struct protection_domain *domain)
1817{
1818 return domain->flags & PD_DMA_OPS_MASK;
1819}
1820
Joerg Roedelfd7b5532011-04-05 15:31:08 +02001821static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02001822{
Joerg Roedel132bd682011-11-17 14:18:46 +01001823 u64 pte_root = 0;
Joerg Roedelee6c2862011-11-09 12:06:03 +01001824 u64 flags = 0;
Joerg Roedel863c74e2008-12-02 17:56:36 +01001825
Joerg Roedel132bd682011-11-17 14:18:46 +01001826 if (domain->mode != PAGE_MODE_NONE)
1827 pte_root = virt_to_phys(domain->pt_root);
1828
Joerg Roedel38ddf412008-09-11 10:38:32 +02001829 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
1830 << DEV_ENTRY_MODE_SHIFT;
1831 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02001832
Joerg Roedelee6c2862011-11-09 12:06:03 +01001833 flags = amd_iommu_dev_table[devid].data[1];
1834
Joerg Roedelfd7b5532011-04-05 15:31:08 +02001835 if (ats)
1836 flags |= DTE_FLAG_IOTLB;
1837
Joerg Roedel52815b72011-11-17 17:24:28 +01001838 if (domain->flags & PD_IOMMUV2_MASK) {
1839 u64 gcr3 = __pa(domain->gcr3_tbl);
1840 u64 glx = domain->glx;
1841 u64 tmp;
1842
1843 pte_root |= DTE_FLAG_GV;
1844 pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT;
1845
1846 /* First mask out possible old values for GCR3 table */
1847 tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B;
1848 flags &= ~tmp;
1849
1850 tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C;
1851 flags &= ~tmp;
1852
1853 /* Encode GCR3 table into DTE */
1854 tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A;
1855 pte_root |= tmp;
1856
1857 tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B;
1858 flags |= tmp;
1859
1860 tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C;
1861 flags |= tmp;
1862 }
1863
Joerg Roedelee6c2862011-11-09 12:06:03 +01001864 flags &= ~(0xffffUL);
1865 flags |= domain->id;
1866
1867 amd_iommu_dev_table[devid].data[1] = flags;
1868 amd_iommu_dev_table[devid].data[0] = pte_root;
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02001869}
1870
Joerg Roedel15898bb2009-11-24 15:39:42 +01001871static void clear_dte_entry(u16 devid)
Joerg Roedel355bf552008-12-08 12:02:41 +01001872{
Joerg Roedel355bf552008-12-08 12:02:41 +01001873 /* remove entry from the device table seen by the hardware */
Joerg Roedelcbf3ccd2015-10-20 14:59:36 +02001874 amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
1875 amd_iommu_dev_table[devid].data[1] &= DTE_FLAG_MASK;
Joerg Roedel355bf552008-12-08 12:02:41 +01001876
Joerg Roedelc5cca142009-10-09 18:31:20 +02001877 amd_iommu_apply_erratum_63(devid);
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001878}
1879
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001880static void do_attach(struct iommu_dev_data *dev_data,
1881 struct protection_domain *domain)
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001882{
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001883 struct amd_iommu *iommu;
Joerg Roedele25bfb52015-10-20 17:33:38 +02001884 u16 alias;
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001885 bool ats;
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001886
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001887 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedele3156042016-04-08 15:12:24 +02001888 alias = dev_data->alias;
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001889 ats = dev_data->ats.enabled;
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001890
1891 /* Update data structures */
1892 dev_data->domain = domain;
1893 list_add(&dev_data->list, &domain->dev_list);
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001894
1895 /* Do reference counting */
1896 domain->dev_iommu[iommu->index] += 1;
1897 domain->dev_cnt += 1;
1898
Joerg Roedele25bfb52015-10-20 17:33:38 +02001899 /* Update device table */
1900 set_dte_entry(dev_data->devid, domain, ats);
1901 if (alias != dev_data->devid)
Baoquan He9b1a12d2016-01-20 22:01:19 +08001902 set_dte_entry(alias, domain, ats);
Joerg Roedele25bfb52015-10-20 17:33:38 +02001903
Joerg Roedel6c542042011-06-09 17:07:31 +02001904 device_flush_dte(dev_data);
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001905}
1906
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001907static void do_detach(struct iommu_dev_data *dev_data)
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001908{
Suravee Suthikulpanit2efa79e2019-01-24 04:16:45 +00001909 struct protection_domain *domain = dev_data->domain;
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001910 struct amd_iommu *iommu;
Joerg Roedele25bfb52015-10-20 17:33:38 +02001911 u16 alias;
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001912
Joerg Roedel5adad992015-10-09 16:23:33 +02001913 /*
1914 * First check if the device is still attached. It might already
1915 * be detached from its domain because the generic
1916 * iommu_detach_group code detached it and we try again here in
1917 * our alias handling.
1918 */
1919 if (!dev_data->domain)
1920 return;
1921
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001922 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedele3156042016-04-08 15:12:24 +02001923 alias = dev_data->alias;
Joerg Roedelc5cca142009-10-09 18:31:20 +02001924
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001925 /* Update data structures */
1926 dev_data->domain = NULL;
1927 list_del(&dev_data->list);
Joerg Roedelf62dda62011-06-09 12:55:35 +02001928 clear_dte_entry(dev_data->devid);
Joerg Roedele25bfb52015-10-20 17:33:38 +02001929 if (alias != dev_data->devid)
1930 clear_dte_entry(alias);
Joerg Roedel7f760dd2009-11-26 14:49:59 +01001931
1932 /* Flush the DTE entry */
Joerg Roedel6c542042011-06-09 17:07:31 +02001933 device_flush_dte(dev_data);
Suravee Suthikulpanit2efa79e2019-01-24 04:16:45 +00001934
1935 /* Flush IOTLB */
1936 domain_flush_tlb_pde(domain);
1937
1938 /* Wait for the flushes to finish */
1939 domain_flush_complete(domain);
1940
1941 /* decrease reference counters - needs to happen after the flushes */
1942 domain->dev_iommu[iommu->index] -= 1;
1943 domain->dev_cnt -= 1;
Joerg Roedel15898bb2009-11-24 15:39:42 +01001944}
1945
1946/*
1947 * If a device is not yet associated with a domain, this function does
1948 * assigns it visible for the hardware
1949 */
Joerg Roedelec9e79e2011-06-09 17:25:50 +02001950static int __attach_device(struct iommu_dev_data *dev_data,
Joerg Roedel15898bb2009-11-24 15:39:42 +01001951 struct protection_domain *domain)
1952{
Julia Lawall84fe6c12010-05-27 12:31:51 +02001953 int ret;
Joerg Roedel657cbb62009-11-23 15:26:46 +01001954
Joerg Roedel272e4f92015-10-20 17:33:37 +02001955 /*
1956 * Must be called with IRQs disabled. Warn here to detect early
1957 * when its not.
1958 */
1959 WARN_ON(!irqs_disabled());
1960
Joerg Roedel15898bb2009-11-24 15:39:42 +01001961 /* lock domain */
1962 spin_lock(&domain->lock);
1963
Joerg Roedel397111a2014-08-05 17:31:51 +02001964 ret = -EBUSY;
Joerg Roedel150952f2015-10-20 17:33:35 +02001965 if (dev_data->domain != NULL)
Joerg Roedel397111a2014-08-05 17:31:51 +02001966 goto out_unlock;
Joerg Roedel24100052009-11-25 15:59:57 +01001967
Joerg Roedel397111a2014-08-05 17:31:51 +02001968 /* Attach alias group root */
Joerg Roedel150952f2015-10-20 17:33:35 +02001969 do_attach(dev_data, domain);
Joerg Roedel24100052009-11-25 15:59:57 +01001970
Julia Lawall84fe6c12010-05-27 12:31:51 +02001971 ret = 0;
1972
1973out_unlock:
1974
Joerg Roedel355bf552008-12-08 12:02:41 +01001975 /* ready */
1976 spin_unlock(&domain->lock);
Joerg Roedel21129f72009-09-01 11:59:42 +02001977
Julia Lawall84fe6c12010-05-27 12:31:51 +02001978 return ret;
Joerg Roedel15898bb2009-11-24 15:39:42 +01001979}
1980
Joerg Roedel52815b72011-11-17 17:24:28 +01001981
1982static void pdev_iommuv2_disable(struct pci_dev *pdev)
1983{
1984 pci_disable_ats(pdev);
1985 pci_disable_pri(pdev);
1986 pci_disable_pasid(pdev);
1987}
1988
Joerg Roedel6a113dd2011-12-01 12:04:58 +01001989/* FIXME: Change generic reset-function to do the same */
1990static int pri_reset_while_enabled(struct pci_dev *pdev)
1991{
1992 u16 control;
1993 int pos;
1994
Joerg Roedel46277b72011-12-07 14:34:02 +01001995 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
Joerg Roedel6a113dd2011-12-01 12:04:58 +01001996 if (!pos)
1997 return -EINVAL;
1998
Joerg Roedel46277b72011-12-07 14:34:02 +01001999 pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
2000 control |= PCI_PRI_CTRL_RESET;
2001 pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
Joerg Roedel6a113dd2011-12-01 12:04:58 +01002002
2003 return 0;
2004}
2005
Joerg Roedel52815b72011-11-17 17:24:28 +01002006static int pdev_iommuv2_enable(struct pci_dev *pdev)
2007{
Joerg Roedel6a113dd2011-12-01 12:04:58 +01002008 bool reset_enable;
2009 int reqs, ret;
2010
2011 /* FIXME: Hardcode number of outstanding requests for now */
2012 reqs = 32;
2013 if (pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE))
2014 reqs = 1;
2015 reset_enable = pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_ENABLE_RESET);
Joerg Roedel52815b72011-11-17 17:24:28 +01002016
2017 /* Only allow access to user-accessible pages */
2018 ret = pci_enable_pasid(pdev, 0);
2019 if (ret)
2020 goto out_err;
2021
2022 /* First reset the PRI state of the device */
2023 ret = pci_reset_pri(pdev);
2024 if (ret)
2025 goto out_err;
2026
Joerg Roedel6a113dd2011-12-01 12:04:58 +01002027 /* Enable PRI */
2028 ret = pci_enable_pri(pdev, reqs);
Joerg Roedel52815b72011-11-17 17:24:28 +01002029 if (ret)
2030 goto out_err;
2031
Joerg Roedel6a113dd2011-12-01 12:04:58 +01002032 if (reset_enable) {
2033 ret = pri_reset_while_enabled(pdev);
2034 if (ret)
2035 goto out_err;
2036 }
2037
Joerg Roedel52815b72011-11-17 17:24:28 +01002038 ret = pci_enable_ats(pdev, PAGE_SHIFT);
2039 if (ret)
2040 goto out_err;
2041
2042 return 0;
2043
2044out_err:
2045 pci_disable_pri(pdev);
2046 pci_disable_pasid(pdev);
2047
2048 return ret;
2049}
2050
Joerg Roedelc99afa22011-11-21 18:19:25 +01002051/* FIXME: Move this to PCI code */
Joerg Roedela3b93122012-04-12 12:49:26 +02002052#define PCI_PRI_TLP_OFF (1 << 15)
Joerg Roedelc99afa22011-11-21 18:19:25 +01002053
Joerg Roedel98f1ad22012-07-06 13:28:37 +02002054static bool pci_pri_tlp_required(struct pci_dev *pdev)
Joerg Roedelc99afa22011-11-21 18:19:25 +01002055{
Joerg Roedela3b93122012-04-12 12:49:26 +02002056 u16 status;
Joerg Roedelc99afa22011-11-21 18:19:25 +01002057 int pos;
2058
Joerg Roedel46277b72011-12-07 14:34:02 +01002059 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
Joerg Roedelc99afa22011-11-21 18:19:25 +01002060 if (!pos)
2061 return false;
2062
Joerg Roedela3b93122012-04-12 12:49:26 +02002063 pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
Joerg Roedelc99afa22011-11-21 18:19:25 +01002064
Joerg Roedela3b93122012-04-12 12:49:26 +02002065 return (status & PCI_PRI_TLP_OFF) ? true : false;
Joerg Roedelc99afa22011-11-21 18:19:25 +01002066}
2067
Joerg Roedel15898bb2009-11-24 15:39:42 +01002068/*
Frank Arnolddf805ab2012-08-27 19:21:04 +02002069 * If a device is not yet associated with a domain, this function
Joerg Roedel15898bb2009-11-24 15:39:42 +01002070 * assigns it visible for the hardware
2071 */
2072static int attach_device(struct device *dev,
2073 struct protection_domain *domain)
2074{
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -04002075 struct pci_dev *pdev;
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002076 struct iommu_dev_data *dev_data;
Joerg Roedel15898bb2009-11-24 15:39:42 +01002077 unsigned long flags;
2078 int ret;
2079
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002080 dev_data = get_dev_data(dev);
2081
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -04002082 if (!dev_is_pci(dev))
2083 goto skip_ats_check;
2084
2085 pdev = to_pci_dev(dev);
Joerg Roedel52815b72011-11-17 17:24:28 +01002086 if (domain->flags & PD_IOMMUV2_MASK) {
Joerg Roedel02ca2022015-07-28 16:58:49 +02002087 if (!dev_data->passthrough)
Joerg Roedel52815b72011-11-17 17:24:28 +01002088 return -EINVAL;
2089
Joerg Roedel02ca2022015-07-28 16:58:49 +02002090 if (dev_data->iommu_v2) {
2091 if (pdev_iommuv2_enable(pdev) != 0)
2092 return -EINVAL;
Joerg Roedel52815b72011-11-17 17:24:28 +01002093
Joerg Roedel02ca2022015-07-28 16:58:49 +02002094 dev_data->ats.enabled = true;
2095 dev_data->ats.qdep = pci_ats_queue_depth(pdev);
2096 dev_data->pri_tlp = pci_pri_tlp_required(pdev);
2097 }
Joerg Roedel52815b72011-11-17 17:24:28 +01002098 } else if (amd_iommu_iotlb_sup &&
2099 pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002100 dev_data->ats.enabled = true;
2101 dev_data->ats.qdep = pci_ats_queue_depth(pdev);
2102 }
Joerg Roedelfd7b5532011-04-05 15:31:08 +02002103
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -04002104skip_ats_check:
Joerg Roedel15898bb2009-11-24 15:39:42 +01002105 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
Joerg Roedelec9e79e2011-06-09 17:25:50 +02002106 ret = __attach_device(dev_data, domain);
Joerg Roedel15898bb2009-11-24 15:39:42 +01002107 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
2108
2109 /*
2110 * We might boot into a crash-kernel here. The crashed kernel
2111 * left the caches in the IOMMU dirty. So we have to flush
2112 * here to evict all dirty stuff.
2113 */
Joerg Roedel17b124b2011-04-06 18:01:35 +02002114 domain_flush_tlb_pde(domain);
Joerg Roedel15898bb2009-11-24 15:39:42 +01002115
Filippo Sironia9e0dcf2019-09-10 19:49:21 +02002116 domain_flush_complete(domain);
2117
Joerg Roedel15898bb2009-11-24 15:39:42 +01002118 return ret;
2119}
2120
2121/*
2122 * Removes a device from a protection domain (unlocked)
2123 */
Joerg Roedelec9e79e2011-06-09 17:25:50 +02002124static void __detach_device(struct iommu_dev_data *dev_data)
Joerg Roedel15898bb2009-11-24 15:39:42 +01002125{
Joerg Roedel2ca76272010-01-22 16:45:31 +01002126 struct protection_domain *domain;
Joerg Roedel15898bb2009-11-24 15:39:42 +01002127
Joerg Roedel272e4f92015-10-20 17:33:37 +02002128 /*
2129 * Must be called with IRQs disabled. Warn here to detect early
2130 * when its not.
2131 */
2132 WARN_ON(!irqs_disabled());
2133
Joerg Roedelf34c73f2015-10-20 17:33:34 +02002134 if (WARN_ON(!dev_data->domain))
2135 return;
Joerg Roedel15898bb2009-11-24 15:39:42 +01002136
Joerg Roedel2ca76272010-01-22 16:45:31 +01002137 domain = dev_data->domain;
2138
Joerg Roedelf1dd0a82015-10-20 17:33:36 +02002139 spin_lock(&domain->lock);
Joerg Roedel24100052009-11-25 15:59:57 +01002140
Joerg Roedel150952f2015-10-20 17:33:35 +02002141 do_detach(dev_data);
Joerg Roedel71f77582011-06-09 19:03:15 +02002142
Joerg Roedelf1dd0a82015-10-20 17:33:36 +02002143 spin_unlock(&domain->lock);
Joerg Roedel355bf552008-12-08 12:02:41 +01002144}
2145
2146/*
2147 * Removes a device from a protection domain (with devtable_lock held)
2148 */
Joerg Roedel15898bb2009-11-24 15:39:42 +01002149static void detach_device(struct device *dev)
Joerg Roedel355bf552008-12-08 12:02:41 +01002150{
Joerg Roedel52815b72011-11-17 17:24:28 +01002151 struct protection_domain *domain;
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002152 struct iommu_dev_data *dev_data;
Joerg Roedel355bf552008-12-08 12:02:41 +01002153 unsigned long flags;
2154
Joerg Roedelec9e79e2011-06-09 17:25:50 +02002155 dev_data = get_dev_data(dev);
Joerg Roedel52815b72011-11-17 17:24:28 +01002156 domain = dev_data->domain;
Joerg Roedelec9e79e2011-06-09 17:25:50 +02002157
Joerg Roedel355bf552008-12-08 12:02:41 +01002158 /* lock device table */
2159 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
Joerg Roedelec9e79e2011-06-09 17:25:50 +02002160 __detach_device(dev_data);
Joerg Roedel355bf552008-12-08 12:02:41 +01002161 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
Joerg Roedelfd7b5532011-04-05 15:31:08 +02002162
Wan Zongshun2bf9a0a2016-04-01 09:06:03 -04002163 if (!dev_is_pci(dev))
2164 return;
2165
Joerg Roedel02ca2022015-07-28 16:58:49 +02002166 if (domain->flags & PD_IOMMUV2_MASK && dev_data->iommu_v2)
Joerg Roedel52815b72011-11-17 17:24:28 +01002167 pdev_iommuv2_disable(to_pci_dev(dev));
2168 else if (dev_data->ats.enabled)
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002169 pci_disable_ats(to_pci_dev(dev));
Joerg Roedel52815b72011-11-17 17:24:28 +01002170
2171 dev_data->ats.enabled = false;
Joerg Roedel355bf552008-12-08 12:02:41 +01002172}
Joerg Roedele275a2a2008-12-10 18:27:25 +01002173
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002174static int amd_iommu_add_device(struct device *dev)
Joerg Roedel15898bb2009-11-24 15:39:42 +01002175{
Joerg Roedel71f77582011-06-09 19:03:15 +02002176 struct iommu_dev_data *dev_data;
Joerg Roedel07ee8692015-05-28 18:41:42 +02002177 struct iommu_domain *domain;
Joerg Roedele275a2a2008-12-10 18:27:25 +01002178 struct amd_iommu *iommu;
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04002179 int ret, devid;
Joerg Roedele275a2a2008-12-10 18:27:25 +01002180
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002181 if (!check_device(dev) || get_dev_data(dev))
Joerg Roedel98fc5a62009-11-24 17:19:23 +01002182 return 0;
Joerg Roedele275a2a2008-12-10 18:27:25 +01002183
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002184 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +02002185 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04002186 return devid;
2187
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002188 iommu = amd_iommu_rlookup_table[devid];
Joerg Roedele275a2a2008-12-10 18:27:25 +01002189
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002190 ret = iommu_init_device(dev);
Joerg Roedel4d58b8a2015-06-11 09:21:39 +02002191 if (ret) {
2192 if (ret != -ENOTSUPP)
2193 pr_err("Failed to initialize device %s - trying to proceed anyway\n",
2194 dev_name(dev));
Joerg Roedel657cbb62009-11-23 15:26:46 +01002195
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002196 iommu_ignore_device(dev);
Joerg Roedel343e9ca2015-05-28 18:41:43 +02002197 dev->archdata.dma_ops = &nommu_dma_ops;
Joerg Roedele275a2a2008-12-10 18:27:25 +01002198 goto out;
2199 }
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002200 init_iommu_group(dev);
Joerg Roedele275a2a2008-12-10 18:27:25 +01002201
Joerg Roedel07ee8692015-05-28 18:41:42 +02002202 dev_data = get_dev_data(dev);
Joerg Roedel4d58b8a2015-06-11 09:21:39 +02002203
2204 BUG_ON(!dev_data);
2205
Joerg Roedel1e6a7b02015-07-28 16:58:48 +02002206 if (iommu_pass_through || dev_data->iommu_v2)
Joerg Roedel07ee8692015-05-28 18:41:42 +02002207 iommu_request_dm_for_dev(dev);
2208
2209 /* Domains are initialized for this device - have a look what we ended up with */
2210 domain = iommu_get_domain_for_dev(dev);
Joerg Roedel32302322015-07-28 16:58:50 +02002211 if (domain->type == IOMMU_DOMAIN_IDENTITY)
Joerg Roedel07ee8692015-05-28 18:41:42 +02002212 dev_data->passthrough = true;
Joerg Roedel32302322015-07-28 16:58:50 +02002213 else
Joerg Roedel07ee8692015-05-28 18:41:42 +02002214 dev->archdata.dma_ops = &amd_iommu_dma_ops;
Joerg Roedele275a2a2008-12-10 18:27:25 +01002215
2216out:
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002217 iommu_completion_wait(iommu);
2218
Joerg Roedele275a2a2008-12-10 18:27:25 +01002219 return 0;
2220}
2221
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002222static void amd_iommu_remove_device(struct device *dev)
Joerg Roedel8638c492009-12-10 11:12:25 +01002223{
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002224 struct amd_iommu *iommu;
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04002225 int devid;
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002226
2227 if (!check_device(dev))
2228 return;
2229
2230 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +02002231 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04002232 return;
2233
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02002234 iommu = amd_iommu_rlookup_table[devid];
2235
2236 iommu_uninit_device(dev);
2237 iommu_completion_wait(iommu);
Joerg Roedel8638c492009-12-10 11:12:25 +01002238}
2239
Wan Zongshunb097d112016-04-01 09:06:04 -04002240static struct iommu_group *amd_iommu_device_group(struct device *dev)
2241{
2242 if (dev_is_pci(dev))
2243 return pci_device_group(dev);
2244
2245 return acpihid_device_group(dev);
2246}
2247
Joerg Roedel431b2a22008-07-11 17:14:22 +02002248/*****************************************************************************
2249 *
2250 * The next functions belong to the dma_ops mapping/unmapping code.
2251 *
2252 *****************************************************************************/
2253
Joerg Roedelb1516a12016-07-06 13:07:22 +02002254static void __queue_flush(struct flush_queue *queue)
2255{
2256 struct protection_domain *domain;
2257 unsigned long flags;
2258 int idx;
2259
2260 /* First flush TLB of all known domains */
2261 spin_lock_irqsave(&amd_iommu_pd_lock, flags);
2262 list_for_each_entry(domain, &amd_iommu_pd_list, list)
2263 domain_flush_tlb(domain);
2264 spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
2265
2266 /* Wait until flushes have completed */
2267 domain_flush_complete(NULL);
2268
2269 for (idx = 0; idx < queue->next; ++idx) {
2270 struct flush_queue_entry *entry;
2271
2272 entry = queue->entries + idx;
2273
2274 free_iova_fast(&entry->dma_dom->iovad,
2275 entry->iova_pfn,
2276 entry->pages);
2277
2278 /* Not really necessary, just to make sure we catch any bugs */
2279 entry->dma_dom = NULL;
2280 }
2281
2282 queue->next = 0;
2283}
2284
Joerg Roedel281e8cc2016-07-07 16:12:02 +02002285static void queue_flush_all(void)
Joerg Roedelbb279472016-07-06 13:56:36 +02002286{
2287 int cpu;
2288
Joerg Roedelbb279472016-07-06 13:56:36 +02002289 for_each_possible_cpu(cpu) {
2290 struct flush_queue *queue;
2291 unsigned long flags;
2292
2293 queue = per_cpu_ptr(&flush_queue, cpu);
2294 spin_lock_irqsave(&queue->lock, flags);
2295 if (queue->next > 0)
2296 __queue_flush(queue);
2297 spin_unlock_irqrestore(&queue->lock, flags);
2298 }
2299}
2300
Joerg Roedel281e8cc2016-07-07 16:12:02 +02002301static void queue_flush_timeout(unsigned long unsused)
2302{
2303 atomic_set(&queue_timer_on, 0);
2304 queue_flush_all();
2305}
2306
Joerg Roedelb1516a12016-07-06 13:07:22 +02002307static void queue_add(struct dma_ops_domain *dma_dom,
2308 unsigned long address, unsigned long pages)
2309{
2310 struct flush_queue_entry *entry;
2311 struct flush_queue *queue;
2312 unsigned long flags;
2313 int idx;
2314
2315 pages = __roundup_pow_of_two(pages);
2316 address >>= PAGE_SHIFT;
2317
2318 queue = get_cpu_ptr(&flush_queue);
2319 spin_lock_irqsave(&queue->lock, flags);
2320
2321 if (queue->next == FLUSH_QUEUE_SIZE)
2322 __queue_flush(queue);
2323
2324 idx = queue->next++;
2325 entry = queue->entries + idx;
2326
2327 entry->iova_pfn = address;
2328 entry->pages = pages;
2329 entry->dma_dom = dma_dom;
2330
2331 spin_unlock_irqrestore(&queue->lock, flags);
Joerg Roedelbb279472016-07-06 13:56:36 +02002332
2333 if (atomic_cmpxchg(&queue_timer_on, 0, 1) == 0)
2334 mod_timer(&queue_timer, jiffies + msecs_to_jiffies(10));
2335
Joerg Roedelb1516a12016-07-06 13:07:22 +02002336 put_cpu_ptr(&flush_queue);
2337}
2338
2339
Joerg Roedel431b2a22008-07-11 17:14:22 +02002340/*
2341 * In the dma_ops path we only have the struct device. This function
2342 * finds the corresponding IOMMU, the protection domain and the
2343 * requestor id for a given device.
2344 * If the device is not yet associated with a domain this is also done
2345 * in this function.
2346 */
Joerg Roedel94f6d192009-11-24 16:40:02 +01002347static struct protection_domain *get_domain(struct device *dev)
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02002348{
Joerg Roedel94f6d192009-11-24 16:40:02 +01002349 struct protection_domain *domain;
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02002350
Joerg Roedelf99c0f12009-11-23 16:52:56 +01002351 if (!check_device(dev))
Joerg Roedel94f6d192009-11-24 16:40:02 +01002352 return ERR_PTR(-EINVAL);
Joerg Roedeldbcc1122008-09-04 15:04:26 +02002353
Joerg Roedeld26592a2016-07-07 15:31:13 +02002354 domain = get_dev_data(dev)->domain;
Joerg Roedel0bb6e242015-05-28 18:41:40 +02002355 if (!dma_ops_domain(domain))
Joerg Roedel94f6d192009-11-24 16:40:02 +01002356 return ERR_PTR(-EBUSY);
Joerg Roedelf99c0f12009-11-23 16:52:56 +01002357
Joerg Roedel0bb6e242015-05-28 18:41:40 +02002358 return domain;
Joerg Roedelb20ac0d2008-06-26 21:27:59 +02002359}
2360
Joerg Roedel04bfdd82009-09-02 16:00:23 +02002361static void update_device_table(struct protection_domain *domain)
2362{
Joerg Roedel492667d2009-11-27 13:25:47 +01002363 struct iommu_dev_data *dev_data;
Joerg Roedel04bfdd82009-09-02 16:00:23 +02002364
Joerg Roedel3254de62016-07-26 15:18:54 +02002365 list_for_each_entry(dev_data, &domain->dev_list, list) {
Joerg Roedelea61cdd2011-06-09 12:56:30 +02002366 set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
Joerg Roedel3254de62016-07-26 15:18:54 +02002367
2368 if (dev_data->devid == dev_data->alias)
2369 continue;
2370
2371 /* There is an alias, update device table entry for it */
2372 set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
2373 }
Joerg Roedel04bfdd82009-09-02 16:00:23 +02002374}
2375
2376static void update_domain(struct protection_domain *domain)
2377{
2378 if (!domain->updated)
2379 return;
2380
2381 update_device_table(domain);
Joerg Roedel17b124b2011-04-06 18:01:35 +02002382
2383 domain_flush_devices(domain);
2384 domain_flush_tlb_pde(domain);
Joerg Roedel04bfdd82009-09-02 16:00:23 +02002385
2386 domain->updated = false;
2387}
2388
Joerg Roedelf37f7f32016-07-08 11:47:22 +02002389static int dir2prot(enum dma_data_direction direction)
2390{
2391 if (direction == DMA_TO_DEVICE)
2392 return IOMMU_PROT_IR;
2393 else if (direction == DMA_FROM_DEVICE)
2394 return IOMMU_PROT_IW;
2395 else if (direction == DMA_BIDIRECTIONAL)
2396 return IOMMU_PROT_IW | IOMMU_PROT_IR;
2397 else
2398 return 0;
2399}
Joerg Roedel431b2a22008-07-11 17:14:22 +02002400/*
Joerg Roedel431b2a22008-07-11 17:14:22 +02002401 * This function contains common code for mapping of a physically
Joerg Roedel24f81162008-12-08 14:25:39 +01002402 * contiguous memory region into DMA address space. It is used by all
2403 * mapping functions provided with this IOMMU driver.
Joerg Roedel431b2a22008-07-11 17:14:22 +02002404 * Must be called with the domain lock held.
2405 */
Joerg Roedelcb76c322008-06-26 21:28:00 +02002406static dma_addr_t __map_single(struct device *dev,
Joerg Roedelcb76c322008-06-26 21:28:00 +02002407 struct dma_ops_domain *dma_dom,
2408 phys_addr_t paddr,
2409 size_t size,
Joerg Roedelf37f7f32016-07-08 11:47:22 +02002410 enum dma_data_direction direction,
Joerg Roedel832a90c2008-09-18 15:54:23 +02002411 u64 dma_mask)
Joerg Roedelcb76c322008-06-26 21:28:00 +02002412{
2413 dma_addr_t offset = paddr & ~PAGE_MASK;
Joerg Roedel53812c12009-05-12 12:17:38 +02002414 dma_addr_t address, start, ret;
Joerg Roedelcb76c322008-06-26 21:28:00 +02002415 unsigned int pages;
Joerg Roedel518d9b42016-07-05 14:39:47 +02002416 int prot = 0;
Joerg Roedelcb76c322008-06-26 21:28:00 +02002417 int i;
2418
Joerg Roedele3c449f2008-10-15 22:02:11 -07002419 pages = iommu_num_pages(paddr, size, PAGE_SIZE);
Joerg Roedelcb76c322008-06-26 21:28:00 +02002420 paddr &= PAGE_MASK;
2421
Joerg Roedel256e4622016-07-05 14:23:01 +02002422 address = dma_ops_alloc_iova(dev, dma_dom, pages, dma_mask);
Joerg Roedel266a3bd2015-12-21 18:54:24 +01002423 if (address == DMA_ERROR_CODE)
2424 goto out;
Joerg Roedelcb76c322008-06-26 21:28:00 +02002425
Joerg Roedelf37f7f32016-07-08 11:47:22 +02002426 prot = dir2prot(direction);
Joerg Roedel518d9b42016-07-05 14:39:47 +02002427
Joerg Roedelcb76c322008-06-26 21:28:00 +02002428 start = address;
2429 for (i = 0; i < pages; ++i) {
Joerg Roedel518d9b42016-07-05 14:39:47 +02002430 ret = iommu_map_page(&dma_dom->domain, start, paddr,
2431 PAGE_SIZE, prot, GFP_ATOMIC);
2432 if (ret)
Joerg Roedel53812c12009-05-12 12:17:38 +02002433 goto out_unmap;
2434
Joerg Roedelcb76c322008-06-26 21:28:00 +02002435 paddr += PAGE_SIZE;
2436 start += PAGE_SIZE;
2437 }
2438 address += offset;
2439
Joerg Roedelab7032b2015-12-21 18:47:11 +01002440 if (unlikely(amd_iommu_np_cache)) {
Joerg Roedel17b124b2011-04-06 18:01:35 +02002441 domain_flush_pages(&dma_dom->domain, address, size);
Joerg Roedelab7032b2015-12-21 18:47:11 +01002442 domain_flush_complete(&dma_dom->domain);
2443 }
Joerg Roedel270cab242008-09-04 15:49:46 +02002444
Joerg Roedelcb76c322008-06-26 21:28:00 +02002445out:
2446 return address;
Joerg Roedel53812c12009-05-12 12:17:38 +02002447
2448out_unmap:
2449
2450 for (--i; i >= 0; --i) {
2451 start -= PAGE_SIZE;
Joerg Roedel518d9b42016-07-05 14:39:47 +02002452 iommu_unmap_page(&dma_dom->domain, start, PAGE_SIZE);
Joerg Roedel53812c12009-05-12 12:17:38 +02002453 }
2454
Joerg Roedel256e4622016-07-05 14:23:01 +02002455 domain_flush_tlb(&dma_dom->domain);
2456 domain_flush_complete(&dma_dom->domain);
2457
2458 dma_ops_free_iova(dma_dom, address, pages);
Joerg Roedel53812c12009-05-12 12:17:38 +02002459
FUJITA Tomonori8fd524b2009-11-15 21:19:53 +09002460 return DMA_ERROR_CODE;
Joerg Roedelcb76c322008-06-26 21:28:00 +02002461}
2462
Joerg Roedel431b2a22008-07-11 17:14:22 +02002463/*
2464 * Does the reverse of the __map_single function. Must be called with
2465 * the domain lock held too
2466 */
Joerg Roedelcd8c82e2009-11-23 19:33:56 +01002467static void __unmap_single(struct dma_ops_domain *dma_dom,
Joerg Roedelcb76c322008-06-26 21:28:00 +02002468 dma_addr_t dma_addr,
2469 size_t size,
2470 int dir)
2471{
Joerg Roedel04e04632010-09-23 16:12:48 +02002472 dma_addr_t flush_addr;
Joerg Roedelcb76c322008-06-26 21:28:00 +02002473 dma_addr_t i, start;
2474 unsigned int pages;
2475
Joerg Roedel04e04632010-09-23 16:12:48 +02002476 flush_addr = dma_addr;
Joerg Roedele3c449f2008-10-15 22:02:11 -07002477 pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
Joerg Roedelcb76c322008-06-26 21:28:00 +02002478 dma_addr &= PAGE_MASK;
2479 start = dma_addr;
2480
2481 for (i = 0; i < pages; ++i) {
Joerg Roedel518d9b42016-07-05 14:39:47 +02002482 iommu_unmap_page(&dma_dom->domain, start, PAGE_SIZE);
Joerg Roedelcb76c322008-06-26 21:28:00 +02002483 start += PAGE_SIZE;
2484 }
2485
Joerg Roedelb1516a12016-07-06 13:07:22 +02002486 if (amd_iommu_unmap_flush) {
Joerg Roedelb1516a12016-07-06 13:07:22 +02002487 domain_flush_tlb(&dma_dom->domain);
2488 domain_flush_complete(&dma_dom->domain);
Zhen Lei5eb06bf2018-06-06 10:18:46 +08002489 dma_ops_free_iova(dma_dom, dma_addr, pages);
Joerg Roedelb1516a12016-07-06 13:07:22 +02002490 } else {
2491 queue_add(dma_dom, dma_addr, pages);
2492 }
Joerg Roedelcb76c322008-06-26 21:28:00 +02002493}
2494
Joerg Roedel431b2a22008-07-11 17:14:22 +02002495/*
2496 * The exported map_single function for dma_ops.
2497 */
FUJITA Tomonori51491362009-01-05 23:47:25 +09002498static dma_addr_t map_page(struct device *dev, struct page *page,
2499 unsigned long offset, size_t size,
2500 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002501 unsigned long attrs)
Joerg Roedel4da70b92008-06-26 21:28:01 +02002502{
FUJITA Tomonori51491362009-01-05 23:47:25 +09002503 phys_addr_t paddr = page_to_phys(page) + offset;
Joerg Roedel92d420e2015-12-21 19:31:33 +01002504 struct protection_domain *domain;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002505 struct dma_ops_domain *dma_dom;
Joerg Roedel92d420e2015-12-21 19:31:33 +01002506 u64 dma_mask;
Joerg Roedel4da70b92008-06-26 21:28:01 +02002507
Joerg Roedel94f6d192009-11-24 16:40:02 +01002508 domain = get_domain(dev);
2509 if (PTR_ERR(domain) == -EINVAL)
Joerg Roedel4da70b92008-06-26 21:28:01 +02002510 return (dma_addr_t)paddr;
Joerg Roedel94f6d192009-11-24 16:40:02 +01002511 else if (IS_ERR(domain))
2512 return DMA_ERROR_CODE;
Joerg Roedel4da70b92008-06-26 21:28:01 +02002513
Joerg Roedelf99c0f12009-11-23 16:52:56 +01002514 dma_mask = *dev->dma_mask;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002515 dma_dom = to_dma_ops_domain(domain);
Joerg Roedelf99c0f12009-11-23 16:52:56 +01002516
Joerg Roedelb3311b02016-07-08 13:31:31 +02002517 return __map_single(dev, dma_dom, paddr, size, dir, dma_mask);
Joerg Roedel4da70b92008-06-26 21:28:01 +02002518}
2519
Joerg Roedel431b2a22008-07-11 17:14:22 +02002520/*
2521 * The exported unmap_single function for dma_ops.
2522 */
FUJITA Tomonori51491362009-01-05 23:47:25 +09002523static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002524 enum dma_data_direction dir, unsigned long attrs)
Joerg Roedel4da70b92008-06-26 21:28:01 +02002525{
Joerg Roedel4da70b92008-06-26 21:28:01 +02002526 struct protection_domain *domain;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002527 struct dma_ops_domain *dma_dom;
Joerg Roedel4da70b92008-06-26 21:28:01 +02002528
Joerg Roedel94f6d192009-11-24 16:40:02 +01002529 domain = get_domain(dev);
2530 if (IS_ERR(domain))
Joerg Roedel5b28df62008-12-02 17:49:42 +01002531 return;
2532
Joerg Roedelb3311b02016-07-08 13:31:31 +02002533 dma_dom = to_dma_ops_domain(domain);
2534
2535 __unmap_single(dma_dom, dma_addr, size, dir);
Joerg Roedel4da70b92008-06-26 21:28:01 +02002536}
2537
Joerg Roedel80187fd2016-07-06 17:20:54 +02002538static int sg_num_pages(struct device *dev,
2539 struct scatterlist *sglist,
2540 int nelems)
2541{
2542 unsigned long mask, boundary_size;
2543 struct scatterlist *s;
2544 int i, npages = 0;
2545
2546 mask = dma_get_seg_boundary(dev);
2547 boundary_size = mask + 1 ? ALIGN(mask + 1, PAGE_SIZE) >> PAGE_SHIFT :
2548 1UL << (BITS_PER_LONG - PAGE_SHIFT);
2549
2550 for_each_sg(sglist, s, nelems, i) {
2551 int p, n;
2552
2553 s->dma_address = npages << PAGE_SHIFT;
2554 p = npages % boundary_size;
2555 n = iommu_num_pages(sg_phys(s), s->length, PAGE_SIZE);
2556 if (p + n > boundary_size)
2557 npages += boundary_size - p;
2558 npages += n;
2559 }
2560
2561 return npages;
2562}
2563
Joerg Roedel431b2a22008-07-11 17:14:22 +02002564/*
Joerg Roedel431b2a22008-07-11 17:14:22 +02002565 * The exported map_sg function for dma_ops (handles scatter-gather
2566 * lists).
2567 */
Joerg Roedel65b050a2008-06-26 21:28:02 +02002568static int map_sg(struct device *dev, struct scatterlist *sglist,
Joerg Roedel80187fd2016-07-06 17:20:54 +02002569 int nelems, enum dma_data_direction direction,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002570 unsigned long attrs)
Joerg Roedel65b050a2008-06-26 21:28:02 +02002571{
Joerg Roedel80187fd2016-07-06 17:20:54 +02002572 int mapped_pages = 0, npages = 0, prot = 0, i;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002573 struct protection_domain *domain;
Joerg Roedel80187fd2016-07-06 17:20:54 +02002574 struct dma_ops_domain *dma_dom;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002575 struct scatterlist *s;
Joerg Roedel80187fd2016-07-06 17:20:54 +02002576 unsigned long address;
Joerg Roedel832a90c2008-09-18 15:54:23 +02002577 u64 dma_mask;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002578
Joerg Roedel94f6d192009-11-24 16:40:02 +01002579 domain = get_domain(dev);
Joerg Roedela0e191b2013-04-09 15:04:36 +02002580 if (IS_ERR(domain))
Joerg Roedel94f6d192009-11-24 16:40:02 +01002581 return 0;
Joerg Roedeldbcc1122008-09-04 15:04:26 +02002582
Joerg Roedelb3311b02016-07-08 13:31:31 +02002583 dma_dom = to_dma_ops_domain(domain);
Joerg Roedel832a90c2008-09-18 15:54:23 +02002584 dma_mask = *dev->dma_mask;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002585
Joerg Roedel80187fd2016-07-06 17:20:54 +02002586 npages = sg_num_pages(dev, sglist, nelems);
2587
2588 address = dma_ops_alloc_iova(dev, dma_dom, npages, dma_mask);
2589 if (address == DMA_ERROR_CODE)
2590 goto out_err;
2591
2592 prot = dir2prot(direction);
2593
2594 /* Map all sg entries */
Joerg Roedel65b050a2008-06-26 21:28:02 +02002595 for_each_sg(sglist, s, nelems, i) {
Joerg Roedel80187fd2016-07-06 17:20:54 +02002596 int j, pages = iommu_num_pages(sg_phys(s), s->length, PAGE_SIZE);
Joerg Roedel65b050a2008-06-26 21:28:02 +02002597
Joerg Roedel80187fd2016-07-06 17:20:54 +02002598 for (j = 0; j < pages; ++j) {
2599 unsigned long bus_addr, phys_addr;
2600 int ret;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002601
Joerg Roedel80187fd2016-07-06 17:20:54 +02002602 bus_addr = address + s->dma_address + (j << PAGE_SHIFT);
2603 phys_addr = (sg_phys(s) & PAGE_MASK) + (j << PAGE_SHIFT);
Qian Cai355c7802019-08-28 17:39:43 -04002604 ret = iommu_map_page(domain, bus_addr, phys_addr,
2605 PAGE_SIZE, prot,
2606 GFP_ATOMIC | __GFP_NOWARN);
Joerg Roedel80187fd2016-07-06 17:20:54 +02002607 if (ret)
2608 goto out_unmap;
2609
2610 mapped_pages += 1;
2611 }
Joerg Roedel65b050a2008-06-26 21:28:02 +02002612 }
2613
Joerg Roedel80187fd2016-07-06 17:20:54 +02002614 /* Everything is mapped - write the right values into s->dma_address */
2615 for_each_sg(sglist, s, nelems, i) {
Stanislaw Gruszkacfa2d252019-03-13 10:03:17 +01002616 /*
2617 * Add in the remaining piece of the scatter-gather offset that
2618 * was masked out when we were determining the physical address
2619 * via (sg_phys(s) & PAGE_MASK) earlier.
2620 */
2621 s->dma_address += address + (s->offset & ~PAGE_MASK);
Joerg Roedel80187fd2016-07-06 17:20:54 +02002622 s->dma_length = s->length;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002623 }
2624
Joerg Roedel80187fd2016-07-06 17:20:54 +02002625 return nelems;
2626
2627out_unmap:
2628 pr_err("%s: IOMMU mapping error in map_sg (io-pages: %d)\n",
2629 dev_name(dev), npages);
2630
2631 for_each_sg(sglist, s, nelems, i) {
2632 int j, pages = iommu_num_pages(sg_phys(s), s->length, PAGE_SIZE);
2633
2634 for (j = 0; j < pages; ++j) {
2635 unsigned long bus_addr;
2636
2637 bus_addr = address + s->dma_address + (j << PAGE_SHIFT);
2638 iommu_unmap_page(domain, bus_addr, PAGE_SIZE);
2639
Jerry Snitselaar50c382e2019-01-19 10:38:05 -07002640 if (--mapped_pages == 0)
Joerg Roedel80187fd2016-07-06 17:20:54 +02002641 goto out_free_iova;
2642 }
2643 }
2644
2645out_free_iova:
Jerry Snitselaar8a6c9f62019-01-17 12:29:02 -07002646 free_iova_fast(&dma_dom->iovad, address >> PAGE_SHIFT, npages);
Joerg Roedel80187fd2016-07-06 17:20:54 +02002647
2648out_err:
Joerg Roedel92d420e2015-12-21 19:31:33 +01002649 return 0;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002650}
2651
Joerg Roedel431b2a22008-07-11 17:14:22 +02002652/*
2653 * The exported map_sg function for dma_ops (handles scatter-gather
2654 * lists).
2655 */
Joerg Roedel65b050a2008-06-26 21:28:02 +02002656static void unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonori160c1d82009-01-05 23:59:02 +09002657 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002658 unsigned long attrs)
Joerg Roedel65b050a2008-06-26 21:28:02 +02002659{
Joerg Roedel65b050a2008-06-26 21:28:02 +02002660 struct protection_domain *domain;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002661 struct dma_ops_domain *dma_dom;
Joerg Roedel80187fd2016-07-06 17:20:54 +02002662 unsigned long startaddr;
2663 int npages = 2;
Joerg Roedel65b050a2008-06-26 21:28:02 +02002664
Joerg Roedel94f6d192009-11-24 16:40:02 +01002665 domain = get_domain(dev);
2666 if (IS_ERR(domain))
Joerg Roedel5b28df62008-12-02 17:49:42 +01002667 return;
2668
Joerg Roedel80187fd2016-07-06 17:20:54 +02002669 startaddr = sg_dma_address(sglist) & PAGE_MASK;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002670 dma_dom = to_dma_ops_domain(domain);
Joerg Roedel80187fd2016-07-06 17:20:54 +02002671 npages = sg_num_pages(dev, sglist, nelems);
2672
Joerg Roedelb3311b02016-07-08 13:31:31 +02002673 __unmap_single(dma_dom, startaddr, npages << PAGE_SHIFT, dir);
Joerg Roedel65b050a2008-06-26 21:28:02 +02002674}
2675
Joerg Roedel431b2a22008-07-11 17:14:22 +02002676/*
2677 * The exported alloc_coherent function for dma_ops.
2678 */
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002679static void *alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02002680 dma_addr_t *dma_addr, gfp_t flag,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002681 unsigned long attrs)
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002682{
Joerg Roedel832a90c2008-09-18 15:54:23 +02002683 u64 dma_mask = dev->coherent_dma_mask;
Joerg Roedel3b839a52015-04-01 14:58:47 +02002684 struct protection_domain *domain;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002685 struct dma_ops_domain *dma_dom;
Joerg Roedel3b839a52015-04-01 14:58:47 +02002686 struct page *page;
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002687
Joerg Roedel94f6d192009-11-24 16:40:02 +01002688 domain = get_domain(dev);
2689 if (PTR_ERR(domain) == -EINVAL) {
Joerg Roedel3b839a52015-04-01 14:58:47 +02002690 page = alloc_pages(flag, get_order(size));
2691 *dma_addr = page_to_phys(page);
2692 return page_address(page);
Joerg Roedel94f6d192009-11-24 16:40:02 +01002693 } else if (IS_ERR(domain))
2694 return NULL;
Joerg Roedeldbcc1122008-09-04 15:04:26 +02002695
Joerg Roedelb3311b02016-07-08 13:31:31 +02002696 dma_dom = to_dma_ops_domain(domain);
Joerg Roedel3b839a52015-04-01 14:58:47 +02002697 size = PAGE_ALIGN(size);
Joerg Roedelf99c0f12009-11-23 16:52:56 +01002698 dma_mask = dev->coherent_dma_mask;
2699 flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
Joerg Roedel2d0ec7a2015-06-01 17:30:57 +02002700 flag |= __GFP_ZERO;
FUJITA Tomonori13d9fea2008-09-10 20:19:40 +09002701
Joerg Roedel3b839a52015-04-01 14:58:47 +02002702 page = alloc_pages(flag | __GFP_NOWARN, get_order(size));
2703 if (!page) {
Mel Gormand0164ad2015-11-06 16:28:21 -08002704 if (!gfpflags_allow_blocking(flag))
Joerg Roedel3b839a52015-04-01 14:58:47 +02002705 return NULL;
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002706
Joerg Roedel3b839a52015-04-01 14:58:47 +02002707 page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
2708 get_order(size));
2709 if (!page)
2710 return NULL;
2711 }
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002712
Joerg Roedel832a90c2008-09-18 15:54:23 +02002713 if (!dma_mask)
2714 dma_mask = *dev->dma_mask;
2715
Joerg Roedelb3311b02016-07-08 13:31:31 +02002716 *dma_addr = __map_single(dev, dma_dom, page_to_phys(page),
Joerg Roedelbda350d2016-07-05 16:28:02 +02002717 size, DMA_BIDIRECTIONAL, dma_mask);
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002718
Joerg Roedel92d420e2015-12-21 19:31:33 +01002719 if (*dma_addr == DMA_ERROR_CODE)
Joerg Roedel5b28df62008-12-02 17:49:42 +01002720 goto out_free;
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002721
Joerg Roedel3b839a52015-04-01 14:58:47 +02002722 return page_address(page);
Joerg Roedel5b28df62008-12-02 17:49:42 +01002723
2724out_free:
2725
Joerg Roedel3b839a52015-04-01 14:58:47 +02002726 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
2727 __free_pages(page, get_order(size));
Joerg Roedel5b28df62008-12-02 17:49:42 +01002728
2729 return NULL;
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002730}
2731
Joerg Roedel431b2a22008-07-11 17:14:22 +02002732/*
2733 * The exported free_coherent function for dma_ops.
Joerg Roedel431b2a22008-07-11 17:14:22 +02002734 */
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002735static void free_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02002736 void *virt_addr, dma_addr_t dma_addr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07002737 unsigned long attrs)
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002738{
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002739 struct protection_domain *domain;
Joerg Roedelb3311b02016-07-08 13:31:31 +02002740 struct dma_ops_domain *dma_dom;
Joerg Roedel3b839a52015-04-01 14:58:47 +02002741 struct page *page;
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002742
Joerg Roedel3b839a52015-04-01 14:58:47 +02002743 page = virt_to_page(virt_addr);
2744 size = PAGE_ALIGN(size);
2745
Joerg Roedel94f6d192009-11-24 16:40:02 +01002746 domain = get_domain(dev);
2747 if (IS_ERR(domain))
Joerg Roedel5b28df62008-12-02 17:49:42 +01002748 goto free_mem;
2749
Joerg Roedelb3311b02016-07-08 13:31:31 +02002750 dma_dom = to_dma_ops_domain(domain);
2751
2752 __unmap_single(dma_dom, dma_addr, size, DMA_BIDIRECTIONAL);
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002753
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002754free_mem:
Joerg Roedel3b839a52015-04-01 14:58:47 +02002755 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
2756 __free_pages(page, get_order(size));
Joerg Roedel5d8b53c2008-06-26 21:28:03 +02002757}
2758
Joerg Roedelc432f3d2008-06-26 21:28:04 +02002759/*
Joerg Roedelb39ba6a2008-09-09 18:40:46 +02002760 * This function is called by the DMA layer to find out if we can handle a
2761 * particular device. It is part of the dma_ops.
2762 */
2763static int amd_iommu_dma_supported(struct device *dev, u64 mask)
2764{
Joerg Roedel420aef82009-11-23 16:14:57 +01002765 return check_device(dev);
Joerg Roedelb39ba6a2008-09-09 18:40:46 +02002766}
2767
FUJITA Tomonori160c1d82009-01-05 23:59:02 +09002768static struct dma_map_ops amd_iommu_dma_ops = {
Joerg Roedela639a8e2015-12-22 16:06:49 +01002769 .alloc = alloc_coherent,
2770 .free = free_coherent,
2771 .map_page = map_page,
2772 .unmap_page = unmap_page,
2773 .map_sg = map_sg,
2774 .unmap_sg = unmap_sg,
2775 .dma_supported = amd_iommu_dma_supported,
Joerg Roedel6631ee92008-06-26 21:28:05 +02002776};
2777
Joerg Roedel81cd07b2016-07-07 18:01:10 +02002778static int init_reserved_iova_ranges(void)
2779{
2780 struct pci_dev *pdev = NULL;
2781 struct iova *val;
2782
2783 init_iova_domain(&reserved_iova_ranges, PAGE_SIZE,
2784 IOVA_START_PFN, DMA_32BIT_PFN);
2785
2786 lockdep_set_class(&reserved_iova_ranges.iova_rbtree_lock,
2787 &reserved_rbtree_key);
2788
2789 /* MSI memory range */
2790 val = reserve_iova(&reserved_iova_ranges,
2791 IOVA_PFN(MSI_RANGE_START), IOVA_PFN(MSI_RANGE_END));
2792 if (!val) {
2793 pr_err("Reserving MSI range failed\n");
2794 return -ENOMEM;
2795 }
2796
2797 /* HT memory range */
2798 val = reserve_iova(&reserved_iova_ranges,
2799 IOVA_PFN(HT_RANGE_START), IOVA_PFN(HT_RANGE_END));
2800 if (!val) {
2801 pr_err("Reserving HT range failed\n");
2802 return -ENOMEM;
2803 }
2804
2805 /*
2806 * Memory used for PCI resources
2807 * FIXME: Check whether we can reserve the PCI-hole completly
2808 */
2809 for_each_pci_dev(pdev) {
2810 int i;
2811
2812 for (i = 0; i < PCI_NUM_RESOURCES; ++i) {
2813 struct resource *r = &pdev->resource[i];
2814
2815 if (!(r->flags & IORESOURCE_MEM))
2816 continue;
2817
2818 val = reserve_iova(&reserved_iova_ranges,
2819 IOVA_PFN(r->start),
2820 IOVA_PFN(r->end));
2821 if (!val) {
2822 pr_err("Reserve pci-resource range failed\n");
2823 return -ENOMEM;
2824 }
2825 }
2826 }
2827
2828 return 0;
2829}
2830
Joerg Roedel3a18404c2015-05-28 18:41:45 +02002831int __init amd_iommu_init_api(void)
Joerg Roedel27c21272011-05-30 15:56:24 +02002832{
Joerg Roedelc5b5da92016-07-06 11:55:37 +02002833 int ret, cpu, err = 0;
Joerg Roedel307d5852016-07-05 11:54:04 +02002834
2835 ret = iova_cache_get();
2836 if (ret)
2837 return ret;
Wan Zongshun9a4d3bf52016-04-01 09:06:05 -04002838
Joerg Roedel81cd07b2016-07-07 18:01:10 +02002839 ret = init_reserved_iova_ranges();
2840 if (ret)
2841 return ret;
2842
Joerg Roedelc5b5da92016-07-06 11:55:37 +02002843 for_each_possible_cpu(cpu) {
2844 struct flush_queue *queue = per_cpu_ptr(&flush_queue, cpu);
2845
2846 queue->entries = kzalloc(FLUSH_QUEUE_SIZE *
2847 sizeof(*queue->entries),
2848 GFP_KERNEL);
2849 if (!queue->entries)
2850 goto out_put_iova;
2851
2852 spin_lock_init(&queue->lock);
2853 }
2854
Wan Zongshun9a4d3bf52016-04-01 09:06:05 -04002855 err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops);
2856 if (err)
2857 return err;
2858#ifdef CONFIG_ARM_AMBA
2859 err = bus_set_iommu(&amba_bustype, &amd_iommu_ops);
2860 if (err)
2861 return err;
2862#endif
Wan Zongshun0076cd32016-05-10 09:21:01 -04002863 err = bus_set_iommu(&platform_bus_type, &amd_iommu_ops);
2864 if (err)
2865 return err;
Wan Zongshun9a4d3bf52016-04-01 09:06:05 -04002866 return 0;
Joerg Roedelc5b5da92016-07-06 11:55:37 +02002867
2868out_put_iova:
2869 for_each_possible_cpu(cpu) {
2870 struct flush_queue *queue = per_cpu_ptr(&flush_queue, cpu);
2871
2872 kfree(queue->entries);
2873 }
2874
2875 return -ENOMEM;
Joerg Roedelf5325092010-01-22 17:44:35 +01002876}
2877
Joerg Roedel6631ee92008-06-26 21:28:05 +02002878int __init amd_iommu_init_dma_ops(void)
2879{
Joerg Roedelbb279472016-07-06 13:56:36 +02002880 setup_timer(&queue_timer, queue_flush_timeout, 0);
2881 atomic_set(&queue_timer_on, 0);
2882
Joerg Roedel32302322015-07-28 16:58:50 +02002883 swiotlb = iommu_pass_through ? 1 : 0;
Joerg Roedel6631ee92008-06-26 21:28:05 +02002884 iommu_detected = 1;
Joerg Roedel6631ee92008-06-26 21:28:05 +02002885
Joerg Roedel52717822015-07-28 16:58:51 +02002886 /*
2887 * In case we don't initialize SWIOTLB (actually the common case
2888 * when AMD IOMMU is enabled), make sure there are global
2889 * dma_ops set as a fall-back for devices not handled by this
2890 * driver (for example non-PCI devices).
2891 */
2892 if (!swiotlb)
2893 dma_ops = &nommu_dma_ops;
2894
Joerg Roedel62410ee2012-06-12 16:42:43 +02002895 if (amd_iommu_unmap_flush)
2896 pr_info("AMD-Vi: IO/TLB flush on unmap enabled\n");
2897 else
2898 pr_info("AMD-Vi: Lazy IO/TLB flushing enabled\n");
2899
Joerg Roedel6631ee92008-06-26 21:28:05 +02002900 return 0;
Joerg Roedelc5b5da92016-07-06 11:55:37 +02002901
Joerg Roedel6631ee92008-06-26 21:28:05 +02002902}
Joerg Roedel6d98cd82008-12-08 12:05:55 +01002903
2904/*****************************************************************************
2905 *
2906 * The following functions belong to the exported interface of AMD IOMMU
2907 *
2908 * This interface allows access to lower level functions of the IOMMU
2909 * like protection domain handling and assignement of devices to domains
2910 * which is not possible with the dma_ops interface.
2911 *
2912 *****************************************************************************/
2913
Joerg Roedel6d98cd82008-12-08 12:05:55 +01002914static void cleanup_domain(struct protection_domain *domain)
2915{
Joerg Roedel9b29d3c2014-08-05 17:50:15 +02002916 struct iommu_dev_data *entry;
Joerg Roedel6d98cd82008-12-08 12:05:55 +01002917 unsigned long flags;
Joerg Roedel6d98cd82008-12-08 12:05:55 +01002918
2919 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
2920
Joerg Roedel9b29d3c2014-08-05 17:50:15 +02002921 while (!list_empty(&domain->dev_list)) {
2922 entry = list_first_entry(&domain->dev_list,
2923 struct iommu_dev_data, list);
2924 __detach_device(entry);
Joerg Roedel492667d2009-11-27 13:25:47 +01002925 }
Joerg Roedel6d98cd82008-12-08 12:05:55 +01002926
2927 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
2928}
2929
Joerg Roedel26508152009-08-26 16:52:40 +02002930static void protection_domain_free(struct protection_domain *domain)
2931{
2932 if (!domain)
2933 return;
2934
Joerg Roedelaeb26f52009-11-20 16:44:01 +01002935 del_domain_from_list(domain);
2936
Joerg Roedel26508152009-08-26 16:52:40 +02002937 if (domain->id)
2938 domain_id_free(domain->id);
2939
2940 kfree(domain);
2941}
2942
Joerg Roedel7a5a5662015-06-30 08:56:11 +02002943static int protection_domain_init(struct protection_domain *domain)
2944{
2945 spin_lock_init(&domain->lock);
2946 mutex_init(&domain->api_lock);
2947 domain->id = domain_id_alloc();
2948 if (!domain->id)
2949 return -ENOMEM;
2950 INIT_LIST_HEAD(&domain->dev_list);
2951
2952 return 0;
2953}
2954
Joerg Roedel26508152009-08-26 16:52:40 +02002955static struct protection_domain *protection_domain_alloc(void)
Joerg Roedelc156e342008-12-02 18:13:27 +01002956{
2957 struct protection_domain *domain;
2958
2959 domain = kzalloc(sizeof(*domain), GFP_KERNEL);
2960 if (!domain)
Joerg Roedel26508152009-08-26 16:52:40 +02002961 return NULL;
Joerg Roedelc156e342008-12-02 18:13:27 +01002962
Joerg Roedel7a5a5662015-06-30 08:56:11 +02002963 if (protection_domain_init(domain))
Joerg Roedel26508152009-08-26 16:52:40 +02002964 goto out_err;
2965
Joerg Roedelaeb26f52009-11-20 16:44:01 +01002966 add_domain_to_list(domain);
2967
Joerg Roedel26508152009-08-26 16:52:40 +02002968 return domain;
2969
2970out_err:
2971 kfree(domain);
2972
2973 return NULL;
2974}
2975
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01002976static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
2977{
2978 struct protection_domain *pdomain;
Joerg Roedel0bb6e242015-05-28 18:41:40 +02002979 struct dma_ops_domain *dma_domain;
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01002980
Joerg Roedel0bb6e242015-05-28 18:41:40 +02002981 switch (type) {
2982 case IOMMU_DOMAIN_UNMANAGED:
2983 pdomain = protection_domain_alloc();
2984 if (!pdomain)
2985 return NULL;
2986
2987 pdomain->mode = PAGE_MODE_3_LEVEL;
2988 pdomain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);
2989 if (!pdomain->pt_root) {
2990 protection_domain_free(pdomain);
2991 return NULL;
2992 }
2993
2994 pdomain->domain.geometry.aperture_start = 0;
2995 pdomain->domain.geometry.aperture_end = ~0ULL;
2996 pdomain->domain.geometry.force_aperture = true;
2997
2998 break;
2999 case IOMMU_DOMAIN_DMA:
3000 dma_domain = dma_ops_domain_alloc();
3001 if (!dma_domain) {
3002 pr_err("AMD-Vi: Failed to allocate\n");
3003 return NULL;
3004 }
3005 pdomain = &dma_domain->domain;
3006 break;
Joerg Roedel07f643a2015-05-28 18:41:41 +02003007 case IOMMU_DOMAIN_IDENTITY:
3008 pdomain = protection_domain_alloc();
3009 if (!pdomain)
3010 return NULL;
3011
3012 pdomain->mode = PAGE_MODE_NONE;
3013 break;
Joerg Roedel0bb6e242015-05-28 18:41:40 +02003014 default:
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003015 return NULL;
Joerg Roedel0bb6e242015-05-28 18:41:40 +02003016 }
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003017
3018 return &pdomain->domain;
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003019}
3020
3021static void amd_iommu_domain_free(struct iommu_domain *dom)
Joerg Roedel26508152009-08-26 16:52:40 +02003022{
3023 struct protection_domain *domain;
Joerg Roedelcda70052016-07-07 15:57:04 +02003024 struct dma_ops_domain *dma_dom;
Joerg Roedel98383fc2008-12-02 18:34:12 +01003025
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003026 domain = to_pdomain(dom);
3027
Joerg Roedel98383fc2008-12-02 18:34:12 +01003028 if (domain->dev_cnt > 0)
3029 cleanup_domain(domain);
3030
3031 BUG_ON(domain->dev_cnt != 0);
3032
Joerg Roedelcda70052016-07-07 15:57:04 +02003033 if (!dom)
3034 return;
Joerg Roedel98383fc2008-12-02 18:34:12 +01003035
Joerg Roedelcda70052016-07-07 15:57:04 +02003036 switch (dom->type) {
3037 case IOMMU_DOMAIN_DMA:
Joerg Roedel281e8cc2016-07-07 16:12:02 +02003038 /*
3039 * First make sure the domain is no longer referenced from the
3040 * flush queue
3041 */
3042 queue_flush_all();
3043
3044 /* Now release the domain */
Joerg Roedelb3311b02016-07-08 13:31:31 +02003045 dma_dom = to_dma_ops_domain(domain);
Joerg Roedelcda70052016-07-07 15:57:04 +02003046 dma_ops_domain_free(dma_dom);
3047 break;
3048 default:
3049 if (domain->mode != PAGE_MODE_NONE)
3050 free_pagetable(domain);
Joerg Roedel52815b72011-11-17 17:24:28 +01003051
Joerg Roedelcda70052016-07-07 15:57:04 +02003052 if (domain->flags & PD_IOMMUV2_MASK)
3053 free_gcr3_table(domain);
3054
3055 protection_domain_free(domain);
3056 break;
3057 }
Joerg Roedel98383fc2008-12-02 18:34:12 +01003058}
3059
Joerg Roedel684f2882008-12-08 12:07:44 +01003060static void amd_iommu_detach_device(struct iommu_domain *dom,
3061 struct device *dev)
3062{
Joerg Roedel657cbb62009-11-23 15:26:46 +01003063 struct iommu_dev_data *dev_data = dev->archdata.iommu;
Joerg Roedel684f2882008-12-08 12:07:44 +01003064 struct amd_iommu *iommu;
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04003065 int devid;
Joerg Roedel684f2882008-12-08 12:07:44 +01003066
Joerg Roedel98fc5a62009-11-24 17:19:23 +01003067 if (!check_device(dev))
Joerg Roedel684f2882008-12-08 12:07:44 +01003068 return;
3069
Joerg Roedel98fc5a62009-11-24 17:19:23 +01003070 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +02003071 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04003072 return;
Joerg Roedel684f2882008-12-08 12:07:44 +01003073
Joerg Roedel657cbb62009-11-23 15:26:46 +01003074 if (dev_data->domain != NULL)
Joerg Roedel15898bb2009-11-24 15:39:42 +01003075 detach_device(dev);
Joerg Roedel684f2882008-12-08 12:07:44 +01003076
3077 iommu = amd_iommu_rlookup_table[devid];
3078 if (!iommu)
3079 return;
3080
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003081#ifdef CONFIG_IRQ_REMAP
3082 if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) &&
3083 (dom->type == IOMMU_DOMAIN_UNMANAGED))
3084 dev_data->use_vapic = 0;
3085#endif
3086
Joerg Roedel684f2882008-12-08 12:07:44 +01003087 iommu_completion_wait(iommu);
3088}
3089
Joerg Roedel01106062008-12-02 19:34:11 +01003090static int amd_iommu_attach_device(struct iommu_domain *dom,
3091 struct device *dev)
3092{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003093 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel657cbb62009-11-23 15:26:46 +01003094 struct iommu_dev_data *dev_data;
Joerg Roedel01106062008-12-02 19:34:11 +01003095 struct amd_iommu *iommu;
Joerg Roedel15898bb2009-11-24 15:39:42 +01003096 int ret;
Joerg Roedel01106062008-12-02 19:34:11 +01003097
Joerg Roedel98fc5a62009-11-24 17:19:23 +01003098 if (!check_device(dev))
Joerg Roedel01106062008-12-02 19:34:11 +01003099 return -EINVAL;
3100
Joerg Roedel657cbb62009-11-23 15:26:46 +01003101 dev_data = dev->archdata.iommu;
3102
Joerg Roedelf62dda62011-06-09 12:55:35 +02003103 iommu = amd_iommu_rlookup_table[dev_data->devid];
Joerg Roedel01106062008-12-02 19:34:11 +01003104 if (!iommu)
3105 return -EINVAL;
3106
Joerg Roedel657cbb62009-11-23 15:26:46 +01003107 if (dev_data->domain)
Joerg Roedel15898bb2009-11-24 15:39:42 +01003108 detach_device(dev);
Joerg Roedel01106062008-12-02 19:34:11 +01003109
Joerg Roedel15898bb2009-11-24 15:39:42 +01003110 ret = attach_device(dev, domain);
Joerg Roedel01106062008-12-02 19:34:11 +01003111
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003112#ifdef CONFIG_IRQ_REMAP
3113 if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) {
3114 if (dom->type == IOMMU_DOMAIN_UNMANAGED)
3115 dev_data->use_vapic = 1;
3116 else
3117 dev_data->use_vapic = 0;
3118 }
3119#endif
3120
Joerg Roedel01106062008-12-02 19:34:11 +01003121 iommu_completion_wait(iommu);
3122
Joerg Roedel15898bb2009-11-24 15:39:42 +01003123 return ret;
Joerg Roedel01106062008-12-02 19:34:11 +01003124}
3125
Joerg Roedel468e2362010-01-21 16:37:36 +01003126static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02003127 phys_addr_t paddr, size_t page_size, int iommu_prot)
Joerg Roedelc6229ca2008-12-02 19:48:43 +01003128{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003129 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedelc6229ca2008-12-02 19:48:43 +01003130 int prot = 0;
3131 int ret;
3132
Joerg Roedel132bd682011-11-17 14:18:46 +01003133 if (domain->mode == PAGE_MODE_NONE)
3134 return -EINVAL;
3135
Joerg Roedelc6229ca2008-12-02 19:48:43 +01003136 if (iommu_prot & IOMMU_READ)
3137 prot |= IOMMU_PROT_IR;
3138 if (iommu_prot & IOMMU_WRITE)
3139 prot |= IOMMU_PROT_IW;
3140
Joerg Roedel5d214fe2010-02-08 14:44:49 +01003141 mutex_lock(&domain->api_lock);
Joerg Roedelb911b892016-07-05 14:29:11 +02003142 ret = iommu_map_page(domain, iova, paddr, page_size, prot, GFP_KERNEL);
Joerg Roedel5d214fe2010-02-08 14:44:49 +01003143 mutex_unlock(&domain->api_lock);
3144
Joerg Roedel795e74f2010-05-11 17:40:57 +02003145 return ret;
Joerg Roedelc6229ca2008-12-02 19:48:43 +01003146}
3147
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02003148static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
3149 size_t page_size)
Joerg Roedeleb74ff62008-12-02 19:59:10 +01003150{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003151 struct protection_domain *domain = to_pdomain(dom);
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02003152 size_t unmap_size;
Joerg Roedeleb74ff62008-12-02 19:59:10 +01003153
Joerg Roedel132bd682011-11-17 14:18:46 +01003154 if (domain->mode == PAGE_MODE_NONE)
3155 return -EINVAL;
3156
Joerg Roedel5d214fe2010-02-08 14:44:49 +01003157 mutex_lock(&domain->api_lock);
Joerg Roedel468e2362010-01-21 16:37:36 +01003158 unmap_size = iommu_unmap_page(domain, iova, page_size);
Joerg Roedel795e74f2010-05-11 17:40:57 +02003159 mutex_unlock(&domain->api_lock);
Joerg Roedeleb74ff62008-12-02 19:59:10 +01003160
Joerg Roedel17b124b2011-04-06 18:01:35 +02003161 domain_flush_tlb_pde(domain);
Joerg Roedel3abebf02017-10-13 14:32:37 +02003162 domain_flush_complete(domain);
Joerg Roedel5d214fe2010-02-08 14:44:49 +01003163
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02003164 return unmap_size;
Joerg Roedeleb74ff62008-12-02 19:59:10 +01003165}
3166
Joerg Roedel645c4c82008-12-02 20:05:50 +01003167static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
Varun Sethibb5547ac2013-03-29 01:23:58 +05303168 dma_addr_t iova)
Joerg Roedel645c4c82008-12-02 20:05:50 +01003169{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003170 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel3039ca12015-04-01 14:58:48 +02003171 unsigned long offset_mask, pte_pgsize;
Joerg Roedelf03152b2010-01-21 16:15:24 +01003172 u64 *pte, __pte;
Joerg Roedel645c4c82008-12-02 20:05:50 +01003173
Joerg Roedel132bd682011-11-17 14:18:46 +01003174 if (domain->mode == PAGE_MODE_NONE)
3175 return iova;
3176
Joerg Roedel3039ca12015-04-01 14:58:48 +02003177 pte = fetch_pte(domain, iova, &pte_pgsize);
Joerg Roedel645c4c82008-12-02 20:05:50 +01003178
Joerg Roedela6d41a42009-09-02 17:08:55 +02003179 if (!pte || !IOMMU_PTE_PRESENT(*pte))
Joerg Roedel645c4c82008-12-02 20:05:50 +01003180 return 0;
3181
Joerg Roedelb24b1b62015-04-01 14:58:51 +02003182 offset_mask = pte_pgsize - 1;
3183 __pte = *pte & PM_ADDR_MASK;
Joerg Roedelf03152b2010-01-21 16:15:24 +01003184
Joerg Roedelb24b1b62015-04-01 14:58:51 +02003185 return (__pte & ~offset_mask) | (iova & offset_mask);
Joerg Roedel645c4c82008-12-02 20:05:50 +01003186}
3187
Joerg Roedelab636482014-09-05 10:48:21 +02003188static bool amd_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08003189{
Joerg Roedel80a506b2010-07-27 17:14:24 +02003190 switch (cap) {
3191 case IOMMU_CAP_CACHE_COHERENCY:
Joerg Roedelab636482014-09-05 10:48:21 +02003192 return true;
Joerg Roedelbdddadc2012-07-02 18:38:13 +02003193 case IOMMU_CAP_INTR_REMAP:
Joerg Roedelab636482014-09-05 10:48:21 +02003194 return (irq_remapping_enabled == 1);
Will Deaconcfdeec22014-10-27 11:24:48 +00003195 case IOMMU_CAP_NOEXEC:
3196 return false;
Joerg Roedel80a506b2010-07-27 17:14:24 +02003197 }
3198
Joerg Roedelab636482014-09-05 10:48:21 +02003199 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08003200}
3201
Joerg Roedel35cf2482015-05-28 18:41:37 +02003202static void amd_iommu_get_dm_regions(struct device *dev,
3203 struct list_head *head)
3204{
3205 struct unity_map_entry *entry;
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04003206 int devid;
Joerg Roedel35cf2482015-05-28 18:41:37 +02003207
3208 devid = get_device_id(dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +02003209 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04003210 return;
Joerg Roedel35cf2482015-05-28 18:41:37 +02003211
3212 list_for_each_entry(entry, &amd_iommu_unity_map, list) {
3213 struct iommu_dm_region *region;
3214
3215 if (devid < entry->devid_start || devid > entry->devid_end)
3216 continue;
3217
3218 region = kzalloc(sizeof(*region), GFP_KERNEL);
3219 if (!region) {
3220 pr_err("Out of memory allocating dm-regions for %s\n",
3221 dev_name(dev));
3222 return;
3223 }
3224
3225 region->start = entry->address_start;
3226 region->length = entry->address_end - entry->address_start;
3227 if (entry->prot & IOMMU_PROT_IR)
3228 region->prot |= IOMMU_READ;
3229 if (entry->prot & IOMMU_PROT_IW)
3230 region->prot |= IOMMU_WRITE;
3231
3232 list_add_tail(&region->list, head);
3233 }
3234}
3235
3236static void amd_iommu_put_dm_regions(struct device *dev,
3237 struct list_head *head)
3238{
3239 struct iommu_dm_region *entry, *next;
3240
3241 list_for_each_entry_safe(entry, next, head, list)
3242 kfree(entry);
3243}
3244
Joerg Roedel8d54d6c2016-07-05 13:32:20 +02003245static void amd_iommu_apply_dm_region(struct device *dev,
3246 struct iommu_domain *domain,
3247 struct iommu_dm_region *region)
3248{
Joerg Roedelb3311b02016-07-08 13:31:31 +02003249 struct dma_ops_domain *dma_dom = to_dma_ops_domain(to_pdomain(domain));
Joerg Roedel8d54d6c2016-07-05 13:32:20 +02003250 unsigned long start, end;
3251
3252 start = IOVA_PFN(region->start);
Gary R Hook03bfadf2017-11-03 10:50:34 -06003253 end = IOVA_PFN(region->start + region->length - 1);
Joerg Roedel8d54d6c2016-07-05 13:32:20 +02003254
3255 WARN_ON_ONCE(reserve_iova(&dma_dom->iovad, start, end) == NULL);
3256}
3257
Thierry Redingb22f6432014-06-27 09:03:12 +02003258static const struct iommu_ops amd_iommu_ops = {
Joerg Roedelab636482014-09-05 10:48:21 +02003259 .capable = amd_iommu_capable,
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003260 .domain_alloc = amd_iommu_domain_alloc,
3261 .domain_free = amd_iommu_domain_free,
Joerg Roedel26961ef2008-12-03 17:00:17 +01003262 .attach_dev = amd_iommu_attach_device,
3263 .detach_dev = amd_iommu_detach_device,
Joerg Roedel468e2362010-01-21 16:37:36 +01003264 .map = amd_iommu_map,
3265 .unmap = amd_iommu_unmap,
Olav Haugan315786e2014-10-25 09:55:16 -07003266 .map_sg = default_iommu_map_sg,
Joerg Roedel26961ef2008-12-03 17:00:17 +01003267 .iova_to_phys = amd_iommu_iova_to_phys,
Joerg Roedelaafd8ba2015-05-28 18:41:39 +02003268 .add_device = amd_iommu_add_device,
3269 .remove_device = amd_iommu_remove_device,
Wan Zongshunb097d112016-04-01 09:06:04 -04003270 .device_group = amd_iommu_device_group,
Joerg Roedel35cf2482015-05-28 18:41:37 +02003271 .get_dm_regions = amd_iommu_get_dm_regions,
3272 .put_dm_regions = amd_iommu_put_dm_regions,
Joerg Roedel8d54d6c2016-07-05 13:32:20 +02003273 .apply_dm_region = amd_iommu_apply_dm_region,
Ohad Ben-Cohenaa3de9c2011-11-10 11:32:29 +02003274 .pgsize_bitmap = AMD_IOMMU_PGSIZES,
Joerg Roedel26961ef2008-12-03 17:00:17 +01003275};
3276
Joerg Roedel0feae532009-08-26 15:26:30 +02003277/*****************************************************************************
3278 *
3279 * The next functions do a basic initialization of IOMMU for pass through
3280 * mode
3281 *
3282 * In passthrough mode the IOMMU is initialized and enabled but not used for
3283 * DMA-API translation.
3284 *
3285 *****************************************************************************/
3286
Joerg Roedel72e1dcc2011-11-10 19:13:51 +01003287/* IOMMUv2 specific functions */
3288int amd_iommu_register_ppr_notifier(struct notifier_block *nb)
3289{
3290 return atomic_notifier_chain_register(&ppr_notifier, nb);
3291}
3292EXPORT_SYMBOL(amd_iommu_register_ppr_notifier);
3293
3294int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb)
3295{
3296 return atomic_notifier_chain_unregister(&ppr_notifier, nb);
3297}
3298EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier);
Joerg Roedel132bd682011-11-17 14:18:46 +01003299
3300void amd_iommu_domain_direct_map(struct iommu_domain *dom)
3301{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003302 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel132bd682011-11-17 14:18:46 +01003303 unsigned long flags;
3304
3305 spin_lock_irqsave(&domain->lock, flags);
3306
3307 /* Update data structure */
3308 domain->mode = PAGE_MODE_NONE;
3309 domain->updated = true;
3310
3311 /* Make changes visible to IOMMUs */
3312 update_domain(domain);
3313
3314 /* Page-table is not visible to IOMMU anymore, so free it */
3315 free_pagetable(domain);
3316
3317 spin_unlock_irqrestore(&domain->lock, flags);
3318}
3319EXPORT_SYMBOL(amd_iommu_domain_direct_map);
Joerg Roedel52815b72011-11-17 17:24:28 +01003320
3321int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
3322{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003323 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel52815b72011-11-17 17:24:28 +01003324 unsigned long flags;
3325 int levels, ret;
3326
3327 if (pasids <= 0 || pasids > (PASID_MASK + 1))
3328 return -EINVAL;
3329
3330 /* Number of GCR3 table levels required */
3331 for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9)
3332 levels += 1;
3333
3334 if (levels > amd_iommu_max_glx_val)
3335 return -EINVAL;
3336
3337 spin_lock_irqsave(&domain->lock, flags);
3338
3339 /*
3340 * Save us all sanity checks whether devices already in the
3341 * domain support IOMMUv2. Just force that the domain has no
3342 * devices attached when it is switched into IOMMUv2 mode.
3343 */
3344 ret = -EBUSY;
3345 if (domain->dev_cnt > 0 || domain->flags & PD_IOMMUV2_MASK)
3346 goto out;
3347
3348 ret = -ENOMEM;
3349 domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC);
3350 if (domain->gcr3_tbl == NULL)
3351 goto out;
3352
3353 domain->glx = levels;
3354 domain->flags |= PD_IOMMUV2_MASK;
3355 domain->updated = true;
3356
3357 update_domain(domain);
3358
3359 ret = 0;
3360
3361out:
3362 spin_unlock_irqrestore(&domain->lock, flags);
3363
3364 return ret;
3365}
3366EXPORT_SYMBOL(amd_iommu_domain_enable_v2);
Joerg Roedel22e266c2011-11-21 15:59:08 +01003367
3368static int __flush_pasid(struct protection_domain *domain, int pasid,
3369 u64 address, bool size)
3370{
3371 struct iommu_dev_data *dev_data;
3372 struct iommu_cmd cmd;
3373 int i, ret;
3374
3375 if (!(domain->flags & PD_IOMMUV2_MASK))
3376 return -EINVAL;
3377
3378 build_inv_iommu_pasid(&cmd, domain->id, pasid, address, size);
3379
3380 /*
3381 * IOMMU TLB needs to be flushed before Device TLB to
3382 * prevent device TLB refill from IOMMU TLB
3383 */
3384 for (i = 0; i < amd_iommus_present; ++i) {
3385 if (domain->dev_iommu[i] == 0)
3386 continue;
3387
3388 ret = iommu_queue_command(amd_iommus[i], &cmd);
3389 if (ret != 0)
3390 goto out;
3391 }
3392
3393 /* Wait until IOMMU TLB flushes are complete */
3394 domain_flush_complete(domain);
3395
3396 /* Now flush device TLBs */
3397 list_for_each_entry(dev_data, &domain->dev_list, list) {
3398 struct amd_iommu *iommu;
3399 int qdep;
3400
Joerg Roedel1c1cc452015-07-30 11:24:45 +02003401 /*
3402 There might be non-IOMMUv2 capable devices in an IOMMUv2
3403 * domain.
3404 */
3405 if (!dev_data->ats.enabled)
3406 continue;
Joerg Roedel22e266c2011-11-21 15:59:08 +01003407
3408 qdep = dev_data->ats.qdep;
3409 iommu = amd_iommu_rlookup_table[dev_data->devid];
3410
3411 build_inv_iotlb_pasid(&cmd, dev_data->devid, pasid,
3412 qdep, address, size);
3413
3414 ret = iommu_queue_command(iommu, &cmd);
3415 if (ret != 0)
3416 goto out;
3417 }
3418
3419 /* Wait until all device TLBs are flushed */
3420 domain_flush_complete(domain);
3421
3422 ret = 0;
3423
3424out:
3425
3426 return ret;
3427}
3428
3429static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid,
3430 u64 address)
3431{
3432 return __flush_pasid(domain, pasid, address, false);
3433}
3434
3435int amd_iommu_flush_page(struct iommu_domain *dom, int pasid,
3436 u64 address)
3437{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003438 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel22e266c2011-11-21 15:59:08 +01003439 unsigned long flags;
3440 int ret;
3441
3442 spin_lock_irqsave(&domain->lock, flags);
3443 ret = __amd_iommu_flush_page(domain, pasid, address);
3444 spin_unlock_irqrestore(&domain->lock, flags);
3445
3446 return ret;
3447}
3448EXPORT_SYMBOL(amd_iommu_flush_page);
3449
3450static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid)
3451{
3452 return __flush_pasid(domain, pasid, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
3453 true);
3454}
3455
3456int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid)
3457{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003458 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedel22e266c2011-11-21 15:59:08 +01003459 unsigned long flags;
3460 int ret;
3461
3462 spin_lock_irqsave(&domain->lock, flags);
3463 ret = __amd_iommu_flush_tlb(domain, pasid);
3464 spin_unlock_irqrestore(&domain->lock, flags);
3465
3466 return ret;
3467}
3468EXPORT_SYMBOL(amd_iommu_flush_tlb);
3469
Joerg Roedelb16137b2011-11-21 16:50:23 +01003470static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc)
3471{
3472 int index;
3473 u64 *pte;
3474
3475 while (true) {
3476
3477 index = (pasid >> (9 * level)) & 0x1ff;
3478 pte = &root[index];
3479
3480 if (level == 0)
3481 break;
3482
3483 if (!(*pte & GCR3_VALID)) {
3484 if (!alloc)
3485 return NULL;
3486
3487 root = (void *)get_zeroed_page(GFP_ATOMIC);
3488 if (root == NULL)
3489 return NULL;
3490
3491 *pte = __pa(root) | GCR3_VALID;
3492 }
3493
3494 root = __va(*pte & PAGE_MASK);
3495
3496 level -= 1;
3497 }
3498
3499 return pte;
3500}
3501
3502static int __set_gcr3(struct protection_domain *domain, int pasid,
3503 unsigned long cr3)
3504{
3505 u64 *pte;
3506
3507 if (domain->mode != PAGE_MODE_NONE)
3508 return -EINVAL;
3509
3510 pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true);
3511 if (pte == NULL)
3512 return -ENOMEM;
3513
3514 *pte = (cr3 & PAGE_MASK) | GCR3_VALID;
3515
3516 return __amd_iommu_flush_tlb(domain, pasid);
3517}
3518
3519static int __clear_gcr3(struct protection_domain *domain, int pasid)
3520{
3521 u64 *pte;
3522
3523 if (domain->mode != PAGE_MODE_NONE)
3524 return -EINVAL;
3525
3526 pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false);
3527 if (pte == NULL)
3528 return 0;
3529
3530 *pte = 0;
3531
3532 return __amd_iommu_flush_tlb(domain, pasid);
3533}
3534
3535int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid,
3536 unsigned long cr3)
3537{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003538 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedelb16137b2011-11-21 16:50:23 +01003539 unsigned long flags;
3540 int ret;
3541
3542 spin_lock_irqsave(&domain->lock, flags);
3543 ret = __set_gcr3(domain, pasid, cr3);
3544 spin_unlock_irqrestore(&domain->lock, flags);
3545
3546 return ret;
3547}
3548EXPORT_SYMBOL(amd_iommu_domain_set_gcr3);
3549
3550int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid)
3551{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003552 struct protection_domain *domain = to_pdomain(dom);
Joerg Roedelb16137b2011-11-21 16:50:23 +01003553 unsigned long flags;
3554 int ret;
3555
3556 spin_lock_irqsave(&domain->lock, flags);
3557 ret = __clear_gcr3(domain, pasid);
3558 spin_unlock_irqrestore(&domain->lock, flags);
3559
3560 return ret;
3561}
3562EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3);
Joerg Roedelc99afa22011-11-21 18:19:25 +01003563
3564int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid,
3565 int status, int tag)
3566{
3567 struct iommu_dev_data *dev_data;
3568 struct amd_iommu *iommu;
3569 struct iommu_cmd cmd;
3570
3571 dev_data = get_dev_data(&pdev->dev);
3572 iommu = amd_iommu_rlookup_table[dev_data->devid];
3573
3574 build_complete_ppr(&cmd, dev_data->devid, pasid, status,
3575 tag, dev_data->pri_tlp);
3576
3577 return iommu_queue_command(iommu, &cmd);
3578}
3579EXPORT_SYMBOL(amd_iommu_complete_ppr);
Joerg Roedelf3572db2011-11-23 12:36:25 +01003580
3581struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev)
3582{
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003583 struct protection_domain *pdomain;
Joerg Roedelf3572db2011-11-23 12:36:25 +01003584
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003585 pdomain = get_domain(&pdev->dev);
3586 if (IS_ERR(pdomain))
Joerg Roedelf3572db2011-11-23 12:36:25 +01003587 return NULL;
3588
3589 /* Only return IOMMUv2 domains */
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003590 if (!(pdomain->flags & PD_IOMMUV2_MASK))
Joerg Roedelf3572db2011-11-23 12:36:25 +01003591 return NULL;
3592
Joerg Roedel3f4b87b2015-03-26 13:43:07 +01003593 return &pdomain->domain;
Joerg Roedelf3572db2011-11-23 12:36:25 +01003594}
3595EXPORT_SYMBOL(amd_iommu_get_v2_domain);
Joerg Roedel6a113dd2011-12-01 12:04:58 +01003596
3597void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum)
3598{
3599 struct iommu_dev_data *dev_data;
3600
3601 if (!amd_iommu_v2_supported())
3602 return;
3603
3604 dev_data = get_dev_data(&pdev->dev);
3605 dev_data->errata |= (1 << erratum);
3606}
3607EXPORT_SYMBOL(amd_iommu_enable_device_erratum);
Joerg Roedel52efdb82011-12-07 12:01:36 +01003608
3609int amd_iommu_device_info(struct pci_dev *pdev,
3610 struct amd_iommu_device_info *info)
3611{
3612 int max_pasids;
3613 int pos;
3614
3615 if (pdev == NULL || info == NULL)
3616 return -EINVAL;
3617
3618 if (!amd_iommu_v2_supported())
3619 return -EINVAL;
3620
3621 memset(info, 0, sizeof(*info));
3622
3623 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS);
3624 if (pos)
3625 info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP;
3626
3627 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
3628 if (pos)
3629 info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP;
3630
3631 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
3632 if (pos) {
3633 int features;
3634
3635 max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1));
3636 max_pasids = min(max_pasids, (1 << 20));
3637
3638 info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP;
3639 info->max_pasids = min(pci_max_pasids(pdev), max_pasids);
3640
3641 features = pci_pasid_features(pdev);
3642 if (features & PCI_PASID_CAP_EXEC)
3643 info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP;
3644 if (features & PCI_PASID_CAP_PRIV)
3645 info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP;
3646 }
3647
3648 return 0;
3649}
3650EXPORT_SYMBOL(amd_iommu_device_info);
Joerg Roedel2b324502012-06-21 16:29:10 +02003651
3652#ifdef CONFIG_IRQ_REMAP
3653
3654/*****************************************************************************
3655 *
3656 * Interrupt Remapping Implementation
3657 *
3658 *****************************************************************************/
3659
Jiang Liu7c71d302015-04-13 14:11:33 +08003660static struct irq_chip amd_ir_chip;
3661
Joerg Roedel2b324502012-06-21 16:29:10 +02003662#define DTE_IRQ_PHYS_ADDR_MASK (((1ULL << 45)-1) << 6)
3663#define DTE_IRQ_REMAP_INTCTL (2ULL << 60)
3664#define DTE_IRQ_TABLE_LEN (8ULL << 1)
3665#define DTE_IRQ_REMAP_ENABLE 1ULL
3666
3667static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
3668{
3669 u64 dte;
3670
3671 dte = amd_iommu_dev_table[devid].data[2];
3672 dte &= ~DTE_IRQ_PHYS_ADDR_MASK;
3673 dte |= virt_to_phys(table->table);
3674 dte |= DTE_IRQ_REMAP_INTCTL;
3675 dte |= DTE_IRQ_TABLE_LEN;
3676 dte |= DTE_IRQ_REMAP_ENABLE;
3677
3678 amd_iommu_dev_table[devid].data[2] = dte;
3679}
3680
Joerg Roedel2b324502012-06-21 16:29:10 +02003681static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
3682{
3683 struct irq_remap_table *table = NULL;
3684 struct amd_iommu *iommu;
3685 unsigned long flags;
3686 u16 alias;
3687
3688 write_lock_irqsave(&amd_iommu_devtable_lock, flags);
3689
3690 iommu = amd_iommu_rlookup_table[devid];
3691 if (!iommu)
3692 goto out_unlock;
3693
3694 table = irq_lookup_table[devid];
3695 if (table)
Baoquan He09284b92016-09-20 09:05:34 +08003696 goto out_unlock;
Joerg Roedel2b324502012-06-21 16:29:10 +02003697
3698 alias = amd_iommu_alias_table[devid];
3699 table = irq_lookup_table[alias];
3700 if (table) {
3701 irq_lookup_table[devid] = table;
3702 set_dte_irq_entry(devid, table);
3703 iommu_flush_dte(iommu, devid);
3704 goto out;
3705 }
3706
3707 /* Nothing there yet, allocate new irq remapping table */
3708 table = kzalloc(sizeof(*table), GFP_ATOMIC);
3709 if (!table)
Baoquan He09284b92016-09-20 09:05:34 +08003710 goto out_unlock;
Joerg Roedel2b324502012-06-21 16:29:10 +02003711
Joerg Roedel197887f2013-04-09 21:14:08 +02003712 /* Initialize table spin-lock */
3713 spin_lock_init(&table->lock);
3714
Joerg Roedel2b324502012-06-21 16:29:10 +02003715 if (ioapic)
3716 /* Keep the first 32 indexes free for IOAPIC interrupts */
3717 table->min_index = 32;
3718
3719 table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC);
3720 if (!table->table) {
3721 kfree(table);
Dan Carpenter821f0f62012-10-02 11:34:40 +03003722 table = NULL;
Baoquan He09284b92016-09-20 09:05:34 +08003723 goto out_unlock;
Joerg Roedel2b324502012-06-21 16:29:10 +02003724 }
3725
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003726 if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir))
3727 memset(table->table, 0,
3728 MAX_IRQS_PER_TABLE * sizeof(u32));
3729 else
3730 memset(table->table, 0,
3731 (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2)));
Joerg Roedel2b324502012-06-21 16:29:10 +02003732
3733 if (ioapic) {
3734 int i;
3735
3736 for (i = 0; i < 32; ++i)
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003737 iommu->irte_ops->set_allocated(table, i);
Joerg Roedel2b324502012-06-21 16:29:10 +02003738 }
3739
3740 irq_lookup_table[devid] = table;
3741 set_dte_irq_entry(devid, table);
3742 iommu_flush_dte(iommu, devid);
3743 if (devid != alias) {
3744 irq_lookup_table[alias] = table;
Alex Williamsone028a9e2014-04-22 10:08:40 -06003745 set_dte_irq_entry(alias, table);
Joerg Roedel2b324502012-06-21 16:29:10 +02003746 iommu_flush_dte(iommu, alias);
3747 }
3748
3749out:
3750 iommu_completion_wait(iommu);
3751
3752out_unlock:
3753 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
3754
3755 return table;
3756}
3757
Jiang Liu3c3d4f92015-04-13 14:11:38 +08003758static int alloc_irq_index(u16 devid, int count)
Joerg Roedel2b324502012-06-21 16:29:10 +02003759{
3760 struct irq_remap_table *table;
3761 unsigned long flags;
3762 int index, c;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003763 struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
3764
3765 if (!iommu)
3766 return -ENODEV;
Joerg Roedel2b324502012-06-21 16:29:10 +02003767
3768 table = get_irq_table(devid, false);
3769 if (!table)
3770 return -ENODEV;
3771
3772 spin_lock_irqsave(&table->lock, flags);
3773
3774 /* Scan table for free entries */
3775 for (c = 0, index = table->min_index;
3776 index < MAX_IRQS_PER_TABLE;
3777 ++index) {
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003778 if (!iommu->irte_ops->is_allocated(table, index))
Joerg Roedel2b324502012-06-21 16:29:10 +02003779 c += 1;
3780 else
3781 c = 0;
3782
3783 if (c == count) {
Joerg Roedel2b324502012-06-21 16:29:10 +02003784 for (; c != 0; --c)
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003785 iommu->irte_ops->set_allocated(table, index - c + 1);
Joerg Roedel2b324502012-06-21 16:29:10 +02003786
3787 index -= count - 1;
Joerg Roedel2b324502012-06-21 16:29:10 +02003788 goto out;
3789 }
3790 }
3791
3792 index = -ENOSPC;
3793
3794out:
3795 spin_unlock_irqrestore(&table->lock, flags);
3796
3797 return index;
3798}
3799
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05003800static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte,
3801 struct amd_ir_data *data)
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003802{
3803 struct irq_remap_table *table;
3804 struct amd_iommu *iommu;
3805 unsigned long flags;
3806 struct irte_ga *entry;
3807
3808 iommu = amd_iommu_rlookup_table[devid];
3809 if (iommu == NULL)
3810 return -EINVAL;
3811
3812 table = get_irq_table(devid, false);
3813 if (!table)
3814 return -ENOMEM;
3815
3816 spin_lock_irqsave(&table->lock, flags);
3817
3818 entry = (struct irte_ga *)table->table;
3819 entry = &entry[index];
3820 entry->lo.fields_remap.valid = 0;
3821 entry->hi.val = irte->hi.val;
3822 entry->lo.val = irte->lo.val;
3823 entry->lo.fields_remap.valid = 1;
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05003824 if (data)
3825 data->ref = entry;
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003826
3827 spin_unlock_irqrestore(&table->lock, flags);
3828
3829 iommu_flush_irt(iommu, devid);
3830 iommu_completion_wait(iommu);
3831
3832 return 0;
3833}
3834
3835static int modify_irte(u16 devid, int index, union irte *irte)
Joerg Roedel2b324502012-06-21 16:29:10 +02003836{
3837 struct irq_remap_table *table;
3838 struct amd_iommu *iommu;
3839 unsigned long flags;
3840
3841 iommu = amd_iommu_rlookup_table[devid];
3842 if (iommu == NULL)
3843 return -EINVAL;
3844
3845 table = get_irq_table(devid, false);
3846 if (!table)
3847 return -ENOMEM;
3848
3849 spin_lock_irqsave(&table->lock, flags);
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003850 table->table[index] = irte->val;
Joerg Roedel2b324502012-06-21 16:29:10 +02003851 spin_unlock_irqrestore(&table->lock, flags);
3852
3853 iommu_flush_irt(iommu, devid);
3854 iommu_completion_wait(iommu);
3855
3856 return 0;
3857}
3858
3859static void free_irte(u16 devid, int index)
3860{
3861 struct irq_remap_table *table;
3862 struct amd_iommu *iommu;
3863 unsigned long flags;
3864
3865 iommu = amd_iommu_rlookup_table[devid];
3866 if (iommu == NULL)
3867 return;
3868
3869 table = get_irq_table(devid, false);
3870 if (!table)
3871 return;
3872
3873 spin_lock_irqsave(&table->lock, flags);
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003874 iommu->irte_ops->clear_allocated(table, index);
Joerg Roedel2b324502012-06-21 16:29:10 +02003875 spin_unlock_irqrestore(&table->lock, flags);
3876
3877 iommu_flush_irt(iommu, devid);
3878 iommu_completion_wait(iommu);
3879}
3880
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003881static void irte_prepare(void *entry,
3882 u32 delivery_mode, u32 dest_mode,
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003883 u8 vector, u32 dest_apicid, int devid)
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003884{
3885 union irte *irte = (union irte *) entry;
3886
3887 irte->val = 0;
3888 irte->fields.vector = vector;
3889 irte->fields.int_type = delivery_mode;
3890 irte->fields.destination = dest_apicid;
3891 irte->fields.dm = dest_mode;
3892 irte->fields.valid = 1;
3893}
3894
3895static void irte_ga_prepare(void *entry,
3896 u32 delivery_mode, u32 dest_mode,
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003897 u8 vector, u32 dest_apicid, int devid)
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003898{
3899 struct irte_ga *irte = (struct irte_ga *) entry;
3900
3901 irte->lo.val = 0;
3902 irte->hi.val = 0;
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003903 irte->lo.fields_remap.int_type = delivery_mode;
3904 irte->lo.fields_remap.dm = dest_mode;
3905 irte->hi.fields.vector = vector;
3906 irte->lo.fields_remap.destination = dest_apicid;
3907 irte->lo.fields_remap.valid = 1;
3908}
3909
3910static void irte_activate(void *entry, u16 devid, u16 index)
3911{
3912 union irte *irte = (union irte *) entry;
3913
3914 irte->fields.valid = 1;
3915 modify_irte(devid, index, irte);
3916}
3917
3918static void irte_ga_activate(void *entry, u16 devid, u16 index)
3919{
3920 struct irte_ga *irte = (struct irte_ga *) entry;
3921
3922 irte->lo.fields_remap.valid = 1;
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05003923 modify_irte_ga(devid, index, irte, NULL);
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003924}
3925
3926static void irte_deactivate(void *entry, u16 devid, u16 index)
3927{
3928 union irte *irte = (union irte *) entry;
3929
3930 irte->fields.valid = 0;
3931 modify_irte(devid, index, irte);
3932}
3933
3934static void irte_ga_deactivate(void *entry, u16 devid, u16 index)
3935{
3936 struct irte_ga *irte = (struct irte_ga *) entry;
3937
3938 irte->lo.fields_remap.valid = 0;
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05003939 modify_irte_ga(devid, index, irte, NULL);
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003940}
3941
3942static void irte_set_affinity(void *entry, u16 devid, u16 index,
3943 u8 vector, u32 dest_apicid)
3944{
3945 union irte *irte = (union irte *) entry;
3946
3947 irte->fields.vector = vector;
3948 irte->fields.destination = dest_apicid;
3949 modify_irte(devid, index, irte);
3950}
3951
3952static void irte_ga_set_affinity(void *entry, u16 devid, u16 index,
3953 u8 vector, u32 dest_apicid)
3954{
3955 struct irte_ga *irte = (struct irte_ga *) entry;
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003956 struct iommu_dev_data *dev_data = search_dev_data(devid);
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003957
Suravee Suthikulpanit1781a292017-06-26 04:28:04 -05003958 if (!dev_data || !dev_data->use_vapic ||
3959 !irte->lo.fields_remap.guest_mode) {
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003960 irte->hi.fields.vector = vector;
3961 irte->lo.fields_remap.destination = dest_apicid;
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05003962 modify_irte_ga(devid, index, irte, NULL);
3963 }
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003964}
3965
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05003966#define IRTE_ALLOCATED (~1U)
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05003967static void irte_set_allocated(struct irq_remap_table *table, int index)
3968{
3969 table->table[index] = IRTE_ALLOCATED;
3970}
3971
3972static void irte_ga_set_allocated(struct irq_remap_table *table, int index)
3973{
3974 struct irte_ga *ptr = (struct irte_ga *)table->table;
3975 struct irte_ga *irte = &ptr[index];
3976
3977 memset(&irte->lo.val, 0, sizeof(u64));
3978 memset(&irte->hi.val, 0, sizeof(u64));
3979 irte->hi.fields.vector = 0xff;
3980}
3981
3982static bool irte_is_allocated(struct irq_remap_table *table, int index)
3983{
3984 union irte *ptr = (union irte *)table->table;
3985 union irte *irte = &ptr[index];
3986
3987 return irte->val != 0;
3988}
3989
3990static bool irte_ga_is_allocated(struct irq_remap_table *table, int index)
3991{
3992 struct irte_ga *ptr = (struct irte_ga *)table->table;
3993 struct irte_ga *irte = &ptr[index];
3994
3995 return irte->hi.fields.vector != 0;
3996}
3997
3998static void irte_clear_allocated(struct irq_remap_table *table, int index)
3999{
4000 table->table[index] = 0;
4001}
4002
4003static void irte_ga_clear_allocated(struct irq_remap_table *table, int index)
4004{
4005 struct irte_ga *ptr = (struct irte_ga *)table->table;
4006 struct irte_ga *irte = &ptr[index];
4007
4008 memset(&irte->lo.val, 0, sizeof(u64));
4009 memset(&irte->hi.val, 0, sizeof(u64));
4010}
4011
Jiang Liu7c71d302015-04-13 14:11:33 +08004012static int get_devid(struct irq_alloc_info *info)
Joerg Roedel5527de72012-06-26 11:17:32 +02004013{
Jiang Liu7c71d302015-04-13 14:11:33 +08004014 int devid = -1;
Joerg Roedel5527de72012-06-26 11:17:32 +02004015
Jiang Liu7c71d302015-04-13 14:11:33 +08004016 switch (info->type) {
4017 case X86_IRQ_ALLOC_TYPE_IOAPIC:
4018 devid = get_ioapic_devid(info->ioapic_id);
4019 break;
4020 case X86_IRQ_ALLOC_TYPE_HPET:
4021 devid = get_hpet_devid(info->hpet_id);
4022 break;
4023 case X86_IRQ_ALLOC_TYPE_MSI:
4024 case X86_IRQ_ALLOC_TYPE_MSIX:
4025 devid = get_device_id(&info->msi_dev->dev);
4026 break;
4027 default:
4028 BUG_ON(1);
4029 break;
Joerg Roedel5527de72012-06-26 11:17:32 +02004030 }
4031
Jiang Liu7c71d302015-04-13 14:11:33 +08004032 return devid;
Joerg Roedel5527de72012-06-26 11:17:32 +02004033}
4034
Jiang Liu7c71d302015-04-13 14:11:33 +08004035static struct irq_domain *get_ir_irq_domain(struct irq_alloc_info *info)
Joerg Roedel5527de72012-06-26 11:17:32 +02004036{
Jiang Liu7c71d302015-04-13 14:11:33 +08004037 struct amd_iommu *iommu;
4038 int devid;
Joerg Roedel5527de72012-06-26 11:17:32 +02004039
Jiang Liu7c71d302015-04-13 14:11:33 +08004040 if (!info)
4041 return NULL;
Joerg Roedel5527de72012-06-26 11:17:32 +02004042
Jiang Liu7c71d302015-04-13 14:11:33 +08004043 devid = get_devid(info);
4044 if (devid >= 0) {
4045 iommu = amd_iommu_rlookup_table[devid];
4046 if (iommu)
4047 return iommu->ir_domain;
4048 }
Joerg Roedel5527de72012-06-26 11:17:32 +02004049
Jiang Liu7c71d302015-04-13 14:11:33 +08004050 return NULL;
Joerg Roedel5527de72012-06-26 11:17:32 +02004051}
4052
Jiang Liu7c71d302015-04-13 14:11:33 +08004053static struct irq_domain *get_irq_domain(struct irq_alloc_info *info)
Joerg Roedel0b4d48c2012-06-26 14:54:17 +02004054{
Jiang Liu7c71d302015-04-13 14:11:33 +08004055 struct amd_iommu *iommu;
4056 int devid;
Joerg Roedel0b4d48c2012-06-26 14:54:17 +02004057
Jiang Liu7c71d302015-04-13 14:11:33 +08004058 if (!info)
4059 return NULL;
Joerg Roedel0b4d48c2012-06-26 14:54:17 +02004060
Jiang Liu7c71d302015-04-13 14:11:33 +08004061 switch (info->type) {
4062 case X86_IRQ_ALLOC_TYPE_MSI:
4063 case X86_IRQ_ALLOC_TYPE_MSIX:
4064 devid = get_device_id(&info->msi_dev->dev);
Joerg Roedel9ee35e42016-04-21 18:21:31 +02004065 if (devid < 0)
Wan Zongshun7aba6cb2016-04-01 09:06:02 -04004066 return NULL;
4067
Dan Carpenter1fb260b2016-01-07 12:36:06 +03004068 iommu = amd_iommu_rlookup_table[devid];
4069 if (iommu)
4070 return iommu->msi_domain;
Jiang Liu7c71d302015-04-13 14:11:33 +08004071 break;
4072 default:
4073 break;
4074 }
Joerg Roedel0b4d48c2012-06-26 14:54:17 +02004075
Jiang Liu7c71d302015-04-13 14:11:33 +08004076 return NULL;
Joerg Roedeld9761952012-06-26 16:00:08 +02004077}
4078
Joerg Roedel6b474b82012-06-26 16:46:04 +02004079struct irq_remap_ops amd_iommu_irq_ops = {
Joerg Roedel6b474b82012-06-26 16:46:04 +02004080 .prepare = amd_iommu_prepare,
4081 .enable = amd_iommu_enable,
4082 .disable = amd_iommu_disable,
4083 .reenable = amd_iommu_reenable,
4084 .enable_faulting = amd_iommu_enable_faulting,
Jiang Liu7c71d302015-04-13 14:11:33 +08004085 .get_ir_irq_domain = get_ir_irq_domain,
4086 .get_irq_domain = get_irq_domain,
Joerg Roedel6b474b82012-06-26 16:46:04 +02004087};
Jiang Liu7c71d302015-04-13 14:11:33 +08004088
4089static void irq_remapping_prepare_irte(struct amd_ir_data *data,
4090 struct irq_cfg *irq_cfg,
4091 struct irq_alloc_info *info,
4092 int devid, int index, int sub_handle)
4093{
4094 struct irq_2_irte *irte_info = &data->irq_2_irte;
4095 struct msi_msg *msg = &data->msi_entry;
Jiang Liu7c71d302015-04-13 14:11:33 +08004096 struct IO_APIC_route_entry *entry;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004097 struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
4098
4099 if (!iommu)
4100 return;
Jiang Liu7c71d302015-04-13 14:11:33 +08004101
Jiang Liu7c71d302015-04-13 14:11:33 +08004102 data->irq_2_irte.devid = devid;
4103 data->irq_2_irte.index = index + sub_handle;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004104 iommu->irte_ops->prepare(data->entry, apic->irq_delivery_mode,
4105 apic->irq_dest_mode, irq_cfg->vector,
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05004106 irq_cfg->dest_apicid, devid);
Jiang Liu7c71d302015-04-13 14:11:33 +08004107
4108 switch (info->type) {
4109 case X86_IRQ_ALLOC_TYPE_IOAPIC:
4110 /* Setup IOAPIC entry */
4111 entry = info->ioapic_entry;
4112 info->ioapic_entry = NULL;
4113 memset(entry, 0, sizeof(*entry));
4114 entry->vector = index;
4115 entry->mask = 0;
4116 entry->trigger = info->ioapic_trigger;
4117 entry->polarity = info->ioapic_polarity;
4118 /* Mask level triggered irqs. */
4119 if (info->ioapic_trigger)
4120 entry->mask = 1;
4121 break;
4122
4123 case X86_IRQ_ALLOC_TYPE_HPET:
4124 case X86_IRQ_ALLOC_TYPE_MSI:
4125 case X86_IRQ_ALLOC_TYPE_MSIX:
4126 msg->address_hi = MSI_ADDR_BASE_HI;
4127 msg->address_lo = MSI_ADDR_BASE_LO;
4128 msg->data = irte_info->index;
4129 break;
4130
4131 default:
4132 BUG_ON(1);
4133 break;
4134 }
4135}
4136
Suravee Suthikulpanit880ac602016-08-23 13:52:34 -05004137struct amd_irte_ops irte_32_ops = {
4138 .prepare = irte_prepare,
4139 .activate = irte_activate,
4140 .deactivate = irte_deactivate,
4141 .set_affinity = irte_set_affinity,
4142 .set_allocated = irte_set_allocated,
4143 .is_allocated = irte_is_allocated,
4144 .clear_allocated = irte_clear_allocated,
4145};
4146
4147struct amd_irte_ops irte_128_ops = {
4148 .prepare = irte_ga_prepare,
4149 .activate = irte_ga_activate,
4150 .deactivate = irte_ga_deactivate,
4151 .set_affinity = irte_ga_set_affinity,
4152 .set_allocated = irte_ga_set_allocated,
4153 .is_allocated = irte_ga_is_allocated,
4154 .clear_allocated = irte_ga_clear_allocated,
4155};
4156
Jiang Liu7c71d302015-04-13 14:11:33 +08004157static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
4158 unsigned int nr_irqs, void *arg)
4159{
4160 struct irq_alloc_info *info = arg;
4161 struct irq_data *irq_data;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004162 struct amd_ir_data *data = NULL;
Jiang Liu7c71d302015-04-13 14:11:33 +08004163 struct irq_cfg *cfg;
4164 int i, ret, devid;
4165 int index = -1;
4166
4167 if (!info)
4168 return -EINVAL;
4169 if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_MSI &&
4170 info->type != X86_IRQ_ALLOC_TYPE_MSIX)
4171 return -EINVAL;
4172
4173 /*
4174 * With IRQ remapping enabled, don't need contiguous CPU vectors
4175 * to support multiple MSI interrupts.
4176 */
4177 if (info->type == X86_IRQ_ALLOC_TYPE_MSI)
4178 info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS;
4179
4180 devid = get_devid(info);
4181 if (devid < 0)
4182 return -EINVAL;
4183
4184 ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, arg);
4185 if (ret < 0)
4186 return ret;
4187
Jiang Liu7c71d302015-04-13 14:11:33 +08004188 if (info->type == X86_IRQ_ALLOC_TYPE_IOAPIC) {
4189 if (get_irq_table(devid, true))
4190 index = info->ioapic_pin;
4191 else
4192 ret = -ENOMEM;
4193 } else {
Jiang Liu3c3d4f92015-04-13 14:11:38 +08004194 index = alloc_irq_index(devid, nr_irqs);
Jiang Liu7c71d302015-04-13 14:11:33 +08004195 }
4196 if (index < 0) {
4197 pr_warn("Failed to allocate IRTE\n");
Wei Yongjun517abe42016-07-28 02:10:26 +00004198 ret = index;
Jiang Liu7c71d302015-04-13 14:11:33 +08004199 goto out_free_parent;
4200 }
4201
4202 for (i = 0; i < nr_irqs; i++) {
4203 irq_data = irq_domain_get_irq_data(domain, virq + i);
4204 cfg = irqd_cfg(irq_data);
4205 if (!irq_data || !cfg) {
4206 ret = -EINVAL;
4207 goto out_free_data;
4208 }
4209
Joerg Roedela130e692015-08-13 11:07:25 +02004210 ret = -ENOMEM;
4211 data = kzalloc(sizeof(*data), GFP_KERNEL);
4212 if (!data)
4213 goto out_free_data;
4214
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004215 if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir))
4216 data->entry = kzalloc(sizeof(union irte), GFP_KERNEL);
4217 else
4218 data->entry = kzalloc(sizeof(struct irte_ga),
4219 GFP_KERNEL);
4220 if (!data->entry) {
4221 kfree(data);
4222 goto out_free_data;
4223 }
4224
Jiang Liu7c71d302015-04-13 14:11:33 +08004225 irq_data->hwirq = (devid << 16) + i;
4226 irq_data->chip_data = data;
4227 irq_data->chip = &amd_ir_chip;
4228 irq_remapping_prepare_irte(data, cfg, info, devid, index, i);
4229 irq_set_status_flags(virq + i, IRQ_MOVE_PCNTXT);
4230 }
Joerg Roedela130e692015-08-13 11:07:25 +02004231
Jiang Liu7c71d302015-04-13 14:11:33 +08004232 return 0;
4233
4234out_free_data:
4235 for (i--; i >= 0; i--) {
4236 irq_data = irq_domain_get_irq_data(domain, virq + i);
4237 if (irq_data)
4238 kfree(irq_data->chip_data);
4239 }
4240 for (i = 0; i < nr_irqs; i++)
4241 free_irte(devid, index + i);
4242out_free_parent:
4243 irq_domain_free_irqs_common(domain, virq, nr_irqs);
4244 return ret;
4245}
4246
4247static void irq_remapping_free(struct irq_domain *domain, unsigned int virq,
4248 unsigned int nr_irqs)
4249{
4250 struct irq_2_irte *irte_info;
4251 struct irq_data *irq_data;
4252 struct amd_ir_data *data;
4253 int i;
4254
4255 for (i = 0; i < nr_irqs; i++) {
4256 irq_data = irq_domain_get_irq_data(domain, virq + i);
4257 if (irq_data && irq_data->chip_data) {
4258 data = irq_data->chip_data;
4259 irte_info = &data->irq_2_irte;
4260 free_irte(irte_info->devid, irte_info->index);
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004261 kfree(data->entry);
Jiang Liu7c71d302015-04-13 14:11:33 +08004262 kfree(data);
4263 }
4264 }
4265 irq_domain_free_irqs_common(domain, virq, nr_irqs);
4266}
4267
4268static void irq_remapping_activate(struct irq_domain *domain,
4269 struct irq_data *irq_data)
4270{
4271 struct amd_ir_data *data = irq_data->chip_data;
4272 struct irq_2_irte *irte_info = &data->irq_2_irte;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004273 struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid];
Jiang Liu7c71d302015-04-13 14:11:33 +08004274
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004275 if (iommu)
4276 iommu->irte_ops->activate(data->entry, irte_info->devid,
4277 irte_info->index);
Jiang Liu7c71d302015-04-13 14:11:33 +08004278}
4279
4280static void irq_remapping_deactivate(struct irq_domain *domain,
4281 struct irq_data *irq_data)
4282{
4283 struct amd_ir_data *data = irq_data->chip_data;
4284 struct irq_2_irte *irte_info = &data->irq_2_irte;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004285 struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid];
Jiang Liu7c71d302015-04-13 14:11:33 +08004286
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004287 if (iommu)
4288 iommu->irte_ops->deactivate(data->entry, irte_info->devid,
4289 irte_info->index);
Jiang Liu7c71d302015-04-13 14:11:33 +08004290}
4291
4292static struct irq_domain_ops amd_ir_domain_ops = {
4293 .alloc = irq_remapping_alloc,
4294 .free = irq_remapping_free,
4295 .activate = irq_remapping_activate,
4296 .deactivate = irq_remapping_deactivate,
4297};
4298
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05004299static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
4300{
4301 struct amd_iommu *iommu;
4302 struct amd_iommu_pi_data *pi_data = vcpu_info;
4303 struct vcpu_data *vcpu_pi_info = pi_data->vcpu_data;
4304 struct amd_ir_data *ir_data = data->chip_data;
4305 struct irte_ga *irte = (struct irte_ga *) ir_data->entry;
4306 struct irq_2_irte *irte_info = &ir_data->irq_2_irte;
Suravee Suthikulpanitd98de492016-08-23 13:52:40 -05004307 struct iommu_dev_data *dev_data = search_dev_data(irte_info->devid);
4308
4309 /* Note:
4310 * This device has never been set up for guest mode.
4311 * we should not modify the IRTE
4312 */
4313 if (!dev_data || !dev_data->use_vapic)
4314 return 0;
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05004315
4316 pi_data->ir_data = ir_data;
4317
4318 /* Note:
4319 * SVM tries to set up for VAPIC mode, but we are in
4320 * legacy mode. So, we force legacy mode instead.
4321 */
4322 if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) {
4323 pr_debug("AMD-Vi: %s: Fall back to using intr legacy remap\n",
4324 __func__);
4325 pi_data->is_guest_mode = false;
4326 }
4327
4328 iommu = amd_iommu_rlookup_table[irte_info->devid];
4329 if (iommu == NULL)
4330 return -EINVAL;
4331
4332 pi_data->prev_ga_tag = ir_data->cached_ga_tag;
4333 if (pi_data->is_guest_mode) {
4334 /* Setting */
4335 irte->hi.fields.ga_root_ptr = (pi_data->base >> 12);
4336 irte->hi.fields.vector = vcpu_pi_info->vector;
Suravee Suthikulpanitbe5c6ef2017-07-05 21:29:59 -05004337 irte->lo.fields_vapic.ga_log_intr = 1;
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05004338 irte->lo.fields_vapic.guest_mode = 1;
4339 irte->lo.fields_vapic.ga_tag = pi_data->ga_tag;
4340
4341 ir_data->cached_ga_tag = pi_data->ga_tag;
4342 } else {
4343 /* Un-Setting */
4344 struct irq_cfg *cfg = irqd_cfg(data);
4345
4346 irte->hi.val = 0;
4347 irte->lo.val = 0;
4348 irte->hi.fields.vector = cfg->vector;
4349 irte->lo.fields_remap.guest_mode = 0;
4350 irte->lo.fields_remap.destination = cfg->dest_apicid;
4351 irte->lo.fields_remap.int_type = apic->irq_delivery_mode;
4352 irte->lo.fields_remap.dm = apic->irq_dest_mode;
4353
4354 /*
4355 * This communicates the ga_tag back to the caller
4356 * so that it can do all the necessary clean up.
4357 */
4358 ir_data->cached_ga_tag = 0;
4359 }
4360
4361 return modify_irte_ga(irte_info->devid, irte_info->index, irte, ir_data);
4362}
4363
Jiang Liu7c71d302015-04-13 14:11:33 +08004364static int amd_ir_set_affinity(struct irq_data *data,
4365 const struct cpumask *mask, bool force)
4366{
4367 struct amd_ir_data *ir_data = data->chip_data;
4368 struct irq_2_irte *irte_info = &ir_data->irq_2_irte;
4369 struct irq_cfg *cfg = irqd_cfg(data);
4370 struct irq_data *parent = data->parent_data;
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004371 struct amd_iommu *iommu = amd_iommu_rlookup_table[irte_info->devid];
Jiang Liu7c71d302015-04-13 14:11:33 +08004372 int ret;
4373
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004374 if (!iommu)
4375 return -ENODEV;
4376
Jiang Liu7c71d302015-04-13 14:11:33 +08004377 ret = parent->chip->irq_set_affinity(parent, mask, force);
4378 if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE)
4379 return ret;
4380
4381 /*
4382 * Atomically updates the IRTE with the new destination, vector
4383 * and flushes the interrupt entry cache.
4384 */
Suravee Suthikulpanit77bdab42016-08-23 13:52:35 -05004385 iommu->irte_ops->set_affinity(ir_data->entry, irte_info->devid,
4386 irte_info->index, cfg->vector, cfg->dest_apicid);
Jiang Liu7c71d302015-04-13 14:11:33 +08004387
4388 /*
4389 * After this point, all the interrupts will start arriving
4390 * at the new destination. So, time to cleanup the previous
4391 * vector allocation.
4392 */
Jiang Liuc6c20022015-04-14 10:30:02 +08004393 send_cleanup_vector(cfg);
Jiang Liu7c71d302015-04-13 14:11:33 +08004394
4395 return IRQ_SET_MASK_OK_DONE;
4396}
4397
4398static void ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
4399{
4400 struct amd_ir_data *ir_data = irq_data->chip_data;
4401
4402 *msg = ir_data->msi_entry;
4403}
4404
4405static struct irq_chip amd_ir_chip = {
4406 .irq_ack = ir_ack_apic_edge,
4407 .irq_set_affinity = amd_ir_set_affinity,
Suravee Suthikulpanitb9fc6b52016-08-23 13:52:39 -05004408 .irq_set_vcpu_affinity = amd_ir_set_vcpu_affinity,
Jiang Liu7c71d302015-04-13 14:11:33 +08004409 .irq_compose_msi_msg = ir_compose_msi_msg,
4410};
4411
4412int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
4413{
4414 iommu->ir_domain = irq_domain_add_tree(NULL, &amd_ir_domain_ops, iommu);
4415 if (!iommu->ir_domain)
4416 return -ENOMEM;
4417
4418 iommu->ir_domain->parent = arch_get_ir_parent_domain();
4419 iommu->msi_domain = arch_create_msi_irq_domain(iommu->ir_domain);
4420
4421 return 0;
4422}
Suravee Suthikulpanit8dbea3f2016-08-23 13:52:38 -05004423
4424int amd_iommu_update_ga(int cpu, bool is_run, void *data)
4425{
4426 unsigned long flags;
4427 struct amd_iommu *iommu;
4428 struct irq_remap_table *irt;
4429 struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
4430 int devid = ir_data->irq_2_irte.devid;
4431 struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
4432 struct irte_ga *ref = (struct irte_ga *) ir_data->ref;
4433
4434 if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
4435 !ref || !entry || !entry->lo.fields_vapic.guest_mode)
4436 return 0;
4437
4438 iommu = amd_iommu_rlookup_table[devid];
4439 if (!iommu)
4440 return -ENODEV;
4441
4442 irt = get_irq_table(devid, false);
4443 if (!irt)
4444 return -ENODEV;
4445
4446 spin_lock_irqsave(&irt->lock, flags);
4447
4448 if (ref->lo.fields_vapic.guest_mode) {
4449 if (cpu >= 0)
4450 ref->lo.fields_vapic.destination = cpu;
4451 ref->lo.fields_vapic.is_run = is_run;
4452 barrier();
4453 }
4454
4455 spin_unlock_irqrestore(&irt->lock, flags);
4456
4457 iommu_flush_irt(iommu, devid);
4458 iommu_completion_wait(iommu);
4459 return 0;
4460}
4461EXPORT_SYMBOL(amd_iommu_update_ga);
Joerg Roedel2b324502012-06-21 16:29:10 +02004462#endif