# Choose a zone virtualization backend (PV or PVH)

The `dev.edera/virt-backend` annotation and PV/PVH backends described here apply to **Xen-based** Edera nodes only. On KVM nodes, zones always run as hardware-virtualized VMs—there is no equivalent backend selection.

Every Edera zone boots with a virtualization backend that determines how the zone’s kernel runs on the hypervisor. You can leave this to Edera, or pin it per workload with a single pod annotation.

## Backends

| Backend | Hardware requirement | When it applies |
| --- | --- | --- |
| `auto` (default) | None | Follows dom0: the zone boots PVH when the host supports it, otherwise PV. |
| `pv` | None | Pure paravirtualization. Works on any instance, including cloud VMs without hardware virtualization. |
| `pvh` | VT-x / AMD-V | Paravirtualization inside a hardware-virtualized container. Better performance where hardware virtualization is available. |

When you do not specify a backend, the zone uses `auto`. The `auto` heuristic mirrors dom0: on a host where dom0 booted in PVH, zones resolve to PVH; on a host running dom0 in PV, zones resolve to PV. This is why the same manifest can come up PVH on a bare-metal node and PV on a standard cloud VM—without any change to your pod.

PVH is currently required for GPU workloads.

## Set the backend on a pod

Add the `dev.edera/virt-backend` annotation to the pod. Valid values are `auto`, `pv`, and `pvh`.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  annotations:
    dev.edera/virt-backend: pvh
spec:
  runtimeClassName: edera
  containers:
    - name: my-app
      image: my-app:latest
```

For standalone zones launched without Kubernetes, use the equivalent flag:

```bash
protect zone launch -V pvh
```

## Verify the backend a zone booted with

The backend you request is not always the backend a zone runs as—`auto` resolves at boot. To confirm what a zone actually booted with, read the Xen guest type from inside the zone:

```bash
kubectl exec my-app -- cat /sys/hypervisor/guest_type
```

The value is the authoritative answer: `PV`, `PVH`, or `HVM`.

Early in a PVH zone’s boot log, `dmesg` reports `Hypervisor detected: Xen HVM`. This is expected—PVH boots inside a hardware-virtualized container—and does not mean the zone is running in HVM mode. Trust `/sys/hypervisor/guest_type`.

## Check for PVH support before requesting it

Because `pvh` hard-fails on a host that cannot support it, confirm a host is PVH-capable _before_ you pin a workload to it.

### With edera-check (recommended)

[edera-check](https://github.com/edera-dev/edera-check) is Edera’s readiness CLI. Run `postinstall` on a host that already has Edera installed, or `preinstall` on a fresh host before installing:

```bash
sudo edera-check postinstall
```

It reports PVH capability under the **Guest Support Checks** group. On a host that cannot run PVH—for example a standard cloud VM that does not expose hardware virtualization—the group fails:

```text
Running Group Guest Support Checks [Optional] - Supported guest type checks
    • Guest Type Support: Failed: PVH guests not supported
⚠ PVH guest support not available on this system
⚠ Guest Support Checks: Failed [Optional]
```

On a PVH-capable host the group passes (`✅ Guest Support Checks: Passed`).

Guest support is an **optional** check group, so a missing-PVH result does **not** make `edera-check` exit non-zero. Read the `Guest Support Checks` result directly rather than relying on the exit code.

### Quick manual check

To check without installing anything, read the Xen guest type of the **host** (dom0)—not a zone:

```bash
cat /sys/hypervisor/guest_type
```

`PVH` means the host can run PVH zones; `PV` means it cannot—stop here and use `pv` or `auto`. This is the same file you read to verify a zone’s backend, but read on the host: because dom0 itself boots PVH wherever the hardware allows, the host’s value is a reliable proxy for what its zones can do.

## Hardware requirements and failure behavior

`pv` runs anywhere. `pvh` requires hardware virtualization extensions (VT-x or AMD-V). On most clouds those extensions are only exposed on bare-metal instances; for example, on AWS use a `.metal` instance type for PVH.

Requesting `pvh` on a host without hardware virtualization **does not fall back to PV**. The zone fails to start, and on the Kubernetes path the pod remains in `ContainerCreating` while the sandbox is repeatedly retried. For configurations that must run on mixed hardware, prefer `auto` (or omit the annotation) so each node selects the backend it can support. Reserve explicit `pvh` for workloads you know will land on hardware-virtualization-capable nodes, such as GPU nodes.
