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