diff --git a/0023-OvmfPkg-ResetVector-improve-page-table-flag-names.patch b/0023-OvmfPkg-ResetVector-improve-page-table-flag-names.patch new file mode 100644 index 0000000000000000000000000000000000000000..9018373fbb6271fb26cf4666a8a35436d9a043be --- /dev/null +++ b/0023-OvmfPkg-ResetVector-improve-page-table-flag-names.patch @@ -0,0 +1,120 @@ +From 1c6421bd87b9586b235ca924055a82b102bd32e9 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:53 +0100 +Subject: [PATCH 23/34] OvmfPkg/ResetVector: improve page table flag names + +commit fded08e74400fd0b76ad4733111e946f3ecea244 upstream + +Add comments, rename some of the PAGE_* flags and combined attributes. +Specifically use "LARGEPAGE" instead of "2M" because that bit is used +for both 2M and 1G large pages. + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-2-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 39 +++++++++++++---------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 317cad430f29..6fec6f2beeea 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -10,6 +10,7 @@ + + BITS 32 + ++; common for all levels + %define PAGE_PRESENT 0x01 + %define PAGE_READ_WRITE 0x02 + %define PAGE_USER_SUPERVISOR 0x04 +@@ -17,25 +18,29 @@ BITS 32 + %define PAGE_CACHE_DISABLE 0x010 + %define PAGE_ACCESSED 0x020 + %define PAGE_DIRTY 0x040 +-%define PAGE_PAT 0x080 + %define PAGE_GLOBAL 0x0100 +-%define PAGE_2M_MBO 0x080 +-%define PAGE_2M_PAT 0x01000 ++ ++; page table entries (level 1) ++%define PAGE_PTE_PAT 0x080 ++ ++; page directory entries (level 2+) ++%define PAGE_PDE_LARGEPAGE 0x080 ++%define PAGE_PDE_PAT 0x01000 + + %define PAGE_4K_PDE_ATTR (PAGE_ACCESSED + \ + PAGE_DIRTY + \ + PAGE_READ_WRITE + \ + PAGE_PRESENT) + +-%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \ +- PAGE_ACCESSED + \ +- PAGE_DIRTY + \ +- PAGE_READ_WRITE + \ +- PAGE_PRESENT) ++%define PAGE_PDE_LARGEPAGE_ATTR (PAGE_PDE_LARGEPAGE + \ ++ PAGE_ACCESSED + \ ++ PAGE_DIRTY + \ ++ PAGE_READ_WRITE + \ ++ PAGE_PRESENT) + +-%define PAGE_PDP_ATTR (PAGE_ACCESSED + \ +- PAGE_READ_WRITE + \ +- PAGE_PRESENT) ++%define PAGE_PDE_DIRECTORY_ATTR (PAGE_ACCESSED + \ ++ PAGE_READ_WRITE + \ ++ PAGE_PRESENT) + + %define TDX_BSP 1 + %define TDX_AP 2 +@@ -84,19 +89,19 @@ clearPageTablesMemoryLoop: + ; + ; Top level Page Directory Pointers (1 * 512GB entry) + ; +- mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDP_ATTR ++ mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (4)], edx + + ; + ; Next level Page Directory Pointers (4 * 1GB entries => 4GB) + ; +- mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDP_ATTR ++ mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (0x1004)], edx +- mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDP_ATTR ++ mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (0x100C)], edx +- mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDP_ATTR ++ mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (0x1014)], edx +- mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDP_ATTR ++ mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (0x101C)], edx + + ; +@@ -107,7 +112,7 @@ pageTableEntriesLoop: + mov eax, ecx + dec eax + shl eax, 21 +- add eax, PAGE_2M_PDE_ATTR ++ add eax, PAGE_PDE_LARGEPAGE_ATTR + mov [ecx * 8 + PT_ADDR (0x2000 - 8)], eax + mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx + loop pageTableEntriesLoop +-- +2.41.0 + diff --git a/0024-OvmfPkg-ResetVector-add-ClearOvmfPageTables-macro.patch b/0024-OvmfPkg-ResetVector-add-ClearOvmfPageTables-macro.patch new file mode 100644 index 0000000000000000000000000000000000000000..592d96b0078c4d725d7458fc482bbf3bdade8288 --- /dev/null +++ b/0024-OvmfPkg-ResetVector-add-ClearOvmfPageTables-macro.patch @@ -0,0 +1,85 @@ +From 02b4b8d092fbd6eeb010e59612225ad63d2d8859 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:54 +0100 +Subject: [PATCH 24/34] OvmfPkg/ResetVector: add ClearOvmfPageTables macro + +commit 52e44713d23de600ac7eb12bdfa0600abd2294eb upstream + +Move code to clear the page tables to a nasm macro. +No functional change. + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-3-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 35 ++++++++++++----------- + 1 file changed, 19 insertions(+), 16 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 6fec6f2beeea..378ba2feeb4f 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -45,6 +45,24 @@ BITS 32 + %define TDX_BSP 1 + %define TDX_AP 2 + ++; ++; For OVMF, build some initial page tables at ++; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000). ++; ++; This range should match with PcdOvmfSecPageTablesSize which is ++; declared in the FDF files. ++; ++; At the end of PEI, the pages tables will be rebuilt into a ++; more permanent location by DxeIpl. ++; ++%macro ClearOvmfPageTables 0 ++ mov ecx, 6 * 0x1000 / 4 ++ xor eax, eax ++.clearPageTablesMemoryLoop: ++ mov dword[ecx * 4 + PT_ADDR (0) - 4], eax ++ loop .clearPageTablesMemoryLoop ++%endmacro ++ + ; + ; Modified: EAX, EBX, ECX, EDX + ; +@@ -69,22 +87,7 @@ SetCr3ForPageTables64: + OneTimeCall GetSevCBitMaskAbove31 + + ClearOvmfPageTables: +- ; +- ; For OVMF, build some initial page tables at +- ; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000). +- ; +- ; This range should match with PcdOvmfSecPageTablesSize which is +- ; declared in the FDF files. +- ; +- ; At the end of PEI, the pages tables will be rebuilt into a +- ; more permanent location by DxeIpl. +- ; +- +- mov ecx, 6 * 0x1000 / 4 +- xor eax, eax +-clearPageTablesMemoryLoop: +- mov dword[ecx * 4 + PT_ADDR (0) - 4], eax +- loop clearPageTablesMemoryLoop ++ ClearOvmfPageTables + + ; + ; Top level Page Directory Pointers (1 * 512GB entry) +-- +2.41.0 + diff --git a/0025-OvmfPkg-ResetVector-add-CreatePageTables4Level-macro.patch b/0025-OvmfPkg-ResetVector-add-CreatePageTables4Level-macro.patch new file mode 100644 index 0000000000000000000000000000000000000000..65d2ab3010ad9bc384da4bac3c532f88f70c1f91 --- /dev/null +++ b/0025-OvmfPkg-ResetVector-add-CreatePageTables4Level-macro.patch @@ -0,0 +1,120 @@ +From 7177e49ae02a2e297ca8410f4ca70e9260ca9486 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:55 +0100 +Subject: [PATCH 25/34] OvmfPkg/ResetVector: add CreatePageTables4Level macro + +commit 4329b5b0cd58891e1385c90a5e509c91ba0eb891 upstream + +Move code to create 4-level page tables to a nasm macro. +No functional change. + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-4-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 70 +++++++++++++---------- + 1 file changed, 39 insertions(+), 31 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 378ba2feeb4f..14cc2c33aa3d 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -63,6 +63,44 @@ BITS 32 + loop .clearPageTablesMemoryLoop + %endmacro + ++; ++; Create page tables for 4-level paging ++; ++; Argument: upper 32 bits of the page table entries ++; ++%macro CreatePageTables4Level 1 ++ ; ++ ; Top level Page Directory Pointers (1 * 512GB entry) ++ ; ++ mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (4)], %1 ++ ++ ; ++ ; Next level Page Directory Pointers (4 * 1GB entries => 4GB) ++ ; ++ mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x1004)], %1 ++ mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x100C)], %1 ++ mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x1014)], %1 ++ mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x101C)], %1 ++ ++ ; ++ ; Page Table Entries (2048 * 2MB entries => 4GB) ++ ; ++ mov ecx, 0x800 ++.pageTableEntriesLoop4Level: ++ mov eax, ecx ++ dec eax ++ shl eax, 21 ++ add eax, PAGE_PDE_LARGEPAGE_ATTR ++ mov dword[ecx * 8 + PT_ADDR (0x2000 - 8)], eax ++ mov dword[(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], %1 ++ loop .pageTableEntriesLoop4Level ++%endmacro ++ + ; + ; Modified: EAX, EBX, ECX, EDX + ; +@@ -88,37 +126,7 @@ SetCr3ForPageTables64: + + ClearOvmfPageTables: + ClearOvmfPageTables +- +- ; +- ; Top level Page Directory Pointers (1 * 512GB entry) +- ; +- mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (4)], edx +- +- ; +- ; Next level Page Directory Pointers (4 * 1GB entries => 4GB) +- ; +- mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x1004)], edx +- mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x100C)], edx +- mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x1014)], edx +- mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x101C)], edx +- +- ; +- ; Page Table Entries (2048 * 2MB entries => 4GB) +- ; +- mov ecx, 0x800 +-pageTableEntriesLoop: +- mov eax, ecx +- dec eax +- shl eax, 21 +- add eax, PAGE_PDE_LARGEPAGE_ATTR +- mov [ecx * 8 + PT_ADDR (0x2000 - 8)], eax +- mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx +- loop pageTableEntriesLoop ++ CreatePageTables4Level edx + + ; Clear the C-bit from the GHCB page if the SEV-ES is enabled. + OneTimeCall SevClearPageEncMaskForGhcbPage +-- +2.41.0 + diff --git a/0026-OvmfPkg-ResetVector-split-TDX-BSP-workflow.patch b/0026-OvmfPkg-ResetVector-split-TDX-BSP-workflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..e216fd1228b5bc8aa6e2f01b9980f2218f25fc57 --- /dev/null +++ b/0026-OvmfPkg-ResetVector-split-TDX-BSP-workflow.patch @@ -0,0 +1,92 @@ +From 5a1ddef7eb1a7bbdb1769f249c2d7224328283e1 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:56 +0100 +Subject: [PATCH 26/34] OvmfPkg/ResetVector: split TDX BSP workflow + +commit b7a97bfac52819d37310106e467623b0ed4a8f87 upstream + +Create a separate control flow for TDX BSP. + +TdxPostBuildPageTables will now only be called when running in TDX +mode, so the TDX check in that function is not needed any more. + +No functional change. + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-5-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/IntelTdx.asm | 4 ---- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 15 ++++++++++----- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm +index 06794baef81d..c6b86019dfb9 100644 +--- a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm ++++ b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm +@@ -197,11 +197,7 @@ NotTdx: + ; Set byte[TDX_WORK_AREA_PGTBL_READY] to 1 + ; + TdxPostBuildPageTables: +- cmp byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX +- jne ExitTdxPostBuildPageTables + mov byte[TDX_WORK_AREA_PGTBL_READY], 1 +- +-ExitTdxPostBuildPageTables: + OneTimeCallRet TdxPostBuildPageTables + + ; +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 14cc2c33aa3d..166e80293c89 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -112,7 +112,7 @@ SetCr3ForPageTables64: + ; is set. + OneTimeCall CheckTdxFeaturesBeforeBuildPagetables + cmp eax, TDX_BSP +- je ClearOvmfPageTables ++ je TdxBspInit + cmp eax, TDX_AP + je SetCr3 + +@@ -124,16 +124,21 @@ SetCr3ForPageTables64: + ; the page table build below. + OneTimeCall GetSevCBitMaskAbove31 + +-ClearOvmfPageTables: + ClearOvmfPageTables + CreatePageTables4Level edx + + ; Clear the C-bit from the GHCB page if the SEV-ES is enabled. + OneTimeCall SevClearPageEncMaskForGhcbPage ++ jmp SetCr3 + +- ; TDX will do some PostBuildPages task, such as setting +- ; byte[TDX_WORK_AREA_PGTBL_READY]. +- OneTimeCall TdxPostBuildPageTables ++TdxBspInit: ++ ; ++ ; TDX BSP workflow ++ ; ++ ClearOvmfPageTables ++ CreatePageTables4Level 0 ++ OneTimeCall TdxPostBuildPageTables ++ jmp SetCr3 + + SetCr3: + ; +-- +2.41.0 + diff --git a/0027-OvmfPkg-ResetVector-split-SEV-and-non-CoCo-workflows.patch b/0027-OvmfPkg-ResetVector-split-SEV-and-non-CoCo-workflows.patch new file mode 100644 index 0000000000000000000000000000000000000000..7aa883a4e23518b7d2b5486fe9d671ebe0ee5617 --- /dev/null +++ b/0027-OvmfPkg-ResetVector-split-SEV-and-non-CoCo-workflows.patch @@ -0,0 +1,109 @@ +From d5835d2d31f3d9ec6925533561c5a55b3d72e436 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:57 +0100 +Subject: [PATCH 27/34] OvmfPkg/ResetVector: split SEV and non-CoCo workflows + +commit e3bd782373d87872c359939462a66d9bc2f2a252 upstream + +Use separate control flows for SEV and non-CoCo cases. + +SevClearPageEncMaskForGhcbPage and GetSevCBitMaskAbove31 will now only +be called when running in SEV mode, so the SEV check in these functions +is not needed any more. + +No functional change. + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-6-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/AmdSev.asm | 14 +------------- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 17 ++++++++++++++--- + 2 files changed, 15 insertions(+), 16 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +index e0433cecad57..16ba5833ffcf 100644 +--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm ++++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +@@ -154,10 +154,6 @@ SevEsUnexpectedRespTerminate: + + ; If SEV-ES is enabled then initialize and make the GHCB page shared + SevClearPageEncMaskForGhcbPage: +- ; Check if SEV is enabled +- cmp byte[WORK_AREA_GUEST_TYPE], 1 +- jnz SevClearPageEncMaskForGhcbPageExit +- + ; Check if SEV-ES is enabled + mov ecx, 1 + bt [SEV_ES_WORK_AREA_STATUS_MSR], ecx +@@ -204,20 +200,12 @@ pageTableEntries4kLoop: + SevClearPageEncMaskForGhcbPageExit: + OneTimeCallRet SevClearPageEncMaskForGhcbPage + +-; Check if SEV is enabled, and get the C-bit mask above 31. ++; Get the C-bit mask above 31. + ; Modified: EDX + ; + ; The value is returned in the EDX + GetSevCBitMaskAbove31: +- xor edx, edx +- +- ; Check if SEV is enabled +- cmp byte[WORK_AREA_GUEST_TYPE], 1 +- jnz GetSevCBitMaskAbove31Exit +- + mov edx, dword[SEV_ES_WORK_AREA_ENC_MASK + 4] +- +-GetSevCBitMaskAbove31Exit: + OneTimeCallRet GetSevCBitMaskAbove31 + + %endif +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 166e80293c89..84a7b4efc019 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -118,15 +118,26 @@ SetCr3ForPageTables64: + + ; Check whether the SEV is active and populate the SevEsWorkArea + OneTimeCall CheckSevFeatures ++ cmp byte[WORK_AREA_GUEST_TYPE], 1 ++ jz SevInit + ++ ; ++ ; normal (non-CoCo) workflow ++ ; ++ ClearOvmfPageTables ++ CreatePageTables4Level 0 ++ jmp SetCr3 ++ ++SevInit: ++ ; ++ ; SEV workflow ++ ; ++ ClearOvmfPageTables + ; If SEV is enabled, the C-bit position is always above 31. + ; The mask will be saved in the EDX and applied during the + ; the page table build below. + OneTimeCall GetSevCBitMaskAbove31 +- +- ClearOvmfPageTables + CreatePageTables4Level edx +- + ; Clear the C-bit from the GHCB page if the SEV-ES is enabled. + OneTimeCall SevClearPageEncMaskForGhcbPage + jmp SetCr3 +-- +2.41.0 + diff --git a/0028-OvmfPkg-ResetVector-add-5-level-paging-support.patch b/0028-OvmfPkg-ResetVector-add-5-level-paging-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..51b4355e18cac5230caf75d2501da3ef1dcfcff2 --- /dev/null +++ b/0028-OvmfPkg-ResetVector-add-5-level-paging-support.patch @@ -0,0 +1,180 @@ +From a6bb118efee0eab992bb473daac86d8e924740cb Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:58 +0100 +Subject: [PATCH 28/34] OvmfPkg/ResetVector: add 5-level paging support + +commit 49b7faba1d6e29bd6238d6b85de22b2c3fca4d12 upstream + +Add macros to check for 5-level paging and gigabyte page support. +Enable 5-level paging for the non-confidential-computing case. + +Signed-off-by: Gerd Hoffmann +Message-Id: <20240301074402.98625-7-kraxel@redhat.com> +Reviewed-by: Laszlo Ersek +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 100 ++++++++++++++++++++++ + OvmfPkg/ResetVector/ResetVector.inf | 1 + + OvmfPkg/ResetVector/ResetVector.nasmb | 1 + + 3 files changed, 102 insertions(+) + +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 84a7b4efc019..2d7fd523e4b1 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -101,6 +101,97 @@ BITS 32 + loop .pageTableEntriesLoop4Level + %endmacro + ++; ++; Check whenever 5-level paging can be used ++; ++; Argument: jump label for 4-level paging ++; ++%macro Check5LevelPaging 1 ++ ; check for cpuid leaf 0x07 ++ mov eax, 0x00 ++ cpuid ++ cmp eax, 0x07 ++ jb %1 ++ ++ ; check for la57 (aka 5-level paging) ++ mov eax, 0x07 ++ mov ecx, 0x00 ++ cpuid ++ bt ecx, 16 ++ jnc %1 ++ ++ ; check for cpuid leaf 0x80000001 ++ mov eax, 0x80000000 ++ cpuid ++ cmp eax, 0x80000001 ++ jb %1 ++ ++ ; check for 1g pages ++ mov eax, 0x80000001 ++ cpuid ++ bt edx, 26 ++ jnc %1 ++%endmacro ++ ++; ++; Create page tables for 5-level paging with gigabyte pages ++; ++; Argument: upper 32 bits of the page table entries ++; ++; We have 6 pages available for the early page tables, ++; we use four of them: ++; PT_ADDR(0) - level 5 directory ++; PT_ADDR(0x1000) - level 4 directory ++; PT_ADDR(0x2000) - level 2 directory (0 -> 1GB) ++; PT_ADDR(0x3000) - level 3 directory ++; ++; The level 2 directory for the first gigabyte has the same ++; physical address in both 4-level and 5-level paging mode, ++; SevClearPageEncMaskForGhcbPage depends on this. ++; ++; The 1 GB -> 4 GB range is mapped using 1G pages in the ++; level 3 directory. ++; ++%macro CreatePageTables5Level 1 ++ ; level 5 ++ mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (4)], %1 ++ ++ ; level 4 ++ mov dword[PT_ADDR (0x1000)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x1004)], %1 ++ ++ ; level 3 (1x -> level 2, 3x 1GB) ++ mov dword[PT_ADDR (0x3000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR ++ mov dword[PT_ADDR (0x3004)], %1 ++ mov dword[PT_ADDR (0x3008)], (1 << 30) + PAGE_PDE_LARGEPAGE_ATTR ++ mov dword[PT_ADDR (0x300c)], %1 ++ mov dword[PT_ADDR (0x3010)], (2 << 30) + PAGE_PDE_LARGEPAGE_ATTR ++ mov dword[PT_ADDR (0x3014)], %1 ++ mov dword[PT_ADDR (0x3018)], (3 << 30) + PAGE_PDE_LARGEPAGE_ATTR ++ mov dword[PT_ADDR (0x301c)], %1 ++ ++ ; ++ ; level 2 (512 * 2MB entries => 1GB) ++ ; ++ mov ecx, 0x200 ++.pageTableEntriesLoop5Level: ++ mov eax, ecx ++ dec eax ++ shl eax, 21 ++ add eax, PAGE_PDE_LARGEPAGE_ATTR ++ mov dword[ecx * 8 + PT_ADDR (0x2000 - 8)], eax ++ mov dword[(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], %1 ++ loop .pageTableEntriesLoop5Level ++%endmacro ++ ++%macro Enable5LevelPaging 0 ++ ; set la57 bit in cr4 ++ mov eax, cr4 ++ bts eax, 12 ++ mov cr4, eax ++%endmacro ++ + ; + ; Modified: EAX, EBX, ECX, EDX + ; +@@ -125,6 +216,13 @@ SetCr3ForPageTables64: + ; normal (non-CoCo) workflow + ; + ClearOvmfPageTables ++%if PG_5_LEVEL ++ Check5LevelPaging Paging4Level ++ CreatePageTables5Level 0 ++ Enable5LevelPaging ++ jmp SetCr3 ++Paging4Level: ++%endif + CreatePageTables4Level 0 + jmp SetCr3 + +@@ -152,6 +250,8 @@ TdxBspInit: + jmp SetCr3 + + SetCr3: ++ ; ++ ; common workflow + ; + ; Set CR3 now that the paging structures are available + ; +diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf +index 5dfba883f349..8b2053819159 100644 +--- a/OvmfPkg/ResetVector/ResetVector.inf ++++ b/OvmfPkg/ResetVector/ResetVector.inf +@@ -68,3 +68,4 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize ++ gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable +diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb +index d5ed1e143773..d67bbca034be 100644 +--- a/OvmfPkg/ResetVector/ResetVector.nasmb ++++ b/OvmfPkg/ResetVector/ResetVector.nasmb +@@ -53,6 +53,7 @@ + + %define WORK_AREA_GUEST_TYPE (FixedPcdGet32 (PcdOvmfWorkAreaBase)) + %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset)) ++%define PG_5_LEVEL (FixedPcdGetBool (PcdUse5LevelPageTable)) + + %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) + %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase)) +-- +2.41.0 + diff --git a/0029-OvmfPkg-ResetVector-print-post-codes-for-4-5-level-p.patch b/0029-OvmfPkg-ResetVector-print-post-codes-for-4-5-level-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f3f8ed81b6f0cfb69be9bba8a6f9ae7b98105cd --- /dev/null +++ b/0029-OvmfPkg-ResetVector-print-post-codes-for-4-5-level-p.patch @@ -0,0 +1,56 @@ +From 54bdc4f493df51608675cfffe7eb8caa3bc8f0e3 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:43:59 +0100 +Subject: [PATCH 29/34] OvmfPkg/ResetVector: print post codes for 4/5 level + paging + +commit 318b0d714a7ef184ceb445d16f63c9687e89b10e upstream + +Signed-off-by: Gerd Hoffmann +Reviewed-by: Laszlo Ersek +Message-Id: <20240301074402.98625-8-kraxel@redhat.com> +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 2d7fd523e4b1..e15945da0476 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -69,6 +69,10 @@ BITS 32 + ; Argument: upper 32 bits of the page table entries + ; + %macro CreatePageTables4Level 1 ++ ++ ; indicate 4-level paging ++ debugShowPostCode 0x41 ++ + ; + ; Top level Page Directory Pointers (1 * 512GB entry) + ; +@@ -153,6 +157,10 @@ BITS 32 + ; level 3 directory. + ; + %macro CreatePageTables5Level 1 ++ ++ ; indicate 5-level paging ++ debugShowPostCode 0x51 ++ + ; level 5 + mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR + mov dword[PT_ADDR (4)], %1 +-- +2.41.0 + diff --git a/0030-OvmfPkg-ResetVector-wire-up-5-level-paging-for-TDX.patch b/0030-OvmfPkg-ResetVector-wire-up-5-level-paging-for-TDX.patch new file mode 100644 index 0000000000000000000000000000000000000000..8afb5d38e0d795c5d507fac963f27663e924dfea --- /dev/null +++ b/0030-OvmfPkg-ResetVector-wire-up-5-level-paging-for-TDX.patch @@ -0,0 +1,113 @@ +From fd3139ccf818d3348b1da29385c809ffd2b47f75 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 1 Mar 2024 08:44:00 +0100 +Subject: [PATCH 30/34] OvmfPkg/ResetVector: wire up 5-level paging for TDX + +commit 275d0a39c42ad73a6e4929822f56f5d8c16ede96 upstream + +BSP workflow is quite simliar to the non-coco case. + +TDX_WORK_AREA_PGTBL_READY is used to record the paging mode: + 1 == 4-level paging + 2 == 5-level paging + +APs will look at TDX_WORK_AREA_PGTBL_READY to figure whenever +they should enable 5-level paging or not. + +Signed-off-by: Gerd Hoffmann +Message-Id: <20240301074402.98625-9-kraxel@redhat.com> +Reviewed-by: Laszlo Ersek +[lersek@redhat.com: move "CheckForSev:" label into "%if PG_5_LEVEL" scope, + as discussed with Gerd] +Cc: Jiewen Yao +Cc: Oliver Steffen +Cc: Michael Roth +Cc: Erdem Aktas +Cc: Min Xu +Cc: Ard Biesheuvel +Cc: Tom Lendacky +[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list + posting into "Cc:" tags in the commit message, in order to pacify + "PatchCheck.py"] +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/IntelTdx.asm | 13 ++++++++++++- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 16 ++++++++++++++++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm +index c6b86019dfb9..7d775591a05b 100644 +--- a/OvmfPkg/ResetVector/Ia32/IntelTdx.asm ++++ b/OvmfPkg/ResetVector/Ia32/IntelTdx.asm +@@ -179,7 +179,7 @@ InitTdx: + ; + ; Modified: EAX, EDX + ; +-; 0-NonTdx, 1-TdxBsp, 2-TdxAps ++; 0-NonTdx, 1-TdxBsp, 2-TdxAps, 3-TdxAps5Level + ; + CheckTdxFeaturesBeforeBuildPagetables: + xor eax, eax +@@ -200,6 +200,17 @@ TdxPostBuildPageTables: + mov byte[TDX_WORK_AREA_PGTBL_READY], 1 + OneTimeCallRet TdxPostBuildPageTables + ++%if PG_5_LEVEL ++ ++; ++; Set byte[TDX_WORK_AREA_PGTBL_READY] to 2 ++; ++TdxPostBuildPageTables5Level: ++ mov byte[TDX_WORK_AREA_PGTBL_READY], 2 ++ OneTimeCallRet TdxPostBuildPageTables5Level ++ ++%endif ++ + ; + ; Check if TDX is enabled + ; +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index e15945da0476..474d22dbfa48 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -44,6 +44,7 @@ BITS 32 + + %define TDX_BSP 1 + %define TDX_AP 2 ++%define TDX_AP_5_LEVEL 3 + + ; + ; For OVMF, build some initial page tables at +@@ -214,6 +215,13 @@ SetCr3ForPageTables64: + je TdxBspInit + cmp eax, TDX_AP + je SetCr3 ++%if PG_5_LEVEL ++ cmp eax, TDX_AP_5_LEVEL ++ jne CheckForSev ++ Enable5LevelPaging ++ jmp SetCr3 ++CheckForSev: ++%endif + + ; Check whether the SEV is active and populate the SevEsWorkArea + OneTimeCall CheckSevFeatures +@@ -253,6 +261,14 @@ TdxBspInit: + ; TDX BSP workflow + ; + ClearOvmfPageTables ++%if PG_5_LEVEL ++ Check5LevelPaging Tdx4Level ++ CreatePageTables5Level 0 ++ OneTimeCall TdxPostBuildPageTables5Level ++ Enable5LevelPaging ++ jmp SetCr3 ++Tdx4Level: ++%endif + CreatePageTables4Level 0 + OneTimeCall TdxPostBuildPageTables + jmp SetCr3 +-- +2.41.0 + diff --git a/0031-OvmfPkg-ResetVector-Clear-SEV-encryption-bit-for-non.patch b/0031-OvmfPkg-ResetVector-Clear-SEV-encryption-bit-for-non.patch new file mode 100644 index 0000000000000000000000000000000000000000..9739af20f28ba80677d9600be306f21c55ab41de --- /dev/null +++ b/0031-OvmfPkg-ResetVector-Clear-SEV-encryption-bit-for-non.patch @@ -0,0 +1,119 @@ +From 25be0ae245087aaa7a0ca5c4ee31652f5ba544d9 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Thu, 2 May 2024 13:49:21 +0200 +Subject: [PATCH 31/34] OvmfPkg/ResetVector: Clear SEV encryption bit for + non-leaf PTEs + +commit fd290ab8628478c62c32c972fc16b86b6c3372ce upstream + +Future changes will make use of CpuPageTableLib to handle splitting +page table mappings during SEC phase. While it's not strictly required +by hardware, CpuPageTableLib relies on non-leaf PTEs never having the +encryption bit set, so go ahead change the page table setup code to +satisfy this expectation. + +Suggested-by: Tom Lendacky +Cc: Ard Biesheuvel +Cc: Gerd Hoffmann +Cc: Erdem Aktas +Cc: Jiewen Yao +Cc: Min Xu +Cc: Tom Lendacky +Signed-off-by: Michael Roth +Reviewed-by: Gerd Hoffmann +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/ResetVector/Ia32/AmdSev.asm | 5 ++++- + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 20 ++++++++++---------- + 2 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +index 16ba5833ffcf..7f942178d50f 100644 +--- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm ++++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm +@@ -162,11 +162,14 @@ SevClearPageEncMaskForGhcbPage: + ; + ; The initial GHCB will live at GHCB_BASE and needs to be un-encrypted. + ; This requires the 2MB page for this range be broken down into 512 4KB +- ; pages. All will be marked encrypted, except for the GHCB. ++ ; pages. All will be marked encrypted, except for the GHCB. Since the ++ ; original PMD entry is no longer a leaf entry, remove the encryption ++ ; bit when pointing to the PTE page. + ; + mov ecx, (GHCB_BASE >> 21) + mov eax, GHCB_PT_ADDR + PAGE_PDP_ATTR + mov [ecx * 8 + PT_ADDR (0x2000)], eax ++ mov [ecx * 8 + PT_ADDR (0x2000) + 4], strict dword 0 + + ; + ; Page Table Entries (512 * 4KB entries => 2MB) +diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +index 474d22dbfa48..d913a39d4693 100644 +--- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm ++++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm +@@ -67,7 +67,7 @@ BITS 32 + ; + ; Create page tables for 4-level paging + ; +-; Argument: upper 32 bits of the page table entries ++; Argument: upper 32 bits of the leaf page table entries + ; + %macro CreatePageTables4Level 1 + +@@ -78,19 +78,19 @@ BITS 32 + ; Top level Page Directory Pointers (1 * 512GB entry) + ; + mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (4)], %1 ++ mov dword[PT_ADDR (4)], 0 + + ; + ; Next level Page Directory Pointers (4 * 1GB entries => 4GB) + ; + mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x1004)], %1 ++ mov dword[PT_ADDR (0x1004)], 0 + mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x100C)], %1 ++ mov dword[PT_ADDR (0x100C)], 0 + mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x1014)], %1 ++ mov dword[PT_ADDR (0x1014)], 0 + mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x101C)], %1 ++ mov dword[PT_ADDR (0x101C)], 0 + + ; + ; Page Table Entries (2048 * 2MB entries => 4GB) +@@ -141,7 +141,7 @@ BITS 32 + ; + ; Create page tables for 5-level paging with gigabyte pages + ; +-; Argument: upper 32 bits of the page table entries ++; Argument: upper 32 bits of the leaf page table entries + ; + ; We have 6 pages available for the early page tables, + ; we use four of them: +@@ -164,15 +164,15 @@ BITS 32 + + ; level 5 + mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (4)], %1 ++ mov dword[PT_ADDR (4)], 0 + + ; level 4 + mov dword[PT_ADDR (0x1000)], PT_ADDR (0x3000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x1004)], %1 ++ mov dword[PT_ADDR (0x1004)], 0 + + ; level 3 (1x -> level 2, 3x 1GB) + mov dword[PT_ADDR (0x3000)], PT_ADDR (0x2000) + PAGE_PDE_DIRECTORY_ATTR +- mov dword[PT_ADDR (0x3004)], %1 ++ mov dword[PT_ADDR (0x3004)], 0 + mov dword[PT_ADDR (0x3008)], (1 << 30) + PAGE_PDE_LARGEPAGE_ATTR + mov dword[PT_ADDR (0x300c)], %1 + mov dword[PT_ADDR (0x3010)], (2 << 30) + PAGE_PDE_LARGEPAGE_ATTR +-- +2.41.0 + diff --git a/0032-OvmfPkg-Don-t-make-APIC-MMIO-accesses-with-encryptio.patch b/0032-OvmfPkg-Don-t-make-APIC-MMIO-accesses-with-encryptio.patch new file mode 100644 index 0000000000000000000000000000000000000000..416ade0fc1f87f4d03096ee8f838f5f5562e921e --- /dev/null +++ b/0032-OvmfPkg-Don-t-make-APIC-MMIO-accesses-with-encryptio.patch @@ -0,0 +1,289 @@ +From 500d3a05d9f5fa81fe5334e78052c6396123eb17 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Thu, 2 May 2024 13:49:26 +0200 +Subject: [PATCH 32/34] OvmfPkg: Don't make APIC MMIO accesses with encryption + bit set + +commit f0ed194236b1fe55199ee82c014b70119ee3f227 upstream + +For the most part, OVMF will clear the encryption bit for MMIO regions, +but there is currently one known exception during SEC when the APIC +base address is accessed via MMIO with the encryption bit set for +SEV-ES/SEV-SNP guests. In the case of SEV-SNP, this requires special +handling on the hypervisor side which may not be available in the +future[1], so make the necessary changes in the SEC-configured page +table to clear the encryption bit for 4K region containing the APIC +base address. + +[Backport Chnages] + +1) OvmfPkg/AmdSev/AmdSevX64.fdf - In the the upstream patch, the address +range from 0x011000 to 0x001000 is used for the token "PcdOvmfSecApicPageTableBase" +in the "PcdOvmfSecPeiTempRamBase". However, in the Anolis OVMF, this address +range is already reserved for the token "PcdCsvDefaultSecureCallBase". +So, using the next avaialble address range from 0x014000 to 0x001000 for +"PcdOvmfSecApicPageTableBase". + +2) OvmfPkg/OvmfPkgX64.fdf - In the the upstream patch, the address range +from 0x010000 to 0x001000 is used for "PcdOvmfSecApicPageTableBase" in +the "PcdOvmfSecPeiTempRamBase". However, in the Anolis OVMF, this address +range is already reserved for the token "PcdCsvDefaultSecureCallBase". +So, using the next avaialble address range from 0x013000 to 0x001000 for +"PcdOvmfSecApicPageTableBase". + +3) OvmfPkg/OvmfPkg.dec - In the the upstream patch, token "PcdOvmfSecApicPageTableBase" +uses the PCD entry "0x72". However, in the Anolis OVMF, PCD entry "0x72" is +already used by "PcdOvmfCsvCpuidBase". So, using next available PCD entry +"0x76" for "PcdOvmfSecApicPageTableBase". + +[1] https://lore.kernel.org/lkml/20240208002420.34mvemnzrwwsaesw@amd.com/#t + +Suggested-by: Tom Lendacky +Cc: Ard Biesheuvel +Cc: Gerd Hoffmann +Cc: Erdem Aktas +Cc: Jiewen Yao +Cc: Min Xu +Cc: Tom Lendacky +Cc: Jianyong Wu +Cc: Anatol Belski +Signed-off-by: Michael Roth +Reviewed-by: Gerd Hoffmann +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/AmdSev/AmdSevX64.fdf | 5 ++- + OvmfPkg/Bhyve/BhyveX64.dsc | 1 + + OvmfPkg/CloudHv/CloudHvX64.fdf | 5 ++- + OvmfPkg/Microvm/MicrovmX64.fdf | 3 ++ + OvmfPkg/OvmfPkg.dec | 5 +++ + OvmfPkg/OvmfPkgX64.fdf | 5 ++- + OvmfPkg/Sec/AmdSev.c | 58 ++++++++++++++++++++++++++++++++++ + OvmfPkg/Sec/AmdSev.h | 14 ++++++++ + OvmfPkg/Sec/SecMain.c | 1 + + OvmfPkg/Sec/SecMain.inf | 3 ++ + 10 files changed, 97 insertions(+), 3 deletions(-) + +diff --git a/OvmfPkg/AmdSev/AmdSevX64.fdf b/OvmfPkg/AmdSev/AmdSevX64.fdf +index 86b9bc194598..135b3c7c2f02 100644 +--- a/OvmfPkg/AmdSev/AmdSevX64.fdf ++++ b/OvmfPkg/AmdSev/AmdSevX64.fdf +@@ -83,7 +83,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm + 0x013000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize + +-0x014000|0x00C000 ++0x014000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize ++ ++0x015000|0x00B000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc +index 9689a2f14efa..a10f59808a00 100644 +--- a/OvmfPkg/Bhyve/BhyveX64.dsc ++++ b/OvmfPkg/Bhyve/BhyveX64.dsc +@@ -174,6 +174,7 @@ + PeiHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/PeiHardwareInfoLib.inf + DxeHardwareInfoLib|OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf ++ CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf +diff --git a/OvmfPkg/CloudHv/CloudHvX64.fdf b/OvmfPkg/CloudHv/CloudHvX64.fdf +index eae3ada1913c..3e6688b1037d 100644 +--- a/OvmfPkg/CloudHv/CloudHvX64.fdf ++++ b/OvmfPkg/CloudHv/CloudHvX64.fdf +@@ -76,7 +76,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCp + 0x00F000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr|gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize + +-0x010000|0x010000 ++0x010000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize ++ ++0x011000|0x00F000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/Microvm/MicrovmX64.fdf b/OvmfPkg/Microvm/MicrovmX64.fdf +index c877b3f088f9..0e98543b0831 100644 +--- a/OvmfPkg/Microvm/MicrovmX64.fdf ++++ b/OvmfPkg/Microvm/MicrovmX64.fdf +@@ -62,6 +62,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm + 0x00C000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + ++0x00D000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize ++ + 0x010000|0x010000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + +diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec +index 374cab99ba10..ff85cd2b2f58 100644 +--- a/OvmfPkg/OvmfPkg.dec ++++ b/OvmfPkg/OvmfPkg.dec +@@ -283,6 +283,11 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase|0|UINT32|0x44 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize|0|UINT32|0x45 + ++ ## Specify the extra page table needed to mark the APIC MMIO range as unencrypted. ++ # The value should be a multiple of 4KB for each. ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|0x0|UINT32|0x76 ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize|0x0|UINT32|0x77 ++ + ## The base address and size of the SEV Launch Secret Area provisioned + # after remote attestation. If this is set in the .fdf, the platform + # is responsible for protecting the area from DXE phase overwrites. +diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf +index 9f12926c8fb0..1bb5bf629b4d 100644 +--- a/OvmfPkg/OvmfPkgX64.fdf ++++ b/OvmfPkg/OvmfPkgX64.fdf +@@ -103,7 +103,10 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCsvCpuidBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm + 0x012000|0x001000 + gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusBase|gUefiOvmfPkgTokenSpaceGuid.PcdMemEncrpytStatusSize + +-0x013000|0x00D000 ++0x013000|0x001000 ++gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize ++ ++0x014000|0x00C000 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + 0x020000|0x0E0000 +diff --git a/OvmfPkg/Sec/AmdSev.c b/OvmfPkg/Sec/AmdSev.c +index 520b1251321b..89fba2fd18ca 100644 +--- a/OvmfPkg/Sec/AmdSev.c ++++ b/OvmfPkg/Sec/AmdSev.c +@@ -8,7 +8,10 @@ + **/ + + #include ++#include ++#include + #include ++#include + #include + #include + #include +@@ -301,3 +304,58 @@ SecValidateSystemRam ( + MemEncryptSevSnpPreValidateSystemRam (Start, EFI_SIZE_TO_PAGES ((UINTN)(End - Start))); + } + } ++ ++/** ++ Map known MMIO regions unencrypted if SEV-ES is active. ++ ++ During early booting, page table entries default to having the encryption bit ++ set for SEV-ES/SEV-SNP guests. In cases where there is MMIO to an address, the ++ encryption bit should be cleared. Clear it here for any known MMIO accesses ++ during SEC, which is currently just the APIC base address. ++ ++**/ ++VOID ++SecMapApicBaseUnencrypted ( ++ VOID ++ ) ++{ ++ PHYSICAL_ADDRESS Cr3; ++ UINT64 ApicAddress; ++ VOID *Buffer; ++ UINTN BufferSize; ++ IA32_MAP_ATTRIBUTE MapAttribute; ++ IA32_MAP_ATTRIBUTE MapMask; ++ RETURN_STATUS Status; ++ ++ if (!SevEsIsEnabled ()) { ++ return; ++ } ++ ++ ApicAddress = (UINT64)GetLocalApicBaseAddress (); ++ Buffer = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecApicPageTableBase); ++ Cr3 = AsmReadCr3 (); ++ ++ MapAttribute.Uint64 = ApicAddress; ++ MapAttribute.Bits.Present = 1; ++ MapAttribute.Bits.ReadWrite = 1; ++ MapMask.Uint64 = MAX_UINT64; ++ BufferSize = SIZE_4KB; ++ ++ Status = PageTableMap ( ++ (UINTN *)&Cr3, ++ Paging4Level, ++ Buffer, ++ &BufferSize, ++ ApicAddress, ++ SIZE_4KB, ++ &MapAttribute, ++ &MapMask, ++ NULL ++ ); ++ if (RETURN_ERROR (Status)) { ++ DEBUG ((DEBUG_ERROR, "Failed to map APIC MMIO region as unencrypted: %d\n", Status)); ++ ASSERT (FALSE); ++ } ++ ++ CpuFlushTlb (); ++} +diff --git a/OvmfPkg/Sec/AmdSev.h b/OvmfPkg/Sec/AmdSev.h +index f75877096e11..c5ab0d5a0b5a 100644 +--- a/OvmfPkg/Sec/AmdSev.h ++++ b/OvmfPkg/Sec/AmdSev.h +@@ -91,4 +91,18 @@ SevSnpIsEnabled ( + VOID + ); + ++/** ++ Map MMIO regions unencrypted if SEV-ES is active. ++ ++ During early booting, page table entries default to having the encryption bit ++ set for SEV-ES/SEV-SNP guests. In cases where there is MMIO to an address, the ++ encryption bit should be cleared. Clear it here for any known MMIO accesses ++ during SEC, which is currently just the APIC base address. ++ ++**/ ++VOID ++SecMapApicBaseUnencrypted ( ++ VOID ++ ); ++ + #endif +diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c +index 31da5d0ace51..f3ea0e42dc44 100644 +--- a/OvmfPkg/Sec/SecMain.c ++++ b/OvmfPkg/Sec/SecMain.c +@@ -939,6 +939,7 @@ SecCoreStartupWithStack ( + // interrupts before initializing the Debug Agent and the debug timer is + // enabled. + // ++ SecMapApicBaseUnencrypted (); + InitializeApicTimer (0, MAX_UINT32, TRUE, 5); + DisableApicTimerInterrupt (); + +diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf +index 3c47a664a95d..d90ebce531b6 100644 +--- a/OvmfPkg/Sec/SecMain.inf ++++ b/OvmfPkg/Sec/SecMain.inf +@@ -55,6 +55,7 @@ + MemEncryptSevLib + CpuExceptionHandlerLib + CcProbeLib ++ CpuPageTableLib + + [Ppis] + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED +@@ -83,6 +84,8 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase + gUefiOvmfPkgTokenSpaceGuid.PcdTdxAcceptPageSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase ++ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableSize + + [FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire +-- +2.41.0 + diff --git a/0033-OvmfPkg-CcExitLib-Drop-special-handling-for-Encrypte.patch b/0033-OvmfPkg-CcExitLib-Drop-special-handling-for-Encrypte.patch new file mode 100644 index 0000000000000000000000000000000000000000..7131cd20da375bdc4fe4ab4883b2c269cff0f32f --- /dev/null +++ b/0033-OvmfPkg-CcExitLib-Drop-special-handling-for-Encrypte.patch @@ -0,0 +1,63 @@ +From 80939e63d458dcc4039b8299f2e68a378c75fdd1 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Thu, 2 May 2024 13:49:29 +0200 +Subject: [PATCH 33/34] OvmfPkg/CcExitLib: Drop special handling for Encrypted + MMIO to APIC + +commit fecf55a66a1cf908c2f906bedb79fe2e8362d50f upstream + +The current #VC handler guards against MMIO to addresses that are mapped +with the encryption bit set, but has an special exception for MMIO +accesses to the APIC base address so allow for early access during SEC. + +Now that the SEC page table has the encryption bit cleared for the APIC +base address range, there is no longer any need for this special +handling. Go ahead and remove it. + +Cc: Ard Biesheuvel +Cc: Gerd Hoffmann +Cc: Erdem Aktas +Cc: Jiewen Yao +Cc: Min Xu +Cc: Tom Lendacky +Signed-off-by: Michael Roth +Reviewed-by: Gerd Hoffmann +Signed-off-by: Hemanth Selam +Signed-off-by: mohanasv +--- + OvmfPkg/Library/CcExitLib/CcExitVcHandler.c | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c +index 5c9a90856e85..cb8aee2e937e 100644 +--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c ++++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c +@@ -97,7 +97,7 @@ UnsupportedExit ( + Validate that the MMIO memory access is not to encrypted memory. + + Examine the pagetable entry for the memory specified. MMIO should not be +- performed against encrypted memory. MMIO to the APIC page is always allowed. ++ performed against encrypted memory. + + @param[in] Ghcb Pointer to the Guest-Hypervisor Communication Block + @param[in] MemoryAddress Memory address to validate +@@ -117,16 +117,6 @@ ValidateMmioMemory ( + { + MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE State; + GHCB_EVENT_INJECTION GpEvent; +- UINTN Address; +- +- // +- // Allow APIC accesses (which will have the encryption bit set during +- // SEC and PEI phases). +- // +- Address = MemoryAddress & ~(SIZE_4KB - 1); +- if (Address == GetLocalApicBaseAddress ()) { +- return 0; +- } + + State = MemEncryptSevGetAddressRangeState ( + 0, +-- +2.41.0 + diff --git a/edk2.spec b/edk2.spec index 381c5464099c0c0e5a517e216e7c4ce0a96b6d9b..8ace527c82d1687beea4626c05c95065bb60f6bb 100644 --- a/edk2.spec +++ b/edk2.spec @@ -1,4 +1,4 @@ -%define anolis_release 5 +%define anolis_release 6 %undefine _auto_set_build_flags ExclusiveArch: x86_64 aarch64 loongarch64 @@ -89,6 +89,19 @@ Patch0021: 0021-OvmfPkg-IoMmuDxe-Implement-SetAttribute-of-CsvIoMmu.patch # 漏洞 8-9 的补丁文件现在通过 https://bugzilla.tianocore.org/show_bug.cgi?id=4541 和 https://bugzilla.tianocore.org/show_bug.cgi?id=4542 提供。这些修补程序已集成到 2024 年 5 月的 EDK2 版本 (edk2-stable202405) 中。 Patch0022: 0022-Bugfix-for-CVE-2023-45236-CVE-2023-45237.patch +# Support for AMD SEV-SNP +Patch0023: 0023-OvmfPkg-ResetVector-improve-page-table-flag-names.patch +Patch0024: 0024-OvmfPkg-ResetVector-add-ClearOvmfPageTables-macro.patch +Patch0025: 0025-OvmfPkg-ResetVector-add-CreatePageTables4Level-macro.patch +Patch0026: 0026-OvmfPkg-ResetVector-split-TDX-BSP-workflow.patch +Patch0027: 0027-OvmfPkg-ResetVector-split-SEV-and-non-CoCo-workflows.patch +Patch0028: 0028-OvmfPkg-ResetVector-add-5-level-paging-support.patch +Patch0029: 0029-OvmfPkg-ResetVector-print-post-codes-for-4-5-level-p.patch +Patch0030: 0030-OvmfPkg-ResetVector-wire-up-5-level-paging-for-TDX.patch +Patch0031: 0031-OvmfPkg-ResetVector-Clear-SEV-encryption-bit-for-non.patch +Patch0032: 0032-OvmfPkg-Don-t-make-APIC-MMIO-accesses-with-encryptio.patch +Patch0033: 0033-OvmfPkg-CcExitLib-Drop-special-handling-for-Encrypte.patch + BuildRequires: python3-devel BuildRequires: libuuid-devel %ifnarch loongarch64 @@ -487,6 +500,9 @@ install -m 0644 \ %changelog +* Fri Jan 24 2025 mohanasv - 202402-6 +- Support for AMD SEV-SNP + * Fri Aug 02 2024 lidongyue - 202402-5 - fix CVE-2023-45236 - fix CVE-2023-45237