net/virtio: validate features at bus level
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Tue, 26 Jan 2021 10:16:08 +0000 (11:16 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:09 +0000 (18:16 +0100)
This patch provides a new callback for the bus type
to validate negotiated features are compatible with it.

Only user for now is PCI modern bus type, which implies
that the device supports Virtio 1.0+.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_pci.c
drivers/net/virtio/virtio_pci.h
drivers/net/virtio/virtio_user_ethdev.c

index 98a393d..0b43025 100644 (file)
@@ -1330,17 +1330,14 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
        PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
                hw->guest_features);
 
-       if (hw->bus_type == VIRTIO_BUS_PCI_MODERN && !vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
-               PMD_INIT_LOG(ERR,
-                       "VIRTIO_F_VERSION_1 features is not enabled.");
+       if (VTPCI_OPS(hw)->features_ok(hw) < 0)
                return -1;
-       }
 
-       if (hw->bus_type == VIRTIO_BUS_PCI_MODERN || hw->bus_type == VIRTIO_BUS_USER) {
+       if (vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
                vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+
                if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
-                       PMD_INIT_LOG(ERR,
-                               "failed to set FEATURES_OK status!");
+                       PMD_INIT_LOG(ERR, "Failed to set FEATURES_OK status!");
                        return -1;
                }
        }
index ea4ab38..1c8d4b7 100644 (file)
@@ -201,6 +201,12 @@ legacy_set_features(struct virtio_hw *hw, uint64_t features)
                VIRTIO_PCI_GUEST_FEATURES);
 }
 
+static int
+legacy_features_ok(struct virtio_hw *hw __rte_unused)
+{
+       return 0;
+}
+
 static uint8_t
 legacy_get_status(struct virtio_hw *hw)
 {
@@ -315,6 +321,7 @@ const struct virtio_pci_ops legacy_ops = {
        .set_status     = legacy_set_status,
        .get_features   = legacy_get_features,
        .set_features   = legacy_set_features,
+       .features_ok    = legacy_features_ok,
        .get_isr        = legacy_get_isr,
        .set_config_irq = legacy_set_config_irq,
        .set_queue_irq  = legacy_set_queue_irq,
@@ -389,6 +396,17 @@ modern_set_features(struct virtio_hw *hw, uint64_t features)
                    &hw->common_cfg->guest_feature);
 }
 
+static int
+modern_features_ok(struct virtio_hw *hw)
+{
+       if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+               PMD_INIT_LOG(ERR, "Version 1+ required with modern devices\n");
+               return -1;
+       }
+
+       return 0;
+}
+
 static uint8_t
 modern_get_status(struct virtio_hw *hw)
 {
@@ -540,6 +558,7 @@ const struct virtio_pci_ops modern_ops = {
        .set_status     = modern_set_status,
        .get_features   = modern_get_features,
        .set_features   = modern_set_features,
+       .features_ok    = modern_features_ok,
        .get_isr        = modern_get_isr,
        .set_config_irq = modern_set_config_irq,
        .set_queue_irq  = modern_set_queue_irq,
index 35f8489..725b9a4 100644 (file)
@@ -227,6 +227,7 @@ struct virtio_pci_ops {
 
        uint64_t (*get_features)(struct virtio_hw *hw);
        void     (*set_features)(struct virtio_hw *hw, uint64_t features);
+       int      (*features_ok)(struct virtio_hw *hw);
 
        uint8_t (*get_isr)(struct virtio_hw *hw);
 
index b4a4331..ed069a3 100644 (file)
@@ -327,6 +327,12 @@ virtio_user_set_features(struct virtio_hw *hw, uint64_t features)
        dev->features = features & dev->device_features;
 }
 
+static int
+virtio_user_features_ok(struct virtio_hw *hw __rte_unused)
+{
+       return 0;
+}
+
 static uint8_t
 virtio_user_get_isr(struct virtio_hw *hw __rte_unused)
 {
@@ -479,6 +485,7 @@ const struct virtio_pci_ops virtio_user_ops = {
        .set_status     = virtio_user_set_status,
        .get_features   = virtio_user_get_features,
        .set_features   = virtio_user_set_features,
+       .features_ok    = virtio_user_features_ok,
        .get_isr        = virtio_user_get_isr,
        .set_config_irq = virtio_user_set_config_irq,
        .set_queue_irq  = virtio_user_set_queue_irq,