History

Merge tag 'vfio-v5.16-rc1' of git://github.com/awilliam/linux-vfio

Pull VFIO updates from Alex Williamson: - Cleanup vfio iommu_group creation (Christoph Hellwig) - Add individual device reset for vfio/fsl-mc (Diana Craciun) - IGD OpRegion 2.0+ support (Colin Xu) - Use modern cdev lifecycle for vfio_group (Jason Gunthorpe) - Use new mdev API in vfio_ccw (Jason Gunthorpe) * tag 'vfio-v5.16-rc1' of git://github.com/awilliam/linux-vfio: (27 commits) vfio/ccw: Convert to use vfio_register_emulated_iommu_dev() vfio/ccw: Pass vfio_ccw_private not mdev_device to various functions vfio/ccw: Use functions for alloc/free of the vfio_ccw_private vfio/ccw: Remove unneeded GFP_DMA vfio: Use cdev_device_add() instead of device_create() vfio: Use a refcount_t instead of a kref in the vfio_group vfio: Don't leak a group reference if the group already exists vfio: Do not open code the group list search in vfio_create_group() vfio: Delete vfio_get/put_group from vfio_iommu_group_notifier() vfio/pci: Add OpRegion 2.0+ Extended VBT support. vfio/iommu_type1: remove IS_IOMMU_CAP_DOMAIN_IN_CONTAINER vfio/iommu_type1: remove the "external" domain vfio/iommu_type1: initialize pgsize_bitmap in ->open vfio/spapr_tce: reject mediated devices vfio: clean up the check for mediated device in vfio_iommu_type1 vfio: remove the unused mdev iommu hook vfio: move the vfio_iommu_driver_ops interface out of <linux/vfio.h> vfio: remove unused method from vfio_iommu_driver_ops vfio: simplify iommu group allocation for mediated devices vfio: remove the iommudata hack for noiommu groups ...

Linus Torvalds committed 5 years ago

Commit d4ec3d52 parents a602285 3bf131123 files · +945 −903Browse files

Unified · Split

23 files
  1. drivers/bus/fsl-mc/Makefile +2 −1
  2. drivers/bus/fsl-mc/fsl-mc-private.h +35 −4
  3. drivers/bus/fsl-mc/obj-api.c +103 −0
  4. drivers/s390/cio/vfio_ccw_drv.c +81 −55
  5. drivers/s390/cio/vfio_ccw_ops.c +80 −62
  6. drivers/s390/cio/vfio_ccw_private.h +5 −0
  7. drivers/s390/crypto/vfio_ap_ops.c +1 −1
  8. drivers/vfio/fsl-mc/vfio_fsl_mc.c +32 −30
  9. drivers/vfio/mdev/mdev_driver.c +4 −41
  10. drivers/vfio/mdev/vfio_mdev.c +1 −1
  11. drivers/vfio/pci/vfio_pci_core.c +2 −11
  12. drivers/vfio/pci/vfio_pci_igd.c +175 −59
  13. drivers/vfio/platform/vfio_platform_common.c +1 −12
  14. drivers/vfio/vfio.c +255 −367
  15. drivers/vfio/vfio.h +72 −0
  16. drivers/vfio/vfio_iommu_spapr_tce.c +5 −1
  17. drivers/vfio/vfio_iommu_type1.c +73 −183
  18. include/linux/fsl/mc.h +14 −0
  19. include/linux/mdev.h +0 −20
  20. include/linux/vfio.h +1 −52
  21. samples/vfio-mdev/mbochs.c +1 −1
  22. samples/vfio-mdev/mdpy.c +1 −1
  23. samples/vfio-mdev/mtty.c +1 −1
drivers/bus/fsl-mc/Makefile+2−1
@@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \ · 14 unmodified lines
15 dprc-driver.o \15 dprc-driver.o \
16 fsl-mc-allocator.o \16 fsl-mc-allocator.o \
17 fsl-mc-msi.o \17 fsl-mc-msi.o \
18 dpmcp.o18 dpmcp.o \
19 obj-api.o
19 20
20# MC userspace support21# MC userspace support
21obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o22obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
drivers/bus/fsl-mc/fsl-mc-private.h+35−4
@@ -48,7 +48,6 @@ struct dpmng_rsp_get_version { · 47 unmodified lines
48 48
49/* DPMCP command IDs */49/* DPMCP command IDs */
50#define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800)50#define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800)
51#define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b)
52#define DPMCP_CMDID_RESET DPMCP_CMD(0x005)51#define DPMCP_CMDID_RESET DPMCP_CMD(0x005)
53 52
54struct dpmcp_cmd_open {53struct dpmcp_cmd_open {
@@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, · 36 unmodified lines
91 90
92/* DPRC command IDs */91/* DPRC command IDs */
93#define DPRC_CMDID_CLOSE DPRC_CMD(0x800)92#define DPRC_CMDID_CLOSE DPRC_CMD(0x800)
94#define DPRC_CMDID_OPEN DPRC_CMD(0x805)
95#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05)93#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05)
96 94
97#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004)95#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004)
@@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, · 355 unmodified lines
453 451
454/* Command IDs */452/* Command IDs */
455#define DPBP_CMDID_CLOSE DPBP_CMD(0x800)453#define DPBP_CMDID_CLOSE DPBP_CMD(0x800)
456#define DPBP_CMDID_OPEN DPBP_CMD(0x804)
457 454
458#define DPBP_CMDID_ENABLE DPBP_CMD(0x002)455#define DPBP_CMDID_ENABLE DPBP_CMD(0x002)
459#define DPBP_CMDID_DISABLE DPBP_CMD(0x003)456#define DPBP_CMDID_DISABLE DPBP_CMD(0x003)
@@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes { · 32 unmodified lines
492 489
493/* Command IDs */490/* Command IDs */
494#define DPCON_CMDID_CLOSE DPCON_CMD(0x800)491#define DPCON_CMDID_CLOSE DPCON_CMD(0x800)
495#define DPCON_CMDID_OPEN DPCON_CMD(0x808)
496 492
497#define DPCON_CMDID_ENABLE DPCON_CMD(0x002)493#define DPCON_CMDID_ENABLE DPCON_CMD(0x002)
498#define DPCON_CMDID_DISABLE DPCON_CMD(0x003)494#define DPCON_CMDID_DISABLE DPCON_CMD(0x003)
@@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification { · 25 unmodified lines
524 __le64 user_ctx;520 __le64 user_ctx;
525};521};
526 522
523/*
524 * Generic FSL MC API
525 */
526
527/* generic command versioning */
528#define OBJ_CMD_BASE_VERSION 1
529#define OBJ_CMD_ID_OFFSET 4
530
531#define OBJ_CMD(id) (((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION)
532
533/* open command codes */
534#define DPRTC_CMDID_OPEN OBJ_CMD(0x810)
535#define DPNI_CMDID_OPEN OBJ_CMD(0x801)
536#define DPSW_CMDID_OPEN OBJ_CMD(0x802)
537#define DPIO_CMDID_OPEN OBJ_CMD(0x803)
538#define DPBP_CMDID_OPEN OBJ_CMD(0x804)
539#define DPRC_CMDID_OPEN OBJ_CMD(0x805)
540#define DPDMUX_CMDID_OPEN OBJ_CMD(0x806)
541#define DPCI_CMDID_OPEN OBJ_CMD(0x807)
542#define DPCON_CMDID_OPEN OBJ_CMD(0x808)
543#define DPSECI_CMDID_OPEN OBJ_CMD(0x809)
544#define DPAIOP_CMDID_OPEN OBJ_CMD(0x80a)
545#define DPMCP_CMDID_OPEN OBJ_CMD(0x80b)
546#define DPMAC_CMDID_OPEN OBJ_CMD(0x80c)
547#define DPDCEI_CMDID_OPEN OBJ_CMD(0x80d)
548#define DPDMAI_CMDID_OPEN OBJ_CMD(0x80e)
549#define DPDBG_CMDID_OPEN OBJ_CMD(0x80f)
550
551/* Generic object command IDs */
552#define OBJ_CMDID_CLOSE OBJ_CMD(0x800)
553#define OBJ_CMDID_RESET OBJ_CMD(0x005)
554
555struct fsl_mc_obj_cmd_open {
556 __le32 obj_id;
557};
527 558
528/**559/**
529 * struct fsl_mc_resource_pool - Pool of MC resources of a given560 * struct fsl_mc_resource_pool - Pool of MC resources of a given
drivers/bus/fsl-mc/obj-api.c+103−0
@@ -0,0 +1,103 @@
1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2/*
3 * Copyright 2021 NXP
4 *
5 */
6#include <linux/kernel.h>
7#include <linux/fsl/mc.h>
8
9#include "fsl-mc-private.h"
10
11static int fsl_mc_get_open_cmd_id(const char *type)
12{
13 static const struct {
14 int cmd_id;
15 const char *type;
16 } dev_ids[] = {
17 { DPRTC_CMDID_OPEN, "dprtc" },
18 { DPRC_CMDID_OPEN, "dprc" },
19 { DPNI_CMDID_OPEN, "dpni" },
20 { DPIO_CMDID_OPEN, "dpio" },
21 { DPSW_CMDID_OPEN, "dpsw" },
22 { DPBP_CMDID_OPEN, "dpbp" },
23 { DPCON_CMDID_OPEN, "dpcon" },
24 { DPMCP_CMDID_OPEN, "dpmcp" },
25 { DPMAC_CMDID_OPEN, "dpmac" },
26 { DPSECI_CMDID_OPEN, "dpseci" },
27 { DPDMUX_CMDID_OPEN, "dpdmux" },
28 { DPDCEI_CMDID_OPEN, "dpdcei" },
29 { DPAIOP_CMDID_OPEN, "dpaiop" },
30 { DPCI_CMDID_OPEN, "dpci" },
31 { DPDMAI_CMDID_OPEN, "dpdmai" },
32 { DPDBG_CMDID_OPEN, "dpdbg" },
33 { 0, NULL }
34 };
35 int i;
36
37 for (i = 0; dev_ids[i].type; i++)
38 if (!strcmp(dev_ids[i].type, type))
39 return dev_ids[i].cmd_id;
40
41 return -1;
42}
43
44int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
45 u32 cmd_flags,
46 int obj_id,
47 char *obj_type,
48 u16 *token)
49{
50 struct fsl_mc_command cmd = { 0 };
51 struct fsl_mc_obj_cmd_open *cmd_params;
52 int err = 0;
53 int cmd_id = fsl_mc_get_open_cmd_id(obj_type);
54
55 if (cmd_id == -1)
56 return -ENODEV;
57
58 /* prepare command */
59 cmd.header = mc_encode_cmd_header(cmd_id, cmd_flags, 0);
60 cmd_params = (struct fsl_mc_obj_cmd_open *)cmd.params;
61 cmd_params->obj_id = cpu_to_le32(obj_id);
62
63 /* send command to mc*/
64 err = mc_send_command(mc_io, &cmd);
65 if (err)
66 return err;
67
68 /* retrieve response parameters */
69 *token = mc_cmd_hdr_read_token(&cmd);
70
71 return err;
72}
73EXPORT_SYMBOL_GPL(fsl_mc_obj_open);
74
75int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
76 u32 cmd_flags,
77 u16 token)
78{
79 struct fsl_mc_command cmd = { 0 };
80
81 /* prepare command */
82 cmd.header = mc_encode_cmd_header(OBJ_CMDID_CLOSE, cmd_flags,
83 token);
84
85 /* send command to mc*/
86 return mc_send_command(mc_io, &cmd);
87}
88EXPORT_SYMBOL_GPL(fsl_mc_obj_close);
89
90int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
91 u32 cmd_flags,
92 u16 token)
93{
94 struct fsl_mc_command cmd = { 0 };
95
96 /* prepare command */
97 cmd.header = mc_encode_cmd_header(OBJ_CMDID_RESET, cmd_flags,
98 token);
99
100 /* send command to mc*/
101 return mc_send_command(mc_io, &cmd);
102}
103EXPORT_SYMBOL_GPL(fsl_mc_obj_reset);
drivers/s390/cio/vfio_ccw_drv.c+81−55
@@ -137,77 +137,107 @@ static void vfio_ccw_sch_irq(struct subchannel *sch) · 136 unmodified lines
137 vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);137 vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
138}138}
139 139
140static void vfio_ccw_free_regions(struct vfio_ccw_private *private)140static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
141{141{
142 if (private->crw_region)
143 kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
144 if (private->schib_region)
145 kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
146 if (private->cmd_region)
147 kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
148 if (private->io_region)
149 kmem_cache_free(vfio_ccw_io_region, private->io_region);
150}
151
152static int vfio_ccw_sch_probe(struct subchannel *sch)
153{
154 struct pmcw *pmcw = &sch->schib.pmcw;
155 struct vfio_ccw_private *private;142 struct vfio_ccw_private *private;
156 int ret = -ENOMEM;
157 143
158 if (pmcw->qf) {144 private = kzalloc(sizeof(*private), GFP_KERNEL);
159 dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
160 dev_name(&sch->dev));
161 return -ENODEV;
162 }
163
164 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
165 if (!private)145 if (!private)
166 return -ENOMEM;146 return ERR_PTR(-ENOMEM);
147
148 private->sch = sch;
149 mutex_init(&private->io_mutex);
150 private->state = VFIO_CCW_STATE_NOT_OPER;
151 INIT_LIST_HEAD(&private->crw);
152 INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
153 INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
154 atomic_set(&private->avail, 1);
167 155
168 private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),156 private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
169 GFP_KERNEL);157 GFP_KERNEL);
170 if (!private->cp.guest_cp)158 if (!private->cp.guest_cp)
171 goto out_free;159 goto out_free_private;
172 160
173 private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,161 private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
174 GFP_KERNEL | GFP_DMA);162 GFP_KERNEL | GFP_DMA);
175 if (!private->io_region)163 if (!private->io_region)
176 goto out_free;164 goto out_free_cp;
177 165
178 private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,166 private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,
179 GFP_KERNEL | GFP_DMA);167 GFP_KERNEL | GFP_DMA);
180 if (!private->cmd_region)168 if (!private->cmd_region)
181 goto out_free;169 goto out_free_io;
182 170
183 private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,171 private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
184 GFP_KERNEL | GFP_DMA);172 GFP_KERNEL | GFP_DMA);
185 173
186 if (!private->schib_region)174 if (!private->schib_region)
187 goto out_free;175 goto out_free_cmd;
188 176
189 private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,177 private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,
190 GFP_KERNEL | GFP_DMA);178 GFP_KERNEL | GFP_DMA);
191 179
192 if (!private->crw_region)180 if (!private->crw_region)
193 goto out_free;181 goto out_free_schib;
182 return private;
183
184out_free_schib:
185 kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
186out_free_cmd:
187 kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
188out_free_io:
189 kmem_cache_free(vfio_ccw_io_region, private->io_region);
190out_free_cp:
191 kfree(private->cp.guest_cp);
192out_free_private:
193 mutex_destroy(&private->io_mutex);
194 kfree(private);
195 return ERR_PTR(-ENOMEM);
196}
197
198static void vfio_ccw_free_private(struct vfio_ccw_private *private)
199{
200 struct vfio_ccw_crw *crw, *temp;
201
202 list_for_each_entry_safe(crw, temp, &private->crw, next) {
203 list_del(&crw->next);
204 kfree(crw);
205 }
206
207 kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
208 kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
209 kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
210 kmem_cache_free(vfio_ccw_io_region, private->io_region);
211 kfree(private->cp.guest_cp);
212 mutex_destroy(&private->io_mutex);
213 kfree(private);
214}
215
216static int vfio_ccw_sch_probe(struct subchannel *sch)
217{
218 struct pmcw *pmcw = &sch->schib.pmcw;
219 struct vfio_ccw_private *private;
220 int ret = -ENOMEM;
221
222 if (pmcw->qf) {
223 dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
224 dev_name(&sch->dev));
225 return -ENODEV;
226 }
227
228 private = vfio_ccw_alloc_private(sch);
229 if (IS_ERR(private))
230 return PTR_ERR(private);
194 231
195 private->sch = sch;
196 dev_set_drvdata(&sch->dev, private);232 dev_set_drvdata(&sch->dev, private);
197 mutex_init(&private->io_mutex);
198 233
199 spin_lock_irq(sch->lock);234 spin_lock_irq(sch->lock);
200 private->state = VFIO_CCW_STATE_NOT_OPER;
201 sch->isc = VFIO_CCW_ISC;235 sch->isc = VFIO_CCW_ISC;
202 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);236 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
203 spin_unlock_irq(sch->lock);237 spin_unlock_irq(sch->lock);
204 if (ret)238 if (ret)
205 goto out_free;239 goto out_free;
206 240
207 INIT_LIST_HEAD(&private->crw);
208 INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
209 INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
210 atomic_set(&private->avail, 1);
211 private->state = VFIO_CCW_STATE_STANDBY;241 private->state = VFIO_CCW_STATE_STANDBY;
212 242
213 ret = vfio_ccw_mdev_reg(sch);243 ret = vfio_ccw_mdev_reg(sch);
@@ -228,31 +258,20 @@ out_disable: · 14 unmodified lines
228 cio_disable_subchannel(sch);258 cio_disable_subchannel(sch);
229out_free:259out_free:
230 dev_set_drvdata(&sch->dev, NULL);260 dev_set_drvdata(&sch->dev, NULL);
231 vfio_ccw_free_regions(private);261 vfio_ccw_free_private(private);
232 kfree(private->cp.guest_cp);
233 kfree(private);
234 return ret;262 return ret;
235}263}
236 264
237static void vfio_ccw_sch_remove(struct subchannel *sch)265static void vfio_ccw_sch_remove(struct subchannel *sch)
238{266{
239 struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);267 struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
240 struct vfio_ccw_crw *crw, *temp;
241 268
242 vfio_ccw_sch_quiesce(sch);269 vfio_ccw_sch_quiesce(sch);
243
244 list_for_each_entry_safe(crw, temp, &private->crw, next) {
245 list_del(&crw->next);
246 kfree(crw);
247 }
248
249 vfio_ccw_mdev_unreg(sch);270 vfio_ccw_mdev_unreg(sch);
250 271
251 dev_set_drvdata(&sch->dev, NULL);272 dev_set_drvdata(&sch->dev, NULL);
252 273
253 vfio_ccw_free_regions(private);274 vfio_ccw_free_private(private);
254 kfree(private->cp.guest_cp);
255 kfree(private);
256 275
257 VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n",276 VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n",
258 sch->schid.cssid, sch->schid.ssid,277 sch->schid.cssid, sch->schid.ssid,
@@ -449,7 +468,7 @@ static int __init vfio_ccw_sch_init(void) · 190 unmodified lines
449 vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");468 vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
450 if (!vfio_ccw_work_q) {469 if (!vfio_ccw_work_q) {
451 ret = -ENOMEM;470 ret = -ENOMEM;
452 goto out_err;471 goto out_regions;
453 }472 }
454 473
455 vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",474 vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",
@@ -458,7 +477,7 @@ static int __init vfio_ccw_sch_init(void) · 2 unmodified lines
458 sizeof(struct ccw_io_region), NULL);477 sizeof(struct ccw_io_region), NULL);
459 if (!vfio_ccw_io_region) {478 if (!vfio_ccw_io_region) {
460 ret = -ENOMEM;479 ret = -ENOMEM;
461 goto out_err;480 goto out_regions;
462 }481 }
463 482
464 vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region",483 vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region",
@@ -467,7 +486,7 @@ static int __init vfio_ccw_sch_init(void) · 2 unmodified lines
467 sizeof(struct ccw_cmd_region), NULL);486 sizeof(struct ccw_cmd_region), NULL);
468 if (!vfio_ccw_cmd_region) {487 if (!vfio_ccw_cmd_region) {
469 ret = -ENOMEM;488 ret = -ENOMEM;
470 goto out_err;489 goto out_regions;
471 }490 }
472 491
473 vfio_ccw_schib_region = kmem_cache_create_usercopy("vfio_ccw_schib_region",492 vfio_ccw_schib_region = kmem_cache_create_usercopy("vfio_ccw_schib_region",
@@ -477,7 +496,7 @@ static int __init vfio_ccw_sch_init(void) · 3 unmodified lines
477 496
478 if (!vfio_ccw_schib_region) {497 if (!vfio_ccw_schib_region) {
479 ret = -ENOMEM;498 ret = -ENOMEM;
480 goto out_err;499 goto out_regions;
481 }500 }
482 501
483 vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region",502 vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region",
@@ -487,19 +506,25 @@ static int __init vfio_ccw_sch_init(void) · 3 unmodified lines
487 506
488 if (!vfio_ccw_crw_region) {507 if (!vfio_ccw_crw_region) {
489 ret = -ENOMEM;508 ret = -ENOMEM;
490 goto out_err;509 goto out_regions;
491 }510 }
492 511
512 ret = mdev_register_driver(&vfio_ccw_mdev_driver);
513 if (ret)
514 goto out_regions;
515
493 isc_register(VFIO_CCW_ISC);516 isc_register(VFIO_CCW_ISC);
494 ret = css_driver_register(&vfio_ccw_sch_driver);517 ret = css_driver_register(&vfio_ccw_sch_driver);
495 if (ret) {518 if (ret) {
496 isc_unregister(VFIO_CCW_ISC);519 isc_unregister(VFIO_CCW_ISC);
497 goto out_err;520 goto out_driver;
498 }521 }
499 522
500 return ret;523 return ret;
501 524
502out_err:525out_driver:
526 mdev_unregister_driver(&vfio_ccw_mdev_driver);
527out_regions:
503 vfio_ccw_destroy_regions();528 vfio_ccw_destroy_regions();
504 destroy_workqueue(vfio_ccw_work_q);529 destroy_workqueue(vfio_ccw_work_q);
505 vfio_ccw_debug_exit();530 vfio_ccw_debug_exit();
@@ -509,6 +534,7 @@ out_err: · 3 unmodified lines
509static void __exit vfio_ccw_sch_exit(void)534static void __exit vfio_ccw_sch_exit(void)
510{535{
511 css_driver_unregister(&vfio_ccw_sch_driver);536 css_driver_unregister(&vfio_ccw_sch_driver);
537 mdev_unregister_driver(&vfio_ccw_mdev_driver);
512 isc_unregister(VFIO_CCW_ISC);538 isc_unregister(VFIO_CCW_ISC);
513 vfio_ccw_destroy_regions();539 vfio_ccw_destroy_regions();
514 destroy_workqueue(vfio_ccw_work_q);540 destroy_workqueue(vfio_ccw_work_q);
drivers/s390/cio/vfio_ccw_ops.c+80−62
@@ -17,13 +17,13 @@ · 16 unmodified lines
17 17
18#include "vfio_ccw_private.h"18#include "vfio_ccw_private.h"
19 19
20static int vfio_ccw_mdev_reset(struct mdev_device *mdev)20static const struct vfio_device_ops vfio_ccw_dev_ops;
21
22static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
21{23{
22 struct vfio_ccw_private *private;
23 struct subchannel *sch;24 struct subchannel *sch;
24 int ret;25 int ret;
25 26
26 private = dev_get_drvdata(mdev_parent_dev(mdev));
27 sch = private->sch;27 sch = private->sch;
28 /*28 /*
29 * TODO:29 * TODO:
@@ -61,7 +61,7 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb, · 31 unmodified lines
61 if (!cp_iova_pinned(&private->cp, unmap->iova))61 if (!cp_iova_pinned(&private->cp, unmap->iova))
62 return NOTIFY_OK;62 return NOTIFY_OK;
63 63
64 if (vfio_ccw_mdev_reset(private->mdev))64 if (vfio_ccw_mdev_reset(private))
65 return NOTIFY_BAD;65 return NOTIFY_BAD;
66 66
67 cp_free(&private->cp);67 cp_free(&private->cp);
@@ -113,10 +113,10 @@ static struct attribute_group *mdev_type_groups[] = { · 45 unmodified lines
113 NULL,113 NULL,
114};114};
115 115
116static int vfio_ccw_mdev_create(struct mdev_device *mdev)116static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
117{117{
118 struct vfio_ccw_private *private =118 struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
119 dev_get_drvdata(mdev_parent_dev(mdev));119 int ret;
120 120
121 if (private->state == VFIO_CCW_STATE_NOT_OPER)121 if (private->state == VFIO_CCW_STATE_NOT_OPER)
122 return -ENODEV;122 return -ENODEV;
@@ -124,6 +124,10 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev) · 1 unmodified line
124 if (atomic_dec_if_positive(&private->avail) < 0)124 if (atomic_dec_if_positive(&private->avail) < 0)
125 return -EPERM;125 return -EPERM;
126 126
127 memset(&private->vdev, 0, sizeof(private->vdev));
128 vfio_init_group_dev(&private->vdev, &mdev->dev,
129 &vfio_ccw_dev_ops);
130
127 private->mdev = mdev;131 private->mdev = mdev;
128 private->state = VFIO_CCW_STATE_IDLE;132 private->state = VFIO_CCW_STATE_IDLE;
129 133
@@ -132,19 +136,31 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev) · 2 unmodified lines
132 private->sch->schid.ssid,136 private->sch->schid.ssid,
133 private->sch->schid.sch_no);137 private->sch->schid.sch_no);
134 138
139 ret = vfio_register_emulated_iommu_dev(&private->vdev);
140 if (ret)
141 goto err_atomic;
142 dev_set_drvdata(&mdev->dev, private);
135 return 0;143 return 0;
144
145err_atomic:
146 vfio_uninit_group_dev(&private->vdev);
147 atomic_inc(&private->avail);
148 private->mdev = NULL;
149 private->state = VFIO_CCW_STATE_IDLE;
150 return ret;
136}151}
137 152
138static int vfio_ccw_mdev_remove(struct mdev_device *mdev)153static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
139{154{
140 struct vfio_ccw_private *private =155 struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent);
141 dev_get_drvdata(mdev_parent_dev(mdev));
142 156
143 VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n",157 VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n",
144 mdev_uuid(mdev), private->sch->schid.cssid,158 mdev_uuid(mdev), private->sch->schid.cssid,
145 private->sch->schid.ssid,159 private->sch->schid.ssid,
146 private->sch->schid.sch_no);160 private->sch->schid.sch_no);
147 161
162 vfio_unregister_group_dev(&private->vdev);
163
148 if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&164 if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
149 (private->state != VFIO_CCW_STATE_STANDBY)) {165 (private->state != VFIO_CCW_STATE_STANDBY)) {
150 if (!vfio_ccw_sch_quiesce(private->sch))166 if (!vfio_ccw_sch_quiesce(private->sch))
@@ -152,23 +168,22 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev) · 1 unmodified line
152 /* The state will be NOT_OPER on error. */168 /* The state will be NOT_OPER on error. */
153 }169 }
154 170
171 vfio_uninit_group_dev(&private->vdev);
155 cp_free(&private->cp);172 cp_free(&private->cp);
156 private->mdev = NULL;173 private->mdev = NULL;
157 atomic_inc(&private->avail);174 atomic_inc(&private->avail);
158
159 return 0;
160}175}
161 176
162static int vfio_ccw_mdev_open_device(struct mdev_device *mdev)177static int vfio_ccw_mdev_open_device(struct vfio_device *vdev)
163{178{
164 struct vfio_ccw_private *private =179 struct vfio_ccw_private *private =
165 dev_get_drvdata(mdev_parent_dev(mdev));180 container_of(vdev, struct vfio_ccw_private, vdev);
166 unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;181 unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
167 int ret;182 int ret;
168 183
169 private->nb.notifier_call = vfio_ccw_mdev_notifier;184 private->nb.notifier_call = vfio_ccw_mdev_notifier;
170 185
171 ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,186 ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
172 &events, &private->nb);187 &events, &private->nb);
173 if (ret)188 if (ret)
174 return ret;189 return ret;
@@ -189,27 +204,26 @@ static int vfio_ccw_mdev_open_device(struct mdev_device *mdev) · 14 unmodified lines
189 204
190out_unregister:205out_unregister:
191 vfio_ccw_unregister_dev_regions(private);206 vfio_ccw_unregister_dev_regions(private);
192 vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,207 vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
193 &private->nb);208 &private->nb);
194 return ret;209 return ret;
195}210}
196 211
197static void vfio_ccw_mdev_close_device(struct mdev_device *mdev)212static void vfio_ccw_mdev_close_device(struct vfio_device *vdev)
198{213{
199 struct vfio_ccw_private *private =214 struct vfio_ccw_private *private =
200 dev_get_drvdata(mdev_parent_dev(mdev));215 container_of(vdev, struct vfio_ccw_private, vdev);
201 216
202 if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&217 if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
203 (private->state != VFIO_CCW_STATE_STANDBY)) {218 (private->state != VFIO_CCW_STATE_STANDBY)) {
204 if (!vfio_ccw_mdev_reset(mdev))219 if (!vfio_ccw_mdev_reset(private))
205 private->state = VFIO_CCW_STATE_STANDBY;220 private->state = VFIO_CCW_STATE_STANDBY;
206 /* The state will be NOT_OPER on error. */221 /* The state will be NOT_OPER on error. */
207 }222 }
208 223
209 cp_free(&private->cp);224 cp_free(&private->cp);
210 vfio_ccw_unregister_dev_regions(private);225 vfio_ccw_unregister_dev_regions(private);
211 vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,226 vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, &private->nb);
212 &private->nb);
213}227}
214 228
215static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,229static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
@@ -233,15 +247,14 @@ static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private, · 17 unmodified lines
233 return ret;247 return ret;
234}248}
235 249
236static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,250static ssize_t vfio_ccw_mdev_read(struct vfio_device *vdev,
237 char __user *buf,251 char __user *buf,
238 size_t count,252 size_t count,
239 loff_t *ppos)253 loff_t *ppos)
240{254{
255 struct vfio_ccw_private *private =
256 container_of(vdev, struct vfio_ccw_private, vdev);
241 unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);257 unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
242 struct vfio_ccw_private *private;
243
244 private = dev_get_drvdata(mdev_parent_dev(mdev));
245 258
246 if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)259 if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
247 return -EINVAL;260 return -EINVAL;
@@ -286,15 +299,14 @@ out_unlock: · 38 unmodified lines
286 return ret;299 return ret;
287}300}
288 301
289static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,302static ssize_t vfio_ccw_mdev_write(struct vfio_device *vdev,
290 const char __user *buf,303 const char __user *buf,
291 size_t count,304 size_t count,
292 loff_t *ppos)305 loff_t *ppos)
293{306{
307 struct vfio_ccw_private *private =
308 container_of(vdev, struct vfio_ccw_private, vdev);
294 unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);309 unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
295 struct vfio_ccw_private *private;
296
297 private = dev_get_drvdata(mdev_parent_dev(mdev));
298 310
299 if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)311 if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
300 return -EINVAL;312 return -EINVAL;
@@ -311,12 +323,9 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, · 10 unmodified lines
311 return -EINVAL;323 return -EINVAL;
312}324}
313 325
314static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info,326static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private *private,
315 struct mdev_device *mdev)327 struct vfio_device_info *info)
316{328{
317 struct vfio_ccw_private *private;
318
319 private = dev_get_drvdata(mdev_parent_dev(mdev));
320 info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;329 info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
321 info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;330 info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;
322 info->num_irqs = VFIO_CCW_NUM_IRQS;331 info->num_irqs = VFIO_CCW_NUM_IRQS;
@@ -324,14 +333,12 @@ static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info, · 1 unmodified line
324 return 0;333 return 0;
325}334}
326 335
327static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,336static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private *private,
328 struct mdev_device *mdev,337 struct vfio_region_info *info,
329 unsigned long arg)338 unsigned long arg)
330{339{
331 struct vfio_ccw_private *private;
332 int i;340 int i;
333 341
334 private = dev_get_drvdata(mdev_parent_dev(mdev));
335 switch (info->index) {342 switch (info->index) {
336 case VFIO_CCW_CONFIG_REGION_INDEX:343 case VFIO_CCW_CONFIG_REGION_INDEX:
337 info->offset = 0;344 info->offset = 0;
@@ -406,19 +413,16 @@ static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info) · 68 unmodified lines
406 return 0;413 return 0;
407}414}
408 415
409static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,416static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private,
410 uint32_t flags,417 uint32_t flags,
411 uint32_t index,418 uint32_t index,
412 void __user *data)419 void __user *data)
413{420{
414 struct vfio_ccw_private *private;
415 struct eventfd_ctx **ctx;421 struct eventfd_ctx **ctx;
416 422
417 if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))423 if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
418 return -EINVAL;424 return -EINVAL;
419 425
420 private = dev_get_drvdata(mdev_parent_dev(mdev));
421
422 switch (index) {426 switch (index) {
423 case VFIO_CCW_IO_IRQ_INDEX:427 case VFIO_CCW_IO_IRQ_INDEX:
424 ctx = &private->io_trigger;428 ctx = &private->io_trigger;
@@ -520,10 +524,12 @@ void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private) · 95 unmodified lines
520 private->region = NULL;524 private->region = NULL;
521}525}
522 526
523static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,527static ssize_t vfio_ccw_mdev_ioctl(struct vfio_device *vdev,
524 unsigned int cmd,528 unsigned int cmd,
525 unsigned long arg)529 unsigned long arg)
526{530{
531 struct vfio_ccw_private *private =
532 container_of(vdev, struct vfio_ccw_private, vdev);
527 int ret = 0;533 int ret = 0;
528 unsigned long minsz;534 unsigned long minsz;
529 535
@@ -540,7 +546,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 10 unmodified lines
540 if (info.argsz < minsz)546 if (info.argsz < minsz)
541 return -EINVAL;547 return -EINVAL;
542 548
543 ret = vfio_ccw_mdev_get_device_info(&info, mdev);549 ret = vfio_ccw_mdev_get_device_info(private, &info);
544 if (ret)550 if (ret)
545 return ret;551 return ret;
546 552
@@ -558,7 +564,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 11 unmodified lines
558 if (info.argsz < minsz)564 if (info.argsz < minsz)
559 return -EINVAL;565 return -EINVAL;
560 566
561 ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg);567 ret = vfio_ccw_mdev_get_region_info(private, &info, arg);
562 if (ret)568 if (ret)
563 return ret;569 return ret;
564 570
@@ -603,47 +609,59 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, · 38 unmodified lines
603 return ret;609 return ret;
604 610
605 data = (void __user *)(arg + minsz);611 data = (void __user *)(arg + minsz);
606 return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, hdr.index, data);612 return vfio_ccw_mdev_set_irqs(private, hdr.flags, hdr.index,
613 data);
607 }614 }
608 case VFIO_DEVICE_RESET:615 case VFIO_DEVICE_RESET:
609 return vfio_ccw_mdev_reset(mdev);616 return vfio_ccw_mdev_reset(private);
610 default:617 default:
611 return -ENOTTY;618 return -ENOTTY;
612 }619 }
613}620}
614 621
615/* Request removal of the device*/622/* Request removal of the device*/
616static void vfio_ccw_mdev_request(struct mdev_device *mdev, unsigned int count)623static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned int count)
617{624{
618 struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev));625 struct vfio_ccw_private *private =
619 626 container_of(vdev, struct vfio_ccw_private, vdev);
620 if (!private)627 struct device *dev = vdev->dev;
621 return;
622 628
623 if (private->req_trigger) {629 if (private->req_trigger) {
624 if (!(count % 10))630 if (!(count % 10))
625 dev_notice_ratelimited(mdev_dev(private->mdev),631 dev_notice_ratelimited(dev,
626 "Relaying device request to user (#%u)\n",632 "Relaying device request to user (#%u)\n",
627 count);633 count);
628 634
629 eventfd_signal(private->req_trigger, 1);635 eventfd_signal(private->req_trigger, 1);
630 } else if (count == 0) {636 } else if (count == 0) {
631 dev_notice(mdev_dev(private->mdev),637 dev_notice(dev,
632 "No device request channel registered, blocked until released by user\n");638 "No device request channel registered, blocked until released by user\n");
633 }639 }
634}640}
635 641
642static const struct vfio_device_ops vfio_ccw_dev_ops = {
643 .open_device = vfio_ccw_mdev_open_device,
644 .close_device = vfio_ccw_mdev_close_device,
645 .read = vfio_ccw_mdev_read,
646 .write = vfio_ccw_mdev_write,
647 .ioctl = vfio_ccw_mdev_ioctl,
648 .request = vfio_ccw_mdev_request,
649};
650
651struct mdev_driver vfio_ccw_mdev_driver = {
652 .driver = {
653 .name = "vfio_ccw_mdev",
654 .owner = THIS_MODULE,
655 .mod_name = KBUILD_MODNAME,
656 },
657 .probe = vfio_ccw_mdev_probe,
658 .remove = vfio_ccw_mdev_remove,
659};
660
636static const struct mdev_parent_ops vfio_ccw_mdev_ops = {661static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
637 .owner = THIS_MODULE,662 .owner = THIS_MODULE,
663 .device_driver = &vfio_ccw_mdev_driver,
638 .supported_type_groups = mdev_type_groups,664 .supported_type_groups = mdev_type_groups,
639 .create = vfio_ccw_mdev_create,
640 .remove = vfio_ccw_mdev_remove,
641 .open_device = vfio_ccw_mdev_open_device,
642 .close_device = vfio_ccw_mdev_close_device,
643 .read = vfio_ccw_mdev_read,
644 .write = vfio_ccw_mdev_write,
645 .ioctl = vfio_ccw_mdev_ioctl,
646 .request = vfio_ccw_mdev_request,
647};665};
648 666
649int vfio_ccw_mdev_reg(struct subchannel *sch)667int vfio_ccw_mdev_reg(struct subchannel *sch)
drivers/s390/cio/vfio_ccw_private.h+5−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/eventfd.h>17#include <linux/eventfd.h>
18#include <linux/workqueue.h>18#include <linux/workqueue.h>
19#include <linux/vfio_ccw.h>19#include <linux/vfio_ccw.h>
20#include <linux/vfio.h>
20#include <asm/crw.h>21#include <asm/crw.h>
21#include <asm/debug.h>22#include <asm/debug.h>
22 23
@@ -67,6 +68,7 @@ struct vfio_ccw_crw { · 44 unmodified lines
67 68
68/**69/**
69 * struct vfio_ccw_private70 * struct vfio_ccw_private
71 * @vdev: Embedded VFIO device
70 * @sch: pointer to the subchannel72 * @sch: pointer to the subchannel
71 * @state: internal state of the device73 * @state: internal state of the device
72 * @completion: synchronization helper of the I/O completion74 * @completion: synchronization helper of the I/O completion
@@ -90,6 +92,7 @@ struct vfio_ccw_crw { · 17 unmodified lines
90 * @crw_work: work for deferral process of CRW handling92 * @crw_work: work for deferral process of CRW handling
91 */93 */
92struct vfio_ccw_private {94struct vfio_ccw_private {
95 struct vfio_device vdev;
93 struct subchannel *sch;96 struct subchannel *sch;
94 int state;97 int state;
95 struct completion *completion;98 struct completion *completion;
@@ -121,6 +124,8 @@ extern void vfio_ccw_mdev_unreg(struct subchannel *sch); · 25 unmodified lines
121 124
122extern int vfio_ccw_sch_quiesce(struct subchannel *sch);125extern int vfio_ccw_sch_quiesce(struct subchannel *sch);
123 126
127extern struct mdev_driver vfio_ccw_mdev_driver;
128
124/*129/*
125 * States of the device statemachine.130 * States of the device statemachine.
126 */131 */
drivers/s390/crypto/vfio_ap_ops.c+1−1
@@ -351,7 +351,7 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev) · 350 unmodified lines
351 list_add(&matrix_mdev->node, &matrix_dev->mdev_list);351 list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
352 mutex_unlock(&matrix_dev->lock);352 mutex_unlock(&matrix_dev->lock);
353 353
354 ret = vfio_register_group_dev(&matrix_mdev->vdev);354 ret = vfio_register_emulated_iommu_dev(&matrix_mdev->vdev);
355 if (ret)355 if (ret)
356 goto err_list;356 goto err_list;
357 dev_set_drvdata(&mdev->dev, matrix_mdev);357 dev_set_drvdata(&mdev->dev, matrix_mdev);
drivers/vfio/fsl-mc/vfio_fsl_mc.c+32−30
@@ -65,6 +65,34 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) · 64 unmodified lines
65 kfree(vdev->regions);65 kfree(vdev->regions);
66}66}
67 67
68static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev)
69{
70 struct fsl_mc_device *mc_dev = vdev->mc_dev;
71 int ret = 0;
72
73 if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
74 return dprc_reset_container(mc_dev->mc_io, 0,
75 mc_dev->mc_handle,
76 mc_dev->obj_desc.id,
77 DPRC_RESET_OPTION_NON_RECURSIVE);
78 } else {
79 u16 token;
80
81 ret = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
82 mc_dev->obj_desc.type,
83 &token);
84 if (ret)
85 goto out;
86 ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token);
87 if (ret) {
88 fsl_mc_obj_close(mc_dev->mc_io, 0, token);
89 goto out;
90 }
91 ret = fsl_mc_obj_close(mc_dev->mc_io, 0, token);
92 }
93out:
94 return ret;
95}
68 96
69static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)97static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev)
70{98{
@@ -78,9 +106,7 @@ static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) · 7 unmodified lines
78 vfio_fsl_mc_regions_cleanup(vdev);106 vfio_fsl_mc_regions_cleanup(vdev);
79 107
80 /* reset the device before cleaning up the interrupts */108 /* reset the device before cleaning up the interrupts */
81 ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle,109 ret = vfio_fsl_mc_reset_device(vdev);
82 mc_cont->obj_desc.id,
83 DPRC_RESET_OPTION_NON_RECURSIVE);
84 110
85 if (WARN_ON(ret))111 if (WARN_ON(ret))
86 dev_warn(&mc_cont->dev,112 dev_warn(&mc_cont->dev,
@@ -203,18 +229,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, · 116 unmodified lines
203 }229 }
204 case VFIO_DEVICE_RESET:230 case VFIO_DEVICE_RESET:
205 {231 {
206 int ret;232 return vfio_fsl_mc_reset_device(vdev);
207 struct fsl_mc_device *mc_dev = vdev->mc_dev;
208
209 /* reset is supported only for the DPRC */
210 if (!is_fsl_mc_bus_dprc(mc_dev))
211 return -ENOTTY;
212
213 ret = dprc_reset_container(mc_dev->mc_io, 0,
214 mc_dev->mc_handle,
215 mc_dev->obj_desc.id,
216 DPRC_RESET_OPTION_NON_RECURSIVE);
217 return ret;
218 233
219 }234 }
220 default:235 default:
@@ -505,22 +520,13 @@ static void vfio_fsl_uninit_device(struct vfio_fsl_mc_device *vdev) · 284 unmodified lines
505 520
506static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)521static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
507{522{
508 struct iommu_group *group;
509 struct vfio_fsl_mc_device *vdev;523 struct vfio_fsl_mc_device *vdev;
510 struct device *dev = &mc_dev->dev;524 struct device *dev = &mc_dev->dev;
511 int ret;525 int ret;
512 526
513 group = vfio_iommu_group_get(dev);
514 if (!group) {
515 dev_err(dev, "VFIO_FSL_MC: No IOMMU group\n");
516 return -EINVAL;
517 }
518
519 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);527 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
520 if (!vdev) {528 if (!vdev)
521 ret = -ENOMEM;529 return -ENOMEM;
522 goto out_group_put;
523 }
524 530
525 vfio_init_group_dev(&vdev->vdev, dev, &vfio_fsl_mc_ops);531 vfio_init_group_dev(&vdev->vdev, dev, &vfio_fsl_mc_ops);
526 vdev->mc_dev = mc_dev;532 vdev->mc_dev = mc_dev;
@@ -556,8 +562,6 @@ out_device: · 29 unmodified lines
556out_uninit:562out_uninit:
557 vfio_uninit_group_dev(&vdev->vdev);563 vfio_uninit_group_dev(&vdev->vdev);
558 kfree(vdev);564 kfree(vdev);
559out_group_put:
560 vfio_iommu_group_put(group, dev);
561 return ret;565 return ret;
562}566}
563 567
@@ -574,8 +578,6 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) · 10 unmodified lines
574 578
575 vfio_uninit_group_dev(&vdev->vdev);579 vfio_uninit_group_dev(&vdev->vdev);
576 kfree(vdev);580 kfree(vdev);
577 vfio_iommu_group_put(mc_dev->dev.iommu_group, dev);
578
579 return 0;581 return 0;
580}582}
581 583
drivers/vfio/mdev/mdev_driver.c+4−41
@@ -13,60 +13,23 @@ · 12 unmodified lines
13 13
14#include "mdev_private.h"14#include "mdev_private.h"
15 15
16static int mdev_attach_iommu(struct mdev_device *mdev)
17{
18 int ret;
19 struct iommu_group *group;
20
21 group = iommu_group_alloc();
22 if (IS_ERR(group))
23 return PTR_ERR(group);
24
25 ret = iommu_group_add_device(group, &mdev->dev);
26 if (!ret)
27 dev_info(&mdev->dev, "MDEV: group_id = %d\n",
28 iommu_group_id(group));
29
30 iommu_group_put(group);
31 return ret;
32}
33
34static void mdev_detach_iommu(struct mdev_device *mdev)
35{
36 iommu_group_remove_device(&mdev->dev);
37 dev_info(&mdev->dev, "MDEV: detaching iommu\n");
38}
39
40static int mdev_probe(struct device *dev)16static int mdev_probe(struct device *dev)
41{17{
42 struct mdev_driver *drv =18 struct mdev_driver *drv =
43 container_of(dev->driver, struct mdev_driver, driver);19 container_of(dev->driver, struct mdev_driver, driver);
44 struct mdev_device *mdev = to_mdev_device(dev);
45 int ret;
46 20
47 ret = mdev_attach_iommu(mdev);21 if (!drv->probe)
48 if (ret)22 return 0;
49 return ret;23 return drv->probe(to_mdev_device(dev));
50
51 if (drv->probe) {
52 ret = drv->probe(mdev);
53 if (ret)
54 mdev_detach_iommu(mdev);
55 }
56
57 return ret;
58}24}
59 25
60static void mdev_remove(struct device *dev)26static void mdev_remove(struct device *dev)
61{27{
62 struct mdev_driver *drv =28 struct mdev_driver *drv =
63 container_of(dev->driver, struct mdev_driver, driver);29 container_of(dev->driver, struct mdev_driver, driver);
64 struct mdev_device *mdev = to_mdev_device(dev);
65 30
66 if (drv->remove)31 if (drv->remove)
67 drv->remove(mdev);32 drv->remove(to_mdev_device(dev));
68
69 mdev_detach_iommu(mdev);
70}33}
71 34
72static int mdev_match(struct device *dev, struct device_driver *drv)35static int mdev_match(struct device *dev, struct device_driver *drv)
drivers/vfio/mdev/vfio_mdev.c+1−1
@@ -119,7 +119,7 @@ static int vfio_mdev_probe(struct mdev_device *mdev) · 118 unmodified lines
119 return -ENOMEM;119 return -ENOMEM;
120 120
121 vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops);121 vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops);
122 ret = vfio_register_group_dev(vdev);122 ret = vfio_register_emulated_iommu_dev(vdev);
123 if (ret)123 if (ret)
124 goto out_uninit;124 goto out_uninit;
125 125
drivers/vfio/pci/vfio_pci_core.c+2−11
@@ -1806,7 +1806,6 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_uninit_device); · 1805 unmodified lines
1806int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)1806int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
1807{1807{
1808 struct pci_dev *pdev = vdev->pdev;1808 struct pci_dev *pdev = vdev->pdev;
1809 struct iommu_group *group;
1810 int ret;1809 int ret;
1811 1810
1812 if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)1811 if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
@@ -1825,10 +1824,6 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) · 12 unmodified lines
1825 return -EBUSY;1824 return -EBUSY;
1826 }1825 }
1827 1826
1828 group = vfio_iommu_group_get(&pdev->dev);
1829 if (!group)
1830 return -EINVAL;
1831
1832 if (pci_is_root_bus(pdev->bus)) {1827 if (pci_is_root_bus(pdev->bus)) {
1833 ret = vfio_assign_device_set(&vdev->vdev, vdev);1828 ret = vfio_assign_device_set(&vdev->vdev, vdev);
1834 } else if (!pci_probe_reset_slot(pdev->slot)) {1829 } else if (!pci_probe_reset_slot(pdev->slot)) {
@@ -1842,10 +1837,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev) · 7 unmodified lines
1842 }1837 }
1843 1838
1844 if (ret)1839 if (ret)
1845 goto out_group_put;1840 return ret;
1846 ret = vfio_pci_vf_init(vdev);1841 ret = vfio_pci_vf_init(vdev);
1847 if (ret)1842 if (ret)
1848 goto out_group_put;1843 return ret;
1849 ret = vfio_pci_vga_init(vdev);1844 ret = vfio_pci_vga_init(vdev);
1850 if (ret)1845 if (ret)
1851 goto out_vf;1846 goto out_vf;
@@ -1876,8 +1871,6 @@ out_power: · 24 unmodified lines
1876 vfio_pci_set_power_state(vdev, PCI_D0);1871 vfio_pci_set_power_state(vdev, PCI_D0);
1877out_vf:1872out_vf:
1878 vfio_pci_vf_uninit(vdev);1873 vfio_pci_vf_uninit(vdev);
1879out_group_put:
1880 vfio_iommu_group_put(group, &pdev->dev);
1881 return ret;1874 return ret;
1882}1875}
1883EXPORT_SYMBOL_GPL(vfio_pci_core_register_device);1876EXPORT_SYMBOL_GPL(vfio_pci_core_register_device);
@@ -1893,8 +1886,6 @@ void vfio_pci_core_unregister_device(struct vfio_pci_core_device *vdev) · 9 unmodified lines
1893 vfio_pci_vf_uninit(vdev);1886 vfio_pci_vf_uninit(vdev);
1894 vfio_pci_vga_uninit(vdev);1887 vfio_pci_vga_uninit(vdev);
1895 1888
1896 vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev);
1897
1898 if (!disable_idle_d3)1889 if (!disable_idle_d3)
1899 vfio_pci_set_power_state(vdev, PCI_D0);1890 vfio_pci_set_power_state(vdev, PCI_D0);
1900}1891}
drivers/vfio/pci/vfio_pci_igd.c+175−59
@@ -25,20 +25,121 @@ · 24 unmodified lines
25#define OPREGION_RVDS 0x3c225#define OPREGION_RVDS 0x3c2
26#define OPREGION_VERSION 0x1626#define OPREGION_VERSION 0x16
27 27
28struct igd_opregion_vbt {
29 void *opregion;
30 void *vbt_ex;
31};
32
33/**
34 * igd_opregion_shift_copy() - Copy OpRegion to user buffer and shift position.
35 * @dst: User buffer ptr to copy to.
36 * @off: Offset to user buffer ptr. Increased by bytes on return.
37 * @src: Source buffer to copy from.
38 * @pos: Increased by bytes on return.
39 * @remaining: Decreased by bytes on return.
40 * @bytes: Bytes to copy and adjust off, pos and remaining.
41 *
42 * Copy OpRegion to offset from specific source ptr and shift the offset.
43 *
44 * Return: 0 on success, -EFAULT otherwise.
45 *
46 */
47static inline unsigned long igd_opregion_shift_copy(char __user *dst,
48 loff_t *off,
49 void *src,
50 loff_t *pos,
51 size_t *remaining,
52 size_t bytes)
53{
54 if (copy_to_user(dst + (*off), src, bytes))
55 return -EFAULT;
56
57 *off += bytes;
58 *pos += bytes;
59 *remaining -= bytes;
60
61 return 0;
62}
63
28static ssize_t vfio_pci_igd_rw(struct vfio_pci_core_device *vdev,64static ssize_t vfio_pci_igd_rw(struct vfio_pci_core_device *vdev,
29 char __user *buf, size_t count, loff_t *ppos,65 char __user *buf, size_t count, loff_t *ppos,
30 bool iswrite)66 bool iswrite)
31{67{
32 unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;68 unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS;
33 void *base = vdev->region[i].data;69 struct igd_opregion_vbt *opregionvbt = vdev->region[i].data;
34 loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;70 loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK, off = 0;
71 size_t remaining;
35 72
36 if (pos >= vdev->region[i].size || iswrite)73 if (pos >= vdev->region[i].size || iswrite)
37 return -EINVAL;74 return -EINVAL;
38 75
39 count = min(count, (size_t)(vdev->region[i].size - pos));76 count = min_t(size_t, count, vdev->region[i].size - pos);
77 remaining = count;
78
79 /* Copy until OpRegion version */
80 if (remaining && pos < OPREGION_VERSION) {
81 size_t bytes = min_t(size_t, remaining, OPREGION_VERSION - pos);
82
83 if (igd_opregion_shift_copy(buf, &off,
84 opregionvbt->opregion + pos, &pos,
85 &remaining, bytes))
86 return -EFAULT;
87 }
88
89 /* Copy patched (if necessary) OpRegion version */
90 if (remaining && pos < OPREGION_VERSION + sizeof(__le16)) {
91 size_t bytes = min_t(size_t, remaining,
92 OPREGION_VERSION + sizeof(__le16) - pos);
93 __le16 version = *(__le16 *)(opregionvbt->opregion +
94 OPREGION_VERSION);
95
96 /* Patch to 2.1 if OpRegion 2.0 has extended VBT */
97 if (le16_to_cpu(version) == 0x0200 && opregionvbt->vbt_ex)
98 version = cpu_to_le16(0x0201);
99
100 if (igd_opregion_shift_copy(buf, &off,
101 &version + (pos - OPREGION_VERSION),
102 &pos, &remaining, bytes))
103 return -EFAULT;
104 }
105
106 /* Copy until RVDA */
107 if (remaining && pos < OPREGION_RVDA) {
108 size_t bytes = min_t(size_t, remaining, OPREGION_RVDA - pos);
40 109
41 if (copy_to_user(buf, base + pos, count))110 if (igd_opregion_shift_copy(buf, &off,
111 opregionvbt->opregion + pos, &pos,
112 &remaining, bytes))
113 return -EFAULT;
114 }
115
116 /* Copy modified (if necessary) RVDA */
117 if (remaining && pos < OPREGION_RVDA + sizeof(__le64)) {
118 size_t bytes = min_t(size_t, remaining,
119 OPREGION_RVDA + sizeof(__le64) - pos);
120 __le64 rvda = cpu_to_le64(opregionvbt->vbt_ex ?
121 OPREGION_SIZE : 0);
122
123 if (igd_opregion_shift_copy(buf, &off,
124 &rvda + (pos - OPREGION_RVDA),
125 &pos, &remaining, bytes))
126 return -EFAULT;
127 }
128
129 /* Copy the rest of OpRegion */
130 if (remaining && pos < OPREGION_SIZE) {
131 size_t bytes = min_t(size_t, remaining, OPREGION_SIZE - pos);
132
133 if (igd_opregion_shift_copy(buf, &off,
134 opregionvbt->opregion + pos, &pos,
135 &remaining, bytes))
136 return -EFAULT;
137 }
138
139 /* Copy extended VBT if exists */
140 if (remaining &&
141 copy_to_user(buf + off, opregionvbt->vbt_ex + (pos - OPREGION_SIZE),
142 remaining))
42 return -EFAULT;143 return -EFAULT;
43 144
44 *ppos += count;145 *ppos += count;
@@ -49,7 +150,13 @@ static ssize_t vfio_pci_igd_rw(struct vfio_pci_core_device *vdev, · 4 unmodified lines
49static void vfio_pci_igd_release(struct vfio_pci_core_device *vdev,150static void vfio_pci_igd_release(struct vfio_pci_core_device *vdev,
50 struct vfio_pci_region *region)151 struct vfio_pci_region *region)
51{152{
52 memunmap(region->data);153 struct igd_opregion_vbt *opregionvbt = region->data;
154
155 if (opregionvbt->vbt_ex)
156 memunmap(opregionvbt->vbt_ex);
157
158 memunmap(opregionvbt->opregion);
159 kfree(opregionvbt);
53}160}
54 161
55static const struct vfio_pci_regops vfio_pci_igd_regops = {162static const struct vfio_pci_regops vfio_pci_igd_regops = {
@@ -61,7 +168,7 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_core_device *vdev) · 5 unmodified lines
61{168{
62 __le32 *dwordp = (__le32 *)(vdev->vconfig + OPREGION_PCI_ADDR);169 __le32 *dwordp = (__le32 *)(vdev->vconfig + OPREGION_PCI_ADDR);
63 u32 addr, size;170 u32 addr, size;
64 void *base;171 struct igd_opregion_vbt *opregionvbt;
65 int ret;172 int ret;
66 u16 version;173 u16 version;
67 174
@@ -72,84 +179,93 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_core_device *vdev) · 4 unmodified lines
72 if (!addr || !(~addr))179 if (!addr || !(~addr))
73 return -ENODEV;180 return -ENODEV;
74 181
75 base = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);182 opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL);
76 if (!base)183 if (!opregionvbt)
184 return -ENOMEM;
185
186 opregionvbt->opregion = memremap(addr, OPREGION_SIZE, MEMREMAP_WB);
187 if (!opregionvbt->opregion) {
188 kfree(opregionvbt);
77 return -ENOMEM;189 return -ENOMEM;
190 }
78 191
79 if (memcmp(base, OPREGION_SIGNATURE, 16)) {192 if (memcmp(opregionvbt->opregion, OPREGION_SIGNATURE, 16)) {
80 memunmap(base);193 memunmap(opregionvbt->opregion);
194 kfree(opregionvbt);
81 return -EINVAL;195 return -EINVAL;
82 }196 }
83 197
84 size = le32_to_cpu(*(__le32 *)(base + 16));198 size = le32_to_cpu(*(__le32 *)(opregionvbt->opregion + 16));
85 if (!size) {199 if (!size) {
86 memunmap(base);200 memunmap(opregionvbt->opregion);
201 kfree(opregionvbt);
87 return -EINVAL;202 return -EINVAL;
88 }203 }
89 204
90 size *= 1024; /* In KB */205 size *= 1024; /* In KB */
91 206
92 /*207 /*
93 * Support opregion v2.1+208 * OpRegion and VBT:
94 * When VBT data exceeds 6KB size and cannot be within mailbox #4, then209 * When VBT data doesn't exceed 6KB, it's stored in Mailbox #4.
95 * the Extended VBT region next to opregion is used to hold the VBT data.210 * When VBT data exceeds 6KB size, Mailbox #4 is no longer large enough
96 * RVDA (Relative Address of VBT Data from Opregion Base) and RVDS211 * to hold the VBT data, the Extended VBT region is introduced since
97 * (Raw VBT Data Size) from opregion structure member are used to hold the212 * OpRegion 2.0 to hold the VBT data. Since OpRegion 2.0, RVDA/RVDS are
98 * address from region base and size of VBT data. RVDA/RVDS are not213 * introduced to define the extended VBT data location and size.
99 * defined before opregion 2.0.214 * OpRegion 2.0: RVDA defines the absolute physical address of the
100 *215 * extended VBT data, RVDS defines the VBT data size.
101 * opregion 2.1+: RVDA is unsigned, relative offset from216 * OpRegion 2.1 and above: RVDA defines the relative address of the
102 * opregion base, and should point to the end of opregion.217 * extended VBT data to OpRegion base, RVDS defines the VBT data size.
103 * otherwise, exposing to userspace to allow read access to everything between
104 * the OpRegion and VBT is not safe.
105 * RVDS is defined as size in bytes.
106 *218 *
107 * opregion 2.0: rvda is the physical VBT address.219 * Due to the RVDA definition diff in OpRegion VBT (also the only diff
108 * Since rvda is HPA it cannot be directly used in guest.220 * between 2.0 and 2.1), exposing OpRegion and VBT as a contiguous range
109 * And it should not be practically available for end user,so it is not supported.221 * for OpRegion 2.0 and above makes it possible to support the
222 * non-contiguous VBT through a single vfio region. From r/w ops view,
223 * only contiguous VBT after OpRegion with version 2.1+ is exposed,
224 * regardless the host OpRegion is 2.0 or non-contiguous 2.1+. The r/w
225 * ops will on-the-fly shift the actural offset into VBT so that data at
226 * correct position can be returned to the requester.
110 */227 */
111 version = le16_to_cpu(*(__le16 *)(base + OPREGION_VERSION));228 version = le16_to_cpu(*(__le16 *)(opregionvbt->opregion +
229 OPREGION_VERSION));
112 if (version >= 0x0200) {230 if (version >= 0x0200) {
113 u64 rvda;231 u64 rvda = le64_to_cpu(*(__le64 *)(opregionvbt->opregion +
114 u32 rvds;232 OPREGION_RVDA));
233 u32 rvds = le32_to_cpu(*(__le32 *)(opregionvbt->opregion +
234 OPREGION_RVDS));
115 235
116 rvda = le64_to_cpu(*(__le64 *)(base + OPREGION_RVDA));236 /* The extended VBT is valid only when RVDA/RVDS are non-zero */
117 rvds = le32_to_cpu(*(__le32 *)(base + OPREGION_RVDS));
118 if (rvda && rvds) {237 if (rvda && rvds) {
119 /* no support for opregion v2.0 with physical VBT address */238 size += rvds;
120 if (version == 0x0200) {
121 memunmap(base);
122 pci_err(vdev->pdev,
123 "IGD assignment does not support opregion v2.0 with an extended VBT region\n");
124 return -EINVAL;
125 }
126 239
127 if (rvda != size) {240 /*
128 memunmap(base);241 * Extended VBT location by RVDA:
129 pci_err(vdev->pdev,242 * Absolute physical addr for 2.0.
130 "Extended VBT does not follow opregion on version 0x%04x\n",243 * Relative addr to OpRegion header for 2.1+.
131 version);244 */
132 return -EINVAL;245 if (version == 0x0200)
246 addr = rvda;
247 else
248 addr += rvda;
249
250 opregionvbt->vbt_ex = memremap(addr, rvds, MEMREMAP_WB);
251 if (!opregionvbt->vbt_ex) {
252 memunmap(opregionvbt->opregion);
253 kfree(opregionvbt);
254 return -ENOMEM;
133 }255 }
134
135 /* region size for opregion v2.0+: opregion and VBT size. */
136 size += rvds;
137 }256 }
138 }257 }
139 258
140 if (size != OPREGION_SIZE) {
141 memunmap(base);
142 base = memremap(addr, size, MEMREMAP_WB);
143 if (!base)
144 return -ENOMEM;
145 }
146
147 ret = vfio_pci_register_dev_region(vdev,259 ret = vfio_pci_register_dev_region(vdev,
148 PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,260 PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE,
149 VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION,261 VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &vfio_pci_igd_regops,
150 &vfio_pci_igd_regops, size, VFIO_REGION_INFO_FLAG_READ, base);262 size, VFIO_REGION_INFO_FLAG_READ, opregionvbt);
151 if (ret) {263 if (ret) {
152 memunmap(base);264 if (opregionvbt->vbt_ex)
265 memunmap(opregionvbt->vbt_ex);
266
267 memunmap(opregionvbt->opregion);
268 kfree(opregionvbt);
153 return ret;269 return ret;
154 }270 }
155 271
drivers/vfio/platform/vfio_platform_common.c+1−12
@@ -642,7 +642,6 @@ static int vfio_platform_of_probe(struct vfio_platform_device *vdev, · 641 unmodified lines
642int vfio_platform_probe_common(struct vfio_platform_device *vdev,642int vfio_platform_probe_common(struct vfio_platform_device *vdev,
643 struct device *dev)643 struct device *dev)
644{644{
645 struct iommu_group *group;
646 int ret;645 int ret;
647 646
648 vfio_init_group_dev(&vdev->vdev, dev, &vfio_platform_ops);647 vfio_init_group_dev(&vdev->vdev, dev, &vfio_platform_ops);
@@ -663,24 +662,15 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev, · 14 unmodified lines
663 goto out_uninit;662 goto out_uninit;
664 }663 }
665 664
666 group = vfio_iommu_group_get(dev);
667 if (!group) {
668 dev_err(dev, "No IOMMU group for device %s\n", vdev->name);
669 ret = -EINVAL;
670 goto put_reset;
671 }
672
673 ret = vfio_register_group_dev(&vdev->vdev);665 ret = vfio_register_group_dev(&vdev->vdev);
674 if (ret)666 if (ret)
675 goto put_iommu;667 goto put_reset;
676 668
677 mutex_init(&vdev->igate);669 mutex_init(&vdev->igate);
678 670
679 pm_runtime_enable(dev);671 pm_runtime_enable(dev);
680 return 0;672 return 0;
681 673
682put_iommu:
683 vfio_iommu_group_put(group, dev);
684put_reset:674put_reset:
685 vfio_platform_put_reset(vdev);675 vfio_platform_put_reset(vdev);
686out_uninit:676out_uninit:
@@ -696,7 +686,6 @@ void vfio_platform_remove_common(struct vfio_platform_device *vdev) · 9 unmodified lines
696 pm_runtime_disable(vdev->device);686 pm_runtime_disable(vdev->device);
697 vfio_platform_put_reset(vdev);687 vfio_platform_put_reset(vdev);
698 vfio_uninit_group_dev(&vdev->vdev);688 vfio_uninit_group_dev(&vdev->vdev);
699 vfio_iommu_group_put(vdev->vdev.dev->iommu_group, vdev->vdev.dev);
700}689}
701EXPORT_SYMBOL_GPL(vfio_platform_remove_common);690EXPORT_SYMBOL_GPL(vfio_platform_remove_common);
702 691
drivers/vfio/vfio.c+255−367
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#include <linux/vfio.h>32#include <linux/vfio.h>
33#include <linux/wait.h>33#include <linux/wait.h>
34#include <linux/sched/signal.h>34#include <linux/sched/signal.h>
35#include "vfio.h"
35 36
36#define DRIVER_VERSION "0.3"37#define DRIVER_VERSION "0.3"
37#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"38#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
@@ -42,9 +43,8 @@ static struct vfio { · 4 unmodified lines
42 struct list_head iommu_drivers_list;43 struct list_head iommu_drivers_list;
43 struct mutex iommu_drivers_lock;44 struct mutex iommu_drivers_lock;
44 struct list_head group_list;45 struct list_head group_list;
45 struct idr group_idr;46 struct mutex group_lock; /* locks group_list */
46 struct mutex group_lock;47 struct ida group_ida;
47 struct cdev group_cdev;
48 dev_t group_devt;48 dev_t group_devt;
49} vfio;49} vfio;
50 50
@@ -68,14 +68,14 @@ struct vfio_unbound_dev { · 17 unmodified lines
68};68};
69 69
70struct vfio_group {70struct vfio_group {
71 struct kref kref;71 struct device dev;
72 int minor;72 struct cdev cdev;
73 refcount_t users;
73 atomic_t container_users;74 atomic_t container_users;
74 struct iommu_group *iommu_group;75 struct iommu_group *iommu_group;
75 struct vfio_container *container;76 struct vfio_container *container;
76 struct list_head device_list;77 struct list_head device_list;
77 struct mutex device_lock;78 struct mutex device_lock;
78 struct device *dev;
79 struct notifier_block nb;79 struct notifier_block nb;
80 struct list_head vfio_next;80 struct list_head vfio_next;
81 struct list_head container_next;81 struct list_head container_next;
@@ -83,7 +83,7 @@ struct vfio_group { · 1 unmodified line
83 struct mutex unbound_lock;83 struct mutex unbound_lock;
84 atomic_t opened;84 atomic_t opened;
85 wait_queue_head_t container_q;85 wait_queue_head_t container_q;
86 bool noiommu;86 enum vfio_group_type type;
87 unsigned int dev_counter;87 unsigned int dev_counter;
88 struct kvm *kvm;88 struct kvm *kvm;
89 struct blocking_notifier_head notifier;89 struct blocking_notifier_head notifier;
@@ -97,6 +97,7 @@ MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. Thi · 7 unmodified lines
97#endif97#endif
98 98
99static DEFINE_XARRAY(vfio_device_set_xa);99static DEFINE_XARRAY(vfio_device_set_xa);
100static const struct file_operations vfio_group_fops;
100 101
101int vfio_assign_device_set(struct vfio_device *device, void *set_id)102int vfio_assign_device_set(struct vfio_device *device, void *set_id)
102{103{
@@ -169,70 +170,6 @@ static void vfio_release_device_set(struct vfio_device *device) · 66 unmodified lines
169 xa_unlock(&vfio_device_set_xa);170 xa_unlock(&vfio_device_set_xa);
170}171}
171 172
172/*
173 * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe
174 * and remove functions, any use cases other than acquiring the first
175 * reference for the purpose of calling vfio_register_group_dev() or removing
176 * that symmetric reference after vfio_unregister_group_dev() should use the raw
177 * iommu_group_{get,put} functions. In particular, vfio_iommu_group_put()
178 * removes the device from the dummy group and cannot be nested.
179 */
180struct iommu_group *vfio_iommu_group_get(struct device *dev)
181{
182 struct iommu_group *group;
183 int __maybe_unused ret;
184
185 group = iommu_group_get(dev);
186
187#ifdef CONFIG_VFIO_NOIOMMU
188 /*
189 * With noiommu enabled, an IOMMU group will be created for a device
190 * that doesn't already have one and doesn't have an iommu_ops on their
191 * bus. We set iommudata simply to be able to identify these groups
192 * as special use and for reclamation later.
193 */
194 if (group || !noiommu || iommu_present(dev->bus))
195 return group;
196
197 group = iommu_group_alloc();
198 if (IS_ERR(group))
199 return NULL;
200
201 iommu_group_set_name(group, "vfio-noiommu");
202 iommu_group_set_iommudata(group, &noiommu, NULL);
203 ret = iommu_group_add_device(group, dev);
204 if (ret) {
205 iommu_group_put(group);
206 return NULL;
207 }
208
209 /*
210 * Where to taint? At this point we've added an IOMMU group for a
211 * device that is not backed by iommu_ops, therefore any iommu_
212 * callback using iommu_ops can legitimately Oops. So, while we may
213 * be about to give a DMA capable device to a user without IOMMU
214 * protection, which is clearly taint-worthy, let's go ahead and do
215 * it here.
216 */
217 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
218 dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n");
219#endif
220
221 return group;
222}
223EXPORT_SYMBOL_GPL(vfio_iommu_group_get);
224
225void vfio_iommu_group_put(struct iommu_group *group, struct device *dev)
226{
227#ifdef CONFIG_VFIO_NOIOMMU
228 if (iommu_group_get_iommudata(group) == &noiommu)
229 iommu_group_remove_device(dev);
230#endif
231
232 iommu_group_put(group);
233}
234EXPORT_SYMBOL_GPL(vfio_iommu_group_put);
235
236#ifdef CONFIG_VFIO_NOIOMMU173#ifdef CONFIG_VFIO_NOIOMMU
237static void *vfio_noiommu_open(unsigned long arg)174static void *vfio_noiommu_open(unsigned long arg)
238{175{
@@ -258,9 +195,9 @@ static long vfio_noiommu_ioctl(void *iommu_data, · 19 unmodified lines
258}195}
259 196
260static int vfio_noiommu_attach_group(void *iommu_data,197static int vfio_noiommu_attach_group(void *iommu_data,
261 struct iommu_group *iommu_group)198 struct iommu_group *iommu_group, enum vfio_group_type type)
262{199{
263 return iommu_group_get_iommudata(iommu_group) == &noiommu ? 0 : -EINVAL;200 return 0;
264}201}
265 202
266static void vfio_noiommu_detach_group(void *iommu_data,203static void vfio_noiommu_detach_group(void *iommu_data,
@@ -277,8 +214,23 @@ static const struct vfio_iommu_driver_ops vfio_noiommu_ops = { · 10 unmodified lines
277 .attach_group = vfio_noiommu_attach_group,214 .attach_group = vfio_noiommu_attach_group,
278 .detach_group = vfio_noiommu_detach_group,215 .detach_group = vfio_noiommu_detach_group,
279};216};
280#endif
281 217
218/*
219 * Only noiommu containers can use vfio-noiommu and noiommu containers can only
220 * use vfio-noiommu.
221 */
222static inline bool vfio_iommu_driver_allowed(struct vfio_container *container,
223 const struct vfio_iommu_driver *driver)
224{
225 return container->noiommu == (driver->ops == &vfio_noiommu_ops);
226}
227#else
228static inline bool vfio_iommu_driver_allowed(struct vfio_container *container,
229 const struct vfio_iommu_driver *driver)
230{
231 return true;
232}
233#endif /* CONFIG_VFIO_NOIOMMU */
282 234
283/**235/**
284 * IOMMU driver registration236 * IOMMU driver registration
@@ -329,19 +281,6 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops) · 44 unmodified lines
329}281}
330EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);282EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
331 283
332/**
333 * Group minor allocation/free - both called with vfio.group_lock held
334 */
335static int vfio_alloc_group_minor(struct vfio_group *group)
336{
337 return idr_alloc(&vfio.group_idr, group, 0, MINORMASK + 1, GFP_KERNEL);
338}
339
340static void vfio_free_group_minor(int minor)
341{
342 idr_remove(&vfio.group_idr, minor);
343}
344
345static int vfio_iommu_group_notifier(struct notifier_block *nb,284static int vfio_iommu_group_notifier(struct notifier_block *nb,
346 unsigned long action, void *data);285 unsigned long action, void *data);
347static void vfio_group_get(struct vfio_group *group);286static void vfio_group_get(struct vfio_group *group);
@@ -370,105 +309,38 @@ static void vfio_container_put(struct vfio_container *container) · 22 unmodified lines
370 kref_put(&container->kref, vfio_container_release);309 kref_put(&container->kref, vfio_container_release);
371}310}
372 311
373static void vfio_group_unlock_and_free(struct vfio_group *group)
374{
375 mutex_unlock(&vfio.group_lock);
376 /*
377 * Unregister outside of lock. A spurious callback is harmless now
378 * that the group is no longer in vfio.group_list.
379 */
380 iommu_group_unregister_notifier(group->iommu_group, &group->nb);
381 kfree(group);
382}
383
384/**312/**
385 * Group objects - create, release, get, put, search313 * Group objects - create, release, get, put, search
386 */314 */
387static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)315static struct vfio_group *
316__vfio_group_get_from_iommu(struct iommu_group *iommu_group)
388{317{
389 struct vfio_group *group, *tmp;318 struct vfio_group *group;
390 struct device *dev;
391 int ret, minor;
392
393 group = kzalloc(sizeof(*group), GFP_KERNEL);
394 if (!group)
395 return ERR_PTR(-ENOMEM);
396
397 kref_init(&group->kref);
398 INIT_LIST_HEAD(&group->device_list);
399 mutex_init(&group->device_lock);
400 INIT_LIST_HEAD(&group->unbound_list);
401 mutex_init(&group->unbound_lock);
402 atomic_set(&group->container_users, 0);
403 atomic_set(&group->opened, 0);
404 init_waitqueue_head(&group->container_q);
405 group->iommu_group = iommu_group;
406#ifdef CONFIG_VFIO_NOIOMMU
407 group->noiommu = (iommu_group_get_iommudata(iommu_group) == &noiommu);
408#endif
409 BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
410
411 group->nb.notifier_call = vfio_iommu_group_notifier;
412
413 /*
414 * blocking notifiers acquire a rwsem around registering and hold
415 * it around callback. Therefore, need to register outside of
416 * vfio.group_lock to avoid A-B/B-A contention. Our callback won't
417 * do anything unless it can find the group in vfio.group_list, so
418 * no harm in registering early.
419 */
420 ret = iommu_group_register_notifier(iommu_group, &group->nb);
421 if (ret) {
422 kfree(group);
423 return ERR_PTR(ret);
424 }
425
426 mutex_lock(&vfio.group_lock);
427 319
428 /* Did we race creating this group? */320 list_for_each_entry(group, &vfio.group_list, vfio_next) {
429 list_for_each_entry(tmp, &vfio.group_list, vfio_next) {321 if (group->iommu_group == iommu_group) {
430 if (tmp->iommu_group == iommu_group) {322 vfio_group_get(group);
431 vfio_group_get(tmp);323 return group;
432 vfio_group_unlock_and_free(group);
433 return tmp;
434 }324 }
435 }325 }
326 return NULL;
327}
436 328
437 minor = vfio_alloc_group_minor(group);329static struct vfio_group *
438 if (minor < 0) {330vfio_group_get_from_iommu(struct iommu_group *iommu_group)
439 vfio_group_unlock_and_free(group);331{
440 return ERR_PTR(minor);332 struct vfio_group *group;
441 }
442
443 dev = device_create(vfio.class, NULL,
444 MKDEV(MAJOR(vfio.group_devt), minor),
445 group, "%s%d", group->noiommu ? "noiommu-" : "",
446 iommu_group_id(iommu_group));
447 if (IS_ERR(dev)) {
448 vfio_free_group_minor(minor);
449 vfio_group_unlock_and_free(group);
450 return ERR_CAST(dev);
451 }
452
453 group->minor = minor;
454 group->dev = dev;
455
456 list_add(&group->vfio_next, &vfio.group_list);
457 333
334 mutex_lock(&vfio.group_lock);
335 group = __vfio_group_get_from_iommu(iommu_group);
458 mutex_unlock(&vfio.group_lock);336 mutex_unlock(&vfio.group_lock);
459
460 return group;337 return group;
461}338}
462 339
463/* called with vfio.group_lock held */340static void vfio_group_release(struct device *dev)
464static void vfio_group_release(struct kref *kref)
465{341{
466 struct vfio_group *group = container_of(kref, struct vfio_group, kref);342 struct vfio_group *group = container_of(dev, struct vfio_group, dev);
467 struct vfio_unbound_dev *unbound, *tmp;343 struct vfio_unbound_dev *unbound, *tmp;
468 struct iommu_group *iommu_group = group->iommu_group;
469
470 WARN_ON(!list_empty(&group->device_list));
471 WARN_ON(group->notifier.head);
472 344
473 list_for_each_entry_safe(unbound, tmp,345 list_for_each_entry_safe(unbound, tmp,
474 &group->unbound_list, unbound_next) {346 &group->unbound_list, unbound_next) {
@@ -476,105 +348,129 @@ static void vfio_group_release(struct kref *kref) · 1 unmodified line
476 kfree(unbound);348 kfree(unbound);
477 }349 }
478 350
479 device_destroy(vfio.class, MKDEV(MAJOR(vfio.group_devt), group->minor));351 mutex_destroy(&group->device_lock);
480 list_del(&group->vfio_next);352 mutex_destroy(&group->unbound_lock);
481 vfio_free_group_minor(group->minor);353 iommu_group_put(group->iommu_group);
482 vfio_group_unlock_and_free(group);354 ida_free(&vfio.group_ida, MINOR(group->dev.devt));
483 iommu_group_put(iommu_group);355 kfree(group);
484}356}
485 357
486static void vfio_group_put(struct vfio_group *group)358static struct vfio_group *vfio_group_alloc(struct iommu_group *iommu_group,
359 enum vfio_group_type type)
487{360{
488 kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock);
489}
490
491struct vfio_group_put_work {
492 struct work_struct work;
493 struct vfio_group *group;361 struct vfio_group *group;
494};362 int minor;
495 363
496static void vfio_group_put_bg(struct work_struct *work)364 group = kzalloc(sizeof(*group), GFP_KERNEL);
497{365 if (!group)
498 struct vfio_group_put_work *do_work;366 return ERR_PTR(-ENOMEM);
499
500 do_work = container_of(work, struct vfio_group_put_work, work);
501 367
502 vfio_group_put(do_work->group);368 minor = ida_alloc_max(&vfio.group_ida, MINORMASK, GFP_KERNEL);
503 kfree(do_work);369 if (minor < 0) {
504}370 kfree(group);
371 return ERR_PTR(minor);
372 }
505 373
506static void vfio_group_schedule_put(struct vfio_group *group)374 device_initialize(&group->dev);
507{375 group->dev.devt = MKDEV(MAJOR(vfio.group_devt), minor);
508 struct vfio_group_put_work *do_work;376 group->dev.class = vfio.class;
377 group->dev.release = vfio_group_release;
378 cdev_init(&group->cdev, &vfio_group_fops);
379 group->cdev.owner = THIS_MODULE;
509 380
510 do_work = kmalloc(sizeof(*do_work), GFP_KERNEL);381 refcount_set(&group->users, 1);
511 if (WARN_ON(!do_work))382 INIT_LIST_HEAD(&group->device_list);
512 return;383 mutex_init(&group->device_lock);
384 INIT_LIST_HEAD(&group->unbound_list);
385 mutex_init(&group->unbound_lock);
386 init_waitqueue_head(&group->container_q);
387 group->iommu_group = iommu_group;
388 /* put in vfio_group_release() */
389 iommu_group_ref_get(iommu_group);
390 group->type = type;
391 BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
513 392
514 INIT_WORK(&do_work->work, vfio_group_put_bg);393 return group;
515 do_work->group = group;
516 schedule_work(&do_work->work);
517}394}
518 395
519/* Assume group_lock or group reference is held */396static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
520static void vfio_group_get(struct vfio_group *group)397 enum vfio_group_type type)
521{398{
522 kref_get(&group->kref);399 struct vfio_group *group;
523}400 struct vfio_group *ret;
401 int err;
524 402
525/*403 group = vfio_group_alloc(iommu_group, type);
526 * Not really a try as we will sleep for mutex, but we need to make404 if (IS_ERR(group))
527 * sure the group pointer is valid under lock and get a reference.405 return group;
528 */
529static struct vfio_group *vfio_group_try_get(struct vfio_group *group)
530{
531 struct vfio_group *target = group;
532 406
533 mutex_lock(&vfio.group_lock);407 err = dev_set_name(&group->dev, "%s%d",
534 list_for_each_entry(group, &vfio.group_list, vfio_next) {408 group->type == VFIO_NO_IOMMU ? "noiommu-" : "",
535 if (group == target) {409 iommu_group_id(iommu_group));
536 vfio_group_get(group);410 if (err) {
537 mutex_unlock(&vfio.group_lock);411 ret = ERR_PTR(err);
538 return group;412 goto err_put;
539 }
540 }413 }
541 mutex_unlock(&vfio.group_lock);
542 414
543 return NULL;415 group->nb.notifier_call = vfio_iommu_group_notifier;
544}416 err = iommu_group_register_notifier(iommu_group, &group->nb);
545 417 if (err) {
546static418 ret = ERR_PTR(err);
547struct vfio_group *vfio_group_get_from_iommu(struct iommu_group *iommu_group)419 goto err_put;
548{420 }
549 struct vfio_group *group;
550 421
551 mutex_lock(&vfio.group_lock);422 mutex_lock(&vfio.group_lock);
552 list_for_each_entry(group, &vfio.group_list, vfio_next) {423
553 if (group->iommu_group == iommu_group) {424 /* Did we race creating this group? */
554 vfio_group_get(group);425 ret = __vfio_group_get_from_iommu(iommu_group);
555 mutex_unlock(&vfio.group_lock);426 if (ret)
556 return group;427 goto err_unlock;
557 }428
429 err = cdev_device_add(&group->cdev, &group->dev);
430 if (err) {
431 ret = ERR_PTR(err);
432 goto err_unlock;
558 }433 }
434
435 list_add(&group->vfio_next, &vfio.group_list);
436
559 mutex_unlock(&vfio.group_lock);437 mutex_unlock(&vfio.group_lock);
438 return group;
560 439
561 return NULL;440err_unlock:
441 mutex_unlock(&vfio.group_lock);
442 iommu_group_unregister_notifier(group->iommu_group, &group->nb);
443err_put:
444 put_device(&group->dev);
445 return ret;
562}446}
563 447
564static struct vfio_group *vfio_group_get_from_minor(int minor)448static void vfio_group_put(struct vfio_group *group)
565{449{
566 struct vfio_group *group;450 if (!refcount_dec_and_mutex_lock(&group->users, &vfio.group_lock))
451 return;
567 452
568 mutex_lock(&vfio.group_lock);453 /*
569 group = idr_find(&vfio.group_idr, minor);454 * These data structures all have paired operations that can only be
570 if (!group) {455 * undone when the caller holds a live reference on the group. Since all
571 mutex_unlock(&vfio.group_lock);456 * pairs must be undone these WARN_ON's indicate some caller did not
572 return NULL;457 * properly hold the group reference.
573 }458 */
574 vfio_group_get(group);459 WARN_ON(!list_empty(&group->device_list));
460 WARN_ON(atomic_read(&group->container_users));
461 WARN_ON(group->notifier.head);
462
463 list_del(&group->vfio_next);
464 cdev_device_del(&group->cdev, &group->dev);
575 mutex_unlock(&vfio.group_lock);465 mutex_unlock(&vfio.group_lock);
576 466
577 return group;467 iommu_group_unregister_notifier(group->iommu_group, &group->nb);
468 put_device(&group->dev);
469}
470
471static void vfio_group_get(struct vfio_group *group)
472{
473 refcount_inc(&group->users);
578}474}
579 475
580static struct vfio_group *vfio_group_get_from_dev(struct device *dev)476static struct vfio_group *vfio_group_get_from_dev(struct device *dev)
@@ -740,14 +636,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, · 159 unmodified lines
740 struct device *dev = data;636 struct device *dev = data;
741 struct vfio_unbound_dev *unbound;637 struct vfio_unbound_dev *unbound;
742 638
743 /*
744 * Need to go through a group_lock lookup to get a reference or we
745 * risk racing a group being removed. Ignore spurious notifies.
746 */
747 group = vfio_group_try_get(group);
748 if (!group)
749 return NOTIFY_OK;
750
751 switch (action) {639 switch (action) {
752 case IOMMU_GROUP_NOTIFY_ADD_DEVICE:640 case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
753 vfio_group_nb_add_dev(group, dev);641 vfio_group_nb_add_dev(group, dev);
@@ -798,15 +686,6 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, · 44 unmodified lines
798 mutex_unlock(&group->unbound_lock);686 mutex_unlock(&group->unbound_lock);
799 break;687 break;
800 }688 }
801
802 /*
803 * If we're the last reference to the group, the group will be
804 * released, which includes unregistering the iommu group notifier.
805 * We hold a read-lock on that notifier list, unregistering needs
806 * a write-lock... deadlock. Release our reference asynchronously
807 * to avoid that situation.
808 */
809 vfio_group_schedule_put(group);
810 return NOTIFY_OK;689 return NOTIFY_OK;
811}690}
812 691
@@ -828,11 +707,78 @@ void vfio_uninit_group_dev(struct vfio_device *device) · 15 unmodified lines
828}707}
829EXPORT_SYMBOL_GPL(vfio_uninit_group_dev);708EXPORT_SYMBOL_GPL(vfio_uninit_group_dev);
830 709
831int vfio_register_group_dev(struct vfio_device *device)710static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev,
711 enum vfio_group_type type)
832{712{
833 struct vfio_device *existing_device;
834 struct iommu_group *iommu_group;713 struct iommu_group *iommu_group;
835 struct vfio_group *group;714 struct vfio_group *group;
715 int ret;
716
717 iommu_group = iommu_group_alloc();
718 if (IS_ERR(iommu_group))
719 return ERR_CAST(iommu_group);
720
721 iommu_group_set_name(iommu_group, "vfio-noiommu");
722 ret = iommu_group_add_device(iommu_group, dev);
723 if (ret)
724 goto out_put_group;
725
726 group = vfio_create_group(iommu_group, type);
727 if (IS_ERR(group)) {
728 ret = PTR_ERR(group);
729 goto out_remove_device;
730 }
731 iommu_group_put(iommu_group);
732 return group;
733
734out_remove_device:
735 iommu_group_remove_device(dev);
736out_put_group:
737 iommu_group_put(iommu_group);
738 return ERR_PTR(ret);
739}
740
741static struct vfio_group *vfio_group_find_or_alloc(struct device *dev)
742{
743 struct iommu_group *iommu_group;
744 struct vfio_group *group;
745
746 iommu_group = iommu_group_get(dev);
747#ifdef CONFIG_VFIO_NOIOMMU
748 if (!iommu_group && noiommu && !iommu_present(dev->bus)) {
749 /*
750 * With noiommu enabled, create an IOMMU group for devices that
751 * don't already have one and don't have an iommu_ops on their
752 * bus. Taint the kernel because we're about to give a DMA
753 * capable device to a user without IOMMU protection.
754 */
755 group = vfio_noiommu_group_alloc(dev, VFIO_NO_IOMMU);
756 if (!IS_ERR(group)) {
757 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
758 dev_warn(dev, "Adding kernel taint for vfio-noiommu group on device\n");
759 }
760 return group;
761 }
762#endif
763 if (!iommu_group)
764 return ERR_PTR(-EINVAL);
765
766 group = vfio_group_get_from_iommu(iommu_group);
767 if (!group)
768 group = vfio_create_group(iommu_group, VFIO_IOMMU);
769
770 /* The vfio_group holds a reference to the iommu_group */
771 iommu_group_put(iommu_group);
772 return group;
773}
774
775static int __vfio_register_dev(struct vfio_device *device,
776 struct vfio_group *group)
777{
778 struct vfio_device *existing_device;
779
780 if (IS_ERR(group))
781 return PTR_ERR(group);
836 782
837 /*783 /*
838 * If the driver doesn't specify a set then the device is added to a784 * If the driver doesn't specify a set then the device is added to a
@@ -841,30 +787,14 @@ int vfio_register_group_dev(struct vfio_device *device) · 2 unmodified lines
841 if (!device->dev_set)787 if (!device->dev_set)
842 vfio_assign_device_set(device, device);788 vfio_assign_device_set(device, device);
843 789
844 iommu_group = iommu_group_get(device->dev);
845 if (!iommu_group)
846 return -EINVAL;
847
848 group = vfio_group_get_from_iommu(iommu_group);
849 if (!group) {
850 group = vfio_create_group(iommu_group);
851 if (IS_ERR(group)) {
852 iommu_group_put(iommu_group);
853 return PTR_ERR(group);
854 }
855 } else {
856 /*
857 * A found vfio_group already holds a reference to the
858 * iommu_group. A created vfio_group keeps the reference.
859 */
860 iommu_group_put(iommu_group);
861 }
862
863 existing_device = vfio_group_get_device(group, device->dev);790 existing_device = vfio_group_get_device(group, device->dev);
864 if (existing_device) {791 if (existing_device) {
865 dev_WARN(device->dev, "Device already exists on group %d\n",792 dev_WARN(device->dev, "Device already exists on group %d\n",
866 iommu_group_id(iommu_group));793 iommu_group_id(group->iommu_group));
867 vfio_device_put(existing_device);794 vfio_device_put(existing_device);
795 if (group->type == VFIO_NO_IOMMU ||
796 group->type == VFIO_EMULATED_IOMMU)
797 iommu_group_remove_device(device->dev);
868 vfio_group_put(group);798 vfio_group_put(group);
869 return -EBUSY;799 return -EBUSY;
870 }800 }
@@ -882,8 +812,25 @@ int vfio_register_group_dev(struct vfio_device *device) · 11 unmodified lines
882 812
883 return 0;813 return 0;
884}814}
815
816int vfio_register_group_dev(struct vfio_device *device)
817{
818 return __vfio_register_dev(device,
819 vfio_group_find_or_alloc(device->dev));
820}
885EXPORT_SYMBOL_GPL(vfio_register_group_dev);821EXPORT_SYMBOL_GPL(vfio_register_group_dev);
886 822
823/*
824 * Register a virtual device without IOMMU backing. The user of this
825 * device must not be able to directly trigger unmediated DMA.
826 */
827int vfio_register_emulated_iommu_dev(struct vfio_device *device)
828{
829 return __vfio_register_dev(device,
830 vfio_noiommu_group_alloc(device->dev, VFIO_EMULATED_IOMMU));
831}
832EXPORT_SYMBOL_GPL(vfio_register_emulated_iommu_dev);
833
887/**834/**
888 * Get a reference to the vfio_device for a device. Even if the835 * Get a reference to the vfio_device for a device. Even if the
889 * caller thinks they own the device, they could be racing with a836 * caller thinks they own the device, they could be racing with a
@@ -1010,6 +957,9 @@ void vfio_unregister_group_dev(struct vfio_device *device) · 120 unmodified lines
1010 if (list_empty(&group->device_list))957 if (list_empty(&group->device_list))
1011 wait_event(group->container_q, !group->container);958 wait_event(group->container_q, !group->container);
1012 959
960 if (group->type == VFIO_NO_IOMMU || group->type == VFIO_EMULATED_IOMMU)
961 iommu_group_remove_device(device->dev);
962
1013 /* Matches the get in vfio_register_group_dev() */963 /* Matches the get in vfio_register_group_dev() */
1014 vfio_group_put(group);964 vfio_group_put(group);
1015}965}
@@ -1042,13 +992,10 @@ static long vfio_ioctl_check_extension(struct vfio_container *container, · 26 unmodified lines
1042 list_for_each_entry(driver, &vfio.iommu_drivers_list,992 list_for_each_entry(driver, &vfio.iommu_drivers_list,
1043 vfio_next) {993 vfio_next) {
1044 994
1045#ifdef CONFIG_VFIO_NOIOMMU
1046 if (!list_empty(&container->group_list) &&995 if (!list_empty(&container->group_list) &&
1047 (container->noiommu !=996 !vfio_iommu_driver_allowed(container,
1048 (driver->ops == &vfio_noiommu_ops)))997 driver))
1049 continue;998 continue;
1050#endif
1051
1052 if (!try_module_get(driver->ops->owner))999 if (!try_module_get(driver->ops->owner))
1053 continue;1000 continue;
1054 1001
@@ -1079,7 +1026,8 @@ static int __vfio_container_attach_groups(struct vfio_container *container, · 24 unmodified lines
1079 int ret = -ENODEV;1026 int ret = -ENODEV;
1080 1027
1081 list_for_each_entry(group, &container->group_list, container_next) {1028 list_for_each_entry(group, &container->group_list, container_next) {
1082 ret = driver->ops->attach_group(data, group->iommu_group);1029 ret = driver->ops->attach_group(data, group->iommu_group,
1030 group->type);
1083 if (ret)1031 if (ret)
1084 goto unwind;1032 goto unwind;
1085 }1033 }
@@ -1120,15 +1068,8 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container, · 34 unmodified lines
1120 list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) {1068 list_for_each_entry(driver, &vfio.iommu_drivers_list, vfio_next) {
1121 void *data;1069 void *data;
1122 1070
1123#ifdef CONFIG_VFIO_NOIOMMU1071 if (!vfio_iommu_driver_allowed(container, driver))
1124 /*
1125 * Only noiommu containers can use vfio-noiommu and noiommu
1126 * containers can only use vfio-noiommu.
1127 */
1128 if (container->noiommu != (driver->ops == &vfio_noiommu_ops))
1129 continue;1072 continue;
1130#endif
1131
1132 if (!try_module_get(driver->ops->owner))1073 if (!try_module_get(driver->ops->owner))
1133 continue;1074 continue;
1134 1075
@@ -1234,62 +1175,12 @@ static int vfio_fops_release(struct inode *inode, struct file *filep) · 99 unmodified lines
1234 return 0;1175 return 0;
1235}1176}
1236 1177
1237/*
1238 * Once an iommu driver is set, we optionally pass read/write/mmap
1239 * on to the driver, allowing management interfaces beyond ioctl.
1240 */
1241static ssize_t vfio_fops_read(struct file *filep, char __user *buf,
1242 size_t count, loff_t *ppos)
1243{
1244 struct vfio_container *container = filep->private_data;
1245 struct vfio_iommu_driver *driver;
1246 ssize_t ret = -EINVAL;
1247
1248 driver = container->iommu_driver;
1249 if (likely(driver && driver->ops->read))
1250 ret = driver->ops->read(container->iommu_data,
1251 buf, count, ppos);
1252
1253 return ret;
1254}
1255
1256static ssize_t vfio_fops_write(struct file *filep, const char __user *buf,
1257 size_t count, loff_t *ppos)
1258{
1259 struct vfio_container *container = filep->private_data;
1260 struct vfio_iommu_driver *driver;
1261 ssize_t ret = -EINVAL;
1262
1263 driver = container->iommu_driver;
1264 if (likely(driver && driver->ops->write))
1265 ret = driver->ops->write(container->iommu_data,
1266 buf, count, ppos);
1267
1268 return ret;
1269}
1270
1271static int vfio_fops_mmap(struct file *filep, struct vm_area_struct *vma)
1272{
1273 struct vfio_container *container = filep->private_data;
1274 struct vfio_iommu_driver *driver;
1275 int ret = -EINVAL;
1276
1277 driver = container->iommu_driver;
1278 if (likely(driver && driver->ops->mmap))
1279 ret = driver->ops->mmap(container->iommu_data, vma);
1280
1281 return ret;
1282}
1283
1284static const struct file_operations vfio_fops = {1178static const struct file_operations vfio_fops = {
1285 .owner = THIS_MODULE,1179 .owner = THIS_MODULE,
1286 .open = vfio_fops_open,1180 .open = vfio_fops_open,
1287 .release = vfio_fops_release,1181 .release = vfio_fops_release,
1288 .read = vfio_fops_read,
1289 .write = vfio_fops_write,
1290 .unlocked_ioctl = vfio_fops_unl_ioctl,1182 .unlocked_ioctl = vfio_fops_unl_ioctl,
1291 .compat_ioctl = compat_ptr_ioctl,1183 .compat_ioctl = compat_ptr_ioctl,
1292 .mmap = vfio_fops_mmap,
1293};1184};
1294 1185
1295/**1186/**
@@ -1366,7 +1257,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) · 70 unmodified lines
1366 if (atomic_read(&group->container_users))1257 if (atomic_read(&group->container_users))
1367 return -EINVAL;1258 return -EINVAL;
1368 1259
1369 if (group->noiommu && !capable(CAP_SYS_RAWIO))1260 if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
1370 return -EPERM;1261 return -EPERM;
1371 1262
1372 f = fdget(container_fd);1263 f = fdget(container_fd);
@@ -1386,7 +1277,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) · 13 unmodified lines
1386 1277
1387 /* Real groups and fake groups cannot mix */1278 /* Real groups and fake groups cannot mix */
1388 if (!list_empty(&container->group_list) &&1279 if (!list_empty(&container->group_list) &&
1389 container->noiommu != group->noiommu) {1280 container->noiommu != (group->type == VFIO_NO_IOMMU)) {
1390 ret = -EPERM;1281 ret = -EPERM;
1391 goto unlock_out;1282 goto unlock_out;
1392 }1283 }
@@ -1394,13 +1285,14 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) · 1 unmodified line
1394 driver = container->iommu_driver;1285 driver = container->iommu_driver;
1395 if (driver) {1286 if (driver) {
1396 ret = driver->ops->attach_group(container->iommu_data,1287 ret = driver->ops->attach_group(container->iommu_data,
1397 group->iommu_group);1288 group->iommu_group,
1289 group->type);
1398 if (ret)1290 if (ret)
1399 goto unlock_out;1291 goto unlock_out;
1400 }1292 }
1401 1293
1402 group->container = container;1294 group->container = container;
1403 container->noiommu = group->noiommu;1295 container->noiommu = (group->type == VFIO_NO_IOMMU);
1404 list_add(&group->container_next, &container->group_list);1296 list_add(&group->container_next, &container->group_list);
1405 1297
1406 /* Get a reference on the container and mark a user within the group */1298 /* Get a reference on the container and mark a user within the group */
@@ -1424,7 +1316,7 @@ static int vfio_group_add_container_user(struct vfio_group *group) · 17 unmodified lines
1424 if (!atomic_inc_not_zero(&group->container_users))1316 if (!atomic_inc_not_zero(&group->container_users))
1425 return -EINVAL;1317 return -EINVAL;
1426 1318
1427 if (group->noiommu) {1319 if (group->type == VFIO_NO_IOMMU) {
1428 atomic_dec(&group->container_users);1320 atomic_dec(&group->container_users);
1429 return -EPERM;1321 return -EPERM;
1430 }1322 }
@@ -1449,7 +1341,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) · 18 unmodified lines
1449 !group->container->iommu_driver || !vfio_group_viable(group))1341 !group->container->iommu_driver || !vfio_group_viable(group))
1450 return -EINVAL;1342 return -EINVAL;
1451 1343
1452 if (group->noiommu && !capable(CAP_SYS_RAWIO))1344 if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))
1453 return -EPERM;1345 return -EPERM;
1454 1346
1455 device = vfio_device_get_from_name(group, buf);1347 device = vfio_device_get_from_name(group, buf);
@@ -1496,7 +1388,7 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) · 40 unmodified lines
1496 1388
1497 fd_install(fdno, filep);1389 fd_install(fdno, filep);
1498 1390
1499 if (group->noiommu)1391 if (group->type == VFIO_NO_IOMMU)
1500 dev_warn(device->dev, "vfio-noiommu device opened by user "1392 dev_warn(device->dev, "vfio-noiommu device opened by user "
1501 "(%s:%d)\n", current->comm, task_pid_nr(current));1393 "(%s:%d)\n", current->comm, task_pid_nr(current));
1502 return fdno;1394 return fdno;
@@ -1585,14 +1477,15 @@ static long vfio_group_fops_unl_ioctl(struct file *filep, · 82 unmodified lines
1585 1477
1586static int vfio_group_fops_open(struct inode *inode, struct file *filep)1478static int vfio_group_fops_open(struct inode *inode, struct file *filep)
1587{1479{
1588 struct vfio_group *group;1480 struct vfio_group *group =
1481 container_of(inode->i_cdev, struct vfio_group, cdev);
1589 int opened;1482 int opened;
1590 1483
1591 group = vfio_group_get_from_minor(iminor(inode));1484 /* users can be zero if this races with vfio_group_put() */
1592 if (!group)1485 if (!refcount_inc_not_zero(&group->users))
1593 return -ENODEV;1486 return -ENODEV;
1594 1487
1595 if (group->noiommu && !capable(CAP_SYS_RAWIO)) {1488 if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) {
1596 vfio_group_put(group);1489 vfio_group_put(group);
1597 return -EPERM;1490 return -EPERM;
1598 }1491 }
@@ -1757,6 +1650,9 @@ struct vfio_group *vfio_group_get_external_user(struct file *filep) · 158 unmodified lines
1757 if (ret)1650 if (ret)
1758 return ERR_PTR(ret);1651 return ERR_PTR(ret);
1759 1652
1653 /*
1654 * Since the caller holds the fget on the file group->users must be >= 1
1655 */
1760 vfio_group_get(group);1656 vfio_group_get(group);
1761 1657
1762 return group;1658 return group;
@@ -2396,7 +2292,7 @@ static int __init vfio_init(void) · 633 unmodified lines
2396{2292{
2397 int ret;2293 int ret;
2398 2294
2399 idr_init(&vfio.group_idr);2295 ida_init(&vfio.group_ida);
2400 mutex_init(&vfio.group_lock);2296 mutex_init(&vfio.group_lock);
2401 mutex_init(&vfio.iommu_drivers_lock);2297 mutex_init(&vfio.iommu_drivers_lock);
2402 INIT_LIST_HEAD(&vfio.group_list);2298 INIT_LIST_HEAD(&vfio.group_list);
@@ -2421,11 +2317,6 @@ static int __init vfio_init(void) · 18 unmodified lines
2421 if (ret)2317 if (ret)
2422 goto err_alloc_chrdev;2318 goto err_alloc_chrdev;
2423 2319
2424 cdev_init(&vfio.group_cdev, &vfio_group_fops);
2425 ret = cdev_add(&vfio.group_cdev, vfio.group_devt, MINORMASK + 1);
2426 if (ret)
2427 goto err_cdev_add;
2428
2429 pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");2320 pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
2430 2321
2431#ifdef CONFIG_VFIO_NOIOMMU2322#ifdef CONFIG_VFIO_NOIOMMU
@@ -2433,8 +2324,6 @@ static int __init vfio_init(void) · 1 unmodified line
2433#endif2324#endif
2434 return 0;2325 return 0;
2435 2326
2436err_cdev_add:
2437 unregister_chrdev_region(vfio.group_devt, MINORMASK + 1);
2438err_alloc_chrdev:2327err_alloc_chrdev:
2439 class_destroy(vfio.class);2328 class_destroy(vfio.class);
2440 vfio.class = NULL;2329 vfio.class = NULL;
@@ -2450,8 +2339,7 @@ static void __exit vfio_cleanup(void) · 9 unmodified lines
2450#ifdef CONFIG_VFIO_NOIOMMU2339#ifdef CONFIG_VFIO_NOIOMMU
2451 vfio_unregister_iommu_driver(&vfio_noiommu_ops);2340 vfio_unregister_iommu_driver(&vfio_noiommu_ops);
2452#endif2341#endif
2453 idr_destroy(&vfio.group_idr);2342 ida_destroy(&vfio.group_ida);
2454 cdev_del(&vfio.group_cdev);
2455 unregister_chrdev_region(vfio.group_devt, MINORMASK + 1);2343 unregister_chrdev_region(vfio.group_devt, MINORMASK + 1);
2456 class_destroy(vfio.class);2344 class_destroy(vfio.class);
2457 vfio.class = NULL;2345 vfio.class = NULL;
drivers/vfio/vfio.h+72−0
@@ -0,0 +1,72 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2012 Red Hat, Inc. All rights reserved.
4 * Author: Alex Williamson <alex.williamson@redhat.com>
5 */
6
7enum vfio_group_type {
8 /*
9 * Physical device with IOMMU backing.
10 */
11 VFIO_IOMMU,
12
13 /*
14 * Virtual device without IOMMU backing. The VFIO core fakes up an
15 * iommu_group as the iommu_group sysfs interface is part of the
16 * userspace ABI. The user of these devices must not be able to
17 * directly trigger unmediated DMA.
18 */
19 VFIO_EMULATED_IOMMU,
20
21 /*
22 * Physical device without IOMMU backing. The VFIO core fakes up an
23 * iommu_group as the iommu_group sysfs interface is part of the
24 * userspace ABI. Users can trigger unmediated DMA by the device,
25 * usage is highly dangerous, requires an explicit opt-in and will
26 * taint the kernel.
27 */
28 VFIO_NO_IOMMU,
29};
30
31/* events for the backend driver notify callback */
32enum vfio_iommu_notify_type {
33 VFIO_IOMMU_CONTAINER_CLOSE = 0,
34};
35
36/**
37 * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks
38 */
39struct vfio_iommu_driver_ops {
40 char *name;
41 struct module *owner;
42 void *(*open)(unsigned long arg);
43 void (*release)(void *iommu_data);
44 long (*ioctl)(void *iommu_data, unsigned int cmd,
45 unsigned long arg);
46 int (*attach_group)(void *iommu_data,
47 struct iommu_group *group,
48 enum vfio_group_type);
49 void (*detach_group)(void *iommu_data,
50 struct iommu_group *group);
51 int (*pin_pages)(void *iommu_data,
52 struct iommu_group *group,
53 unsigned long *user_pfn,
54 int npage, int prot,
55 unsigned long *phys_pfn);
56 int (*unpin_pages)(void *iommu_data,
57 unsigned long *user_pfn, int npage);
58 int (*register_notifier)(void *iommu_data,
59 unsigned long *events,
60 struct notifier_block *nb);
61 int (*unregister_notifier)(void *iommu_data,
62 struct notifier_block *nb);
63 int (*dma_rw)(void *iommu_data, dma_addr_t user_iova,
64 void *data, size_t count, bool write);
65 struct iommu_domain *(*group_iommu_domain)(void *iommu_data,
66 struct iommu_group *group);
67 void (*notify)(void *iommu_data,
68 enum vfio_iommu_notify_type event);
69};
70
71int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);
72void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops);
drivers/vfio/vfio_iommu_spapr_tce.c+5−1
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/sched/mm.h>20#include <linux/sched/mm.h>
21#include <linux/sched/signal.h>21#include <linux/sched/signal.h>
22#include <linux/mm.h>22#include <linux/mm.h>
23#include "vfio.h"
23 24
24#include <asm/iommu.h>25#include <asm/iommu.h>
25#include <asm/tce.h>26#include <asm/tce.h>
@@ -1238,13 +1239,16 @@ release_exit: · 1212 unmodified lines
1238}1239}
1239 1240
1240static int tce_iommu_attach_group(void *iommu_data,1241static int tce_iommu_attach_group(void *iommu_data,
1241 struct iommu_group *iommu_group)1242 struct iommu_group *iommu_group, enum vfio_group_type type)
1242{1243{
1243 int ret = 0;1244 int ret = 0;
1244 struct tce_container *container = iommu_data;1245 struct tce_container *container = iommu_data;
1245 struct iommu_table_group *table_group;1246 struct iommu_table_group *table_group;
1246 struct tce_iommu_group *tcegrp = NULL;1247 struct tce_iommu_group *tcegrp = NULL;
1247 1248
1249 if (type == VFIO_EMULATED_IOMMU)
1250 return -EINVAL;
1251
1248 mutex_lock(&container->lock);1252 mutex_lock(&container->lock);
1249 1253
1250 /* pr_debug("tce_vfio: Attaching group #%u to iommu %p\n",1254 /* pr_debug("tce_vfio: Attaching group #%u to iommu %p\n",
drivers/vfio/vfio_iommu_type1.c+73−183
@@ -36,10 +36,10 @@ · 35 unmodified lines
36#include <linux/uaccess.h>36#include <linux/uaccess.h>
37#include <linux/vfio.h>37#include <linux/vfio.h>
38#include <linux/workqueue.h>38#include <linux/workqueue.h>
39#include <linux/mdev.h>
40#include <linux/notifier.h>39#include <linux/notifier.h>
41#include <linux/dma-iommu.h>40#include <linux/dma-iommu.h>
42#include <linux/irqdomain.h>41#include <linux/irqdomain.h>
42#include "vfio.h"
43 43
44#define DRIVER_VERSION "0.2"44#define DRIVER_VERSION "0.2"
45#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"45#define DRIVER_AUTHOR "Alex Williamson <alex.williamson@redhat.com>"
@@ -65,7 +65,6 @@ MODULE_PARM_DESC(dma_entry_limit, · 19 unmodified lines
65struct vfio_iommu {65struct vfio_iommu {
66 struct list_head domain_list;66 struct list_head domain_list;
67 struct list_head iova_list;67 struct list_head iova_list;
68 struct vfio_domain *external_domain; /* domain for external user */
69 struct mutex lock;68 struct mutex lock;
70 struct rb_root dma_list;69 struct rb_root dma_list;
71 struct blocking_notifier_head notifier;70 struct blocking_notifier_head notifier;
@@ -78,6 +77,7 @@ struct vfio_iommu { · 6 unmodified lines
78 bool nesting;77 bool nesting;
79 bool dirty_page_tracking;78 bool dirty_page_tracking;
80 bool container_open;79 bool container_open;
80 struct list_head emulated_iommu_groups;
81};81};
82 82
83struct vfio_domain {83struct vfio_domain {
@@ -113,7 +113,6 @@ struct vfio_batch { · 29 unmodified lines
113struct vfio_iommu_group {113struct vfio_iommu_group {
114 struct iommu_group *iommu_group;114 struct iommu_group *iommu_group;
115 struct list_head next;115 struct list_head next;
116 bool mdev_group; /* An mdev group */
117 bool pinned_page_dirty_scope;116 bool pinned_page_dirty_scope;
118};117};
119 118
@@ -140,9 +139,6 @@ struct vfio_regions { · 20 unmodified lines
140 size_t len;139 size_t len;
141};140};
142 141
143#define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu) \
144 (!list_empty(&iommu->domain_list))
145
146#define DIRTY_BITMAP_BYTES(n) (ALIGN(n, BITS_PER_TYPE(u64)) / BITS_PER_BYTE)142#define DIRTY_BITMAP_BYTES(n) (ALIGN(n, BITS_PER_TYPE(u64)) / BITS_PER_BYTE)
147 143
148/*144/*
@@ -880,7 +876,7 @@ again: · 731 unmodified lines
880 * already pinned and accounted. Accounting should be done if there is no876 * already pinned and accounted. Accounting should be done if there is no
881 * iommu capable domain in the container.877 * iommu capable domain in the container.
882 */878 */
883 do_accounting = !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu);879 do_accounting = list_empty(&iommu->domain_list);
884 880
885 for (i = 0; i < npage; i++) {881 for (i = 0; i < npage; i++) {
886 struct vfio_pfn *vpfn;882 struct vfio_pfn *vpfn;
@@ -969,7 +965,7 @@ static int vfio_iommu_type1_unpin_pages(void *iommu_data, · 82 unmodified lines
969 965
970 mutex_lock(&iommu->lock);966 mutex_lock(&iommu->lock);
971 967
972 do_accounting = !IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu);968 do_accounting = list_empty(&iommu->domain_list);
973 for (i = 0; i < npage; i++) {969 for (i = 0; i < npage; i++) {
974 struct vfio_dma *dma;970 struct vfio_dma *dma;
975 dma_addr_t iova;971 dma_addr_t iova;
@@ -1090,7 +1086,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, · 114 unmodified lines
1090 if (!dma->size)1086 if (!dma->size)
1091 return 0;1087 return 0;
1092 1088
1093 if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu))1089 if (list_empty(&iommu->domain_list))
1094 return 0;1090 return 0;
1095 1091
1096 /*1092 /*
@@ -1667,7 +1663,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, · 570 unmodified lines
1667 vfio_link_dma(iommu, dma);1663 vfio_link_dma(iommu, dma);
1668 1664
1669 /* Don't pin and map if container doesn't contain IOMMU capable domain*/1665 /* Don't pin and map if container doesn't contain IOMMU capable domain*/
1670 if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu))1666 if (list_empty(&iommu->domain_list))
1671 dma->size = size;1667 dma->size = size;
1672 else1668 else
1673 ret = vfio_pin_map_dma(iommu, dma, size);1669 ret = vfio_pin_map_dma(iommu, dma, size);
@@ -1893,8 +1889,8 @@ static struct vfio_iommu_group* · 219 unmodified lines
1893vfio_iommu_find_iommu_group(struct vfio_iommu *iommu,1889vfio_iommu_find_iommu_group(struct vfio_iommu *iommu,
1894 struct iommu_group *iommu_group)1890 struct iommu_group *iommu_group)
1895{1891{
1892 struct vfio_iommu_group *group;
1896 struct vfio_domain *domain;1893 struct vfio_domain *domain;
1897 struct vfio_iommu_group *group = NULL;
1898 1894
1899 list_for_each_entry(domain, &iommu->domain_list, next) {1895 list_for_each_entry(domain, &iommu->domain_list, next) {
1900 group = find_iommu_group(domain, iommu_group);1896 group = find_iommu_group(domain, iommu_group);
@@ -1902,10 +1898,10 @@ vfio_iommu_find_iommu_group(struct vfio_iommu *iommu, · 1 unmodified line
1902 return group;1898 return group;
1903 }1899 }
1904 1900
1905 if (iommu->external_domain)1901 list_for_each_entry(group, &iommu->emulated_iommu_groups, next)
1906 group = find_iommu_group(iommu->external_domain, iommu_group);1902 if (group->iommu_group == iommu_group)
1907 1903 return group;
1908 return group;1904 return NULL;
1909}1905}
1910 1906
1911static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions,1907static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions,
@@ -1934,89 +1930,6 @@ static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions, · 22 unmodified lines
1934 return ret;1930 return ret;
1935}1931}
1936 1932
1937static int vfio_mdev_attach_domain(struct device *dev, void *data)
1938{
1939 struct mdev_device *mdev = to_mdev_device(dev);
1940 struct iommu_domain *domain = data;
1941 struct device *iommu_device;
1942
1943 iommu_device = mdev_get_iommu_device(mdev);
1944 if (iommu_device) {
1945 if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
1946 return iommu_aux_attach_device(domain, iommu_device);
1947 else
1948 return iommu_attach_device(domain, iommu_device);
1949 }
1950
1951 return -EINVAL;
1952}
1953
1954static int vfio_mdev_detach_domain(struct device *dev, void *data)
1955{
1956 struct mdev_device *mdev = to_mdev_device(dev);
1957 struct iommu_domain *domain = data;
1958 struct device *iommu_device;
1959
1960 iommu_device = mdev_get_iommu_device(mdev);
1961 if (iommu_device) {
1962 if (iommu_dev_feature_enabled(iommu_device, IOMMU_DEV_FEAT_AUX))
1963 iommu_aux_detach_device(domain, iommu_device);
1964 else
1965 iommu_detach_device(domain, iommu_device);
1966 }
1967
1968 return 0;
1969}
1970
1971static int vfio_iommu_attach_group(struct vfio_domain *domain,
1972 struct vfio_iommu_group *group)
1973{
1974 if (group->mdev_group)
1975 return iommu_group_for_each_dev(group->iommu_group,
1976 domain->domain,
1977 vfio_mdev_attach_domain);
1978 else
1979 return iommu_attach_group(domain->domain, group->iommu_group);
1980}
1981
1982static void vfio_iommu_detach_group(struct vfio_domain *domain,
1983 struct vfio_iommu_group *group)
1984{
1985 if (group->mdev_group)
1986 iommu_group_for_each_dev(group->iommu_group, domain->domain,
1987 vfio_mdev_detach_domain);
1988 else
1989 iommu_detach_group(domain->domain, group->iommu_group);
1990}
1991
1992static bool vfio_bus_is_mdev(struct bus_type *bus)
1993{
1994 struct bus_type *mdev_bus;
1995 bool ret = false;
1996
1997 mdev_bus = symbol_get(mdev_bus_type);
1998 if (mdev_bus) {
1999 ret = (bus == mdev_bus);
2000 symbol_put(mdev_bus_type);
2001 }
2002
2003 return ret;
2004}
2005
2006static int vfio_mdev_iommu_device(struct device *dev, void *data)
2007{
2008 struct mdev_device *mdev = to_mdev_device(dev);
2009 struct device **old = data, *new;
2010
2011 new = mdev_get_iommu_device(mdev);
2012 if (!new || (*old && *old != new))
2013 return -EINVAL;
2014
2015 *old = new;
2016
2017 return 0;
2018}
2019
2020/*1933/*
2021 * This is a helper function to insert an address range to iova list.1934 * This is a helper function to insert an address range to iova list.
2022 * The list is initially created with a single entry corresponding to1935 * The list is initially created with a single entry corresponding to
@@ -2241,81 +2154,58 @@ static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu, · 218 unmodified lines
2241}2154}
2242 2155
2243static int vfio_iommu_type1_attach_group(void *iommu_data,2156static int vfio_iommu_type1_attach_group(void *iommu_data,
2244 struct iommu_group *iommu_group)2157 struct iommu_group *iommu_group, enum vfio_group_type type)
2245{2158{
2246 struct vfio_iommu *iommu = iommu_data;2159 struct vfio_iommu *iommu = iommu_data;
2247 struct vfio_iommu_group *group;2160 struct vfio_iommu_group *group;
2248 struct vfio_domain *domain, *d;2161 struct vfio_domain *domain, *d;
2249 struct bus_type *bus = NULL;2162 struct bus_type *bus = NULL;
2250 int ret;
2251 bool resv_msi, msi_remap;2163 bool resv_msi, msi_remap;
2252 phys_addr_t resv_msi_base = 0;2164 phys_addr_t resv_msi_base = 0;
2253 struct iommu_domain_geometry *geo;2165 struct iommu_domain_geometry *geo;
2254 LIST_HEAD(iova_copy);2166 LIST_HEAD(iova_copy);
2255 LIST_HEAD(group_resv_regions);2167 LIST_HEAD(group_resv_regions);
2168 int ret = -EINVAL;
2256 2169
2257 mutex_lock(&iommu->lock);2170 mutex_lock(&iommu->lock);
2258 2171
2259 /* Check for duplicates */2172 /* Check for duplicates */
2260 if (vfio_iommu_find_iommu_group(iommu, iommu_group)) {2173 if (vfio_iommu_find_iommu_group(iommu, iommu_group))
2261 mutex_unlock(&iommu->lock);2174 goto out_unlock;
2262 return -EINVAL;
2263 }
2264 2175
2176 ret = -ENOMEM;
2265 group = kzalloc(sizeof(*group), GFP_KERNEL);2177 group = kzalloc(sizeof(*group), GFP_KERNEL);
2266 domain = kzalloc(sizeof(*domain), GFP_KERNEL);2178 if (!group)
2267 if (!group || !domain) {2179 goto out_unlock;
2268 ret = -ENOMEM;
2269 goto out_free;
2270 }
2271
2272 group->iommu_group = iommu_group;2180 group->iommu_group = iommu_group;
2273 2181
2182 if (type == VFIO_EMULATED_IOMMU) {
2183 list_add(&group->next, &iommu->emulated_iommu_groups);
2184 /*
2185 * An emulated IOMMU group cannot dirty memory directly, it can
2186 * only use interfaces that provide dirty tracking.
2187 * The iommu scope can only be promoted with the addition of a
2188 * dirty tracking group.
2189 */
2190 group->pinned_page_dirty_scope = true;
2191 ret = 0;
2192 goto out_unlock;
2193 }
2194
2274 /* Determine bus_type in order to allocate a domain */2195 /* Determine bus_type in order to allocate a domain */
2275 ret = iommu_group_for_each_dev(iommu_group, &bus, vfio_bus_type);2196 ret = iommu_group_for_each_dev(iommu_group, &bus, vfio_bus_type);
2276 if (ret)2197 if (ret)
2277 goto out_free;2198 goto out_free_group;
2278
2279 if (vfio_bus_is_mdev(bus)) {
2280 struct device *iommu_device = NULL;
2281
2282 group->mdev_group = true;
2283
2284 /* Determine the isolation type */
2285 ret = iommu_group_for_each_dev(iommu_group, &iommu_device,
2286 vfio_mdev_iommu_device);
2287 if (ret || !iommu_device) {
2288 if (!iommu->external_domain) {
2289 INIT_LIST_HEAD(&domain->group_list);
2290 iommu->external_domain = domain;
2291 vfio_update_pgsize_bitmap(iommu);
2292 } else {
2293 kfree(domain);
2294 }
2295
2296 list_add(&group->next,
2297 &iommu->external_domain->group_list);
2298 /*
2299 * Non-iommu backed group cannot dirty memory directly,
2300 * it can only use interfaces that provide dirty
2301 * tracking.
2302 * The iommu scope can only be promoted with the
2303 * addition of a dirty tracking group.
2304 */
2305 group->pinned_page_dirty_scope = true;
2306 mutex_unlock(&iommu->lock);
2307 2199
2308 return 0;2200 ret = -ENOMEM;
2309 }2201 domain = kzalloc(sizeof(*domain), GFP_KERNEL);
2310 2202 if (!domain)
2311 bus = iommu_device->bus;2203 goto out_free_group;
2312 }
2313 2204
2205 ret = -EIO;
2314 domain->domain = iommu_domain_alloc(bus);2206 domain->domain = iommu_domain_alloc(bus);
2315 if (!domain->domain) {2207 if (!domain->domain)
2316 ret = -EIO;2208 goto out_free_domain;
2317 goto out_free;
2318 }
2319 2209
2320 if (iommu->nesting) {2210 if (iommu->nesting) {
2321 ret = iommu_enable_nesting(domain->domain);2211 ret = iommu_enable_nesting(domain->domain);
@@ -2323,7 +2213,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 1 unmodified line
2323 goto out_domain;2213 goto out_domain;
2324 }2214 }
2325 2215
2326 ret = vfio_iommu_attach_group(domain, group);2216 ret = iommu_attach_group(domain->domain, group->iommu_group);
2327 if (ret)2217 if (ret)
2328 goto out_domain;2218 goto out_domain;
2329 2219
@@ -2390,15 +2280,17 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 60 unmodified lines
2390 list_for_each_entry(d, &iommu->domain_list, next) {2280 list_for_each_entry(d, &iommu->domain_list, next) {
2391 if (d->domain->ops == domain->domain->ops &&2281 if (d->domain->ops == domain->domain->ops &&
2392 d->prot == domain->prot) {2282 d->prot == domain->prot) {
2393 vfio_iommu_detach_group(domain, group);2283 iommu_detach_group(domain->domain, group->iommu_group);
2394 if (!vfio_iommu_attach_group(d, group)) {2284 if (!iommu_attach_group(d->domain,
2285 group->iommu_group)) {
2395 list_add(&group->next, &d->group_list);2286 list_add(&group->next, &d->group_list);
2396 iommu_domain_free(domain->domain);2287 iommu_domain_free(domain->domain);
2397 kfree(domain);2288 kfree(domain);
2398 goto done;2289 goto done;
2399 }2290 }
2400 2291
2401 ret = vfio_iommu_attach_group(domain, group);2292 ret = iommu_attach_group(domain->domain,
2293 group->iommu_group);
2402 if (ret)2294 if (ret)
2403 goto out_domain;2295 goto out_domain;
2404 }2296 }
@@ -2435,14 +2327,16 @@ done: · 30 unmodified lines
2435 return 0;2327 return 0;
2436 2328
2437out_detach:2329out_detach:
2438 vfio_iommu_detach_group(domain, group);2330 iommu_detach_group(domain->domain, group->iommu_group);
2439out_domain:2331out_domain:
2440 iommu_domain_free(domain->domain);2332 iommu_domain_free(domain->domain);
2441 vfio_iommu_iova_free(&iova_copy);2333 vfio_iommu_iova_free(&iova_copy);
2442 vfio_iommu_resv_free(&group_resv_regions);2334 vfio_iommu_resv_free(&group_resv_regions);
2443out_free:2335out_free_domain:
2444 kfree(domain);2336 kfree(domain);
2337out_free_group:
2445 kfree(group);2338 kfree(group);
2339out_unlock:
2446 mutex_unlock(&iommu->lock);2340 mutex_unlock(&iommu->lock);
2447 return ret;2341 return ret;
2448}2342}
@@ -2567,25 +2461,19 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, · 118 unmodified lines
2567 LIST_HEAD(iova_copy);2461 LIST_HEAD(iova_copy);
2568 2462
2569 mutex_lock(&iommu->lock);2463 mutex_lock(&iommu->lock);
2464 list_for_each_entry(group, &iommu->emulated_iommu_groups, next) {
2465 if (group->iommu_group != iommu_group)
2466 continue;
2467 update_dirty_scope = !group->pinned_page_dirty_scope;
2468 list_del(&group->next);
2469 kfree(group);
2570 2470
2571 if (iommu->external_domain) {2471 if (list_empty(&iommu->emulated_iommu_groups) &&
2572 group = find_iommu_group(iommu->external_domain, iommu_group);2472 list_empty(&iommu->domain_list)) {
2573 if (group) {2473 WARN_ON(iommu->notifier.head);
2574 update_dirty_scope = !group->pinned_page_dirty_scope;2474 vfio_iommu_unmap_unpin_all(iommu);
2575 list_del(&group->next);
2576 kfree(group);
2577
2578 if (list_empty(&iommu->external_domain->group_list)) {
2579 if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) {
2580 WARN_ON(iommu->notifier.head);
2581 vfio_iommu_unmap_unpin_all(iommu);
2582 }
2583
2584 kfree(iommu->external_domain);
2585 iommu->external_domain = NULL;
2586 }
2587 goto detach_group_done;
2588 }2475 }
2476 goto detach_group_done;
2589 }2477 }
2590 2478
2591 /*2479 /*
@@ -2600,7 +2488,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, · 8 unmodified lines
2600 if (!group)2488 if (!group)
2601 continue;2489 continue;
2602 2490
2603 vfio_iommu_detach_group(domain, group);2491 iommu_detach_group(domain->domain, group->iommu_group);
2604 update_dirty_scope = !group->pinned_page_dirty_scope;2492 update_dirty_scope = !group->pinned_page_dirty_scope;
2605 list_del(&group->next);2493 list_del(&group->next);
2606 kfree(group);2494 kfree(group);
@@ -2613,7 +2501,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, · 6 unmodified lines
2613 */2501 */
2614 if (list_empty(&domain->group_list)) {2502 if (list_empty(&domain->group_list)) {
2615 if (list_is_singular(&iommu->domain_list)) {2503 if (list_is_singular(&iommu->domain_list)) {
2616 if (!iommu->external_domain) {2504 if (list_empty(&iommu->emulated_iommu_groups)) {
2617 WARN_ON(iommu->notifier.head);2505 WARN_ON(iommu->notifier.head);
2618 vfio_iommu_unmap_unpin_all(iommu);2506 vfio_iommu_unmap_unpin_all(iommu);
2619 } else {2507 } else {
@@ -2677,41 +2565,43 @@ static void *vfio_iommu_type1_open(unsigned long arg) · 57 unmodified lines
2677 mutex_init(&iommu->lock);2565 mutex_init(&iommu->lock);
2678 BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);2566 BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);
2679 init_waitqueue_head(&iommu->vaddr_wait);2567 init_waitqueue_head(&iommu->vaddr_wait);
2568 iommu->pgsize_bitmap = PAGE_MASK;
2569 INIT_LIST_HEAD(&iommu->emulated_iommu_groups);
2680 2570
2681 return iommu;2571 return iommu;
2682}2572}
2683 2573
2684static void vfio_release_domain(struct vfio_domain *domain, bool external)2574static void vfio_release_domain(struct vfio_domain *domain)
2685{2575{
2686 struct vfio_iommu_group *group, *group_tmp;2576 struct vfio_iommu_group *group, *group_tmp;
2687 2577
2688 list_for_each_entry_safe(group, group_tmp,2578 list_for_each_entry_safe(group, group_tmp,
2689 &domain->group_list, next) {2579 &domain->group_list, next) {
2690 if (!external)2580 iommu_detach_group(domain->domain, group->iommu_group);
2691 vfio_iommu_detach_group(domain, group);
2692 list_del(&group->next);2581 list_del(&group->next);
2693 kfree(group);2582 kfree(group);
2694 }2583 }
2695 2584
2696 if (!external)2585 iommu_domain_free(domain->domain);
2697 iommu_domain_free(domain->domain);
2698}2586}
2699 2587
2700static void vfio_iommu_type1_release(void *iommu_data)2588static void vfio_iommu_type1_release(void *iommu_data)
2701{2589{
2702 struct vfio_iommu *iommu = iommu_data;2590 struct vfio_iommu *iommu = iommu_data;
2703 struct vfio_domain *domain, *domain_tmp;2591 struct vfio_domain *domain, *domain_tmp;
2592 struct vfio_iommu_group *group, *next_group;
2704 2593
2705 if (iommu->external_domain) {2594 list_for_each_entry_safe(group, next_group,
2706 vfio_release_domain(iommu->external_domain, true);2595 &iommu->emulated_iommu_groups, next) {
2707 kfree(iommu->external_domain);2596 list_del(&group->next);
2597 kfree(group);
2708 }2598 }
2709 2599
2710 vfio_iommu_unmap_unpin_all(iommu);2600 vfio_iommu_unmap_unpin_all(iommu);
2711 2601
2712 list_for_each_entry_safe(domain, domain_tmp,2602 list_for_each_entry_safe(domain, domain_tmp,
2713 &iommu->domain_list, next) {2603 &iommu->domain_list, next) {
2714 vfio_release_domain(domain, false);2604 vfio_release_domain(domain);
2715 list_del(&domain->next);2605 list_del(&domain->next);
2716 kfree(domain);2606 kfree(domain);
2717 }2607 }
include/linux/fsl/mc.h+14−0
@@ -620,6 +620,20 @@ int dpcon_reset(struct fsl_mc_io *mc_io, · 619 unmodified lines
620 u32 cmd_flags,620 u32 cmd_flags,
621 u16 token);621 u16 token);
622 622
623int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
624 u32 cmd_flags,
625 int obj_id,
626 char *obj_type,
627 u16 *token);
628
629int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
630 u32 cmd_flags,
631 u16 token);
632
633int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
634 u32 cmd_flags,
635 u16 token);
636
623/**637/**
624 * struct dpcon_attr - Structure representing DPCON attributes638 * struct dpcon_attr - Structure representing DPCON attributes
625 * @id: DPCON object ID639 * @id: DPCON object ID
include/linux/mdev.h+0−20
@@ -18,7 +18,6 @@ struct mdev_device { · 17 unmodified lines
18 void *driver_data;18 void *driver_data;
19 struct list_head next;19 struct list_head next;
20 struct mdev_type *type;20 struct mdev_type *type;
21 struct device *iommu_device;
22 bool active;21 bool active;
23};22};
24 23
@@ -27,25 +26,6 @@ static inline struct mdev_device *to_mdev_device(struct device *dev) · 2 unmodified lines
27 return container_of(dev, struct mdev_device, dev);26 return container_of(dev, struct mdev_device, dev);
28}27}
29 28
30/*
31 * Called by the parent device driver to set the device which represents
32 * this mdev in iommu protection scope. By default, the iommu device is
33 * NULL, that indicates using vendor defined isolation.
34 *
35 * @dev: the mediated device that iommu will isolate.
36 * @iommu_device: a pci device which represents the iommu for @dev.
37 */
38static inline void mdev_set_iommu_device(struct mdev_device *mdev,
39 struct device *iommu_device)
40{
41 mdev->iommu_device = iommu_device;
42}
43
44static inline struct device *mdev_get_iommu_device(struct mdev_device *mdev)
45{
46 return mdev->iommu_device;
47}
48
49unsigned int mdev_get_type_group_id(struct mdev_device *mdev);29unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
50unsigned int mtype_get_type_group_id(struct mdev_type *mtype);30unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
51struct device *mtype_get_parent_dev(struct mdev_type *mtype);31struct device *mtype_get_parent_dev(struct mdev_type *mtype);
include/linux/vfio.h+1−52
@@ -71,68 +71,17 @@ struct vfio_device_ops { · 70 unmodified lines
71 int (*match)(struct vfio_device *vdev, char *buf);71 int (*match)(struct vfio_device *vdev, char *buf);
72};72};
73 73
74extern struct iommu_group *vfio_iommu_group_get(struct device *dev);
75extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev);
76
77void vfio_init_group_dev(struct vfio_device *device, struct device *dev,74void vfio_init_group_dev(struct vfio_device *device, struct device *dev,
78 const struct vfio_device_ops *ops);75 const struct vfio_device_ops *ops);
79void vfio_uninit_group_dev(struct vfio_device *device);76void vfio_uninit_group_dev(struct vfio_device *device);
80int vfio_register_group_dev(struct vfio_device *device);77int vfio_register_group_dev(struct vfio_device *device);
78int vfio_register_emulated_iommu_dev(struct vfio_device *device);
81void vfio_unregister_group_dev(struct vfio_device *device);79void vfio_unregister_group_dev(struct vfio_device *device);
82extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);80extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
83extern void vfio_device_put(struct vfio_device *device);81extern void vfio_device_put(struct vfio_device *device);
84 82
85int vfio_assign_device_set(struct vfio_device *device, void *set_id);83int vfio_assign_device_set(struct vfio_device *device, void *set_id);
86 84
87/* events for the backend driver notify callback */
88enum vfio_iommu_notify_type {
89 VFIO_IOMMU_CONTAINER_CLOSE = 0,
90};
91
92/**
93 * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks
94 */
95struct vfio_iommu_driver_ops {
96 char *name;
97 struct module *owner;
98 void *(*open)(unsigned long arg);
99 void (*release)(void *iommu_data);
100 ssize_t (*read)(void *iommu_data, char __user *buf,
101 size_t count, loff_t *ppos);
102 ssize_t (*write)(void *iommu_data, const char __user *buf,
103 size_t count, loff_t *size);
104 long (*ioctl)(void *iommu_data, unsigned int cmd,
105 unsigned long arg);
106 int (*mmap)(void *iommu_data, struct vm_area_struct *vma);
107 int (*attach_group)(void *iommu_data,
108 struct iommu_group *group);
109 void (*detach_group)(void *iommu_data,
110 struct iommu_group *group);
111 int (*pin_pages)(void *iommu_data,
112 struct iommu_group *group,
113 unsigned long *user_pfn,
114 int npage, int prot,
115 unsigned long *phys_pfn);
116 int (*unpin_pages)(void *iommu_data,
117 unsigned long *user_pfn, int npage);
118 int (*register_notifier)(void *iommu_data,
119 unsigned long *events,
120 struct notifier_block *nb);
121 int (*unregister_notifier)(void *iommu_data,
122 struct notifier_block *nb);
123 int (*dma_rw)(void *iommu_data, dma_addr_t user_iova,
124 void *data, size_t count, bool write);
125 struct iommu_domain *(*group_iommu_domain)(void *iommu_data,
126 struct iommu_group *group);
127 void (*notify)(void *iommu_data,
128 enum vfio_iommu_notify_type event);
129};
130
131extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);
132
133extern void vfio_unregister_iommu_driver(
134 const struct vfio_iommu_driver_ops *ops);
135
136/*85/*
137 * External user API86 * External user API
138 */87 */
samples/vfio-mdev/mbochs.c+1−1
@@ -553,7 +553,7 @@ static int mbochs_probe(struct mdev_device *mdev) · 552 unmodified lines
553 mbochs_create_config_space(mdev_state);553 mbochs_create_config_space(mdev_state);
554 mbochs_reset(mdev_state);554 mbochs_reset(mdev_state);
555 555
556 ret = vfio_register_group_dev(&mdev_state->vdev);556 ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev);
557 if (ret)557 if (ret)
558 goto err_mem;558 goto err_mem;
559 dev_set_drvdata(&mdev->dev, mdev_state);559 dev_set_drvdata(&mdev->dev, mdev_state);
samples/vfio-mdev/mdpy.c+1−1
@@ -258,7 +258,7 @@ static int mdpy_probe(struct mdev_device *mdev) · 257 unmodified lines
258 258
259 mdpy_count++;259 mdpy_count++;
260 260
261 ret = vfio_register_group_dev(&mdev_state->vdev);261 ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev);
262 if (ret)262 if (ret)
263 goto err_mem;263 goto err_mem;
264 dev_set_drvdata(&mdev->dev, mdev_state);264 dev_set_drvdata(&mdev->dev, mdev_state);
samples/vfio-mdev/mtty.c+1−1
@@ -741,7 +741,7 @@ static int mtty_probe(struct mdev_device *mdev) · 740 unmodified lines
741 741
742 mtty_create_config_space(mdev_state);742 mtty_create_config_space(mdev_state);
743 743
744 ret = vfio_register_group_dev(&mdev_state->vdev);744 ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev);
745 if (ret)745 if (ret)
746 goto err_vconfig;746 goto err_vconfig;
747 dev_set_drvdata(&mdev->dev, mdev_state);747 dev_set_drvdata(&mdev->dev, mdev_state);