On Mon, 2026-06-22 at 20:25 -0400, [email protected] wrote:
> From: Jared Rossi <[email protected]>
>
> The virtio specification requires that each PCI device has a vendor ID of
> 0x1AF4. Verify this value before continuing with boot process.
>
> Signed-off-by: Jared Rossi <[email protected]>
> ---
> pc-bios/s390-ccw/main.c | 1 +
> pc-bios/s390-ccw/virtio-pci.c | 19 +++++++++++++++++++
> pc-bios/s390-ccw/virtio.h | 1 +
> 3 files changed, 21 insertions(+)
>
> diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> index 1059fda03c..567e97bf32 100644
> --- a/pc-bios/s390-ccw/main.c
> +++ b/pc-bios/s390-ccw/main.c
> @@ -164,6 +164,7 @@ static bool find_fid(uint32_t fid)
> }
>
> vdev->pci_fh = entry.fh;
> + vdev->vendor_id = entry.vendor_id;
> virtio_pci_id2type(vdev, entry.device_id);
>
> return vdev->dev_type != 0;
> diff --git a/pc-bios/s390-ccw/virtio-pci.c b/pc-bios/s390-ccw/virtio-pci.c
> index 2c83ec4f13..07b53b894f 100644
> --- a/pc-bios/s390-ccw/virtio-pci.c
> +++ b/pc-bios/s390-ccw/virtio-pci.c
> @@ -325,6 +325,20 @@ static int enable_pci_bus_master(void)
> return 0;
> }
>
> +bool virtio_pci_is_supported(VDev *vdev)
> +{
> + if (vdev->vendor_id == 0x1AF4) {
I'd prefer this hex value be lowercase, as they usually are in code.
Not sure where a good place would be, but defining a constant for the PCI
Vendor ID 0x1af4 (similar
to `#define CU_TYPE_VIRTIO 0x3832`) would provide some good context of
what's happening
here.
> + switch (vdev->dev_type) {
> + case VIRTIO_ID_BLOCK:
> + return true;
> + default:
> + return false;
> + }
> + }
> +
> + return false;
> +}
> +
> int virtio_pci_setup(VDev *vdev)
> {
> VRing *vr;
> @@ -335,6 +349,11 @@ int virtio_pci_setup(VDev *vdev)
> vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
> vdev->cmd_vr_idx = 0;
>
> + if (!virtio_pci_is_supported(vdev)) {
Why is this done here, versus called from virtio_is_supported() such that it
covers both -ccw and -
pci paths?
I'm guessing it's because the CLP data that contains the vendor_id isn't read
until find_fid(),
which runs against the possible call in
probe_boot_device()->is_dev_possibly_bootable(). If there's
a way to straighten out that chicken/egg I think that'd be useful.
> + puts("Virtio PCI unsupported for this device ID");
> + return -ENODEV;
> + }
> +
> if (virtio_pci_read_pci_cap_config()) {
> puts("Invalid virtio PCI capabilities");
> return -EIO;
> diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
> index 75ae5bdbc2..aa307025e0 100644
> --- a/pc-bios/s390-ccw/virtio.h
> +++ b/pc-bios/s390-ccw/virtio.h
> @@ -259,6 +259,7 @@ struct VDev {
> bool scsi_device_selected;
> ScsiDevice selected_scsi_device;
> uint32_t pci_fh;
> + uint16_t vendor_id;
> uint32_t max_transfer;
> uint32_t guest_features[2];
> };