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