From 68f30b0567f8a9dc54c492287db3ee1093111894 Mon Sep 17 00:00:00 2001 From: Liu Zixing Date: Fri, 25 Feb 2022 15:55:44 +0800 Subject: [PATCH 04/11] OvmfPkg/ResetVector: Support CSV in ResetVector phase - A GUID is written along with the first secure call page address, by which the Secure Processor can locate the first secure call page address. - Check whether the VM is a CSV VM when setting the first page table - CSV VM will update first shared GHCB page address to Secure Processor by secure call page Signed-off-by: Xin Jiang --- OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm | 15 +++ OvmfPkg/ResetVector/Ia32/AmdSev.asm | 9 ++ OvmfPkg/ResetVector/Ia32/CsvInit.asm | 107 +++++++++++++++++++ OvmfPkg/ResetVector/ResetVector.inf | 2 + OvmfPkg/ResetVector/ResetVector.nasmb | 4 + 5 files changed, 137 insertions(+) create mode 100644 OvmfPkg/ResetVector/Ia32/CsvInit.asm diff --git a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm index 12f2ced..c86b049 100644 --- a/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm +++ b/OvmfPkg/ResetVector/Ia16/ResetVectorVtf0.asm @@ -48,6 +48,21 @@ TIMES (15 - ((guidedStructureEnd - guidedStructureStart + 15) % 16)) DB 0 guidedStructureStart: %ifdef ARCH_X64 +; +; CSV secure call table +; +; Provide secure call pages when boot up for CSV guest. +; +; GUID : 9a5d926f-2fa5-ceba-ab21-6b275d5556a5 +; +csvSecureCallBase: + DD CSV_DEFAULT_SECURE_CALL_SIZE + DD CSV_DEFAULT_SECURE_CALL_BASE + DW csvSecureCallEnd - csvSecureCallBase + DB 0x6F, 0x92, 0x5D, 0x9A, 0xA5, 0x2F, 0xBA, 0xCE + DB 0xAB, 0x21, 0x6B, 0x27, 0x5D, 0x55, 0x56, 0xA5 +csvSecureCallEnd: + ; ; TDX Metadata offset block ; diff --git a/OvmfPkg/ResetVector/Ia32/AmdSev.asm b/OvmfPkg/ResetVector/Ia32/AmdSev.asm index 3abc830..8f6de37 100644 --- a/OvmfPkg/ResetVector/Ia32/AmdSev.asm +++ b/OvmfPkg/ResetVector/Ia32/AmdSev.asm @@ -192,6 +192,15 @@ pageTableEntries4kLoop: mov ecx, (GHCB_BASE & 0x1F_FFFF) >> 12 mov [ecx * 8 + GHCB_PT_ADDR + 4], strict dword 0 + OneTimeCall CheckCsvFeature + test eax, eax + jz SevClearPageEncMaskForGhcbPageExit + + OneTimeCall CsvInit + mov eax, 1 + test ecx, ecx + jz SevEsUnexpectedRespTerminate + SevClearPageEncMaskForGhcbPageExit: OneTimeCallRet SevClearPageEncMaskForGhcbPage diff --git a/OvmfPkg/ResetVector/Ia32/CsvInit.asm b/OvmfPkg/ResetVector/Ia32/CsvInit.asm new file mode 100644 index 0000000..0744a35 --- /dev/null +++ b/OvmfPkg/ResetVector/Ia32/CsvInit.asm @@ -0,0 +1,107 @@ +;------------------------------------------------------------------------------ +; @file +; Provide the functions to check whether CSV is enabled. +; +; Copyright (c) 2022, HYGON. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +BITS 32 + +; If Secure Command returns ok then ECX will be non-zero. +; If Secure Command returns error then ECX will be zero. +CsvInit: + mov esp, SEV_ES_VC_TOP_OF_STACK + push esi + push edi + + ; copy SECURE_CALL_GUID to CSV_DEFAULT_SECURE_CALL_BASE + 4096 + cld + mov esi, ADDR_OF(SECURE_CALL_GUID) + mov edi, CSV_DEFAULT_SECURE_CALL_BASE + add edi, 4096 + mov ecx, 4 + rep movsd + + ; secure call begin + mov esi, CSV_DEFAULT_SECURE_CALL_BASE + ; write secure cmd to page B + ; 16 bytes of page A/B is GUID, just ignore + mov [esi + 4096 + 16], DWORD 2 ; dec command + mov [esi + 4096 + 20], DWORD 1 ; 1 entry + ; 8 bytes is unused + mov [esi + 4096 + 32], DWORD GHCB_BASE; lower address + mov [esi + 4096 + 36], DWORD 0 ; upper address + mov [esi + 4096 + 40], DWORD 4096 ; lower 32 bit of page size + mov [esi + 4096 + 44], DWORD 0 ; upper 32 bit of page size + mfence + ; read from page A + mov ecx, [esi + 16] + ; check if the response comes + cmp ecx, 2 + jne SecureCommandDone + ; no secure command response, clean ecx + xor ecx, ecx + ; secure call end + +SecureCommandDone: + pop edi + pop esi + mov esp, 0 + + OneTimeCallRet CsvInit + +; Check if CSV feature is enabled. +; +; Modified: EAX, EBX, ECX, EDX +; +; If CSV is enabled then EAX will be non-zero. +; If CSV is disabled then EAX will be zero. +; +CheckCsvFeature: + mov esp, SEV_ES_VC_TOP_OF_STACK + mov eax, ADDR_OF(Idtr) + lidt [cs:eax] + + ; Check if vendor Hygon CPUID_SIGNATURE(0x0) + ; CPUID raises a #VC exception if running as an SEV-ES guest + mov eax, 0 + cpuid + + cmp ebx, 0x6f677948 + jne NoCsv + cmp ecx, 0x656e6975 + jne NoCsv + cmp edx, 0x6e65476e + jne NoCsv + + ; Check if CSV is enabled + ; MSR_0xC0010131 - Bit 30 (CSV enabled) + mov ecx, 0xc0010131 + rdmsr + and eax, 0x40000000 + jmp CsvExit + +NoCsv: + xor eax, eax + +CsvExit: + ; + ; Clear exception handlers and stack + ; + push eax + mov eax, ADDR_OF(IdtrClear) + lidt [cs:eax] + pop eax + mov esp, 0 + + OneTimeCallRet CheckCsvFeature + +SECURE_CALL_GUID: +; low 0xceba2fa59a5d926f +; high 0xa556555d276b21ab + dd 0x9a5d926f + dd 0xceba2fa5 + dd 0x276b21ab + dd 0xa556555d diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/ResetVector.inf index a4154ca..e4adedb 100644 --- a/OvmfPkg/ResetVector/ResetVector.inf +++ b/OvmfPkg/ResetVector/ResetVector.inf @@ -35,6 +35,8 @@ [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdSevEsWorkAreaBase + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallBase + gUefiOvmfPkgTokenSpaceGuid.PcdCsvDefaultSecureCallSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/ResetVector.nasmb index 94fbb0a..d156a51 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -123,11 +123,15 @@ %define TDX_WORK_AREA_PGTBL_READY (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 4) %define TDX_WORK_AREA_GPAW (FixedPcdGet32 (PcdOvmfWorkAreaBase) + 8) + %define CSV_DEFAULT_SECURE_CALL_BASE FixedPcdGet32 (PcdCsvDefaultSecureCallBase) + %define CSV_DEFAULT_SECURE_CALL_SIZE FixedPcdGet32 (PcdCsvDefaultSecureCallSize) + %include "X64/IntelTdxMetadata.asm" %include "Ia32/Flat32ToFlat64.asm" %include "Ia32/PageTables64.asm" %include "Ia32/IntelTdx.asm" %include "X64/OvmfSevMetadata.asm" + %include "Ia32/CsvInit.asm" %endif %include "Ia32/AmdSev.asm" -- 2.25.1