blob: 9b0f22bc0514e0ea5863524f2f7b41718ae05fcc [file] [log] [blame]
Thomas Gleixner2025cf92019-05-29 07:18:02 -07001// SPDX-License-Identifier: GPL-2.0-only
David Woodhouse8a94ade2015-03-24 14:54:56 +00002/*
3 * Copyright © 2015 Intel Corporation.
4 *
David Woodhouse8a94ade2015-03-24 14:54:56 +00005 * Authors: David Woodhouse <dwmw2@infradead.org>
6 */
7
8#include <linux/intel-iommu.h>
David Woodhouse2f26e0a2015-09-09 11:40:47 +01009#include <linux/mmu_notifier.h>
10#include <linux/sched.h>
Ingo Molnar6e84f312017-02-08 18:51:29 +010011#include <linux/sched/mm.h>
David Woodhouse2f26e0a2015-09-09 11:40:47 +010012#include <linux/slab.h>
13#include <linux/intel-svm.h>
14#include <linux/rculist.h>
15#include <linux/pci.h>
16#include <linux/pci-ats.h>
David Woodhousea222a7f2015-10-07 23:35:18 +010017#include <linux/dmar.h>
18#include <linux/interrupt.h>
Souptick Joarder50a7ca32018-08-17 15:44:47 -070019#include <linux/mm_types.h>
Lu Baolu100b8a12021-06-10 10:00:58 +080020#include <linux/xarray.h>
Jacob Pan59a62332020-01-02 08:18:08 +080021#include <linux/ioasid.h>
Ashok Raj9d8c3af2017-08-08 13:29:27 -070022#include <asm/page.h>
Fenghua Yu20f0afd2020-09-15 09:30:13 -070023#include <asm/fpu/api.h>
Lu Baolue93a67f2021-06-10 10:01:04 +080024#include <trace/events/intel_iommu.h>
David Woodhousea222a7f2015-10-07 23:35:18 +010025
Lu Baolu02f3eff2020-07-24 09:49:25 +080026#include "pasid.h"
Lu Baolu0f4834ab2021-06-10 10:01:08 +080027#include "perf.h"
Lu Baolu40483772021-06-10 10:00:59 +080028#include "../iommu-sva-lib.h"
Lu Baoluaf395072018-07-14 15:46:56 +080029
David Woodhousea222a7f2015-10-07 23:35:18 +010030static irqreturn_t prq_event_thread(int irq, void *d);
Fenghua Yuc7b6bac2020-09-15 09:30:05 -070031static void intel_svm_drain_prq(struct device *dev, u32 pasid);
Lu Baolu40483772021-06-10 10:00:59 +080032#define to_intel_svm_dev(handle) container_of(handle, struct intel_svm_dev, sva)
David Woodhouse2f26e0a2015-09-09 11:40:47 +010033
David Woodhousea222a7f2015-10-07 23:35:18 +010034#define PRQ_ORDER 0
35
Lu Baolu100b8a12021-06-10 10:00:58 +080036static DEFINE_XARRAY_ALLOC(pasid_private_array);
37static int pasid_private_add(ioasid_t pasid, void *priv)
38{
39 return xa_alloc(&pasid_private_array, &pasid, priv,
40 XA_LIMIT(pasid, pasid), GFP_ATOMIC);
41}
42
43static void pasid_private_remove(ioasid_t pasid)
44{
45 xa_erase(&pasid_private_array, pasid);
46}
47
48static void *pasid_private_find(ioasid_t pasid)
49{
50 return xa_load(&pasid_private_array, pasid);
51}
52
Lu Baolu9e52cc02021-06-10 10:01:00 +080053static struct intel_svm_dev *
54svm_lookup_device_by_sid(struct intel_svm *svm, u16 sid)
55{
56 struct intel_svm_dev *sdev = NULL, *t;
57
58 rcu_read_lock();
59 list_for_each_entry_rcu(t, &svm->devs, list) {
60 if (t->sid == sid) {
61 sdev = t;
62 break;
63 }
64 }
65 rcu_read_unlock();
66
67 return sdev;
68}
69
70static struct intel_svm_dev *
71svm_lookup_device_by_dev(struct intel_svm *svm, struct device *dev)
72{
73 struct intel_svm_dev *sdev = NULL, *t;
74
75 rcu_read_lock();
76 list_for_each_entry_rcu(t, &svm->devs, list) {
77 if (t->dev == dev) {
78 sdev = t;
79 break;
80 }
81 }
82 rcu_read_unlock();
83
84 return sdev;
85}
86
David Woodhousea222a7f2015-10-07 23:35:18 +010087int intel_svm_enable_prq(struct intel_iommu *iommu)
88{
Lu Baolu4c82b882021-06-10 10:01:02 +080089 struct iopf_queue *iopfq;
David Woodhousea222a7f2015-10-07 23:35:18 +010090 struct page *pages;
91 int irq, ret;
92
93 pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, PRQ_ORDER);
94 if (!pages) {
95 pr_warn("IOMMU: %s: Failed to allocate page request queue\n",
96 iommu->name);
97 return -ENOMEM;
98 }
99 iommu->prq = page_address(pages);
100
101 irq = dmar_alloc_hwirq(DMAR_UNITS_SUPPORTED + iommu->seq_id, iommu->node, iommu);
102 if (irq <= 0) {
103 pr_err("IOMMU: %s: Failed to create IRQ vector for page request queue\n",
104 iommu->name);
105 ret = -EINVAL;
Lu Baolu4c82b882021-06-10 10:01:02 +0800106 goto free_prq;
David Woodhousea222a7f2015-10-07 23:35:18 +0100107 }
108 iommu->pr_irq = irq;
109
Lu Baolu4c82b882021-06-10 10:01:02 +0800110 snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name),
111 "dmar%d-iopfq", iommu->seq_id);
112 iopfq = iopf_queue_alloc(iommu->iopfq_name);
113 if (!iopfq) {
114 pr_err("IOMMU: %s: Failed to allocate iopf queue\n", iommu->name);
115 ret = -ENOMEM;
116 goto free_hwirq;
117 }
118 iommu->iopf_queue = iopfq;
119
David Woodhousea222a7f2015-10-07 23:35:18 +0100120 snprintf(iommu->prq_name, sizeof(iommu->prq_name), "dmar%d-prq", iommu->seq_id);
121
122 ret = request_threaded_irq(irq, NULL, prq_event_thread, IRQF_ONESHOT,
123 iommu->prq_name, iommu);
124 if (ret) {
125 pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n",
126 iommu->name);
Lu Baolu4c82b882021-06-10 10:01:02 +0800127 goto free_iopfq;
David Woodhousea222a7f2015-10-07 23:35:18 +0100128 }
129 dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
130 dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
131 dmar_writeq(iommu->reg + DMAR_PQA_REG, virt_to_phys(iommu->prq) | PRQ_ORDER);
132
Lu Baolu66ac4db2020-05-16 14:20:58 +0800133 init_completion(&iommu->prq_complete);
134
David Woodhousea222a7f2015-10-07 23:35:18 +0100135 return 0;
Lu Baolu4c82b882021-06-10 10:01:02 +0800136
137free_iopfq:
138 iopf_queue_free(iommu->iopf_queue);
139 iommu->iopf_queue = NULL;
140free_hwirq:
141 dmar_free_hwirq(irq);
142 iommu->pr_irq = 0;
143free_prq:
144 free_pages((unsigned long)iommu->prq, PRQ_ORDER);
145 iommu->prq = NULL;
146
147 return ret;
David Woodhousea222a7f2015-10-07 23:35:18 +0100148}
149
150int intel_svm_finish_prq(struct intel_iommu *iommu)
151{
152 dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
153 dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
154 dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
155
Jerry Snitselaar72d54812017-12-20 09:48:56 -0700156 if (iommu->pr_irq) {
157 free_irq(iommu->pr_irq, iommu);
158 dmar_free_hwirq(iommu->pr_irq);
159 iommu->pr_irq = 0;
160 }
David Woodhousea222a7f2015-10-07 23:35:18 +0100161
Lu Baolu4c82b882021-06-10 10:01:02 +0800162 if (iommu->iopf_queue) {
163 iopf_queue_free(iommu->iopf_queue);
164 iommu->iopf_queue = NULL;
165 }
166
David Woodhousea222a7f2015-10-07 23:35:18 +0100167 free_pages((unsigned long)iommu->prq, PRQ_ORDER);
168 iommu->prq = NULL;
169
170 return 0;
171}
172
Jacob Panff3dc652020-01-02 08:18:03 +0800173static inline bool intel_svm_capable(struct intel_iommu *iommu)
174{
175 return iommu->flags & VTD_FLAG_SVM_CAPABLE;
176}
177
178void intel_svm_check(struct intel_iommu *iommu)
179{
180 if (!pasid_supported(iommu))
181 return;
182
183 if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
184 !cap_fl1gp_support(iommu->cap)) {
185 pr_err("%s SVM disabled, incompatible 1GB page capability\n",
186 iommu->name);
187 return;
188 }
189
190 if (cpu_feature_enabled(X86_FEATURE_LA57) &&
191 !cap_5lp_support(iommu->cap)) {
192 pr_err("%s SVM disabled, incompatible paging mode\n",
193 iommu->name);
194 return;
195 }
196
197 iommu->flags |= VTD_FLAG_SVM_CAPABLE;
198}
199
Lu Baolu2d6ffc62020-12-31 08:53:20 +0800200static void __flush_svm_range_dev(struct intel_svm *svm,
201 struct intel_svm_dev *sdev,
202 unsigned long address,
203 unsigned long pages, int ih)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100204{
Lu Baolu9872f9b2021-01-14 16:50:21 +0800205 struct device_domain_info *info = get_domain_info(sdev->dev);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100206
Lu Baolu9872f9b2021-01-14 16:50:21 +0800207 if (WARN_ON(!pages))
208 return;
David Woodhouse5d52f482015-10-20 15:52:13 +0100209
Lu Baolu9872f9b2021-01-14 16:50:21 +0800210 qi_flush_piotlb(sdev->iommu, sdev->did, svm->pasid, address, pages, ih);
211 if (info->ats_enabled)
212 qi_flush_dev_iotlb_pasid(sdev->iommu, sdev->sid, info->pfsid,
213 svm->pasid, sdev->qdep, address,
214 order_base_2(pages));
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100215}
216
Lu Baolu2d6ffc62020-12-31 08:53:20 +0800217static void intel_flush_svm_range_dev(struct intel_svm *svm,
218 struct intel_svm_dev *sdev,
219 unsigned long address,
220 unsigned long pages, int ih)
221{
222 unsigned long shift = ilog2(__roundup_pow_of_two(pages));
223 unsigned long align = (1ULL << (VTD_PAGE_SHIFT + shift));
224 unsigned long start = ALIGN_DOWN(address, align);
225 unsigned long end = ALIGN(address + (pages << VTD_PAGE_SHIFT), align);
226
227 while (start < end) {
228 __flush_svm_range_dev(svm, sdev, start, align >> VTD_PAGE_SHIFT, ih);
229 start += align;
230 }
231}
232
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100233static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
Jacob Pan8744daf2019-08-26 08:53:29 -0700234 unsigned long pages, int ih)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100235{
236 struct intel_svm_dev *sdev;
237
238 rcu_read_lock();
239 list_for_each_entry_rcu(sdev, &svm->devs, list)
Jacob Pan8744daf2019-08-26 08:53:29 -0700240 intel_flush_svm_range_dev(svm, sdev, address, pages, ih);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100241 rcu_read_unlock();
242}
243
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100244/* Pages have been freed at this point */
245static void intel_invalidate_range(struct mmu_notifier *mn,
246 struct mm_struct *mm,
247 unsigned long start, unsigned long end)
248{
249 struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
250
251 intel_flush_svm_range(svm, start,
Jacob Pan8744daf2019-08-26 08:53:29 -0700252 (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 0);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100253}
254
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100255static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
256{
257 struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
David Woodhousee57e58b2016-01-12 19:18:06 +0000258 struct intel_svm_dev *sdev;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100259
David Woodhousee57e58b2016-01-12 19:18:06 +0000260 /* This might end up being called from exit_mmap(), *before* the page
261 * tables are cleared. And __mmu_notifier_release() will delete us from
262 * the list of notifiers so that our invalidate_range() callback doesn't
263 * get called when the page tables are cleared. So we need to protect
264 * against hardware accessing those page tables.
265 *
266 * We do it by clearing the entry in the PASID table and then flushing
267 * the IOTLB and the PASID table caches. This might upset hardware;
268 * perhaps we'll want to point the PASID to a dummy PGD (like the zero
269 * page) so that we end up taking a fault that the hardware really
270 * *has* to handle gracefully without affecting other processes.
271 */
David Woodhousee57e58b2016-01-12 19:18:06 +0000272 rcu_read_lock();
Lu Baolu81ebd912020-05-16 14:20:59 +0800273 list_for_each_entry_rcu(sdev, &svm->devs, list)
Liu Yi L9ad9f452021-01-07 00:03:55 +0800274 intel_pasid_tear_down_entry(sdev->iommu, sdev->dev,
Lu Baolu37e91bd2020-05-16 14:20:57 +0800275 svm->pasid, true);
David Woodhousee57e58b2016-01-12 19:18:06 +0000276 rcu_read_unlock();
277
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100278}
279
280static const struct mmu_notifier_ops intel_mmuops = {
281 .release = intel_mm_release,
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100282 .invalidate_range = intel_invalidate_range,
283};
284
285static DEFINE_MUTEX(pasid_mutex);
286
Lu Baolu19abcf72020-07-24 09:49:22 +0800287static int pasid_to_svm_sdev(struct device *dev, unsigned int pasid,
288 struct intel_svm **rsvm,
289 struct intel_svm_dev **rsdev)
290{
Lu Baolu9e52cc02021-06-10 10:01:00 +0800291 struct intel_svm_dev *sdev = NULL;
Lu Baolu19abcf72020-07-24 09:49:22 +0800292 struct intel_svm *svm;
293
294 /* The caller should hold the pasid_mutex lock */
295 if (WARN_ON(!mutex_is_locked(&pasid_mutex)))
296 return -EINVAL;
297
298 if (pasid == INVALID_IOASID || pasid >= PASID_MAX)
299 return -EINVAL;
300
Lu Baolu100b8a12021-06-10 10:00:58 +0800301 svm = pasid_private_find(pasid);
Lu Baolu19abcf72020-07-24 09:49:22 +0800302 if (IS_ERR(svm))
303 return PTR_ERR(svm);
304
305 if (!svm)
306 goto out;
307
308 /*
309 * If we found svm for the PASID, there must be at least one device
310 * bond.
311 */
312 if (WARN_ON(list_empty(&svm->devs)))
313 return -EINVAL;
Lu Baolu9e52cc02021-06-10 10:01:00 +0800314 sdev = svm_lookup_device_by_dev(svm, dev);
Lu Baolu19abcf72020-07-24 09:49:22 +0800315
316out:
317 *rsvm = svm;
318 *rsdev = sdev;
319
320 return 0;
321}
322
Jacob Pan56722a42020-05-16 14:20:47 +0800323int intel_svm_bind_gpasid(struct iommu_domain *domain, struct device *dev,
324 struct iommu_gpasid_bind_data *data)
325{
Lu Baoludd6692f2020-07-24 09:49:21 +0800326 struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
Lu Baolu19abcf72020-07-24 09:49:22 +0800327 struct intel_svm_dev *sdev = NULL;
Jacob Pan56722a42020-05-16 14:20:47 +0800328 struct dmar_domain *dmar_domain;
Liu Yi Leea4e292020-10-30 10:37:23 +0800329 struct device_domain_info *info;
Lu Baolu19abcf72020-07-24 09:49:22 +0800330 struct intel_svm *svm = NULL;
Lu Baolu420d42f2020-12-31 08:53:23 +0800331 unsigned long iflags;
Jacob Pan56722a42020-05-16 14:20:47 +0800332 int ret = 0;
333
334 if (WARN_ON(!iommu) || !data)
335 return -EINVAL;
336
Jacob Pan6278eec2020-09-25 09:32:47 -0700337 if (data->format != IOMMU_PASID_FORMAT_INTEL_VTD)
338 return -EINVAL;
339
340 /* IOMMU core ensures argsz is more than the start of the union */
341 if (data->argsz < offsetofend(struct iommu_gpasid_bind_data, vendor.vtd))
342 return -EINVAL;
343
344 /* Make sure no undefined flags are used in vendor data */
345 if (data->vendor.vtd.flags & ~(IOMMU_SVA_VTD_GPASID_LAST - 1))
Jacob Pan56722a42020-05-16 14:20:47 +0800346 return -EINVAL;
347
348 if (!dev_is_pci(dev))
349 return -ENOTSUPP;
350
351 /* VT-d supports devices with full 20 bit PASIDs only */
352 if (pci_max_pasids(to_pci_dev(dev)) != PASID_MAX)
353 return -EINVAL;
354
355 /*
356 * We only check host PASID range, we have no knowledge to check
357 * guest PASID range.
358 */
359 if (data->hpasid <= 0 || data->hpasid >= PASID_MAX)
360 return -EINVAL;
361
Liu Yi Leea4e292020-10-30 10:37:23 +0800362 info = get_domain_info(dev);
363 if (!info)
364 return -EINVAL;
365
Jacob Pan56722a42020-05-16 14:20:47 +0800366 dmar_domain = to_dmar_domain(domain);
367
368 mutex_lock(&pasid_mutex);
Lu Baolu19abcf72020-07-24 09:49:22 +0800369 ret = pasid_to_svm_sdev(dev, data->hpasid, &svm, &sdev);
370 if (ret)
Jacob Pan56722a42020-05-16 14:20:47 +0800371 goto out;
Jacob Pan56722a42020-05-16 14:20:47 +0800372
Lu Baolu19abcf72020-07-24 09:49:22 +0800373 if (sdev) {
Jacob Pand315e9e2020-07-24 09:49:20 +0800374 /*
375 * Do not allow multiple bindings of the same device-PASID since
376 * there is only one SL page tables per PASID. We may revisit
377 * once sharing PGD across domains are supported.
378 */
Lu Baolu19abcf72020-07-24 09:49:22 +0800379 dev_warn_ratelimited(dev, "Already bound with PASID %u\n",
380 svm->pasid);
381 ret = -EBUSY;
382 goto out;
383 }
384
385 if (!svm) {
Jacob Pan56722a42020-05-16 14:20:47 +0800386 /* We come here when PASID has never been bond to a device. */
387 svm = kzalloc(sizeof(*svm), GFP_KERNEL);
388 if (!svm) {
389 ret = -ENOMEM;
390 goto out;
391 }
392 /* REVISIT: upper layer/VFIO can track host process that bind
393 * the PASID. ioasid_set = mm might be sufficient for vfio to
394 * check pasid VMM ownership. We can drop the following line
395 * once VFIO and IOASID set check is in place.
396 */
397 svm->mm = get_task_mm(current);
398 svm->pasid = data->hpasid;
399 if (data->flags & IOMMU_SVA_GPASID_VAL) {
400 svm->gpasid = data->gpasid;
401 svm->flags |= SVM_FLAG_GUEST_PASID;
402 }
Lu Baolu100b8a12021-06-10 10:00:58 +0800403 pasid_private_add(data->hpasid, svm);
Jacob Pan56722a42020-05-16 14:20:47 +0800404 INIT_LIST_HEAD_RCU(&svm->devs);
405 mmput(svm->mm);
406 }
407 sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
408 if (!sdev) {
409 ret = -ENOMEM;
410 goto out;
411 }
412 sdev->dev = dev;
Liu Yi Leea4e292020-10-30 10:37:23 +0800413 sdev->sid = PCI_DEVID(info->bus, info->devfn);
Liu Yi L9ad9f452021-01-07 00:03:55 +0800414 sdev->iommu = iommu;
Jacob Pan56722a42020-05-16 14:20:47 +0800415
416 /* Only count users if device has aux domains */
417 if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
418 sdev->users = 1;
419
420 /* Set up device context entry for PASID if not enabled already */
421 ret = intel_iommu_enable_pasid(iommu, sdev->dev);
422 if (ret) {
423 dev_err_ratelimited(dev, "Failed to enable PASID capability\n");
424 kfree(sdev);
425 goto out;
426 }
427
428 /*
429 * PASID table is per device for better security. Therefore, for
430 * each bind of a new device even with an existing PASID, we need to
431 * call the nested mode setup function here.
432 */
Lu Baolu420d42f2020-12-31 08:53:23 +0800433 spin_lock_irqsave(&iommu->lock, iflags);
Lu Baolubfe62402020-05-19 09:34:23 +0800434 ret = intel_pasid_setup_nested(iommu, dev,
435 (pgd_t *)(uintptr_t)data->gpgd,
Jacob Pan8d3bb3b2020-09-25 09:32:44 -0700436 data->hpasid, &data->vendor.vtd, dmar_domain,
Jacob Pan56722a42020-05-16 14:20:47 +0800437 data->addr_width);
Lu Baolu420d42f2020-12-31 08:53:23 +0800438 spin_unlock_irqrestore(&iommu->lock, iflags);
Jacob Pan56722a42020-05-16 14:20:47 +0800439 if (ret) {
440 dev_err_ratelimited(dev, "Failed to set up PASID %llu in nested mode, Err %d\n",
441 data->hpasid, ret);
442 /*
443 * PASID entry should be in cleared state if nested mode
444 * set up failed. So we only need to clear IOASID tracking
445 * data such that free call will succeed.
446 */
447 kfree(sdev);
448 goto out;
449 }
450
451 svm->flags |= SVM_FLAG_GUEST_MODE;
452
453 init_rcu_head(&sdev->rcu);
454 list_add_rcu(&sdev->list, &svm->devs);
455 out:
456 if (!IS_ERR_OR_NULL(svm) && list_empty(&svm->devs)) {
Lu Baolu100b8a12021-06-10 10:00:58 +0800457 pasid_private_remove(data->hpasid);
Jacob Pan56722a42020-05-16 14:20:47 +0800458 kfree(svm);
459 }
460
461 mutex_unlock(&pasid_mutex);
462 return ret;
463}
464
Fenghua Yuc7b6bac2020-09-15 09:30:05 -0700465int intel_svm_unbind_gpasid(struct device *dev, u32 pasid)
Jacob Pan56722a42020-05-16 14:20:47 +0800466{
Lu Baoludd6692f2020-07-24 09:49:21 +0800467 struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
Jacob Pan56722a42020-05-16 14:20:47 +0800468 struct intel_svm_dev *sdev;
469 struct intel_svm *svm;
Lu Baolu19abcf72020-07-24 09:49:22 +0800470 int ret;
Jacob Pan56722a42020-05-16 14:20:47 +0800471
472 if (WARN_ON(!iommu))
473 return -EINVAL;
474
475 mutex_lock(&pasid_mutex);
Lu Baolu19abcf72020-07-24 09:49:22 +0800476 ret = pasid_to_svm_sdev(dev, pasid, &svm, &sdev);
477 if (ret)
Jacob Pan56722a42020-05-16 14:20:47 +0800478 goto out;
Jacob Pan56722a42020-05-16 14:20:47 +0800479
Lu Baolu19abcf72020-07-24 09:49:22 +0800480 if (sdev) {
Jacob Pan56722a42020-05-16 14:20:47 +0800481 if (iommu_dev_feature_enabled(dev, IOMMU_DEV_FEAT_AUX))
482 sdev->users--;
483 if (!sdev->users) {
484 list_del_rcu(&sdev->list);
Lu Baolu37e91bd2020-05-16 14:20:57 +0800485 intel_pasid_tear_down_entry(iommu, dev,
486 svm->pasid, false);
Lu Baolu66ac4db2020-05-16 14:20:58 +0800487 intel_svm_drain_prq(dev, svm->pasid);
Jacob Pan56722a42020-05-16 14:20:47 +0800488 kfree_rcu(sdev, rcu);
489
490 if (list_empty(&svm->devs)) {
491 /*
492 * We do not free the IOASID here in that
493 * IOMMU driver did not allocate it.
494 * Unlike native SVM, IOASID for guest use was
495 * allocated prior to the bind call.
496 * In any case, if the free call comes before
497 * the unbind, IOMMU driver will get notified
498 * and perform cleanup.
499 */
Lu Baolu100b8a12021-06-10 10:00:58 +0800500 pasid_private_remove(pasid);
Jacob Pan56722a42020-05-16 14:20:47 +0800501 kfree(svm);
502 }
503 }
Jacob Pan56722a42020-05-16 14:20:47 +0800504 }
505out:
506 mutex_unlock(&pasid_mutex);
507 return ret;
508}
509
Fenghua Yu20f0afd2020-09-15 09:30:13 -0700510static void _load_pasid(void *unused)
511{
512 update_pasid();
513}
514
515static void load_pasid(struct mm_struct *mm, u32 pasid)
516{
517 mutex_lock(&mm->context.lock);
518
519 /* Synchronize with READ_ONCE in update_pasid(). */
520 smp_store_release(&mm->pasid, pasid);
521
522 /* Update PASID MSR on all CPUs running the mm's tasks. */
523 on_each_cpu_mask(mm_cpumask(mm), _load_pasid, NULL, true);
524
525 mutex_unlock(&mm->context.lock);
526}
527
Lu Baolu40483772021-06-10 10:00:59 +0800528static int intel_svm_alloc_pasid(struct device *dev, struct mm_struct *mm,
529 unsigned int flags)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100530{
Lu Baolu40483772021-06-10 10:00:59 +0800531 ioasid_t max_pasid = dev_is_pci(dev) ?
532 pci_max_pasids(to_pci_dev(dev)) : intel_pasid_max_id;
533
534 return iommu_sva_alloc_pasid(mm, PASID_MIN, max_pasid - 1);
535}
536
537static void intel_svm_free_pasid(struct mm_struct *mm)
538{
539 iommu_sva_free_pasid(mm);
540}
541
542static struct iommu_sva *intel_svm_bind_mm(struct intel_iommu *iommu,
543 struct device *dev,
544 struct mm_struct *mm,
545 unsigned int flags)
546{
547 struct device_domain_info *info = get_domain_info(dev);
548 unsigned long iflags, sflags;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100549 struct intel_svm_dev *sdev;
Lu Baolu40483772021-06-10 10:00:59 +0800550 struct intel_svm *svm;
551 int ret = 0;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100552
Lu Baolu40483772021-06-10 10:00:59 +0800553 svm = pasid_private_find(mm->pasid);
554 if (!svm) {
555 svm = kzalloc(sizeof(*svm), GFP_KERNEL);
556 if (!svm)
557 return ERR_PTR(-ENOMEM);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100558
Lu Baolu40483772021-06-10 10:00:59 +0800559 svm->pasid = mm->pasid;
560 svm->mm = mm;
561 svm->flags = flags;
562 INIT_LIST_HEAD_RCU(&svm->devs);
Jacob Pan6eba09a2020-01-02 08:18:05 +0800563
Lu Baolu40483772021-06-10 10:00:59 +0800564 if (!(flags & SVM_FLAG_SUPERVISOR_MODE)) {
565 svm->notifier.ops = &intel_mmuops;
566 ret = mmu_notifier_register(&svm->notifier, mm);
567 if (ret) {
568 kfree(svm);
569 return ERR_PTR(ret);
570 }
571 }
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100572
Lu Baolu40483772021-06-10 10:00:59 +0800573 ret = pasid_private_add(svm->pasid, svm);
574 if (ret) {
575 if (svm->notifier.ops)
576 mmu_notifier_unregister(&svm->notifier, mm);
577 kfree(svm);
578 return ERR_PTR(ret);
Jacob Pan064a57d2020-05-16 14:20:54 +0800579 }
David Woodhouse5cec7532015-10-15 15:52:15 +0100580 }
581
Lu Baolu40483772021-06-10 10:00:59 +0800582 /* Find the matching device in svm list */
Lu Baolu9e52cc02021-06-10 10:01:00 +0800583 sdev = svm_lookup_device_by_dev(svm, dev);
584 if (sdev) {
Lu Baolu40483772021-06-10 10:00:59 +0800585 sdev->users++;
586 goto success;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100587 }
588
589 sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
590 if (!sdev) {
591 ret = -ENOMEM;
Lu Baolu40483772021-06-10 10:00:59 +0800592 goto free_svm;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100593 }
Lu Baolu40483772021-06-10 10:00:59 +0800594
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100595 sdev->dev = dev;
Liu Yi L9ad9f452021-01-07 00:03:55 +0800596 sdev->iommu = iommu;
Lu Baolud7cbc0f2019-03-25 09:30:29 +0800597 sdev->did = FLPT_DEFAULT_DID;
598 sdev->sid = PCI_DEVID(info->bus, info->devfn);
Lu Baolu40483772021-06-10 10:00:59 +0800599 sdev->users = 1;
600 sdev->pasid = svm->pasid;
601 sdev->sva.dev = dev;
602 init_rcu_head(&sdev->rcu);
Lu Baolud7cbc0f2019-03-25 09:30:29 +0800603 if (info->ats_enabled) {
604 sdev->dev_iotlb = 1;
605 sdev->qdep = info->ats_qdep;
606 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
607 sdev->qdep = 0;
608 }
609
Lu Baolu40483772021-06-10 10:00:59 +0800610 /* Setup the pasid table: */
611 sflags = (flags & SVM_FLAG_SUPERVISOR_MODE) ?
612 PASID_FLAG_SUPERVISOR_MODE : 0;
613 sflags |= cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0;
614 spin_lock_irqsave(&iommu->lock, iflags);
615 ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid,
616 FLPT_DEFAULT_DID, sflags);
617 spin_unlock_irqrestore(&iommu->lock, iflags);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100618
Lu Baolu40483772021-06-10 10:00:59 +0800619 if (ret)
620 goto free_sdev;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100621
Lu Baolu40483772021-06-10 10:00:59 +0800622 /* The newly allocated pasid is loaded to the mm. */
623 if (!(flags & SVM_FLAG_SUPERVISOR_MODE) && list_empty(&svm->devs))
624 load_pasid(mm, svm->pasid);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100625
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100626 list_add_rcu(&sdev->list, &svm->devs);
Jacob Pan064a57d2020-05-16 14:20:54 +0800627success:
Lu Baolu40483772021-06-10 10:00:59 +0800628 return &sdev->sva;
629
630free_sdev:
631 kfree(sdev);
632free_svm:
633 if (list_empty(&svm->devs)) {
634 if (svm->notifier.ops)
635 mmu_notifier_unregister(&svm->notifier, mm);
636 pasid_private_remove(mm->pasid);
637 kfree(svm);
638 }
639
640 return ERR_PTR(ret);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100641}
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100642
Jacob Pan064a57d2020-05-16 14:20:54 +0800643/* Caller must hold pasid_mutex */
Fenghua Yuc7b6bac2020-09-15 09:30:05 -0700644static int intel_svm_unbind_mm(struct device *dev, u32 pasid)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100645{
646 struct intel_svm_dev *sdev;
647 struct intel_iommu *iommu;
648 struct intel_svm *svm;
Lu Baolu40483772021-06-10 10:00:59 +0800649 struct mm_struct *mm;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100650 int ret = -EINVAL;
651
Lu Baoludd6692f2020-07-24 09:49:21 +0800652 iommu = device_to_iommu(dev, NULL, NULL);
Lu Baolu4774cc52018-07-14 15:47:01 +0800653 if (!iommu)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100654 goto out;
655
Lu Baolu19abcf72020-07-24 09:49:22 +0800656 ret = pasid_to_svm_sdev(dev, pasid, &svm, &sdev);
657 if (ret)
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100658 goto out;
Lu Baolu40483772021-06-10 10:00:59 +0800659 mm = svm->mm;
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100660
Lu Baolu19abcf72020-07-24 09:49:22 +0800661 if (sdev) {
Jacob Pan034d4732020-01-02 08:18:10 +0800662 sdev->users--;
663 if (!sdev->users) {
664 list_del_rcu(&sdev->list);
665 /* Flush the PASID cache and IOTLB for this device.
666 * Note that we do depend on the hardware *not* using
667 * the PASID any more. Just as we depend on other
668 * devices never using PASIDs that they have no right
669 * to use. We have a *shared* PASID table, because it's
670 * large and has to be physically contiguous. So it's
671 * hard to be as defensive as we might like. */
Lu Baolu37e91bd2020-05-16 14:20:57 +0800672 intel_pasid_tear_down_entry(iommu, dev,
673 svm->pasid, false);
Lu Baolu66ac4db2020-05-16 14:20:58 +0800674 intel_svm_drain_prq(dev, svm->pasid);
Jacob Pan034d4732020-01-02 08:18:10 +0800675 kfree_rcu(sdev, rcu);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100676
Jacob Pan034d4732020-01-02 08:18:10 +0800677 if (list_empty(&svm->devs)) {
Lu Baolu40483772021-06-10 10:00:59 +0800678 intel_svm_free_pasid(mm);
679 if (svm->notifier.ops) {
680 mmu_notifier_unregister(&svm->notifier, mm);
Fenghua Yu20f0afd2020-09-15 09:30:13 -0700681 /* Clear mm's pasid. */
Lu Baolu40483772021-06-10 10:00:59 +0800682 load_pasid(mm, PASID_DISABLED);
Fenghua Yu20f0afd2020-09-15 09:30:13 -0700683 }
Lu Baolu100b8a12021-06-10 10:00:58 +0800684 pasid_private_remove(svm->pasid);
Jacob Pan034d4732020-01-02 08:18:10 +0800685 /* We mandate that no page faults may be outstanding
686 * for the PASID when intel_svm_unbind_mm() is called.
687 * If that is not obeyed, subtle errors will happen.
688 * Let's make them less subtle... */
689 memset(svm, 0x6b, sizeof(*svm));
690 kfree(svm);
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100691 }
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100692 }
693 }
Lu Baolu19abcf72020-07-24 09:49:22 +0800694out:
David Woodhouse2f26e0a2015-09-09 11:40:47 +0100695 return ret;
696}
CQ Tang15060ab2017-05-10 11:39:03 -0700697
David Woodhousea222a7f2015-10-07 23:35:18 +0100698/* Page request queue descriptor */
699struct page_req_dsc {
Jacob Pan5b438f42019-01-11 13:04:57 +0800700 union {
701 struct {
702 u64 type:8;
703 u64 pasid_present:1;
704 u64 priv_data_present:1;
705 u64 rsvd:6;
706 u64 rid:16;
707 u64 pasid:20;
708 u64 exe_req:1;
709 u64 pm_req:1;
710 u64 rsvd2:10;
711 };
712 u64 qw_0;
713 };
714 union {
715 struct {
716 u64 rd_req:1;
717 u64 wr_req:1;
718 u64 lpig:1;
719 u64 prg_index:9;
720 u64 addr:52;
721 };
722 u64 qw_1;
723 };
724 u64 priv_data[2];
David Woodhousea222a7f2015-10-07 23:35:18 +0100725};
726
Jacob Pan52355fb2020-03-17 09:10:18 +0800727#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x20)
Joerg Roedel7f8312a2015-11-17 16:11:39 +0100728
Ashok Raj9d8c3af2017-08-08 13:29:27 -0700729static bool is_canonical_address(u64 addr)
730{
731 int shift = 64 - (__VIRTUAL_MASK_SHIFT + 1);
732 long saddr = (long) addr;
733
734 return (((saddr << shift) >> shift) == saddr);
735}
736
Lu Baolu66ac4db2020-05-16 14:20:58 +0800737/**
738 * intel_svm_drain_prq - Drain page requests and responses for a pasid
739 * @dev: target device
740 * @pasid: pasid for draining
741 *
742 * Drain all pending page requests and responses related to @pasid in both
743 * software and hardware. This is supposed to be called after the device
744 * driver has stopped DMA, the pasid entry has been cleared, and both IOTLB
745 * and DevTLB have been invalidated.
746 *
747 * It waits until all pending page requests for @pasid in the page fault
748 * queue are completed by the prq handling thread. Then follow the steps
749 * described in VT-d spec CH7.10 to drain all page requests and page
750 * responses pending in the hardware.
751 */
Fenghua Yuc7b6bac2020-09-15 09:30:05 -0700752static void intel_svm_drain_prq(struct device *dev, u32 pasid)
Lu Baolu66ac4db2020-05-16 14:20:58 +0800753{
754 struct device_domain_info *info;
755 struct dmar_domain *domain;
756 struct intel_iommu *iommu;
757 struct qi_desc desc[3];
758 struct pci_dev *pdev;
759 int head, tail;
760 u16 sid, did;
761 int qdep;
762
763 info = get_domain_info(dev);
764 if (WARN_ON(!info || !dev_is_pci(dev)))
765 return;
766
767 if (!info->pri_enabled)
768 return;
769
770 iommu = info->iommu;
771 domain = info->domain;
772 pdev = to_pci_dev(dev);
773 sid = PCI_DEVID(info->bus, info->devfn);
774 did = domain->iommu_did[iommu->seq_id];
775 qdep = pci_ats_queue_depth(pdev);
776
777 /*
778 * Check and wait until all pending page requests in the queue are
779 * handled by the prq handling thread.
780 */
781prq_retry:
782 reinit_completion(&iommu->prq_complete);
783 tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
784 head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
785 while (head != tail) {
786 struct page_req_dsc *req;
787
788 req = &iommu->prq[head / sizeof(*req)];
789 if (!req->pasid_present || req->pasid != pasid) {
790 head = (head + sizeof(*req)) & PRQ_RING_MASK;
791 continue;
792 }
793
794 wait_for_completion(&iommu->prq_complete);
795 goto prq_retry;
796 }
797
Lu Baolud5b9e4b2021-06-10 10:01:03 +0800798 iopf_queue_flush_dev(dev);
799
Lu Baolu66ac4db2020-05-16 14:20:58 +0800800 /*
801 * Perform steps described in VT-d spec CH7.10 to drain page
802 * requests and responses in hardware.
803 */
804 memset(desc, 0, sizeof(desc));
805 desc[0].qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
806 QI_IWD_FENCE |
807 QI_IWD_TYPE;
808 desc[1].qw0 = QI_EIOTLB_PASID(pasid) |
809 QI_EIOTLB_DID(did) |
810 QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
811 QI_EIOTLB_TYPE;
812 desc[2].qw0 = QI_DEV_EIOTLB_PASID(pasid) |
813 QI_DEV_EIOTLB_SID(sid) |
814 QI_DEV_EIOTLB_QDEP(qdep) |
815 QI_DEIOTLB_TYPE |
816 QI_DEV_IOTLB_PFSID(info->pfsid);
817qi_retry:
818 reinit_completion(&iommu->prq_complete);
819 qi_submit_sync(iommu, desc, 3, QI_OPT_WAIT_DRAIN);
820 if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) {
821 wait_for_completion(&iommu->prq_complete);
822 goto qi_retry;
823 }
824}
825
Lu Baolueb8d93e2020-07-24 09:49:23 +0800826static int prq_to_iommu_prot(struct page_req_dsc *req)
827{
828 int prot = 0;
829
830 if (req->rd_req)
831 prot |= IOMMU_FAULT_PERM_READ;
832 if (req->wr_req)
833 prot |= IOMMU_FAULT_PERM_WRITE;
834 if (req->exe_req)
835 prot |= IOMMU_FAULT_PERM_EXEC;
836 if (req->pm_req)
837 prot |= IOMMU_FAULT_PERM_PRIV;
838
839 return prot;
840}
841
Lu Baolu0f4834ab2021-06-10 10:01:08 +0800842static int intel_svm_prq_report(struct intel_iommu *iommu, struct device *dev,
843 struct page_req_dsc *desc)
Lu Baolueb8d93e2020-07-24 09:49:23 +0800844{
845 struct iommu_fault_event event;
846
847 if (!dev || !dev_is_pci(dev))
848 return -ENODEV;
849
850 /* Fill in event data for device specific processing */
851 memset(&event, 0, sizeof(struct iommu_fault_event));
852 event.fault.type = IOMMU_FAULT_PAGE_REQ;
Lu Baolu03d20502021-03-20 10:54:11 +0800853 event.fault.prm.addr = (u64)desc->addr << VTD_PAGE_SHIFT;
Lu Baolueb8d93e2020-07-24 09:49:23 +0800854 event.fault.prm.pasid = desc->pasid;
855 event.fault.prm.grpid = desc->prg_index;
856 event.fault.prm.perm = prq_to_iommu_prot(desc);
857
858 if (desc->lpig)
859 event.fault.prm.flags |= IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE;
860 if (desc->pasid_present) {
861 event.fault.prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
862 event.fault.prm.flags |= IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID;
863 }
864 if (desc->priv_data_present) {
865 /*
866 * Set last page in group bit if private data is present,
867 * page response is required as it does for LPIG.
868 * iommu_report_device_fault() doesn't understand this vendor
869 * specific requirement thus we set last_page as a workaround.
870 */
871 event.fault.prm.flags |= IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE;
872 event.fault.prm.flags |= IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA;
Gustavo A. R. Silva606636d2021-06-10 10:01:09 +0800873 event.fault.prm.private_data[0] = desc->priv_data[0];
874 event.fault.prm.private_data[1] = desc->priv_data[1];
Lu Baolu0f4834ab2021-06-10 10:01:08 +0800875 } else if (dmar_latency_enabled(iommu, DMAR_LATENCY_PRQ)) {
876 /*
877 * If the private data fields are not used by hardware, use it
878 * to monitor the prq handle latency.
879 */
880 event.fault.prm.private_data[0] = ktime_to_ns(ktime_get());
Lu Baolueb8d93e2020-07-24 09:49:23 +0800881 }
882
883 return iommu_report_device_fault(dev, &event);
884}
885
Lu Baoluae7f09b2021-06-10 10:01:01 +0800886static void handle_bad_prq_event(struct intel_iommu *iommu,
887 struct page_req_dsc *req, int result)
888{
889 struct qi_desc desc;
890
891 pr_err("%s: Invalid page request: %08llx %08llx\n",
892 iommu->name, ((unsigned long long *)req)[0],
893 ((unsigned long long *)req)[1]);
894
895 /*
896 * Per VT-d spec. v3.0 ch7.7, system software must
897 * respond with page group response if private data
898 * is present (PDP) or last page in group (LPIG) bit
899 * is set. This is an additional VT-d feature beyond
900 * PCI ATS spec.
901 */
902 if (!req->lpig && !req->priv_data_present)
903 return;
904
905 desc.qw0 = QI_PGRP_PASID(req->pasid) |
906 QI_PGRP_DID(req->rid) |
907 QI_PGRP_PASID_P(req->pasid_present) |
908 QI_PGRP_PDP(req->priv_data_present) |
909 QI_PGRP_RESP_CODE(result) |
910 QI_PGRP_RESP_TYPE;
911 desc.qw1 = QI_PGRP_IDX(req->prg_index) |
912 QI_PGRP_LPIG(req->lpig);
Lu Baoluae7f09b2021-06-10 10:01:01 +0800913
Gustavo A. R. Silva606636d2021-06-10 10:01:09 +0800914 if (req->priv_data_present) {
915 desc.qw2 = req->priv_data[0];
916 desc.qw3 = req->priv_data[1];
917 } else {
918 desc.qw2 = 0;
919 desc.qw3 = 0;
920 }
921
Lu Baoluae7f09b2021-06-10 10:01:01 +0800922 qi_submit_sync(iommu, &desc, 1, 0);
923}
924
David Woodhousea222a7f2015-10-07 23:35:18 +0100925static irqreturn_t prq_event_thread(int irq, void *d)
926{
Lu Baolueb8d93e2020-07-24 09:49:23 +0800927 struct intel_svm_dev *sdev = NULL;
David Woodhousea222a7f2015-10-07 23:35:18 +0100928 struct intel_iommu *iommu = d;
929 struct intel_svm *svm = NULL;
Lu Baoluae7f09b2021-06-10 10:01:01 +0800930 struct page_req_dsc *req;
931 int head, tail, handled;
932 u64 address;
David Woodhousea222a7f2015-10-07 23:35:18 +0100933
Lu Baoluae7f09b2021-06-10 10:01:01 +0800934 /*
935 * Clear PPR bit before reading head/tail registers, to ensure that
936 * we get a new interrupt if needed.
937 */
David Woodhouse46924002016-02-15 12:42:38 +0000938 writel(DMA_PRS_PPR, iommu->reg + DMAR_PRS_REG);
939
David Woodhousea222a7f2015-10-07 23:35:18 +0100940 tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
941 head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
Lu Baoluae7f09b2021-06-10 10:01:01 +0800942 handled = (head != tail);
David Woodhousea222a7f2015-10-07 23:35:18 +0100943 while (head != tail) {
David Woodhousea222a7f2015-10-07 23:35:18 +0100944 req = &iommu->prq[head / sizeof(*req)];
David Woodhouse7f92a2e2015-10-16 17:22:31 +0100945 address = (u64)req->addr << VTD_PAGE_SHIFT;
Lu Baoluae7f09b2021-06-10 10:01:01 +0800946
947 if (unlikely(!req->pasid_present)) {
948 pr_err("IOMMU: %s: Page request without PASID\n",
949 iommu->name);
950bad_req:
951 svm = NULL;
952 sdev = NULL;
953 handle_bad_prq_event(iommu, req, QI_RESP_INVALID);
954 goto prq_advance;
David Woodhousea222a7f2015-10-07 23:35:18 +0100955 }
Lu Baoluae7f09b2021-06-10 10:01:01 +0800956
957 if (unlikely(!is_canonical_address(address))) {
958 pr_err("IOMMU: %s: Address is not canonical\n",
959 iommu->name);
960 goto bad_req;
Jacob Pan78a523f2021-03-02 02:13:59 -0800961 }
Lu Baoluae7f09b2021-06-10 10:01:01 +0800962
963 if (unlikely(req->pm_req && (req->rd_req | req->wr_req))) {
964 pr_err("IOMMU: %s: Page request in Privilege Mode\n",
965 iommu->name);
966 goto bad_req;
Jacob Pan78a523f2021-03-02 02:13:59 -0800967 }
Lu Baoluae7f09b2021-06-10 10:01:01 +0800968
969 if (unlikely(req->exe_req && req->rd_req)) {
970 pr_err("IOMMU: %s: Execution request not supported\n",
971 iommu->name);
972 goto bad_req;
973 }
974
David Woodhousea222a7f2015-10-07 23:35:18 +0100975 if (!svm || svm->pasid != req->pasid) {
Lu Baoluae7f09b2021-06-10 10:01:01 +0800976 /*
977 * It can't go away, because the driver is not permitted
David Woodhousea222a7f2015-10-07 23:35:18 +0100978 * to unbind the mm while any page faults are outstanding.
Lu Baoluae7f09b2021-06-10 10:01:01 +0800979 */
980 svm = pasid_private_find(req->pasid);
981 if (IS_ERR_OR_NULL(svm) || (svm->flags & SVM_FLAG_SUPERVISOR_MODE))
982 goto bad_req;
David Woodhousea222a7f2015-10-07 23:35:18 +0100983 }
984
Lu Baoluae7f09b2021-06-10 10:01:01 +0800985 if (!sdev || sdev->sid != req->rid) {
Lu Baolu9e52cc02021-06-10 10:01:00 +0800986 sdev = svm_lookup_device_by_sid(svm, req->rid);
Lu Baoluae7f09b2021-06-10 10:01:01 +0800987 if (!sdev)
988 goto bad_req;
989 }
Ashok Raj9d8c3af2017-08-08 13:29:27 -0700990
Lu Baolue93a67f2021-06-10 10:01:04 +0800991 sdev->prq_seq_number++;
992
Lu Baolueb8d93e2020-07-24 09:49:23 +0800993 /*
994 * If prq is to be handled outside iommu driver via receiver of
995 * the fault notifiers, we skip the page response here.
996 */
Lu Baolu0f4834ab2021-06-10 10:01:08 +0800997 if (intel_svm_prq_report(iommu, sdev->dev, req))
Lu Baolud5b9e4b2021-06-10 10:01:03 +0800998 handle_bad_prq_event(iommu, req, QI_RESP_INVALID);
Lu Baolue93a67f2021-06-10 10:01:04 +0800999
1000 trace_prq_report(iommu, sdev->dev, req->qw_0, req->qw_1,
1001 req->priv_data[0], req->priv_data[1],
1002 sdev->prq_seq_number);
Lu Baolueb8d93e2020-07-24 09:49:23 +08001003prq_advance:
David Woodhousea222a7f2015-10-07 23:35:18 +01001004 head = (head + sizeof(*req)) & PRQ_RING_MASK;
1005 }
1006
1007 dmar_writeq(iommu->reg + DMAR_PQH_REG, tail);
1008
Lu Baolu66ac4db2020-05-16 14:20:58 +08001009 /*
1010 * Clear the page request overflow bit and wake up all threads that
1011 * are waiting for the completion of this handling.
1012 */
Lu Baolu28a77182021-01-26 16:07:29 +08001013 if (readl(iommu->reg + DMAR_PRS_REG) & DMA_PRS_PRO) {
1014 pr_info_ratelimited("IOMMU: %s: PRQ overflow detected\n",
1015 iommu->name);
1016 head = dmar_readq(iommu->reg + DMAR_PQH_REG) & PRQ_RING_MASK;
1017 tail = dmar_readq(iommu->reg + DMAR_PQT_REG) & PRQ_RING_MASK;
1018 if (head == tail) {
Lu Baolud5b9e4b2021-06-10 10:01:03 +08001019 iopf_queue_discard_partial(iommu->iopf_queue);
Lu Baolu28a77182021-01-26 16:07:29 +08001020 writel(DMA_PRS_PRO, iommu->reg + DMAR_PRS_REG);
1021 pr_info_ratelimited("IOMMU: %s: PRQ overflow cleared",
1022 iommu->name);
1023 }
1024 }
Lu Baolu66ac4db2020-05-16 14:20:58 +08001025
1026 if (!completion_done(&iommu->prq_complete))
1027 complete(&iommu->prq_complete);
1028
David Woodhousea222a7f2015-10-07 23:35:18 +01001029 return IRQ_RETVAL(handled);
1030}
Jacob Pan064a57d2020-05-16 14:20:54 +08001031
Lu Baolu40483772021-06-10 10:00:59 +08001032struct iommu_sva *intel_svm_bind(struct device *dev, struct mm_struct *mm, void *drvdata)
Jacob Pan064a57d2020-05-16 14:20:54 +08001033{
Lu Baolu40483772021-06-10 10:00:59 +08001034 struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
Fenghua Yu2a5054c2020-09-15 09:30:06 -07001035 unsigned int flags = 0;
Lu Baolu40483772021-06-10 10:00:59 +08001036 struct iommu_sva *sva;
Jacob Pan064a57d2020-05-16 14:20:54 +08001037 int ret;
1038
Jacob Pan064a57d2020-05-16 14:20:54 +08001039 if (drvdata)
Fenghua Yu2a5054c2020-09-15 09:30:06 -07001040 flags = *(unsigned int *)drvdata;
Jacob Pan064a57d2020-05-16 14:20:54 +08001041
Lu Baolu40483772021-06-10 10:00:59 +08001042 if (flags & SVM_FLAG_SUPERVISOR_MODE) {
1043 if (!ecap_srs(iommu->ecap)) {
1044 dev_err(dev, "%s: Supervisor PASID not supported\n",
1045 iommu->name);
1046 return ERR_PTR(-EOPNOTSUPP);
1047 }
1048
1049 if (mm) {
1050 dev_err(dev, "%s: Supervisor PASID with user provided mm\n",
1051 iommu->name);
1052 return ERR_PTR(-EINVAL);
1053 }
1054
1055 mm = &init_mm;
1056 }
1057
1058 mutex_lock(&pasid_mutex);
1059 ret = intel_svm_alloc_pasid(dev, mm, flags);
1060 if (ret) {
1061 mutex_unlock(&pasid_mutex);
1062 return ERR_PTR(ret);
1063 }
1064
1065 sva = intel_svm_bind_mm(iommu, dev, mm, flags);
1066 if (IS_ERR_OR_NULL(sva))
1067 intel_svm_free_pasid(mm);
Jacob Pan064a57d2020-05-16 14:20:54 +08001068 mutex_unlock(&pasid_mutex);
1069
1070 return sva;
1071}
1072
1073void intel_svm_unbind(struct iommu_sva *sva)
1074{
Lu Baolu40483772021-06-10 10:00:59 +08001075 struct intel_svm_dev *sdev = to_intel_svm_dev(sva);
Jacob Pan064a57d2020-05-16 14:20:54 +08001076
1077 mutex_lock(&pasid_mutex);
Jacob Pan064a57d2020-05-16 14:20:54 +08001078 intel_svm_unbind_mm(sdev->dev, sdev->pasid);
1079 mutex_unlock(&pasid_mutex);
1080}
1081
Fenghua Yuc7b6bac2020-09-15 09:30:05 -07001082u32 intel_svm_get_pasid(struct iommu_sva *sva)
Jacob Pan064a57d2020-05-16 14:20:54 +08001083{
1084 struct intel_svm_dev *sdev;
Fenghua Yuc7b6bac2020-09-15 09:30:05 -07001085 u32 pasid;
Jacob Pan064a57d2020-05-16 14:20:54 +08001086
1087 mutex_lock(&pasid_mutex);
1088 sdev = to_intel_svm_dev(sva);
1089 pasid = sdev->pasid;
1090 mutex_unlock(&pasid_mutex);
1091
1092 return pasid;
1093}
Lu Baolu8b737122020-07-24 09:49:24 +08001094
1095int intel_svm_page_response(struct device *dev,
1096 struct iommu_fault_event *evt,
1097 struct iommu_page_response *msg)
1098{
1099 struct iommu_fault_page_request *prm;
1100 struct intel_svm_dev *sdev = NULL;
1101 struct intel_svm *svm = NULL;
1102 struct intel_iommu *iommu;
1103 bool private_present;
1104 bool pasid_present;
1105 bool last_page;
1106 u8 bus, devfn;
1107 int ret = 0;
1108 u16 sid;
1109
1110 if (!dev || !dev_is_pci(dev))
1111 return -ENODEV;
1112
1113 iommu = device_to_iommu(dev, &bus, &devfn);
1114 if (!iommu)
1115 return -ENODEV;
1116
1117 if (!msg || !evt)
1118 return -EINVAL;
1119
1120 mutex_lock(&pasid_mutex);
1121
1122 prm = &evt->fault.prm;
1123 sid = PCI_DEVID(bus, devfn);
1124 pasid_present = prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID;
1125 private_present = prm->flags & IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA;
1126 last_page = prm->flags & IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE;
1127
1128 if (!pasid_present) {
1129 ret = -EINVAL;
1130 goto out;
1131 }
1132
1133 if (prm->pasid == 0 || prm->pasid >= PASID_MAX) {
1134 ret = -EINVAL;
1135 goto out;
1136 }
1137
1138 ret = pasid_to_svm_sdev(dev, prm->pasid, &svm, &sdev);
1139 if (ret || !sdev) {
1140 ret = -ENODEV;
1141 goto out;
1142 }
1143
1144 /*
1145 * For responses from userspace, need to make sure that the
1146 * pasid has been bound to its mm.
1147 */
1148 if (svm->flags & SVM_FLAG_GUEST_MODE) {
1149 struct mm_struct *mm;
1150
1151 mm = get_task_mm(current);
1152 if (!mm) {
1153 ret = -EINVAL;
1154 goto out;
1155 }
1156
1157 if (mm != svm->mm) {
1158 ret = -ENODEV;
1159 mmput(mm);
1160 goto out;
1161 }
1162
1163 mmput(mm);
1164 }
1165
1166 /*
1167 * Per VT-d spec. v3.0 ch7.7, system software must respond
1168 * with page group response if private data is present (PDP)
1169 * or last page in group (LPIG) bit is set. This is an
1170 * additional VT-d requirement beyond PCI ATS spec.
1171 */
1172 if (last_page || private_present) {
1173 struct qi_desc desc;
1174
1175 desc.qw0 = QI_PGRP_PASID(prm->pasid) | QI_PGRP_DID(sid) |
1176 QI_PGRP_PASID_P(pasid_present) |
1177 QI_PGRP_PDP(private_present) |
1178 QI_PGRP_RESP_CODE(msg->code) |
1179 QI_PGRP_RESP_TYPE;
1180 desc.qw1 = QI_PGRP_IDX(prm->grpid) | QI_PGRP_LPIG(last_page);
1181 desc.qw2 = 0;
1182 desc.qw3 = 0;
Gustavo A. R. Silva606636d2021-06-10 10:01:09 +08001183
1184 if (private_present) {
1185 desc.qw2 = prm->private_data[0];
1186 desc.qw3 = prm->private_data[1];
1187 } else if (prm->private_data[0]) {
Lu Baolu0f4834ab2021-06-10 10:01:08 +08001188 dmar_latency_update(iommu, DMAR_LATENCY_PRQ,
1189 ktime_to_ns(ktime_get()) - prm->private_data[0]);
Gustavo A. R. Silva606636d2021-06-10 10:01:09 +08001190 }
Lu Baolu8b737122020-07-24 09:49:24 +08001191
1192 qi_submit_sync(iommu, &desc, 1, 0);
1193 }
1194out:
1195 mutex_unlock(&pasid_mutex);
1196 return ret;
1197}