* [PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820()
@ 2015-07-22 15:31 Dmitry Skorodumov
[not found] ` <1437579068-14982-1-git-send-email-sdmitry-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Skorodumov @ 2015-07-22 15:31 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA; +Cc: sdmitry-bzQdu9zFT3WakBO8gow8eQ
The efi_info structure stores low 32 bits of memory map
in efi_memmap and high 32 bits in efi_memmap_hi.
While constructing pointer in the setup_e820(), need
to take into account all 64 bits of the pointer.
It is because on 64bit machine the function
efi_get_memory_map() may return full 64bit pointer and before
the patch that pointer was truncated.
Signed-off-by: Dmitry Skorodumov <sdmitry-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
tested in Parallels virtual machine with more then 3GB of memory
---
arch/x86/boot/compressed/eboot.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 2c82bd1..9108fe5 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1184,6 +1184,12 @@ static efi_status_t setup_e820(struct boot_params *params,
u32 nr_entries;
u32 nr_desc;
int i;
+ unsigned long m;
+
+ m = efi->efi_memmap;
+#ifdef CONFIG_X86_64
+ m |= (u64)efi->efi_memmap_hi << 32;
+#endif
nr_entries = 0;
nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
@@ -1191,7 +1197,6 @@ static efi_status_t setup_e820(struct boot_params *params,
for (i = 0; i < nr_desc; i++) {
efi_memory_desc_t *d;
unsigned int e820_type = 0;
- unsigned long m = efi->efi_memmap;
d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
switch (d->type) {
--
1.7.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820()
[not found] ` <1437579068-14982-1-git-send-email-sdmitry-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
@ 2015-07-28 11:24 ` Matt Fleming
[not found] ` <20150728112413.GA645-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
2015-07-28 14:16 ` Dmitry Skorodumov
0 siblings, 2 replies; 5+ messages in thread
From: Matt Fleming @ 2015-07-28 11:24 UTC (permalink / raw)
To: Dmitry Skorodumov; +Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA, Borislav Petkov
On Wed, 22 Jul, at 07:31:08PM, Dmitry Skorodumov wrote:
> The efi_info structure stores low 32 bits of memory map
> in efi_memmap and high 32 bits in efi_memmap_hi.
>
> While constructing pointer in the setup_e820(), need
> to take into account all 64 bits of the pointer.
>
> It is because on 64bit machine the function
> efi_get_memory_map() may return full 64bit pointer and before
> the patch that pointer was truncated.
>
> Signed-off-by: Dmitry Skorodumov <sdmitry-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
>
> tested in Parallels virtual machine with more then 3GB of memory
When you say "tested", you mean that it doesn't boot correctly without
your patch but does boot correctly with it applied? What I'm really
asking is: are we sure that your setup triggered this new code?
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index 2c82bd1..9108fe5 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -1184,6 +1184,12 @@ static efi_status_t setup_e820(struct boot_params *params,
> u32 nr_entries;
> u32 nr_desc;
> int i;
> + unsigned long m;
> +
> + m = efi->efi_memmap;
> +#ifdef CONFIG_X86_64
> + m |= (u64)efi->efi_memmap_hi << 32;
> +#endif
>
> nr_entries = 0;
> nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
> @@ -1191,7 +1197,6 @@ static efi_status_t setup_e820(struct boot_params *params,
> for (i = 0; i < nr_desc; i++) {
> efi_memory_desc_t *d;
> unsigned int e820_type = 0;
> - unsigned long m = efi->efi_memmap;
>
> d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
> switch (d->type) {
Is there a reason that adding efi->efi_memmap_hi can't be done inside
this for loop? Gcc should be smart enough to hoist this calculation out
of the loop.
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE:[PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820()
[not found] ` <20150728112413.GA645-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
@ 2015-07-28 13:18 ` Dmitry Skorodumov
[not found] ` <BY1PR0301MB1255463A9A89D6247A81D242A18D0-M1kb196zaopYAF46dOS0O5wN6zqB+hSMnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Skorodumov @ 2015-07-28 13:18 UTC (permalink / raw)
To: Matt Fleming
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Borislav Petkov, Denis Lunev
Matt Fleming <matt@...> writes:
> On Wed, 22 Jul, at 07:31:08PM, Dmitry Skorodumov wrote:
> > The efi_info structure stores low 32 bits of memory map
> > in efi_memmap and high 32 bits in efi_memmap_hi.
> >
> > While constructing pointer in the setup_e820(), need
> > to take into account all 64 bits of the pointer.
> > tested in Parallels virtual machine with more then 3GB of memory
> When you say "tested", you mean that it doesn't boot correctly without
> your patch but does boot correctly with it applied? What I'm really
> asking is: are we sure that your setup triggered this new code?
Yes, while debugging I added a lot of logging to trace the problem.
Parallels VM doesn't boot correctly without the patch.
I believe that any EDK2-based efi-bios will not work also,
though I heard that OVMF uses own linux boot loader..
It is because the memory for memmap was allocated from EFI_LOADER_DATA pool -
efi_call_early(allocate_pool, EFI_LOADER_DATA, map_size... );
It is possible to kludge the problem by patching EFI-bios of the machine
to allocate EFI_LOADER_DATA-memory below the 4GB space,
but I think that fixing setup_e820() is the right thing.
> > + m = efi->efi_memmap;
> > +#ifdef CONFIG_X86_64
> > + m |= (u64)efi->efi_memmap_hi << 32;
> > +#endif
..
> > for (i = 0; i < nr_desc; i++) {
> > - unsigned long m = efi->efi_memmap;
> > d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
> Is there a reason that adding efi->efi_memmap_hi can't be done inside
> this for loop? Gcc should be smart enough to hoist this calculation out
> of the loop.
Smart from its side.. I'll correct this and resend the patch.--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820()
2015-07-28 11:24 ` Matt Fleming
[not found] ` <20150728112413.GA645-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
@ 2015-07-28 14:16 ` Dmitry Skorodumov
1 sibling, 0 replies; 5+ messages in thread
From: Dmitry Skorodumov @ 2015-07-28 14:16 UTC (permalink / raw)
To: linux-efi-u79uwXL29TY76Z2rM5mHXA
> On Wed, 22 Jul, at 07:31:08PM, Dmitry Skorodumov wrote:
> > The efi_info structure stores low 32 bits of memory map
> > in efi_memmap and high 32 bits in efi_memmap_hi.
> >
> > While constructing pointer in the setup_e820(), need
> > to take into account all 64 bits of the pointer.
> > tested in Parallels virtual machine with more then 3GB of memory
> When you say "tested", you mean that it doesn't boot correctly without
> your patch but does boot correctly with it applied? What I'm really
> asking is: are we sure that your setup triggered this new code?
Yes, while debugging I added a lot of logging to trace the problem.
Parallels VM doesn't boot correctly without the patch.
I believe that any EDK2-based efi-bios will not work also,
though I heard that OVMF uses own linux boot loader..
It is because the memory for memmap was allocated from EFI_LOADER_DATA pool -
efi_call_early(allocate_pool, EFI_LOADER_DATA, map_size... );
It is possible to kludge the problem by patching EFI-bios of the machine
to allocate EFI_LOADER_DATA-memory below the 4GB space,
but I think that fixing setup_e820() is the right thing.
> > + m = efi->efi_memmap;
> > +#ifdef CONFIG_X86_64
> > + m |= (u64)efi->efi_memmap_hi << 32;
> > +#endif
..
> > for (i = 0; i < nr_desc; i++) {
> > - unsigned long m = efi->efi_memmap;
> > d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
> Is there a reason that adding efi->efi_memmap_hi can't be done inside
> this for loop? Gcc should be smart enough to hoist this calculation out
> of the loop.
Smart from its side.. I'll correct this and resend the patch.
PS: Looks my mailer have not sent the message to the list.
Resending via gmane-web, sorry for potential duplicate
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820()
[not found] ` <BY1PR0301MB1255463A9A89D6247A81D242A18D0-M1kb196zaopYAF46dOS0O5wN6zqB+hSMnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
@ 2015-07-28 20:42 ` Matt Fleming
0 siblings, 0 replies; 5+ messages in thread
From: Matt Fleming @ 2015-07-28 20:42 UTC (permalink / raw)
To: Dmitry Skorodumov
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Borislav Petkov, Denis Lunev
On Tue, 28 Jul, at 01:18:37PM, Dmitry Skorodumov wrote:
> Matt Fleming <matt@...> writes:
>
> > On Wed, 22 Jul, at 07:31:08PM, Dmitry Skorodumov wrote:
> > > The efi_info structure stores low 32 bits of memory map
> > > in efi_memmap and high 32 bits in efi_memmap_hi.
> > >
> > > While constructing pointer in the setup_e820(), need
> > > to take into account all 64 bits of the pointer.
>
> > > tested in Parallels virtual machine with more then 3GB of memory
>
> > When you say "tested", you mean that it doesn't boot correctly without
> > your patch but does boot correctly with it applied? What I'm really
> > asking is: are we sure that your setup triggered this new code?
>
> Yes, while debugging I added a lot of logging to trace the problem.
> Parallels VM doesn't boot correctly without the patch.
OK cool, I would definitely include this in the patch commit message.
> I believe that any EDK2-based efi-bios will not work also,
> though I heard that OVMF uses own linux boot loader..
> It is because the memory for memmap was allocated from EFI_LOADER_DATA pool -
> efi_call_early(allocate_pool, EFI_LOADER_DATA, map_size... );
>
> It is possible to kludge the problem by patching EFI-bios of the machine
> to allocate EFI_LOADER_DATA-memory below the 4GB space,
> but I think that fixing setup_e820() is the right thing.
Yes your fix looks correct to me, I just wanted to know whether you hit
the bug with a real workload or via code inspection.
> > > + m = efi->efi_memmap;
> > > +#ifdef CONFIG_X86_64
> > > + m |= (u64)efi->efi_memmap_hi << 32;
> > > +#endif
> ..
> > > for (i = 0; i < nr_desc; i++) {
> > > - unsigned long m = efi->efi_memmap;
> > > d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
>
> > Is there a reason that adding efi->efi_memmap_hi can't be done inside
> > this for loop? Gcc should be smart enough to hoist this calculation out
> > of the loop.
>
> Smart from its side.. I'll correct this and resend the patch.
Great, thanks.
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-07-28 20:42 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-22 15:31 [PATCH] [v2] x86_64/efi: Use all 64 bit of efi_memmap in setup_e820() Dmitry Skorodumov
[not found] ` <1437579068-14982-1-git-send-email-sdmitry-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2015-07-28 11:24 ` Matt Fleming
[not found] ` <20150728112413.GA645-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
2015-07-28 13:18 ` Dmitry Skorodumov
[not found] ` <BY1PR0301MB1255463A9A89D6247A81D242A18D0-M1kb196zaopYAF46dOS0O5wN6zqB+hSMnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2015-07-28 20:42 ` [PATCH] " Matt Fleming
2015-07-28 14:16 ` Dmitry Skorodumov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox