|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: hvmloader - allow_memory_relocate overlaps
On 2023-12-19 17:12, Jan Beulich wrote:
> On 16.12.2023 08:01, Neowutran wrote:
> > I am wondering if the variable "allow_memory_relocate" is still
> > relevant today and if its default value is still relevant.
> > Should it be defined to 0 by default instead of 1 (it seems to be a
> > workaround for qemu-traditional, so maybe an outdated default value ? ) ?
>
> So are you saying you use qemu-trad?
No, I am using "qemu_xen" ( from
xenstore-read -> 'device-model =
"qemu_xen"'
> Otherwise isn't libxl suppressing this behavior anyway?
If by "isn't libxl suppressing this behavior" you means if libxl is setting
the value of "allow_memory_relocate", then the answer is no.
Following this lead, I checked in what code path
"allow_memory_relocate" could be defined.
It is only defined in one code path,
In the file "tools/libs/light/libxl_dm.c",
in the function "void libxl__spawn_local_dm(libxl__egc *egc,
libxl__dm_spawn_state *dmss)":
'''
// ...
if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
// ...
libxl__xs_printf(gc, XBT_NULL,
GCSPRINTF("%s/hvmloader/allow-memory-relocate", path),
"%d",
b_info->device_model_version==LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL &&
!libxl__vnuma_configured(b_info));
// ...
'''
However, on QubesOS (my system), "local_dm" is never used, "stub_dm"
is always used.
In the function "void lib
xl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)",
the value of "allow_memory_relocate" is never defined.
I tried to patch the code to define "allow_memory_relocate" in
"libxl__spawn_stub_dm":
'''
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -2431,6 +2431,10 @@ void libxl__spawn_stub_dm(libxl__egc *egc,
libxl__stub_dm_spawn_state *sdss)
libxl__xs_get_dompath(gc, guest_domid)),
"%s",
libxl_bios_type_to_string(guest_config->b_info.u.hvm.bios));
+ libxl__xs_printf(gc, XBT_NULL,
+ libxl__sprintf(gc,
"%s/hvmloader/allow-memory-relocate", libxl__xs_get_dompath(gc, guest_domid)),
+ "%d",
+ 0);
}
ret = xc_domain_set_target(ctx->xch, dm_domid, guest_domid);
if (ret<0) {
'''
And it is indeed another way to solve my issue.
However I do not understand the xen hypervisor enough to known i
f
"allow-memory-relocate" should have been defined in
"libxl__spawn_stub_dm" or if the real issue is somewhere else.
> Or did that code go stale?
>
> > Code extract:
> >
> > tools/firmware/hvmloader/pci.c
> > "
> > /*
> > * Do we allow hvmloader to relocate guest memory in order to
> > * increase the size of the lowmem MMIO hole? Defaulting to 1
> > * here will
> > mean that non-libxl toolstacks (including xend and
> > * home-grown ones) means that those using qemu-xen will still
> > * experience the memory relocation bug described below; but it
> > * also means that those using q
> > emu-traditional will *not*
> > * experience any change; and it also means that there is a
> > * work-around for those using qemu-xen, namely switching to
> > * qemu-traditional.
> > *
> > * If we defaulted to 0, and failing to resize the hole caused any
> > * problems with qemu-traditional, then there is no work-around.
> > *
> > * Since xend can
only use qemu-traditional, I think this is the
> > * option that will have the least impact.
> > */
> > bool allow_memory_relocate = 1;
> > "
> >
> > "
> > /*
> > * At the moment qemu-xen can't deal with relocated memory regions.
> > * It's too close to the release to make a proper fix; for now,
> > * only allow t
> > he MMIO hole to grow large enough to move guest memory
> > * if we're running qemu-traditional. Items that don't fit will be
> > * relocated into the 64-bit address space.
> > *
> > * This loop now does the following:
> > * - If allow_memory_relocate, increase the MMIO hole until it's
> > * big enough, or
> > until it's 2GiB
> > * - If !allow_memory_relocate, increase the MMIO hole until it's
> > * big enough, or until it's 2GiB, or until it overlaps guest
> > * memory
> > */
> > while ( (mmio_total > (pci_mem_end - pci_mem_start))
> >
&& ((pci_mem_start << 1) != 0)
> > && (allow_memory_relocate
> > || (((pci_mem_start << 1) >> PAGE_SHIFT)
> > >= hvm_info->low_mem_pgend)) )
> > pci_mem_start <<= 1;
> > "
> >
> > The issue it cause is documented in the source code: guest memory can
> > be trashed by the hvmloader.
> >
> > Due to this issue, it is impossible to passthrough a large PCI device to a
> > HVM with a lot of ram.
> > (https://github.com/QubesOS/qubes-issues/issues/4321).
> >
> > (Forcing "allow_memory_relocate" to be 0 seems to solve the issue
> > linked)
>
> What I don't understand here (and what I also can't find helpful logs for)
> is: The code in hvmloader is in principle intended to work in both cases.
> If there's suspected guest memory corruption, can we get to see the actual
> results of the MMIO hole creation and its using for device ranges? If there
> indeed is an overlap with guest RAM, that's a bug which wants fixing.
tools/firmware/
hvmloader/pci.c, function "void pci_setup(void)"
I added a log to print if the hvmloader would have tried to overlaps
guest memory
'''
+ printf("NEOWUTRAN pci.c: pci_mem_end: %d\n",pci_mem_end);
+ printf("NEOWUTRAN pci.c: pci_mem_start: %d\n",pci_mem_start);
+ printf("NEOWUTRAN pci.c: allow_memory_relocate:
%d\n",allow_memory_relocate);
+ printf("NEOWUTRAN pci.c: hvm_info->low_mem_pgend:
%d\n",hvm_info->low_mem_pgend);
+
+
while ( (mmio_total > (pci_mem_end - pci_mem_start))
&& ((pci_mem_start << 1) != 0)
&& (allow_memory_relocate
|| (((pci_mem_start << 1) >> PAGE_SHIFT)
>= hvm_info->low_mem_pgend)) )
pci_mem_start <<= 1;
+ if ( (mmio_total > (pci_mem_end - pci_mem_start))
+ && ((pci_mem_start << 1) != 0)
+ && (1
+ || (((pci_mem_start << 1) >> PAGE_SHIFT)
+ >= hvm_info->low_mem_pgend)) ){
+
printf("NEOWUTRAN pci.c: HVM_LOADER would have tried to relocate guest
memory\n");
+ printf("NEOWUTRAN pci.c: pci_mem_start: %d\n",pci_mem_start);
+
+ }
'''
And the associated result is:
(d22) NEOWUTRAN pci.c: pci_mem_end: -67108864
(d22) NEOWUTRAN pci.c: pci_mem_start: -268435456
(d22) NEOWUTRAN pci.c: allow_memory_relocate: 0
(d22) NEOWUTRAN pci.c: hvm_info->low_mem_pgend: 983040
(d22) NEOWUTRAN pci.c: HVM_LOADER would have tried to relocate guest memory
(d22) NEOWUTRAN pci.c: pci_mem_start: -268435456
So if "allow_memory_relocate" was not defined to 0, the hvmloader
would have tried to overlaps guest memory, and it seems that is
something that qemu_xen cannot handle.
> I
> don't see why we would want to drop allow_memory_relocate in the way you
> suggest; quite the other way around, if upstream qemu still can't tolerate
> hvmloader doing this, then it wants fixing there such that RAM relocation
> can be enabled unconditionally. Then the variable will indeed not be needed
> anymor
e.
I can send different logs or try different things if needed
>
> Jan
Thanks,
Neowutran
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |