Commit abdf31bd authored by Shannon Nelson's avatar Shannon Nelson Committed by Michael S. Tsirkin

pds_vdpa: always allow offering VIRTIO_NET_F_MAC

Our driver sets a mac if the HW is 00:..:00 so we need to be sure to
advertise VIRTIO_NET_F_MAC even if the HW doesn't.  We also need to be
sure that virtio_net sees the VIRTIO_NET_F_MAC and doesn't rewrite the
mac address that a user may have set with the vdpa utility.

After reading the hw_feature bits, add the VIRTIO_NET_F_MAC to the driver's
supported_features and use that for reporting what is available.  If the
HW is not advertising it, be sure to strip the VIRTIO_NET_F_MAC before
finishing the feature negotiation.  If the user specifies a device_features
bitpattern in the vdpa utility without the VIRTIO_NET_F_MAC set, then
don't set the mac.

Fixes: 151cc834 ("pds_vdpa: add support for vdpa and vdpamgmt interfaces")
Signed-off-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Message-Id: <20230711042437.69381-3-shannon.nelson@amd.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
parent 0cd2c13b
...@@ -224,8 +224,6 @@ static int config_show(struct seq_file *seq, void *v) ...@@ -224,8 +224,6 @@ static int config_show(struct seq_file *seq, void *v)
seq_printf(seq, "dev_status: %#x\n", status); seq_printf(seq, "dev_status: %#x\n", status);
print_status_bits(seq, status); print_status_bits(seq, status);
seq_printf(seq, "req_features: %#llx\n", pdsv->req_features);
print_feature_bits_all(seq, pdsv->req_features);
driver_features = vp_modern_get_driver_features(&pdsv->vdpa_aux->vd_mdev); driver_features = vp_modern_get_driver_features(&pdsv->vdpa_aux->vd_mdev);
seq_printf(seq, "driver_features: %#llx\n", driver_features); seq_printf(seq, "driver_features: %#llx\n", driver_features);
print_feature_bits_all(seq, driver_features); print_feature_bits_all(seq, driver_features);
......
...@@ -318,6 +318,7 @@ static int pds_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 featur ...@@ -318,6 +318,7 @@ static int pds_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 featur
struct device *dev = &pdsv->vdpa_dev.dev; struct device *dev = &pdsv->vdpa_dev.dev;
u64 driver_features; u64 driver_features;
u64 nego_features; u64 nego_features;
u64 hw_features;
u64 missing; u64 missing;
if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)) && features) { if (!(features & BIT_ULL(VIRTIO_F_ACCESS_PLATFORM)) && features) {
...@@ -325,21 +326,26 @@ static int pds_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 featur ...@@ -325,21 +326,26 @@ static int pds_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 featur
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
pdsv->req_features = features;
/* Check for valid feature bits */ /* Check for valid feature bits */
nego_features = features & le64_to_cpu(pdsv->vdpa_aux->ident.hw_features); nego_features = features & pdsv->supported_features;
missing = pdsv->req_features & ~nego_features; missing = features & ~nego_features;
if (missing) { if (missing) {
dev_err(dev, "Can't support all requested features in %#llx, missing %#llx features\n", dev_err(dev, "Can't support all requested features in %#llx, missing %#llx features\n",
pdsv->req_features, missing); features, missing);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
pdsv->negotiated_features = nego_features;
driver_features = pds_vdpa_get_driver_features(vdpa_dev); driver_features = pds_vdpa_get_driver_features(vdpa_dev);
dev_dbg(dev, "%s: %#llx => %#llx\n", dev_dbg(dev, "%s: %#llx => %#llx\n",
__func__, driver_features, nego_features); __func__, driver_features, nego_features);
/* if we're faking the F_MAC, strip it before writing to device */
hw_features = le64_to_cpu(pdsv->vdpa_aux->ident.hw_features);
if (!(hw_features & BIT_ULL(VIRTIO_NET_F_MAC)))
nego_features &= ~BIT_ULL(VIRTIO_NET_F_MAC);
if (driver_features == nego_features) if (driver_features == nego_features)
return 0; return 0;
...@@ -352,7 +358,7 @@ static u64 pds_vdpa_get_driver_features(struct vdpa_device *vdpa_dev) ...@@ -352,7 +358,7 @@ static u64 pds_vdpa_get_driver_features(struct vdpa_device *vdpa_dev)
{ {
struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev); struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);
return vp_modern_get_driver_features(&pdsv->vdpa_aux->vd_mdev); return pdsv->negotiated_features;
} }
static void pds_vdpa_set_config_cb(struct vdpa_device *vdpa_dev, static void pds_vdpa_set_config_cb(struct vdpa_device *vdpa_dev,
...@@ -564,7 +570,7 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name, ...@@ -564,7 +570,7 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) { if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_FEATURES)) {
u64 unsupp_features = u64 unsupp_features =
add_config->device_features & ~mgmt->supported_features; add_config->device_features & ~pdsv->supported_features;
if (unsupp_features) { if (unsupp_features) {
dev_err(dev, "Unsupported features: %#llx\n", unsupp_features); dev_err(dev, "Unsupported features: %#llx\n", unsupp_features);
...@@ -615,7 +621,8 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name, ...@@ -615,7 +621,8 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
} }
/* Set a mac, either from the user config if provided /* Set a mac, either from the user config if provided
* or set a random mac if default is 00:..:00 * or use the device's mac if not 00:..:00
* or set a random mac
*/ */
if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)) { if (add_config->mask & BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR)) {
ether_addr_copy(pdsv->mac, add_config->net.mac); ether_addr_copy(pdsv->mac, add_config->net.mac);
...@@ -624,7 +631,8 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name, ...@@ -624,7 +631,8 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
vc = pdsv->vdpa_aux->vd_mdev.device; vc = pdsv->vdpa_aux->vd_mdev.device;
memcpy_fromio(pdsv->mac, vc->mac, sizeof(pdsv->mac)); memcpy_fromio(pdsv->mac, vc->mac, sizeof(pdsv->mac));
if (is_zero_ether_addr(pdsv->mac)) { if (is_zero_ether_addr(pdsv->mac) &&
(pdsv->supported_features & BIT_ULL(VIRTIO_NET_F_MAC))) {
eth_random_addr(pdsv->mac); eth_random_addr(pdsv->mac);
dev_info(dev, "setting random mac %pM\n", pdsv->mac); dev_info(dev, "setting random mac %pM\n", pdsv->mac);
} }
...@@ -752,6 +760,10 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux) ...@@ -752,6 +760,10 @@ int pds_vdpa_get_mgmt_info(struct pds_vdpa_aux *vdpa_aux)
mgmt->id_table = pds_vdpa_id_table; mgmt->id_table = pds_vdpa_id_table;
mgmt->device = dev; mgmt->device = dev;
mgmt->supported_features = le64_to_cpu(vdpa_aux->ident.hw_features); mgmt->supported_features = le64_to_cpu(vdpa_aux->ident.hw_features);
/* advertise F_MAC even if the device doesn't */
mgmt->supported_features |= BIT_ULL(VIRTIO_NET_F_MAC);
mgmt->config_attr_mask = BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR); mgmt->config_attr_mask = BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MACADDR);
mgmt->config_attr_mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP); mgmt->config_attr_mask |= BIT_ULL(VDPA_ATTR_DEV_NET_CFG_MAX_VQP);
mgmt->config_attr_mask |= BIT_ULL(VDPA_ATTR_DEV_FEATURES); mgmt->config_attr_mask |= BIT_ULL(VDPA_ATTR_DEV_FEATURES);
......
...@@ -35,8 +35,8 @@ struct pds_vdpa_device { ...@@ -35,8 +35,8 @@ struct pds_vdpa_device {
struct pds_vdpa_aux *vdpa_aux; struct pds_vdpa_aux *vdpa_aux;
struct pds_vdpa_vq_info vqs[PDS_VDPA_MAX_QUEUES]; struct pds_vdpa_vq_info vqs[PDS_VDPA_MAX_QUEUES];
u64 supported_features; /* specified device features */ u64 supported_features; /* supported device features */
u64 req_features; /* features requested by vdpa */ u64 negotiated_features; /* negotiated features */
u8 vdpa_index; /* rsvd for future subdevice use */ u8 vdpa_index; /* rsvd for future subdevice use */
u8 num_vqs; /* num vqs in use */ u8 num_vqs; /* num vqs in use */
u8 mac[ETH_ALEN]; /* mac selected when the device was added */ u8 mac[ETH_ALEN]; /* mac selected when the device was added */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment