DEV Community

David Tio
David Tio

Posted on • Originally published at blog.dtio.app

KVM Acceleration in a Rootless Podman Container: Before and After

KVM Acceleration in a Rootless Podman Container: Before and After

Quick one-liner: Pass /dev/kvm into your Podman container, boot Alpine Linux with -nographic, and time the difference between software emulation and hardware acceleration.


Why This Matters

In Post #1, we built a custom qemu:base container image with QEMU fully installed. I mentioned that if you tried to boot a VM without KVM it would be crawling slow. Let's test that theory.

Without KVM, QEMU runs in pure software emulation mode. Every single CPU instruction your VM executes gets translated and re-executed by QEMU on the host. Your modern multi-GHz processor spends most of its time pretending to be a slower, imaginary processor. An OS that boots in 10 seconds on bare metal can take 5–10 minutes in software emulation.

KVM changes everything. KVM (Kernel-based Virtual Machine) is a Linux kernel module that exposes your CPU's hardware virtualization extensions — Intel VT-x or AMD-V — to user-space software like QEMU. Instead of translating instructions, QEMU hands them directly to the CPU. The VM runs at near-native speed.

This post makes that difference measurable. You'll boot Alpine Linux twice — once without KVM, once with — and time both. The gap is dramatic.


Prerequisites

  • qemu:base image from Post #1
  • A host CPU with Intel VT-x or AMD-V (most CPUs made after 2010)
  • Virtualization enabled in your BIOS/UEFI
  • Alpine Linux 3.23.3 x86_64 ISO (~347 MB) downloaded to your machine

Step 1: Get the Alpine ISO

Alpine Linux is the perfect test ISO: it's tiny, boots fast, and drops you to a login prompt with minimal fanfare. That makes boot time easy to measure.

Download the standard x86_64 ISO:

$ wget https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/x86_64/alpine-standard-3.23.3-x86_64.iso \
    -O ~/Downloads/alpine-standard-3.23.3-x86_64.iso
Enter fullscreen mode Exit fullscreen mode

The download is ~347 MB. Once it's on disk, you'll mount ~/Downloads into the container as /vms.


Step 2: Boot WITHOUT KVM (baseline)

Let's establish the baseline. This is pure software emulation — no KVM, no hardware acceleration.

$ time podman run --rm -it \
    -v ~/Downloads:/vms:z \
    qemu:base \
    qemu-system-x86_64 \
        -nographic \
        -m 512 \
        -cdrom /vms/alpine-standard-3.23.3-x86_64.iso
Enter fullscreen mode Exit fullscreen mode

Watch the output. QEMU will print boot messages, then Alpine's init system will work through its startup sequence. You'll eventually see:

localhost login:
Enter fullscreen mode Exit fullscreen mode

When you see the login prompt, press Ctrl+A then X to exit QEMU. The time command will print how long it took.

On my machine this came in at ~22 seconds. Alpine is small enough that even software emulation is bearable. Write your number down — the comparison with KVM is still telling.


Step 3: Verify KVM is Available on Your Host

Before adding --device /dev/kvm, check that KVM is actually available:

$ ls -la /dev/kvm
Enter fullscreen mode Exit fullscreen mode

You should see something like:

crw-rw----+ 1 root kvm 10, 232 Mar 30 09:00 /dev/kvm
Enter fullscreen mode Exit fullscreen mode

If /dev/kvm doesn't exist, either:

  1. Virtualization is disabled in your BIOS. Reboot, enter your UEFI settings, and look for "Intel Virtualization Technology", "VT-x", or "AMD-V". Enable it.
  2. The KVM kernel module isn't loaded. Run sudo modprobe kvm_intel (or kvm_amd for AMD CPUs).

Also check that your user can access the device:

$ stat /dev/kvm
Enter fullscreen mode Exit fullscreen mode

Rootless Podman passes device permissions through automatically, but your user needs read-write access to /dev/kvm on the host. If you're in the kvm group, you're set:

$ groups | grep kvm
Enter fullscreen mode Exit fullscreen mode

If not: sudo usermod -aG kvm $USER, then log out and back in.


Step 4: Boot WITH KVM

Same command, two additions: --device /dev/kvm for Podman, and -enable-kvm -cpu host for QEMU.

$ time podman run --rm -it \
    --device /dev/kvm \
    -v ~/Downloads:/vms:z \
    qemu:base \
    qemu-system-x86_64 \
        -enable-kvm \
        -cpu host \
        -nographic \
        -m 512 \
        -cdrom /vms/alpine-standard-3.23.3-x86_64.iso
Enter fullscreen mode Exit fullscreen mode

The difference is immediate. Boot messages scroll by quickly. Alpine's init sequence runs in seconds.

Press Ctrl+A then X to exit and check the time output. On my machine:

# Without KVM
real    0m21.868s

# With KVM
real    0m7.814s
Enter fullscreen mode Exit fullscreen mode

3x faster — and that's on a lightweight OS that was already tolerable in software emulation. On a heavier OS the gap is far wider.


Step 5: What the Flags Do

Flag Where What It Does
--device /dev/kvm Podman Passes the KVM character device into the container namespace
-enable-kvm QEMU Tells QEMU to use the KVM kernel module instead of software emulation
-cpu host QEMU Exposes the host's actual CPU model and features to the VM (required for full KVM benefit)
-nographic QEMU Disables the graphical window — redirects all serial output to the terminal
-m 512 QEMU Allocates 512 MB RAM to the VM
-cdrom /vms/alpine-standard-3.23.3-x86_64.iso QEMU Boots from the mounted ISO
-v ~/Downloads:/vms:z Podman Bind-mounts your Downloads directory; :z sets SELinux relabeling

Why -cpu host and not -cpu qemu64? The default QEMU CPU model (qemu64) is a minimal baseline that works everywhere but exposes no modern CPU extensions. With -cpu host, QEMU passes through all of your CPU's features — AVX, AES-NI, etc. — which is both faster and more realistic for testing.

Why does rootless Podman allow /dev/kvm? Podman uses the --device flag to grant access to specific devices without requiring --privileged. The container gets read-write access to /dev/kvm only, nothing else. This is much safer than running the whole container as root.


What You've Built

  • ✅ KVM device passed into a rootless Podman container
  • ✅ Alpine Linux booted inside the container with hardware acceleration
  • ✅ Before/after timing comparison showing the real-world difference
  • ✅ Hardware-accelerated VM running without root privileges

What's Next?

Right now, every time you stop the container, the VM state disappears. Alpine loses any changes you made. The ISO is read-only. The VM has no persistent disk.

Post #3: We'll create a persistent disk image with qemu-img, attach it to the VM, and install Alpine properly — so the VM survives container restarts.


This guide is Part 2 of the KVM Virtual Machines on Podman series.

Part 1: Build a KVM-Ready Container Image from Scratch
Coming up in Part 3: Persistent Disk Images — Keep Your VM Between Runs


Found this helpful?


Published: 30 Mar 2026
Author: David Tio
Tags: KVM, QEMU, Podman, Virtualization, Containers, Alpine Linux, Linux, Tutorial
Series: KVM Virtual Machines on Podman
Word Count: ~900


SEO Metadata:

  • Title: KVM Acceleration in a Rootless Podman Container: Before and After (2026)
  • Meta Description: Enable KVM hardware acceleration in a rootless Podman container. Boot Alpine Linux with and without KVM, time the difference, and understand every flag involved.
  • Target Keywords: kvm podman rootless, enable kvm container, --device /dev/kvm podman, qemu kvm acceleration, alpine linux qemu container, hardware virtualization podman
  • Series: KVM Virtual Machines on Podman

Top comments (0)