* [PATCH] vfio/pci: Introduce x-pci-class-code option
@ 2025-05-24 15:31 Tomita Moeko
2025-05-24 15:34 ` Tomita Moeko
2025-05-27 18:44 ` Alex Williamson
0 siblings, 2 replies; 3+ messages in thread
From: Tomita Moeko @ 2025-05-24 15:31 UTC (permalink / raw)
To: Alex Williamson, Cédric Le Goater; +Cc: Tomita Moeko, qemu-devel
Introduce x-pci-class-code option to allow users to override PCI class
code of a device, similar to the existing x-pci-vendor-id option. Only
the lower 24 bits of this option are used, though a uint32 is used here
for determining whether the value is valid and set by user.
This is mainly intended for IGD devices that expose themselves either
as VGA controller (primary display) or Display controller (non-primary
display). The UEFI GOP driver depends on the device reporting a VGA
controller class code (0x030000).
Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
hw/vfio/pci.c | 17 +++++++++++++++++
hw/vfio/pci.h | 1 +
hw/vfio/trace-events | 1 +
3 files changed, 19 insertions(+)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a1bfdfe375..879347a54e 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3062,6 +3062,21 @@ static bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp)
vdev->sub_device_id);
}
+ /*
+ * Class code is a 24-bit value at config space 0x09. Allow overriding it
+ * with any 24-bit value.
+ */
+ if (vdev->class_code != PCI_ANY_ID) {
+ if (vdev->class_code > 0xffffff) {
+ error_setg(errp, "invalid PCI class code provided");
+ return false;
+ }
+ /* Higher 24 bits of PCI_CLASS_REVISION are class code */
+ vfio_add_emulated_long(vdev, PCI_CLASS_REVISION,
+ vdev->class_code << 8, ~0xff);
+ trace_vfio_pci_emulated_class_code(vbasedev->name, vdev->class_code);
+ }
+
/* QEMU can change multi-function devices to single function, or reverse */
vdev->emulated_config_bits[PCI_HEADER_TYPE] =
PCI_HEADER_TYPE_MULTI_FUNCTION;
@@ -3482,6 +3497,8 @@ static const Property vfio_pci_dev_properties[] = {
sub_vendor_id, PCI_ANY_ID),
DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
sub_device_id, PCI_ANY_ID),
+ DEFINE_PROP_UINT32("x-pci-class-code", VFIOPCIDevice,
+ class_code, PCI_ANY_ID),
DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
nv_gpudirect_clique,
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 5ce0fb916f..587eb8cc9a 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -156,6 +156,7 @@ struct VFIOPCIDevice {
uint32_t device_id;
uint32_t sub_vendor_id;
uint32_t sub_device_id;
+ uint32_t class_code;
uint32_t features;
#define VFIO_FEATURE_ENABLE_VGA_BIT 0
#define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index e90ec9bff8..d0b006aa29 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -46,6 +46,7 @@ vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s 0x%04x"
vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s 0x%04x"
+vfio_pci_emulated_class_code(const char *name, uint16_t val) "%s 0x%06x"
# pci-quirks.c
vfio_quirk_rom_in_denylist(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"
--
2.47.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] vfio/pci: Introduce x-pci-class-code option
2025-05-24 15:31 [PATCH] vfio/pci: Introduce x-pci-class-code option Tomita Moeko
@ 2025-05-24 15:34 ` Tomita Moeko
2025-05-27 18:44 ` Alex Williamson
1 sibling, 0 replies; 3+ messages in thread
From: Tomita Moeko @ 2025-05-24 15:34 UTC (permalink / raw)
To: Alex Williamson, Cédric Le Goater; +Cc: qemu-devel
On 5/24/25 23:31, Tomita Moeko wrote:
> Introduce x-pci-class-code option to allow users to override PCI class
> code of a device, similar to the existing x-pci-vendor-id option. Only
> the lower 24 bits of this option are used, though a uint32 is used here
> for determining whether the value is valid and set by user.
>
> This is mainly intended for IGD devices that expose themselves either
> as VGA controller (primary display) or Display controller (non-primary
> display). The UEFI GOP driver depends on the device reporting a VGA
> controller class code (0x030000).
>
> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
> ---
> hw/vfio/pci.c | 17 +++++++++++++++++
> hw/vfio/pci.h | 1 +
> hw/vfio/trace-events | 1 +
> 3 files changed, 19 insertions(+)
>
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index a1bfdfe375..879347a54e 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -3062,6 +3062,21 @@ static bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp)
> vdev->sub_device_id);
> }
>
> + /*
> + * Class code is a 24-bit value at config space 0x09. Allow overriding it
> + * with any 24-bit value.
> + */
> + if (vdev->class_code != PCI_ANY_ID) {
> + if (vdev->class_code > 0xffffff) {
> + error_setg(errp, "invalid PCI class code provided");
> + return false;
> + }
> + /* Higher 24 bits of PCI_CLASS_REVISION are class code */
> + vfio_add_emulated_long(vdev, PCI_CLASS_REVISION,
> + vdev->class_code << 8, ~0xff);
> + trace_vfio_pci_emulated_class_code(vbasedev->name, vdev->class_code);
> + }
> +
> /* QEMU can change multi-function devices to single function, or reverse */
> vdev->emulated_config_bits[PCI_HEADER_TYPE] =
> PCI_HEADER_TYPE_MULTI_FUNCTION;
> @@ -3482,6 +3497,8 @@ static const Property vfio_pci_dev_properties[] = {
> sub_vendor_id, PCI_ANY_ID),
> DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
> sub_device_id, PCI_ANY_ID),
> + DEFINE_PROP_UINT32("x-pci-class-code", VFIOPCIDevice,
> + class_code, PCI_ANY_ID),
> DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
> DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
> nv_gpudirect_clique,
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index 5ce0fb916f..587eb8cc9a 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -156,6 +156,7 @@ struct VFIOPCIDevice {
> uint32_t device_id;
> uint32_t sub_vendor_id;
> uint32_t sub_device_id;
> + uint32_t class_code;
> uint32_t features;
> #define VFIO_FEATURE_ENABLE_VGA_BIT 0
> #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
> index e90ec9bff8..d0b006aa29 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -46,6 +46,7 @@ vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s 0x%04x"
> +vfio_pci_emulated_class_code(const char *name, uint16_t val) "%s 0x%06x"
^^^^^^^^
Sorry there is a mistake, it should be `uint32_t` here...
> # pci-quirks.c
> vfio_quirk_rom_in_denylist(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] vfio/pci: Introduce x-pci-class-code option
2025-05-24 15:31 [PATCH] vfio/pci: Introduce x-pci-class-code option Tomita Moeko
2025-05-24 15:34 ` Tomita Moeko
@ 2025-05-27 18:44 ` Alex Williamson
1 sibling, 0 replies; 3+ messages in thread
From: Alex Williamson @ 2025-05-27 18:44 UTC (permalink / raw)
To: Tomita Moeko; +Cc: Cédric Le Goater, qemu-devel
On Sat, 24 May 2025 23:31:02 +0800
Tomita Moeko <tomitamoeko@gmail.com> wrote:
> Introduce x-pci-class-code option to allow users to override PCI class
> code of a device, similar to the existing x-pci-vendor-id option. Only
> the lower 24 bits of this option are used, though a uint32 is used here
> for determining whether the value is valid and set by user.
>
> This is mainly intended for IGD devices that expose themselves either
> as VGA controller (primary display) or Display controller (non-primary
> display). The UEFI GOP driver depends on the device reporting a VGA
> controller class code (0x030000).
Seems like a tricky one. Arguably it's no more crazy than allowing
vendor and device ID overrides. We're probably safe in the fact that
this is an experimental option (user keeps the pieces when it breaks)
and the obscurity of raw class values means it's unlikely to enter any
kind of common usage.
But, vfio_populate_vga() only cares that the device has a VGA region
because these only exist on VGA class devices. With this we can assign
a VGA device, override the class code to Display, use x-vga=on, and now
we've got a mess of VGA access to a non-VGA device that doesn't make
any sense. vfio_populate_vga() needs to care about the exposed class
code now too. Thanks,
Alex
> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
> ---
> hw/vfio/pci.c | 17 +++++++++++++++++
> hw/vfio/pci.h | 1 +
> hw/vfio/trace-events | 1 +
> 3 files changed, 19 insertions(+)
>
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index a1bfdfe375..879347a54e 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -3062,6 +3062,21 @@ static bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp)
> vdev->sub_device_id);
> }
>
> + /*
> + * Class code is a 24-bit value at config space 0x09. Allow overriding it
> + * with any 24-bit value.
> + */
> + if (vdev->class_code != PCI_ANY_ID) {
> + if (vdev->class_code > 0xffffff) {
> + error_setg(errp, "invalid PCI class code provided");
> + return false;
> + }
> + /* Higher 24 bits of PCI_CLASS_REVISION are class code */
> + vfio_add_emulated_long(vdev, PCI_CLASS_REVISION,
> + vdev->class_code << 8, ~0xff);
> + trace_vfio_pci_emulated_class_code(vbasedev->name, vdev->class_code);
> + }
> +
> /* QEMU can change multi-function devices to single function, or reverse */
> vdev->emulated_config_bits[PCI_HEADER_TYPE] =
> PCI_HEADER_TYPE_MULTI_FUNCTION;
> @@ -3482,6 +3497,8 @@ static const Property vfio_pci_dev_properties[] = {
> sub_vendor_id, PCI_ANY_ID),
> DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
> sub_device_id, PCI_ANY_ID),
> + DEFINE_PROP_UINT32("x-pci-class-code", VFIOPCIDevice,
> + class_code, PCI_ANY_ID),
> DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
> DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
> nv_gpudirect_clique,
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index 5ce0fb916f..587eb8cc9a 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -156,6 +156,7 @@ struct VFIOPCIDevice {
> uint32_t device_id;
> uint32_t sub_vendor_id;
> uint32_t sub_device_id;
> + uint32_t class_code;
> uint32_t features;
> #define VFIO_FEATURE_ENABLE_VGA_BIT 0
> #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT)
> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
> index e90ec9bff8..d0b006aa29 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -46,6 +46,7 @@ vfio_pci_emulated_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_device_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_sub_vendor_id(const char *name, uint16_t val) "%s 0x%04x"
> vfio_pci_emulated_sub_device_id(const char *name, uint16_t val) "%s 0x%04x"
> +vfio_pci_emulated_class_code(const char *name, uint16_t val) "%s 0x%06x"
>
> # pci-quirks.c
> vfio_quirk_rom_in_denylist(const char *name, uint16_t vid, uint16_t did) "%s %04x:%04x"
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-05-27 18:45 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-24 15:31 [PATCH] vfio/pci: Introduce x-pci-class-code option Tomita Moeko
2025-05-24 15:34 ` Tomita Moeko
2025-05-27 18:44 ` Alex Williamson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).