Skip to content

Commit dbb6f1c

Browse files
siwliu-kernelmstsirkin
authored andcommitted
vdpa: validate device feature provisioning against supported class
Today when device features are explicitly provisioned, the features user supplied may contain device class specific features that are not supported by the parent management device. On the other hand, when parent management device supports more than one class, the device features to provision may be ambiguous if none of the class specific attributes is provided at the same time. Validate these cases and prompt appropriate user errors accordingly. Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com> Message-Id: <1675725124-7375-5-git-send-email-si-wei.liu@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent e7d09cd commit dbb6f1c

1 file changed

Lines changed: 50 additions & 9 deletions

File tree

drivers/vdpa/vdpa.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -465,12 +465,28 @@ static int vdpa_nl_mgmtdev_handle_fill(struct sk_buff *msg, const struct vdpa_mg
465465
return 0;
466466
}
467467

468+
static u64 vdpa_mgmtdev_get_classes(const struct vdpa_mgmt_dev *mdev,
469+
unsigned int *nclasses)
470+
{
471+
u64 supported_classes = 0;
472+
unsigned int n = 0;
473+
474+
for (int i = 0; mdev->id_table[i].device; i++) {
475+
if (mdev->id_table[i].device > 63)
476+
continue;
477+
supported_classes |= BIT_ULL(mdev->id_table[i].device);
478+
n++;
479+
}
480+
if (nclasses)
481+
*nclasses = n;
482+
483+
return supported_classes;
484+
}
485+
468486
static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *msg,
469487
u32 portid, u32 seq, int flags)
470488
{
471-
u64 supported_classes = 0;
472489
void *hdr;
473-
int i = 0;
474490
int err;
475491

476492
hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, VDPA_CMD_MGMTDEV_NEW);
@@ -480,14 +496,9 @@ static int vdpa_mgmtdev_fill(const struct vdpa_mgmt_dev *mdev, struct sk_buff *m
480496
if (err)
481497
goto msg_err;
482498

483-
while (mdev->id_table[i].device) {
484-
if (mdev->id_table[i].device <= 63)
485-
supported_classes |= BIT_ULL(mdev->id_table[i].device);
486-
i++;
487-
}
488-
489499
if (nla_put_u64_64bit(msg, VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES,
490-
supported_classes, VDPA_ATTR_UNSPEC)) {
500+
vdpa_mgmtdev_get_classes(mdev, NULL),
501+
VDPA_ATTR_UNSPEC)) {
491502
err = -EMSGSIZE;
492503
goto msg_err;
493504
}
@@ -571,13 +582,25 @@ vdpa_nl_cmd_mgmtdev_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
571582
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MTU) | \
572583
BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP))
573584

585+
/*
586+
* Bitmask for all per-device features: feature bits VIRTIO_TRANSPORT_F_START
587+
* through VIRTIO_TRANSPORT_F_END are unset, i.e. 0xfffffc000fffffff for
588+
* all 64bit features. If the features are extended beyond 64 bits, or new
589+
* "holes" are reserved for other type of features than per-device, this
590+
* macro would have to be updated.
591+
*/
592+
#define VIRTIO_DEVICE_F_MASK (~0ULL << (VIRTIO_TRANSPORT_F_END + 1) | \
593+
((1ULL << VIRTIO_TRANSPORT_F_START) - 1))
594+
574595
static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *info)
575596
{
576597
struct vdpa_dev_set_config config = {};
577598
struct nlattr **nl_attrs = info->attrs;
578599
struct vdpa_mgmt_dev *mdev;
600+
unsigned int ncls = 0;
579601
const u8 *macaddr;
580602
const char *name;
603+
u64 classes;
581604
int err = 0;
582605

583606
if (!info->attrs[VDPA_ATTR_DEV_NAME])
@@ -654,6 +677,24 @@ static int vdpa_nl_cmd_dev_add_set_doit(struct sk_buff *skb, struct genl_info *i
654677
goto err;
655678
}
656679

680+
classes = vdpa_mgmtdev_get_classes(mdev, &ncls);
681+
if (config.mask & VDPA_DEV_NET_ATTRS_MASK &&
682+
!(classes & BIT_ULL(VIRTIO_ID_NET))) {
683+
NL_SET_ERR_MSG_MOD(info->extack,
684+
"Network class attributes provided on unsupported management device");
685+
err = -EINVAL;
686+
goto err;
687+
}
688+
if (!(config.mask & VDPA_DEV_NET_ATTRS_MASK) &&
689+
config.mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES) &&
690+
classes & BIT_ULL(VIRTIO_ID_NET) && ncls > 1 &&
691+
config.device_features & VIRTIO_DEVICE_F_MASK) {
692+
NL_SET_ERR_MSG_MOD(info->extack,
693+
"Management device supports multi-class while device features specified are ambiguous");
694+
err = -EINVAL;
695+
goto err;
696+
}
697+
657698
err = mdev->ops->dev_add(mdev, name, &config);
658699
err:
659700
up_write(&vdpa_dev_lock);

0 commit comments

Comments
 (0)