OvmfPkg/ResetVector: add 5-level paging support
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 <kraxel@redhat.com> Message-Id: <20240301074402.98625-7-kraxel@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Oliver Steffen <osteffen@redhat.com> Cc: Michael Roth <michael.roth@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Tom Lendacky <thomas.lendacky@amd.com> [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"]
This commit is contained in:
		
				
					committed by
					
						
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							e3bd782373
						
					
				
				
					commit
					49b7faba1d
				
			@@ -101,6 +101,97 @@ BITS    32
 | 
				
			|||||||
    loop    .pageTableEntriesLoop4Level
 | 
					    loop    .pageTableEntriesLoop4Level
 | 
				
			||||||
%endmacro
 | 
					%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
 | 
					; Modified:  EAX, EBX, ECX, EDX
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
@@ -125,6 +216,13 @@ SetCr3ForPageTables64:
 | 
				
			|||||||
    ; normal (non-CoCo) workflow
 | 
					    ; normal (non-CoCo) workflow
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
    ClearOvmfPageTables
 | 
					    ClearOvmfPageTables
 | 
				
			||||||
 | 
					%if PG_5_LEVEL
 | 
				
			||||||
 | 
					    Check5LevelPaging Paging4Level
 | 
				
			||||||
 | 
					    CreatePageTables5Level 0
 | 
				
			||||||
 | 
					    Enable5LevelPaging
 | 
				
			||||||
 | 
					    jmp SetCr3
 | 
				
			||||||
 | 
					Paging4Level:
 | 
				
			||||||
 | 
					%endif
 | 
				
			||||||
    CreatePageTables4Level 0
 | 
					    CreatePageTables4Level 0
 | 
				
			||||||
    jmp SetCr3
 | 
					    jmp SetCr3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,6 +250,8 @@ TdxBspInit:
 | 
				
			|||||||
    jmp SetCr3
 | 
					    jmp SetCr3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SetCr3:
 | 
					SetCr3:
 | 
				
			||||||
 | 
					    ;
 | 
				
			||||||
 | 
					    ; common workflow
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
    ; Set CR3 now that the paging structures are available
 | 
					    ; Set CR3 now that the paging structures are available
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,3 +64,4 @@
 | 
				
			|||||||
  gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
 | 
					  gUefiOvmfPkgTokenSpaceGuid.PcdQemuHashTableSize
 | 
				
			||||||
  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
 | 
					  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
 | 
				
			||||||
  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
 | 
					  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
 | 
				
			||||||
 | 
					  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
%define WORK_AREA_GUEST_TYPE          (FixedPcdGet32 (PcdOvmfWorkAreaBase))
 | 
					%define WORK_AREA_GUEST_TYPE          (FixedPcdGet32 (PcdOvmfWorkAreaBase))
 | 
				
			||||||
%define PT_ADDR(Offset)               (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
 | 
					%define PT_ADDR(Offset)               (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Offset))
 | 
				
			||||||
 | 
					%define PG_5_LEVEL                    (FixedPcdGetBool (PcdUse5LevelPageTable))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%define GHCB_PT_ADDR                  (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
 | 
					%define GHCB_PT_ADDR                  (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase))
 | 
				
			||||||
%define GHCB_BASE                     (FixedPcdGet32 (PcdOvmfSecGhcbBase))
 | 
					%define GHCB_BASE                     (FixedPcdGet32 (PcdOvmfSecGhcbBase))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user