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-pci.h | 3 +++ pc-bios/s390-ccw/virtio.c | 2 ++ pc-bios/s390-ccw/virtio.h | 1 + 5 files changed, 26 insertions(+) diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c index 26287cfd81..fb47d29bb1 100644 --- a/pc-bios/s390-ccw/main.c +++ b/pc-bios/s390-ccw/main.c @@ -163,6 +163,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..f501252c81 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 == PCI_VENDOR_VIRTIO) { + 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)) { + 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-pci.h b/pc-bios/s390-ccw/virtio-pci.h index 2494df1619..33b683bd92 100644 --- a/pc-bios/s390-ccw/virtio-pci.h +++ b/pc-bios/s390-ccw/virtio-pci.h @@ -56,6 +56,8 @@ #define VIRTIO_F_VERSION_1 1 /* Feature bit 32 */ +#define PCI_VENDOR_VIRTIO 0x1af4 + struct VirtioPciCap { uint8_t bar; /* Which PCIAS it's in */ uint32_t off; /* Offset within bar */ @@ -65,6 +67,7 @@ typedef struct VirtioPciCap VirtioPciCap; void virtio_pci_id2type(VDev *vdev, uint16_t device_id); int virtio_pci_reset(VDev *vdev); long virtio_pci_notify(VRing *vr); +bool virtio_pci_is_supported(VDev *vdev); int virtio_pci_setup(VDev *vdev); int virtio_pci_setup_device(void); diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c index df04479aa6..a0d249db24 100644 --- a/pc-bios/s390-ccw/virtio.c +++ b/pc-bios/s390-ccw/virtio.c @@ -247,6 +247,8 @@ bool virtio_is_supported(VDev *vdev) case S390_IPL_TYPE_QEMU_SCSI: case S390_IPL_TYPE_CCW: return virtio_ccw_is_supported(vdev); + case S390_IPL_TYPE_PCI: + return virtio_pci_is_supported(vdev); default: return false; } 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]; }; -- 2.54.0
