How Google’s KHO and LUO Let Linux Swap Kernels Without Stopping Your VMs

Linux has been able to apply certain security patches to the kernel for years without shutting a machine down, but replacing the whole kernel with a different version while keeping workloads like virtual machines, databases, or in-memory services alive is a much harder problem. Two technologies developed largely around Google’s needs, Kexec HandOver (KHO) and Live Update Orchestrator (LUO), are bringing that closer to standard kernels and could change how high-availability Linux infrastructure gets maintained.

KHO and LUO in 20 seconds

  • KHO arrived in Linux kernel 6.16 and preserves memory regions during a kexec transition.
  • LUO came later in Linux 6.19 and manages preserving and recovering resources between both kernels.
  • Its main use case is cloud hypervisors, where rebooting the host would disrupt virtual machines.
  • systemd 261 already integrates LUO to preserve service file descriptors.
  • It’s still under development: swapping kernels without a traditional reboot doesn’t yet mean any server can update seamlessly.

That distinction matters, because LUO isn’t just another live patching system. Ksplice, kpatch, or KernelCare let you modify running kernel code, which is very useful for fixing specific vulnerabilities without rebooting, but the kernel stays essentially the same.

KHO and LUO do something different: they genuinely boot another kernel via kexec while trying to carry some of the workload’s state across.

Kernel documentation describes Live Update as a specialized reboot based on kexec that can move from one kernel version to another while preserving certain resources and keeping compatible devices working through the transition. The driving use case has been Linux as a hypervisor in large cloud environments.

KHO: the memory bridge between two kernels

kexec isn’t new. Linux has been able to load a new kernel from the running one for years, skipping part of the normal boot and avoiding a trip back through the machine’s firmware.

The hard part is the state.

A new kernel usually starts from a clean slate. Memory and certain resources that belonged to the previous kernel can’t just be treated as valid for the new one.

Kexec HandOver (KHO) adds infrastructure to preserve specific memory regions during that transition.

KHO landed in Linux 6.16 in 2025. The kernel documentation defines it as a mechanism that can preserve memory regions, possibly holding serialized system state, across a kexec.

It works around a structure called the Flattened Device Tree (FDT). The old kernel describes which regions to preserve, and that information is carried across the transition. The new kernel can then pull those blocks back and rebuild the matching state.

In simple terms, the process looks like this:

Linux Kernel A
      │
      ├── Discardable state
      │
      └── Memory to be preserved
                    │
                    ▼
                  KHO
                    │
                 kexec
                    │
                    ▼
Linux Kernel B
      │
      └── Restores preserved regions

The current documentation says the kernel has to be compiled with:

CONFIG_KEXEC_HANDOVER=y

and enabled at boot with:

kho=on

You can also reserve auxiliary memory zones via kho_scratch. One example from the kernel documentation is:

kho_scratch=16M,512M,256M

which reserves specific areas that stay available for operations needed during future kexecs.

Then the new kernel is loaded with the kernel’s own kexec_file loader:

kexec -l /path/to/bzImage --initrd /path/to/initrd -s

and the transition runs with:

kexec -e

The -s option is worth noting: the documentation says user-space tools currently lack equivalent LUO support with the traditional loader.

But KHO alone doesn’t solve the whole problem.

It can hand memory to the next kernel. What’s missing is understanding what that memory represents, which processes use it, and how to rebuild the resources that depend on it.

That’s where LUO comes in.

LUO: keeping workloads alive across kernel changes

Live Update Orchestrator was merged into the mainline kernel in Linux 6.19, built on the foundation KHO provides.

Its job is to coordinate the whole preservation process.

LUO manages sessions that group the resources that need to survive the transition. A user-space agent creates a session, adds the resources to preserve, and when kexec is invoked, the kernel serializes the needed information.

After the new kernel boots, the same session can be recovered by name.

The basic cycle is:

1. Create LUO session
2. Register resources
3. Preserve state
4. Freeze necessary elements
5. Execute kexec
6. Boot new kernel
7. Recover session
8. Rebuild resources
9. Resume workload

The interface usually lives at:

/dev/liveupdate

and is controlled through ioctl calls. Only one process can hold /dev/liveupdate open at a time, to stop multiple orchestrators from trying to update at once.

To enable LUO, the kernel has to boot with:

liveupdate=on

The current documentation explicitly names subsystems like KVM, IOMMU, interrupts, VFIO, memory, and certain filesystem types as potential participants in the process.

That helps explain Google’s strong interest in the project.

The hard case: updating the host without shutting down its VMs

Picture a physical server running dozens of virtual machines.

A kernel vulnerability shows up that needs an update to a new version.

The traditional route is to migrate the VMs elsewhere or shut the server down, apply the update, and reboot.

In large clouds, those operations are costly.

  • They cause visible downtime
  • Require extra capacity for migration
  • Increase network traffic
  • Extend operational time windows
  • Demand coordination across thousands of hosts

LUO imagines a different scenario.

A VM managed through QEMU/KVM keeps much of its state in memory and uses kernel resources such as memfd, VFIO, or IOMMU.

If those elements can be preserved during kexec, the host could:

Old kernel
    │
    ├── QEMU
    │    └── Running VM
    │
    ▼
Preserve memory and resources
    │
    ▼
kexec
    │
    ▼
New kernel
    │
    ├── Recover resources
    └── Reassociate them with the VM

LUO documentation states plainly that the goal is for VM workloads using vfio, memfd, or iommufd to keep their essential resources through the transition. Some devices may even keep up DMA activity while the kernel changes.

From a VM user’s point of view, that means the hypervisor kernel update should be barely noticeable, or not noticeable at all.

That’s a long way from patching a few functions.

In effect, the server ends up running another kernel.

Google also published luo-agent to run the process

The kernel provides the infrastructure, but something has to coordinate it from user space.

Google maintains the open project googleprodkernel/luo-agent, written mostly in C and licensed under GPL-2.0.

It has two main components:

luod

is the daemon that manages /dev/liveupdate.

And:

luoctl

is the admin tool used to load kernels, manage sessions, and start transitions with kexec.

The architecture keeps each application from directly controlling the whole process.

luod holds the sessions, while clients like QEMU processes subscribe over Unix socket connections.

The typical flow is roughly:

Administrator
     │
   luoctl
     │
     ▼
    luod
     │
     ├── QEMU client
     ├── Database
     └── Other compatible service
              │
              ▼
        LUO sessions
              │
              ▼
           Kernel

Per the project documentation, clients connect to:

/run/luod/liveupdate.sock

and can receive session descriptors via SCM_RIGHTS, the Unix mechanism for passing file descriptors between processes.

Before the switch, clients get a preservation request, save their resources, and respond when they’re ready.

After kexec, they reconnect with the same identifier and claim their session again.

This approach is interesting because it doesn’t force a single state format on every application. Each client knows its own resource needs better than a central orchestrator would.

systemd 261 now preserves file descriptors during updates

LUO isn’t limited to Google’s experimental agent anymore.

The current kernel documentation states plainly that systemd, since version 261, integrates LUO support and can preserve file descriptors per service during kexec-based kernel updates.

Services can set options like:

FileDescriptorStoreMax=

and:

FileDescriptorStorePreserve=

to say which descriptors to keep.

That’s significant because file descriptors are more than just numbers.

  • Open files
  • Pipes
  • Specific sockets
  • Memory via memfd
  • Resources provided by devices
  • LUO sessions

Preserving them lets a new service, after the transition, reach resources that belonged to the previous process.

Take a memory cache like memcached: its gigabytes of data could sit in a memfd, survive the change, and be reached again without rebuilding the cache from storage.

That widens LUO’s relevance well beyond hypervisors.

Databases, containers, and networking could be next

The documentation says outright that the design aims to be workload-independent.

It specifically mentions:

  • virtual machines
  • containers
  • high-performance databases
  • network services
  • in-memory caches

But there’s an important gap between the framework supporting these and any current application automatically surviving a kernel change.

LUO needs drivers that can preserve the various resource types.

So its architecture includes operations like:

can_preserve()
preserve()
freeze()
retrieve()
finish()

The old kernel has to serialize the state, and the new kernel has to know how to rebuild it.

This is extensible infrastructure, not a universal time machine for any Linux process.

In that sense, it can complement another known technology: CRIU (Checkpoint/Restore In Userspace).

CRIU can capture process states and restore them later. It’s used for container migration, checkpointing, and more.

KHO, LUO, and CRIU work on different layers, but together they open up scenarios where part of the state stays in RAM while another part is serialized and rebuilt from user space.

There’s a lot of work left before such a system becomes transparent to any application.

It’s not exactly a “zero-reboot” upgrade

This point is worth clearing up.

Saying LUO lets you change the kernel “without rebooting” is a handy summary but can be technically misleading.

There is a kernel restart.

LUO uses kexec. The old kernel stops running and a new one starts.

What gets removed is the traditional full machine reboot and, above all, the interruption of the workloads that depend on it.

The full cycle like:

power off
BIOS/UEFI
firmware
bootloader
kernel
services
applications

is replaced by:

old kernel
      │
    kexec
      │
new kernel

and KHO/LUO try to carry enough state between the two.

That distinction is key, because it also defines the limits.

Firmware changes, certain hardware modifications, or problems that need a physical device reset will still call for other kinds of maintenance.

LUO doesn’t replace live patching

Technologies like Kpatch, Ksplice, and similar still make sense.

They serve different needs than LUO.

Live patching would be:

Kernel 6.x
   │
Apply patch
   │
Kernel 6.x modified

LUO, on the other hand, proposes:

Kernel A
   │
preserve state
   │
kexec
   │
Kernel B

For a small vulnerability, patching a few functions may be less risky than replacing the whole kernel.

But live patching has limits.

Not every change can be turned into a live patch, and over time gaps can build up between the original kernel and its patched version.

A full transition lets you run the kernel with every fix applied.

That’s why both can coexist: live patching for quick fixes and LUO for full updates with minimal downtime.

Caution: not for instant production deployment

Even though the technology is now in the mainline kernel, it’s still immature.

The official Live Update API documentation warns outright that it’s still under development and that compatibility can’t yet be guaranteed across different kernel versions. Stability is expected in a later phase.

KHO also keeps debug interfaces that the documentation warns could change as the subsystem stabilizes.

So finding CONFIG_KEXEC_HANDOVER or LUO support in a distribution doesn’t automatically make this mechanism ready for critical servers.

For example, the current luo-agent repository requires a Linux 6.19 or newer kernel with CONFIG_LIVEUPDATE enabled.

A test setup might include:

kho=on
kho_scratch=16M,512M,256M
liveupdate=on

but that only turns on the kernel features. The workloads themselves also have to support resource preservation.

Why this matters more now than ten years ago

Kernel reboot headaches aren’t new.

What’s changed is the scale of the infrastructure running on Linux.

A cloud provider can have thousands of physical hypervisors. A single host can run dozens or hundreds of VMs.

When a serious vulnerability lands, updating isn’t just scheduling a nightly reboot.

  • VMs have to be evacuated or migrated
  • The host has to be updated and rebooted
  • Extra capacity is needed for migration traffic
  • Coordination across many hosts is required
  • Operational mistakes could cause outages

In data centers with GPUs, the operations get even harder, thanks to resource costs and device passthrough or VFIO configurations.

On top of that, automated vulnerability discovery is speeding up how fast new software flaws turn up. AI tools are contributing, but the current volume of kernel vulnerabilities can’t be pinned on them alone.

Cutting the operational cost of fast kernel updates lowers the temptation to delay patches.

That’s probably where the real significance of KHO and LUO sits.

They aren’t claiming Linux never needs a reboot.

They’re about splitting two tasks that were traditionally linked:

updating the host OS and stopping the running workloads.

If that split proves stable with VMs, devices, containers, networks, and databases, a kernel update could start to feel much more like routine maintenance.

That day hasn’t arrived yet.

But with Linux 6.16 and KHO, Linux 6.19 and LUO, and systemd 261 with file-descriptor support, the core pieces are no longer just experimental. They’ve become part of the standard Linux infrastructure.

Frequently Asked Questions

Can Linux now update any kernel without rebooting the server?

Not transparently for every system. KHO and LUO enable kexec transitions that preserve certain state and resources, but they need kernel, user-space, and application support.

How is LUO different from Kpatch or Ksplice?

Kpatch and Ksplice do hot patches, modifying the running kernel without rebooting. LUO boots a different kernel via kexec while trying to preserve workload resources.

Which Linux versions include KHO and LUO?

Kexec HandOver arrived in Linux 6.16. Live Update Orchestrator appeared in Linux 6.19. systemd added support starting with version 261.

What is Google’s luo-agent for?

luo-agent provides the user-space components that coordinate LUO. It includes the luod daemon and the luoctl tool for loading kernels, managing sessions, and starting kexec transitions.

Sources:

  • Linux Kernel Documentation, Kexec HandOver (KHO).
  • Linux Kernel Documentation, Live Update Orchestrator and Live Update uAPI.
  • Google Production Kernel, open project luo-agent on GitHub.
  • systemd 261, file descriptor store integration with LUO.
  • Phoronix coverage of KHO in Linux 6.16 and LUO in Linux 6.19.
Scroll to Top