2014-06-14 19:24:11

by Yinghai Lu

[permalink] [raw]
Subject: [PATCH] x86, eboot: Support initrd loaded above 4G

For boot efi kernel directly without bootloader.
If the kernel support XLF_CAN_BE_LOADED_ABOVE_4G, we should
not limit initrd under hdr->initrd_add_max.

Signed-off-by: Yinghai Lu <[email protected]>

---
arch/x86/boot/compressed/eboot.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

Index: linux-2.6/arch/x86/boot/compressed/eboot.c
===================================================================
--- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
+++ linux-2.6/arch/x86/boot/compressed/eboot.c
@@ -1038,6 +1038,7 @@ struct boot_params *make_boot_params(str
int i;
unsigned long ramdisk_addr;
unsigned long ramdisk_size;
+ unsigned long initrd_addr_max;

efi_early = c;
sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
@@ -1100,14 +1101,21 @@ struct boot_params *make_boot_params(str

memset(sdt, 0, sizeof(*sdt));

+ if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G)
+ initrd_addr_max = -1UL;
+ else
+ initrd_addr_max = hdr->initrd_addr_max;
+
status = handle_cmdline_files(sys_table, image,
(char *)(unsigned long)hdr->cmd_line_ptr,
- "initrd=", hdr->initrd_addr_max,
+ "initrd=", initrd_addr_max,
&ramdisk_addr, &ramdisk_size);
if (status != EFI_SUCCESS)
goto fail2;
- hdr->ramdisk_image = ramdisk_addr;
- hdr->ramdisk_size = ramdisk_size;
+ hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
+ hdr->ramdisk_size = ramdisk_size & 0xffffffff;
+ boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
+ boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32;

return boot_params;
fail2:


2014-06-18 14:28:25

by Matt Fleming

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Sat, 14 Jun, at 12:23:41PM, Yinghai Lu wrote:
> For boot efi kernel directly without bootloader.
> If the kernel support XLF_CAN_BE_LOADED_ABOVE_4G, we should
> not limit initrd under hdr->initrd_add_max.
>
> Signed-off-by: Yinghai Lu <[email protected]>
>
> ---
> arch/x86/boot/compressed/eboot.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)

Applied, thanks!

--
Matt Fleming, Intel Open Source Technology Center

2014-07-09 18:26:57

by Matt Fleming

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Wed, 18 Jun, at 03:28:19PM, Matt Fleming wrote:
> On Sat, 14 Jun, at 12:23:41PM, Yinghai Lu wrote:
> > For boot efi kernel directly without bootloader.
> > If the kernel support XLF_CAN_BE_LOADED_ABOVE_4G, we should
> > not limit initrd under hdr->initrd_add_max.
> >
> > Signed-off-by: Yinghai Lu <[email protected]>
> >
> > ---
> > arch/x86/boot/compressed/eboot.c | 14 +++++++++++---
> > 1 file changed, 11 insertions(+), 3 deletions(-)
>
> Applied, thanks!

Well, fooey. This patch breaks one of my ASUS machines. It appears some
firmware implementations exhibit issues reading directly into a buffer
above the 4GB mark.

I haven't diagnosed exactly what goes wrong with the buffer (i.e. in
what way it becomes corrupt), but I should really do that before
thinking of how to fix this.

I'll keep you posted, I just wanted to give you a heads up that things
are screwy in this area.

--
Matt Fleming, Intel Open Source Technology Center

2014-07-10 18:00:09

by Yinghai Lu

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Wed, Jul 9, 2014 at 11:26 AM, Matt Fleming <[email protected]> wrote:
> On Wed, 18 Jun, at 03:28:19PM, Matt Fleming wrote:
>> On Sat, 14 Jun, at 12:23:41PM, Yinghai Lu wrote:
>> > For boot efi kernel directly without bootloader.
>> > If the kernel support XLF_CAN_BE_LOADED_ABOVE_4G, we should
>> > not limit initrd under hdr->initrd_add_max.
>
> Well, fooey. This patch breaks one of my ASUS machines. It appears some
> firmware implementations exhibit issues reading directly into a buffer
> above the 4GB mark.
>
> I haven't diagnosed exactly what goes wrong with the buffer (i.e. in
> what way it becomes corrupt), but I should really do that before
> thinking of how to fix this.
>
> I'll keep you posted, I just wanted to give you a heads up that things
> are screwy in this area.

Oh, no.

so efi could allocate buffer above 4g but can not access it?

Yinghai

2014-07-11 07:40:55

by Matt Fleming

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Thu, 10 Jul, at 11:00:06AM, Yinghai Lu wrote:
>
> Oh, no.
>
> so efi could allocate buffer above 4g but can not access it?

I'm not exactly sure what's wrong with the buffer - whether it's a case
of not being able to access it properly or somehing buggy in the EFI
code for reading files. No fault occurs when reading into it, it just
doesn't contain the correct data.

Either way, I'm going to leave your patch as-is and just ensure I fix
this before the merge window. I think it's a good idea to have whatever
workaround we come up with documented via an entirely separate patch.

--
Matt Fleming, Intel Open Source Technology Center

2014-07-15 15:10:33

by Matt Fleming

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Fri, 11 Jul, at 08:40:29AM, Matt Fleming wrote:
>
> I'm not exactly sure what's wrong with the buffer - whether it's a case
> of not being able to access it properly or somehing buggy in the EFI
> code for reading files. No fault occurs when reading into it, it just
> doesn't contain the correct data.
>
> Either way, I'm going to leave your patch as-is and just ensure I fix
> this before the merge window. I think it's a good idea to have whatever
> workaround we come up with documented via an entirely separate patch.

I spent some time playing around with this bug and it appears to be
triggered by the read-a-chunk-at-a-time logic in handle_cmdline_files(),
(which is itself a bug workaround) introduced here,

commit 2d2da60fb40a
Author: Maarten Lankhorst <[email protected]>
Date: Fri Dec 16 13:30:58 2011 +0100

x86, efi: Break up large initrd reads

The efi boot stub tries to read the entire initrd in 1 go, however
some efi implementations hang if too much if asked to read too much
data at the same time. After some experimentation I found out that my
asrock p67 board will hang if asked to read chunks of 4MiB, so use a
safe value.

elilo reads in chunks of 16KiB, but since that requires many read
calls I use a value of 1 MiB. hpa suggested adding individual
blacklists for when systems are found where this value causes a crash.

Signed-off-by: Maarten Lankhorst <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>

Setting EFI_READ_CHUNK_SIZE to -1 (disabling the chunk workaround)
allows everything to work just fine. Any chunk value smaller than the
initrd file size causes the bug to trigger on my machine.

Going forward, I suspect any attempts to use the EFI File Protocol are
going to result in this kind of breakage, and that the only thing that
can be relied upon is the Disk I/O Protocol.

But doing Disk I/O would necessitate adding the in-kernel FAT driver to
the EFI boot stub, which is a scary idea (though not without merit).

On the flip-side, we've no infrastructure in the EFI boot stub for doing
blacklisting via DMI, so there's no way currently to automatically
disable the chunk-read workaround for known buggy machines.

The simplest solution is to require that the user pull some kind of
kernel parameter on the command line to explicitly disable the
workaround, but that's a pretty lame prospect.

--
Matt Fleming, Intel Open Source Technology Center

2014-07-15 15:34:50

by Michael Brown

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On 15/07/14 16:10, Matt Fleming wrote:
> Going forward, I suspect any attempts to use the EFI File Protocol are
> going to result in this kind of breakage, and that the only thing that
> can be relied upon is the Disk I/O Protocol.
>
> But doing Disk I/O would necessitate adding the in-kernel FAT driver to
> the EFI boot stub, which is a scary idea (though not without merit).

Booting via iPXE will give you an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
(providing access to the initrd previously downloaded by iPXE). It will
also give you a dummy disk I/O protocol which always return EFI_NO_MEDIA.

In those circumstances, only the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL will work.

Michael

2014-07-15 15:45:06

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On 07/15/2014 08:10 AM, Matt Fleming wrote:
>
> Going forward, I suspect any attempts to use the EFI File Protocol are
> going to result in this kind of breakage, and that the only thing that
> can be relied upon is the Disk I/O Protocol.
>

Do we know what the Windows bootloader does? I thought it did use the
EFI File Protocol?

-hpa

2014-07-16 14:34:28

by Matt Fleming

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On Tue, 15 Jul, at 08:44:34AM, H. Peter Anvin wrote:
>
> Do we know what the Windows bootloader does? I thought it did use the
> EFI File Protocol?

Good question. I'm not sure what the answer is, I'll try and find some
time to take a look.

--
Matt Fleming, Intel Open Source Technology Center

2014-07-16 14:45:26

by Michael Brown

[permalink] [raw]
Subject: Re: [PATCH] x86, eboot: Support initrd loaded above 4G

On 16/07/14 15:34, Matt Fleming wrote:
> On Tue, 15 Jul, at 08:44:34AM, H. Peter Anvin wrote:
>> Do we know what the Windows bootloader does? I thought it did use the
>> EFI File Protocol?
>
> Good question. I'm not sure what the answer is, I'll try and find some
> time to take a look.

I'm in the middle of related work at the moment: trying to persuade UEFI
WinPE to load its files from the virtual file system exposed by iPXE.
I'll let you know what I find.

Michael