[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [edk2-devel] [PATCH v5 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH



Hi Anthony,

On 08/13/19 13:30, Anthony PERARD wrote:
> This patch allows the ResetVector to be run indenpendently from build
> time addresses.
> 
> The goal of the patch is to avoid having to create RAM just below 4G
> when creating a Xen PVH guest while being compatible with the way
> hvmloader currently load OVMF, just below 4G.
> 
> Only the new PVH entry point will do the calculation.
> 
> The ResetVector will figure out its current running address by creating
> a temporary stack, make a call and calculate the difference between the
> build time address and the address at run time.
> 
> This patch copies and make the necessary modification to some other asm
> files:
> - copy of UefiCpuPkg/.../Flat32ToFlat64.asm:
>   Allow Transition32FlatTo64Flat to be run from anywhere in memory
> - copy of UefiCpuPkg/../SearchForBfvBase.asm:
>   Add a extra parameter to indicate where to start the search for the
>   boot firmware volume.
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
> Acked-by: Laszlo Ersek <lersek@xxxxxxxxxx>
> ---
> 
> Notes:
>     v3:
>     - rebased, SPDX
>     - fix commit message
> 
>  .../XenResetVector/Ia16/Real16ToFlat32.asm    |  3 +
>  .../XenResetVector/Ia32/Flat32ToFlat64.asm    | 68 +++++++++++++++
>  .../XenResetVector/Ia32/SearchForBfvBase.asm  | 87 +++++++++++++++++++
>  OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm    | 43 +++++++--
>  4 files changed, 194 insertions(+), 7 deletions(-)
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> 
> diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm 
> b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> index 5c329bfaea..36ea74f7fe 100644
> --- a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> +++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> @@ -54,6 +54,9 @@ jumpTo32BitAndLandHere:
>      mov     gs, ax
>      mov     ss, ax
>  
> +    ; parameter for Flat32SearchForBfvBase
> +    xor     eax, eax ; Start searching from top of 4GB for BfvBase
> +
>      OneTimeCallRet TransitionFromReal16To32BitFlat
>  
>  ALIGN   2
> diff --git a/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm 
> b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> new file mode 100644
> index 0000000000..661a8e7028
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> @@ -0,0 +1,68 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Transition from 32 bit flat protected mode into 64 bit flat protected mode
> +;
> +; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS    32
> +
> +;
> +; Modified:  EAX, EBX, ECX, EDX, ESP
> +;
> +Transition32FlatTo64Flat:
> +
> +    OneTimeCall SetCr3ForPageTables64
> +
> +    mov     eax, cr4
> +    bts     eax, 5                      ; enable PAE
> +    mov     cr4, eax
> +
> +    mov     ecx, 0xc0000080
> +    rdmsr
> +    bts     eax, 8                      ; set LME
> +    wrmsr
> +
> +    mov     eax, cr0
> +    bts     eax, 31                     ; set PG
> +    mov     cr0, eax                    ; enable paging
> +
> +    ;
> +    ; backup ESP
> +    ;
> +    mov     ebx, esp
> +
> +    ;
> +    ; recalculate delta
> +    ;
> +    mov     esp, PVH_SPACE(16)
> +    call    .delta
> +.delta:
> +    pop     edx
> +    sub     edx, ADDR_OF(.delta)
> +
> +    ;
> +    ; push return addr and seg to the stack, then return far
> +    ;
> +    push    dword LINEAR_CODE64_SEL
> +    mov     eax, ADDR_OF(jumpTo64BitAndLandHere)
> +    add     eax, edx                             ; add delta
> +    push    eax
> +    retf
> +
> +BITS    64
> +jumpTo64BitAndLandHere:
> +
> +    ;
> +    ; restore ESP
> +    ;
> +    mov     esp, ebx
> +
> +    debugShowPostCode POSTCODE_64BIT_MODE
> +
> +    OneTimeCallRet Transition32FlatTo64Flat
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm 
> b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> new file mode 100644
> index 0000000000..190389c46f
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> @@ -0,0 +1,87 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Search for the Boot Firmware Volume (BFV) base address
> +;
> +; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
> +; Copyright (c) 2019, Citrix Systems, Inc.
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +;#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
> +;  { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 
> 0xd3 } }
> +%define FFS_GUID_DWORD0 0x8c8ce578
> +%define FFS_GUID_DWORD1 0x4f1c8a3d
> +%define FFS_GUID_DWORD2 0x61893599
> +%define FFS_GUID_DWORD3 0xd32dc385
> +
> +BITS    32
> +
> +;
> +; Modified:  EAX, EBX, ECX
> +; Preserved: EDI, ESP
> +;
> +; @param[in]   EAX  Start search from here
> +; @param[out]  EBP  Address of Boot Firmware Volume (BFV)
> +;
> +Flat32SearchForBfvBase:
> +
> +    mov     ecx, eax
> +searchingForBfvHeaderLoop:
> +    ;
> +    ; We check for a firmware volume at every 4KB address in the 16MB
> +    ; just below where we started, ECX.
> +    ;
> +    sub     eax, 0x1000
> +    mov     ebx, ecx
> +    sub     ebx, eax
> +    cmp     ebx, 0x01000000
> +    ; if ECX-EAX > 16MB; jump notfound
> +    ja      searchedForBfvHeaderButNotFound
> +
> +    ;
> +    ; Check FFS GUID
> +    ;
> +    cmp     dword [eax + 0x10], FFS_GUID_DWORD0
> +    jne     searchingForBfvHeaderLoop
> +    cmp     dword [eax + 0x14], FFS_GUID_DWORD1
> +    jne     searchingForBfvHeaderLoop
> +    cmp     dword [eax + 0x18], FFS_GUID_DWORD2
> +    jne     searchingForBfvHeaderLoop
> +    cmp     dword [eax + 0x1c], FFS_GUID_DWORD3
> +    jne     searchingForBfvHeaderLoop
> +
> +    ;
> +    ; Check FV Length
> +    ;
> +    cmp     dword [eax + 0x24], 0
> +    jne     searchingForBfvHeaderLoop
> +    mov     ebx, eax
> +    add     ebx, dword [eax + 0x20]
> +    cmp     ebx, ecx
> +    jnz     searchingForBfvHeaderLoop
> +
> +    jmp     searchedForBfvHeaderAndItWasFound
> +
> +searchedForBfvHeaderButNotFound:
> +    ;
> +    ; Hang if the SEC entry point was not found
> +    ;
> +    debugShowPostCode POSTCODE_BFV_NOT_FOUND
> +
> +    ;
> +    ; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
> +    ; for debugging purposes.
> +    ;
> +    mov     eax, 0xBFBFBFBF
> +    mov     ebp, eax
> +    jmp     $
> +
> +searchedForBfvHeaderAndItWasFound:
> +    mov     ebp, eax
> +
> +    debugShowPostCode POSTCODE_BFV_FOUND
> +
> +    OneTimeCallRet Flat32SearchForBfvBase
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm 
> b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> index f42df3dba2..2df0f12e18 100644
> --- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -16,25 +16,42 @@ xenPVHMain:
>      ;
>      mov     di, 'BP'
>  
> -    ;
> -    ; ESP will be used as initial value of the EAX register
> -    ; in Main.asm
> -    ;
> -    xor     esp, esp
> -
>      ;
>      ; Store "Start of day" struct pointer for later use
>      ;
>      mov     dword[PVH_SPACE (0)], ebx
>      mov     dword[PVH_SPACE (4)], 'XPVH'
>  
> +    ;
> +    ; calculate delta between build-addr and run position
> +    ;
> +    mov     esp, PVH_SPACE(16)          ; create a temporary stack
> +    call    .delta
> +.delta:
> +    pop     edx                         ; get addr of .delta
> +    sub     edx, ADDR_OF(.delta)        ; calculate delta
> +
> +    ;
> +    ; Find address of GDT and gdtr and fix the later
> +    ;
>      mov     ebx, ADDR_OF(gdtr)
> +    add     ebx, edx                    ; add delta gdtr
> +    mov     eax, ADDR_OF(GDT_BASE)
> +    add     eax, edx                    ; add delta to GDT_BASE
> +    mov     dword[ebx + 2], eax         ; fix GDT_BASE addr in gdtr
>      lgdt    [ebx]
>  
>      mov     eax, SEC_DEFAULT_CR0
>      mov     cr0, eax
>  
> -    jmp     LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg)
> +    ;
> +    ; push return addr to the stack, then return far
> +    ;
> +    push    dword LINEAR_CODE_SEL          ; segment to select
> +    mov     eax, ADDR_OF(.jmpToNewCodeSeg) ; return addr
> +    add     eax, edx                       ; add delta to return addr
> +    push    eax
> +    retf
>  .jmpToNewCodeSeg:
>  
>      mov     eax, SEC_DEFAULT_CR4
> @@ -47,6 +64,18 @@ xenPVHMain:
>      mov     gs, ax
>      mov     ss, ax
>  
> +    ;
> +    ; ESP will be used as initial value of the EAX register
> +    ; in Main.asm
> +    ;
> +    xor     esp, esp
> +
> +    ;
> +    ; parameter for Flat32SearchForBfvBase
> +    ;
> +    mov     eax, ADDR_OF(fourGigabytes)

I've just noticed that the line above triggers the following NASM warning:

Ia32/XenPVHMain.asm:76: warning: dword data exceeds bounds

The warning does not stop the build.

The macro comes from "UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc":

%define ADDR_OF(x) (0x100000000 - fourGigabytes + x)

So I believe we effectively store 0 to EAX. If that's the intent (I
think it *could* be), please submit a cleanup in the next development
cycle -- we could store a 0 explicitly and add a comment, just to shut
up the warning. If, on the other hand, this is a bug, please submit a
fix soon (for the upcoming release).

Thanks
Laszlo


> +    add     eax, edx ; add delta
> +
>      ;
>      ; Jump to the main routine of the pre-SEC code
>      ; skiping the 16-bit part of the routine and
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.