1
The following changes since commit ffaf7f0376f8040ce9068d71ae9ae8722505c42e:
1
The following changes since commit 825b96dbcee23d134b691fc75618b59c5f53da32:
2
2
3
Merge tag 'pull-10.0-testing-and-gdstub-updates-100225-1' of https://gitlab.com/stsquad/qemu into staging (2025-02-10 13:26:17 -0500)
3
Merge tag 'migration-20250310-pull-request' of https://gitlab.com/farosas/qemu into staging (2025-03-11 09:32:07 +0800)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/legoater/qemu/ tags/pull-vfio-20250211
7
https://github.com/legoater/qemu/ tags/pull-vfio-20250311
8
8
9
for you to fetch changes up to be7d8579eb5758c0edf81eb068017a56471a77e0:
9
for you to fetch changes up to 4d9607481560e6c8e1508a0aafe94f86a0503c8c:
10
10
11
vfio: Remove superfluous error report in vfio_listener_region_add() (2025-02-11 14:15:19 +0100)
11
vfio/pci: Drop debug commentary from x-device-dirty-page-tracking (2025-03-11 19:04:58 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
vfio queue:
14
vfio queue:
15
15
16
* Coverity fix
16
* Fixed endianness of VFIO device state packets
17
* IGD cleanups using VFIOQuirk
17
* Improved IGD passthrough support with legacy mode
18
* SIGSEV fix in IOMMUFD host IOMMU device
18
* Improved build
19
* Improved error reporting for MMIO region mapping failures
19
* Added support for old AMD GPUs (x550)
20
* Updated property documentation
20
21
21
----------------------------------------------------------------
22
----------------------------------------------------------------
22
Cédric Le Goater (8):
23
Joao Martins (1):
23
vfio/igd: Fix potential overflow in igd_gtt_memory_size()
24
vfio/pci: Drop debug commentary from x-device-dirty-page-tracking
24
util/error: Introduce warn_report_err_once()
25
vfio/pci: Replace "iommu_device" by "vIOMMU"
26
vfio: Rephrase comment in vfio_listener_region_add() error path
27
vfio: Introduce vfio_get_vfio_device()
28
vfio: Improve error reporting when MMIO region mapping fails
29
vfio: Remove reports of DMA mapping errors in backends
30
vfio: Remove superfluous error report in vfio_listener_region_add()
31
25
32
Tomita Moeko (3):
26
Maciej S. Szmigiero (1):
33
vfio/pci: declare generic quirks in a new header file
27
vfio/migration: Use BE byte order for device state wire packets
34
vfio/pci: introduce config_offset field in VFIOConfigMirrorQuirk
35
vfio/igd: use VFIOConfigMirrorQuirk for mirrored registers
36
28
37
Zhenzhong Duan (1):
29
Philippe Mathieu-Daudé (8):
38
vfio/iommufd: Fix SIGSEV in iommufd_cdev_attach()
30
system: Declare qemu_[min/max]rampagesize() in 'system/hostmem.h'
31
hw/vfio/spapr: Do not include <linux/kvm.h>
32
hw/vfio/common: Include missing 'system/tcg.h' header
33
hw/vfio/common: Get target page size using runtime helpers
34
hw/vfio: Compile some common objects once
35
hw/vfio: Compile more objects once
36
hw/vfio: Compile iommufd.c once
37
hw/vfio: Compile display.c once
39
38
40
hw/vfio/pci-quirks.h | 72 ++++++++++++++++++++++++
39
Tomita Moeko (10):
41
include/hw/vfio/vfio-common.h | 1 +
40
vfio/igd: Remove GTT write quirk in IO BAR 4
42
include/qapi/error.h | 12 ++++
41
vfio/igd: Do not include GTT stolen size in etc/igd-bdsm-size
43
backends/iommufd.c | 3 -
42
vfio/igd: Consolidate OpRegion initialization into a single function
44
hw/vfio/common.c | 40 +++++++++----
43
vfio/igd: Move LPC bridge initialization to a separate function
45
hw/vfio/container.c | 2 -
44
vfio/pci: Add placeholder for device-specific config space quirks
46
hw/vfio/helpers.c | 10 ++++
45
vfio/igd: Refactor vfio_probe_igd_bar4_quirk into pci config quirk
47
hw/vfio/igd.c | 127 +++++++++++-------------------------------
46
vfio/igd: Decouple common quirks from legacy mode
48
hw/vfio/iommufd.c | 5 +-
47
vfio/igd: Handle x-igd-opregion option in config quirk
49
hw/vfio/pci-quirks.c | 57 ++-----------------
48
vfio/igd: Introduce x-igd-lpc option for LPC bridge ID quirk
50
hw/vfio/pci.c | 2 +-
49
vfio/igd: Fix broken KVMGT OpRegion support
51
util/error.c | 11 ++++
50
52
12 files changed, 177 insertions(+), 165 deletions(-)
51
Vasilis Liaskovitis (1):
53
create mode 100644 hw/vfio/pci-quirks.h
52
vfio/pci-quirks: Exclude non-ioport BAR from ATI quirk
53
54
hw/vfio/pci.h | 11 +-
55
include/exec/ram_addr.h | 3 -
56
include/system/hostmem.h | 3 +
57
hw/ppc/spapr_caps.c | 1 +
58
hw/s390x/s390-virtio-ccw.c | 1 +
59
hw/vfio/common.c | 9 +-
60
hw/vfio/igd.c | 529 +++++++++++++++++++-------------------------
61
hw/vfio/iommufd.c | 1 -
62
hw/vfio/migration-multifd.c | 15 +-
63
hw/vfio/migration.c | 1 -
64
hw/vfio/pci-quirks.c | 53 +----
65
hw/vfio/pci.c | 35 +--
66
hw/vfio/spapr.c | 4 +-
67
hw/vfio/meson.build | 27 ++-
68
14 files changed, 288 insertions(+), 405 deletions(-)
54
69
55
70
diff view generated by jsdifflib
1
From: Tomita Moeko <tomitamoeko@gmail.com>
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
2
3
With the introduction of config_offset field, VFIOConfigMirrorQuirk can
3
The IO BAR4 of IGD devices contains a pair of 32-bit address/data
4
now be used for those mirrored register in igd bar0. This eliminates
4
registers, MMIO_Index (0x0) and MMIO_Data (0x4), which provide access
5
the need for the macro intoduced in 1a2623b5c9e7 ("vfio/igd: add macro
5
to the MMIO BAR0 (GTTMMADR) from IO space. These registers are probably
6
for declaring mirrored registers").
6
only used by the VBIOS, and are not documented by intel. The observed
7
layout of MMIO_Index register is:
8
31 2 1 0
9
+-------------------------------------------------------------------+
10
| Offset | Rsvd | Sel |
11
+-------------------------------------------------------------------+
12
- Offset: Byte offset in specified region, 4-byte aligned.
13
- Sel: Region selector
14
0: MMIO register region (first half of MMIO BAR0)
15
1: GTT region (second half of MMIO BAR0). Pre Gen11 only.
16
17
Currently, QEMU implements a quirk that adjusts the guest Data Stolen
18
Memory (DSM) region address to be (addr - host BDSM + guest BDSM) when
19
programming GTT entries via IO BAR4, assuming guest still programs GTT
20
with host DSM address, which is not the case. Guest's BDSM register is
21
emulated and initialized to 0 at startup by QEMU, then SeaBIOS programs
22
its value[1]. As result, the address programmed to GTT entries by VBIOS
23
running in guest are valid GPA, and this unnecessary adjustment brings
24
inconsistency.
25
26
[1] https://gitlab.com/qemu-project/seabios/-/blob/1.12-stable/src/fw/pciinit.c#L319-332
7
27
8
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
28
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
9
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
29
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
10
Link: https://lore.kernel.org/r/20250104154219.7209-4-tomitamoeko@gmail.com
30
Tested-by: Alex Williamson <alex.williamson@redhat.com>
31
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
32
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-2-tomitamoeko@gmail.com
11
Signed-off-by: Cédric Le Goater <clg@redhat.com>
33
Signed-off-by: Cédric Le Goater <clg@redhat.com>
12
---
34
---
13
hw/vfio/igd.c | 125 +++++++++++++-------------------------------------
35
hw/vfio/igd.c | 191 +-------------------------------------------------
14
1 file changed, 31 insertions(+), 94 deletions(-)
36
1 file changed, 1 insertion(+), 190 deletions(-)
15
37
16
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
38
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
17
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/vfio/igd.c
40
--- a/hw/vfio/igd.c
19
+++ b/hw/vfio/igd.c
41
+++ b/hw/vfio/igd.c
20
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ static int igd_gen(VFIOPCIDevice *vdev)
21
#include "hw/hw.h"
43
return -1;
22
#include "hw/nvram/fw_cfg.h"
44
}
23
#include "pci.h"
45
24
+#include "pci-quirks.h"
46
-typedef struct VFIOIGDQuirk {
25
#include "trace.h"
47
- struct VFIOPCIDevice *vdev;
26
48
- uint32_t index;
27
/*
49
- uint64_t bdsm;
28
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps vfio_igd_index_quirk = {
50
-} VFIOIGDQuirk;
29
.endianness = DEVICE_LITTLE_ENDIAN,
51
-
30
};
52
#define IGD_GMCH 0x50 /* Graphics Control Register */
31
53
#define IGD_BDSM 0x5c /* Base Data of Stolen Memory */
32
-static uint64_t vfio_igd_pci_config_read(VFIOPCIDevice *vdev, uint64_t offset,
54
#define IGD_BDSM_GEN11 0xc0 /* Base Data of Stolen Memory of gen 11 and later */
33
- unsigned size)
55
@@ -XXX,XX +XXX,XX @@ static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
34
-{
56
return ret;
35
- switch (size) {
57
}
36
- case 1:
58
37
- return pci_get_byte(vdev->pdev.config + offset);
59
-/*
38
- case 2:
60
- * IGD Gen8 and newer support up to 8MB for the GTT and use a 64bit PTE
39
- return pci_get_word(vdev->pdev.config + offset);
61
- * entry, older IGDs use 2MB and 32bit. Each PTE maps a 4k page. Therefore
40
- case 4:
62
- * we either have 2M/4k * 4 = 2k or 8M/4k * 8 = 16k as the maximum iobar index
41
- return pci_get_long(vdev->pdev.config + offset);
63
- * for programming the GTT.
42
- case 8:
64
- *
43
- return pci_get_quad(vdev->pdev.config + offset);
65
- * See linux:include/drm/i915_drm.h for shift and mask values.
44
- default:
66
- */
45
- hw_error("igd: unsupported pci config read at %"PRIx64", size %u",
67
-static int vfio_igd_gtt_max(VFIOPCIDevice *vdev)
46
- offset, size);
68
-{
47
- break;
69
- uint32_t gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
48
- }
70
- int gen = igd_gen(vdev);
49
-
71
- uint64_t ggms_size = igd_gtt_memory_size(gen, gmch);
50
- return 0;
72
-
51
-}
73
- return (ggms_size / (4 * KiB)) * (gen < 8 ? 4 : 8);
52
-
74
-}
53
-static void vfio_igd_pci_config_write(VFIOPCIDevice *vdev, uint64_t offset,
75
-
76
-/*
77
- * The IGD ROM will make use of stolen memory (GGMS) for support of VESA modes.
78
- * Somehow the host stolen memory range is used for this, but how the ROM gets
79
- * it is a mystery, perhaps it's hardcoded into the ROM. Thankfully though, it
80
- * reprograms the GTT through the IOBAR where we can trap it and transpose the
81
- * programming to the VM allocated buffer. That buffer gets reserved by the VM
82
- * firmware via the fw_cfg entry added below. Here we're just monitoring the
83
- * IOBAR address and data registers to detect a write sequence targeting the
84
- * GTTADR. This code is developed by observed behavior and doesn't have a
85
- * direct spec reference, unfortunately.
86
- */
87
-static uint64_t vfio_igd_quirk_data_read(void *opaque,
88
- hwaddr addr, unsigned size)
89
-{
90
- VFIOIGDQuirk *igd = opaque;
91
- VFIOPCIDevice *vdev = igd->vdev;
92
-
93
- igd->index = ~0;
94
-
95
- return vfio_region_read(&vdev->bars[4].region, addr + 4, size);
96
-}
97
-
98
-static void vfio_igd_quirk_data_write(void *opaque, hwaddr addr,
54
- uint64_t data, unsigned size)
99
- uint64_t data, unsigned size)
55
-{
100
-{
56
- switch (size) {
101
- VFIOIGDQuirk *igd = opaque;
57
- case 1:
102
- VFIOPCIDevice *vdev = igd->vdev;
58
- pci_set_byte(vdev->pdev.config + offset, data);
103
- uint64_t val = data;
59
- break;
104
- int gen = igd_gen(vdev);
60
- case 2:
105
-
61
- pci_set_word(vdev->pdev.config + offset, data);
106
- /*
62
- break;
107
- * Programming the GGMS starts at index 0x1 and uses every 4th index (ie.
63
- case 4:
108
- * 0x1, 0x5, 0x9, 0xd,...). For pre-Gen8 each 4-byte write is a whole PTE
64
- pci_set_long(vdev->pdev.config + offset, data);
109
- * entry, with 0th bit enable set. For Gen8 and up, PTEs are 64bit, so
65
- break;
110
- * entries 0x5 & 0xd are the high dword, in our case zero. Each PTE points
66
- case 8:
111
- * to a 4k page, which we translate to a page from the VM allocated region,
67
- pci_set_quad(vdev->pdev.config + offset, data);
112
- * pointed to by the BDSM register. If this is not set, we fail.
68
- break;
113
- *
69
- default:
114
- * We trap writes to the full configured GTT size, but we typically only
70
- hw_error("igd: unsupported pci config write at %"PRIx64", size %u",
115
- * see the vBIOS writing up to (nearly) the 1MB barrier. In fact it often
71
- offset, size);
116
- * seems to miss the last entry for an even 1MB GTT. Doing a gratuitous
72
- break;
117
- * write of that last entry does work, but is hopefully unnecessary since
73
- }
118
- * we clear the previous GTT on initialization.
74
-}
119
- */
75
-
120
- if ((igd->index % 4 == 1) && igd->index < vfio_igd_gtt_max(vdev)) {
76
-#define VFIO_IGD_QUIRK_MIRROR_REG(reg, name) \
121
- if (gen < 8 || (igd->index % 8 == 1)) {
77
-static uint64_t vfio_igd_quirk_read_##name(void *opaque, \
122
- uint64_t base;
78
- hwaddr addr, unsigned size) \
123
-
79
-{ \
124
- if (gen < 11) {
80
- VFIOPCIDevice *vdev = opaque; \
125
- base = pci_get_long(vdev->pdev.config + IGD_BDSM);
81
- \
126
- } else {
82
- return vfio_igd_pci_config_read(vdev, reg + addr, size); \
127
- base = pci_get_quad(vdev->pdev.config + IGD_BDSM_GEN11);
83
-} \
128
- }
84
- \
129
- if (!base) {
85
-static void vfio_igd_quirk_write_##name(void *opaque, hwaddr addr, \
130
- hw_error("vfio-igd: Guest attempted to program IGD GTT before "
86
- uint64_t data, unsigned size) \
131
- "BIOS reserved stolen memory. Unsupported BIOS?");
87
-{ \
132
- }
88
- VFIOPCIDevice *vdev = opaque; \
133
-
89
- \
134
- val = data - igd->bdsm + base;
90
- vfio_igd_pci_config_write(vdev, reg + addr, data, size); \
135
- } else {
91
-} \
136
- val = 0; /* upper 32bits of pte, we only enable below 4G PTEs */
92
- \
137
- }
93
-static const MemoryRegionOps vfio_igd_quirk_mirror_##name = { \
138
-
94
- .read = vfio_igd_quirk_read_##name, \
139
- trace_vfio_pci_igd_bar4_write(vdev->vbasedev.name,
95
- .write = vfio_igd_quirk_write_##name, \
140
- igd->index, data, val);
96
- .endianness = DEVICE_LITTLE_ENDIAN, \
141
- }
142
-
143
- vfio_region_write(&vdev->bars[4].region, addr + 4, val, size);
144
-
145
- igd->index = ~0;
146
-}
147
-
148
-static const MemoryRegionOps vfio_igd_data_quirk = {
149
- .read = vfio_igd_quirk_data_read,
150
- .write = vfio_igd_quirk_data_write,
151
- .endianness = DEVICE_LITTLE_ENDIAN,
97
-};
152
-};
98
-
153
-
99
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_GMCH, ggc)
154
-static uint64_t vfio_igd_quirk_index_read(void *opaque,
100
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_BDSM, bdsm)
155
- hwaddr addr, unsigned size)
101
-VFIO_IGD_QUIRK_MIRROR_REG(IGD_BDSM_GEN11, bdsm64)
156
-{
157
- VFIOIGDQuirk *igd = opaque;
158
- VFIOPCIDevice *vdev = igd->vdev;
159
-
160
- igd->index = ~0;
161
-
162
- return vfio_region_read(&vdev->bars[4].region, addr, size);
163
-}
164
-
165
-static void vfio_igd_quirk_index_write(void *opaque, hwaddr addr,
166
- uint64_t data, unsigned size)
167
-{
168
- VFIOIGDQuirk *igd = opaque;
169
- VFIOPCIDevice *vdev = igd->vdev;
170
-
171
- igd->index = data;
172
-
173
- vfio_region_write(&vdev->bars[4].region, addr, data, size);
174
-}
175
-
176
-static const MemoryRegionOps vfio_igd_index_quirk = {
177
- .read = vfio_igd_quirk_index_read,
178
- .write = vfio_igd_quirk_index_write,
179
- .endianness = DEVICE_LITTLE_ENDIAN,
180
-};
102
-
181
-
103
#define IGD_GGC_MMIO_OFFSET 0x108040
182
#define IGD_GGC_MMIO_OFFSET 0x108040
104
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
183
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
105
184
106
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
185
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
107
{
186
g_autofree struct vfio_region_info *opregion = NULL;
187
g_autofree struct vfio_region_info *host = NULL;
188
g_autofree struct vfio_region_info *lpc = NULL;
108
- VFIOQuirk *quirk;
189
- VFIOQuirk *quirk;
109
+ VFIOQuirk *ggc_quirk, *bdsm_quirk;
190
- VFIOIGDQuirk *igd;
110
+ VFIOConfigMirrorQuirk *ggc_mirror, *bdsm_mirror;
191
PCIDevice *lpc_bridge;
111
int gen;
192
- int i, ret, gen;
193
+ int ret, gen;
194
uint64_t ggms_size, gms_size;
195
uint64_t *bdsm_size;
196
uint32_t gmch;
197
- uint16_t cmd_orig, cmd;
198
Error *err = NULL;
112
199
113
/*
200
/*
114
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
201
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
115
return;
202
return;
116
}
203
}
117
204
205
- /* Setup our quirk to munge GTT addresses to the VM allocated buffer */
118
- quirk = vfio_quirk_alloc(2);
206
- quirk = vfio_quirk_alloc(2);
119
- quirk->data = vdev;
207
- igd = quirk->data = g_malloc0(sizeof(*igd));
120
+ ggc_quirk = vfio_quirk_alloc(1);
208
- igd->vdev = vdev;
121
+ ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror));
209
- igd->index = ~0;
122
+ ggc_mirror->mem = ggc_quirk->mem;
123
+ ggc_mirror->vdev = vdev;
124
+ ggc_mirror->bar = nr;
125
+ ggc_mirror->offset = IGD_GGC_MMIO_OFFSET;
126
+ ggc_mirror->config_offset = IGD_GMCH;
127
128
- memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
129
- &vfio_igd_quirk_mirror_ggc, vdev,
130
+ memory_region_init_io(ggc_mirror->mem, OBJECT(vdev),
131
+ &vfio_generic_mirror_quirk, ggc_mirror,
132
"vfio-igd-ggc-quirk", 2);
133
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
134
- IGD_GGC_MMIO_OFFSET, &quirk->mem[0],
135
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
136
+ ggc_mirror->offset, ggc_mirror->mem,
137
1);
138
139
- if (gen < 11) {
210
- if (gen < 11) {
140
- memory_region_init_io(&quirk->mem[1], OBJECT(vdev),
211
- igd->bdsm = vfio_pci_read_config(&vdev->pdev, IGD_BDSM, 4);
141
- &vfio_igd_quirk_mirror_bdsm, vdev,
142
- "vfio-igd-bdsm-quirk", 4);
143
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
144
- IGD_BDSM_MMIO_OFFSET,
145
- &quirk->mem[1], 1);
146
- } else {
212
- } else {
147
- memory_region_init_io(&quirk->mem[1], OBJECT(vdev),
213
- igd->bdsm = vfio_pci_read_config(&vdev->pdev, IGD_BDSM_GEN11, 4);
148
- &vfio_igd_quirk_mirror_bdsm64, vdev,
214
- igd->bdsm |=
149
- "vfio-igd-bdsm-quirk", 8);
215
- (uint64_t)vfio_pci_read_config(&vdev->pdev, IGD_BDSM_GEN11 + 4, 4) << 32;
150
- memory_region_add_subregion_overlap(vdev->bars[0].region.mem,
216
- }
151
- IGD_BDSM_MMIO_OFFSET,
217
- igd->bdsm &= ~((1 * MiB) - 1); /* 1MB aligned */
152
- &quirk->mem[1], 1);
218
-
153
- }
219
- memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_igd_index_quirk,
154
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, ggc_quirk, next);
220
- igd, "vfio-igd-index-quirk", 4);
155
221
- memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
222
- 0, &quirk->mem[0], 1);
223
-
224
- memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_igd_data_quirk,
225
- igd, "vfio-igd-data-quirk", 4);
226
- memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
227
- 4, &quirk->mem[1], 1);
228
-
156
- QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
229
- QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
157
+ bdsm_quirk = vfio_quirk_alloc(1);
230
-
158
+ bdsm_mirror = bdsm_quirk->data = g_malloc0(sizeof(*bdsm_mirror));
231
/*
159
+ bdsm_mirror->mem = bdsm_quirk->mem;
232
* Allow user to override dsm size using x-igd-gms option, in multiples of
160
+ bdsm_mirror->vdev = vdev;
233
* 32MiB. This option should only be used when the desired size cannot be
161
+ bdsm_mirror->bar = nr;
234
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
162
+ bdsm_mirror->offset = IGD_BDSM_MMIO_OFFSET;
235
pci_set_quad(vdev->emulated_config_bits + IGD_BDSM_GEN11, ~0);
163
+ bdsm_mirror->config_offset = (gen < 11) ? IGD_BDSM : IGD_BDSM_GEN11;
236
}
164
+
237
165
+ memory_region_init_io(bdsm_mirror->mem, OBJECT(vdev),
238
- /*
166
+ &vfio_generic_mirror_quirk, bdsm_mirror,
239
- * This IOBAR gives us access to GTTADR, which allows us to write to
167
+ "vfio-igd-bdsm-quirk", (gen < 11) ? 4 : 8);
240
- * the GTT itself. So let's go ahead and write zero to all the GTT
168
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
241
- * entries to avoid spurious DMA faults. Be sure I/O access is enabled
169
+ bdsm_mirror->offset, bdsm_mirror->mem,
242
- * before talking to the device.
170
+ 1);
243
- */
171
+
244
- if (pread(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig),
172
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
245
- vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) {
246
- error_report("IGD device %s - failed to read PCI command register",
247
- vdev->vbasedev.name);
248
- }
249
-
250
- cmd = cmd_orig | PCI_COMMAND_IO;
251
-
252
- if (pwrite(vdev->vbasedev.fd, &cmd, sizeof(cmd),
253
- vdev->config_offset + PCI_COMMAND) != sizeof(cmd)) {
254
- error_report("IGD device %s - failed to write PCI command register",
255
- vdev->vbasedev.name);
256
- }
257
-
258
- for (i = 1; i < vfio_igd_gtt_max(vdev); i += 4) {
259
- vfio_region_write(&vdev->bars[4].region, 0, i, 4);
260
- vfio_region_write(&vdev->bars[4].region, 4, 0, 4);
261
- }
262
-
263
- if (pwrite(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig),
264
- vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) {
265
- error_report("IGD device %s - failed to restore PCI command register",
266
- vdev->vbasedev.name);
267
- }
268
-
269
trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name,
270
(ggms_size + gms_size) / MiB);
173
}
271
}
174
175
void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
176
--
272
--
177
2.48.1
273
2.48.1
178
274
179
275
diff view generated by jsdifflib
1
The risk is mainly theoretical since the applied bit mask will keep
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
the 'ggms' shift value below 3. Nevertheless, let's use a 64 bit
3
integer type and resolve the coverity issue.
4
2
5
Resolves: Coverity CID 1585908
3
Though GTT Stolen Memory (GSM) is right below Data Stolen Memory (DSM)
6
Fixes: 1e1eac5f3dcd ("vfio/igd: canonicalize memory size calculations")
4
in host address space, direct access to GSM is prohibited, and it is
5
not mapped to guest address space. Both host and guest accesses GSM
6
indirectly through the second half of MMIO BAR0 (GTTMMADR).
7
8
Guest firmware only need to reserve a memory region for DSM and program
9
the BDSM register with the base address of that region, that's actually
10
what both SeaBIOS[1] and IgdAssignmentDxe does now.
11
12
[1] https://gitlab.com/qemu-project/seabios/-/blob/1.12-stable/src/fw/pciinit.c#L319-332
13
14
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
7
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
15
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
8
Link: https://lore.kernel.org/r/20250107130604.669697-1-clg@redhat.com
16
Tested-by: Alex Williamson <alex.williamson@redhat.com>
17
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
18
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-3-tomitamoeko@gmail.com
9
Signed-off-by: Cédric Le Goater <clg@redhat.com>
19
Signed-off-by: Cédric Le Goater <clg@redhat.com>
10
---
20
---
11
hw/vfio/igd.c | 2 +-
21
hw/vfio/igd.c | 28 +++-------------------------
12
1 file changed, 1 insertion(+), 1 deletion(-)
22
1 file changed, 3 insertions(+), 25 deletions(-)
13
23
14
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
24
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/vfio/igd.c
26
--- a/hw/vfio/igd.c
17
+++ b/hw/vfio/igd.c
27
+++ b/hw/vfio/igd.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t igd_gtt_memory_size(int gen, uint16_t gmch)
28
@@ -XXX,XX +XXX,XX @@ static int igd_gen(VFIOPCIDevice *vdev)
19
} else {
29
20
ggms = (gmch >> IGD_GMCH_GEN8_GGMS_SHIFT) & IGD_GMCH_GEN8_GGMS_MASK;
30
#define IGD_GMCH_GEN6_GMS_SHIFT 3 /* SNB_GMCH in i915 */
21
if (ggms != 0) {
31
#define IGD_GMCH_GEN6_GMS_MASK 0x1f
22
- ggms = 1 << ggms;
32
-#define IGD_GMCH_GEN6_GGMS_SHIFT 8
23
+ ggms = 1ULL << ggms;
33
-#define IGD_GMCH_GEN6_GGMS_MASK 0x3
34
#define IGD_GMCH_GEN8_GMS_SHIFT 8 /* BDW_GMCH in i915 */
35
#define IGD_GMCH_GEN8_GMS_MASK 0xff
36
-#define IGD_GMCH_GEN8_GGMS_SHIFT 6
37
-#define IGD_GMCH_GEN8_GGMS_MASK 0x3
38
-
39
-static uint64_t igd_gtt_memory_size(int gen, uint16_t gmch)
40
-{
41
- uint64_t ggms;
42
-
43
- if (gen < 8) {
44
- ggms = (gmch >> IGD_GMCH_GEN6_GGMS_SHIFT) & IGD_GMCH_GEN6_GGMS_MASK;
45
- } else {
46
- ggms = (gmch >> IGD_GMCH_GEN8_GGMS_SHIFT) & IGD_GMCH_GEN8_GGMS_MASK;
47
- if (ggms != 0) {
48
- ggms = 1ULL << ggms;
49
- }
50
- }
51
-
52
- return ggms * MiB;
53
-}
54
55
static uint64_t igd_stolen_memory_size(int gen, uint32_t gmch)
56
{
57
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
58
g_autofree struct vfio_region_info *lpc = NULL;
59
PCIDevice *lpc_bridge;
60
int ret, gen;
61
- uint64_t ggms_size, gms_size;
62
+ uint64_t gms_size;
63
uint64_t *bdsm_size;
64
uint32_t gmch;
65
Error *err = NULL;
66
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
24
}
67
}
25
}
68
}
26
69
70
- ggms_size = igd_gtt_memory_size(gen, gmch);
71
gms_size = igd_stolen_memory_size(gen, gmch);
72
73
/*
74
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
75
* config offset 0x5C.
76
*/
77
bdsm_size = g_malloc(sizeof(*bdsm_size));
78
- *bdsm_size = cpu_to_le64(ggms_size + gms_size);
79
+ *bdsm_size = cpu_to_le64(gms_size);
80
fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
81
bdsm_size, sizeof(*bdsm_size));
82
83
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
84
pci_set_quad(vdev->emulated_config_bits + IGD_BDSM_GEN11, ~0);
85
}
86
87
- trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name,
88
- (ggms_size + gms_size) / MiB);
89
+ trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, (gms_size / MiB));
90
}
27
--
91
--
28
2.48.1
92
2.48.1
29
93
30
94
diff view generated by jsdifflib
1
Depending on the configuration of the host and VM, a passthrough
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
device may generate recurring DMA mapping errors at runtime. In such
2
3
cases, reporting the issue once is sufficient.
3
Both x-igd-opregion option and legacy mode require identical steps to
4
4
set up OpRegion for IGD devices. Consolidate these steps into a single
5
We have already the warn/error_report_once() routines taking a format
5
vfio_pci_igd_setup_opregion function.
6
and arguments. Using the same design pattern, add a new warning
6
7
variant taking an 'Error *' parameter.
7
The function call in pci.c is wrapped with ifdef temporarily to prevent
8
8
build error for non-x86 archs, it will be removed after we decouple it
9
Cc: Markus Armbruster <armbru@redhat.com>
9
from legacy mode.
10
11
Additionally, move vfio_pci_igd_opregion_init to igd.c to prevent it
12
from being compiled in non-x86 builds.
13
14
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
10
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
15
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
16
Tested-by: Alex Williamson <alex.williamson@redhat.com>
12
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-2-clg@redhat.com
17
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
18
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-4-tomitamoeko@gmail.com
19
[ clg: Fixed spelling in vfio_pci_igd_setup_opregion() ]
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
20
Signed-off-by: Cédric Le Goater <clg@redhat.com>
14
---
21
---
15
include/qapi/error.h | 12 ++++++++++++
22
hw/vfio/pci.h | 4 +-
16
util/error.c | 11 +++++++++++
23
hw/vfio/igd.c | 101 +++++++++++++++++++++++++++++++++++--------
17
2 files changed, 23 insertions(+)
24
hw/vfio/pci-quirks.c | 50 ---------------------
18
25
hw/vfio/pci.c | 22 ++--------
19
diff --git a/include/qapi/error.h b/include/qapi/error.h
26
4 files changed, 88 insertions(+), 89 deletions(-)
20
index XXXXXXX..XXXXXXX 100644
27
21
--- a/include/qapi/error.h
28
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
22
+++ b/include/qapi/error.h
29
index XXXXXXX..XXXXXXX 100644
23
@@ -XXX,XX +XXX,XX @@ void warn_reportf_err(Error *err, const char *fmt, ...)
30
--- a/hw/vfio/pci.h
24
void error_reportf_err(Error *err, const char *fmt, ...)
31
+++ b/hw/vfio/pci.h
25
G_GNUC_PRINTF(2, 3);
32
@@ -XXX,XX +XXX,XX @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
33
34
bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
35
36
-bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
37
- struct vfio_region_info *info,
38
- Error **errp);
39
+bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp);
40
41
void vfio_display_reset(VFIOPCIDevice *vdev);
42
bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
43
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/vfio/igd.c
46
+++ b/hw/vfio/igd.c
47
@@ -XXX,XX +XXX,XX @@ static int igd_gen(VFIOPCIDevice *vdev)
48
return -1;
49
}
50
51
+#define IGD_ASLS 0xfc /* ASL Storage Register */
52
#define IGD_GMCH 0x50 /* Graphics Control Register */
53
#define IGD_BDSM 0x5c /* Base Data of Stolen Memory */
54
#define IGD_BDSM_GEN11 0xc0 /* Base Data of Stolen Memory of gen 11 and later */
55
@@ -XXX,XX +XXX,XX @@ static uint64_t igd_stolen_memory_size(int gen, uint32_t gmch)
56
return 0;
57
}
26
58
27
+/*
59
+/*
28
+ * Similar to warn_report_err(), except it prints the message just once.
60
+ * The OpRegion includes the Video BIOS Table, which seems important for
29
+ * Return true when it prints, false otherwise.
61
+ * telling the driver what sort of outputs it has. Without this, the device
62
+ * may work in the guest, but we may not get output. This also requires BIOS
63
+ * support to reserve and populate a section of guest memory sufficient for
64
+ * the table and to write the base address of that memory to the ASLS register
65
+ * of the IGD device.
30
+ */
66
+ */
31
+bool warn_report_err_once_cond(bool *printed, Error *err);
67
+static bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
32
+
68
+ struct vfio_region_info *info,
33
+#define warn_report_err_once(err) \
69
+ Error **errp)
34
+ ({ \
35
+ static bool print_once_; \
36
+ warn_report_err_once_cond(&print_once_, err); \
37
+ })
38
+
39
/*
40
* Just like error_setg(), except you get to specify the error class.
41
* Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
42
diff --git a/util/error.c b/util/error.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/util/error.c
45
+++ b/util/error.c
46
@@ -XXX,XX +XXX,XX @@ void warn_report_err(Error *err)
47
error_free(err);
48
}
49
50
+bool warn_report_err_once_cond(bool *printed, Error *err)
51
+{
70
+{
52
+ if (*printed) {
71
+ int ret;
53
+ error_free(err);
72
+
54
+ return false;
73
+ vdev->igd_opregion = g_malloc0(info->size);
55
+ }
74
+ ret = pread(vdev->vbasedev.fd, vdev->igd_opregion,
56
+ *printed = true;
75
+ info->size, info->offset);
57
+ warn_report_err(err);
76
+ if (ret != info->size) {
77
+ error_setg(errp, "failed to read IGD OpRegion");
78
+ g_free(vdev->igd_opregion);
79
+ vdev->igd_opregion = NULL;
80
+ return false;
81
+ }
82
+
83
+ /*
84
+ * Provide fw_cfg with a copy of the OpRegion which the VM firmware is to
85
+ * allocate 32bit reserved memory for, copy these contents into, and write
86
+ * the reserved memory base address to the device ASLS register at 0xFC.
87
+ * Alignment of this reserved region seems flexible, but using a 4k page
88
+ * alignment seems to work well. This interface assumes a single IGD
89
+ * device, which may be at VM address 00:02.0 in legacy mode or another
90
+ * address in UPT mode.
91
+ *
92
+ * NB, there may be future use cases discovered where the VM should have
93
+ * direct interaction with the host OpRegion, in which case the write to
94
+ * the ASLS register would trigger MemoryRegion setup to enable that.
95
+ */
96
+ fw_cfg_add_file(fw_cfg_find(), "etc/igd-opregion",
97
+ vdev->igd_opregion, info->size);
98
+
99
+ trace_vfio_pci_igd_opregion_enabled(vdev->vbasedev.name);
100
+
101
+ pci_set_long(vdev->pdev.config + IGD_ASLS, 0);
102
+ pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
103
+ pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
104
+
58
+ return true;
105
+ return true;
59
+}
106
+}
60
+
107
+
61
void error_reportf_err(Error *err, const char *fmt, ...)
108
+bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp)
109
+{
110
+ g_autofree struct vfio_region_info *opregion = NULL;
111
+ int ret;
112
+
113
+ /* Hotplugging is not supported for opregion access */
114
+ if (vdev->pdev.qdev.hotplugged) {
115
+ error_setg(errp, "IGD OpRegion is not supported on hotplugged device");
116
+ return false;
117
+ }
118
+
119
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
120
+ VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
121
+ VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);
122
+ if (ret) {
123
+ error_setg_errno(errp, -ret,
124
+ "Device does not supports IGD OpRegion feature");
125
+ return false;
126
+ }
127
+
128
+ if (!vfio_pci_igd_opregion_init(vdev, opregion, errp)) {
129
+ return false;
130
+ }
131
+
132
+ return true;
133
+}
134
+
135
/*
136
* The rather short list of registers that we copy from the host devices.
137
* The LPC/ISA bridge values are definitely needed to support the vBIOS, the
138
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
139
void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
62
{
140
{
63
va_list ap;
141
g_autofree struct vfio_region_info *rom = NULL;
142
- g_autofree struct vfio_region_info *opregion = NULL;
143
g_autofree struct vfio_region_info *host = NULL;
144
g_autofree struct vfio_region_info *lpc = NULL;
145
PCIDevice *lpc_bridge;
146
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
147
* Check whether we have all the vfio device specific regions to
148
* support legacy mode (added in Linux v4.6). If not, bail.
149
*/
150
- ret = vfio_get_dev_region_info(&vdev->vbasedev,
151
- VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
152
- VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);
153
- if (ret) {
154
- error_report("IGD device %s does not support OpRegion access,"
155
- "legacy mode disabled", vdev->vbasedev.name);
156
- return;
157
- }
158
-
159
ret = vfio_get_dev_region_info(&vdev->vbasedev,
160
VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
161
VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host);
162
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
163
return;
164
}
165
166
+ /* Setup OpRegion access */
167
+ if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
168
+ error_append_hint(&err, "IGD legacy mode disabled\n");
169
+ error_report_err(err);
170
+ return;
171
+ }
172
+
173
/* Create our LPC/ISA bridge */
174
ret = vfio_pci_igd_lpc_init(vdev, lpc);
175
if (ret) {
176
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
177
return;
178
}
179
180
- /* Setup OpRegion access */
181
- if (!vfio_pci_igd_opregion_init(vdev, opregion, &err)) {
182
- error_append_hint(&err, "IGD legacy mode disabled\n");
183
- error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
184
- return;
185
- }
186
-
187
/*
188
* Allow user to override dsm size using x-igd-gms option, in multiples of
189
* 32MiB. This option should only be used when the desired size cannot be
190
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/hw/vfio/pci-quirks.c
193
+++ b/hw/vfio/pci-quirks.c
194
@@ -XXX,XX +XXX,XX @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice *vdev, int nr)
195
trace_vfio_quirk_rtl8168_probe(vdev->vbasedev.name);
196
}
197
198
-#define IGD_ASLS 0xfc /* ASL Storage Register */
199
-
200
-/*
201
- * The OpRegion includes the Video BIOS Table, which seems important for
202
- * telling the driver what sort of outputs it has. Without this, the device
203
- * may work in the guest, but we may not get output. This also requires BIOS
204
- * support to reserve and populate a section of guest memory sufficient for
205
- * the table and to write the base address of that memory to the ASLS register
206
- * of the IGD device.
207
- */
208
-bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
209
- struct vfio_region_info *info, Error **errp)
210
-{
211
- int ret;
212
-
213
- vdev->igd_opregion = g_malloc0(info->size);
214
- ret = pread(vdev->vbasedev.fd, vdev->igd_opregion,
215
- info->size, info->offset);
216
- if (ret != info->size) {
217
- error_setg(errp, "failed to read IGD OpRegion");
218
- g_free(vdev->igd_opregion);
219
- vdev->igd_opregion = NULL;
220
- return false;
221
- }
222
-
223
- /*
224
- * Provide fw_cfg with a copy of the OpRegion which the VM firmware is to
225
- * allocate 32bit reserved memory for, copy these contents into, and write
226
- * the reserved memory base address to the device ASLS register at 0xFC.
227
- * Alignment of this reserved region seems flexible, but using a 4k page
228
- * alignment seems to work well. This interface assumes a single IGD
229
- * device, which may be at VM address 00:02.0 in legacy mode or another
230
- * address in UPT mode.
231
- *
232
- * NB, there may be future use cases discovered where the VM should have
233
- * direct interaction with the host OpRegion, in which case the write to
234
- * the ASLS register would trigger MemoryRegion setup to enable that.
235
- */
236
- fw_cfg_add_file(fw_cfg_find(), "etc/igd-opregion",
237
- vdev->igd_opregion, info->size);
238
-
239
- trace_vfio_pci_igd_opregion_enabled(vdev->vbasedev.name);
240
-
241
- pci_set_long(vdev->pdev.config + IGD_ASLS, 0);
242
- pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
243
- pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
244
-
245
- return true;
246
-}
247
-
248
/*
249
* Common quirk probe entry points.
250
*/
251
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
252
index XXXXXXX..XXXXXXX 100644
253
--- a/hw/vfio/pci.c
254
+++ b/hw/vfio/pci.c
255
@@ -XXX,XX +XXX,XX @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
256
vfio_bar_quirk_setup(vdev, i);
257
}
258
259
+#ifdef CONFIG_VFIO_IGD
260
if (!vdev->igd_opregion &&
261
vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
262
- g_autofree struct vfio_region_info *opregion = NULL;
263
-
264
- if (vdev->pdev.qdev.hotplugged) {
265
- error_setg(errp,
266
- "cannot support IGD OpRegion feature on hotplugged "
267
- "device");
268
- goto out_unset_idev;
269
- }
270
-
271
- ret = vfio_get_dev_region_info(vbasedev,
272
- VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
273
- VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);
274
- if (ret) {
275
- error_setg_errno(errp, -ret,
276
- "does not support requested IGD OpRegion feature");
277
- goto out_unset_idev;
278
- }
279
-
280
- if (!vfio_pci_igd_opregion_init(vdev, opregion, errp)) {
281
+ if (!vfio_pci_igd_setup_opregion(vdev, errp)) {
282
goto out_unset_idev;
283
}
284
}
285
+#endif
286
287
/* QEMU emulates all of MSI & MSIX */
288
if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {
64
--
289
--
65
2.48.1
290
2.48.1
66
291
67
292
diff view generated by jsdifflib
1
Currently, the mapping handlers of the IOMMU backends, VFIO IOMMU Type
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
1 aka. legacy and IOMMUFD, return an errno and also report an error.
3
This can lead to excessive log messages at runtime for recurring DMA
4
mapping errors. Since these errors are already reported by the callers
5
in the vfio_container_dma_un/map() routines, simply remove them and
6
allow the callers to handle the reporting.
7
2
8
The mapping handler of the IOMMUFD backend has a comment suggesting
3
A new option will soon be introduced to decouple the LPC bridge/Host
9
MMIO region mapping failures return EFAULT. I am not sure this is
4
bridge ID quirk from legacy mode. To prepare for this, move the LPC
10
entirely true, so keep the EFAULT case until the conditions are
5
bridge initialization into a separate function.
11
clarified.
12
6
7
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
13
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
8
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
14
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-7-clg@redhat.com
9
Tested-by: Alex Williamson <alex.williamson@redhat.com>
10
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
11
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-5-tomitamoeko@gmail.com
15
Signed-off-by: Cédric Le Goater <clg@redhat.com>
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
16
---
13
---
17
backends/iommufd.c | 3 ---
14
hw/vfio/igd.c | 122 +++++++++++++++++++++++++++++---------------------
18
hw/vfio/container.c | 2 --
15
1 file changed, 70 insertions(+), 52 deletions(-)
19
2 files changed, 5 deletions(-)
20
16
21
diff --git a/backends/iommufd.c b/backends/iommufd.c
17
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/backends/iommufd.c
19
--- a/hw/vfio/igd.c
24
+++ b/backends/iommufd.c
20
+++ b/hw/vfio/igd.c
25
@@ -XXX,XX +XXX,XX @@ int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
21
@@ -XXX,XX +XXX,XX @@ static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
26
/* TODO: Not support mapping hardware PCI BAR region for now. */
27
if (errno == EFAULT) {
28
warn_report("IOMMU_IOAS_MAP failed: %m, PCI BAR?");
29
- } else {
30
- error_report("IOMMU_IOAS_MAP failed: %m");
31
}
32
}
33
return ret;
34
@@ -XXX,XX +XXX,XX @@ int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
35
36
if (ret) {
37
ret = -errno;
38
- error_report("IOMMU_IOAS_UNMAP failed: %m");
39
}
40
return ret;
22
return ret;
41
}
23
}
42
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
24
43
index XXXXXXX..XXXXXXX 100644
25
+static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp)
44
--- a/hw/vfio/container.c
26
+{
45
+++ b/hw/vfio/container.c
27
+ g_autofree struct vfio_region_info *host = NULL;
46
@@ -XXX,XX +XXX,XX @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer,
28
+ g_autofree struct vfio_region_info *lpc = NULL;
47
unmap.size -= 1ULL << ctz64(bcontainer->pgsizes);
29
+ PCIDevice *lpc_bridge;
48
continue;
30
+ int ret;
49
}
31
+
50
- error_report("VFIO_UNMAP_DMA failed: %s", strerror(errno));
32
+ /*
51
return -errno;
33
+ * Copying IDs or creating new devices are not supported on hotplug
34
+ */
35
+ if (vdev->pdev.qdev.hotplugged) {
36
+ error_setg(errp, "IGD LPC is not supported on hotplugged device");
37
+ return false;
38
+ }
39
+
40
+ /*
41
+ * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that we
42
+ * can stuff host values into, so if there's already one there and it's not
43
+ * one we can hack on, this quirk is no-go. Sorry Q35.
44
+ */
45
+ lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
46
+ 0, PCI_DEVFN(0x1f, 0));
47
+ if (lpc_bridge && !object_dynamic_cast(OBJECT(lpc_bridge),
48
+ "vfio-pci-igd-lpc-bridge")) {
49
+ error_setg(errp,
50
+ "Cannot create LPC bridge due to existing device at 1f.0");
51
+ return false;
52
+ }
53
+
54
+ /*
55
+ * Check whether we have all the vfio device specific regions to
56
+ * support LPC quirk (added in Linux v4.6).
57
+ */
58
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
59
+ VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
60
+ VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG, &lpc);
61
+ if (ret) {
62
+ error_setg(errp, "IGD LPC bridge access is not supported by kernel");
63
+ return false;
64
+ }
65
+
66
+ ret = vfio_get_dev_region_info(&vdev->vbasedev,
67
+ VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
68
+ VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host);
69
+ if (ret) {
70
+ error_setg(errp, "IGD host bridge access is not supported by kernel");
71
+ return false;
72
+ }
73
+
74
+ /* Create/modify LPC bridge */
75
+ ret = vfio_pci_igd_lpc_init(vdev, lpc);
76
+ if (ret) {
77
+ error_setg(errp, "Failed to create/modify LPC bridge for IGD");
78
+ return false;
79
+ }
80
+
81
+ /* Stuff some host values into the VM PCI host bridge */
82
+ ret = vfio_pci_igd_host_init(vdev, host);
83
+ if (ret) {
84
+ error_setg(errp, "Failed to modify host bridge for IGD");
85
+ return false;
86
+ }
87
+
88
+ return true;
89
+}
90
+
91
#define IGD_GGC_MMIO_OFFSET 0x108040
92
#define IGD_BDSM_MMIO_OFFSET 0x1080C0
93
94
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
95
void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
96
{
97
g_autofree struct vfio_region_info *rom = NULL;
98
- g_autofree struct vfio_region_info *host = NULL;
99
- g_autofree struct vfio_region_info *lpc = NULL;
100
- PCIDevice *lpc_bridge;
101
int ret, gen;
102
uint64_t gms_size;
103
uint64_t *bdsm_size;
104
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
105
return;
52
}
106
}
53
107
54
@@ -XXX,XX +XXX,XX @@ static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
108
- /*
55
return 0;
109
- * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that we
110
- * can stuff host values into, so if there's already one there and it's not
111
- * one we can hack on, legacy mode is no-go. Sorry Q35.
112
- */
113
- lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev),
114
- 0, PCI_DEVFN(0x1f, 0));
115
- if (lpc_bridge && !object_dynamic_cast(OBJECT(lpc_bridge),
116
- "vfio-pci-igd-lpc-bridge")) {
117
- error_report("IGD device %s cannot support legacy mode due to existing "
118
- "devices at address 1f.0", vdev->vbasedev.name);
119
- return;
120
- }
121
-
122
/*
123
* IGD is not a standard, they like to change their specs often. We
124
* only attempt to support back to SandBridge and we hope that newer
125
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
126
return;
56
}
127
}
57
128
58
- error_report("VFIO_MAP_DMA failed: %s", strerror(errno));
129
- /*
59
return -errno;
130
- * Check whether we have all the vfio device specific regions to
60
}
131
- * support legacy mode (added in Linux v4.6). If not, bail.
132
- */
133
- ret = vfio_get_dev_region_info(&vdev->vbasedev,
134
- VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
135
- VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host);
136
- if (ret) {
137
- error_report("IGD device %s does not support host bridge access,"
138
- "legacy mode disabled", vdev->vbasedev.name);
139
- return;
140
- }
141
-
142
- ret = vfio_get_dev_region_info(&vdev->vbasedev,
143
- VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,
144
- VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG, &lpc);
145
- if (ret) {
146
- error_report("IGD device %s does not support LPC bridge access,"
147
- "legacy mode disabled", vdev->vbasedev.name);
148
- return;
149
- }
150
-
151
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
152
153
/*
154
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
155
return;
156
}
157
158
- /* Create our LPC/ISA bridge */
159
- ret = vfio_pci_igd_lpc_init(vdev, lpc);
160
- if (ret) {
161
- error_report("IGD device %s failed to create LPC bridge, "
162
- "legacy mode disabled", vdev->vbasedev.name);
163
- return;
164
- }
165
-
166
- /* Stuff some host values into the VM PCI host bridge */
167
- ret = vfio_pci_igd_host_init(vdev, host);
168
- if (ret) {
169
- error_report("IGD device %s failed to modify host bridge, "
170
- "legacy mode disabled", vdev->vbasedev.name);
171
+ /* Setup LPC bridge / Host bridge PCI IDs */
172
+ if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
173
+ error_append_hint(&err, "IGD legacy mode disabled\n");
174
+ error_report_err(err);
175
return;
176
}
61
177
62
--
178
--
63
2.48.1
179
2.48.1
64
180
65
181
diff view generated by jsdifflib
1
From: Tomita Moeko <tomitamoeko@gmail.com>
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
2
3
Device may only expose a specific portion of PCI config space through a
3
IGD devices require device-specific quirk to be applied to their PCI
4
region in a BAR, such behavior is seen in igd GGC and BDSM mirrors in
4
config space. Currently, it is put in the BAR4 quirk that does nothing
5
BAR0. To handle these, config_offset is introduced to allow mirroring
5
to BAR4 itself. Add a placeholder for PCI config space quirks to hold
6
arbitrary region in PCI config space.
6
that quirk later.
7
7
8
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
8
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
9
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
9
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
10
Link: https://lore.kernel.org/r/20250104154219.7209-3-tomitamoeko@gmail.com
10
Tested-by: Alex Williamson <alex.williamson@redhat.com>
11
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
12
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-6-tomitamoeko@gmail.com
11
Signed-off-by: Cédric Le Goater <clg@redhat.com>
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
12
---
14
---
13
hw/vfio/pci-quirks.h | 3 ++-
15
hw/vfio/pci.h | 1 +
14
hw/vfio/pci-quirks.c | 2 ++
16
hw/vfio/pci-quirks.c | 5 +++++
15
2 files changed, 4 insertions(+), 1 deletion(-)
17
hw/vfio/pci.c | 4 ++++
18
3 files changed, 10 insertions(+)
16
19
17
diff --git a/hw/vfio/pci-quirks.h b/hw/vfio/pci-quirks.h
20
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/vfio/pci-quirks.h
22
--- a/hw/vfio/pci.h
20
+++ b/hw/vfio/pci-quirks.h
23
+++ b/hw/vfio/pci.h
21
@@ -XXX,XX +XXX,XX @@ extern const MemoryRegionOps vfio_generic_window_data_quirk;
24
@@ -XXX,XX +XXX,XX @@ uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size);
22
*/
25
void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size);
23
typedef struct VFIOConfigMirrorQuirk {
26
24
struct VFIOPCIDevice *vdev;
27
bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev);
25
- uint32_t offset;
28
+bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp);
26
+ uint32_t offset; /* Offset in BAR */
29
void vfio_vga_quirk_setup(VFIOPCIDevice *vdev);
27
+ uint32_t config_offset; /* Offset in PCI config space */
30
void vfio_vga_quirk_exit(VFIOPCIDevice *vdev);
28
uint8_t bar;
31
void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev);
29
MemoryRegion *mem;
30
uint8_t data[];
31
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
32
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
32
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/vfio/pci-quirks.c
34
--- a/hw/vfio/pci-quirks.c
34
+++ b/hw/vfio/pci-quirks.c
35
+++ b/hw/vfio/pci-quirks.c
35
@@ -XXX,XX +XXX,XX @@ static uint64_t vfio_generic_quirk_mirror_read(void *opaque,
36
@@ -XXX,XX +XXX,XX @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice *vdev, int nr)
36
(void)vfio_region_read(&vdev->bars[mirror->bar].region,
37
/*
37
addr + mirror->offset, size);
38
* Common quirk probe entry points.
38
39
*/
39
+ addr += mirror->config_offset;
40
+bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp)
40
data = vfio_pci_read_config(&vdev->pdev, addr, size);
41
+{
41
trace_vfio_quirk_generic_mirror_read(vdev->vbasedev.name,
42
+ return true;
42
memory_region_name(mirror->mem),
43
+}
43
@@ -XXX,XX +XXX,XX @@ static void vfio_generic_quirk_mirror_write(void *opaque, hwaddr addr,
44
+
44
VFIOConfigMirrorQuirk *mirror = opaque;
45
void vfio_vga_quirk_setup(VFIOPCIDevice *vdev)
45
VFIOPCIDevice *vdev = mirror->vdev;
46
{
46
47
vfio_vga_probe_ati_3c3_quirk(vdev);
47
+ addr += mirror->config_offset;
48
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
48
vfio_pci_write_config(&vdev->pdev, addr, data, size);
49
index XXXXXXX..XXXXXXX 100644
49
trace_vfio_quirk_generic_mirror_write(vdev->vbasedev.name,
50
--- a/hw/vfio/pci.c
50
memory_region_name(mirror->mem),
51
+++ b/hw/vfio/pci.c
52
@@ -XXX,XX +XXX,XX @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
53
goto out_unset_idev;
54
}
55
56
+ if (!vfio_config_quirk_setup(vdev, errp)) {
57
+ goto out_unset_idev;
58
+ }
59
+
60
if (vdev->vga) {
61
vfio_vga_quirk_setup(vdev);
62
}
51
--
63
--
52
2.48.1
64
2.48.1
53
65
54
66
diff view generated by jsdifflib
1
From: Tomita Moeko <tomitamoeko@gmail.com>
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
2
3
Declare generic vfio_generic_{window_address,window_data,mirror}_quirk
3
The actual IO BAR4 write quirk in vfio_probe_igd_bar4_quirk was removed
4
in newly created pci_quirks.h so that they can be used elsewhere, like
4
in previous change, leaving the function not matching its name, so move
5
igd.c.
5
it into the newly introduced vfio_config_quirk_setup. There is no
6
functional change in this commit.
7
8
For now, to align with current legacy mode behavior, it returns and
9
proceeds on error. Later it will fail on error after decoupling the
10
quirks from legacy mode.
6
11
7
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
12
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
8
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
13
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
9
Link: https://lore.kernel.org/r/20250104154219.7209-2-tomitamoeko@gmail.com
14
Tested-by: Alex Williamson <alex.williamson@redhat.com>
15
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
16
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-7-tomitamoeko@gmail.com
10
Signed-off-by: Cédric Le Goater <clg@redhat.com>
17
Signed-off-by: Cédric Le Goater <clg@redhat.com>
11
---
18
---
12
hw/vfio/pci-quirks.h | 71 ++++++++++++++++++++++++++++++++++++++++++++
19
hw/vfio/pci.h | 2 +-
13
hw/vfio/pci-quirks.c | 55 +++-------------------------------
20
hw/vfio/igd.c | 21 ++++++++++++---------
14
2 files changed, 75 insertions(+), 51 deletions(-)
21
hw/vfio/pci-quirks.c | 6 +++++-
15
create mode 100644 hw/vfio/pci-quirks.h
22
3 files changed, 18 insertions(+), 11 deletions(-)
16
23
17
diff --git a/hw/vfio/pci-quirks.h b/hw/vfio/pci-quirks.h
24
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
18
new file mode 100644
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX
26
--- a/hw/vfio/pci.h
20
--- /dev/null
27
+++ b/hw/vfio/pci.h
21
+++ b/hw/vfio/pci-quirks.h
28
@@ -XXX,XX +XXX,XX @@ bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
22
@@ -XXX,XX +XXX,XX @@
29
void vfio_quirk_reset(VFIOPCIDevice *vdev);
23
+/*
30
VFIOQuirk *vfio_quirk_alloc(int nr_mem);
24
+ * vfio generic region quirks (mostly backdoors to PCI config space)
31
void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr);
25
+ *
32
-void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);
26
+ * Copyright Red Hat, Inc. 2012-2015
33
+bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp);
27
+ *
34
28
+ * Authors:
35
extern const PropertyInfo qdev_prop_nv_gpudirect_clique;
29
+ * Alex Williamson <alex.williamson@redhat.com>
36
30
+ *
37
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
31
+ * This work is licensed under the terms of the GNU GPL, version 2. See
38
index XXXXXXX..XXXXXXX 100644
32
+ * the COPYING file in the top-level directory.
39
--- a/hw/vfio/igd.c
33
+ */
40
+++ b/hw/vfio/igd.c
34
+#ifndef HW_VFIO_VFIO_PCI_QUIRKS_H
41
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
35
+#define HW_VFIO_VFIO_PCI_QUIRKS_H
42
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
43
}
44
45
-void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
46
+bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
47
+ Error **errp G_GNUC_UNUSED)
48
{
49
g_autofree struct vfio_region_info *rom = NULL;
50
int ret, gen;
51
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
52
* PCI bus address.
53
*/
54
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
55
- !vfio_is_vga(vdev) || nr != 4 ||
56
+ !vfio_is_vga(vdev) ||
57
&vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
58
0, PCI_DEVFN(0x2, 0))) {
59
- return;
60
+ return true;
61
}
62
63
/*
64
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
65
if (gen == -1) {
66
error_report("IGD device %s is unsupported in legacy mode, "
67
"try SandyBridge or newer", vdev->vbasedev.name);
68
- return;
69
+ return true;
70
}
71
72
/*
73
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
74
if ((ret || !rom->size) && !vdev->pdev.romfile) {
75
error_report("IGD device %s has no ROM, legacy mode disabled",
76
vdev->vbasedev.name);
77
- return;
78
+ return true;
79
}
80
81
/*
82
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
83
error_report("IGD device %s hotplugged, ROM disabled, "
84
"legacy mode disabled", vdev->vbasedev.name);
85
vdev->rom_read_failed = true;
86
- return;
87
+ return true;
88
}
89
90
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
91
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
92
error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
93
error_report("IGD device %s failed to enable VGA access, "
94
"legacy mode disabled", vdev->vbasedev.name);
95
- return;
96
+ return true;
97
}
98
99
/* Setup OpRegion access */
100
if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
101
error_append_hint(&err, "IGD legacy mode disabled\n");
102
error_report_err(err);
103
- return;
104
+ return true;
105
}
106
107
/* Setup LPC bridge / Host bridge PCI IDs */
108
if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
109
error_append_hint(&err, "IGD legacy mode disabled\n");
110
error_report_err(err);
111
- return;
112
+ return true;
113
}
114
115
/*
116
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
117
}
118
119
trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, (gms_size / MiB));
36
+
120
+
37
+#include "qemu/osdep.h"
121
+ return true;
38
+#include "exec/memop.h"
122
}
39
+
40
+/*
41
+ * The generic window quirks operate on an address and data register,
42
+ * vfio_generic_window_address_quirk handles the address register and
43
+ * vfio_generic_window_data_quirk handles the data register. These ops
44
+ * pass reads and writes through to hardware until a value matching the
45
+ * stored address match/mask is written. When this occurs, the data
46
+ * register access emulated PCI config space for the device rather than
47
+ * passing through accesses. This enables devices where PCI config space
48
+ * is accessible behind a window register to maintain the virtualization
49
+ * provided through vfio.
50
+ */
51
+typedef struct VFIOConfigWindowMatch {
52
+ uint32_t match;
53
+ uint32_t mask;
54
+} VFIOConfigWindowMatch;
55
+
56
+typedef struct VFIOConfigWindowQuirk {
57
+ struct VFIOPCIDevice *vdev;
58
+
59
+ uint32_t address_val;
60
+
61
+ uint32_t address_offset;
62
+ uint32_t data_offset;
63
+
64
+ bool window_enabled;
65
+ uint8_t bar;
66
+
67
+ MemoryRegion *addr_mem;
68
+ MemoryRegion *data_mem;
69
+
70
+ uint32_t nr_matches;
71
+ VFIOConfigWindowMatch matches[];
72
+} VFIOConfigWindowQuirk;
73
+
74
+extern const MemoryRegionOps vfio_generic_window_address_quirk;
75
+extern const MemoryRegionOps vfio_generic_window_data_quirk;
76
+
77
+/*
78
+ * The generic mirror quirk handles devices which expose PCI config space
79
+ * through a region within a BAR. When enabled, reads and writes are
80
+ * redirected through to emulated PCI config space. XXX if PCI config space
81
+ * used memory regions, this could just be an alias.
82
+ */
83
+typedef struct VFIOConfigMirrorQuirk {
84
+ struct VFIOPCIDevice *vdev;
85
+ uint32_t offset;
86
+ uint8_t bar;
87
+ MemoryRegion *mem;
88
+ uint8_t data[];
89
+} VFIOConfigMirrorQuirk;
90
+
91
+extern const MemoryRegionOps vfio_generic_mirror_quirk;
92
+
93
+#endif /* HW_VFIO_VFIO_PCI_QUIRKS_H */
94
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
123
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
95
index XXXXXXX..XXXXXXX 100644
124
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/vfio/pci-quirks.c
125
--- a/hw/vfio/pci-quirks.c
97
+++ b/hw/vfio/pci-quirks.c
126
+++ b/hw/vfio/pci-quirks.c
98
@@ -XXX,XX +XXX,XX @@
127
@@ -XXX,XX +XXX,XX @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice *vdev, int nr)
99
#include "hw/nvram/fw_cfg.h"
100
#include "hw/qdev-properties.h"
101
#include "pci.h"
102
+#include "pci-quirks.h"
103
#include "trace.h"
104
105
/*
106
@@ -XXX,XX +XXX,XX @@ bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev)
107
* Device specific region quirks (mostly backdoors to PCI config space)
108
*/
128
*/
109
129
bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp)
110
-/*
130
{
111
- * The generic window quirks operate on an address and data register,
131
+#ifdef CONFIG_VFIO_IGD
112
- * vfio_generic_window_address_quirk handles the address register and
132
+ if (!vfio_probe_igd_config_quirk(vdev, errp)) {
113
- * vfio_generic_window_data_quirk handles the data register. These ops
133
+ return false;
114
- * pass reads and writes through to hardware until a value matching the
134
+ }
115
- * stored address match/mask is written. When this occurs, the data
135
+#endif
116
- * register access emulated PCI config space for the device rather than
136
return true;
117
- * passing through accesses. This enables devices where PCI config space
118
- * is accessible behind a window register to maintain the virtualization
119
- * provided through vfio.
120
- */
121
-typedef struct VFIOConfigWindowMatch {
122
- uint32_t match;
123
- uint32_t mask;
124
-} VFIOConfigWindowMatch;
125
-
126
-typedef struct VFIOConfigWindowQuirk {
127
- struct VFIOPCIDevice *vdev;
128
-
129
- uint32_t address_val;
130
-
131
- uint32_t address_offset;
132
- uint32_t data_offset;
133
-
134
- bool window_enabled;
135
- uint8_t bar;
136
-
137
- MemoryRegion *addr_mem;
138
- MemoryRegion *data_mem;
139
-
140
- uint32_t nr_matches;
141
- VFIOConfigWindowMatch matches[];
142
-} VFIOConfigWindowQuirk;
143
-
144
static uint64_t vfio_generic_window_quirk_address_read(void *opaque,
145
hwaddr addr,
146
unsigned size)
147
@@ -XXX,XX +XXX,XX @@ static void vfio_generic_window_quirk_address_write(void *opaque, hwaddr addr,
148
}
149
}
137
}
150
138
151
-static const MemoryRegionOps vfio_generic_window_address_quirk = {
139
@@ -XXX,XX +XXX,XX @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
152
+const MemoryRegionOps vfio_generic_window_address_quirk = {
140
vfio_probe_rtl8168_bar2_quirk(vdev, nr);
153
.read = vfio_generic_window_quirk_address_read,
141
#ifdef CONFIG_VFIO_IGD
154
.write = vfio_generic_window_quirk_address_write,
142
vfio_probe_igd_bar0_quirk(vdev, nr);
155
.endianness = DEVICE_LITTLE_ENDIAN,
143
- vfio_probe_igd_bar4_quirk(vdev, nr);
156
@@ -XXX,XX +XXX,XX @@ static void vfio_generic_window_quirk_data_write(void *opaque, hwaddr addr,
144
#endif
157
addr + window->data_offset, data, size);
158
}
145
}
159
146
160
-static const MemoryRegionOps vfio_generic_window_data_quirk = {
161
+const MemoryRegionOps vfio_generic_window_data_quirk = {
162
.read = vfio_generic_window_quirk_data_read,
163
.write = vfio_generic_window_quirk_data_write,
164
.endianness = DEVICE_LITTLE_ENDIAN,
165
};
166
167
-/*
168
- * The generic mirror quirk handles devices which expose PCI config space
169
- * through a region within a BAR. When enabled, reads and writes are
170
- * redirected through to emulated PCI config space. XXX if PCI config space
171
- * used memory regions, this could just be an alias.
172
- */
173
-typedef struct VFIOConfigMirrorQuirk {
174
- struct VFIOPCIDevice *vdev;
175
- uint32_t offset;
176
- uint8_t bar;
177
- MemoryRegion *mem;
178
- uint8_t data[];
179
-} VFIOConfigMirrorQuirk;
180
-
181
static uint64_t vfio_generic_quirk_mirror_read(void *opaque,
182
hwaddr addr, unsigned size)
183
{
184
@@ -XXX,XX +XXX,XX @@ static void vfio_generic_quirk_mirror_write(void *opaque, hwaddr addr,
185
addr, data);
186
}
187
188
-static const MemoryRegionOps vfio_generic_mirror_quirk = {
189
+const MemoryRegionOps vfio_generic_mirror_quirk = {
190
.read = vfio_generic_quirk_mirror_read,
191
.write = vfio_generic_quirk_mirror_write,
192
.endianness = DEVICE_LITTLE_ENDIAN,
193
--
147
--
194
2.48.1
148
2.48.1
195
149
196
150
diff view generated by jsdifflib
1
For pseries machines, commit 567b5b309abe ("vfio/pci: Relax DMA map
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
errors for MMIO regions") introduced 2 error reports to notify the
2
3
user of MMIO mapping errors. Consolidate both code paths under one.
3
So far, IGD-specific quirks all require enabling legacy mode, which is
4
4
toggled by assigning IGD to 00:02.0. However, some quirks, like the BDSM
5
Cc: Harsh Prateek Bora <harshpb@linux.ibm.com>
5
and GGC register quirks, should be applied to all supported IGD devices.
6
Cc: Shivaprasad G Bhat <sbhat@linux.ibm.com>
6
A new config option, x-igd-legacy-mode=[on|off|auto], is introduced to
7
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
7
control the legacy mode only quirks. The default value is "auto", which
8
keeps current behavior that enables legacy mode implicitly and continues
9
on error when all following conditions are met.
10
* Machine type is i440fx
11
* IGD device is at guest BDF 00:02.0
12
13
If any one of the conditions above is not met, the default behavior is
14
equivalent to "off", QEMU will fail immediately if any error occurs.
15
16
Users can also use "on" to force enabling legacy mode. It checks if all
17
the conditions above are met and set up legacy mode. QEMU will also fail
18
immediately on error in this case.
19
20
Additionally, the hotplug check in legacy mode is removed as hotplugging
21
IGD device is never supported, and it will be checked when enabling the
22
OpRegion quirk.
23
24
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
8
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
25
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
9
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-8-clg@redhat.com
26
Tested-by: Alex Williamson <alex.williamson@redhat.com>
27
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
28
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-8-tomitamoeko@gmail.com
29
[ clg: - Changed warn_report() by info_report() in
30
vfio_probe_igd_config_quirk() as suggested by Alex W.
31
- Fixed spelling in vfio_probe_igd_config_quirk () ]
10
Signed-off-by: Cédric Le Goater <clg@redhat.com>
32
Signed-off-by: Cédric Le Goater <clg@redhat.com>
11
---
33
---
12
hw/vfio/common.c | 10 ++++------
34
hw/vfio/pci.h | 1 +
13
1 file changed, 4 insertions(+), 6 deletions(-)
35
hw/vfio/igd.c | 127 +++++++++++++++++++++++++++++---------------------
14
36
hw/vfio/pci.c | 2 +
15
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
37
3 files changed, 77 insertions(+), 53 deletions(-)
38
39
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
16
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/vfio/common.c
41
--- a/hw/vfio/pci.h
18
+++ b/hw/vfio/common.c
42
+++ b/hw/vfio/pci.h
19
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
43
@@ -XXX,XX +XXX,XX @@ struct VFIOPCIDevice {
44
uint32_t display_xres;
45
uint32_t display_yres;
46
int32_t bootindex;
47
+ OnOffAuto igd_legacy_mode;
48
uint32_t igd_gms;
49
OffAutoPCIBAR msix_relo;
50
uint8_t nv_gpudirect_clique;
51
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/vfio/igd.c
54
+++ b/hw/vfio/igd.c
55
@@ -XXX,XX +XXX,XX @@
56
#include "qemu/error-report.h"
57
#include "qapi/error.h"
58
#include "qapi/qmp/qerror.h"
59
+#include "hw/boards.h"
60
#include "hw/hw.h"
61
#include "hw/nvram/fw_cfg.h"
62
#include "pci.h"
63
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
64
* bus address.
65
*/
66
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
67
- !vfio_is_vga(vdev) || nr != 0 ||
68
- &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
69
- 0, PCI_DEVFN(0x2, 0))) {
70
+ !vfio_is_vga(vdev) || nr != 0) {
20
return;
71
return;
21
}
72
}
22
73
23
+ /* PPC64/pseries machine only */
74
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
24
if (!vfio_container_add_section_window(bcontainer, section, &err)) {
75
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
25
- goto fail;
76
}
26
+ goto mmio_dma_error;
77
27
}
78
-bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
28
79
- Error **errp G_GNUC_UNUSED)
29
memory_region_ref(section->mr);
80
+bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
81
{
31
"0x%"HWADDR_PRIx", %p) = %d (%s)",
82
- g_autofree struct vfio_region_info *rom = NULL;
32
bcontainer, iova, int128_get64(llsize), vaddr, ret,
83
int ret, gen;
33
strerror(-ret));
84
uint64_t gms_size;
34
+ mmio_dma_error:
85
uint64_t *bdsm_size;
35
if (memory_region_is_ram_device(section->mr)) {
86
uint32_t gmch;
36
/* Allow unexpected mappings not to be fatal for RAM devices */
87
+ bool legacy_mode_enabled = false;
37
VFIODevice *vbasedev =
88
Error *err = NULL;
38
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
89
39
return;
90
/*
40
91
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
41
fail:
92
* PCI bus address.
42
- if (memory_region_is_ram_device(section->mr)) {
93
*/
43
- error_reportf_err(err, "PCI p2p may not work: ");
94
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
44
- return;
95
- !vfio_is_vga(vdev) ||
96
- &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
97
- 0, PCI_DEVFN(0x2, 0))) {
98
+ !vfio_is_vga(vdev)) {
99
return true;
100
}
101
102
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
103
return true;
104
}
105
106
- /*
107
- * Most of what we're doing here is to enable the ROM to run, so if
108
- * there's no ROM, there's no point in setting up this quirk.
109
- * NB. We only seem to get BIOS ROMs, so a UEFI VM would need CSM support.
110
- */
111
- ret = vfio_get_region_info(&vdev->vbasedev,
112
- VFIO_PCI_ROM_REGION_INDEX, &rom);
113
- if ((ret || !rom->size) && !vdev->pdev.romfile) {
114
- error_report("IGD device %s has no ROM, legacy mode disabled",
115
- vdev->vbasedev.name);
116
- return true;
45
- }
117
- }
46
-
118
-
47
if (!bcontainer->initialized) {
119
- /*
48
/*
120
- * Ignore the hotplug corner case, mark the ROM failed, we can't
49
* At machine init time or when the device is attached to the
121
- * create the devices we need for legacy mode in the hotplug scenario.
50
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_del(MemoryListener *listener,
122
- */
51
123
- if (vdev->pdev.qdev.hotplugged) {
52
memory_region_unref(section->mr);
124
- error_report("IGD device %s hotplugged, ROM disabled, "
53
125
- "legacy mode disabled", vdev->vbasedev.name);
54
+ /* PPC64/pseries machine only */
126
- vdev->rom_read_failed = true;
55
vfio_container_del_section_window(bcontainer, section);
127
- return true;
128
- }
129
-
130
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
131
132
/*
133
- * If IGD VGA Disable is clear (expected) and VGA is not already enabled,
134
- * try to enable it. Probably shouldn't be using legacy mode without VGA,
135
- * but also no point in us enabling VGA if disabled in hardware.
136
+ * For backward compatibility, enable legacy mode when
137
+ * - Machine type is i440fx (pc_piix)
138
+ * - IGD device is at guest BDF 00:02.0
139
+ * - Not manually disabled by x-igd-legacy-mode=off
140
*/
141
- if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, &err)) {
142
- error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
143
- error_report("IGD device %s failed to enable VGA access, "
144
- "legacy mode disabled", vdev->vbasedev.name);
145
- return true;
146
- }
147
+ if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) &&
148
+ !strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") &&
149
+ (&vdev->pdev == pci_find_device(pci_device_root_bus(&vdev->pdev),
150
+ 0, PCI_DEVFN(0x2, 0)))) {
151
+ /*
152
+ * IGD legacy mode requires:
153
+ * - VBIOS in ROM BAR or file
154
+ * - VGA IO/MMIO ranges are claimed by IGD
155
+ * - OpRegion
156
+ * - Same LPC bridge and Host bridge VID/DID/SVID/SSID as host
157
+ */
158
+ g_autofree struct vfio_region_info *rom = NULL;
159
+
160
+ legacy_mode_enabled = true;
161
+ info_report("IGD legacy mode enabled, "
162
+ "use x-igd-legacy-mode=off to disable it if unwanted.");
163
+
164
+ /*
165
+ * Most of what we're doing here is to enable the ROM to run, so if
166
+ * there's no ROM, there's no point in setting up this quirk.
167
+ * NB. We only seem to get BIOS ROMs, so UEFI VM would need CSM support.
168
+ */
169
+ ret = vfio_get_region_info(&vdev->vbasedev,
170
+ VFIO_PCI_ROM_REGION_INDEX, &rom);
171
+ if ((ret || !rom->size) && !vdev->pdev.romfile) {
172
+ error_setg(&err, "Device has no ROM");
173
+ goto error;
174
+ }
175
176
- /* Setup OpRegion access */
177
- if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
178
- error_append_hint(&err, "IGD legacy mode disabled\n");
179
- error_report_err(err);
180
- return true;
181
- }
182
+ /*
183
+ * If IGD VGA Disable is clear (expected) and VGA is not already
184
+ * enabled, try to enable it. Probably shouldn't be using legacy mode
185
+ * without VGA, but also no point in us enabling VGA if disabled in
186
+ * hardware.
187
+ */
188
+ if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, &err)) {
189
+ error_setg(&err, "Unable to enable VGA access");
190
+ goto error;
191
+ }
192
193
- /* Setup LPC bridge / Host bridge PCI IDs */
194
- if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
195
- error_append_hint(&err, "IGD legacy mode disabled\n");
196
- error_report_err(err);
197
- return true;
198
+ /* Setup OpRegion access */
199
+ if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
200
+ goto error;
201
+ }
202
+
203
+ /* Setup LPC bridge / Host bridge PCI IDs */
204
+ if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
205
+ goto error;
206
+ }
207
+ } else if (vdev->igd_legacy_mode == ON_OFF_AUTO_ON) {
208
+ error_setg(&err,
209
+ "Machine is not i440fx or assigned BDF is not 00:02.0");
210
+ goto error;
211
}
212
213
/*
214
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
215
trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, (gms_size / MiB));
216
217
return true;
218
+
219
+error:
220
+ /*
221
+ * When legacy mode is implicity enabled, continue on error,
222
+ * to keep compatibility
223
+ */
224
+ if (legacy_mode_enabled && (vdev->igd_legacy_mode == ON_OFF_AUTO_AUTO)) {
225
+ error_report_err(err);
226
+ error_report("IGD legacy mode disabled");
227
+ return true;
228
+ }
229
+
230
+ error_propagate(errp, err);
231
+ return false;
56
}
232
}
57
233
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/hw/vfio/pci.c
236
+++ b/hw/vfio/pci.c
237
@@ -XXX,XX +XXX,XX @@ static const Property vfio_pci_dev_properties[] = {
238
VFIO_FEATURE_ENABLE_REQ_BIT, true),
239
DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
240
VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
241
+ DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
242
+ igd_legacy_mode, ON_OFF_AUTO_AUTO),
243
DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
244
vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
245
DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
58
--
246
--
59
2.48.1
247
2.48.1
60
248
61
249
diff view generated by jsdifflib
New patch
1
From: Tomita Moeko <tomitamoeko@gmail.com>
1
2
3
Both enable OpRegion option (x-igd-opregion) and legacy mode require
4
setting up OpRegion copy for IGD devices. As the config quirk no longer
5
depends on legacy mode, we can now handle x-igd-opregion option there
6
instead of in vfio_realize.
7
8
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
9
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
10
Tested-by: Alex Williamson <alex.williamson@redhat.com>
11
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
12
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-9-tomitamoeko@gmail.com
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
14
---
15
hw/vfio/pci.h | 2 --
16
hw/vfio/igd.c | 14 +++++++++-----
17
hw/vfio/pci.c | 9 ---------
18
3 files changed, 9 insertions(+), 16 deletions(-)
19
20
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/vfio/pci.h
23
+++ b/hw/vfio/pci.h
24
@@ -XXX,XX +XXX,XX @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
25
26
bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
27
28
-bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp);
29
-
30
void vfio_display_reset(VFIOPCIDevice *vdev);
31
bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
32
void vfio_display_finalize(VFIOPCIDevice *vdev);
33
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/vfio/igd.c
36
+++ b/hw/vfio/igd.c
37
@@ -XXX,XX +XXX,XX @@ static bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
38
return true;
39
}
40
41
-bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp)
42
+static bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp)
43
{
44
g_autofree struct vfio_region_info *opregion = NULL;
45
int ret;
46
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
47
goto error;
48
}
49
50
- /* Setup OpRegion access */
51
- if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
52
- goto error;
53
- }
54
+ /* Enable OpRegion quirk */
55
+ vdev->features |= VFIO_FEATURE_ENABLE_IGD_OPREGION;
56
57
/* Setup LPC bridge / Host bridge PCI IDs */
58
if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
59
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
60
goto error;
61
}
62
63
+ /* Setup OpRegion access */
64
+ if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) &&
65
+ !vfio_pci_igd_setup_opregion(vdev, errp)) {
66
+ goto error;
67
+ }
68
+
69
/*
70
* Allow user to override dsm size using x-igd-gms option, in multiples of
71
* 32MiB. This option should only be used when the desired size cannot be
72
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/vfio/pci.c
75
+++ b/hw/vfio/pci.c
76
@@ -XXX,XX +XXX,XX @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
77
vfio_bar_quirk_setup(vdev, i);
78
}
79
80
-#ifdef CONFIG_VFIO_IGD
81
- if (!vdev->igd_opregion &&
82
- vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
83
- if (!vfio_pci_igd_setup_opregion(vdev, errp)) {
84
- goto out_unset_idev;
85
- }
86
- }
87
-#endif
88
-
89
/* QEMU emulates all of MSI & MSIX */
90
if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {
91
memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff,
92
--
93
2.48.1
94
95
diff view generated by jsdifflib
New patch
1
From: Tomita Moeko <tomitamoeko@gmail.com>
1
2
3
The LPC bridge/Host bridge IDs quirk is also not dependent on legacy
4
mode. Recent Windows driver no longer depends on these IDs, as well as
5
Linux i915 driver, while UEFI GOP seems still needs them. Make it an
6
option to allow users enabling and disabling it as needed.
7
8
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
9
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
10
Tested-by: Alex Williamson <alex.williamson@redhat.com>
11
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
12
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-10-tomitamoeko@gmail.com
13
[ clg: - Fixed spelling in vfio_probe_igd_config_quirk() ]
14
Signed-off-by: Cédric Le Goater <clg@redhat.com>
15
---
16
hw/vfio/pci.h | 3 +++
17
hw/vfio/igd.c | 14 ++++++++------
18
hw/vfio/pci.c | 2 ++
19
3 files changed, 13 insertions(+), 6 deletions(-)
20
21
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/vfio/pci.h
24
+++ b/hw/vfio/pci.h
25
@@ -XXX,XX +XXX,XX @@ struct VFIOPCIDevice {
26
#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2
27
#define VFIO_FEATURE_ENABLE_IGD_OPREGION \
28
(1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
29
+#define VFIO_FEATURE_ENABLE_IGD_LPC_BIT 3
30
+#define VFIO_FEATURE_ENABLE_IGD_LPC \
31
+ (1 << VFIO_FEATURE_ENABLE_IGD_LPC_BIT)
32
OnOffAuto display;
33
uint32_t display_xres;
34
uint32_t display_yres;
35
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/vfio/igd.c
38
+++ b/hw/vfio/igd.c
39
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
40
goto error;
41
}
42
43
- /* Enable OpRegion quirk */
44
+ /* Enable OpRegion and LPC bridge quirk */
45
vdev->features |= VFIO_FEATURE_ENABLE_IGD_OPREGION;
46
-
47
- /* Setup LPC bridge / Host bridge PCI IDs */
48
- if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
49
- goto error;
50
- }
51
+ vdev->features |= VFIO_FEATURE_ENABLE_IGD_LPC;
52
} else if (vdev->igd_legacy_mode == ON_OFF_AUTO_ON) {
53
error_setg(&err,
54
"Machine is not i440fx or assigned BDF is not 00:02.0");
55
@@ -XXX,XX +XXX,XX @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
56
goto error;
57
}
58
59
+ /* Setup LPC bridge / Host bridge PCI IDs */
60
+ if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_LPC) &&
61
+ !vfio_pci_igd_setup_lpc_bridge(vdev, errp)) {
62
+ goto error;
63
+ }
64
+
65
/*
66
* Allow user to override dsm size using x-igd-gms option, in multiples of
67
* 32MiB. This option should only be used when the desired size cannot be
68
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/vfio/pci.c
71
+++ b/hw/vfio/pci.c
72
@@ -XXX,XX +XXX,XX @@ static const Property vfio_pci_dev_properties[] = {
73
VFIO_FEATURE_ENABLE_REQ_BIT, true),
74
DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
75
VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
76
+ DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features,
77
+ VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
78
DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
79
igd_legacy_mode, ON_OFF_AUTO_AUTO),
80
DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
81
--
82
2.48.1
83
84
diff view generated by jsdifflib
1
This helper will be useful in the listener handlers to extract the
1
From: Tomita Moeko <tomitamoeko@gmail.com>
2
VFIO device from a memory region using memory_region_owner(). At the
3
moment, we only care for PCI passthrough devices. If the need arises,
4
we will add more.
5
2
3
The KVMGT/GVT-g vGPU also exposes OpRegion. But unlike IGD passthrough,
4
it only needs the OpRegion quirk. A previous change moved x-igd-opregion
5
handling to config quirk breaks KVMGT functionality as it brings extra
6
checks and applied other quirks. Here we check if the device is mdev
7
(KVMGT) or not (passthrough), and then applies corresponding quirks.
8
9
As before, users must manually specify x-igd-opregion=on to enable it
10
on KVMGT devices. In the future, we may check the VID/DID and enable
11
OpRegion automatically.
12
13
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
6
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
14
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
7
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-5-clg@redhat.com
15
Tested-by: Alex Williamson <alex.williamson@redhat.com>
16
Reviewed-by: Corvin Köhne <c.koehne@beckhoff.com>
17
Link: https://lore.kernel.org/qemu-devel/20250306180131.32970-11-tomitamoeko@gmail.com
8
Signed-off-by: Cédric Le Goater <clg@redhat.com>
18
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
---
19
---
10
include/hw/vfio/vfio-common.h | 1 +
20
hw/vfio/igd.c | 27 ++++++++++++++++++++++++++-
11
hw/vfio/helpers.c | 10 ++++++++++
21
1 file changed, 26 insertions(+), 1 deletion(-)
12
2 files changed, 11 insertions(+)
13
22
14
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
23
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/vfio/vfio-common.h
25
--- a/hw/vfio/igd.c
17
+++ b/include/hw/vfio/vfio-common.h
26
+++ b/hw/vfio/igd.c
18
@@ -XXX,XX +XXX,XX @@ bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp);
27
@@ -XXX,XX +XXX,XX @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
19
bool vfio_attach_device(char *name, VFIODevice *vbasedev,
28
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
20
AddressSpace *as, Error **errp);
29
}
21
void vfio_detach_device(VFIODevice *vbasedev);
30
22
+VFIODevice *vfio_get_vfio_device(Object *obj);
31
-bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
23
32
+static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
24
int vfio_kvm_device_add_fd(int fd, Error **errp);
33
{
25
int vfio_kvm_device_del_fd(int fd, Error **errp);
34
int ret, gen;
26
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
35
uint64_t gms_size;
27
index XXXXXXX..XXXXXXX 100644
36
@@ -XXX,XX +XXX,XX @@ error:
28
--- a/hw/vfio/helpers.c
37
error_propagate(errp, err);
29
+++ b/hw/vfio/helpers.c
38
return false;
30
@@ -XXX,XX +XXX,XX @@
31
#include <sys/ioctl.h>
32
33
#include "hw/vfio/vfio-common.h"
34
+#include "hw/vfio/pci.h"
35
#include "hw/hw.h"
36
#include "trace.h"
37
#include "qapi/error.h"
38
@@ -XXX,XX +XXX,XX @@ bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp)
39
40
return HOST_IOMMU_DEVICE_GET_CLASS(hiod)->realize(hiod, vbasedev, errp);
41
}
39
}
42
+
40
+
43
+VFIODevice *vfio_get_vfio_device(Object *obj)
41
+/*
42
+ * KVMGT/GVT-g vGPU exposes an emulated OpRegion. So far, users have to specify
43
+ * x-igd-opregion=on to enable the access.
44
+ * TODO: Check VID/DID and enable opregion access automatically
45
+ */
46
+static bool vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp)
44
+{
47
+{
45
+ if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) {
48
+ if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) &&
46
+ return &VFIO_PCI(obj)->vbasedev;
49
+ !vfio_pci_igd_setup_opregion(vdev, errp)) {
47
+ } else {
50
+ return false;
48
+ return NULL;
49
+ }
51
+ }
52
+
53
+ return true;
54
+}
55
+
56
+bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
57
+{
58
+ /* KVMGT/GVT-g vGPU is exposed as mdev */
59
+ if (vdev->vbasedev.mdev) {
60
+ return vfio_pci_kvmgt_config_quirk(vdev, errp);
61
+ }
62
+
63
+ return vfio_pci_igd_config_quirk(vdev, errp);
50
+}
64
+}
51
--
65
--
52
2.48.1
66
2.48.1
53
67
54
68
diff view generated by jsdifflib
New patch
1
From: "Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>
1
2
3
Wire data commonly use BE byte order (including in the existing migration
4
protocol), use it also for for VFIO device state packets.
5
6
This will allow VFIO multifd device state transfer between hosts with
7
different endianness.
8
Although currently there is no such use case, it's good to have it now
9
for completeness.
10
11
Reviewed-by: Avihai Horon <avihaih@nvidia.com>
12
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
13
Link: https://lore.kernel.org/qemu-devel/dcfc04cc1a50655650dbac8398e2742ada84ee39.1741611079.git.maciej.szmigiero@oracle.com
14
Signed-off-by: Cédric Le Goater <clg@redhat.com>
15
---
16
hw/vfio/migration-multifd.c | 15 ++++++++++-----
17
1 file changed, 10 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/vfio/migration-multifd.c b/hw/vfio/migration-multifd.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/vfio/migration-multifd.c
22
+++ b/hw/vfio/migration-multifd.c
23
@@ -XXX,XX +XXX,XX @@
24
#include "hw/vfio/vfio-common.h"
25
#include "migration/misc.h"
26
#include "qapi/error.h"
27
+#include "qemu/bswap.h"
28
#include "qemu/error-report.h"
29
#include "qemu/lockable.h"
30
#include "qemu/main-loop.h"
31
@@ -XXX,XX +XXX,XX @@ bool vfio_multifd_load_state_buffer(void *opaque, char *data, size_t data_size,
32
return false;
33
}
34
35
+ packet->version = be32_to_cpu(packet->version);
36
if (packet->version != VFIO_DEVICE_STATE_PACKET_VER_CURRENT) {
37
error_setg(errp, "%s: packet has unknown version %" PRIu32,
38
vbasedev->name, packet->version);
39
return false;
40
}
41
42
+ packet->idx = be32_to_cpu(packet->idx);
43
+ packet->flags = be32_to_cpu(packet->flags);
44
+
45
if (packet->idx == UINT32_MAX) {
46
error_setg(errp, "%s: packet index is invalid", vbasedev->name);
47
return false;
48
@@ -XXX,XX +XXX,XX @@ vfio_save_complete_precopy_thread_config_state(VFIODevice *vbasedev,
49
50
packet_len = sizeof(*packet) + bioc->usage;
51
packet = g_malloc0(packet_len);
52
- packet->version = VFIO_DEVICE_STATE_PACKET_VER_CURRENT;
53
- packet->idx = idx;
54
- packet->flags = VFIO_DEVICE_STATE_CONFIG_STATE;
55
+ packet->version = cpu_to_be32(VFIO_DEVICE_STATE_PACKET_VER_CURRENT);
56
+ packet->idx = cpu_to_be32(idx);
57
+ packet->flags = cpu_to_be32(VFIO_DEVICE_STATE_CONFIG_STATE);
58
memcpy(&packet->data, bioc->data, bioc->usage);
59
60
if (!multifd_queue_device_state(idstr, instance_id,
61
@@ -XXX,XX +XXX,XX @@ vfio_multifd_save_complete_precopy_thread(SaveLiveCompletePrecopyThreadData *d,
62
}
63
64
packet = g_malloc0(sizeof(*packet) + migration->data_buffer_size);
65
- packet->version = VFIO_DEVICE_STATE_PACKET_VER_CURRENT;
66
+ packet->version = cpu_to_be32(VFIO_DEVICE_STATE_PACKET_VER_CURRENT);
67
68
for (idx = 0; ; idx++) {
69
ssize_t data_size;
70
@@ -XXX,XX +XXX,XX @@ vfio_multifd_save_complete_precopy_thread(SaveLiveCompletePrecopyThreadData *d,
71
break;
72
}
73
74
- packet->idx = idx;
75
+ packet->idx = cpu_to_be32(idx);
76
packet_size = sizeof(*packet) + data_size;
77
78
if (!multifd_queue_device_state(d->idstr, d->instance_id,
79
--
80
2.48.1
81
82
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Both qemu_minrampagesize() and qemu_maxrampagesize() are
4
related to host memory backends, having the following call
5
stack:
6
7
qemu_minrampagesize()
8
-> find_min_backend_pagesize()
9
-> object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)
10
11
qemu_maxrampagesize()
12
-> find_max_backend_pagesize()
13
-> object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)
14
15
Having TYPE_MEMORY_BACKEND defined in "system/hostmem.h":
16
17
include/system/hostmem.h:23:#define TYPE_MEMORY_BACKEND "memory-backend"
18
19
Move their prototype declaration to "system/hostmem.h".
20
21
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
23
Reviewed-by: Eric Auger <eric.auger@redhat.com>
24
Message-Id: <20250308230917.18907-7-philmd@linaro.org>
25
Acked-by: David Hildenbrand <david@redhat.com>
26
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-2-philmd@linaro.org
27
Signed-off-by: Cédric Le Goater <clg@redhat.com>
28
---
29
include/exec/ram_addr.h | 3 ---
30
include/system/hostmem.h | 3 +++
31
hw/ppc/spapr_caps.c | 1 +
32
hw/s390x/s390-virtio-ccw.c | 1 +
33
hw/vfio/spapr.c | 1 +
34
5 files changed, 6 insertions(+), 3 deletions(-)
35
36
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/exec/ram_addr.h
39
+++ b/include/exec/ram_addr.h
40
@@ -XXX,XX +XXX,XX @@ static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr,
41
42
bool ramblock_is_pmem(RAMBlock *rb);
43
44
-long qemu_minrampagesize(void);
45
-long qemu_maxrampagesize(void);
46
-
47
/**
48
* qemu_ram_alloc_from_file,
49
* qemu_ram_alloc_from_fd: Allocate a ram block from the specified backing
50
diff --git a/include/system/hostmem.h b/include/system/hostmem.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/system/hostmem.h
53
+++ b/include/system/hostmem.h
54
@@ -XXX,XX +XXX,XX @@ bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
55
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev);
56
char *host_memory_backend_get_name(HostMemoryBackend *backend);
57
58
+long qemu_minrampagesize(void);
59
+long qemu_maxrampagesize(void);
60
+
61
#endif
62
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/ppc/spapr_caps.c
65
+++ b/hw/ppc/spapr_caps.c
66
@@ -XXX,XX +XXX,XX @@
67
#include "kvm_ppc.h"
68
#include "migration/vmstate.h"
69
#include "system/tcg.h"
70
+#include "system/hostmem.h"
71
72
#include "hw/ppc/spapr.h"
73
74
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/s390x/s390-virtio-ccw.c
77
+++ b/hw/s390x/s390-virtio-ccw.c
78
@@ -XXX,XX +XXX,XX @@
79
#include "hw/s390x/tod.h"
80
#include "system/system.h"
81
#include "system/cpus.h"
82
+#include "system/hostmem.h"
83
#include "target/s390x/kvm/pv.h"
84
#include "migration/blocker.h"
85
#include "qapi/visitor.h"
86
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/vfio/spapr.c
89
+++ b/hw/vfio/spapr.c
90
@@ -XXX,XX +XXX,XX @@
91
#include <linux/kvm.h>
92
#endif
93
#include "system/kvm.h"
94
+#include "system/hostmem.h"
95
#include "exec/address-spaces.h"
96
97
#include "hw/vfio/vfio-common.h"
98
--
99
2.48.1
100
101
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
<linux/kvm.h> is already included by "system/kvm.h" in the next line.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Cédric Le Goater <clg@redhat.com>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-Id: <20250307180337.14811-3-philmd@linaro.org>
11
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-3-philmd@linaro.org
12
Signed-off-by: Cédric Le Goater <clg@redhat.com>
13
---
14
hw/vfio/spapr.c | 3 ---
15
1 file changed, 3 deletions(-)
16
17
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/vfio/spapr.c
20
+++ b/hw/vfio/spapr.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qemu/osdep.h"
23
#include <sys/ioctl.h>
24
#include <linux/vfio.h>
25
-#ifdef CONFIG_KVM
26
-#include <linux/kvm.h>
27
-#endif
28
#include "system/kvm.h"
29
#include "system/hostmem.h"
30
#include "exec/address-spaces.h"
31
--
32
2.48.1
33
34
diff view generated by jsdifflib
1
When the IOMMU address space width is smaller than the physical
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
address width, a MMIO region of a device can fail to map because the
3
region is outside the supported IOVA ranges of the VM. In this case,
4
PCI peer-to-peer transactions on BARs are not supported. This can
5
occur with the 39-bit IOMMU address space width, as can be the case on
6
some Intel consumer processors, or when using a vIOMMU device with
7
default settings.
8
2
9
The current error message is unclear, improve it and also change the
3
Always include necessary headers explicitly, to avoid
10
error report to a warning because it is a non fatal condition for the
4
when refactoring unrelated ones:
11
VM. To prevent excessive log messages, restrict these recurring DMA
12
mapping errors to a single warning at runtime.
13
5
14
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
6
hw/vfio/common.c:1176:45: error: implicit declaration of function ‘tcg_enabled’;
15
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-6-clg@redhat.com
7
1176 | tcg_enabled() ? DIRTY_CLIENTS_ALL :
8
| ^~~~~~~~~~~
9
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Cédric Le Goater <clg@redhat.com>
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
Message-Id: <20250307180337.14811-2-philmd@linaro.org>
16
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-4-philmd@linaro.org
16
Signed-off-by: Cédric Le Goater <clg@redhat.com>
17
Signed-off-by: Cédric Le Goater <clg@redhat.com>
17
---
18
---
18
hw/vfio/common.c | 17 ++++++++++++++++-
19
hw/vfio/common.c | 1 +
19
1 file changed, 16 insertions(+), 1 deletion(-)
20
1 file changed, 1 insertion(+)
20
21
21
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
22
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/vfio/common.c
24
--- a/hw/vfio/common.c
24
+++ b/hw/vfio/common.c
25
+++ b/hw/vfio/common.c
25
@@ -XXX,XX +XXX,XX @@ static bool vfio_get_section_iova_range(VFIOContainerBase *bcontainer,
26
@@ -XXX,XX +XXX,XX @@
26
return true;
27
#include "migration/misc.h"
27
}
28
#include "migration/blocker.h"
28
29
#include "migration/qemu-file.h"
29
+static void vfio_device_error_append(VFIODevice *vbasedev, Error **errp)
30
+#include "system/tcg.h"
30
+{
31
#include "system/tpm.h"
31
+ /*
32
32
+ * MMIO region mapping failures are not fatal but in this case PCI
33
VFIODeviceList vfio_device_list =
33
+ * peer-to-peer transactions are broken.
34
+ */
35
+ if (vbasedev && vbasedev->type == VFIO_DEVICE_TYPE_PCI) {
36
+ error_append_hint(errp, "%s: PCI peer-to-peer transactions "
37
+ "on BARs are not supported.\n", vbasedev->name);
38
+ }
39
+}
40
+
41
static void vfio_listener_region_add(MemoryListener *listener,
42
MemoryRegionSection *section)
43
{
44
@@ -XXX,XX +XXX,XX @@ static void vfio_listener_region_add(MemoryListener *listener,
45
strerror(-ret));
46
if (memory_region_is_ram_device(section->mr)) {
47
/* Allow unexpected mappings not to be fatal for RAM devices */
48
- error_report_err(err);
49
+ VFIODevice *vbasedev =
50
+ vfio_get_vfio_device(memory_region_owner(section->mr));
51
+ vfio_device_error_append(vbasedev, &err);
52
+ warn_report_err_once(err);
53
return;
54
}
55
goto fail;
56
--
34
--
57
2.48.1
35
2.48.1
58
36
59
37
diff view generated by jsdifflib
1
Rephrase a bit the ending comment about how errors are handled
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
depending on the phase in which vfio_listener_region_add() is called.
3
2
4
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
3
Prefer runtime helpers to get target page size.
5
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-4-clg@redhat.com
4
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-Id: <20250305153929.43687-3-philmd@linaro.org>
8
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-5-philmd@linaro.org
6
Signed-off-by: Cédric Le Goater <clg@redhat.com>
9
Signed-off-by: Cédric Le Goater <clg@redhat.com>
7
---
10
---
8
hw/vfio/common.c | 15 ++++++++++-----
11
hw/vfio/common.c | 8 +++++---
9
1 file changed, 10 insertions(+), 5 deletions(-)
12
1 file changed, 5 insertions(+), 3 deletions(-)
10
13
11
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
14
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/vfio/common.c
16
--- a/hw/vfio/common.c
14
+++ b/hw/vfio/common.c
17
+++ b/hw/vfio/common.c
15
@@ -XXX,XX +XXX,XX @@ fail:
18
@@ -XXX,XX +XXX,XX @@
16
error_reportf_err(err, "PCI p2p may not work: ");
19
#include "exec/address-spaces.h"
17
return;
20
#include "exec/memory.h"
18
}
21
#include "exec/ram_addr.h"
19
- /*
22
+#include "exec/target_page.h"
20
- * On the initfn path, store the first error in the container so we
23
#include "hw/hw.h"
21
- * can gracefully fail. Runtime, there's not much we can do other
24
#include "qemu/error-report.h"
22
- * than throw a hardware error.
25
#include "qemu/main-loop.h"
23
- */
26
@@ -XXX,XX +XXX,XX @@ static void vfio_register_ram_discard_listener(VFIOContainerBase *bcontainer,
24
+
27
MemoryRegionSection *section)
25
if (!bcontainer->initialized) {
28
{
26
+ /*
29
RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr);
27
+ * At machine init time or when the device is attached to the
30
+ int target_page_size = qemu_target_page_size();
28
+ * VM, store the first error in the container so we can
31
VFIORamDiscardListener *vrdl;
29
+ * gracefully fail the device realize routine.
32
30
+ */
33
/* Ignore some corner cases not relevant in practice. */
31
if (!bcontainer->error) {
34
- g_assert(QEMU_IS_ALIGNED(section->offset_within_region, TARGET_PAGE_SIZE));
32
error_propagate_prepend(&bcontainer->error, err,
35
+ g_assert(QEMU_IS_ALIGNED(section->offset_within_region, target_page_size));
33
"Region %s: ",
36
g_assert(QEMU_IS_ALIGNED(section->offset_within_address_space,
34
@@ -XXX,XX +XXX,XX @@ fail:
37
- TARGET_PAGE_SIZE));
35
error_free(err);
38
- g_assert(QEMU_IS_ALIGNED(int128_get64(section->size), TARGET_PAGE_SIZE));
36
}
39
+ target_page_size));
37
} else {
40
+ g_assert(QEMU_IS_ALIGNED(int128_get64(section->size), target_page_size));
38
+ /*
41
39
+ * At runtime, there's not much we can do other than throw a
42
vrdl = g_new0(VFIORamDiscardListener, 1);
40
+ * hardware error.
43
vrdl->bcontainer = bcontainer;
41
+ */
42
error_report_err(err);
43
hw_error("vfio: DMA mapping failed, unable to continue");
44
}
45
--
44
--
46
2.48.1
45
2.48.1
47
46
48
47
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Some files don't rely on any target-specific knowledge
4
and can be compiled once:
5
6
- helpers.c
7
- container-base.c
8
- migration.c (removing unnecessary "exec/ram_addr.h")
9
- migration-multifd.c
10
- cpr.c
11
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Cédric Le Goater <clg@redhat.com>
16
Reviewed-by: Eric Auger <eric.auger@redhat.com>
17
Message-Id: <20250308230917.18907-4-philmd@linaro.org>
18
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-6-philmd@linaro.org
19
Signed-off-by: Cédric Le Goater <clg@redhat.com>
20
---
21
hw/vfio/migration.c | 1 -
22
hw/vfio/meson.build | 13 ++++++++-----
23
2 files changed, 8 insertions(+), 6 deletions(-)
24
25
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/vfio/migration.c
28
+++ b/hw/vfio/migration.c
29
@@ -XXX,XX +XXX,XX @@
30
#include "qapi/error.h"
31
#include "qapi/qapi-events-vfio.h"
32
#include "exec/ramlist.h"
33
-#include "exec/ram_addr.h"
34
#include "pci.h"
35
#include "trace.h"
36
#include "hw/hw.h"
37
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/vfio/meson.build
40
+++ b/hw/vfio/meson.build
41
@@ -XXX,XX +XXX,XX @@
42
vfio_ss = ss.source_set()
43
vfio_ss.add(files(
44
- 'helpers.c',
45
'common.c',
46
- 'container-base.c',
47
'container.c',
48
- 'migration.c',
49
- 'migration-multifd.c',
50
- 'cpr.c',
51
))
52
vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
53
vfio_ss.add(when: 'CONFIG_IOMMUFD', if_true: files(
54
@@ -XXX,XX +XXX,XX @@ vfio_ss.add(when: 'CONFIG_VFIO_AP', if_true: files('ap.c'))
55
vfio_ss.add(when: 'CONFIG_VFIO_IGD', if_true: files('igd.c'))
56
57
specific_ss.add_all(when: 'CONFIG_VFIO', if_true: vfio_ss)
58
+
59
+system_ss.add(when: 'CONFIG_VFIO', if_true: files(
60
+ 'helpers.c',
61
+ 'container-base.c',
62
+ 'migration.c',
63
+ 'migration-multifd.c',
64
+ 'cpr.c',
65
+))
66
--
67
2.48.1
68
69
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
These files depend on the VFIO symbol in their Kconfig
4
definition. They don't rely on target specific definitions,
5
move them to system_ss[] to build them once.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Cédric Le Goater <clg@redhat.com>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Message-Id: <20250308230917.18907-5-philmd@linaro.org>
13
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-7-philmd@linaro.org
14
Signed-off-by: Cédric Le Goater <clg@redhat.com>
15
---
16
hw/vfio/meson.build | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/vfio/meson.build
22
+++ b/hw/vfio/meson.build
23
@@ -XXX,XX +XXX,XX @@ vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
24
))
25
vfio_ss.add(when: 'CONFIG_VFIO_CCW', if_true: files('ccw.c'))
26
vfio_ss.add(when: 'CONFIG_VFIO_PLATFORM', if_true: files('platform.c'))
27
-vfio_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c'))
28
-vfio_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c'))
29
vfio_ss.add(when: 'CONFIG_VFIO_AP', if_true: files('ap.c'))
30
vfio_ss.add(when: 'CONFIG_VFIO_IGD', if_true: files('igd.c'))
31
32
specific_ss.add_all(when: 'CONFIG_VFIO', if_true: vfio_ss)
33
34
+system_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c'))
35
+system_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c'))
36
system_ss.add(when: 'CONFIG_VFIO', if_true: files(
37
'helpers.c',
38
'container-base.c',
39
--
40
2.48.1
41
42
diff view generated by jsdifflib
1
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
When iommufd_cdev_ram_block_discard_disable() fails for whatever reason,
3
Removing unused "exec/ram_addr.h" header allow to compile
4
errp should be set or else SIGSEV is triggered in vfio_realize() when
4
iommufd.c once for all targets.
5
error_prepend() is called.
6
5
7
By this chance, use the same error message for both legacy and iommufd
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
backend.
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
9
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Fixes: 5ee3dc7af785 ("vfio/iommufd: Implement the iommufd backend")
9
Reviewed-by: Cédric Le Goater <clg@redhat.com>
11
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
13
Link: https://lore.kernel.org/r/20250116102307.260849-1-zhenzhong.duan@intel.com
11
Message-Id: <20250308230917.18907-6-philmd@linaro.org>
12
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-8-philmd@linaro.org
14
Signed-off-by: Cédric Le Goater <clg@redhat.com>
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
15
---
14
---
16
hw/vfio/iommufd.c | 5 +++--
15
hw/vfio/iommufd.c | 1 -
17
1 file changed, 3 insertions(+), 2 deletions(-)
16
hw/vfio/meson.build | 6 +++---
17
2 files changed, 3 insertions(+), 4 deletions(-)
18
18
19
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
19
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/vfio/iommufd.c
21
--- a/hw/vfio/iommufd.c
22
+++ b/hw/vfio/iommufd.c
22
+++ b/hw/vfio/iommufd.c
23
@@ -XXX,XX +XXX,XX @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
23
@@ -XXX,XX +XXX,XX @@
24
} else {
24
#include "qemu/cutils.h"
25
ret = iommufd_cdev_ram_block_discard_disable(true);
25
#include "qemu/chardev_open.h"
26
if (ret) {
26
#include "pci.h"
27
- error_setg(errp,
27
-#include "exec/ram_addr.h"
28
- "Cannot set discarding of RAM broken (%d)", ret);
28
29
+ error_setg_errno(errp, -ret,
29
static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova,
30
+ "Cannot set discarding of RAM broken");
30
ram_addr_t size, void *vaddr, bool readonly)
31
goto err_discard_disable;
31
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
32
}
32
index XXXXXXX..XXXXXXX 100644
33
goto found_container;
33
--- a/hw/vfio/meson.build
34
@@ -XXX,XX +XXX,XX @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
34
+++ b/hw/vfio/meson.build
35
35
@@ -XXX,XX +XXX,XX @@ vfio_ss.add(files(
36
ret = iommufd_cdev_ram_block_discard_disable(true);
36
'container.c',
37
if (ret) {
37
))
38
+ error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken");
38
vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
39
goto err_discard_disable;
39
-vfio_ss.add(when: 'CONFIG_IOMMUFD', if_true: files(
40
}
40
- 'iommufd.c',
41
41
-))
42
vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
43
'display.c',
44
'pci-quirks.c',
45
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VFIO', if_true: files(
46
'migration-multifd.c',
47
'cpr.c',
48
))
49
+system_ss.add(when: ['CONFIG_VFIO', 'CONFIG_IOMMUFD'], if_true: files(
50
+ 'iommufd.c',
51
+))
42
--
52
--
43
2.48.1
53
2.48.1
44
54
45
55
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
display.c doesn't rely on target specific definitions,
4
move it to system_ss[] to build it once.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Cédric Le Goater <clg@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Message-Id: <20250308230917.18907-8-philmd@linaro.org>
12
Link: https://lore.kernel.org/qemu-devel/20250311085743.21724-9-philmd@linaro.org
13
Signed-off-by: Cédric Le Goater <clg@redhat.com>
14
---
15
hw/vfio/meson.build | 4 +++-
16
1 file changed, 3 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/vfio/meson.build
21
+++ b/hw/vfio/meson.build
22
@@ -XXX,XX +XXX,XX @@ vfio_ss.add(files(
23
))
24
vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c'))
25
vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
26
- 'display.c',
27
'pci-quirks.c',
28
'pci.c',
29
))
30
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VFIO', if_true: files(
31
system_ss.add(when: ['CONFIG_VFIO', 'CONFIG_IOMMUFD'], if_true: files(
32
'iommufd.c',
33
))
34
+system_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
35
+ 'display.c',
36
+))
37
--
38
2.48.1
39
40
diff view generated by jsdifflib
New patch
1
From: Vasilis Liaskovitis <vliaskovitis@suse.com>
1
2
3
The ATI BAR4 quirk is targeting an ioport BAR. Older devices may
4
have a BAR4 which is not an ioport, causing a segfault here. Test
5
the BAR type to skip these devices.
6
7
Similar to
8
"8f419c5b: vfio/pci-quirks: Exclude non-ioport BAR from NVIDIA quirk"
9
10
Untested, as I don't have the card to test.
11
12
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2856
13
Signed-off-by: Vasilis Liaskovitis <vliaskovitis@suse.com>
14
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
15
Link: https://lore.kernel.org/qemu-devel/20250310235833.41026-1-vliaskovitis@suse.com
16
Signed-off-by: Cédric Le Goater <clg@redhat.com>
17
---
18
hw/vfio/pci-quirks.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/vfio/pci-quirks.c
24
+++ b/hw/vfio/pci-quirks.c
25
@@ -XXX,XX +XXX,XX @@ static void vfio_probe_ati_bar4_quirk(VFIOPCIDevice *vdev, int nr)
26
27
/* This windows doesn't seem to be used except by legacy VGA code */
28
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_ATI, PCI_ANY_ID) ||
29
- !vdev->vga || nr != 4) {
30
+ !vdev->vga || nr != 4 || !vdev->bars[4].ioport) {
31
return;
32
}
33
34
--
35
2.48.1
36
37
diff view generated by jsdifflib
1
This is to be consistent with other reported errors related to vIOMMU
1
From: Joao Martins <joao.m.martins@oracle.com>
2
devices.
3
2
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
The intent behind the x-device-dirty-page-tracking option is twofold:
5
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
4
6
Link: https://lore.kernel.org/qemu-devel/20250206131438.1505542-3-clg@redhat.com
5
1) development/testing in the presence of VFs with VF dirty page tracking
6
7
2) deliberately choosing platform dirty tracker over the VF one.
8
9
Item 2) scenario is useful when VF dirty tracker is not as fast as
10
IOMMU, or there's some limitations around it (e.g. number of them is
11
limited; aggregated address space under tracking is limited),
12
efficiency/scalability (e.g. 1 pagetable in IOMMU dirty tracker to scan
13
vs N VFs) or just troubleshooting. Given item 2 it is not restricted to
14
debugging, hence drop the debug parenthesis from the option description.
15
16
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
17
Reviewed-by: Cédric Le Goater <clg@redhat.com>
18
Link: https://lore.kernel.org/qemu-devel/20250311174807.79825-1-joao.m.martins@oracle.com
19
[ clg: Fixed subject spelling ]
7
Signed-off-by: Cédric Le Goater <clg@redhat.com>
20
Signed-off-by: Cédric Le Goater <clg@redhat.com>
8
---
21
---
9
hw/vfio/pci.c | 2 +-
22
hw/vfio/pci.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
23
1 file changed, 1 insertion(+), 1 deletion(-)
11
24
12
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
25
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
13
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/vfio/pci.c
27
--- a/hw/vfio/pci.c
15
+++ b/hw/vfio/pci.c
28
+++ b/hw/vfio/pci.c
16
@@ -XXX,XX +XXX,XX @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
29
@@ -XXX,XX +XXX,XX @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data)
17
30
object_class_property_set_description(klass, /* 9.1 */
18
if (!vbasedev->mdev &&
31
"x-device-dirty-page-tracking",
19
!pci_device_set_iommu_device(pdev, vbasedev->hiod, errp)) {
32
"Disable device dirty page tracking and use "
20
- error_prepend(errp, "Failed to set iommu_device: ");
33
- "container-based dirty page tracking (DEBUG)");
21
+ error_prepend(errp, "Failed to set vIOMMU: ");
34
+ "container-based dirty page tracking");
22
goto out_teardown;
35
object_class_property_set_description(klass, /* 9.1 */
23
}
36
"migration-events",
24
37
"Emit VFIO migration QAPI event when a VFIO device "
25
--
38
--
26
2.48.1
39
2.48.1
27
40
28
41
diff view generated by jsdifflib