File Index
Files and directories
Sign in
FILE

vfio_pci_zdev.c

File preview with syntax highlighting.

linux-6.19.14/drivers/vfio/pci/vfio_pci_zdev.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  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#include <linux/io.h>
 10#include <linux/pci.h>
 11#include <linux/uaccess.h>
 12#include <linux/vfio.h>
 13#include <linux/vfio_zdev.h>
 14#include <linux/kvm_host.h>
 15#include <asm/pci_clp.h>
 16#include <asm/pci_io.h>
 17
 18#include "vfio_pci_priv.h"
 19
 20/*
 21 * Add the Base PCI Function information to the device info region.
 22 */
 23static int zpci_base_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
 24{
 25	struct vfio_device_info_cap_zpci_base cap = {
 26		.header.id = VFIO_DEVICE_INFO_CAP_ZPCI_BASE,
 27		.header.version = 2,
 28		.start_dma = zdev->start_dma,
 29		.end_dma = zdev->end_dma,
 30		.pchid = zdev->pchid,
 31		.vfn = zdev->vfn,
 32		.fmb_length = zdev->fmb_length,
 33		.pft = zdev->pft,
 34		.gid = zdev->pfgid,
 35		.fh = zdev->fh
 36	};
 37
 38	return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
 39}
 40
 41/*
 42 * Add the Base PCI Function Group information to the device info region.
 43 */
 44static int zpci_group_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
 45{
 46	struct vfio_device_info_cap_zpci_group cap = {
 47		.header.id = VFIO_DEVICE_INFO_CAP_ZPCI_GROUP,
 48		.header.version = 2,
 49		.dasm = zdev->dma_mask,
 50		.msi_addr = zdev->msi_addr,
 51		.flags = VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH,
 52		.mui = zdev->fmb_update,
 53		.noi = zdev->max_msi,
 54		.maxstbl = ZPCI_MAX_WRITE_SIZE,
 55		.version = zdev->version,
 56		.reserved = 0,
 57		.imaxstbl = zdev->maxstbl
 58	};
 59
 60	return vfio_info_add_capability(caps, &cap.header, sizeof(cap));
 61}
 62
 63/*
 64 * Add the device utility string to the device info region.
 65 */
 66static int zpci_util_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
 67{
 68	struct vfio_device_info_cap_zpci_util *cap;
 69	int cap_size = sizeof(*cap) + CLP_UTIL_STR_LEN;
 70	int ret;
 71
 72	cap = kmalloc(cap_size, GFP_KERNEL);
 73	if (!cap)
 74		return -ENOMEM;
 75
 76	cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_UTIL;
 77	cap->header.version = 1;
 78	cap->size = CLP_UTIL_STR_LEN;
 79	memcpy(cap->util_str, zdev->util_str, cap->size);
 80
 81	ret = vfio_info_add_capability(caps, &cap->header, cap_size);
 82
 83	kfree(cap);
 84
 85	return ret;
 86}
 87
 88/*
 89 * Add the function path string to the device info region.
 90 */
 91static int zpci_pfip_cap(struct zpci_dev *zdev, struct vfio_info_cap *caps)
 92{
 93	struct vfio_device_info_cap_zpci_pfip *cap;
 94	int cap_size = sizeof(*cap) + CLP_PFIP_NR_SEGMENTS;
 95	int ret;
 96
 97	cap = kmalloc(cap_size, GFP_KERNEL);
 98	if (!cap)
 99		return -ENOMEM;
100
101	cap->header.id = VFIO_DEVICE_INFO_CAP_ZPCI_PFIP;
102	cap->header.version = 1;
103	cap->size = CLP_PFIP_NR_SEGMENTS;
104	memcpy(cap->pfip, zdev->pfip, cap->size);
105
106	ret = vfio_info_add_capability(caps, &cap->header, cap_size);
107
108	kfree(cap);
109
110	return ret;
111}
112
113/*
114 * Add all supported capabilities to the VFIO_DEVICE_GET_INFO capability chain.
115 */
116int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
117				struct vfio_info_cap *caps)
118{
119	struct zpci_dev *zdev = to_zpci(vdev->pdev);
120	int ret;
121
122	if (!zdev)
123		return -ENODEV;
124
125	ret = zpci_base_cap(zdev, caps);
126	if (ret)
127		return ret;
128
129	ret = zpci_group_cap(zdev, caps);
130	if (ret)
131		return ret;
132
133	if (zdev->util_str_avail) {
134		ret = zpci_util_cap(zdev, caps);
135		if (ret)
136			return ret;
137	}
138
139	ret = zpci_pfip_cap(zdev, caps);
140
141	return ret;
142}
143
144int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)
145{
146	struct zpci_dev *zdev = to_zpci(vdev->pdev);
147
148	if (!zdev)
149		return -ENODEV;
150
151	if (!vdev->vdev.kvm)
152		return 0;
153
154	if (zpci_kvm_hook.kvm_register)
155		return zpci_kvm_hook.kvm_register(zdev, vdev->vdev.kvm);
156
157	return -ENOENT;
158}
159
160void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)
161{
162	struct zpci_dev *zdev = to_zpci(vdev->pdev);
163
164	if (!zdev || !vdev->vdev.kvm)
165		return;
166
167	if (zpci_kvm_hook.kvm_unregister)
168		zpci_kvm_hook.kvm_unregister(zdev);
169}
~/ Read-only file preview.