RE: input/output error _at_boot

From: Dexuan Cui <decui_at_microsoft.com>
Date: Thu, 9 Mar 2017 13:03:46 +0000
> From: owner-freebsd-current_at_freebsd.org [mailto:owner-freebsd-
> current_at_freebsd.org] On Behalf Of Toomas Soome
>
> IMO there are multiple issues around this problem and workaround.
>
> First of all, to control UEFI memory allocation, the AllocatePages() has options:
>
> AllocateAnyPages,
> AllocateMaxAddress,
> AllocateAddress
>
> On x86, we use:
>
>         staging = 1024*1024*1024;
>         status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData,
>             nr_pages, &staging);
>
> Which means:
>
> "Allocation requests of Type AllocateMaxAddress allocate any available range of
> pages whose uppermost address is less than or equal to the address pointed to
> by Memory on input.”
>
> So, we are asking for an amount of memory (64MB), with condition that all the
> pages should be below 1GB.
>
> And we get it. If hyper-v is in fact returning us memory from already occupied
> area - there can be exactly one conclusion - it is bug in hyper-v.

Hyper-V has no bug here: Hyper-V doesn't return memory from already occupied
area. The issue is: the loader here tries to write the 64MB staging area (BTW, it's
48MB in 10.3) into the physical memory range [2MB, 2MB+64MB) -- the loader
assumes this range is writable. However, this is not true with Hyper-V EFI
firmware: there is a read-only BootServicesData memory block starting at
about 47.449MB, causing a crash in the loader.

If you're interested, the whole long story is in the below link.  :-)
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=211746, e.g. please see the
screenshot in comment #8.


> Note, this allocation method does *not* set the starting point for allocation, it
> can return us *any* chunk of memory of given size, below 1GB.
Yes. This can potentially cause new issues...

> So the attempt to control such allocation by size, is unfortunately flawed - it
> really does not control the allocation.
Yes, you're correct.
The patch is flawed. I only expect (or hope) it can work around the issues with
typical Hyper-V UEFI firmware.
In my test, it works with Hyper-V 2012 R2 and 2016.
I hope it could work in future Hyper-V too...

> Note that I have also seen AllocateAddress failures - there was nicely available
> chunk of memory, but the firmware just did not allocate with given address (it
> did happen with OVMF + qemu).
>
> The secondary flaw there is also about firmware. Sure, with UEFI you can have
> “random” allocations and the actual control over memory is actually problem,
> but to plant an “egg”  in 1MB-1GB range, where you have most chances any OS
> will live - IMO this is just stupid.
>
> The only real solution here is to either rise the MaxAddress limit or use
> AllocateAnyPages, get kernel loaded into the memory, and after switching off
> the boot services and before jumping to kernel, relocate the kernel to available
> location below 1GB…
Yes. IMO the biggest issue is that currently the kernel can't be relocated... :-(
It's a long term work to make it relocatable, I'm afraid.

Thanks,
-- Dexuan
Received on Thu Mar 09 2017 - 12:03:49 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:10 UTC