Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Daniel Kiper
On Fri, Mar 27, 2015 at 03:06:43PM +, Jan Beulich wrote:
> >>> On 27.03.15 at 15:57,  wrote:
> > On Fri, Mar 27, 2015 at 02:34:19PM +, Jan Beulich wrote:
> >> >>> On 27.03.15 at 15:26,  wrote:
> >> > On Fri, Mar 27, 2015 at 01:36:32PM +, Jan Beulich wrote:
> >> >> >>> On 27.03.15 at 14:06,  wrote:
> >> >> > On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
> >> >> >> >>> On 30.01.15 at 18:54,  wrote:
> >> >> >> > +/* Skip Multiboot2 information fixed part */
> >> >> >> > +lea MB2_fixed_sizeof(%ebx),%ecx
> >> >> >>
> >> >> >> Let's please not add more assumptions than necessary about stuff
> >> >> >> being below 4G.
> >> >> >
> >> >> > I am not sure what do you mean by that.
> >> >>
> >> >> See the 32-bit register used for addressing here (and in many more
> >> >> places)?
> >> >
> >> > This is what I expected but I was confused because you were referring 
> >> > only
> >> > here to this problem. Anyway, is it possible to do this in different way?
> >> > Should we care if image is always loaded at 0x10 right now? Even with
> >> > Xen early boot code being relocatable loader could not load image higher
> >> > than 0x - 14 MiB.
> >>
> >> I don't understand what you're alluding to. Just use 64-bit registers
> >> for memory accesses and LEAs, and be done. This will result in smaller
> >> code as a benefit.
> >
> > Well... How can I do that here if processor is in 32-bit mode? Maybe,
> > we could that things after switching to 64-bit mode. However, I think
> > this requires separate patch to do these changes.
>
> No, if the processor is in 32-bit mode, then using 32-bit registers is
> fine of course. But I'm pretty certain I spotted at least some cases
> where it looked like you used 32-bit registers in 64-bit mode.

OK, I will double check. If I find something then I will fix it.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Jan Beulich
>>> On 27.03.15 at 15:57,  wrote:
> On Fri, Mar 27, 2015 at 02:34:19PM +, Jan Beulich wrote:
>> >>> On 27.03.15 at 15:26,  wrote:
>> > On Fri, Mar 27, 2015 at 01:36:32PM +, Jan Beulich wrote:
>> >> >>> On 27.03.15 at 14:06,  wrote:
>> >> > On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
>> >> >> >>> On 30.01.15 at 18:54,  wrote:
>> >> >> > +/* Skip Multiboot2 information fixed part */
>> >> >> > +lea MB2_fixed_sizeof(%ebx),%ecx
>> >> >>
>> >> >> Let's please not add more assumptions than necessary about stuff
>> >> >> being below 4G.
>> >> >
>> >> > I am not sure what do you mean by that.
>> >>
>> >> See the 32-bit register used for addressing here (and in many more
>> >> places)?
>> >
>> > This is what I expected but I was confused because you were referring only
>> > here to this problem. Anyway, is it possible to do this in different way?
>> > Should we care if image is always loaded at 0x10 right now? Even with
>> > Xen early boot code being relocatable loader could not load image higher
>> > than 0x - 14 MiB.
>>
>> I don't understand what you're alluding to. Just use 64-bit registers
>> for memory accesses and LEAs, and be done. This will result in smaller
>> code as a benefit.
> 
> Well... How can I do that here if processor is in 32-bit mode? Maybe,
> we could that things after switching to 64-bit mode. However, I think
> this requires separate patch to do these changes.

No, if the processor is in 32-bit mode, then using 32-bit registers is
fine of course. But I'm pretty certain I spotted at least some cases
where it looked like you used 32-bit registers in 64-bit mode.

Jan


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Daniel Kiper
On Fri, Mar 27, 2015 at 02:34:19PM +, Jan Beulich wrote:
> >>> On 27.03.15 at 15:26,  wrote:
> > On Fri, Mar 27, 2015 at 01:36:32PM +, Jan Beulich wrote:
> >> >>> On 27.03.15 at 14:06,  wrote:
> >> > On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
> >> >> >>> On 30.01.15 at 18:54,  wrote:
> >> >> > +/* Skip Multiboot2 information fixed part */
> >> >> > +lea MB2_fixed_sizeof(%ebx),%ecx
> >> >>
> >> >> Let's please not add more assumptions than necessary about stuff
> >> >> being below 4G.
> >> >
> >> > I am not sure what do you mean by that.
> >>
> >> See the 32-bit register used for addressing here (and in many more
> >> places)?
> >
> > This is what I expected but I was confused because you were referring only
> > here to this problem. Anyway, is it possible to do this in different way?
> > Should we care if image is always loaded at 0x10 right now? Even with
> > Xen early boot code being relocatable loader could not load image higher
> > than 0x - 14 MiB.
>
> I don't understand what you're alluding to. Just use 64-bit registers
> for memory accesses and LEAs, and be done. This will result in smaller
> code as a benefit.

Well... How can I do that here if processor is in 32-bit mode? Maybe,
we could that things after switching to 64-bit mode. However, I think
this requires separate patch to do these changes.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Jan Beulich
>>> On 27.03.15 at 15:26,  wrote:
> On Fri, Mar 27, 2015 at 01:36:32PM +, Jan Beulich wrote:
>> >>> On 27.03.15 at 14:06,  wrote:
>> > On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
>> >> >>> On 30.01.15 at 18:54,  wrote:
>> >> > +/* Skip Multiboot2 information fixed part */
>> >> > +lea MB2_fixed_sizeof(%ebx),%ecx
>> >>
>> >> Let's please not add more assumptions than necessary about stuff
>> >> being below 4G.
>> >
>> > I am not sure what do you mean by that.
>>
>> See the 32-bit register used for addressing here (and in many more
>> places)?
> 
> This is what I expected but I was confused because you were referring only
> here to this problem. Anyway, is it possible to do this in different way?
> Should we care if image is always loaded at 0x10 right now? Even with
> Xen early boot code being relocatable loader could not load image higher
> than 0x - 14 MiB.

I don't understand what you're alluding to. Just use 64-bit registers
for memory accesses and LEAs, and be done. This will result in smaller
code as a benefit.

Jan


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Daniel Kiper
On Fri, Mar 27, 2015 at 01:36:32PM +, Jan Beulich wrote:
> >>> On 27.03.15 at 14:06,  wrote:
> > On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
> >> >>> On 30.01.15 at 18:54,  wrote:
> >> > +/* Skip Multiboot2 information fixed part */
> >> > +lea MB2_fixed_sizeof(%ebx),%ecx
> >>
> >> Let's please not add more assumptions than necessary about stuff
> >> being below 4G.
> >
> > I am not sure what do you mean by that.
>
> See the 32-bit register used for addressing here (and in many more
> places)?

This is what I expected but I was confused because you were referring only
here to this problem. Anyway, is it possible to do this in different way?
Should we care if image is always loaded at 0x10 right now? Even with
Xen early boot code being relocatable loader could not load image higher
than 0x - 14 MiB.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Jan Beulich
>>> On 27.03.15 at 14:06,  wrote:
> On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
>> >>> On 30.01.15 at 18:54,  wrote:
>> > +/* Skip Multiboot2 information fixed part */
>> > +lea MB2_fixed_sizeof(%ebx),%ecx
>>
>> Let's please not add more assumptions than necessary about stuff
>> being below 4G.
> 
> I am not sure what do you mean by that.

See the 32-bit register used for addressing here (and in many more
places)?

Jan


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-27 Thread Daniel Kiper
On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
> >>> On 30.01.15 at 18:54,  wrote:
> > @@ -94,6 +111,17 @@ ENTRY(start)
> >  gdt_boot_descr:
> >  .word   6*8-1
> >  .long   sym_phys(trampoline_gdt)
> > +.long   0 /* Needed for 64-bit lgdt */
> > +
> > +cs32_switch_addr:
> > +.long   sym_phys(cs32_switch)
> > +.long   BOOT_CS32
> > +
> > +efi_st:
> > +.quad   0
> > +
> > +efi_ih:
> > +.quad   0
> >
> >  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
> >  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> > @@ -124,6 +152,133 @@ print_err:
> >  .Lhalt: hlt
> >  jmp .Lhalt
> >
> > +.code64
> > +
> > +__efi64_start:
> > +cld
> > +
> > +/* Bootloaders may set multiboot[12].mem_lower to a nonzero value 
> > */
> > +xor %edx,%edx
> > +
> > +/* Check for Multiboot2 bootloader */
> > +cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +je  efi_multiboot2_proto
> > +
> > +jmp not_multiboot
> > +
> > +efi_multiboot2_proto:
>
> jne not_multiboot (and efi_multiboot2_proto dropped altogether)
>
> > +/* Skip Multiboot2 information fixed part */
> > +lea MB2_fixed_sizeof(%ebx),%ecx
>
> Let's please not add more assumptions than necessary about stuff
> being below 4G.

I am not sure what do you mean by that.

> > +
> > +0:
> > +/* Get mem_lower from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> > +jne 1f
> > +
> > +mov MB2_mem_lower(%ecx),%edx
> > +jmp 4f
> > +
> > +1:
> > +/* Get EFI SystemTable address from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_EFI64,(%ecx)
> > +jne 2f
> > +
> > +lea MB2_efi64_st(%ecx),%esi
> > +lea efi_st(%rip),%edi
> > +movsq
>
> A simple pair of mov-s please, assuming all of this really needs to be
> done in assembly in the first place. Also please use .L labels
> in this assembly coded switch statement to ease reading.
>
> > +
> > +/* Do not go into real mode on EFI platform */
> > +movb$1,skip_realmode(%rip)
> > +
> > +jmp 4f
> > +
> > +2:
> > +/* Get EFI ImageHandle address from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_EFI64_IH,(%ecx)
> > +jne 3f
> > +
> > +lea MB2_efi64_ih(%ecx),%esi
> > +lea efi_ih(%rip),%edi
> > +movsq
> > +jmp 4f
> > +
> > +3:
> > +/* Is it the end of Multiboot2 information? */
> > +cmpl$MULTIBOOT2_TAG_TYPE_END,(%ecx)
> > +je  run_bs
> > +
> > +4:
>
> Please switch the order so that 2 can fall through into 4 (and you
> then won't need the run_bs label, which otherwise should also
> becom .Lrun_bs).
>
> > +/* Go to next Multiboot2 information tag */
> > +add MB2_tag_size(%ecx),%ecx
> > +add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> > +and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> > +jmp 0b
> > +
> > +run_bs:
> > +push%rax
> > +push%rdx
> > +
> > +/* Initialize BSS (no nasty surprises!) */
> > +lea __bss_start(%rip),%rdi
> > +lea _end(%rip),%rcx
> > +sub %rdi,%rcx
> > +xor %rax,%rax
> > +rep stosb
>
> rep stosb
>
> > +
> > +mov efi_ih(%rip),%rdi   /* EFI ImageHandle */
> > +mov efi_st(%rip),%rsi   /* EFI SystemTable */
> > +callefi_multiboot2
>
> With efi_multiboot2 being a C function it really looks like much of the
> above doesn't need to be done in assembly.

Potentially make sense. I will try to do that.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-17 Thread Daniel Kiper
On Tue, Mar 17, 2015 at 10:32:01AM +, Jan Beulich wrote:
> >>> On 30.01.15 at 18:54,  wrote:
> > @@ -94,6 +111,17 @@ ENTRY(start)
> >  gdt_boot_descr:
> >  .word   6*8-1
> >  .long   sym_phys(trampoline_gdt)
> > +.long   0 /* Needed for 64-bit lgdt */
> > +
> > +cs32_switch_addr:
> > +.long   sym_phys(cs32_switch)
> > +.long   BOOT_CS32
> > +
> > +efi_st:
> > +.quad   0
> > +
> > +efi_ih:
> > +.quad   0
> >
> >  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
> >  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> > @@ -124,6 +152,133 @@ print_err:
> >  .Lhalt: hlt
> >  jmp .Lhalt
> >
> > +.code64
> > +
> > +__efi64_start:
> > +cld
> > +
> > +/* Bootloaders may set multiboot[12].mem_lower to a nonzero value 
> > */
> > +xor %edx,%edx
> > +
> > +/* Check for Multiboot2 bootloader */
> > +cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +je  efi_multiboot2_proto
> > +
> > +jmp not_multiboot
> > +
> > +efi_multiboot2_proto:
>
> jne not_multiboot (and efi_multiboot2_proto dropped altogether)

[...]

Jan, thanks for your comments. Now I am working on relocatable early Xen code.
I hope that I will finish that this week and start tests on this crazy
UEFI platforms. Then I get back to this patch series and replay for your
and other guys comments.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-03-17 Thread Jan Beulich
>>> On 30.01.15 at 18:54,  wrote:
> @@ -94,6 +111,17 @@ ENTRY(start)
>  gdt_boot_descr:
>  .word   6*8-1
>  .long   sym_phys(trampoline_gdt)
> +.long   0 /* Needed for 64-bit lgdt */
> +
> +cs32_switch_addr:
> +.long   sym_phys(cs32_switch)
> +.long   BOOT_CS32
> +
> +efi_st:
> +.quad   0
> +
> +efi_ih:
> +.quad   0
>  
>  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
>  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> @@ -124,6 +152,133 @@ print_err:
>  .Lhalt: hlt
>  jmp .Lhalt
>  
> +.code64
> +
> +__efi64_start:
> +cld
> +
> +/* Bootloaders may set multiboot[12].mem_lower to a nonzero value */
> +xor %edx,%edx
> +
> +/* Check for Multiboot2 bootloader */
> +cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +je  efi_multiboot2_proto
> +
> +jmp not_multiboot
> +
> +efi_multiboot2_proto:

jne not_multiboot (and efi_multiboot2_proto dropped altogether)

> +/* Skip Multiboot2 information fixed part */
> +lea MB2_fixed_sizeof(%ebx),%ecx

Let's please not add more assumptions than necessary about stuff
being below 4G.

> +
> +0:
> +/* Get mem_lower from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> +jne 1f
> +
> +mov MB2_mem_lower(%ecx),%edx
> +jmp 4f
> +
> +1:
> +/* Get EFI SystemTable address from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_EFI64,(%ecx)
> +jne 2f
> +
> +lea MB2_efi64_st(%ecx),%esi
> +lea efi_st(%rip),%edi
> +movsq

A simple pair of mov-s please, assuming all of this really needs to be
done in assembly in the first place. Also please use .L labels
in this assembly coded switch statement to ease reading.

> +
> +/* Do not go into real mode on EFI platform */
> +movb$1,skip_realmode(%rip)
> +
> +jmp 4f
> +
> +2:
> +/* Get EFI ImageHandle address from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_EFI64_IH,(%ecx)
> +jne 3f
> +
> +lea MB2_efi64_ih(%ecx),%esi
> +lea efi_ih(%rip),%edi
> +movsq
> +jmp 4f
> +
> +3:
> +/* Is it the end of Multiboot2 information? */
> +cmpl$MULTIBOOT2_TAG_TYPE_END,(%ecx)
> +je  run_bs
> +
> +4:

Please switch the order so that 2 can fall through into 4 (and you
then won't need the run_bs label, which otherwise should also
becom .Lrun_bs).

> +/* Go to next Multiboot2 information tag */
> +add MB2_tag_size(%ecx),%ecx
> +add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +jmp 0b
> +
> +run_bs:
> +push%rax
> +push%rdx
> +
> +/* Initialize BSS (no nasty surprises!) */
> +lea __bss_start(%rip),%rdi
> +lea _end(%rip),%rcx
> +sub %rdi,%rcx
> +xor %rax,%rax
> +rep stosb

rep stosb

> +
> +mov efi_ih(%rip),%rdi   /* EFI ImageHandle */
> +mov efi_st(%rip),%rsi   /* EFI SystemTable */
> +callefi_multiboot2

With efi_multiboot2 being a C function it really looks like much of the
above doesn't need to be done in assembly.

> +
> +pop %rcx
> +pop %rax
> +
> +shl $10-4,%rcx  /* Convert multiboot2.mem_lower to 
> bytes/16 */
> +
> +cli
> +
> +/* Initialise GDT */
> +lgdtgdt_boot_descr(%rip)
> +
> +/* Reload code selector */
> +ljmpl   *cs32_switch_addr(%rip)
> +
> +.code32
> +
> +cs32_switch:
> +/* Initialise basic data segments */
> +mov $BOOT_DS,%edx
> +mov %edx,%ds
> +mov %edx,%es
> +mov %edx,%fs
> +mov %edx,%gs
> +mov %edx,%ss
> +
> +mov $sym_phys(cpu0_stack)+1024,%esp
> +
> +/* Disable paging */
> +mov %cr0,%edx
> +and $(~X86_CR0_PG),%edx
> +mov %edx,%cr0
> +
> +push%eax
> +push%ecx
> +
> +/* Disable Long Mode */
> +mov $MSR_EFER,%ecx
> +rdmsr
> +and $(~EFER_LME),%eax
> +wrmsr

I don't think this is really needed.

> +
> +pop %ecx
> +pop %eax
> +
> +/* Turn off PAE */
> +mov %cr4,%edx
> +and $(~X86_CR4_PAE),%edx
> +mov %edx,%cr4

Nor this.

> @@ -179,7 +334,7 @@ multiboot2_proto:
>  and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>  jmp 0b
>  
> -trampoline_setup:
> +bios_platform:
>  /* Set up trampoline segment 64k below EBDA */

This is still trampoline setup code, so it's not clear why you rename
the label. If you need another named label ...

> @@ -195,12 +350,13 @@ trampoline_setup:
>   * multiboot structure

Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-02-15 Thread Daniel Kiper
On Sat, Feb 14, 2015 at 08:23:45PM +0300, Andrei Borzenkov wrote:
> В Wed, 11 Feb 2015 08:20:04 +
> "Jan Beulich"  пишет:
>
> > >>> On 10.02.15 at 22:27,  wrote:
> > > After some testing we have found at least one machine on which this thing
> > > does not work. It is Dell PowerEdge R820 with latest firmware. Machine
> > > crashes/stops because early 32-bit code is not relocatable and must live
> > > under 0x10 address. (side note: I am surprised how it worked without
> > > any issue until now; Multiboot protocol, any version, does not guarantee
> > > that OS image will be loaded at specified/requested address;
> >
> > How does it not? It's an ELF binary without relocations that's being
> > loaded - I can't see how such could be validly loaded anywhere but
> > at the virtual address(es) its program header states (and I don't
> > know whether grub [1 or 2] would correctly process relocations if
> > there were any, but I doubt it).
> >
>
> grub2 relocates own modules when loading them. It does not do

Great! However, it also ignores MULTIBOOT_TAG_TYPE_EFI_BS flag
and overwrite BS if it leaves in region requested by image. It
is a bug which I have just discovered. I will fix it.

> relocation when loading Xen binary, but it does not sound impossible.

Ugh... You are right. I was confused because multiboot2 command just
allocate memory outside reserved regions. I thought that this is final
destination. However, later if you execute boot command then image
is relocated to final destination. Facepalm! Anyway, we must support
relocatable images in multiboot2 protocol. I think that image (any
format, e.g. PE) could inform loader that it can live anywhere below
4 GiB by setting special flag in multiboot2 header. Or ELF image could
have relocation section which would be interpreted by loader. Both
approaches make sense and are feasible.

Daniel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-02-14 Thread Andrei Borzenkov
В Wed, 11 Feb 2015 08:20:04 +
"Jan Beulich"  пишет:

> >>> On 10.02.15 at 22:27,  wrote:
> > After some testing we have found at least one machine on which this thing
> > does not work. It is Dell PowerEdge R820 with latest firmware. Machine
> > crashes/stops because early 32-bit code is not relocatable and must live
> > under 0x10 address. (side note: I am surprised how it worked without
> > any issue until now; Multiboot protocol, any version, does not guarantee
> > that OS image will be loaded at specified/requested address;
> 
> How does it not? It's an ELF binary without relocations that's being
> loaded - I can't see how such could be validly loaded anywhere but
> at the virtual address(es) its program header states (and I don't
> know whether grub [1 or 2] would correctly process relocations if
> there were any, but I doubt it).
> 

grub2 relocates own modules when loading them. It does not do
relocation when loading Xen binary, but it does not sound impossible.

> > Now I see two solutions for these issues:
> > 
> > 1) We can make early 32-bit code relocatable. We may use something similar
> >to xen/arch/x86/boot/trampoline.S:bootsym_rel(). Additionally, I think
> >that early code should not blindly map first 16 MiB of memory. It should
> >map first 1 MiB of memory and then 16 MiB of memory starting from
> >xen_phys_start. This way we also fix long standing bug in early code
> >which I described earlier.
> > 
> > 2) We can jump from EFI x86-64 mode directly into "Xen x86-64 mode" like
> >it is done in case of EFI loader. However, then we must duplicate 
> > multiboot2
> >protocol implementation in x86-64 mode (if we wish that multiboot2 
> > protocol
> >can be used on legacy BIOS and EFI platforms; I think that we should 
> > support
> >this protocol on both for users convenience). Additionally, we must use
> >a workaround to relocate trampoline if boot services uses memory below 1 
> > MiB
> >(please check commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d, x86/EFI: 
> > make
> >trampoline allocation more flexible, for more details).
> > 
> > I prefer #1 because this way we do not duplicate multiboot2 protocol 
> > implementation
> > (one for legacy BIOS and EFI) and we avoid issues with trampoline 
> > relocation 
> > when
> > low memory is occupied by boot services and/or 1:1 EFI page tables.
> 
> Between the two, 1 is certainly the preferable option.
> 
> > PS I have just realized that commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d
> >will not work if trampoline code will overwrite some of EFI 1:1 page 
> > tables.
> >Dell PowerEdge R820 store part of 1:1 page tables below 1 MiB. Xen loaded
> >by native EFI loader boots but it is only lucky coincidence that it does
> >not overwrite used entries. So, I tend to go and choose #1 even more.
> 
> How awful a firmware implementation! On PC-like systems, _nothing_
> that _absolutely_ has to be below 1Mb should be placed there.
> 
> Jan
> 
> 
> ___
> Grub-devel mailing list
> grub-de...@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-02-11 Thread Jan Beulich
>>> On 10.02.15 at 22:27,  wrote:
> After some testing we have found at least one machine on which this thing
> does not work. It is Dell PowerEdge R820 with latest firmware. Machine
> crashes/stops because early 32-bit code is not relocatable and must live
> under 0x10 address. (side note: I am surprised how it worked without
> any issue until now; Multiboot protocol, any version, does not guarantee
> that OS image will be loaded at specified/requested address;

How does it not? It's an ELF binary without relocations that's being
loaded - I can't see how such could be validly loaded anywhere but
at the virtual address(es) its program header states (and I don't
know whether grub [1 or 2] would correctly process relocations if
there were any, but I doubt it).

> Now I see two solutions for these issues:
> 
> 1) We can make early 32-bit code relocatable. We may use something similar
>to xen/arch/x86/boot/trampoline.S:bootsym_rel(). Additionally, I think
>that early code should not blindly map first 16 MiB of memory. It should
>map first 1 MiB of memory and then 16 MiB of memory starting from
>xen_phys_start. This way we also fix long standing bug in early code
>which I described earlier.
> 
> 2) We can jump from EFI x86-64 mode directly into "Xen x86-64 mode" like
>it is done in case of EFI loader. However, then we must duplicate 
> multiboot2
>protocol implementation in x86-64 mode (if we wish that multiboot2 
> protocol
>can be used on legacy BIOS and EFI platforms; I think that we should 
> support
>this protocol on both for users convenience). Additionally, we must use
>a workaround to relocate trampoline if boot services uses memory below 1 
> MiB
>(please check commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d, x86/EFI: 
> make
>trampoline allocation more flexible, for more details).
> 
> I prefer #1 because this way we do not duplicate multiboot2 protocol 
> implementation
> (one for legacy BIOS and EFI) and we avoid issues with trampoline relocation 
> when
> low memory is occupied by boot services and/or 1:1 EFI page tables.

Between the two, 1 is certainly the preferable option.

> PS I have just realized that commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d
>will not work if trampoline code will overwrite some of EFI 1:1 page 
> tables.
>Dell PowerEdge R820 store part of 1:1 page tables below 1 MiB. Xen loaded
>by native EFI loader boots but it is only lucky coincidence that it does
>not overwrite used entries. So, I tend to go and choose #1 even more.

How awful a firmware implementation! On PC-like systems, _nothing_
that _absolutely_ has to be below 1Mb should be placed there.

Jan


___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-02-10 Thread Andrew Cooper
On 10/02/2015 21:27, Daniel Kiper wrote:
> On Fri, Jan 30, 2015 at 06:54:22PM +0100, Daniel Kiper wrote:
>> Signed-off-by: Daniel Kiper 
>> ---
>>  xen/arch/x86/boot/head.S  |  174 
>> +++--
>>  xen/arch/x86/efi/efi-boot.h   |   29 +++
>>  xen/arch/x86/setup.c  |   23 ++---
>>  xen/arch/x86/x86_64/asm-offsets.c |2 +
>>  xen/common/efi/boot.c |   11 +++
>>  5 files changed, 222 insertions(+), 17 deletions(-)
> After some testing we have found at least one machine on which this thing
> does not work. It is Dell PowerEdge R820 with latest firmware. Machine
> crashes/stops because early 32-bit code is not relocatable and must live
> under 0x10 address. (side note: I am surprised how it worked without
> any issue until now; Multiboot protocol, any version, does not guarantee
> that OS image will be loaded at specified/requested address; So, it looks
> that there are not any legacy BIOS machines with e.g. 1 MiB - 2 MiB region
> reserved in the wild or they are not very common; Am I missing something?).
> Sadly, this region is used by BS, so, GRUB2 loads Xen higher (at least
> above 64 MiB). Please look at memory map on this machine:
>
> Type   StartEnd  # Pages  Attributes
> BS_Data0001-0009 0090 000F
> BS_Data0010-03FF 3F00 000F
> Available  0400-0FFFEFFF BFFF 000F
> BS_Code0000-1006CFFF 006E 000F
> Available  1006D000-B3E73FFF 000A3E07 000F
>
> [...]
>
> Additionally, early Xen boot code maps only first 16 MiB of memory. Hence,
> it means that jump into __high_start fails immediately.
>
> Now I see two solutions for these issues:
>
> 1) We can make early 32-bit code relocatable. We may use something similar
>to xen/arch/x86/boot/trampoline.S:bootsym_rel(). Additionally, I think
>that early code should not blindly map first 16 MiB of memory. It should
>map first 1 MiB of memory and then 16 MiB of memory starting from
>xen_phys_start. This way we also fix long standing bug in early code
>which I described earlier.
>
> 2) We can jump from EFI x86-64 mode directly into "Xen x86-64 mode" like
>it is done in case of EFI loader. However, then we must duplicate 
> multiboot2
>protocol implementation in x86-64 mode (if we wish that multiboot2 protocol
>can be used on legacy BIOS and EFI platforms; I think that we should 
> support
>this protocol on both for users convenience). Additionally, we must use
>a workaround to relocate trampoline if boot services uses memory below 1 
> MiB
>(please check commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d, x86/EFI: 
> make
>trampoline allocation more flexible, for more details).
>
> I prefer #1 because this way we do not duplicate multiboot2 protocol 
> implementation
> (one for legacy BIOS and EFI) and we avoid issues with trampoline relocation 
> when
> low memory is occupied by boot services and/or 1:1 EFI page tables.
>
> Daniel
>
> PS I have just realized that commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d
>will not work if trampoline code will overwrite some of EFI 1:1 page 
> tables.
>Dell PowerEdge R820 store part of 1:1 page tables below 1 MiB. Xen loaded
>by native EFI loader boots but it is only lucky coincidence that it does
>not overwrite used entries. So, I tend to go and choose #1 even more.

I have to admit to also being surprised at the fragility of the Xen, and
how it cannot function if _start isn't loaded on the 1MB boundary.

Given that there is provably one system in the wild which causes us to
fall over this limitation, it clearly needs fixing.

I would also agree that making the entry point relocatable is the
correct way forwards.  However, you cannot use something like
bootsym_rel() as that requires infrastructure to patch the references
(observe the loop over __trampoline_rel_{start,end} just before the call
to cmdline_parse_early())

This can probably be achieved by having a small bit of hand-written PIC
which puts an appropriate offset into %ds.

~Andrew

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-02-10 Thread Daniel Kiper
On Fri, Jan 30, 2015 at 06:54:22PM +0100, Daniel Kiper wrote:
> Signed-off-by: Daniel Kiper 
> ---
>  xen/arch/x86/boot/head.S  |  174 
> +++--
>  xen/arch/x86/efi/efi-boot.h   |   29 +++
>  xen/arch/x86/setup.c  |   23 ++---
>  xen/arch/x86/x86_64/asm-offsets.c |2 +
>  xen/common/efi/boot.c |   11 +++
>  5 files changed, 222 insertions(+), 17 deletions(-)

After some testing we have found at least one machine on which this thing
does not work. It is Dell PowerEdge R820 with latest firmware. Machine
crashes/stops because early 32-bit code is not relocatable and must live
under 0x10 address. (side note: I am surprised how it worked without
any issue until now; Multiboot protocol, any version, does not guarantee
that OS image will be loaded at specified/requested address; So, it looks
that there are not any legacy BIOS machines with e.g. 1 MiB - 2 MiB region
reserved in the wild or they are not very common; Am I missing something?).
Sadly, this region is used by BS, so, GRUB2 loads Xen higher (at least
above 64 MiB). Please look at memory map on this machine:

Type   StartEnd  # Pages  Attributes
BS_Data0001-0009 0090 000F
BS_Data0010-03FF 3F00 000F
Available  0400-0FFFEFFF BFFF 000F
BS_Code0000-1006CFFF 006E 000F
Available  1006D000-B3E73FFF 000A3E07 000F

[...]

Additionally, early Xen boot code maps only first 16 MiB of memory. Hence,
it means that jump into __high_start fails immediately.

Now I see two solutions for these issues:

1) We can make early 32-bit code relocatable. We may use something similar
   to xen/arch/x86/boot/trampoline.S:bootsym_rel(). Additionally, I think
   that early code should not blindly map first 16 MiB of memory. It should
   map first 1 MiB of memory and then 16 MiB of memory starting from
   xen_phys_start. This way we also fix long standing bug in early code
   which I described earlier.

2) We can jump from EFI x86-64 mode directly into "Xen x86-64 mode" like
   it is done in case of EFI loader. However, then we must duplicate multiboot2
   protocol implementation in x86-64 mode (if we wish that multiboot2 protocol
   can be used on legacy BIOS and EFI platforms; I think that we should support
   this protocol on both for users convenience). Additionally, we must use
   a workaround to relocate trampoline if boot services uses memory below 1 MiB
   (please check commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d, x86/EFI: make
   trampoline allocation more flexible, for more details).

I prefer #1 because this way we do not duplicate multiboot2 protocol 
implementation
(one for legacy BIOS and EFI) and we avoid issues with trampoline relocation 
when
low memory is occupied by boot services and/or 1:1 EFI page tables.

Daniel

PS I have just realized that commit c1f2dfe8f6a559bc28935f24e31bb33d17d9713d
   will not work if trampoline code will overwrite some of EFI 1:1 page tables.
   Dell PowerEdge R820 store part of 1:1 page tables below 1 MiB. Xen loaded
   by native EFI loader boots but it is only lucky coincidence that it does
   not overwrite used entries. So, I tend to go and choose #1 even more.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-01-30 Thread Andrew Cooper
On 30/01/2015 23:43, Daniel Kiper wrote:
> On Fri, Jan 30, 2015 at 07:06:53PM +, Andrew Cooper wrote:
>> On 30/01/15 17:54, Daniel Kiper wrote:
>>> +
>>> +efi_multiboot2_proto:
>>> +/* Skip Multiboot2 information fixed part */
>>> +lea MB2_fixed_sizeof(%ebx),%ecx
>>> +
>>> +0:
>>> +/* Get mem_lower from Multiboot2 information */
>>> +cmpl$MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
>>> +jne 1f
>>> +
>>> +mov MB2_mem_lower(%ecx),%edx
>>> +jmp 4f
>>> +
>>> +1:
>>> +/* Get EFI SystemTable address from Multiboot2 information */
>>> +cmpl$MULTIBOOT2_TAG_TYPE_EFI64,(%ecx)
>>> +jne 2f
>>> +
>>> +lea MB2_efi64_st(%ecx),%esi
>>> +lea efi_st(%rip),%edi
>>> +movsq
>> This is complete overkill for copying a 64bit variable out of the tag
>> and into a local variable.  Just use a plain 64bit load and store.
> I am not sure what do you mean by "64bit load and store" but I have
> just realized that we do not need these variables. They are remnants
> from early developments when I thought that we need ImageHandle
> and SystemTable here and later somewhere else.

mov MB2_efi64_st(%rcx), %rdi
mov %rdi, efi_st(%rip)

But if they are not needed, drop the code completely.

>>> +jmp 4f
>>> +
>>> +3:
>>> +/* Is it the end of Multiboot2 information? */
>>> +cmpl$MULTIBOOT2_TAG_TYPE_END,(%ecx)
>>> +je  run_bs
>>> +
>>> +4:
>>> +/* Go to next Multiboot2 information tag */
>>> +add MB2_tag_size(%ecx),%ecx
>>> +add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
>>> +and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>>> +jmp 0b
>>> +
>>> +run_bs:
>>> +push%rax
>>> +push%rdx
>> Does the EFI spec guarantee that we have a good stack to use at this point?
> Unified Extensible Firmware Interface Specification, Version 2.4 Errata B,
> section 2.3.4, x64 Platforms says: During boot services time the processor
> is in the following execution mode: ..., 128 KiB, or more, of available
> stack space. GRUB2 uses this stack too and do not move it to different
> memory region. So, I think that here we are on safe side.

Sounds ok then.

>
>>> +/* Initialize BSS (no nasty surprises!) */
>>> +lea __bss_start(%rip),%rdi
>>> +lea _end(%rip),%rcx
>>> +sub %rdi,%rcx
>>> +xor %rax,%rax
>> xor %eax,%eax is shorter.
>>
>>> +rep stosb
>> It would be more efficient to make sure that the linker aligns
>> __bss_start and _end on 8 byte boundaries, and use stosq instead.
> Right but just for this. Is it pays? We do this only once.

The BSS in Xen is 300k.  It is absolutely better to clear it 8 bytes at
a time rather than 1.

> However, if you wish...
>
>>> +mov efi_ih(%rip),%rdi   /* EFI ImageHandle */
>>> +mov efi_st(%rip),%rsi   /* EFI SystemTable */
>>> +callefi_multiboot2
>>> +
>>> +pop %rcx
>>> +pop %rax
>>> +
>>> +shl $10-4,%rcx  /* Convert multiboot2.mem_lower to 
>>> bytes/16 */
>>> +
>>> +cli
>> This looks suspiciously out of place.  Surely the EFI spec doesn't
>> permit entry with interrupts enabled?
> Unified Extensible Firmware Interface Specification, Version 2.4 Errata B,
> section 2.3.4, x64 Platforms says: During boot services time the processor
> is in the following execution mode: ..., Interrupts are enabled–though no
> interrupt services are supported other than the UEFI boot services timer
> functions (All loaded device drivers are serviced synchronously by 
> “polling.”).
> So, I think that we should use BS with interrupts enabled and disable
> them after ExitBootServices(). Hmmm... Now I think that we should use
> cli immediately after efi_multiboot2() call.

I presume then that the firmware has set up a valid idt somewhere and is
actually serving any interrupts we get.

> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index f8be3dd..c5725ca 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -75,6 +75,17 @@ static size_t wstrlen(const CHAR16 * s);
>  static int set_color(u32 mask, int bpp, u8 *pos, u8 *sz);
>  static bool_t match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
>
> +static void efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
> +static void efi_console_set_mode(void);
> +static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(void);
> +static UINTN efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
> +   UINTN cols, UINTN rows, UINTN depth);
> +static void efi_tables(void);
> +static void setup_efi_pci(void);
> +static void efi_variables(void);
> +static void efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN 
> gop_mode);
> +static void efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
> *SystemTable);
> +
>> If any of these forward declarations are ne

Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-01-30 Thread Daniel Kiper
On Fri, Jan 30, 2015 at 07:06:53PM +, Andrew Cooper wrote:
> On 30/01/15 17:54, Daniel Kiper wrote:
> > Signed-off-by: Daniel Kiper 
> > ---
> >  xen/arch/x86/boot/head.S  |  174 
> > +++--
> >  xen/arch/x86/efi/efi-boot.h   |   29 +++
> >  xen/arch/x86/setup.c  |   23 ++---
> >  xen/arch/x86/x86_64/asm-offsets.c |2 +
> >  xen/common/efi/boot.c |   11 +++
> >  5 files changed, 222 insertions(+), 17 deletions(-)
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index 7861057..89f5aa7 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -8,6 +8,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  .text
> >  .code32
> > @@ -57,6 +58,9 @@ ENTRY(start)
> >  .long   .Lmultiboot2_info_req_end - .Lmultiboot2_info_req
> >  .long   MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> >  .long   MULTIBOOT2_TAG_TYPE_MMAP
> > +.long   MULTIBOOT2_TAG_TYPE_EFI_BS
> > +.long   MULTIBOOT2_TAG_TYPE_EFI64
> > +.long   MULTIBOOT2_TAG_TYPE_EFI64_IH
> >  .Lmultiboot2_info_req_end:
> >
> >  .align  MULTIBOOT2_TAG_ALIGN
> > @@ -80,6 +84,19 @@ ENTRY(start)
> >  .long   0 /* Number of the lines - no preference. */
> >  .long   0 /* Number of bits per pixel - no preference. */
> >
> > +/* Do not disable EFI boot services. */
> > +.align  MULTIBOOT2_TAG_ALIGN
> > +.short  MULTIBOOT2_HEADER_TAG_EFI_BS
> > +.short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> > +.long   8 /* Tag size. */
> > +
> > +/* EFI64 entry point. */
> > +.align  MULTIBOOT2_TAG_ALIGN
> > +.short  MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64
> > +.short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> > +.long   12 /* Tag size. */
> > +.long   sym_phys(__efi64_start)
> > +
> >  /* Multiboot2 header end tag. */
> >  .align  MULTIBOOT2_TAG_ALIGN
> >  .short  MULTIBOOT2_HEADER_TAG_END
> > @@ -94,6 +111,17 @@ ENTRY(start)
> >  gdt_boot_descr:
> >  .word   6*8-1
> >  .long   sym_phys(trampoline_gdt)
> > +.long   0 /* Needed for 64-bit lgdt */
> > +
> > +cs32_switch_addr:
> > +.long   sym_phys(cs32_switch)
> > +.long   BOOT_CS32
>
> .word
>
> ljmpl refers to an m32:16 not an m32:32
>
> > +
> > +efi_st:
> > +.quad   0
> > +
> > +efi_ih:
> > +.quad   0
> >
> >  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
> >  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> > @@ -124,6 +152,133 @@ print_err:
> >  .Lhalt: hlt
> >  jmp .Lhalt
> >
> > +.code64
> > +
> > +__efi64_start:
> > +cld
> > +
> > +/* Bootloaders may set multiboot[12].mem_lower to a nonzero value 
> > */
> > +xor %edx,%edx
> > +
> > +/* Check for Multiboot2 bootloader */
> > +cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +je  efi_multiboot2_proto
> > +
> > +jmp not_multiboot
>
> not_multiboot is 32bit code.  You must drop out of 64bit before using
> it, or make a 64bit variant.
>
> > +
> > +efi_multiboot2_proto:
> > +/* Skip Multiboot2 information fixed part */
> > +lea MB2_fixed_sizeof(%ebx),%ecx
> > +
> > +0:
> > +/* Get mem_lower from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> > +jne 1f
> > +
> > +mov MB2_mem_lower(%ecx),%edx
> > +jmp 4f
> > +
> > +1:
> > +/* Get EFI SystemTable address from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_EFI64,(%ecx)
> > +jne 2f
> > +
> > +lea MB2_efi64_st(%ecx),%esi
> > +lea efi_st(%rip),%edi
> > +movsq
>
> This is complete overkill for copying a 64bit variable out of the tag
> and into a local variable.  Just use a plain 64bit load and store.

I am not sure what do you mean by "64bit load and store" but I have
just realized that we do not need these variables. They are remnants
from early developments when I thought that we need ImageHandle
and SystemTable here and later somewhere else.

> > +/* Do not go into real mode on EFI platform */
> > +movb$1,skip_realmode(%rip)
> > +
> > +jmp 4f
> > +
> > +2:
> > +/* Get EFI ImageHandle address from Multiboot2 information */
> > +cmpl$MULTIBOOT2_TAG_TYPE_EFI64_IH,(%ecx)
> > +jne 3f
> > +
> > +lea MB2_efi64_ih(%ecx),%esi
> > +lea efi_ih(%rip),%edi
> > +movsq
>
> And here.

Ditto.

> > +jmp 4f
> > +
> > +3:
> > +/* Is it the end of Multiboot2 information? */
> > +cmpl$MULTIBOOT2_TAG_TYPE_END,(%ecx)
> > +je  run_bs
> > +
> > +4:
> > +/* Go to next Multiboot2 information tag */
> > +add MB2_tag_size(%ecx),%ecx
> > +add $(MULTIBOOT2

Re: [Xen-devel] [PATCH 18/18] x86: add multiboot2 protocol support for EFI platforms

2015-01-30 Thread Andrew Cooper
On 30/01/15 17:54, Daniel Kiper wrote:
> Signed-off-by: Daniel Kiper 
> ---
>  xen/arch/x86/boot/head.S  |  174 
> +++--
>  xen/arch/x86/efi/efi-boot.h   |   29 +++
>  xen/arch/x86/setup.c  |   23 ++---
>  xen/arch/x86/x86_64/asm-offsets.c |2 +
>  xen/common/efi/boot.c |   11 +++
>  5 files changed, 222 insertions(+), 17 deletions(-)
>
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 7861057..89f5aa7 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -8,6 +8,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  .text
>  .code32
> @@ -57,6 +58,9 @@ ENTRY(start)
>  .long   .Lmultiboot2_info_req_end - .Lmultiboot2_info_req
>  .long   MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
>  .long   MULTIBOOT2_TAG_TYPE_MMAP
> +.long   MULTIBOOT2_TAG_TYPE_EFI_BS
> +.long   MULTIBOOT2_TAG_TYPE_EFI64
> +.long   MULTIBOOT2_TAG_TYPE_EFI64_IH
>  .Lmultiboot2_info_req_end:
>  
>  .align  MULTIBOOT2_TAG_ALIGN
> @@ -80,6 +84,19 @@ ENTRY(start)
>  .long   0 /* Number of the lines - no preference. */
>  .long   0 /* Number of bits per pixel - no preference. */
>  
> +/* Do not disable EFI boot services. */
> +.align  MULTIBOOT2_TAG_ALIGN
> +.short  MULTIBOOT2_HEADER_TAG_EFI_BS
> +.short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +.long   8 /* Tag size. */
> +
> +/* EFI64 entry point. */
> +.align  MULTIBOOT2_TAG_ALIGN
> +.short  MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64
> +.short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +.long   12 /* Tag size. */
> +.long   sym_phys(__efi64_start)
> +
>  /* Multiboot2 header end tag. */
>  .align  MULTIBOOT2_TAG_ALIGN
>  .short  MULTIBOOT2_HEADER_TAG_END
> @@ -94,6 +111,17 @@ ENTRY(start)
>  gdt_boot_descr:
>  .word   6*8-1
>  .long   sym_phys(trampoline_gdt)
> +.long   0 /* Needed for 64-bit lgdt */
> +
> +cs32_switch_addr:
> +.long   sym_phys(cs32_switch)
> +.long   BOOT_CS32

.word

ljmpl refers to an m32:16 not an m32:32

> +
> +efi_st:
> +.quad   0
> +
> +efi_ih:
> +.quad   0
>  
>  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
>  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> @@ -124,6 +152,133 @@ print_err:
>  .Lhalt: hlt
>  jmp .Lhalt
>  
> +.code64
> +
> +__efi64_start:
> +cld
> +
> +/* Bootloaders may set multiboot[12].mem_lower to a nonzero value */
> +xor %edx,%edx
> +
> +/* Check for Multiboot2 bootloader */
> +cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +je  efi_multiboot2_proto
> +
> +jmp not_multiboot

not_multiboot is 32bit code.  You must drop out of 64bit before using
it, or make a 64bit variant.

> +
> +efi_multiboot2_proto:
> +/* Skip Multiboot2 information fixed part */
> +lea MB2_fixed_sizeof(%ebx),%ecx
> +
> +0:
> +/* Get mem_lower from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> +jne 1f
> +
> +mov MB2_mem_lower(%ecx),%edx
> +jmp 4f
> +
> +1:
> +/* Get EFI SystemTable address from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_EFI64,(%ecx)
> +jne 2f
> +
> +lea MB2_efi64_st(%ecx),%esi
> +lea efi_st(%rip),%edi
> +movsq

This is complete overkill for copying a 64bit variable out of the tag
and into a local variable.  Just use a plain 64bit load and store.

> +
> +/* Do not go into real mode on EFI platform */
> +movb$1,skip_realmode(%rip)
> +
> +jmp 4f
> +
> +2:
> +/* Get EFI ImageHandle address from Multiboot2 information */
> +cmpl$MULTIBOOT2_TAG_TYPE_EFI64_IH,(%ecx)
> +jne 3f
> +
> +lea MB2_efi64_ih(%ecx),%esi
> +lea efi_ih(%rip),%edi
> +movsq

And here.

> +jmp 4f
> +
> +3:
> +/* Is it the end of Multiboot2 information? */
> +cmpl$MULTIBOOT2_TAG_TYPE_END,(%ecx)
> +je  run_bs
> +
> +4:
> +/* Go to next Multiboot2 information tag */
> +add MB2_tag_size(%ecx),%ecx
> +add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +jmp 0b
> +
> +run_bs:
> +push%rax
> +push%rdx

Does the EFI spec guarantee that we have a good stack to use at this point?

> +
> +/* Initialize BSS (no nasty surprises!) */
> +lea __bss_start(%rip),%rdi
> +lea _end(%rip),%rcx
> +sub %rdi,%rcx
> +xor %rax,%rax

xor %eax,%eax is shorter.

> +rep stosb

It would be more efficient to make sure that the linker aligns
__bss_start and _end on 8 byte boundaries, and use stos