All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Borislav Petkov <bp@alien8.de>
Cc: edk2-devel@lists.sourceforge.net,
	David Woodhouse <dwmw2@infradead.org>,
	linux-efi@vger.kernel.org, lkml <linux-kernel@vger.kernel.org>,
	Gleb Natapov <gleb@redhat.com>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	Matt Fleming <matt@console-pimps.org>,
	"Jordan Justen (Intel address)" <jordan.l.justen@intel.com>
Subject: Re: [edk2] Corrupted EFI region
Date: Wed, 07 Aug 2013 19:49:16 +0200	[thread overview]
Message-ID: <5202889C.2080608@redhat.com> (raw)
In-Reply-To: <20130807151935.GJ17920@pd.tnic>

[-- Attachment #1: Type: text/plain, Size: 4476 bytes --]

On 08/07/13 17:19, Borislav Petkov wrote:
> On Tue, Aug 06, 2013 at 05:31:29PM +0200, Laszlo Ersek wrote:
>> Can you capture the OVMF debug output? Do you see
>>
>>   ConvertPages: Incompatible memory types
>>
>> there?
>>
>> Can you set the following bits too in the debug mask?
>>
>> #define DEBUG_POOL      0x00000010  // Alloc & Free's
>> #define DEBUG_PAGE      0x00000020  // Alloc & Free's
> 
> Ok, I got debug output; I have to be careful now of not missing
> anything. Ok, so here we go:
> 
> First of all, I changed debugging mask to:
> 
>   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010007F
> 
> (I just set all three bits you requested).
> 
> Using the new OVMF.id changed the addresses, of course, so we're looking
> at 0x7dc59XXX ones now.
> 
> [    0.000000] memblock_reserve: [0x0000007dc59018-0x0000007dc59618] efi_memblock_x86_reserve_range+0x70/0x75
> 
> So, I've attached an archive of the debug logs. The initial observations
> I could do is that the region still gets "squashed" to:
> 
> [    0.014041] efi: mem11: type=4, attr=0xf, range=[0x000000007dc59000-0x000000007dc59000) (0MB)
> 
> from
> 
> [    0.000000] efi: mem11: type=4, attr=0xf, range=[0x000000007dc59000-0x000000007e146000) (4MB)
> 
> And the interesting stuff in the OVMF output is right at the end:
> 
> ConvertRange: 7DC59000-7DC5AFFF to 4
> AddRange: 7DC59000-7DC5AFFF to 4
> AllocatePoolI: Type 4, Addr 7DC59018 (len 16F0) 26,735,072
> Jumping to kernel
> 
> We get that same output no matter if I boot it with "-enable-kvm" or
> not.
> 
> If the order of the debug messages is the same as the calls actually
> happen, we AllocatePoolI to address 7DC59018 which we already have added
> as a range. But I'm not going to pretend I even know the code so I'll
> let you comment instead :).

I think this allows us to solve the bug :)

First, forget everything I said :) I was completely lost.

Remember this?

01 efi_main()
02  exit_boot()
03    low_alloc()
04    GetMemoryMap()
05    ExitBootServices()
06
07 start_kernel()
08   setup_arch()
09    efi_memblock_x86_reserve_range()
10    efi_reserve_boot_services()
11  efi_enter_virtual_mode()
12    SetVirtualAddressMap()

Now, lines 01 to 05 *do not happen*.

More precisely, they don't happen in the kernel. They happen in the firmware. Specifically, "OvmfPkg/Library/LoadLinuxLib/Linux.c".

You're booting the kernel from the qemu command line. The kernel you run is also an "[o]ld kernel[] without EFI handover protocol". So what happens is, OVMF downloads the kernel image from qemu over fw_cfg, figures it's an old kernel...

PlatformBdsPolicyBehavior() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c]
  // Process QEMU's -kernel command line option:
  TryRunningQemuKernel()    [OvmfPkg/Library/PlatformBdsLib/QemuKernel.c]
    LoadLinux()             [OvmfPkg/Library/LoadLinuxLib/Linux.c]
      // Old kernels without EFI handover protocol
      SetupLinuxBootParams()
        SetupLinuxMemmap()
          AllocatePool() <-------------- !!!
          gBS->GetMemoryMap()
          gBS->ExitBootServices()
      prints "Jumping to kernel"
      JumpToKernel()

Now pull up efi_memblock_x86_reserve_range(). It reserves "boot_params.efi_info->efi_memmap".

I assumed this field would come from the exit_boot() kernel function. It doesn't. It comes from SetupLinuxMemmap(). The former allocates the backing store as EFI_LOADER_DATA. The latter, alas, marked with !!! above, as boot services data. :)

So, what you're seeing in the OVMF debug log:

> ConvertRange: 7DC59000-7DC5AFFF to 4
> AddRange: 7DC59000-7DC5AFFF to 4
> AllocatePoolI: Type 4, Addr 7DC59018 (len 16F0) 26,735,072

This is self-consistent. It just documents that the AllocatePool() call marked with !!! needs to grab two full pages first (two first lines), carve them up into pool chunks, and then serve the request from them (third line).

The address displayed here shows up in the linux dmesg later on because the storage for the memory map itself is allocated, and populated, by OVMF, not the EFI stub in the kernel.

In one sentence, efi_memblock_x86_reserve_range() expects that "boot_params.efi_info->efi_memmap" has been allocated as "loader data" (by whomever), but SetupLinuxMemmap() violates this by allocating the storage as "boot services data".

This leads to double reservation attempts between efi_memblock_x86_reserve_range(), and efi_reserve_boot_services().

The attached edk2 patch should fix it. Please confirm.

Thanks,
Laszlo


[-- Attachment #2: 0001-OvmfPkg-allocate-the-EFI-memory-map-for-Linux-as-Loa.patch --]
[-- Type: text/plain, Size: 1729 bytes --]

From 4a9e1f10fa2d06496f1983c25c47c6a1373d2f42 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 7 Aug 2013 19:39:30 +0200
Subject: [PATCH] OvmfPkg: allocate the EFI memory map for Linux as Loader Data

In Linux, efi_memblock_x86_reserve_range() and efi_reserve_boot_services()
expect that whoever allocates the EFI memmap allocates it in Loader Data
type memory. Linux's own exit_boot()-->low_alloc() complies, but
SetupLinuxMemmap() in LoadLinuxLib doesn't.

The memory type discrepancy leads to efi_memblock_x86_reserve_range() and
efi_reserve_boot_services() both trying to reserve the range backing the
memmap, resulting in memmap entry truncation in
efi_reserve_boot_services().

This fix also makes this allocation consistent with all other persistent
allocations in  "OvmfPkg/Library/LoadLinuxLib/Linux.c".

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/Library/LoadLinuxLib/Linux.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Library/LoadLinuxLib/Linux.c b/OvmfPkg/Library/LoadLinuxLib/Linux.c
index cd673aa..4a3e2c1 100644
--- a/OvmfPkg/Library/LoadLinuxLib/Linux.c
+++ b/OvmfPkg/Library/LoadLinuxLib/Linux.c
@@ -280,8 +280,12 @@ SetupLinuxMemmap (
   // Enlarge space here, because we will allocate pool now.
   //
   MemoryMapSize += EFI_PAGE_SIZE;
-  MemoryMap = AllocatePool (MemoryMapSize);
-  ASSERT (MemoryMap != NULL);
+  Status = gBS->AllocatePool (
+                  EfiLoaderData,
+                  MemoryMapSize,
+                  (VOID **) &MemoryMap
+                  );
+  ASSERT_EFI_ERROR (Status);
 
   //
   // Get System MemoryMap
-- 
1.7.1


WARNING: multiple messages have this Message-ID (diff)
From: Laszlo Ersek <lersek-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Borislav Petkov <bp-Gina5bIWoIWzQB+pC5nmwQ@public.gmane.org>
Cc: edk2-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	lkml <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Gleb Natapov <gleb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Matthew Garrett <mjg59-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>,
	Matt Fleming
	<matt-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>,
	"Jordan Justen (Intel address)"
	<jordan.l.justen-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: Re: [edk2] Corrupted EFI region
Date: Wed, 07 Aug 2013 19:49:16 +0200	[thread overview]
Message-ID: <5202889C.2080608@redhat.com> (raw)
In-Reply-To: <20130807151935.GJ17920-fF5Pk5pvG8Y@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 4476 bytes --]

On 08/07/13 17:19, Borislav Petkov wrote:
> On Tue, Aug 06, 2013 at 05:31:29PM +0200, Laszlo Ersek wrote:
>> Can you capture the OVMF debug output? Do you see
>>
>>   ConvertPages: Incompatible memory types
>>
>> there?
>>
>> Can you set the following bits too in the debug mask?
>>
>> #define DEBUG_POOL      0x00000010  // Alloc & Free's
>> #define DEBUG_PAGE      0x00000020  // Alloc & Free's
> 
> Ok, I got debug output; I have to be careful now of not missing
> anything. Ok, so here we go:
> 
> First of all, I changed debugging mask to:
> 
>   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8010007F
> 
> (I just set all three bits you requested).
> 
> Using the new OVMF.id changed the addresses, of course, so we're looking
> at 0x7dc59XXX ones now.
> 
> [    0.000000] memblock_reserve: [0x0000007dc59018-0x0000007dc59618] efi_memblock_x86_reserve_range+0x70/0x75
> 
> So, I've attached an archive of the debug logs. The initial observations
> I could do is that the region still gets "squashed" to:
> 
> [    0.014041] efi: mem11: type=4, attr=0xf, range=[0x000000007dc59000-0x000000007dc59000) (0MB)
> 
> from
> 
> [    0.000000] efi: mem11: type=4, attr=0xf, range=[0x000000007dc59000-0x000000007e146000) (4MB)
> 
> And the interesting stuff in the OVMF output is right at the end:
> 
> ConvertRange: 7DC59000-7DC5AFFF to 4
> AddRange: 7DC59000-7DC5AFFF to 4
> AllocatePoolI: Type 4, Addr 7DC59018 (len 16F0) 26,735,072
> Jumping to kernel
> 
> We get that same output no matter if I boot it with "-enable-kvm" or
> not.
> 
> If the order of the debug messages is the same as the calls actually
> happen, we AllocatePoolI to address 7DC59018 which we already have added
> as a range. But I'm not going to pretend I even know the code so I'll
> let you comment instead :).

I think this allows us to solve the bug :)

First, forget everything I said :) I was completely lost.

Remember this?

01 efi_main()
02  exit_boot()
03    low_alloc()
04    GetMemoryMap()
05    ExitBootServices()
06
07 start_kernel()
08   setup_arch()
09    efi_memblock_x86_reserve_range()
10    efi_reserve_boot_services()
11  efi_enter_virtual_mode()
12    SetVirtualAddressMap()

Now, lines 01 to 05 *do not happen*.

More precisely, they don't happen in the kernel. They happen in the firmware. Specifically, "OvmfPkg/Library/LoadLinuxLib/Linux.c".

You're booting the kernel from the qemu command line. The kernel you run is also an "[o]ld kernel[] without EFI handover protocol". So what happens is, OVMF downloads the kernel image from qemu over fw_cfg, figures it's an old kernel...

PlatformBdsPolicyBehavior() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c]
  // Process QEMU's -kernel command line option:
  TryRunningQemuKernel()    [OvmfPkg/Library/PlatformBdsLib/QemuKernel.c]
    LoadLinux()             [OvmfPkg/Library/LoadLinuxLib/Linux.c]
      // Old kernels without EFI handover protocol
      SetupLinuxBootParams()
        SetupLinuxMemmap()
          AllocatePool() <-------------- !!!
          gBS->GetMemoryMap()
          gBS->ExitBootServices()
      prints "Jumping to kernel"
      JumpToKernel()

Now pull up efi_memblock_x86_reserve_range(). It reserves "boot_params.efi_info->efi_memmap".

I assumed this field would come from the exit_boot() kernel function. It doesn't. It comes from SetupLinuxMemmap(). The former allocates the backing store as EFI_LOADER_DATA. The latter, alas, marked with !!! above, as boot services data. :)

So, what you're seeing in the OVMF debug log:

> ConvertRange: 7DC59000-7DC5AFFF to 4
> AddRange: 7DC59000-7DC5AFFF to 4
> AllocatePoolI: Type 4, Addr 7DC59018 (len 16F0) 26,735,072

This is self-consistent. It just documents that the AllocatePool() call marked with !!! needs to grab two full pages first (two first lines), carve them up into pool chunks, and then serve the request from them (third line).

The address displayed here shows up in the linux dmesg later on because the storage for the memory map itself is allocated, and populated, by OVMF, not the EFI stub in the kernel.

In one sentence, efi_memblock_x86_reserve_range() expects that "boot_params.efi_info->efi_memmap" has been allocated as "loader data" (by whomever), but SetupLinuxMemmap() violates this by allocating the storage as "boot services data".

This leads to double reservation attempts between efi_memblock_x86_reserve_range(), and efi_reserve_boot_services().

The attached edk2 patch should fix it. Please confirm.

Thanks,
Laszlo


[-- Attachment #2: 0001-OvmfPkg-allocate-the-EFI-memory-map-for-Linux-as-Loa.patch --]
[-- Type: text/plain, Size: 1729 bytes --]

From 4a9e1f10fa2d06496f1983c25c47c6a1373d2f42 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Wed, 7 Aug 2013 19:39:30 +0200
Subject: [PATCH] OvmfPkg: allocate the EFI memory map for Linux as Loader Data

In Linux, efi_memblock_x86_reserve_range() and efi_reserve_boot_services()
expect that whoever allocates the EFI memmap allocates it in Loader Data
type memory. Linux's own exit_boot()-->low_alloc() complies, but
SetupLinuxMemmap() in LoadLinuxLib doesn't.

The memory type discrepancy leads to efi_memblock_x86_reserve_range() and
efi_reserve_boot_services() both trying to reserve the range backing the
memmap, resulting in memmap entry truncation in
efi_reserve_boot_services().

This fix also makes this allocation consistent with all other persistent
allocations in  "OvmfPkg/Library/LoadLinuxLib/Linux.c".

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/Library/LoadLinuxLib/Linux.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/Library/LoadLinuxLib/Linux.c b/OvmfPkg/Library/LoadLinuxLib/Linux.c
index cd673aa..4a3e2c1 100644
--- a/OvmfPkg/Library/LoadLinuxLib/Linux.c
+++ b/OvmfPkg/Library/LoadLinuxLib/Linux.c
@@ -280,8 +280,12 @@ SetupLinuxMemmap (
   // Enlarge space here, because we will allocate pool now.
   //
   MemoryMapSize += EFI_PAGE_SIZE;
-  MemoryMap = AllocatePool (MemoryMapSize);
-  ASSERT (MemoryMap != NULL);
+  Status = gBS->AllocatePool (
+                  EfiLoaderData,
+                  MemoryMapSize,
+                  (VOID **) &MemoryMap
+                  );
+  ASSERT_EFI_ERROR (Status);
 
   //
   // Get System MemoryMap
-- 
1.7.1


  parent reply	other threads:[~2013-08-07 17:47 UTC|newest]

Thread overview: 108+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-31 20:54 Corrupted EFI region Borislav Petkov
2013-07-31 20:54 ` Borislav Petkov
2013-07-31 20:58 ` Matthew Garrett
2013-07-31 20:58   ` Matthew Garrett
2013-07-31 21:51   ` Borislav Petkov
2013-07-31 21:51     ` Borislav Petkov
2013-07-31 21:54     ` Matthew Garrett
2013-07-31 21:54       ` Matthew Garrett
2013-08-01 16:51       ` Borislav Petkov
2013-08-01 16:51         ` Borislav Petkov
2013-07-31 21:55 ` David Woodhouse
2013-07-31 21:55   ` David Woodhouse
2013-08-01 16:49   ` Borislav Petkov
2013-08-01 16:49     ` Borislav Petkov
2013-08-05 11:27     ` [edk2] " Laszlo Ersek
2013-08-05 11:27       ` Laszlo Ersek
2013-08-05 13:02       ` Borislav Petkov
2013-08-05 13:02         ` Borislav Petkov
2013-08-05 13:39         ` Laszlo Ersek
2013-08-05 13:39           ` Laszlo Ersek
2013-08-05 14:03           ` Borislav Petkov
2013-08-05 14:03             ` Borislav Petkov
2013-08-05 14:27             ` Laszlo Ersek
2013-08-05 14:27               ` Laszlo Ersek
2013-08-05 14:40               ` Borislav Petkov
2013-08-05 14:40                 ` Borislav Petkov
2013-08-05 15:15                 ` Laszlo Ersek
2013-08-05 15:15                   ` Laszlo Ersek
2013-08-05 15:34                   ` James Bottomley
2013-08-05 15:34                     ` James Bottomley
2013-08-05 16:27                     ` Laszlo Ersek
2013-08-05 16:27                       ` Laszlo Ersek
2013-08-05 16:12                   ` Borislav Petkov
2013-08-05 16:12                     ` Borislav Petkov
2013-08-05 16:41                     ` Laszlo Ersek
2013-08-05 16:41                       ` Laszlo Ersek
2013-08-05 16:47                       ` Borislav Petkov
2013-08-05 16:47                         ` Borislav Petkov
2013-08-05 17:00                         ` Kinney, Michael D
2013-08-05 17:00                           ` Kinney, Michael D
2013-08-05 17:09                         ` Laszlo Ersek
2013-08-05 17:09                           ` Laszlo Ersek
2013-08-05 21:26                         ` Laszlo Ersek
2013-08-05 21:26                           ` Laszlo Ersek
2013-08-05 22:08                           ` Borislav Petkov
2013-08-05 22:08                             ` Borislav Petkov
2013-08-06 14:10                             ` Borislav Petkov
2013-08-06 14:10                               ` Borislav Petkov
2013-08-06 15:31                               ` Laszlo Ersek
2013-08-06 15:31                                 ` Laszlo Ersek
2013-08-07 15:19                                 ` Borislav Petkov
2013-08-07 17:23                                   ` Andrew Fish
2013-08-07 17:23                                     ` Andrew Fish
2013-08-07 20:19                                     ` Matt Fleming
2013-08-07 20:19                                       ` Matt Fleming
2013-08-07 20:24                                       ` Matt Fleming
2013-08-07 20:24                                         ` Matt Fleming
2013-08-07 21:10                                       ` Andrew Fish
2013-08-07 21:10                                         ` Andrew Fish
2013-08-07 21:23                                         ` Matthew Garrett
2013-08-08 10:17                                         ` Matt Fleming
2013-08-08 10:17                                           ` Matt Fleming
2013-08-08 13:46                                           ` Andrew Fish
2013-08-08 13:46                                             ` Andrew Fish
2013-09-02  8:19                                             ` Matt Fleming
2013-09-02  8:19                                               ` Matt Fleming
2013-09-13 20:38                                           ` jerry.hoemann
2013-09-13 20:38                                             ` jerry.hoemann-VXdhtT5mjnY
2013-09-16 10:59                                             ` Matt Fleming
2013-09-16 10:59                                               ` Matt Fleming
2013-09-16 11:50                                               ` Laszlo Ersek
2013-09-16 11:50                                                 ` Laszlo Ersek
2013-09-16 15:57                                                 ` Josh Triplett
2013-09-16 15:57                                                   ` Josh Triplett
2013-09-16 16:25                                                   ` Laszlo Ersek
2013-09-16 16:25                                                     ` Laszlo Ersek
2013-09-16 16:27                                                     ` Matthew Garrett
2013-09-16 16:27                                                       ` Matthew Garrett
2013-09-16 16:29                                                     ` Josh Triplett
2013-09-16 16:29                                                       ` Josh Triplett
2013-09-18 19:24                                               ` jerry.hoemann
2013-09-18 19:24                                                 ` jerry.hoemann-VXdhtT5mjnY
2013-09-20  9:06                                                 ` Matt Fleming
2013-09-20  9:06                                                   ` Matt Fleming
2013-08-07 17:49                                   ` Laszlo Ersek [this message]
2013-08-07 17:49                                     ` Laszlo Ersek
2013-08-08 15:02                                     ` Borislav Petkov
2013-08-08 15:02                                       ` Borislav Petkov
2013-08-08 21:45                                       ` Brian J. Johnson
2013-08-08 21:45                                         ` Brian J. Johnson
2013-08-18  7:33                                     ` Jordan Justen
2013-08-18  7:33                                       ` Jordan Justen
2013-08-05 15:50                 ` Andrew Fish
2013-08-05 15:50                   ` Andrew Fish
2013-08-05 18:12                   ` Borislav Petkov
2013-08-05 18:12                     ` Borislav Petkov
2013-08-05 21:37                     ` H. Peter Anvin
2013-08-05 21:37                       ` H. Peter Anvin
2013-08-05 21:41                       ` Borislav Petkov
2013-08-05 21:41                         ` Borislav Petkov
2013-08-05 21:49                         ` H. Peter Anvin
2013-08-05 21:49                           ` H. Peter Anvin
2013-08-05 21:55                         ` Laszlo Ersek
2013-08-05 21:55                           ` Laszlo Ersek
2013-08-05 22:52                           ` James Bottomley
2013-08-05 22:52                             ` James Bottomley
2013-08-06  7:26                             ` Laszlo Ersek
2013-08-06  7:26                               ` Laszlo Ersek

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=5202889C.2080608@redhat.com \
    --to=lersek@redhat.com \
    --cc=bp@alien8.de \
    --cc=dwmw2@infradead.org \
    --cc=edk2-devel@lists.sourceforge.net \
    --cc=gleb@redhat.com \
    --cc=jordan.l.justen@intel.com \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt@console-pimps.org \
    --cc=mjg59@srcf.ucam.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.