@@ -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;
}
}
@@ -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,
@@ -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);
@@ -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,