From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: redhat.com, ip: 209.132.183.28, mailfrom: lersek@redhat.com) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by groups.io with SMTP; Fri, 05 Jul 2019 07:55:09 -0700 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3029C356CA; Fri, 5 Jul 2019 14:54:54 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-244.ams2.redhat.com [10.36.116.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id 851039D90A; Fri, 5 Jul 2019 14:54:51 +0000 (UTC) Subject: Re: [PATCH v3 08/35] OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH To: Anthony PERARD , devel@edk2.groups.io Cc: xen-devel@lists.xenproject.org, Ard Biesheuvel , Jordan Justen , Julien Grall References: <20190704144233.27968-1-anthony.perard@citrix.com> <20190704144233.27968-9-anthony.perard@citrix.com> From: "Laszlo Ersek" Message-ID: <246252e2-08fa-72c9-3184-dd5617f2f83f@redhat.com> Date: Fri, 5 Jul 2019 16:54:50 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20190704144233.27968-9-anthony.perard@citrix.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 05 Jul 2019 14:54:59 +0000 (UTC) Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 07/04/19 16:42, 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 > Acked-by: Laszlo Ersek > --- > > Notes: > v3: > - rebased, SPDX > - fix commit message There are more changes in v3 than that. First, some comment updates -- OK. Second (and actually this goes back to another unlisted v3 change, namely on patch#6 first): - in v2: - in patch #6, you store EAX to ESP at the top of xenPVHMain - in patch #8, you stash EAX in EBP at the top of xenPVHMain, then store EBP to ESP at the end of xenPVHMain - in v3: - in patch #6, you zero ESP at the top of xenPVHMain - in patch #8 (this patch), you move the zeroing to the end of xenPVHMain To the extent that I care :) , this looks OK to me -- and so my A-b stands --, but this change could be relevant for xen-devel reviewers, and should be pointed out. Thanks Laszlo > .../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.
> +; 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.
> +; 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) > + add eax, edx ; add delta > + > ; > ; Jump to the main routine of the pre-SEC code > ; skiping the 16-bit part of the routine and >