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 <tomitamo...@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"


Reply via email to