Skip to content

Drivers: hv: balloon: refuse to bind on a Xen PV dom0 nested under Hyper-V - #102

Merged
kaniini merged 2 commits into
edera/mainlinefrom
ariadne/eng-216-hv-balloon-nested-on-xen
Nov 13, 2026
Merged

kaniini merged 2 commits into
edera/mainlinefrom
ariadne/eng-216-hv-balloon-nested-on-xen

Conversation

@kaniini

@kaniini kaniini commented Nov 13, 2026

Copy link
Copy Markdown

On a Xen PV dom0 nested under Hyper-V, hv_balloon autoloads from the VMBus dynamic-memory offer and speaks the protocol end to end, but it was never taught about nested mode: every page range it hands L0 (balloon responses, free-page reports, hot-add requests) is a dom0 pseudo-physical range, and L0 reads those numbers as Xen machine frames. A DM_BALLOON_REQUEST from the host then has L0 reclaim whichever machine frames dom0's PFNs happen to name, which may be Xen's own memory or another domain's, with no error anywhere. A hot-add does the reverse and calls add_memory() on a host range dom0's physmap does not back, so dom0 oopses on first touch.

The probe now returns -ENODEV when hyperv_nested_on_xen is set, so the offer stays unbound. Translating the ranges would not make this correct: a PV dom0 does not own the machine memory it runs on, Xen does, and memory the L1 VM gives back to or takes from L0 has to go through Xen's heap. Dynamic memory for the L1 VM is Xen's job.

A second commit fixes the lower-severity leak noted on the same issue: hyperv_xen_vpci_root_domain() did not free the named fwnode when cpuhp_setup_state() failed after the irq domain was created.

Built with the latest linux-kernel-oci x86_64 host config (HYPERV_BALLOON=m, XEN_PV=y): full vmlinux plus hv_balloon.ko, no warnings. Not runtime-tested on a nested host.

ENG-216

…per-V

The Hyper-V-on-Xen series translates GPADLs, SynIC pages, hypercall
arguments and netvsc buffers to the machine (L1-physical) frames the L0
host expects, but hv_balloon was never taught about nested mode.  It
hands L0 page_to_pfn() ranges straight from dom0's pseudo-physical
address space, in balloon responses, free-page reports and hot-add
requests, and L0 reads each of those numbers as a Xen machine frame.

On a PV dom0 nested on Hyper-V the device autoloads from the VMBus
offer, Xen proxies POST_MESSAGE and SIGNAL_EVENT, and the dynamic memory
protocol runs end to end.  A DM_BALLOON_REQUEST from the host then has
L0 reclaim whichever machine frames dom0's PFNs happen to name: Xen's
own memory, another domain's, or unrelated dom0 memory, with no error
anywhere.  A hot-add does the reverse and calls add_memory() on a host
range that dom0's physmap does not back, so dom0 oopses on first touch.

Translating the ranges would not make this correct either.  A PV dom0
does not own the machine memory it runs on, Xen does, and the memory an
L1 VM returns to or takes from L0 has to be accounted for in Xen's heap,
not handed over behind its back by one of its domains.  Dynamic memory
for the L1 VM is a job for Xen itself.

Refuse the probe when nested on Xen, so the offer stays unbound and dom0
does not speak the protocol at all.  Nothing changes when not nested:
hyperv_nested_on_xen is a build-time false without CONFIG_XEN_PV.

Signed-off-by: Ariadne Conill <[email protected]>
…t be bound

hyperv_xen_vpci_root_domain() frees the named fwnode when creating the
irq domain fails, but not when cpuhp_setup_state() fails afterwards:
irq_domain_remove() does not free the fwnode its domain was created
with, so that path leaked it.  Free it there too.

Signed-off-by: Ariadne Conill <[email protected]>
@kaniini
kaniini merged commit a779e3f into edera/mainline Nov 13, 2026
4 checks passed
@github-actions

Copy link
Copy Markdown

Backport to edera/6.18-lts: proposed in #106

Checks and builds passed.

Run log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants