[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4] Preserve the EFI System Resource Table for dom0


  • To: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Fri, 6 May 2022 12:59:05 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yHgJ52YHejUk3gYauOHYjxRwapqI9poP6xLYhR0n7V8=; b=eFSjbQ3MGpgdLuXMNl5Ubazwid0hV/Z9HZJVMzTUP3ZcKlUIU5T4IWKQhIWY7tWmR6mzv282u3IeDvAp/18k6geNFQTq7H7pv/GkeJUq521B30uaE5+neMQVnpOfYdBQHXfuf6MBUPyknQ3uOLO3aoyOSR+Ikh/mY8WjZiDKMng9q0QBxreoO3xanz+7SCVqjwUsG0lGZeEFoNwm0hEZ3TLC9Z2Z2dpuSneMZLO2KLWqy4NJouMNXuGwV0eZhy4ywm2HCDvAvpikN9oQ1LuGY5qIwgLqMPRhz3YzXbvtheHxKj0iBGRaMW9Q42+8BRURLTMfZOdiO0wPViHk7yoWeQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fVIjcMKZdD/xdE3C1BFY1w8rgOIul7IF/WEbKthxPMpKSe2kxJ0agnQf7YMO2yQAA/o2zrmTXljauOxUxLqwBEZ4UWw/7yMrzeuuqJ+m5XHXRMaDVgxJx5G34mMrOpGlXF9DifaYCz03R9PQOE/qs0beSL0WZAdpe2wH0sKkIRGzIyPMkSyDvAVteMogN3/BtCBH9gtri0J+cyHEIvi1V7hLtSDb1IbSIIQS8GHd+/HZUzKQEQfmVGEjohNLlqkNOR0315hwXOiMW1KaQKbfUcjOiqGwMXrgt2r1818j+rdDxpDdhknpMlMU4GS2D7NnBgP5td5YWwzX3ad+REh3kQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Fri, 06 May 2022 10:59:27 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 05.05.2022 07:38, Demi Marie Obenour wrote:
> @@ -1056,13 +1091,11 @@ static void __init efi_exit_boot(EFI_HANDLE 
> ImageHandle, EFI_SYSTEM_TABLE *Syste
>      EFI_STATUS status;
>      UINTN info_size = 0, map_key;
>      bool retry;
> -#ifdef CONFIG_EFI_SET_VIRTUAL_ADDRESS_MAP
>      unsigned int i;
> -#endif
>  
>      efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
>                           &efi_mdesc_size, &mdesc_ver);
> -    info_size += 8 * efi_mdesc_size;
> +    info_size += 8 * (efi_mdesc_size + 1);

I think I did ask on an earlier version already why you're making this
change. It continues to look to me like a leftover which was needed by
an early version only.

> @@ -1077,6 +1110,35 @@ static void __init efi_exit_boot(EFI_HANDLE 
> ImageHandle, EFI_SYSTEM_TABLE *Syste
>          if ( EFI_ERROR(status) )
>              PrintErrMesg(L"Cannot obtain memory map", status);
>  
> +        for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> +        {
> +            if ( !is_esrt_valid(efi_memmap + i) )
> +                continue;

Instead of repeating the size calculation below, could you make the
function (with an altered name) simply return the size (and zero if
not [valid] ESRT), simplifying things below?

> +            if ( ((EFI_MEMORY_DESCRIPTOR *)(efi_memmap + i))->Type !=
> +                 EfiRuntimeServicesData )
> +            {
> +                /* ESRT needs to be moved to memory of type 
> EfiRuntimeServicesData
> +                 * so that the memory it is in will not be used for other 
> purposes */

Nit: Comment style.

> +                size_t esrt_size = offsetof(ESRT, Entries) +
> +                    ((ESRT *)esrt)->Count * sizeof(ESRT_ENTRY);
> +                void *new_esrt = NULL;
> +                status = efi_bs->AllocatePool(EfiRuntimeServicesData, 
> esrt_size, &new_esrt);

Nit: Please have a blank line between declaration(s) and statement(s).

> +                if ( status != EFI_SUCCESS )
> +                {
> +                    PrintErrMesg(L"Cannot allocate memory for ESRT", status);

Neither this nor ...

> +                    break;
> +                }
> +                memcpy(new_esrt, (void *)esrt, esrt_size);
> +                status = efi_bs->InstallConfigurationTable(&esrt_guid, 
> new_esrt);
> +                if ( status != EFI_SUCCESS )
> +                {
> +                    PrintErrMesg(L"Cannot install new ESRT", status);
> +                    efi_bs->FreePool(new_esrt);

... this ought to be fatal to the booting of Xen. Yet PrintErrMesg()
ends in blexit().

> +                }
> +            }
> +            break;
> +        }
> +
>          efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
>                                      efi_mdesc_size, mdesc_ver);

The allocation may have altered the memory map and hence invalidated what
was retrieved just before. You'd need to "continue;" without setting
"retry" to true, but then the question is why you make this allocation
after retrieving the memory map in the first place. It's not entirely
clear to me if it can be done _much_ earlier (if it can, doing it earlier
would of course be better), but since you need to do it before
ExitBootServices() anyway, and since you will need to call GetMemoryMap()
afterwards again, you could as well do it before calling GetMemoryMap().

> --- a/xen/common/efi/efi.h
> +++ b/xen/common/efi/efi.h
> @@ -10,6 +10,23 @@
>  #include <xen/spinlock.h>
>  #include <asm/page.h>
>  
> +typedef struct _ESRT_ENTRY {
> +    EFI_GUID FwClass;
> +    UINT32 FwType;
> +    UINT32 FwVersion;
> +    UINT32 FwLowestSupportedVersion;
> +    UINT32 FwCapsuleFlags;
> +    UINT32 FwLastAttemptVersion;
> +    UINT32 FwLastAttemptStatus;
> +} ESRT_ENTRY;
> +
> +typedef struct _ESRT {
> +    UINT32 Count;
> +    UINT32 Max;
> +    UINT64 Version;
> +    ESRT_ENTRY Entries[];
> +} ESRT;

I'm pretty sure I did indicate before that types used in just a single
source file should be put in that source file, unless we obtain them
by importing a header (e.g. the ones in include/efi/) from elsewhere.

> --- a/xen/common/efi/runtime.c
> +++ b/xen/common/efi/runtime.c
> @@ -269,7 +269,7 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
>      case XEN_FW_EFI_MEM_INFO:
>          for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
>          {
> -            EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> +            const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
>              u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
>  
>              if ( info->mem.addr >= desc->PhysicalStart &&

With the restructured approach I don't think this stray change should
be left in here anymore. Or am I overlooking anything requiring this
adjustment?

> --- a/xen/include/efi/efiapi.h
> +++ b/xen/include/efi/efiapi.h
> @@ -882,6 +882,9 @@ typedef struct _EFI_BOOT_SERVICES {
>  #define SAL_SYSTEM_TABLE_GUID    \
>      { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 
> 0x4d} }
>  
> +#define ESRT_GUID    \
> +    { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 
> 0x80} }

Like above I'm pretty sure I did ask that you do not alter this
imported header. If gnu-efi now has these definitions, we should
import them all in one go (i.e. then the two struct declarations
would also want to go into their appropriate place under include/efi/.
Otherwise this wants putting next to the other GUIDs defined in
boot.c.

Jan




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.