[edk2-devel] [RFC PATCH 01/19] OvmfPkg: Reserve the Secrets and Cpuid page for the SEV-SNP guest

Lendacky, Thomas thomas.lendacky at amd.com
Thu Apr 8 13:31:03 UTC 2021


On 4/8/21 1:24 AM, Xu, Min M wrote:
> On Wednesday, April 7, 2021 11:03 PM, Laszlo wrote:
>> On 04/07/21 02:44, James Bottomley wrote:
>>> On Wed, 2021-04-07 at 00:21 +0000, Xu, Min M wrote:
>>>> Hi, Laszlo
>>>>
>>>> For Intel TDX supported guest, all processors start in 32-bit
>>>> protected mode, while for Non-Td guest, it starts in 16-bit real
>>>> mode. To make the ResetVector work on both Td-guest and Non-Td guest,
>>>> ResetVector are updated as below:
>>>> ------------------------------------------------------------------
>>>>   ALIGN   16
>>>>   resetVector:
>>>>   ;
>>>>   ; Reset Vector
>>>>   ;
>>>>   ; This is where the processor will begin execution
>>>>   ;
>>>>       nop
>>>>       nop
>>>>       smsw    ax
>>>>       test    al, 1
>>>>       jnz     EarlyBspPmEntry
>>>>       jmp     EarlyBspInitReal16
>>>
>>> Well, then use the rel8 jump like the compiler would in this situation:
>>>
>>>       smsw    ax
>>>       test    al, 1
>>>       jz      1f
>>>       jmp     EarlyBspPmEntry
>>> 1:
>>>       jmp     EarlyBspInitReal16
>>>
>>> So now both entries can be 32k away.
>>
>> The problem is that we need NASM to generate such *shared* entry code that
>> behaves correctly when executed in either 16-bit or 32-bit mode.
>>
>> The rel8 near jumps ("short jumps") are like that -- for example, the
>> "74 cb" opcode decodes to the same "JZ rel8" in both modes.
>>
>> But the rel16 ("non-short") near jumps turn into rel32 near jumps when
>> decoded in 32-bit mode. For example, "E9 cw" decodes to "JMP rel16" in 16-bit
>> mode, but it gets parsed as "E9 cd" (= "JMP rel32") in 32-bit mode.
>>
>> So the idea is to add more BITS directives, for covering the non-short near
>> jumps themselves:
> 
> Yes this is the root cause. TDX requires the startup mode to be 32-bit
> protected mode while the legacy VM startup mode is 16-bit real mode.
> Add more BITS directives can work round this. I have tried it and it works.
> 
> So my initial solution is to use *jmp rel8* because it works in both 16-bit
> and 32-bit mode. But *jmp rel8* depends on the distance which should
> be less than 128 bytes. If more metadata is added in the ResetVector.asm
> then we have to use the BITS solution. 

To me, it sounds like the BITS solution should be the approach you use
from the start.

Thanks,
Tom

>  
>>
>>> ; instructions up to and including the rel8 JZ decode identically ;
>>> between BITS 16 and BITS 32 BITS 16
>>>       smsw    ax
>>>       test    al, 1
>>>       jz     Real
>>>
>>> ; the unconditional near jumps are mode-specific BITS 32
>>>       jmp     near EarlyBspPmEntry
>>> BITS 16
>>> Real:
>>>       jmp     near EarlyBspInitReal16
>>>
>>> ; --------------------
>>>
>>> BITS 16
>>> EarlyBspInitReal16:
>>>       nop
>>>
>>> BITS 32
>>> EarlyBspPmEntry:
>>>       nop
>>
>> $ nasm -f bin jz.nasmb
>>
>> Decoded (executed) in 16-bit mode:
>>
>> $ ndisasm -b 16 -k 7,5 -k 0x10,1 jz
>> 00000000  0F01E0            smsw ax
>> 00000003  A801              test al,0x1
>> 00000005  7405              jz 0xc         ; taken
>> 00000007  skipping 0x5 bytes
>> 0000000C  E90000            jmp word 0xf
>> 0000000F  90                nop
>> 00000010  skipping 0x1 bytes
>>
>> Decoded (executed) in 32-bit mode:
>>
>> $ ndisasm -b 32 -k 0xc,4 jz
>> 00000000  0F01E0            smsw eax
>> 00000003  A801              test al,0x1
>> 00000005  7405              jz 0xc         ; not taken
>> 00000007  E904000000        jmp dword 0x10
>> 0000000C  skipping 0x4 bytes
>> 00000010  90                nop
>>
>>
>> With the garbage *not* hidden:
>>
>> $ ndisasm -b 16 -s 0xc jz
>>
>> 00000000  0F01E0            smsw ax
>> 00000003  A801              test al,0x1
>> 00000005  7405              jz 0xc          ; taken
>> 00000007  E90400            jmp word 0xe    ; garbage
>> 0000000A  0000              add [bx+si],al  ; garbage
>> 0000000C  E90000            jmp word 0xf
>> 0000000F  90                nop
>> 00000010  90                nop             ; garbage
>>
>> $ ndisasm -b 32 -s 0x10 jz
>>
>> 00000000  0F01E0            smsw eax
>> 00000003  A801              test al,0x1
>> 00000005  7405              jz 0xc          ; not taken
>> 00000007  E904000000        jmp dword 0x10
>> 0000000C  E9                db 0xe9         ; garbage
>> 0000000D  0000              add [eax],al    ; garbage
>> 0000000F  90                nop             ; garbage
>> 00000010  90                nop
>>
>> Thanks
>> Laszlo
>>
>>
>>
>> 
>>
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#73850): https://edk2.groups.io/g/devel/message/73850
Mute This Topic: https://groups.io/mt/81584577/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list