public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Laszlo Ersek" <lersek@redhat.com>
To: jejb@linux.ibm.com, devel@edk2.groups.io,
	Bret Barkelew <brbarkel@microsoft.com>,
	"Liming Gao (Byosoft address)" <gaoliming@byosoft.com.cn>
Cc: dovmurik@linux.vnet.ibm.com, Dov.Murik1@il.ibm.com,
	ashish.kalra@amd.com, brijesh.singh@amd.com, tobin@ibm.com,
	david.kaplan@amd.com, jon.grimm@amd.com, thomas.lendacky@amd.com,
	frankeh@us.ibm.com,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
	"Ard Biesheuvel (ARM address)" <ard.biesheuvel@arm.com>
Subject: Re: [edk2-devel] [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package
Date: Wed, 25 Nov 2020 20:08:02 +0100	[thread overview]
Message-ID: <e502bc20-f636-949c-a7bc-1d17394345e2@redhat.com> (raw)
In-Reply-To: <53957e99-3f81-0121-b8fd-db28fdb01a73@redhat.com>

On 11/25/20 19:35, Laszlo Ersek wrote:
> On 11/25/20 18:09, James Bottomley wrote:
>> On Wed, 2020-11-25 at 08:02 -0800, James Bottomley wrote:
>>> On Wed, 2020-11-25 at 15:01 +0100, Laszlo Ersek wrote:
>>>> This upgrade gave me kernel 5.8.18-100.fc31.x86_64 in the guest --
>>>> and this one does *not* crash. From your boot log below, I see your
>>>> guest kernel is 5.5.0; I suggest upgrading it.
>>>
>>> Heh, that's easier said than done ... I always make my encrypted
>>> images too small to upgrade a kernel easily.  Anyway, after doing the
>>> remove and add stuff dance, I finally got it upgraded to the latest
>>> debian testing linux-image-5.8.0-3 it's still crashing although with
>>> a slightly different traceback.  It looks like there might be
>>> something additional in the fedora 5.8 kernel that fixes this.  I'm
>>> going to try out upstream kernels next.
>>
>> I've got the upstream kernel booting through OVMF with a qemu -kernel
>> command line.  I also have a fix: it's not to delete the dummy variable
>> which was part of the ancient x86 anti bricking code (which is also why
>> arm64 doesn't have the problem).
>>
>> If you remove the set variable in arch/x86/platform/efi/quirks.c:
>>
>> /*
>>  * Deleting the dummy variable which kicks off garbage collection
>> */
>> void efi_delete_dummy_variable(void)
>> {
>> 	efi.set_variable_nonblocking((efi_char16_t *)efi_dummy_name,
>> 				     &EFI_DUMMY_GUID,
>> 				     EFI_VARIABLE_NON_VOLATILE |
>> 				     EFI_VARIABLE_BOOTSERVICE_ACCESS |
>> 				     EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL);
>> }
>>
>> The kernel will boot.  I'm not sure why we have this deletion
>> unconditionally in efi_enter_virtual_mode, but removing the call with
>> the patch below allows the kernel to boot.
> 
> I think commit 2ecb7402cfc7 ("efi/x86: Do not clean dummy variable in
> kexec path", 2019-10-07) is related (part of v5.4), but it's not
> sufficient to prevent the boot crash. (That removal only covered the
> kexec path, and not the normal boot path.)
> 
>>
>> However, once the kernel has booted, any attempt to write to an EFI
>> variable results in this:
>>
>> [  975.440240] [Firmware Bug]: Page fault caused by firmware at PA: 0x7e450020
>>
>> And then the efi runtime gets disabled.
> 
> Blech, that doesn't look good. We still get a page fault somewhere in
> the firmware, it just doesn't kill the kernel outright. That kind of
> suggests the crash on the boot path *is* firmware-originated, it's just
> that the kernel is unable to mask the problem that early.

Actually, I do think we have a bug in the firmware. I need to verify it
(and if verification confirms it, to send a patch for it). Consider the
following snippet in file
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c", function
RegisterVariablePolicy():

    // Reallocate and copy the table.
    NewTable = AllocatePool( NewSize );
    if (NewTable == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem( NewTable, mPolicyTable, mCurrentTableUsage );
    mCurrentTableSize = NewSize;
    if (mPolicyTable != NULL) {
      FreePool( mPolicyTable );
    }
    mPolicyTable = NewTable;


* In the SMM build of OVMF, this code is linked (via
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf") into the
following SMM driver:

  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf

For that module (well, for SMM drivers in general), the AllocatePool()
function comes from the following MemoryAllocationLib instance:

  MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf

and so the AllocatePool() call ultimately boils down to allocating *SMRAM*:

  gSmst->SmmAllocatePool()

Which is fine.


* However, in the non-SMM build, the same code snippet is linked (via
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf")
into the following driver:

  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

In this module (well, in runtime DXE drivers in general), the
AllocatePool() call function comes from the following
MemoryAllocationLib instance:

  MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf

And that is *wrong*. Because there, AllocatePool() allocates Boot
Services Data type memory, via

  gBS->AllocatePool() *plus* "EfiBootServicesData"

Therefore, even though VariablePolicyLibVirtualAddressCallback() in file
"MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c"
attempts to convert "mPolicyTable" to a runtime virtual address, in the
SMM-less build, that conversion fails -- the original memory that the
pointer points at, pre-conversion, is not runtime, but boot time memory.


The fix *should be* to call AllocateRuntimePool() from the
MemoryAllocationLib class. In the SMM instance, that will make no
difference; compare, in
"MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c":

VOID *
EFIAPI
AllocatePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

VOID *
EFIAPI
AllocateRuntimePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

The InternalAllocatePool() calls are identical, in the SMM instance.


Whereas in the UEFI instance, in
"MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c", it does
make a difference; compare:

VOID *
EFIAPI
AllocatePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiBootServicesData, AllocationSize);
}

VOID *
EFIAPI
AllocateRuntimePool (
  IN UINTN  AllocationSize
  )
{
  return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
}

The "MemoryType" parameter of InternalAllocatePool(), which gets
forwarded to gBS->AllocatePool(), changes from "EfiBootServicesData" to
"EfiRuntimeServicesData".

Let me test this.

(BTW I see some more pool allocations in
"MdeModulePkg/Library/VariablePolicyHelperLib" to... I guess I'll have
to check those as well.)

Thanks
Laszlo


  reply	other threads:[~2020-11-25 19:08 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20 18:45 [PATCH v2 0/6] SEV Encrypted Boot for Ovmf James Bottomley
2020-11-20 18:45 ` [PATCH v2 1/6] OvmfPkg/Amdsev: Base commit to build encrypted boot specific OVMF James Bottomley
2020-11-23 18:01   ` Laszlo Ersek
2020-11-23 23:25     ` James Bottomley
2020-11-23 23:43       ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 2/6] OvmfPkg/AmdSev: add Grub Firmware Volume Package James Bottomley
2020-11-23 21:08   ` Laszlo Ersek
2020-11-24  6:38     ` James Bottomley
2020-11-24  8:23       ` Laszlo Ersek
2020-11-24 14:54         ` Laszlo Ersek
2020-11-24 15:58           ` Laszlo Ersek
2020-11-24 16:22             ` [edk2-devel] " James Bottomley
2020-11-24 23:22               ` Laszlo Ersek
2020-11-24 23:42                 ` James Bottomley
2020-11-25  1:27                   ` James Bottomley
2020-11-25 14:01                     ` Laszlo Ersek
2020-11-25 16:02                       ` James Bottomley
2020-11-25 17:09                         ` James Bottomley
2020-11-25 18:17                           ` James Bottomley
2020-11-25 19:20                             ` Laszlo Ersek
2020-11-25 20:11                               ` James Bottomley
2020-11-25 18:35                           ` Laszlo Ersek
2020-11-25 19:08                             ` Laszlo Ersek [this message]
2020-11-25 19:14                               ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 3/6] OvmfPkg: convert ES Reset Block structure to be guided James Bottomley
2020-11-23 22:16   ` Laszlo Ersek
2020-11-24 14:57     ` Lendacky, Thomas
2020-11-24 19:07       ` James Bottomley
2020-11-24 23:19         ` Laszlo Ersek
2020-11-24 19:05     ` James Bottomley
2020-11-24 23:15       ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 4/6] OvmfPkg: create a SEV secret area in the AmdSev memfd James Bottomley
2020-11-23 22:28   ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 5/6] OvmfPkg/AmdSev: assign and protect the Sev Secret area James Bottomley
2020-11-23 22:38   ` Laszlo Ersek
2020-11-20 18:45 ` [PATCH v2 6/6] OvmfPkg/AmdSev: Expose the Sev Secret area using a configuration table James Bottomley
2020-11-23 22:56   ` 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-list 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=e502bc20-f636-949c-a7bc-1d17394345e2@redhat.com \
    --to=devel@edk2.groups.io \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox