WIP FPC-III support
[linux/fpc-iii.git] / drivers / vfio / pci / vfio_pci_zdev.c
blob22968563403113ae574e40db601083cf64513677
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * VFIO ZPCI devices support
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>
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.
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>
22 #include "vfio_pci_private.h"
25 * Add the Base PCI Function information to the device info region.
27 static int zpci_base_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev,
28 struct vfio_info_cap *caps)
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
42 return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
46 * Add the Base PCI Function Group information to the device info region.
48 static int zpci_group_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev,
49 struct vfio_info_cap *caps)
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
63 return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
67 * Add the device utility string to the device info region.
69 static int zpci_util_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev,
70 struct vfio_info_cap *caps)
72 struct vfio_device_info_cap_zpci_util *cap;
73 int cap_size = sizeof(*cap) + CLP_UTIL_STR_LEN;
74 int ret;
76 cap = kmalloc(cap_size, GFP_KERNEL);
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);
83 ret = vfio_info_add_capability(caps, &cap->header, cap_size);
85 kfree(cap);
87 return ret;
91 * Add the function path string to the device info region.
93 static int zpci_pfip_cap(struct zpci_dev *zdev, struct vfio_pci_device *vdev,
94 struct vfio_info_cap *caps)
96 struct vfio_device_info_cap_zpci_pfip *cap;
97 int cap_size = sizeof(*cap) + CLP_PFIP_NR_SEGMENTS;
98 int ret;
100 cap = kmalloc(cap_size, GFP_KERNEL);
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);
107 ret = vfio_info_add_capability(caps, &cap->header, cap_size);
109 kfree(cap);
111 return ret;
115 * Add all supported capabilities to the VFIO_DEVICE_GET_INFO capability chain.
117 int vfio_pci_info_zdev_add_caps(struct vfio_pci_device *vdev,
118 struct vfio_info_cap *caps)
120 struct zpci_dev *zdev = to_zpci(vdev->pdev);
121 int ret;
123 if (!zdev)
124 return -ENODEV;
126 ret = zpci_base_cap(zdev, vdev, caps);
127 if (ret)
128 return ret;
130 ret = zpci_group_cap(zdev, vdev, caps);
131 if (ret)
132 return ret;
134 if (zdev->util_str_avail) {
135 ret = zpci_util_cap(zdev, vdev, caps);
136 if (ret)
137 return ret;
140 ret = zpci_pfip_cap(zdev, vdev, caps);
142 return ret;