I am running a direct kernel + Busybox based initrd guest using KVM/QEMU on an aarch64 host. The host platform is a ZynqMP SoC. My goal is to memory map the PL of the ZynqMP SoC from the guest VM running on the host using virtio-mmio.
The PL base address can by mapped from the host at the physical address 0xA0000000.
Doing devmem at 0xA0000000 on the host results in the expected value of 0x00000100:
However devmem at 0xA0000000 on the guest results in 0x00000000
My guest kernel has the following configs enabled:
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
I am adding the virtio_mmio.device=1K@0xa0000000:48
parameter to the kernel command line of my guest (note: the irq parameter is not relevant in my case, can it be ommitted?)
virtio_mmio.device=
[VMMIO] Memory mapped virtio (platform) device.
<size>@<baseaddr>:<irq>[:<id>]
where:
<size> := size (can use standard suffixes
like K, M and G)
<baseaddr> := physical base address
<irq> := interrupt number (as passed to
request_irq())
<id> := (optional) platform device id
example:
virtio_mmio.device=1K@0x100b0000:48:7
If I cat /proc/iomem I see virtio-mmio in the list
a0000000-a00003ff : virtio-mmio.0
So my main question is why is devmem on 0xA0000000 returning 0x00000000 instead of the expected value of 0x00000100? Do virtualization drivers need to be configured on the host too?
I think you may be confused about what 'virtio-mmio' is. 'virtio-mmio' is part of the "virtio" virtual device driver specification. virtio-mmio is not an "expose this host device to the guest" mechanism.
Virtio devices can be divided up into:
If a QEMU machine type has virtio-mmio transports, then that means that on the QEMU commandline you can plug in a specific backend using an option like
-device virtio-net-backend,...
. The guest can then use this in the same way it would any other emulated device.Passing the guest kernel "virtio_mmio.device=1K@0xa0000000:48" says "you should expect to see a virtio-mmio transport at this address, using this interrupt". Unless the QEMU model you're running actually put a virtio transport there, then the kernel won't do the right thing. Typically for Arm machine types this isn't necessary, because the device tree passed to the guest kernel should already define where the virtio-mmio transports are.
In general QEMU doesn't support passing through arbitrary memory-mapped host devices. (PCI device passthrough is supported, because that is much easier to manage in terms of handing the device over from the host to the guest and arranging that the guest can't then do bad things to the host with its device access.)