From: Bryan O'Donoghue <bryan.odonoghue.lkml-SyKdqv6vbfZdzvEItQ6vdLNAH6kLmebB@public.gmane.org>
To: Matt Fleming <matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
Cc: matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org,
linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Darren Hart <darren.hart-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>,
"H. Peter Anvin" <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>,
Ingo Molnar <mingo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Subject: Re: [PATCH] Remove warning in efi_enter_virtual_mode
Date: Wed, 17 Apr 2013 23:00:48 +0100 [thread overview]
Message-ID: <516F1B90.9040508@nexus-software.ie> (raw)
In-Reply-To: <516EAC4A.6040202-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
On 17/04/13 15:06, Matt Fleming wrote:
> (Cc'ing some more folks)
>
> On 16/04/13 16:58, Bryan O'Donoghue wrote:
>> This warning is caused by efi_enter_virtual_mode mapping memory marked
>> as !EFI_RUNTIME_MEMORY. The reason this memory is being mapped is to
>> work around buggy code that stores an ACPI object called the Boot
>> Graphics Resource Table - BGRT in memory of type EfiBootServices*.
>>
>> ------------[ cut here ]------------
>> WARNING: at arch/x86/mm/ioremap.c:102 __ioremap_caller+0x3d3/0x440()
>> Modules linked in:
>> Pid: 0, comm: swapper Not tainted 3.9.0-rc7+ #95
>> Call Trace:
>> [<c102b6af>] warn_slowpath_common+0x5f/0x80
>> [<c1023fb3>] ? __ioremap_caller+0x3d3/0x440
>> [<c1023fb3>] ? __ioremap_caller+0x3d3/0x440
>> [<c102b6ed>] warn_slowpath_null+0x1d/0x20
>> [<c1023fb3>] __ioremap_caller+0x3d3/0x440
>> [<c106007b>] ? get_usage_chars+0xfb/0x110
>> [<c102d937>] ? vprintk_emit+0x147/0x480
>> [<c1418593>] ? efi_enter_virtual_mode+0x1e4/0x3de
>> [<c102406a>] ioremap_cache+0x1a/0x20
>> [<c1418593>] ? efi_enter_virtual_mode+0x1e4/0x3de
>> [<c1418593>] efi_enter_virtual_mode+0x1e4/0x3de
>> [<c1407984>] start_kernel+0x286/0x2f4
>> [<c1407535>] ? repair_env_string+0x51/0x51
>> [<c1407362>] i386_start_kernel+0x12c/0x12f
>> ---[ end trace 4eaa2a86a8e2da22 ]---
>
> The warning is telling you that someone is trying to ioremap RAM, which
> is bad. It's not specifically an issue with the bgrt image, it's just
> that said object happens to occupy an EfiBootServicesData region which
> isn't mapped by the direct kernel mapping on i386.
I understand that.
In my mind the only memory that is relevant to efi_enter_virtual_mode is
memory that the BIOS has marked as EFI_RUNTIME_SERVICE
md->attribute & 0x80000000_00000000
I couldn't quite understand why the code in
arch/x86/platform/efi/efi.c:enter_virtual_mode() looks like this
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
md = p;
if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA)
continue;
While the code in
arch/ia64/kernel/efi.c:enter_virtual_mode
for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
md = p;
if (md->attribute & EFI_MEMORY_RUNTIME) {
The ia64 version is consistent with the standard - but obviously isn't
accounting for the work-around implemented to retrieve the BGRT on ia32.
Looking at the commit message associated with
arch/x86/platform/efi/efi-bgrt.c
It's pretty obvious the mapping of boot code/data was done to facilitate
BGRT.
Since the EFI memory map I'm using is clean - below - there's no reason
for us to map the boot code/data.
> Most (all?) boot loaders mark EFI_BOOT_SERVICES_{CODE,DATA} as E820_RAM,
> which is why ioremap() complained about you trying to ioremap() a page
> of RAM.
But they aught to. It's entirely legitimate for the run-time to reclaim
this memory - since after ExitBootServices() - none of the code/data
inside of EFI_BOOT_SERVICES is of any use.
Caveat being the work-around that was done for BGRT.
They do this because after efi_free_boot_services() we want
> these regions to be available for general allocation.
Agree.
> On x86-64 you rarely hit the ioremap() path because all RAM regions are
> mapped by the kernel direct mapping, e.g __va() works on those
> addresses. On i386, with its reduced virtual address space, it's much
> more likely that those addresses are not part of the direct mapping, and
> so this is the chunk of code that causes problems in
> efi_enter_virtual_mode(),
>
> start_pfn = PFN_DOWN(md->phys_addr);
> end_pfn = PFN_UP(end);
> if (pfn_range_is_mapped(start_pfn, end_pfn)) {
> va = __va(md->phys_addr);
>
> if (!(md->attribute& EFI_MEMORY_WB))
> efi_memory_uc((u64)(unsigned long)va, size);
> } else
> va = efi_ioremap(md->phys_addr, size,
> md->type, md->attribute);
Yes it fails sanity checking in efi_ioremap::__ioremap_caller on an
"is_ram()" call.
> What we probably need is an i386-specific implementation of
> efi_ioremap() that checks to see whether we're mapping a RAM region. I
> thought of maybe using the kmap_high() functions, but I don't think
> repeated calls to the kmap*() functions are guaranteed to provide
> consecutive virtual addresses, and I doubt free_bootmem() (called from
> efi_free_boot_services()) understands kmap'd addresses.
That's one solution - you'd need to make the i386::efi_ioremap() aware
of the BGRT work-around.
Presumably this work-around is also required on ia64 too.
> Maybe we should hot-add the EFI_BOOT_SERVICES_* regions once we've
> finished with them and only then mark them as RAM?
>
> x86 folks? Halp?
>
>> On systems that do not have a BGRT object, there's no reason to map this
>> memory in efi_enter_virtual_mode. This patch searches for the BGRT
>> object and if found - will continue to map the boot services memory,
>> else only memory with attribute EFI_RUNTIME_MEMORY will be mapped.
>
> Like I said above, it just so happens on your machine that a BGRT object
> occupies that chunk of memory, but this might not be the case on every
> EFI i386 machine. You may have other useful things in that region that
> you want to be mapped. It's also entirely possible that someone with the
> same memory map layout as you _will_ want the bgrt image mapped. This
> code needs fixing, instead of just working around the problem.
No, no - we *don't* have a BGRT object at all.
We have a completely clean memory map - but the BGRT code is causing the
is_ram() failure.
Rather than just blow away the BGRT code the patch determines if a BGRT
object exists.
If there is an ACPI::BGRT - then efi_enter_virtual_mode - will still
continue to map EFI_BOOT_SERVICES*
If not then you get this
if (md->attribute & EFI_MEMORY_RUNTIME) {
/* Only map EFI_RUNTIME_MEMORY here */
}
Which is what everybody who is !ACPI::BGRT really wants.
I've coded up a precautionary alternate version of the patch that passes
a kernel parameter to switch off the offending code, though it would
probably be better to pass a kernel parameter to switch it on !
Though that would require modification of the kernel command line for
any system that currently relies on BGRT - so unfortunately I think
switching off the - I hate to use the bug - seems the less
user-impacting method.
I'll send this patch for reference - but, I do believe probing for BGRT
is more appropriate than forcing a kernel parameter addition.
I think even if you make an i386 version of efi_ioremap() you still need
to address the fundamental problem that only systems which want to
implement the ACPI::BGRT work-around care about mapping
EFI_BOOT_SERVICES, unless I've missed a trick here ?
Bryan
WARNING: multiple messages have this Message-ID (diff)
From: "Bryan O'Donoghue" <bryan.odonoghue.lkml@nexus-software.ie>
To: Matt Fleming <matt@console-pimps.org>
Cc: matthew.garrett@nebula.com, linux-efi@vger.kernel.org,
x86@kernel.org, linux-kernel@vger.kernel.org,
Darren Hart <darren.hart@intel.com>,
Josh Triplett <josh@joshtriplett.org>,
"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH] Remove warning in efi_enter_virtual_mode
Date: Wed, 17 Apr 2013 23:00:48 +0100 [thread overview]
Message-ID: <516F1B90.9040508@nexus-software.ie> (raw)
In-Reply-To: <516EAC4A.6040202@console-pimps.org>
On 17/04/13 15:06, Matt Fleming wrote:
> (Cc'ing some more folks)
>
> On 16/04/13 16:58, Bryan O'Donoghue wrote:
>> This warning is caused by efi_enter_virtual_mode mapping memory marked
>> as !EFI_RUNTIME_MEMORY. The reason this memory is being mapped is to
>> work around buggy code that stores an ACPI object called the Boot
>> Graphics Resource Table - BGRT in memory of type EfiBootServices*.
>>
>> ------------[ cut here ]------------
>> WARNING: at arch/x86/mm/ioremap.c:102 __ioremap_caller+0x3d3/0x440()
>> Modules linked in:
>> Pid: 0, comm: swapper Not tainted 3.9.0-rc7+ #95
>> Call Trace:
>> [<c102b6af>] warn_slowpath_common+0x5f/0x80
>> [<c1023fb3>] ? __ioremap_caller+0x3d3/0x440
>> [<c1023fb3>] ? __ioremap_caller+0x3d3/0x440
>> [<c102b6ed>] warn_slowpath_null+0x1d/0x20
>> [<c1023fb3>] __ioremap_caller+0x3d3/0x440
>> [<c106007b>] ? get_usage_chars+0xfb/0x110
>> [<c102d937>] ? vprintk_emit+0x147/0x480
>> [<c1418593>] ? efi_enter_virtual_mode+0x1e4/0x3de
>> [<c102406a>] ioremap_cache+0x1a/0x20
>> [<c1418593>] ? efi_enter_virtual_mode+0x1e4/0x3de
>> [<c1418593>] efi_enter_virtual_mode+0x1e4/0x3de
>> [<c1407984>] start_kernel+0x286/0x2f4
>> [<c1407535>] ? repair_env_string+0x51/0x51
>> [<c1407362>] i386_start_kernel+0x12c/0x12f
>> ---[ end trace 4eaa2a86a8e2da22 ]---
>
> The warning is telling you that someone is trying to ioremap RAM, which
> is bad. It's not specifically an issue with the bgrt image, it's just
> that said object happens to occupy an EfiBootServicesData region which
> isn't mapped by the direct kernel mapping on i386.
I understand that.
In my mind the only memory that is relevant to efi_enter_virtual_mode is
memory that the BIOS has marked as EFI_RUNTIME_SERVICE
md->attribute & 0x80000000_00000000
I couldn't quite understand why the code in
arch/x86/platform/efi/efi.c:enter_virtual_mode() looks like this
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
md = p;
if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA)
continue;
While the code in
arch/ia64/kernel/efi.c:enter_virtual_mode
for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
md = p;
if (md->attribute & EFI_MEMORY_RUNTIME) {
The ia64 version is consistent with the standard - but obviously isn't
accounting for the work-around implemented to retrieve the BGRT on ia32.
Looking at the commit message associated with
arch/x86/platform/efi/efi-bgrt.c
It's pretty obvious the mapping of boot code/data was done to facilitate
BGRT.
Since the EFI memory map I'm using is clean - below - there's no reason
for us to map the boot code/data.
> Most (all?) boot loaders mark EFI_BOOT_SERVICES_{CODE,DATA} as E820_RAM,
> which is why ioremap() complained about you trying to ioremap() a page
> of RAM.
But they aught to. It's entirely legitimate for the run-time to reclaim
this memory - since after ExitBootServices() - none of the code/data
inside of EFI_BOOT_SERVICES is of any use.
Caveat being the work-around that was done for BGRT.
They do this because after efi_free_boot_services() we want
> these regions to be available for general allocation.
Agree.
> On x86-64 you rarely hit the ioremap() path because all RAM regions are
> mapped by the kernel direct mapping, e.g __va() works on those
> addresses. On i386, with its reduced virtual address space, it's much
> more likely that those addresses are not part of the direct mapping, and
> so this is the chunk of code that causes problems in
> efi_enter_virtual_mode(),
>
> start_pfn = PFN_DOWN(md->phys_addr);
> end_pfn = PFN_UP(end);
> if (pfn_range_is_mapped(start_pfn, end_pfn)) {
> va = __va(md->phys_addr);
>
> if (!(md->attribute& EFI_MEMORY_WB))
> efi_memory_uc((u64)(unsigned long)va, size);
> } else
> va = efi_ioremap(md->phys_addr, size,
> md->type, md->attribute);
Yes it fails sanity checking in efi_ioremap::__ioremap_caller on an
"is_ram()" call.
> What we probably need is an i386-specific implementation of
> efi_ioremap() that checks to see whether we're mapping a RAM region. I
> thought of maybe using the kmap_high() functions, but I don't think
> repeated calls to the kmap*() functions are guaranteed to provide
> consecutive virtual addresses, and I doubt free_bootmem() (called from
> efi_free_boot_services()) understands kmap'd addresses.
That's one solution - you'd need to make the i386::efi_ioremap() aware
of the BGRT work-around.
Presumably this work-around is also required on ia64 too.
> Maybe we should hot-add the EFI_BOOT_SERVICES_* regions once we've
> finished with them and only then mark them as RAM?
>
> x86 folks? Halp?
>
>> On systems that do not have a BGRT object, there's no reason to map this
>> memory in efi_enter_virtual_mode. This patch searches for the BGRT
>> object and if found - will continue to map the boot services memory,
>> else only memory with attribute EFI_RUNTIME_MEMORY will be mapped.
>
> Like I said above, it just so happens on your machine that a BGRT object
> occupies that chunk of memory, but this might not be the case on every
> EFI i386 machine. You may have other useful things in that region that
> you want to be mapped. It's also entirely possible that someone with the
> same memory map layout as you _will_ want the bgrt image mapped. This
> code needs fixing, instead of just working around the problem.
No, no - we *don't* have a BGRT object at all.
We have a completely clean memory map - but the BGRT code is causing the
is_ram() failure.
Rather than just blow away the BGRT code the patch determines if a BGRT
object exists.
If there is an ACPI::BGRT - then efi_enter_virtual_mode - will still
continue to map EFI_BOOT_SERVICES*
If not then you get this
if (md->attribute & EFI_MEMORY_RUNTIME) {
/* Only map EFI_RUNTIME_MEMORY here */
}
Which is what everybody who is !ACPI::BGRT really wants.
I've coded up a precautionary alternate version of the patch that passes
a kernel parameter to switch off the offending code, though it would
probably be better to pass a kernel parameter to switch it on !
Though that would require modification of the kernel command line for
any system that currently relies on BGRT - so unfortunately I think
switching off the - I hate to use the bug - seems the less
user-impacting method.
I'll send this patch for reference - but, I do believe probing for BGRT
is more appropriate than forcing a kernel parameter addition.
I think even if you make an i386 version of efi_ioremap() you still need
to address the fundamental problem that only systems which want to
implement the ACPI::BGRT work-around care about mapping
EFI_BOOT_SERVICES, unless I've missed a trick here ?
Bryan
next prev parent reply other threads:[~2013-04-17 22:00 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-16 15:58 [PATCH] Remove warning in efi_enter_virtual_mode Bryan O'Donoghue
2013-04-16 15:58 ` Bryan O'Donoghue
[not found] ` <1366127886-31460-1-git-send-email-bryan.odonoghue.lkml-SyKdqv6vbfZdzvEItQ6vdLNAH6kLmebB@public.gmane.org>
2013-04-17 14:06 ` Matt Fleming
2013-04-17 14:06 ` Matt Fleming
[not found] ` <516EAC4A.6040202-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-04-17 22:00 ` Bryan O'Donoghue [this message]
2013-04-17 22:00 ` Bryan O'Donoghue
[not found] ` <516F1B90.9040508-SyKdqv6vbfZdzvEItQ6vdLNAH6kLmebB@public.gmane.org>
2013-04-18 11:00 ` Matt Fleming
2013-04-18 11:00 ` Matt Fleming
[not found] ` <516FD24A.3070502-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-04-18 13:40 ` Josh Boyer
2013-04-18 13:40 ` Josh Boyer
[not found] ` <20130418134059.GF18383-dHPIJuKSOV01V+h/cAXI7w8O6CCKKCg3HZ5vskTnxNA@public.gmane.org>
2013-04-18 15:01 ` Matthew Garrett
2013-04-18 15:01 ` Matthew Garrett
[not found] ` <1366297271.13667.14.camel-+5W/JHIUVxg@public.gmane.org>
2013-04-18 15:17 ` Josh Boyer
2013-04-18 15:17 ` Josh Boyer
2013-04-18 22:07 ` Bryan O'Donoghue
2013-04-18 22:07 ` Bryan O'Donoghue
[not found] ` <51706E8A.7030909-SyKdqv6vbfZdzvEItQ6vdLNAH6kLmebB@public.gmane.org>
2013-04-18 23:01 ` Josh Triplett
2013-04-18 23:01 ` Josh Triplett
2013-04-18 23:44 ` H. Peter Anvin
2013-04-18 23:44 ` H. Peter Anvin
2013-04-18 23:42 ` H. Peter Anvin
2013-04-18 23:42 ` H. Peter Anvin
2013-04-18 14:51 ` Darren Hart
[not found] ` <51700876.1000305-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-04-18 16:19 ` Matt Fleming
2013-04-18 16:19 ` Matt Fleming
2013-04-19 0:18 ` Darren Hart
[not found] ` <51708D3D.9010707-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-04-19 7:50 ` Matt Fleming
2013-04-19 7:50 ` Matt Fleming
[not found] ` <5170F736.2060803-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-04-19 12:01 ` Josh Boyer
2013-04-19 12:01 ` Josh Boyer
2013-09-10 17:43 ` Darren Hart
2013-09-10 17:43 ` Darren Hart
[not found] ` <1378835007.19978.125.camel-d05DLm829JQHkdubuh725LKMmGWinSIL2HeeBUIffwg@public.gmane.org>
2013-09-12 7:55 ` Matt Fleming
2013-09-12 7:55 ` Matt Fleming
[not found] ` <20130912075500.GC895-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-09-12 22:30 ` Darren Hart
2013-09-12 22:30 ` Darren Hart
2013-04-18 16:33 ` Josh Triplett
2013-04-18 16:38 ` H. Peter Anvin
2013-04-18 16:38 ` H. Peter Anvin
2013-04-18 16:44 ` Josh Triplett
2013-04-18 19:55 ` Matt Fleming
2013-04-18 19:55 ` Matt Fleming
[not found] ` <51704FA8.7060801-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2013-04-18 19:57 ` H. Peter Anvin
2013-04-18 19:57 ` H. Peter Anvin
2013-04-18 19:58 ` Matthew Garrett
2013-04-18 19:58 ` Matthew Garrett
[not found] ` <1366315083.13667.19.camel-+5W/JHIUVxg@public.gmane.org>
2013-04-18 20:11 ` Darren Hart
2013-04-18 20:11 ` Darren Hart
[not found] ` <51705366.8070001-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-04-18 20:13 ` H. Peter Anvin
2013-04-18 20:13 ` H. Peter Anvin
[not found] ` <517053EF.2030900-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2013-04-18 20:17 ` Darren Hart
2013-04-18 20:17 ` Darren Hart
[not found] ` <517054EF.9070500-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-04-18 20:45 ` H. Peter Anvin
2013-04-18 20:45 ` H. Peter Anvin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=516F1B90.9040508@nexus-software.ie \
--to=bryan.odonoghue.lkml-sykdqv6vbfzdzveitq6vdlnah6klmebb@public.gmane.org \
--cc=darren.hart-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org \
--cc=josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org \
--cc=linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org \
--cc=matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org \
--cc=mingo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
--cc=x86-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.