or rax, rdx\r
mov rdi, rax ; RDI now holds the original GHCB GPA\r
\r
+ ;\r
+ ; For SEV-SNP, the recommended handling for getting the x2APIC ID\r
+ ; would be to use the SNP CPUID table to fetch CPUID.00H:EAX and\r
+ ; CPUID:0BH:EBX[15:0] instead of the GHCB MSR protocol vmgexits\r
+ ; below.\r
+ ;\r
+ ; To avoid the unecessary ugliness to accomplish that here, the BSP\r
+ ; has performed these checks in advance (where #VC handler handles\r
+ ; the CPUID table lookups automatically) and cached them in a flag\r
+ ; so those checks can be skipped here.\r
+ ;\r
+ mov eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (SevSnpIsEnabled)]\r
+ cmp al, 1\r
+ jne CheckExtTopoAvail\r
+\r
+ ;\r
+ ; Even with SEV-SNP, the actual x2APIC ID in CPUID.0BH:EDX\r
+ ; fetched from the hypervisor the same way SEV-ES does it.\r
+ ;\r
+ mov eax, [esi + MP_CPU_EXCHANGE_INFO_FIELD (ExtTopoAvail)]\r
+ cmp al, 1\r
+ je GetApicIdSevEs\r
+ ; The 8-bit APIC ID fallback is also the same as with SEV-ES\r
+ jmp NoX2ApicSevEs\r
+\r
+CheckExtTopoAvail:\r
mov rdx, 0 ; CPUID function 0\r
mov rax, 0 ; RAX register requested\r
or rax, 4\r
test edx, 0ffffh\r
jz NoX2ApicSevEs ; CPUID.0BH:EBX[15:0] is zero\r
\r
+GetApicIdSevEs:\r
mov rdx, 0bh ; CPUID function 0x0b\r
mov rax, 0c0000000h ; RDX register requested\r
or rax, 4\r