1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * VFIO ZPCI devices support 4 * 5 * Copyright (C) IBM Corp. 2020. All rights reserved. 6 * Author(s): Pierre Morel <pmorel@linux.ibm.com> 7 * Matthew Rosato <mjrosato@linux.ibm.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 #include <linux/io.h> 15 #include <linux/pci.h> 16 #include <linux/uaccess.h> 17 #include <linux/vfio.h> 18 #include <linux/vfio_zdev.h> 19 #include <asm/pci_clp.h> 20 #include <asm/pci_io.h> 21 22 #include "vfio_pci_private.h" 23 24 /* 25 * Add the Base PCI Function information to the device info region. 26 */ 27 static int zpci_base_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev, 28 struct vfio_info_cap *caps) 29 { 30 struct vfio_device_info_cap_zpci_base cap = { 31 .header.id = VFIO_DEVICE_INFO_CAP_ZPCI_BASE, 32 .header.version = 1, 33 .start_dma = zdev->start_dma, 34 .end_dma = zdev->end_dma, 35 .pchid = zdev->pchid, 36 .vfn = zdev->vfn, 37 .fmb_length = zdev->fmb_length, 38 .pft = zdev->pft, 39 .gid = zdev->pfgid 40 }; 41 42 return vfio_info_add_capability(caps, &cap.header, sizeof(cap)); 43 } 44 45 /* 46 * Add the Base PCI Function Group information to the device info region. 47 */ 48 static int zpci_group_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev, 49 struct vfio_info_cap *caps) 50 { 51 struct vfio_device_info_cap_zpci_group cap = { 52 .header.id = VFIO_DEVICE_INFO_CAP_ZPCI_GROUP, 53 .header.version = 1, 54 .dasm = zdev->dma_mask, 55 .msi_addr = zdev->msi_addr, 56 .flags = VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH, 57 .mui = zdev->fmb_update, 58 .noi = zdev->max_msi, 59 .maxstbl = ZPCI_MAX_WRITE_SIZE, 60 .version = zdev->version 61 }; 62 63 return vfio_info_add_capability(caps, &cap.header, sizeof(cap)); 64 } 65 66 /* 67 * Add the device utility string to the device info region. 68 */ 69 static int zpci_util_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev, 70 struct vfio_info_cap *caps) 71 { 72 struct vfio_device_info_cap_zpci_util *cap; 73 int cap_size = sizeof(*cap) + CLP_UTIL_STR_LEN; 74 int ret; 75 76 cap = kmalloc(cap_size, GFP_KERNEL); 77 78 cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_UTIL; 79 cap->header.version = 1; 80 cap->size = CLP_UTIL_STR_LEN; 81 memcpy(cap->util_str, zdev->util_str, cap->size); 82 83 ret = vfio_info_add_capability(caps, &cap->header, cap_size); 84 85 kfree(cap); 86 87 return ret; 88 } 89 90 /* 91 * Add the function path string to the device info region. 92 */ 93 static int zpci_pfip_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev, 94 struct vfio_info_cap *caps) 95 { 96 struct vfio_device_info_cap_zpci_pfip *cap; 97 int cap_size = sizeof(*cap) + CLP_PFIP_NR_SEGMENTS; 98 int ret; 99 100 cap = kmalloc(cap_size, GFP_KERNEL); 101 102 cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_PFIP; 103 cap->header.version = 1; 104 cap->size = CLP_PFIP_NR_SEGMENTS; 105 memcpy(cap->pfip, zdev->pfip, cap->size); 106 107 ret = vfio_info_add_capability(caps, &cap->header, cap_size); 108 109 kfree(cap); 110 111 return ret; 112 } 113 114 /* 115 * Add all supported capabilities to the VFIO_DEVICE_GET_INFO capability chain. 116 */ 117 int vfio_pci_info_zdev_add_caps(struct vfio_pci_device *vdev, 118 struct vfio_info_cap *caps) 119 { 120 struct zpci_dev *zdev = to_zpci(vdev->pdev); 121 int ret; 122 123 if (!zdev) 124 return -ENODEV; 125 126 ret = zpci_base_cap(zdev, vdev, caps); 127 if (ret) 128 return ret; 129 130 ret = zpci_group_cap(zdev, vdev, caps); 131 if (ret) 132 return ret; 133 134 if (zdev->util_str_avail) { 135 ret = zpci_util_cap(zdev, vdev, caps); 136 if (ret) 137 return ret; 138 } 139 140 ret = zpci_pfip_cap(zdev, vdev, caps); 141 142 return ret; 143 } 144