Backends: QEMU & AVF
Podroid has two VM engines behind one setting. The default uses QEMU with software CPU emulation and works on any device. On Pixel 8/9/10 and similar devices that ship pKVM, the AVF backend runs the guest on real CPU cores for near-native speed.
Choosing a backend
Go to Settings → Advanced → Backend. The three options are:
- Auto (default) - Podroid probes the device at startup and uses AVF if the feature, both permissions, and non-protected VM support are all present; otherwise it falls back to QEMU. This is the right choice for most users.
- AVF (KVM) - always use AVF; the VM will fail to start if the prerequisites are not met.
- QEMU (TCG) - always use software emulation, even on a device that supports AVF.
Changing the backend setting takes effect at the next VM start. The VM must be stopped before you switch.
QEMU (TCG)
The QEMU backend is the default and works on any ARM64 Android 9+ device with no setup beyond installing the app. The guest CPU is emulated in software via TCG (Tiny Code Generator). See Performance & why it's slow for a full explanation of where the overhead comes from and what Podroid does to reduce it. The short version: simple workloads are 2-5x slower than native; JIT-heavy workloads (Node, JVM, compilers) are slower still because of double-JIT and cold-cache process-spawn costs.
QEMU supports both TCP and UDP port forwarding. Rules you configure in the Port Forwarding screen work for both protocols.
AVF (pKVM)
The Android Virtualization Framework (AVF) is a system hypervisor shipped on some Android devices. On devices that include pKVM (protected Kernel-based Virtual Machine), Podroid can run the guest directly on physical CPU cores - no TCG translation, no double-JIT, no cold-cache overhead. CPU-bound tasks that crawl on QEMU run at near-native speed on AVF.
AVF is currently available on Pixel 8, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL, and Pixel 10 series devices (and any other Android device your manufacturer ships with pKVM). Two development-mode permissions must be granted once before Podroid can open a VM.
Setting up AVF
Step 1 - Confirm the device supports AVF. Run the following in a terminal with ADB access to the device:
$ adb shell pm list features | grep virtualization_framework
If the command prints a line containing android.software.virtualization_framework, the device supports AVF. If the command prints nothing, the device does not have pKVM and AVF is not available.
Step 2 - Grant the two permissions. These are development-mode permissions not exposed in the system UI. Grant them over ADB:
$ adb shell pm grant com.excp.podroid android.permission.MANAGE_VIRTUAL_MACHINE
$ adb shell pm grant com.excp.podroid android.permission.USE_CUSTOM_VIRTUAL_MACHINE
If you do not have a computer handy, install Shizuku and start it (over ADB or wireless debugging). Then open Shizuku's rish shell and run the same two pm grant lines above, replacing adb shell with just the pm grant ... command directly inside rish.
Step 3 - Run the AVF diagnostic. In Podroid, go to Settings → About → "AVF (pKVM) diagnostic". This runs a probe and a smoke test that checks: the virtualization_framework feature flag, both permissions, the presence of /apex/com.android.virt, the AVF system service, and the hypervisor capabilities reported by the kernel. If it reports success on all points, you are ready. Set Backend to Auto (or AVF if you want to force it) and start the VM.
Permission lifetime
The two pm grant permissions persist across reboots and in-place app updates. You do not need to re-grant them after an OTA or a Podroid update installed over the existing app. However, they are lost on uninstall: if you uninstall and reinstall Podroid, run the two pm grant commands again before using AVF.
How Auto-selection works
When the backend is set to Auto, Podroid checks four conditions at startup: (1) the android.software.virtualization_framework feature is present, (2) MANAGE_VIRTUAL_MACHINE is granted, (3) USE_CUSTOM_VIRTUAL_MACHINE is granted, and (4) the device advertises support for non-protected VMs. All four must pass. If any fails, Podroid silently falls back to QEMU - no error, the VM just starts with software emulation.
Condition (4) is the non-obvious one. pKVM can operate in two modes: protected (guest memory is encrypted and the host cannot inspect it) and non-protected. Podroid's guest image is a standard Alpine Linux squashfs - it does not meet the signing and measurement requirements for protected VMs. A device that only advertises protected VM support cannot run Podroid's image under AVF, so Auto falls back to QEMU on such devices.
If your device only supports protected VMs, AVF cannot run Podroid's custom kernel and there is no app-side workaround: the protected-VM firmware (pvmfw) only boots payloads that carry a signed, verified boot image, which a general-purpose Linux kernel does not. The only remaining route to hardware virtualization is to open the hypervisor device node (/dev/kvm, or /dev/gunyah on Qualcomm SoCs) directly, which requires root. Podroid is deliberately no-root, so it uses QEMU on these devices. If you are rooted and on a recent Qualcomm Snapdragon device (8 Gen 3 / SM8650 or newer with Gunyah enabled), a separate, unaffiliated project, DroidVM, runs VMs through the Gunyah hypervisor or KVM for near-native speed.
Differences between backends
| Feature | QEMU (TCG) | AVF (pKVM) |
|---|---|---|
| Device requirement | Any ARM64 Android 9+ | Device must ship pKVM (recent Pixels and select others) |
| Setup required | None | Two pm grant commands (once) |
| CPU speed | Software emulation (2-5x+ overhead) | Near-native (hardware VMs, no TCG) |
| Port forwarding protocols | TCP and UDP | TCP only (UDP rules are silently ignored) |
| vCPU count | Configurable (1 to device core count) | 1 vCPU = one physical core; >1 vCPU = all host cores |
| Terminal console | hvc0 via QEMU virtio-console | hvc0 (same guest view, different host path) |
| Downloads folder sharing | Supported | May be a no-op on shipping Pixel AVF builds (requires an AOSP-main SharedPath API not yet in stable releases) |
| Verbose logging toggle | Not applicable | "Verbose AVF logging" in Settings → Advanced (useful for bug reports) |
Some Pixel 8, Pixel 8a, and Pixel 9 units reboot the device during AVF VM startup. This appears to be a pKVM firmware issue on certain builds. If AVF causes a reboot, switch the backend to QEMU (TCG) in Settings → Advanced. QEMU is the reliable fallback on all devices. See Limitations & troubleshooting for the current status.
Podroid is free software (GPL). Docs for v1.2.1. Found something inaccurate? Open an issue.