public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Laszlo Ersek" <lersek@redhat.com>
To: Dun Tan <dun.tan@intel.com>, devel@edk2.groups.io
Cc: Ray Ni <ray.ni@intel.com>, Rahul Kumar <rahul1.kumar@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm:Map SMRAM in 4K page granularity
Date: Tue, 6 Feb 2024 14:33:36 +0100	[thread overview]
Message-ID: <c359a40c-4e57-c57d-f5ae-dd1857c6e57a@redhat.com> (raw)
In-Reply-To: <20240205140345.1437-4-dun.tan@intel.com>

On 2/5/24 15:03, Dun Tan wrote:
> This patch is to map SMRAM in 4K page granularity
> during SMM page table initialization(SmmInitPageTable)
> so as to avoid the SMRAM paging-structure layout
> change when SMI happens (PerformRemainingTasks).
> The reason is to avoid the Paging-Structure change
> impact to the multiple Processors. Refer SDM section
> "4.10.4" & "4.10.5".
> 
> Currently, SMM BSP needs to update the SMRAM range
> paging attribute in smm page table according to the
> SmmMemoryAttributesTable when SMM ready to lock
> happens. If the SMRAM range is not 4k mapped in page
> table, the page table update process may split 1G/2M
> paging entries to 4k ones.Meanwhile, all APs are still
> running in SMI, which might access the affected
> linear-address range between the time of modification
> and the time of invalidation access. That will be
> a potential problem leading exception happens.

Is this originally a bug from commit 717fb60443fb
("UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.", 2016-11-17)?

Laszlo

> 
> Signed-off-by: Dun Tan <dun.tan@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 92 insertions(+), 24 deletions(-)
> 
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> index 12f3c0b8e8..0012d63674 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
> @@ -1647,49 +1647,115 @@ EdkiiSmmClearMemoryAttributes (
>  }
>  
>  /**
> -  Create page table based on input PagingMode and PhysicalAddressBits in smm.
> -
> -  @param[in]      PagingMode           The paging mode.
> -  @param[in]      PhysicalAddressBits  The bits of physical address to map.
> +  Create page table based on input PagingMode, LinearAddress and Length.
>  
> -  @retval         PageTable Address
> +  @param[in, out]  PageTable           The pointer to the page table.
> +  @param[in]       PagingMode          The paging mode.
> +  @param[in]       LinearAddress       The start of the linear address range.
> +  @param[in]       Length              The length of the linear address range.
>  
>  **/
> -UINTN
> -GenSmmPageTable (
> -  IN PAGING_MODE  PagingMode,
> -  IN UINT8        PhysicalAddressBits
> +VOID
> +GenPageTable (
> +  IN OUT UINTN        *PageTable,
> +  IN     PAGING_MODE  PagingMode,
> +  IN     UINT64       LinearAddress,
> +  IN     UINT64       Length
>    )
>  {
> +  RETURN_STATUS       Status;
>    UINTN               PageTableBufferSize;
> -  UINTN               PageTable;
>    VOID                *PageTableBuffer;
>    IA32_MAP_ATTRIBUTE  MapAttribute;
>    IA32_MAP_ATTRIBUTE  MapMask;
> -  RETURN_STATUS       Status;
> -  UINTN               GuardPage;
> -  UINTN               Index;
> -  UINT64              Length;
>  
> -  Length                           = LShiftU64 (1, PhysicalAddressBits);
> -  PageTable                        = 0;
> -  PageTableBufferSize              = 0;
>    MapMask.Uint64                   = MAX_UINT64;
> -  MapAttribute.Uint64              = mAddressEncMask;
> +  MapAttribute.Uint64              = mAddressEncMask|LinearAddress;
>    MapAttribute.Bits.Present        = 1;
>    MapAttribute.Bits.ReadWrite      = 1;
>    MapAttribute.Bits.UserSupervisor = 1;
>    MapAttribute.Bits.Accessed       = 1;
>    MapAttribute.Bits.Dirty          = 1;
> +  PageTableBufferSize              = 0;
> +
> +  Status = PageTableMap (
> +             PageTable,
> +             PagingMode,
> +             NULL,
> +             &PageTableBufferSize,
> +             LinearAddress,
> +             Length,
> +             &MapAttribute,
> +             &MapMask,
> +             NULL
> +             );
> +  if (Status == RETURN_BUFFER_TOO_SMALL) {
> +    DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize));
> +    PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
> +    ASSERT (PageTableBuffer != NULL);
> +    Status = PageTableMap (
> +               PageTable,
> +               PagingMode,
> +               PageTableBuffer,
> +               &PageTableBufferSize,
> +               LinearAddress,
> +               Length,
> +               &MapAttribute,
> +               &MapMask,
> +               NULL
> +               );
> +  }
>  
> -  Status = PageTableMap (&PageTable, PagingMode, NULL, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
> -  ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
> -  DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize));
> -  PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
> -  ASSERT (PageTableBuffer != NULL);
> -  Status = PageTableMap (&PageTable, PagingMode, PageTableBuffer, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
>    ASSERT (Status == RETURN_SUCCESS);
>    ASSERT (PageTableBufferSize == 0);
> +}
> +
> +/**
> +  Create page table based on input PagingMode and PhysicalAddressBits in smm.
> +
> +  @param[in]      PagingMode           The paging mode.
> +  @param[in]      PhysicalAddressBits  The bits of physical address to map.
> +
> +  @retval         PageTable Address
> +
> +**/
> +UINTN
> +GenSmmPageTable (
> +  IN PAGING_MODE  PagingMode,
> +  IN UINT8        PhysicalAddressBits
> +  )
> +{
> +  UINTN          PageTable;
> +  RETURN_STATUS  Status;
> +  UINTN          GuardPage;
> +  UINTN          Index;
> +  UINT64         Length;
> +  PAGING_MODE    SmramPagingMode;
> +
> +  PageTable = 0;
> +  Length    = LShiftU64 (1, PhysicalAddressBits);
> +  ASSERT (Length > mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize);
> +
> +  if (sizeof (UINTN) == sizeof (UINT64)) {
> +    SmramPagingMode = m5LevelPagingNeeded ? Paging5Level4KB : Paging4Level4KB;
> +  } else {
> +    SmramPagingMode = PagingPae4KB;
> +  }
> +
> +  GenPageTable (&PageTable, PagingMode, 0, mCpuHotPlugData.SmrrBase);
> +
> +  //
> +  // Map smram range in 4K page granularity to avoid subsequent page split when smm ready to lock.
> +  // If BSP are splitting the 1G/2M paging entries to 512 2M/4K paging entries, and all APs are
> +  // still running in SMI at the same time, which might access the affected linear-address range
> +  // between the time of modification and the time of invalidation access. That will be a potential
> +  // problem leading exception happen.
> +  //
> +  ASSERT (mCpuHotPlugData.SmrrBase % SIZE_4KB == 0);
> +  ASSERT (mCpuHotPlugData.SmrrSize % SIZE_4KB == 0);
> +  GenPageTable (&PageTable, SmramPagingMode, mCpuHotPlugData.SmrrBase, mCpuHotPlugData.SmrrSize);
> +
> +  GenPageTable (&PageTable, PagingMode, mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize, Length - mCpuHotPlugData.SmrrBase - mCpuHotPlugData.SmrrSize);
>  
>    if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
>      //
> @@ -1698,6 +1764,7 @@ GenSmmPageTable (
>      for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
>        GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE + Index * (mSmmStackSize + mSmmShadowStackSize);
>        Status    = ConvertMemoryPageAttributes (PageTable, PagingMode, GuardPage, SIZE_4KB, EFI_MEMORY_RP, TRUE, NULL);
> +      ASSERT (Status == RETURN_SUCCESS);
>      }
>    }
>  
> @@ -1706,6 +1773,7 @@ GenSmmPageTable (
>      // Mark [0, 4k] as non-present
>      //
>      Status = ConvertMemoryPageAttributes (PageTable, PagingMode, 0, SIZE_4KB, EFI_MEMORY_RP, TRUE, NULL);
> +    ASSERT (Status == RETURN_SUCCESS);
>    }
>  
>    return (UINTN)PageTable;



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115163): https://edk2.groups.io/g/devel/message/115163
Mute This Topic: https://groups.io/mt/104176237/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-02-06 13:33 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-05 14:03 [edk2-devel] [PATCH 0/3] Fix potential issue in CpuPageTableLib and SMM page table initialization duntan
2024-02-05 14:03 ` [edk2-devel] [PATCH 1/3] UefiCpuPkg: Reduce and optimize access to attribute duntan
2024-02-06  1:20   ` Ni, Ray
2024-02-06 13:32   ` Laszlo Ersek
2024-02-06 15:02     ` Ni, Ray
2024-02-06 17:34     ` Pedro Falcato
2024-02-07  0:47       ` Zhou, Jianfeng
2024-02-07  1:05         ` Pedro Falcato
2024-02-07  1:57           ` Zhou, Jianfeng
2024-02-07 17:52             ` Pedro Falcato
2024-02-07 20:42             ` Laszlo Ersek
2024-02-08  2:29               ` Zhou, Jianfeng
2024-02-07 20:33           ` Laszlo Ersek
2024-02-07 20:17         ` Laszlo Ersek
2024-02-05 14:03 ` [edk2-devel] [PATCH 2/3] UefiCpuPkg: Add more Paging mode enumeration duntan
2024-02-06  1:21   ` Ni, Ray
2024-02-05 14:03 ` [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpuDxeSmm:Map SMRAM in 4K page granularity duntan
2024-02-06  1:23   ` Ni, Ray
2024-02-06 13:33   ` Laszlo Ersek [this message]
2024-02-06  1:48 ` [edk2-devel] [PATCH 0/3] Fix potential issue in CpuPageTableLib and SMM page table initialization Ni, Ray

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=c359a40c-4e57-c57d-f5ae-dd1857c6e57a@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