1
Based-on: <20240228-reuse-v8-0-282660281e60@daynix.com>
1
Based-on: <20240315-reuse-v9-0-67aa69af4d53@daynix.com>
2
("[PATCH v8 00/15] hw/pci: SR-IOV related fixes and improvements")
2
("[PATCH for 9.1 v9 00/11] hw/pci: SR-IOV related fixes and improvements")
3
3
4
Introduction
4
Introduction
5
------------
5
------------
6
6
7
This series is based on the RFC series submitted by Yui Washizu[1].
7
This series is based on the RFC series submitted by Yui Washizu[1].
...
...
55
Summary
55
Summary
56
-------
56
-------
57
57
58
Patch 1 disables ROM BAR, which virtio-net-pci enables by default, for
58
Patch 1 disables ROM BAR, which virtio-net-pci enables by default, for
59
VFs.
59
VFs.
60
Patch 2 and 3 adds validations.
60
Patch 2 makes zero stride valid for 1 VF configuration.
61
Patch 4 adds user-created SR-IOV VF infrastructure.
61
Patch 3 and 4 adds validations.
62
Patch 5 makes virtio-pci work as SR-IOV PF for user-created VFs.
62
Patch 5 adds user-created SR-IOV VF infrastructure.
63
Patch 6 allows user to create SR-IOV VFs with virtio-net-pci.
63
Patch 6 makes virtio-pci work as SR-IOV PF for user-created VFs.
64
Patch 7 allows user to create SR-IOV VFs with virtio-net-pci.
64
65
65
[1] https://patchew.org/QEMU/1689731808-3009-1-git-send-email-yui.washidu@gmail.com/
66
[1] https://patchew.org/QEMU/1689731808-3009-1-git-send-email-yui.washidu@gmail.com/
66
[2] https://lore.kernel.org/all/5d46f455-f530-4e5e-9ae7-13a2297d4bc5@daynix.com/
67
[2] https://lore.kernel.org/all/5d46f455-f530-4e5e-9ae7-13a2297d4bc5@daynix.com/
67
68
68
Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
69
Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
69
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
70
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
70
---
71
---
72
Changes in v4:
73
- Added patch "hw/pci: Fix SR-IOV VF number calculation" to fix division
74
by zero reported by Yui Washizu.
75
- Rebased.
76
- Link to v3: https://lore.kernel.org/r/20240305-sriov-v3-0-abdb75770372@daynix.com
77
71
Changes in v3:
78
Changes in v3:
72
- Rebased.
79
- Rebased.
73
- Link to v2: https://lore.kernel.org/r/20231210-sriov-v2-0-b959e8a6dfaf@daynix.com
80
- Link to v2: https://lore.kernel.org/r/20231210-sriov-v2-0-b959e8a6dfaf@daynix.com
74
81
75
Changes in v2:
82
Changes in v2:
76
- Changed to keep VF instances.
83
- Changed to keep VF instances.
77
- Link to v1: https://lore.kernel.org/r/20231202-sriov-v1-0-32b3570f7bd6@daynix.com
84
- Link to v1: https://lore.kernel.org/r/20231202-sriov-v1-0-32b3570f7bd6@daynix.com
78
85
79
---
86
---
80
Akihiko Odaki (6):
87
Akihiko Odaki (7):
81
hw/pci: Do not add ROM BAR for SR-IOV VF
88
hw/pci: Do not add ROM BAR for SR-IOV VF
89
hw/pci: Fix SR-IOV VF number calculation
82
pcie_sriov: Ensure PF and VF are mutually exclusive
90
pcie_sriov: Ensure PF and VF are mutually exclusive
83
pcie_sriov: Check PCI Express for SR-IOV PF
91
pcie_sriov: Check PCI Express for SR-IOV PF
84
pcie_sriov: Allow user to create SR-IOV device
92
pcie_sriov: Allow user to create SR-IOV device
85
virtio-pci: Implement SR-IOV PF
93
virtio-pci: Implement SR-IOV PF
86
virtio-net: Implement SR-IOV VF
94
virtio-net: Implement SR-IOV VF
87
95
88
include/hw/pci/pci_device.h | 6 +-
96
include/hw/pci/pci_device.h | 6 +-
89
include/hw/pci/pcie_sriov.h | 19 +++
97
include/hw/pci/pcie_sriov.h | 19 +++
90
hw/pci/pci.c | 70 +++++++----
98
hw/pci/pci.c | 76 +++++++----
91
hw/pci/pcie_sriov.c | 299 +++++++++++++++++++++++++++++++++++---------
99
hw/pci/pcie_sriov.c | 298 +++++++++++++++++++++++++++++++++++---------
92
hw/virtio/virtio-net-pci.c | 1 +
100
hw/virtio/virtio-net-pci.c | 1 +
93
hw/virtio/virtio-pci.c | 7 ++
101
hw/virtio/virtio-pci.c | 7 ++
94
6 files changed, 319 insertions(+), 83 deletions(-)
102
6 files changed, 323 insertions(+), 84 deletions(-)
95
---
103
---
96
base-commit: 2c4eb0476e461b8a4b2f745d25f987e831c7f640
104
base-commit: 2ac5458086ab61282f30c2f8bdf2ae9a0a06a75d
97
change-id: 20231202-sriov-9402fb262be8
105
change-id: 20231202-sriov-9402fb262be8
98
106
99
Best regards,
107
Best regards,
100
--
108
--
101
Akihiko Odaki <akihiko.odaki@daynix.com>
109
Akihiko Odaki <akihiko.odaki@daynix.com>
diff view generated by jsdifflib
1
A SR-IOV VF cannot have a ROM BAR.
1
A SR-IOV VF cannot have a ROM BAR.
2
2
3
Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
3
Co-developed-by: Yui Washizu <yui.washidu@gmail.com>
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
---
5
---
6
hw/pci/pci.c | 8 ++++++++
6
hw/pci/pci.c | 8 ++++++++
7
1 file changed, 8 insertions(+)
7
1 file changed, 8 insertions(+)
8
8
9
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
9
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/pci/pci.c
11
--- a/hw/pci/pci.c
12
+++ b/hw/pci/pci.c
12
+++ b/hw/pci/pci.c
13
@@ -XXX,XX +XXX,XX @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
13
@@ -XXX,XX +XXX,XX @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
14
return;
14
return;
15
}
15
}
16
16
17
+ if (pci_is_vf(pdev)) {
17
+ if (pci_is_vf(pdev)) {
18
+ if (pdev->rom_bar != UINT32_MAX) {
18
+ if (pdev->rom_bar != UINT32_MAX) {
19
+ error_setg(errp, "ROM BAR cannot be enabled for SR-IOV VF");
19
+ error_setg(errp, "ROM BAR cannot be enabled for SR-IOV VF");
20
+ }
20
+ }
21
+
21
+
22
+ return;
22
+ return;
23
+ }
23
+ }
24
+
24
+
25
if (load_file || pdev->romsize == UINT32_MAX) {
25
if (load_file || pdev->romsize == UINT32_MAX) {
26
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
26
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
27
if (path == NULL) {
27
if (path == NULL) {
28
28
29
--
29
--
30
2.44.0
30
2.44.0
diff view generated by jsdifflib
New patch
1
pci_config_get_bar_addr() had a division by vf_stride. vf_stride needs
2
to be non-zero when there are multiple VFs, but the specification does
3
not prohibit to make it zero when there is only one VF.
1
4
5
Do not perform the division for the first VF to avoid division by zero.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
---
9
hw/pci/pci.c | 6 +++++-
10
1 file changed, 5 insertions(+), 1 deletion(-)
11
12
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/pci/pci.c
15
+++ b/hw/pci/pci.c
16
@@ -XXX,XX +XXX,XX @@ static pcibus_t pci_config_get_bar_addr(PCIDevice *d, int reg,
17
pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_OFFSET);
18
uint16_t vf_stride =
19
pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_STRIDE);
20
- uint32_t vf_num = (d->devfn - (pf->devfn + vf_offset)) / vf_stride;
21
+ uint32_t vf_num = d->devfn - (pf->devfn + vf_offset);
22
+
23
+ if (vf_num) {
24
+ vf_num /= vf_stride;
25
+ }
26
27
if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
28
new_addr = pci_get_quad(pf->config + bar);
29
30
--
31
2.44.0
diff view generated by jsdifflib
...
...
16
+ if (pci_is_vf(dev)) {
16
+ if (pci_is_vf(dev)) {
17
+ error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
17
+ error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
18
+ return false;
18
+ return false;
19
+ }
19
+ }
20
+
20
+
21
pcie_add_capability(dev, PCI_EXT_CAP_ID_SRIOV, 1,
21
if (total_vfs) {
22
offset, PCI_EXT_CAP_SRIOV_SIZEOF);
22
uint16_t ari_cap = pcie_find_capability(dev, PCI_EXT_CAP_ID_ARI);
23
dev->exp.sriov_cap = offset;
23
uint16_t first_vf_devfn = dev->devfn + vf_offset;
24
24
25
--
25
--
26
2.44.0
26
2.44.0
diff view generated by jsdifflib
1
SR-IOV requires PCI Express.
1
SR-IOV requires PCI Express.
2
2
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
4
---
5
hw/pci/pcie_sriov.c | 5 +++++
5
hw/pci/pcie_sriov.c | 5 +++++
6
1 file changed, 5 insertions(+)
6
1 file changed, 5 insertions(+)
7
7
8
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
8
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
9
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/pci/pcie_sriov.c
10
--- a/hw/pci/pcie_sriov.c
11
+++ b/hw/pci/pcie_sriov.c
11
+++ b/hw/pci/pcie_sriov.c
12
@@ -XXX,XX +XXX,XX @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
12
@@ -XXX,XX +XXX,XX @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
13
uint8_t *cfg = dev->config + offset;
13
uint8_t *cfg = dev->config + offset;
14
uint8_t *wmask;
14
uint8_t *wmask;
15
15
16
+ if (!pci_is_express(dev)) {
16
+ if (!pci_is_express(dev)) {
17
+ error_setg(errp, "PCI Express is required for SR-IOV PF");
17
+ error_setg(errp, "PCI Express is required for SR-IOV PF");
18
+ return false;
18
+ return false;
19
+ }
19
+ }
20
+
20
+
21
if (pci_is_vf(dev)) {
21
if (pci_is_vf(dev)) {
22
error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
22
error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time");
23
return false;
23
return false;
24
24
25
--
25
--
26
2.44.0
26
2.44.0
diff view generated by jsdifflib
...
...
12
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
---
13
---
14
include/hw/pci/pci_device.h | 6 +-
14
include/hw/pci/pci_device.h | 6 +-
15
include/hw/pci/pcie_sriov.h | 19 +++
15
include/hw/pci/pcie_sriov.h | 19 +++
16
hw/pci/pci.c | 62 ++++++----
16
hw/pci/pci.c | 62 ++++++----
17
hw/pci/pcie_sriov.c | 289 +++++++++++++++++++++++++++++++++++---------
17
hw/pci/pcie_sriov.c | 288 +++++++++++++++++++++++++++++++++++---------
18
4 files changed, 293 insertions(+), 83 deletions(-)
18
4 files changed, 292 insertions(+), 83 deletions(-)
19
19
20
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
20
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
21
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/pci/pci_device.h
22
--- a/include/hw/pci/pci_device.h
23
+++ b/include/hw/pci/pci_device.h
23
+++ b/include/hw/pci/pci_device.h
...
...
212
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
212
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
213
index XXXXXXX..XXXXXXX 100644
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/pci/pcie_sriov.c
214
--- a/hw/pci/pcie_sriov.c
215
+++ b/hw/pci/pcie_sriov.c
215
+++ b/hw/pci/pcie_sriov.c
216
@@ -XXX,XX +XXX,XX @@
216
@@ -XXX,XX +XXX,XX @@
217
#include "hw/qdev-properties.h"
217
#include "qapi/error.h"
218
#include "qemu/error-report.h"
219
#include "qemu/range.h"
220
+#include "qapi/error.h"
221
#include "trace.h"
218
#include "trace.h"
222
219
223
+static GHashTable *pfs;
220
+static GHashTable *pfs;
224
+
221
+
225
static void unparent_vfs(PCIDevice *dev, uint16_t total_vfs)
222
static void unparent_vfs(PCIDevice *dev, uint16_t total_vfs)
...
...
diff view generated by jsdifflib
1
Allow user to attach SR-IOV VF to a virtio-pci PF.
1
Allow user to attach SR-IOV VF to a virtio-pci PF.
2
2
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
---
4
---
5
hw/virtio/virtio-pci.c | 7 +++++++
5
hw/virtio/virtio-pci.c | 7 +++++++
6
1 file changed, 7 insertions(+)
6
1 file changed, 7 insertions(+)
7
7
8
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
8
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
9
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/virtio/virtio-pci.c
10
--- a/hw/virtio/virtio-pci.c
11
+++ b/hw/virtio/virtio-pci.c
11
+++ b/hw/virtio/virtio-pci.c
12
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
12
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
13
pci_register_bar(&proxy->pci_dev, proxy->legacy_io_bar_idx,
13
pci_register_bar(&proxy->pci_dev, proxy->legacy_io_bar_idx,
14
PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
14
PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
15
}
15
}
16
+
16
+
17
+ if (pcie_sriov_pf_init_from_user_created_vfs(&proxy->pci_dev,
17
+ if (pcie_sriov_pf_init_from_user_created_vfs(&proxy->pci_dev,
18
+ PCI_CONFIG_SPACE_SIZE,
18
+ PCI_CONFIG_SPACE_SIZE,
19
+ errp)) {
19
+ errp)) {
20
+ virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
20
+ virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
21
+ }
21
+ }
22
}
22
}
23
23
24
static void virtio_pci_device_unplugged(DeviceState *d)
24
static void virtio_pci_device_unplugged(DeviceState *d)
25
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_device_unplugged(DeviceState *d)
25
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_device_unplugged(DeviceState *d)
26
bool modern = virtio_pci_modern(proxy);
26
bool modern = virtio_pci_modern(proxy);
27
bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
27
bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;
28
28
29
+ pcie_sriov_pf_exit(&proxy->pci_dev);
29
+ pcie_sriov_pf_exit(&proxy->pci_dev);
30
virtio_pci_stop_ioeventfd(proxy);
30
virtio_pci_stop_ioeventfd(proxy);
31
31
32
if (modern) {
32
if (modern) {
33
33
34
--
34
--
35
2.44.0
35
2.44.0
diff view generated by jsdifflib
1
A virtio-net device can be added as a SR-IOV VF to another virtio-pci
1
A virtio-net device can be added as a SR-IOV VF to another virtio-pci
2
device that will be the PF.
2
device that will be the PF.
3
3
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
---
5
---
6
hw/virtio/virtio-net-pci.c | 1 +
6
hw/virtio/virtio-net-pci.c | 1 +
7
1 file changed, 1 insertion(+)
7
1 file changed, 1 insertion(+)
8
8
9
diff --git a/hw/virtio/virtio-net-pci.c b/hw/virtio/virtio-net-pci.c
9
diff --git a/hw/virtio/virtio-net-pci.c b/hw/virtio/virtio-net-pci.c
10
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/virtio/virtio-net-pci.c
11
--- a/hw/virtio/virtio-net-pci.c
12
+++ b/hw/virtio/virtio-net-pci.c
12
+++ b/hw/virtio/virtio-net-pci.c
13
@@ -XXX,XX +XXX,XX @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
13
@@ -XXX,XX +XXX,XX @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
14
k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
14
k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
15
k->revision = VIRTIO_PCI_ABI_VERSION;
15
k->revision = VIRTIO_PCI_ABI_VERSION;
16
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
16
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
17
+ k->sriov_vf_user_creatable = true;
17
+ k->sriov_vf_user_creatable = true;
18
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
18
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
19
device_class_set_props(dc, virtio_net_properties);
19
device_class_set_props(dc, virtio_net_properties);
20
vpciklass->realize = virtio_net_pci_realize;
20
vpciklass->realize = virtio_net_pci_realize;
21
21
22
--
22
--
23
2.44.0
23
2.44.0
diff view generated by jsdifflib