Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * VFIO ZPCI devices support
0004  *
0005  * Copyright (C) IBM Corp. 2020.  All rights reserved.
0006  *  Author(s): Pierre Morel <pmorel@linux.ibm.com>
0007  *                 Matthew Rosato <mjrosato@linux.ibm.com>
0008  */
0009 #include <linux/io.h>
0010 #include <linux/pci.h>
0011 #include <linux/uaccess.h>
0012 #include <linux/vfio.h>
0013 #include <linux/vfio_zdev.h>
0014 #include <linux/kvm_host.h>
0015 #include <asm/pci_clp.h>
0016 #include <asm/pci_io.h>
0017 
0018 #include <linux/vfio_pci_core.h>
0019 
0020 /*
0021  * Add the Base PCI Function information to the device info region.
0022  */
0023 static int zpci_base_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
0024 {
0025     struct vfio_device_info_cap_zpci_base cap = {
0026         .header.id = VFIO_DEVICE_INFO_CAP_ZPCI_BASE,
0027         .header.version = 2,
0028         .start_dma = zdev->start_dma,
0029         .end_dma = zdev->end_dma,
0030         .pchid = zdev->pchid,
0031         .vfn = zdev->vfn,
0032         .fmb_length = zdev->fmb_length,
0033         .pft = zdev->pft,
0034         .gid = zdev->pfgid,
0035         .fh = zdev->fh
0036     };
0037 
0038     return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
0039 }
0040 
0041 /*
0042  * Add the Base PCI Function Group information to the device info region.
0043  */
0044 static int zpci_group_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
0045 {
0046     struct vfio_device_info_cap_zpci_group cap = {
0047         .header.id = VFIO_DEVICE_INFO_CAP_ZPCI_GROUP,
0048         .header.version = 2,
0049         .dasm = zdev->dma_mask,
0050         .msi_addr = zdev->msi_addr,
0051         .flags = VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH,
0052         .mui = zdev->fmb_update,
0053         .noi = zdev->max_msi,
0054         .maxstbl = ZPCI_MAX_WRITE_SIZE,
0055         .version = zdev->version,
0056         .reserved = 0,
0057         .imaxstbl = zdev->maxstbl
0058     };
0059 
0060     return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
0061 }
0062 
0063 /*
0064  * Add the device utility string to the device info region.
0065  */
0066 static int zpci_util_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
0067 {
0068     struct vfio_device_info_cap_zpci_util *cap;
0069     int cap_size = sizeof(*cap) + CLP_UTIL_STR_LEN;
0070     int ret;
0071 
0072     cap = kmalloc(cap_size, GFP_KERNEL);
0073     if (!cap)
0074         return -ENOMEM;
0075 
0076     cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_UTIL;
0077     cap->header.version = 1;
0078     cap->size = CLP_UTIL_STR_LEN;
0079     memcpy(cap->util_str, zdev->util_str, cap->size);
0080 
0081     ret = vfio_info_add_capability(caps, &cap->header, cap_size);
0082 
0083     kfree(cap);
0084 
0085     return ret;
0086 }
0087 
0088 /*
0089  * Add the function path string to the device info region.
0090  */
0091 static int zpci_pfip_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
0092 {
0093     struct vfio_device_info_cap_zpci_pfip *cap;
0094     int cap_size = sizeof(*cap) + CLP_PFIP_NR_SEGMENTS;
0095     int ret;
0096 
0097     cap = kmalloc(cap_size, GFP_KERNEL);
0098     if (!cap)
0099         return -ENOMEM;
0100 
0101     cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_PFIP;
0102     cap->header.version = 1;
0103     cap->size = CLP_PFIP_NR_SEGMENTS;
0104     memcpy(cap->pfip, zdev->pfip, cap->size);
0105 
0106     ret = vfio_info_add_capability(caps, &cap->header, cap_size);
0107 
0108     kfree(cap);
0109 
0110     return ret;
0111 }
0112 
0113 /*
0114  * Add all supported capabilities to the VFIO_DEVICE_GET_INFO capability chain.
0115  */
0116 int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
0117                 struct vfio_info_cap *caps)
0118 {
0119     struct zpci_dev *zdev = to_zpci(vdev->pdev);
0120     int ret;
0121 
0122     if (!zdev)
0123         return -ENODEV;
0124 
0125     ret = zpci_base_cap(zdev, caps);
0126     if (ret)
0127         return ret;
0128 
0129     ret = zpci_group_cap(zdev, caps);
0130     if (ret)
0131         return ret;
0132 
0133     if (zdev->util_str_avail) {
0134         ret = zpci_util_cap(zdev, caps);
0135         if (ret)
0136             return ret;
0137     }
0138 
0139     ret = zpci_pfip_cap(zdev, caps);
0140 
0141     return ret;
0142 }
0143 
0144 int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)
0145 {
0146     struct zpci_dev *zdev = to_zpci(vdev->pdev);
0147 
0148     if (!zdev)
0149         return -ENODEV;
0150 
0151     if (!vdev->vdev.kvm)
0152         return 0;
0153 
0154     if (zpci_kvm_hook.kvm_register)
0155         return zpci_kvm_hook.kvm_register(zdev, vdev->vdev.kvm);
0156 
0157     return -ENOENT;
0158 }
0159 
0160 void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)
0161 {
0162     struct zpci_dev *zdev = to_zpci(vdev->pdev);
0163 
0164     if (!zdev || !vdev->vdev.kvm)
0165         return;
0166 
0167     if (zpci_kvm_hook.kvm_unregister)
0168         zpci_kvm_hook.kvm_unregister(zdev);
0169 }