Difference between revisions of "R-Car/Virtualization/VFIO"
< R-Car | Virtualization
(Fill in QEMU branch.) |
(Reset support has been implemented) |
||
Line 16: | Line 16: | ||
* Configure workarounds for missing functionality: | * Configure workarounds for missing functionality: | ||
<pre> | <pre> | ||
− | |||
$ echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode | $ echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode | ||
</pre> | </pre> | ||
Line 67: | Line 66: | ||
-kernel /path/to/guest/kernel/Image \ | -kernel /path/to/guest/kernel/Image \ | ||
-device vfio-platform,host=e6055400.gpio,manufacturer=renesas,model=rcar-gen3-gpio | -device vfio-platform,host=e6055400.gpio,manufacturer=renesas,model=rcar-gen3-gpio | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre> | </pre> | ||
Line 78: | Line 71: | ||
<pre> | <pre> | ||
Booting Linux on physical CPU 0x0000000000 [0x411fd073] | Booting Linux on physical CPU 0x0000000000 [0x411fd073] | ||
+ | Linux version 4.15.0-arm64-virt-00009-g1e04d78a91abdbbd ... | ||
... | ... | ||
gpio_rcar c000000.e6055400.gpio: missing clock, ignoring | gpio_rcar c000000.e6055400.gpio: missing clock, ignoring | ||
Line 83: | Line 77: | ||
gpio_rcar c000000.e6055400.gpio: driving 32 GPIOs | gpio_rcar c000000.e6055400.gpio: driving 32 GPIOs | ||
... | ... | ||
+ | </pre> | ||
+ | |||
+ | Host kernel output: | ||
+ | <pre> | ||
+ | vfio-platform e6055400.gpio: reset | ||
+ | vfio-platform e6055400.gpio: vfio-noiommu device opened by user (qemu-system-aar:3003) | ||
</pre> | </pre> | ||
Line 107: | Line 107: | ||
* Export GPIOs used for LEDs, and turn all LEDs off: | * Export GPIOs used for LEDs, and turn all LEDs off: | ||
<pre> | <pre> | ||
− | base=$(cat /sys/class/gpio/gpiochip*/base) | + | # base=$(cat /sys/class/gpio/gpiochip*/base) |
− | for i in | + | # for i in 11 12 13; do |
echo $(($base + $i)) > /sys/class/gpio/export | echo $(($base + $i)) > /sys/class/gpio/export | ||
echo low > /sys/class/gpio/gpio$(($base + $i))/direction | echo low > /sys/class/gpio/gpio$(($base + $i))/direction | ||
Line 116: | Line 116: | ||
* Cycle through all LEDs, letting them blink once: | * Cycle through all LEDs, letting them blink once: | ||
<pre> | <pre> | ||
− | for i in | + | # for i in 11 12 13; do |
echo high > /sys/class/gpio/gpio$(($base + $i))/direction | echo high > /sys/class/gpio/gpio$(($base + $i))/direction | ||
sleep 1 | sleep 1 | ||
Line 122: | Line 122: | ||
done | done | ||
</pre> | </pre> | ||
+ | |||
+ | * Shut the guest down: | ||
+ | <pre> | ||
+ | # poweroff | ||
+ | </pre> | ||
+ | |||
+ | Guest kernel output: | ||
+ | <pre> | ||
+ | reboot: Power down | ||
+ | </pre> | ||
+ | |||
+ | Host kernel output: | ||
+ | <pre> | ||
+ | vfio-platform e6055400.gpio: reset | ||
+ | </pre> | ||
+ | |||
+ | The GPIO module has been reset, turning on all three LEDs. | ||
== Future Work == | == Future Work == | ||
− | |||
* IOMMU groups | * IOMMU groups | ||
* Interrupts | * Interrupts | ||
* Clocks | * Clocks | ||
* PM Domains | * PM Domains |
Revision as of 09:05, 13 February 2018
Device Pass-Through Using VFIO
Platform Device Pass-Through Prototype
This is a proof-of-concept showing how to provide guest access to an R-Car GPIO controller block on the Renesas Salvator-X and Salvator-XS boards.
Host Side
- Build and boot a host kernel using:
- Repository: https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
- Branch: "topic/rcar3-virt-gpio-passthrough"
- Config: "renesas_defconfig"
- Configure workarounds for missing functionality:
$ echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
- Unbind GPIO6 from the "gpio-rcar" driver:
$ echo e6055400.gpio > /sys/bus/platform/drivers/gpio_rcar/unbind gpio gpiochip6: REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED
- Bind GPIO6 to the "vfio-platform" driver, for pass-through to guests:
$ echo vfio-platform > /sys/bus/platform/devices/e6055400.gpio/driver_override $ echo e6055400.gpio > /sys/bus/platform/drivers/vfio-platform/bind iommu: Adding device e6055400.gpio to group 0 vfio-platform e6055400.gpio: Adding kernel taint for vfio-noiommu group on device
Guest Side
- Build a guest kernel using:
- Repository: https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
- Branch: "topic/rcar3-virt-gpio-passthrough"
- Config: "virt_defconfig"
- Build QEMU using:
- Repository: https://github.com/geertu/qemu.git
- Branch: "topic/rcar3-virt-gpio-passthrough"
- When starting QEMU, specify pass-through of the GPIO6 platform device. The device specifier consists of three parts:
- $1a
- the device's node name, or
- $1b
- the full path to the device's node in sysfs,
- $2
- the manufacturer part of the device's compatible value,
- $3
- the model part of the device's compatible value.
I.e.:
-device vfio-platform,host=$1a,manufacturer=$2,model=$3 -device vfio-platform,host=e6055400.gpio,manufacturer=renesas,model=rcar-gen3-gpio -device vfio-platform,sysfsdev=$1b,manufacturer=$2,model=$3 -device vfio-platform,sysfsdev=/sys/bus/platform/devices/e6055400.gpio,manufacturer=renesas,model=rcar-gen3-gpio
Full command line:
$ qemu-system-aarch64 -enable-kvm -M virt -cpu cortex-a57 -m 1024 -nographic \ -kernel /path/to/guest/kernel/Image \ -device vfio-platform,host=e6055400.gpio,manufacturer=renesas,model=rcar-gen3-gpio
Guest kernel output:
Booting Linux on physical CPU 0x0000000000 [0x411fd073] Linux version 4.15.0-arm64-virt-00009-g1e04d78a91abdbbd ... ... gpio_rcar c000000.e6055400.gpio: missing clock, ignoring gpio_rcar c000000.e6055400.gpio: missing IRQ, ignoring gpio_rcar c000000.e6055400.gpio: driving 32 GPIOs ...
Host kernel output:
vfio-platform e6055400.gpio: reset vfio-platform e6055400.gpio: vfio-noiommu device opened by user (qemu-system-aar:3003)
- Analysis of "/sys/firmware/devicetree/base" using "dtx_diff" shows that "e6055400.gpio@0" has been added as a subnode to the existing "platform@c000000" node:
--- /sys/firmware/devicetree/base.orig +++ /sys/firmware/devicetree/base @@ -124,6 +124,13 @@ compatible = "qemu,platform", "simple-bus"; interrupt-parent = <0x8001>; ranges = <0x0 0x0 0xc000000 0x2000000>; + + e6055400.gpio@0 { + #gpio-cells = <0x2>; + compatible = "renesas,rcar-gen3-gpio"; + gpio-controller; + reg = <0x0 0x50>; + }; }; pmu {
- Export GPIOs used for LEDs, and turn all LEDs off:
# base=$(cat /sys/class/gpio/gpiochip*/base) # for i in 11 12 13; do echo $(($base + $i)) > /sys/class/gpio/export echo low > /sys/class/gpio/gpio$(($base + $i))/direction done
- Cycle through all LEDs, letting them blink once:
# for i in 11 12 13; do echo high > /sys/class/gpio/gpio$(($base + $i))/direction sleep 1 echo low > /sys/class/gpio/gpio$(($base + $i))/direction done
- Shut the guest down:
# poweroff
Guest kernel output:
reboot: Power down
Host kernel output:
vfio-platform e6055400.gpio: reset
The GPIO module has been reset, turning on all three LEDs.
Future Work
- IOMMU groups
- Interrupts
- Clocks
- PM Domains