From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1ZQGmy-0003VU-L6 for mharc-grub-devel@gnu.org; Fri, 14 Aug 2015 11:21:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34108) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZQGmq-0003T2-FY for grub-devel@gnu.org; Fri, 14 Aug 2015 11:20:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZQGmk-0001Df-Ii for grub-devel@gnu.org; Fri, 14 Aug 2015 11:20:52 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:18197) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZQGmk-0001DR-DX for grub-devel@gnu.org; Fri, 14 Aug 2015 11:20:46 -0400 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t7EFKZW3020001 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 14 Aug 2015 15:20:35 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t7EFKYA5002196 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 14 Aug 2015 15:20:35 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t7EFKXkW004271; Fri, 14 Aug 2015 15:20:34 GMT Received: from l.oracle.com (/10.137.176.158) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 14 Aug 2015 08:20:33 -0700 Received: by l.oracle.com (Postfix, from userid 1000) id B91AF6A065C; Fri, 14 Aug 2015 11:20:31 -0400 (EDT) Date: Fri, 14 Aug 2015 11:20:31 -0400 From: Konrad Rzeszutek Wilk To: Daniel Kiper Subject: Re: [Xen-devel] [PATCH v2 22/23] x86: make Xen early boot code relocatable Message-ID: <20150814152031.GA30421@l.oracle.com> References: <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com> <1437402558-7313-23-git-send-email-daniel.kiper@oracle.com> <20150811164806.GB32231@l.oracle.com> <20150814115205.GA8034@olila.local.net-space.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20150814115205.GA8034@olila.local.net-space.pl> User-Agent: Mutt/1.5.23 (2014-03-12) Content-Transfer-Encoding: quoted-printable X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 141.146.126.69 Cc: jgross@suse.com, grub-devel@gnu.org, keir@xen.org, ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com, andrew.cooper3@citrix.com, gang.wei@intel.com, roy.franz@linaro.org, ning.sun@intel.com, david.vrabel@citrix.com, jbeulich@suse.com, phcoder@gmail.com, xen-devel@lists.xenproject.org, wei.liu2@citrix.com, richard.l.maliszewski@intel.com, qiaowei.ren@intel.com, fu.wei@linaro.org X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Aug 2015 15:20:59 -0000 > > > trampoline_bios_setup: > > > + mov %ebp,%esi > > > + > > > + /* Initialise GDT and basic data segments. */ > > > + add %ebp,sym_offset(gdt_boot_descr_addr)(%esi) > > > + lgdt sym_offset(gdt_boot_descr)(%esi) > > > + > > > + mov $BOOT_DS,%ecx > > > + mov %ecx,%ds > > > + mov %ecx,%es > > > + mov %ecx,%fs > > > + mov %ecx,%gs > > > + mov %ecx,%ss > > > + > > > > > > The non-EFI boot path is now: > > > > start > > \- __start > > \- multiboot2_proto > > | jmp trampoline_bios_setup > > | > > \-and if not MB2: jmp trampoline_bios_setup. > > > > > > In here you tweak the GDT and reload the %ds - but during > > this call chain we do touch the %ds - via: > > > > __start+27>: testb $0x1,(%rbx) > > __start+30>: cmovne 0x4(%rbx),%edx > > > > which is OK (as MB1 says that the %ds has to cover up to 4GB). > > But I wonder why the __start code had the segments reloaded so early? > > Was the bootloader not setting the proper segments? >=20 > This is very good question. I was asking myself about that thing at > least once. Sadly, I cannot find real explanation. >=20 > > Let me double-check what SYSLINUX's mboot.c32 does. Perhaps > > it had done something odd in the past. >=20 > Good idea! Nope, the mboot.c32 COMBOOT images are booted with: %ds,%es,%fs,%gs : 32-bit data segment with zero base and 4GB limit =20 So that is OK. Perhaps this code used to be shared with trampoline startup and got copied over. Anyhow not worried about it. .. snip.. > > > + /* Initialize %fs and later use it to access Xen data if p= ossible. */ > > > + mov $BOOT_FS,%edx > > > + mov %edx,%fs > > > + > > > > We just modified the GDT. Should we reload it (lgdt?)? >=20 > I do not think it is needed. >=20 > Intel 64 and IA-32 Architectures Software Developer=E2=80=99s Manual, > Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z says: >=20 > LGDT ... Loads the values in the source operand into the global > descriptor table register (GDTR)... >=20 > ...and ... >=20 > MOV ... If the destination operand is a segment register (DS, ES, > FS, GS, or SS), the source operand must be a valid segment selector. > In protected mode, moving a segment selector into a segment register > automatically causes the segment descriptor information associated > with that segment selector to be loaded into the hidden (shadow) part > of the segment register. While loading this information, the segment .. snip.. > "shadow register.") When a segment selector is loaded into the visible > part of a segment register, the processor also loads the hidden part > of the segment register with the base address, segment limit, and acces= s > control information from the segment descriptor pointed to by the segme= nt > selector. The information cached in the segment register (visible and Excellent! > hidden) allows the processor to translate addresses without taking > extra bus cycles to read the base address and limit from the segment > descriptor. In systems in which multiple processors have access to the > same descriptor tables, it is the responsibility of software to reload > the segment registers when the descriptor tables are modified (side not= e: > GDTR reload is not required! probably the same applies to UP systems > and if CPU update own active GDT). If this is not done, an old segment > descriptor cached in a segment register might be used after its > memory-resident version has been modified. >=20 > AIUI, only GDT address and limit are loaded into GDTR when lgdt is exec= uted. > Segment descriptor is loaded directly from memory into segment register > (hiden part) only when relevant load instruction is used (e.g. mov %edx= ,%fs). Yeey!