Skip to content

Broken Xen PVH boot #2136

@niklasfemerstrand

Description

@niklasfemerstrand

Nanos already provides pvh_start() and the __xen_guest ELF note but booting Nanos as a PVH guest triple faults during early init because:

  1. pvh_start() is called with RSP=0.
  2. hvm_start_info memory map is ignored.
  3. ACPI init is called unconditionally but PVH has no ACPI tables.
  4. PVH has no local APIC but init_apic() tries to read MADT and APIC MMIO.
  5. Running a Xen PVH guest exposes a latent bug in init_physical_heap() where break after finding bootstrap regions skips low-memory trimming of remaining regions.

init_physical_heap bug detail

Nanos currently performs trimming and bootstrap search in one loop:

for_regions(e) {
    if (e->type == REGION_PHYSICAL) {
        if (e->base < MB) { /* trim */ }
        if (length >= BOOTSTRAP_SIZE) {
            /* found bootstrap */
            break;  // remaining regions never get trimmed
        }
    }
}

Xen allocates RAM starting at address 0x0. After setup_initmap splits around the kernel load address, there are two regions:

Region 0: [0x00000000, 0x00200000)  2 MB
Region 1: [0x00600000, 0x10000000)  ~250 MB

for_regions visits Region 1 first (large enough for bootstrap) and break. Region 0 never gets trimmed, instead its sub-1 MB pages enter the heap, get allocated, and fault because identity mapping below 1 MB are forbidden.

Testing

All existing QEMU tests pass (16 unit + 31 runtime via make test-noaccel).

Boot any PVH guest on Xen 4.20:

name    = "nanos-pvh"
type    = "pvh"
memory  = 256
vcpus   = 1
kernel  = "/kernel.img"
disk    = ["file:/app.img,xvda,w"]
vif     = ["bridge=xenbr0"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions