[PATCH v2 3/5] virtio: mmio: Keep vendor id little endian
Kuan-Wei Chiu
visitorckw at gmail.com
Mon Apr 6 18:54:49 CEST 2026
Hi Daniel,
On Mon, Apr 06, 2026 at 11:24:09PM +0900, Daniel Palmer wrote:
> The vendor id is used as a little endian value but it gets
> swapped to the CPU endian in readl(). Swap it back to le
> to avoid the below weird output from `virtio info`.
>
> Device 0: UMEQ VirtIO Block Device
> Type: Hard Disk
> Capacity: 1.0 MB = 0.0 GB (2056 x 512)
>
> Signed-off-by: Daniel Palmer <daniel at thingy.jp>
> ---
> drivers/virtio/virtio_mmio.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index 1cd737aca249..ddf873fa96fb 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -374,7 +374,7 @@ static int virtio_mmio_probe(struct udevice *udev)
> */
> return 0;
> }
> - uc_priv->vendor = readl(priv->base + VIRTIO_MMIO_VENDOR_ID);
> + uc_priv->vendor = cpu_to_le32(readl(priv->base + VIRTIO_MMIO_VENDOR_ID));
Hi Daniel,
Thanks for the patch!
While using cpu_to_le32() here does fix the visual output, it feels a
bit hacky because it alters the actual core data value just to satisfy
a display quirk.
For example, if someone in the future writes hardware specific logic
like if (uc_priv->vendor == 0x554D4551), it would silently fail on
m68k.
It looks more like a issue in virtio-blk driver to me.
The code currently does this:
sprintf(desc->vendor, "%s", (char *)&uc_priv->vendor);
This direct memory cast relies on little endian byte ordering to spell
"QEMU". On big endian machines, the memory layout naturally spells
"UMEQ".
So maybe we can extract the characters safely using bitwise shifts like
this?
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 3dd0cf36268..af61939270d 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -168,10 +168,15 @@ static int virtio_blk_bind(struct udevice *dev)
* virtio mmio transport supplies string identification for us,
* while pci trnasport uses a 2-byte subvendor value.
*/
- if (uc_priv->vendor >> 16)
- sprintf(desc->vendor, "%s", (char *)&uc_priv->vendor);
- else
+ if (uc_priv->vendor >> 16) {
+ desc->vendor[0] = (uc_priv->vendor >> 0) & 0xff;
+ desc->vendor[1] = (uc_priv->vendor >> 8) & 0xff;
+ desc->vendor[2] = (uc_priv->vendor >> 16) & 0xff;
+ desc->vendor[3] = (uc_priv->vendor >> 24) & 0xff;
+ desc->vendor[4] = '\0';
+ } else {
sprintf(desc->vendor, "%04x", uc_priv->vendor);
+ }
desc->bdev = dev;
/* Indicate what driver features we support */
Regards,
Kuan-Wei
More information about the U-Boot
mailing list