OvmfPkg/ResetVector: add the macro to invoke MSR protocol based VMGEXIT

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The upcoming SEV-SNP support will need to make a few additional MSR
protocol based VMGEXIT's. Add a macro that wraps the common setup and
response validation logic in one place to keep the code readable.

While at it, define SEV_STATUS_MSR that will be used to get the SEV STATUS
MSR instead of open coding it.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Acked-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
This commit is contained in:
Brijesh Singh 2021-07-28 02:10:23 +08:00 committed by mergify[bot]
parent b461d67639
commit 7f05102f65
1 changed files with 48 additions and 25 deletions

View File

@ -35,6 +35,44 @@ BITS 32
%define CPUID_INSN_LEN 2
%define SEV_GHCB_MSR 0xc0010130
%define SEV_STATUS_MSR 0xc0010131
; Macro is used to issue the MSR protocol based VMGEXIT. The caller is
; responsible to populate values in the EDX:EAX registers. After the vmmcall
; returns, it verifies that the response code matches with the expected
; code. If it does not match then terminate the guest. The result of request
; is returned in the EDX:EAX.
;
; args 1:Request code, 2: Response code
%macro VmgExit 2
;
; Add request code:
; GHCB_MSR[11:0] = Request code
or eax, %1
mov ecx, SEV_GHCB_MSR
wrmsr
; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
; mode, so work around this by temporarily switching to 64-bit mode.
;
BITS 64
rep vmmcall
BITS 32
mov ecx, SEV_GHCB_MSR
rdmsr
;
; Verify the reponse code, if it does not match then request to terminate
; GHCB_MSR[11:0] = Response code
mov ecx, eax
and ecx, 0xfff
cmp ecx, %2
jne SevEsUnexpectedRespTerminate
%endmacro
; Check if Secure Encrypted Virtualization (SEV) features are enabled.
;
; Register usage is tight in this routine, so multiple calls for the
@ -84,7 +122,7 @@ CheckSevFeatures:
; Check if SEV memory encryption is enabled
; MSR_0xC0010131 - Bit 0 (SEV enabled)
mov ecx, 0xc0010131
mov ecx, SEV_STATUS_MSR
rdmsr
bt eax, 0
jnc NoSev
@ -99,7 +137,7 @@ CheckSevFeatures:
; Check if SEV-ES is enabled
; MSR_0xC0010131 - Bit 1 (SEV-ES enabled)
mov ecx, 0xc0010131
mov ecx, SEV_STATUS_MSR
rdmsr
bt eax, 1
jnc GetSevEncBit
@ -196,10 +234,10 @@ SevEsIdtNotCpuid:
mov eax, 1
jmp SevEsIdtTerminate
SevEsIdtNoCpuidResponse:
SevEsUnexpectedRespTerminate:
;
; Use VMGEXIT to request termination.
; 2 - GHCB_CPUID_RESPONSE not received
; 2 - Unexpected Response is received
;
mov eax, 2
@ -215,7 +253,7 @@ SevEsIdtTerminate:
shl eax, 16
or eax, 0x1100
xor edx, edx
mov ecx, 0xc0010130
mov ecx, SEV_GHCB_MSR
wrmsr
;
; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
@ -275,7 +313,7 @@ SevEsIdtVmmComm:
mov [esp + VC_CPUID_REQUEST_REGISTER], eax
; Save current GHCB MSR value
mov ecx, 0xc0010130
mov ecx, SEV_GHCB_MSR
rdmsr
mov [esp + VC_GHCB_MSR_EAX], eax
mov [esp + VC_GHCB_MSR_EDX], edx
@ -292,31 +330,16 @@ NextReg:
jge VmmDone
shl eax, GHCB_CPUID_REGISTER_SHIFT
or eax, GHCB_CPUID_REQUEST
mov edx, [esp + VC_CPUID_FUNCTION]
mov ecx, 0xc0010130
wrmsr
VmgExit GHCB_CPUID_REQUEST, GHCB_CPUID_RESPONSE
;
; Issue VMGEXIT - NASM doesn't support the vmmcall instruction in 32-bit
; mode, so work around this by temporarily switching to 64-bit mode.
;
BITS 64
rep vmmcall
BITS 32
;
; Read GHCB MSR
; Response GHCB MSR
; GHCB_MSR[63:32] = CPUID register value
; GHCB_MSR[31:30] = CPUID register
; GHCB_MSR[11:0] = CPUID response protocol
;
mov ecx, 0xc0010130
rdmsr
mov ecx, eax
and ecx, 0xfff
cmp ecx, GHCB_CPUID_RESPONSE
jne SevEsIdtNoCpuidResponse
; Save returned value
shr eax, GHCB_CPUID_REGISTER_SHIFT
@ -334,7 +357,7 @@ VmmDone:
;
mov eax, [esp + VC_GHCB_MSR_EAX]
mov edx, [esp + VC_GHCB_MSR_EDX]
mov ecx, 0xc0010130
mov ecx, SEV_GHCB_MSR
wrmsr
mov eax, [esp + VC_CPUID_RESULT_EAX]