Re: [PATCH v2 1/1] x86/boot/compressed: Fix reloading of GDTR post-relocation

From: Arvind Sankar
Date: Sat Feb 29 2020 - 11:50:50 EST


On Sat, Feb 29, 2020 at 10:24:25AM +0100, Ingo Molnar wrote:
>
> * Arvind Sankar <nivedita@xxxxxxxxxxxx> wrote:
>
> > On Thu, Feb 27, 2020 at 06:47:55PM +0100, Ard Biesheuvel wrote:
> > >
> > > Interesting. I am going to rip most of the EFI handover protocol stuff
> > > out of OVMF, since it is mostly unnecessary, and having the PE/COFF
> > > loader put the image in the correct place right away is a nice
> > > complimentary improvement to that. (Note that the OVMF implementation
> > > of the EFI handover protocol does not currently honor the preferred
> > > address from the setup header anyway)
> >
> > Yeah, for my testing I'm running the image from the EFI shell, which
> > enters via PE entry point and honors the pref address.
>
> So with KASLR, which is the distro default on most x86 distros, we'll
> relocate the kernel to another address anyway, right?
>
> But telling the bootloader the preferred address would avoid any
> relocation overhead even in this case, right?
>
> Thanks,
>
> Ingo

If I understand correctly, pref_address was added to try to avoid having
to apply the relocations (vmlinux.relocs) by loading at the link-time
address if possible, and you're saying that with KASLR, we have to do
relocations anyway; and without KASLR the bootloader knows the preferred
address from the setup header already?

The patch I'm working on is meant to address the case when we are loaded
via the EFI LoadImage service, which is a generic PE loader, and hence
doesn't look at the pref_address in the setup header. We currently will
end up with at least 2 copies of the kernel, with 1 additional copy if
KASLR is enabled. The loader puts us somewhere, the EFI stub then makes
a copy trying to move us to pref_address, and then KASLR will allocate
an additional copy (not really a copy, but a buffer of the same size to
decompress into). By telling the PE loader what the preferred address is
I'm trying to avoid the EFI stub creating an additional copy, so we'll
have 1 copy, or 2 with KASLR.

That was the original motivation for the patch. As I've been working on
it, I'm thinking that the copy in the EFI stub can be avoided in more
cases.

AFAICT, pref_address is completely irrelevant on 64-bit, which will have
relocations applied only if KASLR is enabled and changes the virtual
address, but it never cares what physical address it's running out of.
It only requires being above LOAD_PHYSICAL_ADDR and below 2^46 or 2^52.
All we need to do is align the decompression buffer correctly.

For 32-bit, loading at pref_address can avoid relocations being applied,
but if we're not already loaded there in the first place, trying to
allocate a new buffer and copying the whole image is probably not worth
it. It does have more restrictions on physical addresses in that it
can't run at too high a physical address, so it may still be necessary
to relocate to avoid that.

Thanks.