1*bf4197beSJulian Ruess // SPDX-License-Identifier: GPL-2.0 2*bf4197beSJulian Ruess /* 3*bf4197beSJulian Ruess * vfio-ISM driver for s390 4*bf4197beSJulian Ruess * 5*bf4197beSJulian Ruess * Copyright IBM Corp. 6*bf4197beSJulian Ruess */ 7*bf4197beSJulian Ruess 8*bf4197beSJulian Ruess #include <linux/slab.h> 9*bf4197beSJulian Ruess #include "../vfio_pci_priv.h" 10*bf4197beSJulian Ruess 11*bf4197beSJulian Ruess #define ISM_VFIO_PCI_OFFSET_SHIFT 48 12*bf4197beSJulian Ruess #define ISM_VFIO_PCI_OFFSET_TO_INDEX(off) ((off) >> ISM_VFIO_PCI_OFFSET_SHIFT) 13*bf4197beSJulian Ruess #define ISM_VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << ISM_VFIO_PCI_OFFSET_SHIFT) 14*bf4197beSJulian Ruess #define ISM_VFIO_PCI_OFFSET_MASK (((u64)(1) << ISM_VFIO_PCI_OFFSET_SHIFT) - 1) 15*bf4197beSJulian Ruess 16*bf4197beSJulian Ruess /* 17*bf4197beSJulian Ruess * Use __zpci_load() to bypass automatic use of 18*bf4197beSJulian Ruess * PCI MIO instructions which are not supported on ISM devices 19*bf4197beSJulian Ruess */ 20*bf4197beSJulian Ruess #define ISM_READ(size) \ 21*bf4197beSJulian Ruess static int ism_read##size(struct zpci_dev *zdev, int bar, \ 22*bf4197beSJulian Ruess size_t *filled, char __user *buf, \ 23*bf4197beSJulian Ruess loff_t off) \ 24*bf4197beSJulian Ruess { \ 25*bf4197beSJulian Ruess u64 req, tmp; \ 26*bf4197beSJulian Ruess u##size val; \ 27*bf4197beSJulian Ruess int ret; \ 28*bf4197beSJulian Ruess \ 29*bf4197beSJulian Ruess req = ZPCI_CREATE_REQ(READ_ONCE(zdev->fh), bar, sizeof(val)); \ 30*bf4197beSJulian Ruess ret = __zpci_load(&tmp, req, off); \ 31*bf4197beSJulian Ruess if (ret) \ 32*bf4197beSJulian Ruess return ret; \ 33*bf4197beSJulian Ruess val = (u##size)tmp; \ 34*bf4197beSJulian Ruess if (copy_to_user(buf, &val, sizeof(val))) \ 35*bf4197beSJulian Ruess return -EFAULT; \ 36*bf4197beSJulian Ruess *filled = sizeof(val); \ 37*bf4197beSJulian Ruess return 0; \ 38*bf4197beSJulian Ruess } 39*bf4197beSJulian Ruess 40*bf4197beSJulian Ruess ISM_READ(64); 41*bf4197beSJulian Ruess ISM_READ(32); 42*bf4197beSJulian Ruess ISM_READ(16); 43*bf4197beSJulian Ruess ISM_READ(8); 44*bf4197beSJulian Ruess 45*bf4197beSJulian Ruess struct ism_vfio_pci_core_device { 46*bf4197beSJulian Ruess struct vfio_pci_core_device core_device; 47*bf4197beSJulian Ruess struct kmem_cache *store_block_cache; 48*bf4197beSJulian Ruess }; 49*bf4197beSJulian Ruess 50*bf4197beSJulian Ruess static int ism_vfio_pci_open_device(struct vfio_device *core_vdev) 51*bf4197beSJulian Ruess { 52*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd; 53*bf4197beSJulian Ruess struct vfio_pci_core_device *vdev; 54*bf4197beSJulian Ruess int ret; 55*bf4197beSJulian Ruess 56*bf4197beSJulian Ruess ivpcd = container_of(core_vdev, struct ism_vfio_pci_core_device, 57*bf4197beSJulian Ruess core_device.vdev); 58*bf4197beSJulian Ruess vdev = &ivpcd->core_device; 59*bf4197beSJulian Ruess 60*bf4197beSJulian Ruess ret = vfio_pci_core_enable(vdev); 61*bf4197beSJulian Ruess if (ret) 62*bf4197beSJulian Ruess return ret; 63*bf4197beSJulian Ruess 64*bf4197beSJulian Ruess vfio_pci_core_finish_enable(vdev); 65*bf4197beSJulian Ruess return 0; 66*bf4197beSJulian Ruess } 67*bf4197beSJulian Ruess 68*bf4197beSJulian Ruess /* 69*bf4197beSJulian Ruess * ism_vfio_pci_do_io_r() 70*bf4197beSJulian Ruess * 71*bf4197beSJulian Ruess * On s390, kernel primitives such as ioread() and iowrite() are switched over 72*bf4197beSJulian Ruess * from function-handle-based PCI load/stores instructions to PCI memory-I/O (MIO) 73*bf4197beSJulian Ruess * loads/stores when these are available and not explicitly disabled. Since these 74*bf4197beSJulian Ruess * instructions cannot be used with ISM devices, ensure that classic 75*bf4197beSJulian Ruess * function-handle-based PCI instructions are used instead. 76*bf4197beSJulian Ruess */ 77*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_do_io_r(struct vfio_pci_core_device *vdev, 78*bf4197beSJulian Ruess char __user *buf, loff_t off, size_t count, 79*bf4197beSJulian Ruess int bar) 80*bf4197beSJulian Ruess { 81*bf4197beSJulian Ruess struct zpci_dev *zdev = to_zpci(vdev->pdev); 82*bf4197beSJulian Ruess ssize_t done = 0; 83*bf4197beSJulian Ruess int ret; 84*bf4197beSJulian Ruess 85*bf4197beSJulian Ruess while (count) { 86*bf4197beSJulian Ruess size_t filled; 87*bf4197beSJulian Ruess 88*bf4197beSJulian Ruess if (count >= 8 && IS_ALIGNED(off, 8)) { 89*bf4197beSJulian Ruess ret = ism_read64(zdev, bar, &filled, buf, off); 90*bf4197beSJulian Ruess if (ret) 91*bf4197beSJulian Ruess return ret; 92*bf4197beSJulian Ruess } else if (count >= 4 && IS_ALIGNED(off, 4)) { 93*bf4197beSJulian Ruess ret = ism_read32(zdev, bar, &filled, buf, off); 94*bf4197beSJulian Ruess if (ret) 95*bf4197beSJulian Ruess return ret; 96*bf4197beSJulian Ruess } else if (count >= 2 && IS_ALIGNED(off, 2)) { 97*bf4197beSJulian Ruess ret = ism_read16(zdev, bar, &filled, buf, off); 98*bf4197beSJulian Ruess if (ret) 99*bf4197beSJulian Ruess return ret; 100*bf4197beSJulian Ruess } else { 101*bf4197beSJulian Ruess ret = ism_read8(zdev, bar, &filled, buf, off); 102*bf4197beSJulian Ruess if (ret) 103*bf4197beSJulian Ruess return ret; 104*bf4197beSJulian Ruess } 105*bf4197beSJulian Ruess 106*bf4197beSJulian Ruess count -= filled; 107*bf4197beSJulian Ruess done += filled; 108*bf4197beSJulian Ruess off += filled; 109*bf4197beSJulian Ruess buf += filled; 110*bf4197beSJulian Ruess } 111*bf4197beSJulian Ruess 112*bf4197beSJulian Ruess return done; 113*bf4197beSJulian Ruess } 114*bf4197beSJulian Ruess 115*bf4197beSJulian Ruess /* 116*bf4197beSJulian Ruess * ism_vfio_pci_do_io_w() 117*bf4197beSJulian Ruess * 118*bf4197beSJulian Ruess * Ensure that the PCI store block (PCISTB) instruction is used as required by the 119*bf4197beSJulian Ruess * ISM device. The ISM device also uses a 256 TiB BAR 0 for write operations, 120*bf4197beSJulian Ruess * which requires a 48bit region address space (ISM_VFIO_PCI_OFFSET_SHIFT). 121*bf4197beSJulian Ruess */ 122*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_do_io_w(struct vfio_pci_core_device *vdev, 123*bf4197beSJulian Ruess char __user *buf, loff_t off, size_t count, 124*bf4197beSJulian Ruess int bar) 125*bf4197beSJulian Ruess { 126*bf4197beSJulian Ruess struct zpci_dev *zdev = to_zpci(vdev->pdev); 127*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd; 128*bf4197beSJulian Ruess ssize_t ret; 129*bf4197beSJulian Ruess void *data; 130*bf4197beSJulian Ruess u64 req; 131*bf4197beSJulian Ruess 132*bf4197beSJulian Ruess if (count > zdev->maxstbl) 133*bf4197beSJulian Ruess return -EINVAL; 134*bf4197beSJulian Ruess if (((off % PAGE_SIZE) + count) > PAGE_SIZE) 135*bf4197beSJulian Ruess return -EINVAL; 136*bf4197beSJulian Ruess 137*bf4197beSJulian Ruess ivpcd = container_of(vdev, struct ism_vfio_pci_core_device, 138*bf4197beSJulian Ruess core_device); 139*bf4197beSJulian Ruess data = kmem_cache_alloc(ivpcd->store_block_cache, GFP_KERNEL); 140*bf4197beSJulian Ruess if (!data) 141*bf4197beSJulian Ruess return -ENOMEM; 142*bf4197beSJulian Ruess 143*bf4197beSJulian Ruess if (copy_from_user(data, buf, count)) { 144*bf4197beSJulian Ruess ret = -EFAULT; 145*bf4197beSJulian Ruess goto out_free; 146*bf4197beSJulian Ruess } 147*bf4197beSJulian Ruess 148*bf4197beSJulian Ruess req = ZPCI_CREATE_REQ(READ_ONCE(zdev->fh), bar, count); 149*bf4197beSJulian Ruess ret = __zpci_store_block(data, req, off); 150*bf4197beSJulian Ruess if (ret) 151*bf4197beSJulian Ruess goto out_free; 152*bf4197beSJulian Ruess 153*bf4197beSJulian Ruess ret = count; 154*bf4197beSJulian Ruess 155*bf4197beSJulian Ruess out_free: 156*bf4197beSJulian Ruess kmem_cache_free(ivpcd->store_block_cache, data); 157*bf4197beSJulian Ruess return ret; 158*bf4197beSJulian Ruess } 159*bf4197beSJulian Ruess 160*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, 161*bf4197beSJulian Ruess char __user *buf, size_t count, loff_t *ppos, 162*bf4197beSJulian Ruess bool iswrite) 163*bf4197beSJulian Ruess { 164*bf4197beSJulian Ruess int bar = ISM_VFIO_PCI_OFFSET_TO_INDEX(*ppos); 165*bf4197beSJulian Ruess loff_t pos = *ppos & ISM_VFIO_PCI_OFFSET_MASK; 166*bf4197beSJulian Ruess resource_size_t end; 167*bf4197beSJulian Ruess ssize_t done = 0; 168*bf4197beSJulian Ruess 169*bf4197beSJulian Ruess if (pci_resource_start(vdev->pdev, bar)) 170*bf4197beSJulian Ruess end = pci_resource_len(vdev->pdev, bar); 171*bf4197beSJulian Ruess else 172*bf4197beSJulian Ruess return -EINVAL; 173*bf4197beSJulian Ruess 174*bf4197beSJulian Ruess if (pos >= end) 175*bf4197beSJulian Ruess return -EINVAL; 176*bf4197beSJulian Ruess 177*bf4197beSJulian Ruess count = min(count, (size_t)(end - pos)); 178*bf4197beSJulian Ruess 179*bf4197beSJulian Ruess if (iswrite) 180*bf4197beSJulian Ruess done = ism_vfio_pci_do_io_w(vdev, buf, pos, count, bar); 181*bf4197beSJulian Ruess else 182*bf4197beSJulian Ruess done = ism_vfio_pci_do_io_r(vdev, buf, pos, count, bar); 183*bf4197beSJulian Ruess 184*bf4197beSJulian Ruess if (done >= 0) 185*bf4197beSJulian Ruess *ppos += done; 186*bf4197beSJulian Ruess 187*bf4197beSJulian Ruess return done; 188*bf4197beSJulian Ruess } 189*bf4197beSJulian Ruess 190*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_config_rw(struct vfio_pci_core_device *vdev, 191*bf4197beSJulian Ruess char __user *buf, size_t count, 192*bf4197beSJulian Ruess loff_t *ppos, bool iswrite) 193*bf4197beSJulian Ruess { 194*bf4197beSJulian Ruess loff_t pos = *ppos; 195*bf4197beSJulian Ruess size_t done = 0; 196*bf4197beSJulian Ruess int ret = 0; 197*bf4197beSJulian Ruess 198*bf4197beSJulian Ruess pos &= ISM_VFIO_PCI_OFFSET_MASK; 199*bf4197beSJulian Ruess 200*bf4197beSJulian Ruess while (count) { 201*bf4197beSJulian Ruess /* 202*bf4197beSJulian Ruess * zPCI must not use MIO instructions for config space access, 203*bf4197beSJulian Ruess * so we can use common code path here. 204*bf4197beSJulian Ruess */ 205*bf4197beSJulian Ruess ret = vfio_pci_config_rw_single(vdev, buf, count, &pos, iswrite); 206*bf4197beSJulian Ruess if (ret < 0) 207*bf4197beSJulian Ruess return ret; 208*bf4197beSJulian Ruess 209*bf4197beSJulian Ruess count -= ret; 210*bf4197beSJulian Ruess done += ret; 211*bf4197beSJulian Ruess buf += ret; 212*bf4197beSJulian Ruess pos += ret; 213*bf4197beSJulian Ruess } 214*bf4197beSJulian Ruess 215*bf4197beSJulian Ruess *ppos += done; 216*bf4197beSJulian Ruess 217*bf4197beSJulian Ruess return done; 218*bf4197beSJulian Ruess } 219*bf4197beSJulian Ruess 220*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_rw(struct vfio_device *core_vdev, char __user *buf, 221*bf4197beSJulian Ruess size_t count, loff_t *ppos, bool iswrite) 222*bf4197beSJulian Ruess { 223*bf4197beSJulian Ruess unsigned int index = ISM_VFIO_PCI_OFFSET_TO_INDEX(*ppos); 224*bf4197beSJulian Ruess struct vfio_pci_core_device *vdev; 225*bf4197beSJulian Ruess int ret; 226*bf4197beSJulian Ruess 227*bf4197beSJulian Ruess vdev = container_of(core_vdev, struct vfio_pci_core_device, vdev); 228*bf4197beSJulian Ruess 229*bf4197beSJulian Ruess if (!count) 230*bf4197beSJulian Ruess return 0; 231*bf4197beSJulian Ruess 232*bf4197beSJulian Ruess switch (index) { 233*bf4197beSJulian Ruess case VFIO_PCI_CONFIG_REGION_INDEX: 234*bf4197beSJulian Ruess ret = ism_vfio_pci_config_rw(vdev, buf, count, ppos, iswrite); 235*bf4197beSJulian Ruess break; 236*bf4197beSJulian Ruess 237*bf4197beSJulian Ruess case VFIO_PCI_BAR0_REGION_INDEX ... VFIO_PCI_BAR5_REGION_INDEX: 238*bf4197beSJulian Ruess ret = ism_vfio_pci_bar_rw(vdev, buf, count, ppos, iswrite); 239*bf4197beSJulian Ruess break; 240*bf4197beSJulian Ruess 241*bf4197beSJulian Ruess default: 242*bf4197beSJulian Ruess return -EINVAL; 243*bf4197beSJulian Ruess } 244*bf4197beSJulian Ruess 245*bf4197beSJulian Ruess return ret; 246*bf4197beSJulian Ruess } 247*bf4197beSJulian Ruess 248*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_read(struct vfio_device *core_vdev, 249*bf4197beSJulian Ruess char __user *buf, size_t count, loff_t *ppos) 250*bf4197beSJulian Ruess { 251*bf4197beSJulian Ruess return ism_vfio_pci_rw(core_vdev, buf, count, ppos, false); 252*bf4197beSJulian Ruess } 253*bf4197beSJulian Ruess 254*bf4197beSJulian Ruess static ssize_t ism_vfio_pci_write(struct vfio_device *core_vdev, 255*bf4197beSJulian Ruess const char __user *buf, size_t count, 256*bf4197beSJulian Ruess loff_t *ppos) 257*bf4197beSJulian Ruess { 258*bf4197beSJulian Ruess return ism_vfio_pci_rw(core_vdev, (char __user *)buf, count, ppos, 259*bf4197beSJulian Ruess true); 260*bf4197beSJulian Ruess } 261*bf4197beSJulian Ruess 262*bf4197beSJulian Ruess static int ism_vfio_pci_ioctl_get_region_info(struct vfio_device *core_vdev, 263*bf4197beSJulian Ruess struct vfio_region_info *info, 264*bf4197beSJulian Ruess struct vfio_info_cap *caps) 265*bf4197beSJulian Ruess { 266*bf4197beSJulian Ruess struct vfio_pci_core_device *vdev = 267*bf4197beSJulian Ruess container_of(core_vdev, struct vfio_pci_core_device, vdev); 268*bf4197beSJulian Ruess struct pci_dev *pdev = vdev->pdev; 269*bf4197beSJulian Ruess 270*bf4197beSJulian Ruess switch (info->index) { 271*bf4197beSJulian Ruess case VFIO_PCI_CONFIG_REGION_INDEX: 272*bf4197beSJulian Ruess info->offset = ISM_VFIO_PCI_INDEX_TO_OFFSET(info->index); 273*bf4197beSJulian Ruess info->size = pdev->cfg_size; 274*bf4197beSJulian Ruess info->flags = VFIO_REGION_INFO_FLAG_READ | 275*bf4197beSJulian Ruess VFIO_REGION_INFO_FLAG_WRITE; 276*bf4197beSJulian Ruess break; 277*bf4197beSJulian Ruess case VFIO_PCI_BAR0_REGION_INDEX ... VFIO_PCI_BAR5_REGION_INDEX: 278*bf4197beSJulian Ruess info->offset = ISM_VFIO_PCI_INDEX_TO_OFFSET(info->index); 279*bf4197beSJulian Ruess info->size = pci_resource_len(pdev, info->index); 280*bf4197beSJulian Ruess if (!info->size) { 281*bf4197beSJulian Ruess info->flags = 0; 282*bf4197beSJulian Ruess break; 283*bf4197beSJulian Ruess } 284*bf4197beSJulian Ruess info->flags = VFIO_REGION_INFO_FLAG_READ | 285*bf4197beSJulian Ruess VFIO_REGION_INFO_FLAG_WRITE; 286*bf4197beSJulian Ruess break; 287*bf4197beSJulian Ruess default: 288*bf4197beSJulian Ruess info->offset = 0; 289*bf4197beSJulian Ruess info->size = 0; 290*bf4197beSJulian Ruess info->flags = 0; 291*bf4197beSJulian Ruess return -EINVAL; 292*bf4197beSJulian Ruess } 293*bf4197beSJulian Ruess return 0; 294*bf4197beSJulian Ruess } 295*bf4197beSJulian Ruess 296*bf4197beSJulian Ruess static int ism_vfio_pci_init_dev(struct vfio_device *core_vdev) 297*bf4197beSJulian Ruess { 298*bf4197beSJulian Ruess struct zpci_dev *zdev = to_zpci(to_pci_dev(core_vdev->dev)); 299*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd; 300*bf4197beSJulian Ruess char cache_name[20]; 301*bf4197beSJulian Ruess int ret; 302*bf4197beSJulian Ruess 303*bf4197beSJulian Ruess ivpcd = container_of(core_vdev, struct ism_vfio_pci_core_device, 304*bf4197beSJulian Ruess core_device.vdev); 305*bf4197beSJulian Ruess 306*bf4197beSJulian Ruess snprintf(cache_name, sizeof(cache_name), "ism_sb_fid_%08x", zdev->fid); 307*bf4197beSJulian Ruess 308*bf4197beSJulian Ruess ivpcd->store_block_cache = 309*bf4197beSJulian Ruess kmem_cache_create(cache_name, zdev->maxstbl, 310*bf4197beSJulian Ruess (&(struct kmem_cache_args){ 311*bf4197beSJulian Ruess .align = PAGE_SIZE, 312*bf4197beSJulian Ruess .useroffset = 0, 313*bf4197beSJulian Ruess .usersize = zdev->maxstbl, 314*bf4197beSJulian Ruess }), 315*bf4197beSJulian Ruess (SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT)); 316*bf4197beSJulian Ruess if (!ivpcd->store_block_cache) 317*bf4197beSJulian Ruess return -ENOMEM; 318*bf4197beSJulian Ruess 319*bf4197beSJulian Ruess ret = vfio_pci_core_init_dev(core_vdev); 320*bf4197beSJulian Ruess if (ret) 321*bf4197beSJulian Ruess kmem_cache_destroy(ivpcd->store_block_cache); 322*bf4197beSJulian Ruess 323*bf4197beSJulian Ruess return ret; 324*bf4197beSJulian Ruess } 325*bf4197beSJulian Ruess 326*bf4197beSJulian Ruess static void ism_vfio_pci_release_dev(struct vfio_device *core_vdev) 327*bf4197beSJulian Ruess { 328*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd = container_of( 329*bf4197beSJulian Ruess core_vdev, struct ism_vfio_pci_core_device, core_device.vdev); 330*bf4197beSJulian Ruess 331*bf4197beSJulian Ruess kmem_cache_destroy(ivpcd->store_block_cache); 332*bf4197beSJulian Ruess vfio_pci_core_release_dev(core_vdev); 333*bf4197beSJulian Ruess } 334*bf4197beSJulian Ruess 335*bf4197beSJulian Ruess static const struct vfio_device_ops ism_pci_ops = { 336*bf4197beSJulian Ruess .name = "ism-vfio-pci", 337*bf4197beSJulian Ruess .init = ism_vfio_pci_init_dev, 338*bf4197beSJulian Ruess .release = ism_vfio_pci_release_dev, 339*bf4197beSJulian Ruess .open_device = ism_vfio_pci_open_device, 340*bf4197beSJulian Ruess .close_device = vfio_pci_core_close_device, 341*bf4197beSJulian Ruess .ioctl = vfio_pci_core_ioctl, 342*bf4197beSJulian Ruess .get_region_info_caps = ism_vfio_pci_ioctl_get_region_info, 343*bf4197beSJulian Ruess .device_feature = vfio_pci_core_ioctl_feature, 344*bf4197beSJulian Ruess .read = ism_vfio_pci_read, 345*bf4197beSJulian Ruess .write = ism_vfio_pci_write, 346*bf4197beSJulian Ruess .request = vfio_pci_core_request, 347*bf4197beSJulian Ruess .match = vfio_pci_core_match, 348*bf4197beSJulian Ruess .match_token_uuid = vfio_pci_core_match_token_uuid, 349*bf4197beSJulian Ruess .bind_iommufd = vfio_iommufd_physical_bind, 350*bf4197beSJulian Ruess .unbind_iommufd = vfio_iommufd_physical_unbind, 351*bf4197beSJulian Ruess .attach_ioas = vfio_iommufd_physical_attach_ioas, 352*bf4197beSJulian Ruess .detach_ioas = vfio_iommufd_physical_detach_ioas, 353*bf4197beSJulian Ruess }; 354*bf4197beSJulian Ruess 355*bf4197beSJulian Ruess static int ism_vfio_pci_probe(struct pci_dev *pdev, 356*bf4197beSJulian Ruess const struct pci_device_id *id) 357*bf4197beSJulian Ruess { 358*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd; 359*bf4197beSJulian Ruess int ret; 360*bf4197beSJulian Ruess 361*bf4197beSJulian Ruess ivpcd = vfio_alloc_device(ism_vfio_pci_core_device, core_device.vdev, 362*bf4197beSJulian Ruess &pdev->dev, &ism_pci_ops); 363*bf4197beSJulian Ruess if (IS_ERR(ivpcd)) 364*bf4197beSJulian Ruess return PTR_ERR(ivpcd); 365*bf4197beSJulian Ruess 366*bf4197beSJulian Ruess dev_set_drvdata(&pdev->dev, &ivpcd->core_device); 367*bf4197beSJulian Ruess 368*bf4197beSJulian Ruess ret = vfio_pci_core_register_device(&ivpcd->core_device); 369*bf4197beSJulian Ruess if (ret) 370*bf4197beSJulian Ruess vfio_put_device(&ivpcd->core_device.vdev); 371*bf4197beSJulian Ruess 372*bf4197beSJulian Ruess return ret; 373*bf4197beSJulian Ruess } 374*bf4197beSJulian Ruess 375*bf4197beSJulian Ruess static void ism_vfio_pci_remove(struct pci_dev *pdev) 376*bf4197beSJulian Ruess { 377*bf4197beSJulian Ruess struct vfio_pci_core_device *core_device; 378*bf4197beSJulian Ruess struct ism_vfio_pci_core_device *ivpcd; 379*bf4197beSJulian Ruess 380*bf4197beSJulian Ruess core_device = dev_get_drvdata(&pdev->dev); 381*bf4197beSJulian Ruess ivpcd = container_of(core_device, struct ism_vfio_pci_core_device, 382*bf4197beSJulian Ruess core_device); 383*bf4197beSJulian Ruess 384*bf4197beSJulian Ruess vfio_pci_core_unregister_device(&ivpcd->core_device); 385*bf4197beSJulian Ruess vfio_put_device(&ivpcd->core_device.vdev); 386*bf4197beSJulian Ruess } 387*bf4197beSJulian Ruess 388*bf4197beSJulian Ruess static const struct pci_device_id ism_device_table[] = { 389*bf4197beSJulian Ruess { PCI_DRIVER_OVERRIDE_DEVICE_VFIO(PCI_VENDOR_ID_IBM, 390*bf4197beSJulian Ruess PCI_DEVICE_ID_IBM_ISM) }, 391*bf4197beSJulian Ruess {} 392*bf4197beSJulian Ruess }; 393*bf4197beSJulian Ruess MODULE_DEVICE_TABLE(pci, ism_device_table); 394*bf4197beSJulian Ruess 395*bf4197beSJulian Ruess static struct pci_driver ism_vfio_pci_driver = { 396*bf4197beSJulian Ruess .name = KBUILD_MODNAME, 397*bf4197beSJulian Ruess .id_table = ism_device_table, 398*bf4197beSJulian Ruess .probe = ism_vfio_pci_probe, 399*bf4197beSJulian Ruess .remove = ism_vfio_pci_remove, 400*bf4197beSJulian Ruess .err_handler = &vfio_pci_core_err_handlers, 401*bf4197beSJulian Ruess .driver_managed_dma = true, 402*bf4197beSJulian Ruess }; 403*bf4197beSJulian Ruess 404*bf4197beSJulian Ruess module_pci_driver(ism_vfio_pci_driver); 405*bf4197beSJulian Ruess 406*bf4197beSJulian Ruess MODULE_LICENSE("GPL"); 407*bf4197beSJulian Ruess MODULE_DESCRIPTION("vfio-pci variant driver for the IBM Internal Shared Memory (ISM) device"); 408*bf4197beSJulian Ruess MODULE_AUTHOR("IBM Corporation"); 409