History

vfio: Introduce VFIO_DEVICE_FEATURE ioctl and first user

The VFIO_DEVICE_FEATURE ioctl is meant to be a general purpose, device agnostic ioctl for setting, retrieving, and probing device features. This implementation provides a 16-bit field for specifying a feature index, where the data porition of the ioctl is determined by the semantics for the given feature. Additional flag bits indicate the direction and nature of the operation; SET indicates user data is provided into the device feature, GET indicates the device feature is written out into user data. The PROBE flag augments determining whether the given feature is supported, and if provided, whether the given operation on the feature is supported. The first user of this ioctl is for setting the vfio-pci VF token, where the user provides a shared secret key (UUID) on a SR-IOV PF device, which users must provide when opening associated VF devices.

Alex Williamson committed 6 years ago

Commit 43eeeec1 parent cc20d792 files · +96 −0Browse files

Unified · Split

2 files
  1. drivers/vfio/pci/vfio_pci.c +59 −0
  2. include/uapi/linux/vfio.h +37 −0
drivers/vfio/pci/vfio_pci.c+59−0
@@ -1180,6 +1180,65 @@ hot_reset_release: · 1179 unmodified lines
1180 1180
1181 return vfio_pci_ioeventfd(vdev, ioeventfd.offset,1181 return vfio_pci_ioeventfd(vdev, ioeventfd.offset,
1182 ioeventfd.data, count, ioeventfd.fd);1182 ioeventfd.data, count, ioeventfd.fd);
1183 } else if (cmd == VFIO_DEVICE_FEATURE) {
1184 struct vfio_device_feature feature;
1185 uuid_t uuid;
1186
1187 minsz = offsetofend(struct vfio_device_feature, flags);
1188
1189 if (copy_from_user(&feature, (void __user *)arg, minsz))
1190 return -EFAULT;
1191
1192 if (feature.argsz < minsz)
1193 return -EINVAL;
1194
1195 /* Check unknown flags */
1196 if (feature.flags & ~(VFIO_DEVICE_FEATURE_MASK |
1197 VFIO_DEVICE_FEATURE_SET |
1198 VFIO_DEVICE_FEATURE_GET |
1199 VFIO_DEVICE_FEATURE_PROBE))
1200 return -EINVAL;
1201
1202 /* GET & SET are mutually exclusive except with PROBE */
1203 if (!(feature.flags & VFIO_DEVICE_FEATURE_PROBE) &&
1204 (feature.flags & VFIO_DEVICE_FEATURE_SET) &&
1205 (feature.flags & VFIO_DEVICE_FEATURE_GET))
1206 return -EINVAL;
1207
1208 switch (feature.flags & VFIO_DEVICE_FEATURE_MASK) {
1209 case VFIO_DEVICE_FEATURE_PCI_VF_TOKEN:
1210 if (!vdev->vf_token)
1211 return -ENOTTY;
1212
1213 /*
1214 * We do not support GET of the VF Token UUID as this
1215 * could expose the token of the previous device user.
1216 */
1217 if (feature.flags & VFIO_DEVICE_FEATURE_GET)
1218 return -EINVAL;
1219
1220 if (feature.flags & VFIO_DEVICE_FEATURE_PROBE)
1221 return 0;
1222
1223 /* Don't SET unless told to do so */
1224 if (!(feature.flags & VFIO_DEVICE_FEATURE_SET))
1225 return -EINVAL;
1226
1227 if (feature.argsz < minsz + sizeof(uuid))
1228 return -EINVAL;
1229
1230 if (copy_from_user(&uuid, (void __user *)(arg + minsz),
1231 sizeof(uuid)))
1232 return -EFAULT;
1233
1234 mutex_lock(&vdev->vf_token->lock);
1235 uuid_copy(&vdev->vf_token->uuid, &uuid);
1236 mutex_unlock(&vdev->vf_token->lock);
1237
1238 return 0;
1239 default:
1240 return -ENOTTY;
1241 }
1183 }1242 }
1184 1243
1185 return -ENOTTY;1244 return -ENOTTY;
include/uapi/linux/vfio.h+37−0
@@ -707,6 +707,43 @@ struct vfio_device_ioeventfd { · 706 unmodified lines
707 707
708#define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16)708#define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16)
709 709
710/**
711 * VFIO_DEVICE_FEATURE - _IORW(VFIO_TYPE, VFIO_BASE + 17,
712 * struct vfio_device_feature)
713 *
714 * Get, set, or probe feature data of the device. The feature is selected
715 * using the FEATURE_MASK portion of the flags field. Support for a feature
716 * can be probed by setting both the FEATURE_MASK and PROBE bits. A probe
717 * may optionally include the GET and/or SET bits to determine read vs write
718 * access of the feature respectively. Probing a feature will return success
719 * if the feature is supported and all of the optionally indicated GET/SET
720 * methods are supported. The format of the data portion of the structure is
721 * specific to the given feature. The data portion is not required for
722 * probing. GET and SET are mutually exclusive, except for use with PROBE.
723 *
724 * Return 0 on success, -errno on failure.
725 */
726struct vfio_device_feature {
727 __u32 argsz;
728 __u32 flags;
729#define VFIO_DEVICE_FEATURE_MASK (0xffff) /* 16-bit feature index */
730#define VFIO_DEVICE_FEATURE_GET (1 << 16) /* Get feature into data[] */
731#define VFIO_DEVICE_FEATURE_SET (1 << 17) /* Set feature from data[] */
732#define VFIO_DEVICE_FEATURE_PROBE (1 << 18) /* Probe feature support */
733 __u8 data[];
734};
735
736#define VFIO_DEVICE_FEATURE _IO(VFIO_TYPE, VFIO_BASE + 17)
737
738/*
739 * Provide support for setting a PCI VF Token, which is used as a shared
740 * secret between PF and VF drivers. This feature may only be set on a
741 * PCI SR-IOV PF when SR-IOV is enabled on the PF and there are no existing
742 * open VFs. Data provided when setting this feature is a 16-byte array
743 * (__u8 b[16]), representing a UUID.
744 */
745#define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0)
746
710/* -------- API for Type1 VFIO IOMMU -------- */747/* -------- API for Type1 VFIO IOMMU -------- */
711 748
712/**749/**