xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 01/23] x86/boot: remove unneeded instruction
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
@ 2015-07-20 14:28 ` Daniel Kiper
  2015-07-20 14:28 ` [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file Daniel Kiper
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:28 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/head.S |    1 -
 1 file changed, 1 deletion(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index cfd59dc..f63b349 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -169,7 +169,6 @@ __start:
         /* Apply relocations to bootstrap trampoline. */
         mov     sym_phys(trampoline_phys),%edx
         mov     $sym_phys(__trampoline_rel_start),%edi
-        mov     %edx,sym_phys(trampoline_phys)
 1:
         mov     (%edi),%eax
         add     %edx,(%edi,%eax)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
  2015-07-20 14:28 ` [PATCH v2 01/23] x86/boot: remove unneeded instruction Daniel Kiper
@ 2015-07-20 14:28 ` Daniel Kiper
  2015-07-20 14:28 ` [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb Daniel Kiper
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:28 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/build32.mk |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index c208249..c83effe 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -13,7 +13,7 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
 	sed 's/ /,0x/g' | sed 's/,0x$$//' | sed 's/^[0-9]*,/ .long /') >$@
 
 %.bin: %.lnk
-	$(OBJCOPY) -O binary $< $@
+	$(OBJCOPY) -O binary -j .text $< $@
 
 %.lnk: %.o
 	$(LD) $(LDFLAGS_DIRECT) -N -Ttext 0 -o $@ $<
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
  2015-07-20 14:28 ` [PATCH v2 01/23] x86/boot: remove unneeded instruction Daniel Kiper
  2015-07-20 14:28 ` [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file Daniel Kiper
@ 2015-07-20 14:28 ` Daniel Kiper
  2015-07-20 14:28 ` [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:28 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Additionally, align relevant comment to coding style.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/head.S |    5 +++--
 xen/arch/x86/xen.lds.S   |    2 ++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index f63b349..ed42782 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -123,12 +123,13 @@ __start:
         call    reloc
         mov     %eax,sym_phys(multiboot_ptr)
 
-        /* Initialize BSS (no nasty surprises!) */
+        /* Initialize BSS (no nasty surprises!). */
         mov     $sym_phys(__bss_start),%edi
         mov     $sym_phys(__bss_end),%ecx
         sub     %edi,%ecx
+        shr     $2,%ecx
         xor     %eax,%eax
-        rep     stosb
+        rep     stosl
 
         /* Interrogate CPU extended features via CPUID. */
         mov     $0x80000000,%eax
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 6553cff..3e1f2af 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -162,6 +162,7 @@ SECTIONS
   . = ALIGN(STACK_SIZE);
   __init_end = .;
 
+  . = ALIGN(4);
   .bss : {                     /* BSS */
        __bss_start = .;
        *(.bss.stack_aligned)
@@ -175,6 +176,7 @@ SECTIONS
        *(.bss.percpu.read_mostly)
        . = ALIGN(SMP_CACHE_BYTES);
        __per_cpu_data_end = .;
+       . = ALIGN(4);
        __bss_end = .;
   } :text
   _end = . ;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (2 preceding siblings ...)
  2015-07-20 14:28 ` [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb Daniel Kiper
@ 2015-07-20 14:28 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:28 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/head.S  |    4 +++-
 xen/arch/x86/boot/reloc.c |   20 ++++++++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index ed42782..3cbb2e6 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -119,8 +119,10 @@ __start:
 
         /* Save the Multiboot info struct (after relocation) for later use. */
         mov     $sym_phys(cpu0_stack)+1024,%esp
-        push    %ebx
+        push    %ebx                /* Multiboot information address. */
+        push    %eax                /* Boot trampoline address. */
         call    reloc
+        add     $8,%esp             /* Remove reloc() args from stack. */
         mov     %eax,sym_phys(multiboot_ptr)
 
         /* Initialize BSS (no nasty surprises!). */
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 63045c0..708898f 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -10,15 +10,27 @@
  *    Keir Fraser <keir@xen.org>
  */
 
-/* entered with %eax = BOOT_TRAMPOLINE */
+/*
+ * This entry point is entered from xen/arch/x86/boot/head.S with:
+ *   - 0x4(%esp) = BOOT_TRAMPOLINE_ADDRESS,
+ *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS.
+ */
 asm (
     "    .text                         \n"
     "    .globl _start                 \n"
     "_start:                           \n"
+    "    push %ebp                     \n"
+    "    mov  %esp,%ebp                \n"
     "    call 1f                       \n"
-    "1:  pop  %ebx                     \n"
-    "    mov  %eax,alloc-1b(%ebx)      \n"
-    "    jmp  reloc                    \n"
+    "1:  pop  %ecx                     \n"
+    "    mov  0x8(%ebp),%eax           \n"
+    "    mov  %eax,alloc-1b(%ecx)      \n"
+    "    mov  0xc(%ebp),%eax           \n"
+    "    push %eax                     \n"
+    "    call reloc                    \n"
+    "    add  $4,%esp                  \n"
+    "    pop  %ebp                     \n"
+    "    ret                           \n"
     );
 
 /*
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (3 preceding siblings ...)
  2015-07-20 14:28 ` [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 06/23] x86/boot: use %ecx instead of %eax Daniel Kiper
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Create generic alloc and copy functions. We need
separate tools for memory allocation and copy to
provide multiboot2 protocol support.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v2 - suggestions/fixes:
   - generalize new functions names
     (suggested by Jan Beulich),
   - reduce number of casts
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/reloc.c |   59 ++++++++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 708898f..09fd540 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -45,9 +45,10 @@ asm (
 typedef unsigned int u32;
 #include "../../../include/xen/multiboot.h"
 
-static void *reloc_mbi_struct(void *old, unsigned int bytes)
+static u32 alloc_mem(u32 bytes)
 {
-    void *new;
+    u32 s;
+
     asm(
     "    call 1f                      \n"
     "1:  pop  %%edx                   \n"
@@ -55,50 +56,64 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
     "    sub  %1,%0                   \n"
     "    and  $~15,%0                 \n"
     "    mov  %0,alloc-1b(%%edx)      \n"
-    "    mov  %0,%%edi                \n"
-    "    rep  movsb                   \n"
-       : "=&r" (new), "+c" (bytes), "+S" (old)
-	: : "edx", "edi", "memory");
-    return new;
+       : "=&r" (s) : "r" (bytes) : "edx", "memory");
+
+    return s;
 }
 
-static char *reloc_mbi_string(char *old)
+static u32 copy_mem(u32 src, u32 bytes)
 {
-    char *p;
-    for ( p = old; *p != '\0'; p++ )
+    u32 dst, dst_asm;
+
+    dst = alloc_mem(bytes);
+    dst_asm = dst;
+
+    asm volatile("rep movsb" : "+S" (src), "+D" (dst_asm), "+c" (bytes) : : "memory");
+
+    return dst;
+}
+
+static u32 copy_string(u32 src)
+{
+    u32 p;
+
+    if ( src == 0 )
+        return 0;
+
+    for ( p = src; *(char *)p != '\0'; p++ )
         continue;
-    return reloc_mbi_struct(old, p - old + 1);
+
+    return copy_mem(src, p - src + 1);
 }
 
-multiboot_info_t *reloc(multiboot_info_t *mbi_old)
+multiboot_info_t *reloc(u32 mbi_old)
 {
-    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
+    multiboot_info_t *mbi = (multiboot_info_t *)copy_mem(mbi_old, sizeof(*mbi));
     int i;
 
     if ( mbi->flags & MBI_CMDLINE )
-        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
+        mbi->cmdline = copy_string(mbi->cmdline);
 
     if ( mbi->flags & MBI_MODULES )
     {
-        module_t *mods = reloc_mbi_struct(
-            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        module_t *mods;
 
-        mbi->mods_addr = (u32)mods;
+        mbi->mods_addr = copy_mem(mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+
+        mods = (module_t *)mbi->mods_addr;
 
         for ( i = 0; i < mbi->mods_count; i++ )
         {
             if ( mods[i].string )
-                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
+                mods[i].string = copy_string(mods[i].string);
         }
     }
 
     if ( mbi->flags & MBI_MEMMAP )
-        mbi->mmap_addr = (u32)reloc_mbi_struct(
-            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
+        mbi->mmap_addr = copy_mem(mbi->mmap_addr, mbi->mmap_length);
 
     if ( mbi->flags & MBI_LOADERNAME )
-        mbi->boot_loader_name = (u32)reloc_mbi_string(
-            (char *)mbi->boot_loader_name);
+        mbi->boot_loader_name = copy_string(mbi->boot_loader_name);
 
     /* Mask features we don't understand or don't relocate. */
     mbi->flags &= (MBI_MEMLIMITS |
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 06/23] x86/boot: use %ecx instead of %eax
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (4 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Use %ecx instead of %eax to store low memory upper limit from EBDA.
This way we do not wipe multiboot protocol identifier. It is needed
in reloc() to differentiate between multiboot (v1) and
multiboot2 protocol.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/boot/head.S |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 3cbb2e6..77e7da9 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -87,14 +87,14 @@ __start:
         jne     not_multiboot
 
         /* Set up trampoline segment 64k below EBDA */
-        movzwl  0x40e,%eax          /* EBDA segment */
-        cmp     $0xa000,%eax        /* sanity check (high) */
+        movzwl  0x40e,%ecx          /* EBDA segment */
+        cmp     $0xa000,%ecx        /* sanity check (high) */
         jae     0f
-        cmp     $0x4000,%eax        /* sanity check (low) */
+        cmp     $0x4000,%ecx        /* sanity check (low) */
         jae     1f
 0:
-        movzwl  0x413,%eax          /* use base memory size on failure */
-        shl     $10-4,%eax
+        movzwl  0x413,%ecx          /* use base memory size on failure */
+        shl     $10-4,%ecx
 1:
         /*
          * Compare the value in the BDA with the information from the
@@ -106,21 +106,21 @@ __start:
         cmp     $0x100,%edx         /* is the multiboot value too small? */
         jb      2f                  /* if so, do not use it */
         shl     $10-4,%edx
-        cmp     %eax,%edx           /* compare with BDA value */
-        cmovb   %edx,%eax           /* and use the smaller */
+        cmp     %ecx,%edx           /* compare with BDA value */
+        cmovb   %edx,%ecx           /* and use the smaller */
 
 2:      /* Reserve 64kb for the trampoline */
-        sub     $0x1000,%eax
+        sub     $0x1000,%ecx
 
         /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
-        xor     %al, %al
-        shl     $4, %eax
-        mov     %eax,sym_phys(trampoline_phys)
+        xor     %cl, %cl
+        shl     $4, %ecx
+        mov     %ecx,sym_phys(trampoline_phys)
 
         /* Save the Multiboot info struct (after relocation) for later use. */
         mov     $sym_phys(cpu0_stack)+1024,%esp
         push    %ebx                /* Multiboot information address. */
-        push    %eax                /* Boot trampoline address. */
+        push    %ecx                /* Boot trampoline address. */
         call    reloc
         add     $8,%esp             /* Remove reloc() args from stack. */
         mov     %eax,sym_phys(multiboot_ptr)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (5 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 06/23] x86/boot: use %ecx instead of %eax Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 08/23] x86: add multiboot2 protocol support Daniel Kiper
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Rename mbi and mbi_old variables and rearrange code a bit to make
it more readable. Additionally, this way multiboot (v1) protocol
implementation and future multiboot2 protocol implementation will
use the same variable naming convention.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - extract this change from main mutliboot2
     protocol implementation
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/reloc.c |   39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 09fd540..feb1d72 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -86,41 +86,44 @@ static u32 copy_string(u32 src)
     return copy_mem(src, p - src + 1);
 }
 
-multiboot_info_t *reloc(u32 mbi_old)
+multiboot_info_t *reloc(u32 mbi_in)
 {
-    multiboot_info_t *mbi = (multiboot_info_t *)copy_mem(mbi_old, sizeof(*mbi));
     int i;
+    multiboot_info_t *mbi_out;
 
-    if ( mbi->flags & MBI_CMDLINE )
-        mbi->cmdline = copy_string(mbi->cmdline);
+    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));
 
-    if ( mbi->flags & MBI_MODULES )
+    if ( mbi_out->flags & MBI_CMDLINE )
+        mbi_out->cmdline = copy_string(mbi_out->cmdline);
+
+    if ( mbi_out->flags & MBI_MODULES )
     {
         module_t *mods;
 
-        mbi->mods_addr = copy_mem(mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        mbi_out->mods_addr = copy_mem(mbi_out->mods_addr,
+                                      mbi_out->mods_count * sizeof(module_t));
 
-        mods = (module_t *)mbi->mods_addr;
+        mods = (module_t *)mbi_out->mods_addr;
 
-        for ( i = 0; i < mbi->mods_count; i++ )
+        for ( i = 0; i < mbi_out->mods_count; i++ )
         {
             if ( mods[i].string )
                 mods[i].string = copy_string(mods[i].string);
         }
     }
 
-    if ( mbi->flags & MBI_MEMMAP )
-        mbi->mmap_addr = copy_mem(mbi->mmap_addr, mbi->mmap_length);
+    if ( mbi_out->flags & MBI_MEMMAP )
+        mbi_out->mmap_addr = copy_mem(mbi_out->mmap_addr, mbi_out->mmap_length);
 
-    if ( mbi->flags & MBI_LOADERNAME )
-        mbi->boot_loader_name = copy_string(mbi->boot_loader_name);
+    if ( mbi_out->flags & MBI_LOADERNAME )
+        mbi_out->boot_loader_name = copy_string(mbi_out->boot_loader_name);
 
     /* Mask features we don't understand or don't relocate. */
-    mbi->flags &= (MBI_MEMLIMITS |
-                   MBI_CMDLINE |
-                   MBI_MODULES |
-                   MBI_MEMMAP |
-                   MBI_LOADERNAME);
+    mbi_out->flags &= (MBI_MEMLIMITS |
+                       MBI_CMDLINE |
+                       MBI_MODULES |
+                       MBI_MEMMAP |
+                       MBI_LOADERNAME);
 
-    return mbi;
+    return mbi_out;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 08/23] x86: add multiboot2 protocol support
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (6 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:17   ` Konrad Rzeszutek Wilk
                     ` (2 more replies)
  2015-07-20 14:29 ` [PATCH v2 09/23] efi: create efi_enabled() Daniel Kiper
                   ` (29 subsequent siblings)
  37 siblings, 3 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Add multiboot2 protocol support. Alter min memory limit handling as we
now may not find it from either multiboot (v1) or multiboot2.

This way we are laying the foundation for EFI + GRUB2 + Xen development.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
v2 - suggestions/fixes:
   - generate multiboot2 header using macros
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - simplify assembly in xen/arch/x86/boot/head.S
     (suggested by Jan Beulich),
   - do not include include/xen/compiler.h
     in xen/arch/x86/boot/reloc.c
     (suggested by Jan Beulich),
   - do not read data beyond the end of Multiboot2 information
     (suggested by Jan Beulich).

v2 - not fixed yet:
   - dynamic dependency generation for xen/arch/x86/boot/reloc.S;
     this requires more work; I am not sure that it pays because
     potential patch requires more changes than addition of just
     multiboot2.h to Makefile
     (suggested by Jan Beulich),
   - isolated/stray __packed attribute usage for multiboot2_memory_map_t
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/Makefile        |    3 +-
 xen/arch/x86/boot/head.S          |  105 +++++++++++++++++++++--
 xen/arch/x86/boot/reloc.c         |  146 +++++++++++++++++++++++++++++++-
 xen/arch/x86/x86_64/asm-offsets.c |    7 ++
 xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
 5 files changed, 420 insertions(+), 10 deletions(-)
 create mode 100644 xen/include/xen/multiboot2.h

diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
index 5fdb5ae..06893d8 100644
--- a/xen/arch/x86/boot/Makefile
+++ b/xen/arch/x86/boot/Makefile
@@ -1,6 +1,7 @@
 obj-bin-y += head.o
 
-RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h
+RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
+	     $(BASEDIR)/include/xen/multiboot2.h
 
 head.o: reloc.S
 
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 77e7da9..57197db 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <xen/multiboot.h>
+#include <xen/multiboot2.h>
 #include <public/xen.h>
 #include <asm/asm_defns.h>
 #include <asm/desc.h>
@@ -19,6 +20,28 @@
 #define BOOT_PSEUDORM_CS 0x0020
 #define BOOT_PSEUDORM_DS 0x0028
 
+#define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
+#define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
+
+        .macro mb2ht_args arg, args:vararg
+        .long \arg
+        .ifnb \args
+        mb2ht_args \args
+        .endif
+        .endm
+
+        .macro mb2ht_init type, req, args:vararg
+        .align MULTIBOOT2_TAG_ALIGN
+        0:
+        .short \type
+        .short \req
+        .long 1f - 0b
+        .ifnb \args
+        mb2ht_args \args
+        .endif
+        1:
+        .endm
+
 ENTRY(start)
         jmp     __start
 
@@ -34,6 +57,42 @@ multiboot1_header_start:       /*** MULTIBOOT1 HEADER ****/
         .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
 multiboot1_header_end:
 
+/*** MULTIBOOT2 HEADER ****/
+/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
+        .align  MULTIBOOT2_HEADER_ALIGN
+
+.Lmultiboot2_header:
+        /* Magic number indicating a Multiboot2 header. */
+        .long   MULTIBOOT2_HEADER_MAGIC
+        /* Architecture: i386. */
+        .long   MULTIBOOT2_ARCHITECTURE_I386
+        /* Multiboot2 header length. */
+        .long   .Lmultiboot2_header_end - .Lmultiboot2_header
+        /* Multiboot2 header checksum. */
+        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
+                        (.Lmultiboot2_header_end - .Lmultiboot2_header))
+
+        /* Multiboot2 information request tag. */
+        mb2ht_init MB2_HT(INFORMATION_REQUEST), MB2_HT(REQUIRED), \
+                   MB2_TT(BASIC_MEMINFO), MB2_TT(MMAP)
+
+        /* Align modules at page boundry. */
+        mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
+
+        /* Console flags tag. */
+        mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
+                   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
+
+        /* Framebuffer tag. */
+        mb2ht_init MB2_HT(FRAMEBUFFER), MB2_HT(OPTIONAL), \
+                   0, /* Number of the columns - no preference. */ \
+                   0, /* Number of the lines - no preference. */ \
+                   0  /* Number of bits per pixel - no preference. */
+
+        /* Multiboot2 header end tag. */
+        mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
+.Lmultiboot2_header_end:
+
         .section .init.rodata, "a", @progbits
         .align 4
 
@@ -82,10 +141,48 @@ __start:
         mov     %ecx,%es
         mov     %ecx,%ss
 
-        /* Check for Multiboot bootloader */
+        /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
+        xor     %edx,%edx
+
+        /* Check for Multiboot2 bootloader. */
+        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+        je      multiboot2_proto
+
+        /* Check for Multiboot bootloader. */
         cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
         jne     not_multiboot
 
+        /* Get mem_lower from Multiboot information. */
+        testb   $MBI_MEMLIMITS,MB_flags(%ebx)
+
+        /* Not available? BDA value will be fine. */
+        cmovnz  MB_mem_lower(%ebx),%edx
+        jmp     trampoline_setup
+
+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,MB2_tag_type(%ecx)
+        jne     1f
+
+        mov     MB2_mem_lower(%ecx),%edx
+        jmp     trampoline_setup
+
+1:
+        /* Is it the end of Multiboot2 information? */
+        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
+        je      trampoline_setup
+
+        /* 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
+
+trampoline_setup:
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -100,9 +197,6 @@ __start:
          * Compare the value in the BDA with the information from the
          * multiboot structure (if available) and use the smallest.
          */
-        testb   $MBI_MEMLIMITS,(%ebx)
-        jz      2f                  /* not available? BDA value will be fine */
-        mov     MB_mem_lower(%ebx),%edx
         cmp     $0x100,%edx         /* is the multiboot value too small? */
         jb      2f                  /* if so, do not use it */
         shl     $10-4,%edx
@@ -119,10 +213,11 @@ __start:
 
         /* Save the Multiboot info struct (after relocation) for later use. */
         mov     $sym_phys(cpu0_stack)+1024,%esp
+        push    %eax                /* Multiboot magic. */
         push    %ebx                /* Multiboot information address. */
         push    %ecx                /* Boot trampoline address. */
         call    reloc
-        add     $8,%esp             /* Remove reloc() args from stack. */
+        add     $12,%esp            /* Remove reloc() args from stack. */
         mov     %eax,sym_phys(multiboot_ptr)
 
         /* Initialize BSS (no nasty surprises!). */
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index feb1d72..41b1cc0 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -5,15 +5,18 @@
  * and modules. This is most easily done early with paging disabled.
  *
  * Copyright (c) 2009, Citrix Systems, Inc.
+ * Copyright (c) 2013, 2014, 2015 Oracle Co.
  *
  * Authors:
  *    Keir Fraser <keir@xen.org>
+ *    Daniel Kiper <daniel.kiper@oracle.com>
  */
 
 /*
  * This entry point is entered from xen/arch/x86/boot/head.S with:
  *   - 0x4(%esp) = BOOT_TRAMPOLINE_ADDRESS,
- *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS.
+ *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
+ *   - 0xc(%esp) = MULTIBOOT_MAGIC.
  */
 asm (
     "    .text                         \n"
@@ -25,10 +28,12 @@ asm (
     "1:  pop  %ecx                     \n"
     "    mov  0x8(%ebp),%eax           \n"
     "    mov  %eax,alloc-1b(%ecx)      \n"
+    "    mov  0x10(%ebp),%eax          \n"
+    "    push %eax                     \n"
     "    mov  0xc(%ebp),%eax           \n"
     "    push %eax                     \n"
     "    call reloc                    \n"
-    "    add  $4,%esp                  \n"
+    "    add  $8,%esp                  \n"
     "    pop  %ebp                     \n"
     "    ret                           \n"
     );
@@ -43,7 +48,15 @@ asm (
     );
 
 typedef unsigned int u32;
+typedef unsigned long long u64;
+
 #include "../../../include/xen/multiboot.h"
+#include "../../../include/xen/multiboot2.h"
+
+#define ALIGN_UP(addr, align) \
+                (((addr) + (typeof(addr))(align) - 1) & ~((typeof(addr))(align) - 1))
+
+#define get_mb2_data(tag, type, member) (((type *)(tag))->member)
 
 static u32 alloc_mem(u32 bytes)
 {
@@ -61,6 +74,11 @@ static u32 alloc_mem(u32 bytes)
     return s;
 }
 
+static void zero_mem(u32 s, u32 bytes)
+{
+    asm volatile("rep stosb" : "+D" (s), "+c" (bytes) : "a" (0) : "memory");
+}
+
 static u32 copy_mem(u32 src, u32 bytes)
 {
     u32 dst, dst_asm;
@@ -86,12 +104,12 @@ static u32 copy_string(u32 src)
     return copy_mem(src, p - src + 1);
 }
 
-multiboot_info_t *reloc(u32 mbi_in)
+static multiboot_info_t *mbi_mbi(void *mbi_in)
 {
     int i;
     multiboot_info_t *mbi_out;
 
-    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));
+    mbi_out = (multiboot_info_t *)copy_mem((u32)mbi_in, sizeof(*mbi_out));
 
     if ( mbi_out->flags & MBI_CMDLINE )
         mbi_out->cmdline = copy_string(mbi_out->cmdline);
@@ -127,3 +145,123 @@ multiboot_info_t *reloc(u32 mbi_in)
 
     return mbi_out;
 }
+
+static multiboot_info_t *mbi2_mbi(void *mbi_in)
+{
+    /* Do not complain that mbi_out_mods is not initialized. */
+    module_t *mbi_out_mods = (module_t *)0;
+    memory_map_t *mmap_dst;
+    multiboot2_memory_map_t *mmap_src;
+    multiboot2_tag_t *tag;
+    multiboot_info_t *mbi_out;
+    u32 ptr;
+    unsigned int i, mod_idx = 0;
+
+    mbi_out = (multiboot_info_t *)alloc_mem(sizeof(*mbi_out));
+    zero_mem((u32)mbi_out, sizeof(*mbi_out));
+
+    /* Skip Multiboot2 information fixed part. */
+    tag = mbi_in + sizeof(multiboot2_fixed_t);
+
+    for ( ; ; )
+    {
+        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
+            ++mbi_out->mods_count;
+        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
+        {
+            mbi_out->flags = MBI_MODULES;
+            mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(module_t));
+            mbi_out_mods = (module_t *)mbi_out->mods_addr;
+            break;
+        }
+
+        /* Go to next Multiboot2 information tag. */
+        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
+
+        /* Check Multiboot2 information total size just in case. */
+	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
+            break;
+    }
+
+    /* Skip Multiboot2 information fixed part. */
+    tag = mbi_in + sizeof(multiboot2_fixed_t);
+
+    for ( ; ; )
+    {
+        switch ( tag->type )
+        {
+        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
+            mbi_out->flags |= MBI_LOADERNAME;
+            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);
+            mbi_out->boot_loader_name = copy_string(ptr);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_CMDLINE:
+            mbi_out->flags |= MBI_CMDLINE;
+            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);
+            mbi_out->cmdline = copy_string(ptr);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
+            mbi_out->flags |= MBI_MEMLIMITS;
+            mbi_out->mem_lower = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_lower);
+            mbi_out->mem_upper = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_upper);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MMAP:
+            mbi_out->flags |= MBI_MEMMAP;
+            mbi_out->mmap_length = get_mb2_data(tag, multiboot2_tag_mmap_t, size);
+            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
+            mbi_out->mmap_length += sizeof(((multiboot2_tag_mmap_t){0}).entries);
+            mbi_out->mmap_length /= get_mb2_data(tag, multiboot2_tag_mmap_t, entry_size);
+            mbi_out->mmap_length *= sizeof(memory_map_t);
+
+            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);
+
+            mmap_src = get_mb2_data(tag, multiboot2_tag_mmap_t, entries);
+            mmap_dst = (memory_map_t *)mbi_out->mmap_addr;
+
+            for ( i = 0; i < mbi_out->mmap_length / sizeof(memory_map_t); ++i )
+            {
+                mmap_dst[i].size = sizeof(memory_map_t);
+                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
+                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
+                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
+                mmap_dst[i].length_low = (u32)mmap_src[i].len;
+                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
+                mmap_dst[i].type = mmap_src[i].type;
+            }
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MODULE:
+            mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, multiboot2_tag_module_t, mod_start);
+            mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, multiboot2_tag_module_t, mod_end);
+            ptr = (u32)get_mb2_data(tag, multiboot2_tag_module_t, cmdline);
+            mbi_out_mods[mod_idx].string = copy_string(ptr);
+            mbi_out_mods[mod_idx].reserved = 0;
+            ++mod_idx;
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_END:
+            return mbi_out;
+
+        default:
+            break;
+        }
+
+        /* Go to next Multiboot2 information tag. */
+        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
+
+        /* Check Multiboot2 information total size just in case. */
+	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
+            return mbi_out;
+    }
+}
+
+static multiboot_info_t __attribute__((__used__)) *reloc(void *mbi_in, u32 mb_magic)
+{
+    if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC )
+        return mbi2_mbi(mbi_in);
+    else
+        return mbi_mbi(mbi_in);
+}
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index 447c650..b926082 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -13,6 +13,7 @@
 #include <asm/fixmap.h>
 #include <asm/hardirq.h>
 #include <xen/multiboot.h>
+#include <xen/multiboot2.h>
 
 #define DEFINE(_sym, _val)                                                 \
     asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
@@ -166,4 +167,10 @@ void __dummy__(void)
     OFFSET(MB_flags, multiboot_info_t, flags);
     OFFSET(MB_cmdline, multiboot_info_t, cmdline);
     OFFSET(MB_mem_lower, multiboot_info_t, mem_lower);
+    BLANK();
+
+    DEFINE(MB2_fixed_sizeof, sizeof(multiboot2_fixed_t));
+    OFFSET(MB2_tag_type, multiboot2_tag_t, type);
+    OFFSET(MB2_tag_size, multiboot2_tag_t, size);
+    OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
 }
diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
new file mode 100644
index 0000000..09ee64e
--- /dev/null
+++ b/xen/include/xen/multiboot2.h
@@ -0,0 +1,169 @@
+/*
+ *  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  multiboot2.h - Multiboot 2 header file.
+ *
+ *  Based on grub-2.00/include/multiboot2.h file.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to
+ *  deal in the Software without restriction, including without limitation the
+ *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ *  sell copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
+ *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __MULTIBOOT2_H__
+#define __MULTIBOOT2_H__
+
+/* The magic field should contain this.  */
+#define MULTIBOOT2_HEADER_MAGIC			0xe85250d6
+
+/* This should be in %eax on x86 architecture.  */
+#define MULTIBOOT2_BOOTLOADER_MAGIC		0x36d76289
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT2_SEARCH			32768
+
+/* Multiboot 2 header alignment. */
+#define MULTIBOOT2_HEADER_ALIGN			8
+
+/* Alignment of multiboot 2 modules.  */
+#define MULTIBOOT2_MOD_ALIGN			0x00001000
+
+/* Alignment of the multiboot 2 info structure.  */
+#define MULTIBOOT2_INFO_ALIGN			0x00000008
+
+/* Multiboot 2 architectures. */
+#define MULTIBOOT2_ARCHITECTURE_I386	0
+#define MULTIBOOT2_ARCHITECTURE_MIPS32	4
+
+/* Header tag types. */
+#define MULTIBOOT2_HEADER_TAG_END			0
+#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST	1
+#define MULTIBOOT2_HEADER_TAG_ADDRESS			2
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS		3
+#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS		4
+#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER		5
+#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN		6
+#define MULTIBOOT2_HEADER_TAG_EFI_BS			7
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32	8
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64	9
+
+/* Header tag flags. */
+#define MULTIBOOT2_HEADER_TAG_REQUIRED	0
+#define MULTIBOOT2_HEADER_TAG_OPTIONAL	1
+
+/* Header console tag console_flags. */
+#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED	1
+#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED	2
+
+/* Flags set in the 'flags' member of the multiboot header.  */
+#define MULTIBOOT2_TAG_TYPE_END			0
+#define MULTIBOOT2_TAG_TYPE_CMDLINE		1
+#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME	2
+#define MULTIBOOT2_TAG_TYPE_MODULE		3
+#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO	4
+#define MULTIBOOT2_TAG_TYPE_BOOTDEV		5
+#define MULTIBOOT2_TAG_TYPE_MMAP		6
+#define MULTIBOOT2_TAG_TYPE_VBE			7
+#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER		8
+#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS	9
+#define MULTIBOOT2_TAG_TYPE_APM			10
+#define MULTIBOOT2_TAG_TYPE_EFI32		11
+#define MULTIBOOT2_TAG_TYPE_EFI64		12
+#define MULTIBOOT2_TAG_TYPE_SMBIOS		13
+#define MULTIBOOT2_TAG_TYPE_ACPI_OLD		14
+#define MULTIBOOT2_TAG_TYPE_ACPI_NEW		15
+#define MULTIBOOT2_TAG_TYPE_NETWORK		16
+#define MULTIBOOT2_TAG_TYPE_EFI_MMAP		17
+#define MULTIBOOT2_TAG_TYPE_EFI_BS		18
+#define MULTIBOOT2_TAG_TYPE_EFI32_IH		19
+#define MULTIBOOT2_TAG_TYPE_EFI64_IH		20
+
+/* Multiboot 2 tag alignment. */
+#define MULTIBOOT2_TAG_ALIGN			8
+
+/* Memory types. */
+#define MULTIBOOT2_MEMORY_AVAILABLE		1
+#define MULTIBOOT2_MEMORY_RESERVED		2
+#define MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE	3
+#define MULTIBOOT2_MEMORY_NVS			4
+#define MULTIBOOT2_MEMORY_BADRAM		5
+
+/* Framebuffer types. */
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED	0
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB		1
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT	2
+
+#ifndef __ASSEMBLY__
+typedef struct {
+    u32 total_size;
+    u32 reserved;
+} multiboot2_fixed_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+} multiboot2_tag_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    char string[0];
+} multiboot2_tag_string_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    u32 mem_lower;
+    u32 mem_upper;
+} multiboot2_tag_basic_meminfo_t;
+
+typedef struct __packed {
+    u64 addr;
+    u64 len;
+    u32 type;
+    u32 zero;
+} multiboot2_memory_map_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    u32 entry_size;
+    u32 entry_version;
+    multiboot2_memory_map_t entries[0];
+} multiboot2_tag_mmap_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    u64 pointer;
+} multiboot2_tag_efi64_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    u64 pointer;
+} multiboot2_tag_efi64_ih_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
+    u32 mod_start;
+    u32 mod_end;
+    char cmdline[0];
+} multiboot2_tag_module_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MULTIBOOT2_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 09/23] efi: create efi_enabled()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (7 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 08/23] x86: add multiboot2 protocol support Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:20   ` Konrad Rzeszutek Wilk
  2015-08-20 15:18   ` Jan Beulich
  2015-07-20 14:29 ` [PATCH v2 10/23] efi: build xen.gz with EFI code Daniel Kiper
                   ` (28 subsequent siblings)
  37 siblings, 2 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

We need more fine grained knowledge about EFI environment and check
for EFI platform and EFI loader separately to properly support
multiboot2 protocol. In general Xen loaded by this protocol uses
memory mappings and loaded modules in similar way to Xen loaded
by multiboot (v1) protocol. Hence, create efi_enabled() which
checks available features in efi.flags. This patch only defines
EFI_PLATFORM feature which is equal to old efi_enabled == 1.
Following patch will define EFI_LOADER feature accordingly.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/dmi_scan.c    |    4 ++--
 xen/arch/x86/domain_page.c |    2 +-
 xen/arch/x86/efi/stub.c    |   11 ++++++++---
 xen/arch/x86/mpparse.c     |    4 ++--
 xen/arch/x86/setup.c       |   10 +++++-----
 xen/arch/x86/shutdown.c    |    2 +-
 xen/arch/x86/time.c        |    2 +-
 xen/arch/x86/xen.lds.S     |    2 --
 xen/common/efi/boot.c      |    4 ++++
 xen/common/efi/runtime.c   |   17 +++++++----------
 xen/drivers/acpi/osl.c     |    2 +-
 xen/include/xen/efi.h      |   16 ++++++++++++++--
 12 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index 269168c..95c5a77 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -229,7 +229,7 @@ const char *__init dmi_get_table(paddr_t *base, u32 *len)
 {
 	static unsigned int __initdata instance;
 
-	if (efi_enabled) {
+	if (efi_enabled(EFI_PLATFORM)) {
 		if (efi_smbios3_size && !(instance & 1)) {
 			*base = efi_smbios3_address;
 			*len = efi_smbios3_size;
@@ -693,7 +693,7 @@ static void __init dmi_decode(struct dmi_header *dm)
 
 void __init dmi_scan_machine(void)
 {
-	if ((!efi_enabled ? dmi_iterate(dmi_decode) :
+	if ((!efi_enabled(EFI_PLATFORM) ? dmi_iterate(dmi_decode) :
 	                    dmi_efi_iterate(dmi_decode)) == 0)
  		dmi_check_system(dmi_blacklist);
 	else
diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
index d86f8fe..fdf0d8a 100644
--- a/xen/arch/x86/domain_page.c
+++ b/xen/arch/x86/domain_page.c
@@ -36,7 +36,7 @@ static inline struct vcpu *mapcache_current_vcpu(void)
      * domain's page tables but current may point at another domain's VCPU.
      * Return NULL as though current is not properly set up yet.
      */
-    if ( efi_enabled && efi_rs_using_pgtables() )
+    if ( efi_enabled(EFI_PLATFORM) && efi_rs_using_pgtables() )
         return NULL;
 
     /*
diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
index 07c2bd0..c5ae369 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -4,9 +4,14 @@
 #include <xen/lib.h>
 #include <asm/page.h>
 
-#ifndef efi_enabled
-const bool_t efi_enabled = 0;
-#endif
+struct efi __read_mostly efi = {
+	.flags   = 0, /* Initialized later. */
+	.acpi    = EFI_INVALID_TABLE_ADDR,
+	.acpi20  = EFI_INVALID_TABLE_ADDR,
+	.mps     = EFI_INVALID_TABLE_ADDR,
+	.smbios  = EFI_INVALID_TABLE_ADDR,
+	.smbios3 = EFI_INVALID_TABLE_ADDR
+};
 
 void __init efi_init_memory(void) { }
 
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 8609f4a..5223579 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -557,7 +557,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 
 static __init void efi_unmap_mpf(void)
 {
-	if (efi_enabled)
+	if (efi_enabled(EFI_PLATFORM))
 		clear_fixmap(FIX_EFI_MPF);
 }
 
@@ -715,7 +715,7 @@ void __init find_smp_config (void)
 {
 	unsigned int address;
 
-	if (efi_enabled) {
+	if (efi_enabled(EFI_PLATFORM)) {
 		efi_check_config();
 		return;
 	}
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index ff34670..bce708c 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -444,8 +444,8 @@ static void __init parse_video_info(void)
 {
     struct boot_video_info *bvi = &bootsym(boot_vid_info);
 
-    /* The EFI loader fills vga_console_info directly. */
-    if ( efi_enabled )
+    /* vga_console_info is filled directly on EFI platform. */
+    if ( efi_enabled(EFI_PLATFORM) )
         return;
 
     if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
@@ -695,7 +695,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
         panic("dom0 kernel not specified. Check bootloader configuration.");
 
-    if ( efi_enabled )
+    if ( efi_enabled(EFI_PLATFORM) )
     {
         set_pdx_range(xen_phys_start >> PAGE_SHIFT,
                       (xen_phys_start + BOOTSTRAP_MAP_BASE) >> PAGE_SHIFT);
@@ -806,7 +806,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * we can relocate the dom0 kernel and other multiboot modules. Also, on
      * x86/64, we relocate Xen to higher memory.
      */
-    for ( i = 0; !efi_enabled && i < mbi->mods_count; i++ )
+    for ( i = 0; !efi_enabled(EFI_PLATFORM) && i < mbi->mods_count; i++ )
     {
         if ( mod[i].mod_start & (PAGE_SIZE - 1) )
             panic("Bootloader didn't honor module alignment request.");
@@ -994,7 +994,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen.");
-    reserve_e820_ram(&boot_e820, efi_enabled ? mbi->mem_upper : __pa(&_start),
+    reserve_e820_ram(&boot_e820, efi_enabled(EFI_PLATFORM) ? mbi->mem_upper : __pa(&_start),
                      __pa(&_end));
 
     /* Late kexec reservation (dynamic start address). */
diff --git a/xen/arch/x86/shutdown.c b/xen/arch/x86/shutdown.c
index 0e1499d..79dcd16 100644
--- a/xen/arch/x86/shutdown.c
+++ b/xen/arch/x86/shutdown.c
@@ -116,7 +116,7 @@ void machine_halt(void)
 static void default_reboot_type(void)
 {
     if ( reboot_type == BOOT_INVALID )
-        reboot_type = efi_enabled ? BOOT_EFI
+        reboot_type = efi_enabled(EFI_PLATFORM) ? BOOT_EFI
                                   : acpi_disabled ? BOOT_KBD
                                                   : BOOT_ACPI;
 }
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index bbb7e6c..11e7e11 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -690,7 +690,7 @@ static unsigned long get_cmos_time(void)
     static bool_t __read_mostly cmos_rtc_probe;
     boolean_param("cmos-rtc-probe", cmos_rtc_probe);
 
-    if ( efi_enabled )
+    if ( efi_enabled(EFI_PLATFORM) )
     {
         res = efi_get_time();
         if ( res )
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 3e1f2af..87f3e83 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -191,8 +191,6 @@ SECTIONS
   .pad : {
     . = ALIGN(MB(16));
   } :text
-#else
-  efi = .;
 #endif
 
   /* Sections to be discarded */
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 75a939f..1f188fe 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -717,6 +717,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     char *option_str;
     bool_t use_cfg_file;
 
+#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
+    set_bit(EFI_PLATFORM, &efi.flags);
+#endif
+
     efi_ih = ImageHandle;
     efi_bs = SystemTable->BootServices;
     efi_bs_revision = efi_bs->Hdr.Revision;
diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index ae87557..aa064e7 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -10,14 +10,10 @@ DEFINE_XEN_GUEST_HANDLE(CHAR16);
 
 #ifndef COMPAT
 
-#ifdef CONFIG_ARM  /* Disabled until runtime services implemented */
-const bool_t efi_enabled = 0;
-#else
+#ifndef CONFIG_ARM
 # include <asm/i387.h>
 # include <asm/xstate.h>
 # include <public/platform.h>
-
-const bool_t efi_enabled = 1;
 #endif
 
 unsigned int __read_mostly efi_num_ct;
@@ -42,11 +38,12 @@ UINT64 __read_mostly efi_boot_remain_var_store_size;
 UINT64 __read_mostly efi_boot_max_var_size;
 
 struct efi __read_mostly efi = {
-	.acpi   = EFI_INVALID_TABLE_ADDR,
-	.acpi20 = EFI_INVALID_TABLE_ADDR,
-	.mps    = EFI_INVALID_TABLE_ADDR,
-	.smbios = EFI_INVALID_TABLE_ADDR,
-	.smbios3 = EFI_INVALID_TABLE_ADDR,
+	.flags   = 0, /* Initialized later. */
+	.acpi    = EFI_INVALID_TABLE_ADDR,
+	.acpi20  = EFI_INVALID_TABLE_ADDR,
+	.mps     = EFI_INVALID_TABLE_ADDR,
+	.smbios  = EFI_INVALID_TABLE_ADDR,
+	.smbios3 = EFI_INVALID_TABLE_ADDR
 };
 
 const struct efi_pci_rom *__read_mostly efi_pci_roms;
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
index 4c09859..f4f6628 100644
--- a/xen/drivers/acpi/osl.c
+++ b/xen/drivers/acpi/osl.c
@@ -66,7 +66,7 @@ void __init acpi_os_vprintf(const char *fmt, va_list args)
 
 acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
-	if (efi_enabled) {
+	if (efi_enabled(EFI_PLATFORM)) {
 		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
 			return efi.acpi20;
 		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
index e74dad1..318bbec 100644
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -2,15 +2,17 @@
 #define __XEN_EFI_H__
 
 #ifndef __ASSEMBLY__
+#include <xen/bitops.h>
 #include <xen/types.h>
 #endif
 
-extern const bool_t efi_enabled;
-
 #define EFI_INVALID_TABLE_ADDR (~0UL)
 
+#define EFI_PLATFORM	0
+
 /* Add fields here only if they need to be referenced from non-EFI code. */
 struct efi {
+    unsigned long flags;
     unsigned long mps;          /* MPS table */
     unsigned long acpi;         /* ACPI table (IA64 ext 0.71) */
     unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
@@ -40,6 +42,16 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *);
 int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *);
 int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *);
 
+/*
+ * Test whether the above EFI_* bits are enabled.
+ *
+ * Stolen from Linux Kernel.
+ */
+static inline bool_t efi_enabled(int feature)
+{
+    return test_bit(feature, &efi.flags) != 0;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __XEN_EFI_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (8 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 09/23] efi: create efi_enabled() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 11/23] efi: split out efi_init() Daniel Kiper
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Build xen.gz with EFI code. We need this to support multiboot2
protocol on EFI platforms.

If we wish to load not ELF file using multiboot (v1) or multiboot2 then
it must contain "linear" (or "flat") representation of code and data.
Currently, PE file contains many sections which are not "linear" (one
after another without any holes) or even do not have representation
in a file (e.g. BSS). In theory there is a chance that we could build
proper PE file using current build system. However, it means that
xen.efi further diverge from xen ELF file (in terms of contents and
build method). ELF have all needed properties. So, it means that this
is good starting point for further development. Additionally, I think
that this is also good starting point for further xen.efi code and
build optimizations. It looks that there is a chance that finally we
can generate xen.efi directly from xen ELF using just simple objcopy.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - build EFI code only if it is supported in a given build environment
     (suggested by Jan Beulich).
---
 xen/arch/x86/Makefile     |   13 +++++--------
 xen/arch/x86/efi/Makefile |   16 +++++++++-------
 xen/arch/x86/mm.c         |    3 ++-
 xen/common/efi/runtime.c  |    6 ++++++
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 5f24951..0335445 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -80,7 +80,7 @@ ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in
 
 ifeq ($(lto),y)
 # Gather all LTO objects together
-prelink_lto.o: $(ALL_OBJS)
+prelink_lto.o: $(ALL_OBJS) efi/relocs-dummy.o
 	$(LD_LTO) -r -o $@ $^
 
 prelink-efi_lto.o: $(ALL_OBJS) efi/runtime.o efi/compat.o
@@ -90,14 +90,14 @@ prelink-efi_lto.o: $(ALL_OBJS) efi/runtime.o efi/compat.o
 prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o
 	$(LD) $(LDFLAGS) -r -o $@ $^
 
-prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink-efi_lto.o efi/boot.init.o
+prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink-efi_lto.o
 	$(guard) $(LD) $(LDFLAGS) -r -o $@ $^
 else
-prelink.o: $(ALL_OBJS)
+prelink.o: $(ALL_OBJS) efi/relocs-dummy.o
 	$(LD) $(LDFLAGS) -r -o $@ $^
 
-prelink-efi.o: $(ALL_OBJS) efi/boot.init.o efi/runtime.o efi/compat.o
-	$(guard) $(LD) $(LDFLAGS) -r -o $@ $(filter-out %/efi/built_in.o,$^)
+prelink-efi.o: $(ALL_OBJS)
+	$(guard) $(LD) $(LDFLAGS) -r -o $@ $^
 endif
 
 $(BASEDIR)/common/symbols-dummy.o:
@@ -146,9 +146,6 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol
 	if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi
 	rm -f $(@D)/.$(@F).[0-9]*
 
-efi/boot.init.o efi/runtime.o efi/compat.o: $(BASEDIR)/arch/x86/efi/built_in.o
-efi/boot.init.o efi/runtime.o efi/compat.o: ;
-
 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c
 	$(CC) $(filter-out -flto,$(CFLAGS)) -S -o $@ $<
 
diff --git a/xen/arch/x86/efi/Makefile b/xen/arch/x86/efi/Makefile
index 1daa7ac..b1e8883 100644
--- a/xen/arch/x86/efi/Makefile
+++ b/xen/arch/x86/efi/Makefile
@@ -1,14 +1,16 @@
 CFLAGS += -fshort-wchar
 
-obj-y += stub.o
-
-create = test -e $(1) || touch -t 199901010000 $(1)
-
 efi := $(filter y,$(x86_64)$(shell rm -f disabled))
 efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
 efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
-efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
+efi := $(if $(efi),$(shell rm disabled)y)
 
-extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
+extra-y += relocs-dummy.o
 
-stub.o: $(extra-y)
+ifeq ($(efi),y)
+obj-y += boot.init.o
+obj-y += compat.o
+obj-y += runtime.o
+else
+obj-y += stub.o
+endif
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 342414f..cef2eb6 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -344,7 +344,8 @@ void __init arch_init_memory(void)
 
     subarch_init_memory();
 
-    efi_init_memory();
+    if ( efi_enabled(EFI_PLATFORM) )
+        efi_init_memory();
 
     mem_sharing_init();
 
diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index aa064e7..3eb21c1 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -167,6 +167,9 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
 {
     unsigned int i, n;
 
+    if ( !efi_enabled(EFI_PLATFORM) )
+        return -EOPNOTSUPP;
+
     switch ( idx )
     {
     case XEN_FW_EFI_VERSION:
@@ -301,6 +304,9 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
     EFI_STATUS status = EFI_NOT_STARTED;
     int rc = 0;
 
+    if ( !efi_enabled(EFI_PLATFORM) )
+        return -EOPNOTSUPP;
+
     switch ( op->function )
     {
     case XEN_EFI_get_time:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 11/23] efi: split out efi_init()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (9 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 10/23] efi: build xen.gz with EFI code Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:25   ` Konrad Rzeszutek Wilk
  2015-07-20 14:29 ` [PATCH v2 12/23] efi: split out efi_console_set_mode() Daniel Kiper
                   ` (26 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which initializes basic EFI variables. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 1f188fe..6f327cd 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -595,6 +595,22 @@ static char *__init get_value(const struct file *cfg, const char *section,
     return NULL;
 }
 
+static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+    efi_ih = ImageHandle;
+    efi_bs = SystemTable->BootServices;
+    efi_bs_revision = efi_bs->Hdr.Revision;
+    efi_rs = SystemTable->RuntimeServices;
+    efi_ct = SystemTable->ConfigurationTable;
+    efi_num_ct = SystemTable->NumberOfTableEntries;
+    efi_version = SystemTable->Hdr.Revision;
+    efi_fw_vendor = SystemTable->FirmwareVendor;
+    efi_fw_revision = SystemTable->FirmwareRevision;
+
+    StdOut = SystemTable->ConOut;
+    StdErr = SystemTable->StdErr ?: StdOut;
+}
+
 static void __init setup_efi_pci(void)
 {
     EFI_STATUS status;
@@ -721,18 +737,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     set_bit(EFI_PLATFORM, &efi.flags);
 #endif
 
-    efi_ih = ImageHandle;
-    efi_bs = SystemTable->BootServices;
-    efi_bs_revision = efi_bs->Hdr.Revision;
-    efi_rs = SystemTable->RuntimeServices;
-    efi_ct = SystemTable->ConfigurationTable;
-    efi_num_ct = SystemTable->NumberOfTableEntries;
-    efi_version = SystemTable->Hdr.Revision;
-    efi_fw_vendor = SystemTable->FirmwareVendor;
-    efi_fw_revision = SystemTable->FirmwareRevision;
+    efi_init(ImageHandle, SystemTable);
 
-    StdOut = SystemTable->ConOut;
-    StdErr = SystemTable->StdErr ?: StdOut;
     use_cfg_file = efi_arch_use_config_file(SystemTable);
 
     status = efi_bs->HandleProtocol(ImageHandle, &loaded_image_guid,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 12/23] efi: split out efi_console_set_mode()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (10 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 11/23] efi: split out efi_init() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 13/23] efi: split out efi_get_gop() Daniel Kiper
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which sets console mode. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 6f327cd..4614146 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -611,6 +611,25 @@ static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTabl
     StdErr = SystemTable->StdErr ?: StdOut;
 }
 
+static void __init efi_console_set_mode(void)
+{
+    UINTN cols, rows, size;
+    unsigned int best, i;
+
+    for ( i = 0, size = 0, best = StdOut->Mode->Mode;
+          i < StdOut->Mode->MaxMode; ++i )
+    {
+        if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
+             cols * rows > size )
+        {
+            size = cols * rows;
+            best = i;
+        }
+    }
+    if ( best != StdOut->Mode->Mode )
+        StdOut->SetMode(StdOut, best);
+}
+
 static void __init setup_efi_pci(void)
 {
     EFI_STATUS status;
@@ -799,23 +818,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         }
 
         if ( !base_video )
-        {
-            unsigned int best;
-            UINTN cols, rows, size;
-
-            for ( i = 0, size = 0, best = StdOut->Mode->Mode;
-                  i < StdOut->Mode->MaxMode; ++i )
-            {
-                if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
-                     cols * rows > size )
-                {
-                    size = cols * rows;
-                    best = i;
-                }
-            }
-            if ( best != StdOut->Mode->Mode )
-                StdOut->SetMode(StdOut, best);
-        }
+            efi_console_set_mode();
     }
 
     PrintStr(L"Xen " __stringify(XEN_VERSION) "." __stringify(XEN_SUBVERSION)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 13/23] efi: split out efi_get_gop()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (11 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 12/23] efi: split out efi_console_set_mode() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 14/23] efi: split out efi_find_gop_mode() Daniel Kiper
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which gets pointer to GOP device. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   59 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 4614146..6fad230 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -630,6 +630,41 @@ static void __init efi_console_set_mode(void)
         StdOut->SetMode(StdOut, best);
 }
 
+static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
+{
+    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
+    EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+    EFI_HANDLE *handles;
+    EFI_STATUS status;
+    UINTN info_size, size = 0;
+    static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+    unsigned int i;
+
+    status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
+    if ( status == EFI_BUFFER_TOO_SMALL )
+        status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
+    if ( !EFI_ERROR(status) )
+        status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
+                                      handles);
+    if ( EFI_ERROR(status) )
+        size = 0;
+    for ( i = 0; i < size / sizeof(*handles); ++i )
+    {
+        status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
+        if ( EFI_ERROR(status) )
+            continue;
+        status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
+        if ( !EFI_ERROR(status) )
+            break;
+    }
+    if ( handles )
+        efi_bs->FreePool(handles);
+    if ( EFI_ERROR(status) )
+        gop = NULL;
+
+    return gop;
+}
+
 static void __init setup_efi_pci(void)
 {
     EFI_STATUS status;
@@ -736,14 +771,12 @@ void EFIAPI __init noreturn
 efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 {
     static EFI_GUID __initdata loaded_image_guid = LOADED_IMAGE_PROTOCOL;
-    static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
     static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
     EFI_LOADED_IMAGE *loaded_image;
     EFI_STATUS status;
     unsigned int i, argc;
     CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
     UINTN map_key, info_size, gop_mode = ~0;
-    EFI_HANDLE *handles = NULL;
     EFI_SHIM_LOCK_PROTOCOL *shim_lock;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
     EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
@@ -837,27 +870,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                                &cols, &rows) == EFI_SUCCESS )
             efi_arch_console_init(cols, rows);
 
-        status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
-        if ( status == EFI_BUFFER_TOO_SMALL )
-            status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
-        if ( !EFI_ERROR(status) )
-            status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
-                                          handles);
-        if ( EFI_ERROR(status) )
-            size = 0;
-        for ( i = 0; i < size / sizeof(*handles); ++i )
-        {
-            status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
-            if ( EFI_ERROR(status) )
-                continue;
-            status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
-            if ( !EFI_ERROR(status) )
-                break;
-        }
-        if ( handles )
-            efi_bs->FreePool(handles);
-        if ( EFI_ERROR(status) )
-            gop = NULL;
+        gop = efi_get_gop();
 
         /* Get the file system interface. */
         dir_handle = get_parent_handle(loaded_image, &file_name);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 14/23] efi: split out efi_find_gop_mode()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (12 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 13/23] efi: split out efi_get_gop() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:31   ` Konrad Rzeszutek Wilk
  2015-08-20 15:48   ` Jan Beulich
  2015-07-20 14:29 ` [PATCH v2 15/23] efi: split out efi_tables() Daniel Kiper
                   ` (23 subsequent siblings)
  37 siblings, 2 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which finds suitable GOP mode. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   94 ++++++++++++++++++++++++++++---------------------
 1 file changed, 54 insertions(+), 40 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 6fad230..8d16470 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -665,6 +665,58 @@ static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
     return gop;
 }
 
+static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
+                                      UINTN cols, UINTN rows, UINTN depth)
+{
+    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
+    EFI_STATUS status;
+    UINTN gop_mode = ~0, info_size, size;
+    unsigned int i;
+
+    if ( !gop )
+        return gop_mode;
+
+    for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
+    {
+        unsigned int bpp = 0;
+
+        status = gop->QueryMode(gop, i, &info_size, &mode_info);
+        if ( EFI_ERROR(status) )
+            continue;
+        switch ( mode_info->PixelFormat )
+        {
+        case PixelBitMask:
+            bpp = hweight32(mode_info->PixelInformation.RedMask |
+                            mode_info->PixelInformation.GreenMask |
+                            mode_info->PixelInformation.BlueMask);
+            break;
+        case PixelRedGreenBlueReserved8BitPerColor:
+        case PixelBlueGreenRedReserved8BitPerColor:
+            bpp = 24;
+            break;
+        default:
+            continue;
+        }
+        if ( cols == mode_info->HorizontalResolution &&
+             rows == mode_info->VerticalResolution &&
+             (!depth || bpp == depth) )
+        {
+            gop_mode = i;
+            break;
+        }
+        if ( !cols && !rows &&
+             mode_info->HorizontalResolution *
+             mode_info->VerticalResolution > size )
+        {
+            size = mode_info->HorizontalResolution *
+                   mode_info->VerticalResolution;
+            gop_mode = i;
+        }
+    }
+
+    return gop_mode;
+}
+
 static void __init setup_efi_pci(void)
 {
     EFI_STATUS status;
@@ -978,46 +1030,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
         dir_handle->Close(dir_handle);
 
-        if ( gop && !base_video )
-        {
-            for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
-            {
-                unsigned int bpp = 0;
-
-                status = gop->QueryMode(gop, i, &info_size, &mode_info);
-                if ( EFI_ERROR(status) )
-                    continue;
-                switch ( mode_info->PixelFormat )
-                {
-                case PixelBitMask:
-                    bpp = hweight32(mode_info->PixelInformation.RedMask |
-                                    mode_info->PixelInformation.GreenMask |
-                                    mode_info->PixelInformation.BlueMask);
-                    break;
-                case PixelRedGreenBlueReserved8BitPerColor:
-                case PixelBlueGreenRedReserved8BitPerColor:
-                    bpp = 24;
-                    break;
-                default:
-                    continue;
-                }
-                if ( cols == mode_info->HorizontalResolution &&
-                     rows == mode_info->VerticalResolution &&
-                     (!depth || bpp == depth) )
-                {
-                    gop_mode = i;
-                    break;
-                }
-                if ( !cols && !rows &&
-                     mode_info->HorizontalResolution *
-                     mode_info->VerticalResolution > size )
-                {
-                    size = mode_info->HorizontalResolution *
-                           mode_info->VerticalResolution;
-                    gop_mode = i;
-                }
-            }
-        }
+        if ( !base_video )
+            gop_mode = efi_find_gop_mode(gop, cols, rows, depth);
     }
 
     efi_arch_edd();
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 15/23] efi: split out efi_tables()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (13 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 14/23] efi: split out efi_find_gop_mode() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:32   ` Konrad Rzeszutek Wilk
  2015-07-20 14:29 ` [PATCH v2 16/23] efi: split out efi_variables() Daniel Kiper
                   ` (22 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which collects system tables data. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   61 +++++++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 8d16470..fd62125 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -717,6 +717,39 @@ static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
     return gop_mode;
 }
 
+static void __init efi_tables(void)
+{
+    unsigned int i;
+
+    /* Obtain basic table pointers. */
+    for ( i = 0; i < efi_num_ct; ++i )
+    {
+        static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
+        static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
+        static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
+        static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
+        static EFI_GUID __initdata smbios3_guid = SMBIOS3_TABLE_GUID;
+
+        if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
+	       efi.acpi20 = (long)efi_ct[i].VendorTable;
+        if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
+	       efi.acpi = (long)efi_ct[i].VendorTable;
+        if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
+	       efi.mps = (long)efi_ct[i].VendorTable;
+        if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
+	       efi.smbios = (long)efi_ct[i].VendorTable;
+        if ( match_guid(&smbios3_guid, &efi_ct[i].VendorGuid) )
+	       efi.smbios3 = (long)efi_ct[i].VendorTable;
+    }
+
+#ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
+    dmi_efi_get_table(efi.smbios != EFI_INVALID_TABLE_ADDR
+                      ? (void *)(long)efi.smbios : NULL,
+                      efi.smbios3 != EFI_INVALID_TABLE_ADDR
+                      ? (void *)(long)efi.smbios3 : NULL);
+#endif
+}
+
 static void __init setup_efi_pci(void)
 {
     EFI_STATUS status;
@@ -1039,33 +1072,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     /* XXX Collect EDID info. */
     efi_arch_cpu();
 
-    /* Obtain basic table pointers. */
-    for ( i = 0; i < efi_num_ct; ++i )
-    {
-        static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
-        static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
-        static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
-        static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
-        static EFI_GUID __initdata smbios3_guid = SMBIOS3_TABLE_GUID;
-
-        if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
-	       efi.acpi20 = (long)efi_ct[i].VendorTable;
-        if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
-	       efi.acpi = (long)efi_ct[i].VendorTable;
-        if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
-	       efi.mps = (long)efi_ct[i].VendorTable;
-        if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
-	       efi.smbios = (long)efi_ct[i].VendorTable;
-        if ( match_guid(&smbios3_guid, &efi_ct[i].VendorGuid) )
-	       efi.smbios3 = (long)efi_ct[i].VendorTable;
-    }
-
-#ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
-    dmi_efi_get_table(efi.smbios != EFI_INVALID_TABLE_ADDR
-                      ? (void *)(long)efi.smbios : NULL,
-                      efi.smbios3 != EFI_INVALID_TABLE_ADDR
-                      ? (void *)(long)efi.smbios3 : NULL);
-#endif
+    efi_tables();
 
     /* Collect PCI ROM contents. */
     setup_efi_pci();
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 16/23] efi: split out efi_variables()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (14 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 15/23] efi: split out efi_tables() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:34   ` Konrad Rzeszutek Wilk
  2015-07-20 14:29 ` [PATCH v2 17/23] efi: split out efi_set_gop_mode() Daniel Kiper
                   ` (21 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which collects variable store parameters. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index fd62125..177697a 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -837,6 +837,29 @@ static void __init setup_efi_pci(void)
     efi_bs->FreePool(handles);
 }
 
+static void __init efi_variables(void)
+{
+    EFI_STATUS status;
+
+    status = (efi_rs->Hdr.Revision >> 16) >= 2 ?
+             efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE |
+                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                       EFI_VARIABLE_RUNTIME_ACCESS,
+                                       &efi_boot_max_var_store_size,
+                                       &efi_boot_remain_var_store_size,
+                                       &efi_boot_max_var_size) :
+             EFI_INCOMPATIBLE_VERSION;
+    if ( EFI_ERROR(status) )
+    {
+        efi_boot_max_var_store_size = 0;
+        efi_boot_remain_var_store_size = 0;
+        efi_boot_max_var_size = status;
+        PrintStr(L"Warning: Could not query variable store: ");
+        DisplayUint(status, 0);
+        PrintStr(newline);
+    }
+}
+
 static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
 {
    if ( bpp < 0 )
@@ -1078,23 +1101,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     setup_efi_pci();
 
     /* Get snapshot of variable store parameters. */
-    status = (efi_rs->Hdr.Revision >> 16) >= 2 ?
-             efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE |
-                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
-                                       EFI_VARIABLE_RUNTIME_ACCESS,
-                                       &efi_boot_max_var_store_size,
-                                       &efi_boot_remain_var_store_size,
-                                       &efi_boot_max_var_size) :
-             EFI_INCOMPATIBLE_VERSION;
-    if ( EFI_ERROR(status) )
-    {
-        efi_boot_max_var_store_size = 0;
-        efi_boot_remain_var_store_size = 0;
-        efi_boot_max_var_size = status;
-        PrintStr(L"Warning: Could not query variable store: ");
-        DisplayUint(status, 0);
-        PrintStr(newline);
-    }
+    efi_variables();
 
     efi_arch_memory_setup();
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 17/23] efi: split out efi_set_gop_mode()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (15 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 16/23] efi: split out efi_variables() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 19:34   ` Konrad Rzeszutek Wilk
  2015-07-20 14:29 ` [PATCH v2 18/23] efi: split out efi_exit_boot() Daniel Kiper
                   ` (20 subsequent siblings)
  37 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which sets chosen GOP mode. We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 177697a..04b9c7e 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -860,6 +860,25 @@ static void __init efi_variables(void)
     }
 }
 
+static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode)
+{
+    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
+    EFI_STATUS status;
+    UINTN info_size;
+
+    if ( !gop )
+        return;
+
+    /* Set graphics mode. */
+    if ( gop_mode < gop->Mode->MaxMode && gop_mode != gop->Mode->Mode )
+        gop->SetMode(gop, gop_mode);
+
+    /* Get graphics and frame buffer info. */
+    status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
+    if ( !EFI_ERROR(status) )
+        efi_arch_video_init(gop, info_size, mode_info);
+}
+
 static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
 {
    if ( bpp < 0 )
@@ -887,7 +906,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     UINTN map_key, info_size, gop_mode = ~0;
     EFI_SHIM_LOCK_PROTOCOL *shim_lock;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
-    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
     union string section = { NULL }, name;
     bool_t base_video = 0, retry;
     char *option_str;
@@ -1105,18 +1123,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     efi_arch_memory_setup();
 
-    if ( gop )
-    {
-
-        /* Set graphics mode. */
-        if ( gop_mode < gop->Mode->MaxMode && gop_mode != gop->Mode->Mode )
-            gop->SetMode(gop, gop_mode);
-
-        /* Get graphics and frame buffer info. */
-        status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
-        if ( !EFI_ERROR(status) )
-            efi_arch_video_init(gop, info_size, mode_info);
-    }
+    efi_set_gop_mode(gop, gop_mode);
 
     info_size = 0;
     efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 18/23] efi: split out efi_exit_boot()
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (16 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 17/23] efi: split out efi_set_gop_mode() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 19/23] x86/efi: create new early memory allocator Daniel Kiper
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

..which gets memory map and calls ExitBootServices(). We want to re-use this
code to support multiboot2 protocol on EFI platforms.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/common/efi/boot.c |   92 +++++++++++++++++++++++++++----------------------
 1 file changed, 50 insertions(+), 42 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 04b9c7e..bf2f198 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -879,6 +879,53 @@ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop
         efi_arch_video_init(gop, info_size, mode_info);
 }
 
+static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+    EFI_STATUS status;
+    UINTN info_size = 0, map_key;
+    bool_t retry;
+
+    efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
+                         &efi_mdesc_size, &mdesc_ver);
+    info_size += 8 * efi_mdesc_size;
+    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
+    if ( !efi_memmap )
+        blexit(L"Unable to allocate memory for EFI memory map");
+
+    for ( retry = 0; ; retry = 1 )
+    {
+        efi_memmap_size = info_size;
+        status = SystemTable->BootServices->GetMemoryMap(&efi_memmap_size,
+                                                         efi_memmap, &map_key,
+                                                         &efi_mdesc_size,
+                                                         &mdesc_ver);
+        if ( EFI_ERROR(status) )
+            PrintErrMesg(L"Cannot obtain memory map", status);
+
+        efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
+                                    efi_mdesc_size, mdesc_ver);
+
+        efi_arch_pre_exit_boot();
+
+        status = SystemTable->BootServices->ExitBootServices(ImageHandle,
+                                                             map_key);
+        efi_bs = NULL;
+        if ( status != EFI_INVALID_PARAMETER || retry )
+            break;
+    }
+
+    if ( EFI_ERROR(status) )
+        PrintErrMesg(L"Cannot exit boot services", status);
+
+    /* Adjust pointers into EFI. */
+    efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
+#ifdef USE_SET_VIRTUAL_ADDRESS_MAP
+    efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
+#endif
+    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
+    efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
+}
+
 static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
 {
    if ( bpp < 0 )
@@ -903,11 +950,11 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     EFI_STATUS status;
     unsigned int i, argc;
     CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
-    UINTN map_key, info_size, gop_mode = ~0;
+    UINTN gop_mode = ~0;
     EFI_SHIM_LOCK_PROTOCOL *shim_lock;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
     union string section = { NULL }, name;
-    bool_t base_video = 0, retry;
+    bool_t base_video = 0;
     char *option_str;
     bool_t use_cfg_file;
 
@@ -1125,46 +1172,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     efi_set_gop_mode(gop, gop_mode);
 
-    info_size = 0;
-    efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
-                         &efi_mdesc_size, &mdesc_ver);
-    info_size += 8 * efi_mdesc_size;
-    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
-    if ( !efi_memmap )
-        blexit(L"Unable to allocate memory for EFI memory map");
-
-    for ( retry = 0; ; retry = 1 )
-    {
-        efi_memmap_size = info_size;
-        status = SystemTable->BootServices->GetMemoryMap(&efi_memmap_size,
-                                                         efi_memmap, &map_key,
-                                                         &efi_mdesc_size,
-                                                         &mdesc_ver);
-        if ( EFI_ERROR(status) )
-            PrintErrMesg(L"Cannot obtain memory map", status);
-
-        efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
-                                    efi_mdesc_size, mdesc_ver);
-
-        efi_arch_pre_exit_boot();
-
-        status = SystemTable->BootServices->ExitBootServices(ImageHandle,
-                                                             map_key);
-        efi_bs = NULL;
-        if ( status != EFI_INVALID_PARAMETER || retry )
-            break;
-    }
-
-    if ( EFI_ERROR(status) )
-        PrintErrMesg(L"Cannot exit boot services", status);
-
-    /* Adjust pointers into EFI. */
-    efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
-#ifdef USE_SET_VIRTUAL_ADDRESS_MAP
-    efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
-#endif
-    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
-    efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
+    efi_exit_boot(ImageHandle, SystemTable);
 
     efi_arch_post_exit_boot();
     for( ; ; ); /* not reached */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 19/23] x86/efi: create new early memory allocator
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (17 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 18/23] efi: split out efi_exit_boot() Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

There is a problem with place_string() which is used as early memory
allocator. It gets memory chunks starting from start symbol and
going down. Sadly this does not work when Xen is loaded using multiboot2
protocol because start lives on 1 MiB address. So, I tried to use
mem_lower address calculated by GRUB2. However, it works only on some
machines. There are machines in the wild (e.g. Dell PowerEdge R820)
which uses first ~640 KiB for boot services code or data... :-(((

In case of multiboot2 protocol we need that place_string() only allocate
memory chunk for EFI memory map. However, I think that it should be fixed
instead of making another function used just in one case. I thought about
two solutions.

1) We could use native EFI allocation functions (e.g. AllocatePool()
   or AllocatePages()) to get memory chunk. However, later (somewhere
   in __start_xen()) we must copy its contents to safe place or reserve
   this in e820 memory map and map it in Xen virtual address space.
   In later case we must also care about conflicts with e.g. crash
   kernel regions which could be quite difficult.

2) We may allocate memory area statically somewhere in Xen code which
   could be used as memory pool for early dynamic allocations. Looks
   quite simple. Additionally, it would not depend on EFI at all and
   could be used on legacy BIOS platforms if we need it. However, we
   must carefully choose size of this pool. We do not want increase
   Xen binary size too much and waste too much memory but also we must fit
   at least memory map on x86 EFI platforms. As I saw on small machine,
   e.g. IBM System x3550 M2 with 8 GiB RAM, memory map may contain more
   than 200 entries. Every entry on x86-64 platform is 40 bytes in size.
   So, it means that we need more than 8 KiB for EFI memory map only.
   Additionally, if we want to use this memory pool for Xen and modules
   command line storage (it would be used when xen.efi is executed as EFI
   application) then we should add, I think, about 1 KiB. In this case,
   to be on safe side, we should assume at least 64 KiB pool for early
   memory allocations, which is about 4 times of our earlier calculations.
   However, during discussion on Xen-devel Jan Beulich suggested that
   just in case we should use 1 MiB memory pool like it was in original
   place_string() implementation. So, let's use 1 MiB as it was proposed.
   If we think that we should not waste unallocated memory in the pool
   on running system then we can mark this region as __initdata and move
   all required data to dynamically allocated places somewhere in __start_xen().

Now solution #2 is implemented but maybe we should consider #1 one day.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/efi/efi-boot.h |   38 ++++++++++++++++++++++++++++++--------
 xen/arch/x86/setup.c        |    3 +--
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 2dd69f6..3d25c48 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -103,9 +103,36 @@ static void __init relocate_trampoline(unsigned long phys)
         *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
 }
 
+#define EBMALLOC_SIZE	MB(1)
+
+static char __initdata ebmalloc_mem[EBMALLOC_SIZE];
+static char __initdata *ebmalloc_free = NULL;
+
+/* EFI boot allocator. */
+static void __init *ebmalloc(size_t size)
+{
+    void *ptr;
+
+    /*
+     * Init ebmalloc_free on runtime. Static initialization
+     * will not work because it puts virtual address there.
+     */
+    if ( ebmalloc_free == NULL )
+        ebmalloc_free = ebmalloc_mem;
+
+    ptr = ebmalloc_free;
+
+    ebmalloc_free += size;
+
+    if ( ebmalloc_free - ebmalloc_mem > sizeof(ebmalloc_mem) )
+        blexit(L"Out of static memory\r\n");
+
+    return ptr;
+}
+
 static void __init place_string(u32 *addr, const char *s)
 {
-    static char *__initdata alloc = start;
+    char *alloc = NULL;
 
     if ( s && *s )
     {
@@ -113,7 +140,7 @@ static void __init place_string(u32 *addr, const char *s)
         const char *old = (char *)(long)*addr;
         size_t len2 = *addr ? strlen(old) + 1 : 0;
 
-        alloc -= len1 + len2;
+        alloc = ebmalloc(len1 + len2);
         /*
          * Insert new string before already existing one. This is needed
          * for options passed on the command line to override options from
@@ -196,12 +223,7 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
 
 static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
 {
-    place_string(&mbi.mem_upper, NULL);
-    mbi.mem_upper -= map_size;
-    mbi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
-    if ( mbi.mem_upper < xen_phys_start )
-        return NULL;
-    return (void *)(long)mbi.mem_upper;
+    return ebmalloc(map_size);
 }
 
 static void __init efi_arch_pre_exit_boot(void)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index bce708c..a59fc4e 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -994,8 +994,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen.");
-    reserve_e820_ram(&boot_e820, efi_enabled(EFI_PLATFORM) ? mbi->mem_upper : __pa(&_start),
-                     __pa(&_end));
+    reserve_e820_ram(&boot_e820, __pa(&_start), __pa(&_end));
 
     /* Late kexec reservation (dynamic start address). */
     kexec_reserve_area(&boot_e820);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (18 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 19/23] x86/efi: create new early memory allocator Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-10 20:07   ` Konrad Rzeszutek Wilk
                     ` (3 more replies)
  2015-07-20 14:29 ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Daniel Kiper
                   ` (17 subsequent siblings)
  37 siblings, 4 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v2 - suggestions/fixes:
   - generate multiboot2 header using macros
     (suggested by Jan Beulich),
   - switch CPU to x86_32 mode before
     jumping to 32-bit code
     (suggested by Andrew Cooper),
   - reduce code changes to increase patch readability
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - ignore MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag on EFI platform
     and find on my own multiboot2.mem_lower value,
   - stop execution if EFI platform is detected
     in legacy BIOS path.
---
 xen/arch/x86/boot/head.S          |  157 +++++++++++++++++++++++++++++++++++--
 xen/arch/x86/efi/efi-boot.h       |   30 +++++++
 xen/arch/x86/efi/stub.c           |    5 ++
 xen/arch/x86/setup.c              |   10 ++-
 xen/arch/x86/x86_64/asm-offsets.c |    2 +
 xen/arch/x86/xen.lds.S            |    4 +-
 xen/common/efi/boot.c             |   12 +++
 xen/include/xen/efi.h             |    1 +
 8 files changed, 210 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 57197db..056047f 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -89,6 +89,13 @@ multiboot1_header_end:
                    0, /* Number of the lines - no preference. */ \
                    0  /* Number of bits per pixel - no preference. */
 
+        /* Do not disable EFI boot services. */
+        mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
+
+        /* EFI64 entry point. */
+        mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
+                   sym_phys(__efi64_start)
+
         /* Multiboot2 header end tag. */
         mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
 .Lmultiboot2_header_end:
@@ -100,9 +107,15 @@ multiboot1_header_end:
 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)
+        .word   BOOT_CS32
 
 .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
 .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
+.Lbad_mb2_ldr: .asciz "ERR: Use latest Multiboot2 compatible bootloader!"
 
         .section .init.text, "ax", @progbits
 
@@ -111,6 +124,9 @@ bad_cpu:
         jmp     print_err
 not_multiboot:
         mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
+        jmp     print_err
+mb2_too_old:
+        mov     $(sym_phys(.Lbad_mb2_ldr)),%esi # Error message
 print_err:
         mov     $0xB8000,%edi  # VGA framebuffer
 1:      mov     (%esi),%bl
@@ -130,6 +146,119 @@ print_err:
 .Lhalt: hlt
         jmp     .Lhalt
 
+        .code64
+
+__efi64_start:
+        cld
+
+        /* Check for Multiboot2 bootloader. */
+        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+        je      efi_multiboot2_proto
+
+        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
+        lea     not_multiboot(%rip),%rdi
+        jmp     x86_32_switch
+
+efi_multiboot2_proto:
+        /*
+         * Multiboot2 information address is 32-bit,
+         * so, zero higher half of %rbx.
+         */
+        mov     %ebx,%ebx
+
+        /* Skip Multiboot2 information fixed part. */
+        lea     MB2_fixed_sizeof(%rbx),%rcx
+
+0:
+        /* Get EFI SystemTable address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
+        jne     1f
+
+        mov     MB2_efi64_st(%rcx),%rsi
+
+        /* Do not go into real mode on EFI platform. */
+        movb    $1,skip_realmode(%rip)
+        jmp     3f
+
+1:
+        /* Get EFI ImageHandle address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
+        jne     2f
+
+        mov     MB2_efi64_ih(%rcx),%rdi
+        jmp     3f
+
+2:
+        /* Is it the end of Multiboot2 information? */
+        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
+        je      run_bs
+
+3:
+        /* Go to next Multiboot2 information tag. */
+        add     MB2_tag_size(%rcx),%ecx
+        add     $(MULTIBOOT2_TAG_ALIGN-1),%rcx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
+        jmp     0b
+
+run_bs:
+        push    %rax
+        push    %rdi
+
+        /* Initialize BSS (no nasty surprises!). */
+        lea     __bss_start(%rip),%rdi
+        lea     __bss_end(%rip),%rcx
+        sub     %rdi,%rcx
+        shr     $3,%rcx
+        xor     %eax,%eax
+        rep     stosq
+
+        pop     %rdi
+
+        /*
+         * IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable.
+         * OUT: %rax - multiboot2.mem_lower. Do not get this value from
+         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag. It could be bogus on
+         * EFI platforms.
+         */
+        call    efi_multiboot2
+
+        /* Convert multiboot2.mem_lower to bytes/16. */
+        mov     %rax,%rcx
+        shr     $4,%rcx
+
+        pop     %rax
+
+        /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
+        lea     trampoline_setup(%rip),%rdi
+
+x86_32_switch:
+        cli
+
+        /* Initialise GDT. */
+        lgdt    gdt_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
+
+        /* Disable paging. */
+        mov     %cr0,%edx
+        and     $(~X86_CR0_PG),%edx
+        mov     %edx,%cr0
+
+        /* Jump to earlier loaded address. */
+        jmp     *%edi
+
 __start:
         cld
         cli
@@ -157,7 +286,7 @@ __start:
 
         /* Not available? BDA value will be fine. */
         cmovnz  MB_mem_lower(%ebx),%edx
-        jmp     trampoline_setup
+        jmp     trampoline_bios_setup
 
 multiboot2_proto:
         /* Skip Multiboot2 information fixed part. */
@@ -169,12 +298,19 @@ multiboot2_proto:
         jne     1f
 
         mov     MB2_mem_lower(%ecx),%edx
-        jmp     trampoline_setup
+        jmp     trampoline_bios_setup
 
 1:
+        /* EFI mode is not supported via legacy BIOS path. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
+        je      mb2_too_old
+
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%ecx)
+        je      mb2_too_old
+
         /* Is it the end of Multiboot2 information? */
         cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
-        je      trampoline_setup
+        je      trampoline_bios_setup
 
         /* Go to next Multiboot2 information tag. */
         add     MB2_tag_size(%ecx),%ecx
@@ -182,7 +318,7 @@ multiboot2_proto:
         and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
         jmp     0b
 
-trampoline_setup:
+trampoline_bios_setup:
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -198,12 +334,13 @@ trampoline_setup:
          * multiboot structure (if available) and use the smallest.
          */
         cmp     $0x100,%edx         /* is the multiboot value too small? */
-        jb      2f                  /* if so, do not use it */
+        jb      trampoline_setup    /* if so, do not use it */
         shl     $10-4,%edx
         cmp     %ecx,%edx           /* compare with BDA value */
         cmovb   %edx,%ecx           /* and use the smaller */
 
-2:      /* Reserve 64kb for the trampoline */
+trampoline_setup:
+        /* Reserve 64kb for the trampoline. */
         sub     $0x1000,%ecx
 
         /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
@@ -220,6 +357,13 @@ trampoline_setup:
         add     $12,%esp            /* Remove reloc() args from stack. */
         mov     %eax,sym_phys(multiboot_ptr)
 
+        /*
+         * Do not zero BSS on EFI platform here.
+         * It was initialized earlier.
+         */
+        cmpb    $1,sym_phys(skip_realmode)
+        je      1f
+
         /* Initialize BSS (no nasty surprises!). */
         mov     $sym_phys(__bss_start),%edi
         mov     $sym_phys(__bss_end),%ecx
@@ -228,6 +372,7 @@ trampoline_setup:
         xor     %eax,%eax
         rep     stosl
 
+1:
         /* Interrogate CPU extended features via CPUID. */
         mov     $0x80000000,%eax
         cpuid
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 3d25c48..1b25a2d 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -228,6 +228,9 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
 
 static void __init efi_arch_pre_exit_boot(void)
 {
+    if ( !efi_enabled(EFI_LOADER) )
+        return;
+
     if ( !trampoline_phys )
     {
         if ( !cfg.addr )
@@ -662,6 +665,33 @@ static bool_t __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
     return 1; /* x86 always uses a config file */
 }
 
+paddr_t __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+    EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+    UINTN cols, gop_mode = ~0, rows;
+
+    set_bit(EFI_PLATFORM, &efi.flags);
+
+    efi_init(ImageHandle, SystemTable);
+
+    efi_console_set_mode();
+
+    if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
+                           &cols, &rows) == EFI_SUCCESS )
+        efi_arch_console_init(cols, rows);
+
+    gop = efi_get_gop();
+    gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
+    efi_arch_edd();
+    efi_tables();
+    setup_efi_pci();
+    efi_variables();
+    efi_set_gop_mode(gop, gop_mode);
+    efi_exit_boot(ImageHandle, SystemTable);
+
+    return cfg.addr;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
index c5ae369..d30fe89 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -13,6 +13,11 @@ struct efi __read_mostly efi = {
 	.smbios3 = EFI_INVALID_TABLE_ADDR
 };
 
+void __init efi_multiboot2(void)
+{
+    /* TODO: Fail if entered! */
+}
+
 void __init efi_init_memory(void) { }
 
 void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t l4e) { }
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index a59fc4e..8bec67f 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -695,7 +695,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
         panic("dom0 kernel not specified. Check bootloader configuration.");
 
-    if ( efi_enabled(EFI_PLATFORM) )
+    if ( efi_enabled(EFI_LOADER) )
     {
         set_pdx_range(xen_phys_start >> PAGE_SHIFT,
                       (xen_phys_start + BOOTSTRAP_MAP_BASE) >> PAGE_SHIFT);
@@ -708,7 +708,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         l3_bootmap[l3_table_offset(BOOTSTRAP_MAP_BASE)] =
             l3e_from_paddr(__pa(l2_bootmap), __PAGE_HYPERVISOR);
 
-        memmap_type = loader;
+        memmap_type = "EFI";
+    }
+    else if ( efi_enabled(EFI_PLATFORM) )
+    {
+        memmap_type = "EFI";
     }
     else if ( e820_raw_nr != 0 )
     {
@@ -806,7 +810,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * we can relocate the dom0 kernel and other multiboot modules. Also, on
      * x86/64, we relocate Xen to higher memory.
      */
-    for ( i = 0; !efi_enabled(EFI_PLATFORM) && i < mbi->mods_count; i++ )
+    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
     {
         if ( mod[i].mod_start & (PAGE_SIZE - 1) )
             panic("Bootloader didn't honor module alignment request.");
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index b926082..b7aed49 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -173,4 +173,6 @@ void __dummy__(void)
     OFFSET(MB2_tag_type, multiboot2_tag_t, type);
     OFFSET(MB2_tag_size, multiboot2_tag_t, size);
     OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
+    OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer);
+    OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
 }
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 87f3e83..a399615 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -162,7 +162,7 @@ SECTIONS
   . = ALIGN(STACK_SIZE);
   __init_end = .;
 
-  . = ALIGN(4);
+  . = ALIGN(8);
   .bss : {                     /* BSS */
        __bss_start = .;
        *(.bss.stack_aligned)
@@ -176,7 +176,7 @@ SECTIONS
        *(.bss.percpu.read_mostly)
        . = ALIGN(SMP_CACHE_BYTES);
        __per_cpu_data_end = .;
-       . = ALIGN(4);
+       . = ALIGN(8);
        __bss_end = .;
   } :text
   _end = . ;
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index bf2f198..5a02e71 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -79,6 +79,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);
+
 static const EFI_BOOT_SERVICES *__initdata efi_bs;
 static UINT32 __initdata efi_bs_revision;
 static EFI_HANDLE __initdata efi_ih;
@@ -960,6 +971,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
 #ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
     set_bit(EFI_PLATFORM, &efi.flags);
+    set_bit(EFI_LOADER, &efi.flags);
 #endif
 
     efi_init(ImageHandle, SystemTable);
diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
index 318bbec..6b952df 100644
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -9,6 +9,7 @@
 #define EFI_INVALID_TABLE_ADDR (~0UL)
 
 #define EFI_PLATFORM	0
+#define EFI_LOADER	1
 
 /* Add fields here only if they need to be referenced from non-EFI code. */
 struct efi {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (19 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 22/23] x86: make Xen early boot code relocatable Daniel Kiper
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Current early command line parser implementation in assembler
is very difficult to change to relocatable stuff using segment
registers. This requires a lot of changes in very weird and
fragile code. So, reimplement this functionality in C. This
way code will be relocatable out of the box and much easier
to maintain.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 .gitignore                     |    5 +-
 xen/arch/x86/Makefile          |    2 +-
 xen/arch/x86/boot/Makefile     |    7 +-
 xen/arch/x86/boot/build32.mk   |    2 +
 xen/arch/x86/boot/cmdline.S    |  367 -------------------------------------
 xen/arch/x86/boot/cmdline.c    |  396 ++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/edd.S        |    3 -
 xen/arch/x86/boot/head.S       |   17 ++
 xen/arch/x86/boot/trampoline.S |   14 ++
 xen/arch/x86/boot/video.S      |    6 -
 10 files changed, 439 insertions(+), 380 deletions(-)
 delete mode 100644 xen/arch/x86/boot/cmdline.S
 create mode 100644 xen/arch/x86/boot/cmdline.c

diff --git a/.gitignore b/.gitignore
index f6ddb00..e0618b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -223,9 +223,10 @@ xen/arch/arm/xen.lds
 xen/arch/x86/asm-offsets.s
 xen/arch/x86/boot/mkelf32
 xen/arch/x86/xen.lds
+xen/arch/x86/boot/cmdline.S
 xen/arch/x86/boot/reloc.S
-xen/arch/x86/boot/reloc.bin
-xen/arch/x86/boot/reloc.lnk
+xen/arch/x86/boot/*.bin
+xen/arch/x86/boot/*.lnk
 xen/arch/x86/efi.lds
 xen/arch/x86/efi/check.efi
 xen/arch/x86/efi/disabled
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 0335445..82c5a93 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -170,4 +170,4 @@ clean::
 	rm -f asm-offsets.s *.lds boot/*.o boot/*~ boot/core boot/mkelf32
 	rm -f $(BASEDIR)/.xen-syms.[0-9]* boot/.*.d
 	rm -f $(BASEDIR)/.xen.efi.[0-9]* efi/*.o efi/.*.d efi/*.efi efi/disabled efi/mkreloc
-	rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
+	rm -f boot/cmdline.S boot/reloc.S boot/*.lnk boot/*.bin
diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
index 06893d8..d73cc76 100644
--- a/xen/arch/x86/boot/Makefile
+++ b/xen/arch/x86/boot/Makefile
@@ -1,9 +1,14 @@
 obj-bin-y += head.o
 
+CMDLINE_DEPS = video.h
+
 RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
 	     $(BASEDIR)/include/xen/multiboot2.h
 
-head.o: reloc.S
+head.o: cmdline.S reloc.S
+
+cmdline.S: cmdline.c $(CMDLINE_DEPS)
+	$(MAKE) -f build32.mk $@ CMDLINE_DEPS="$(CMDLINE_DEPS)"
 
 reloc.S: reloc.c $(RELOC_DEPS)
 	$(MAKE) -f build32.mk $@ RELOC_DEPS="$(RELOC_DEPS)"
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index c83effe..d681643 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -30,6 +30,8 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
 			esac; \
 		done
 
+cmdline.o: cmdline.c $(CMDLINE_DEPS)
+
 reloc.o: reloc.c $(RELOC_DEPS)
 
 .PRECIOUS: %.bin %.lnk
diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
deleted file mode 100644
index 00687eb..0000000
--- a/xen/arch/x86/boot/cmdline.S
+++ /dev/null
@@ -1,367 +0,0 @@
-/******************************************************************************
- * cmdline.S
- *
- * Early command-line parsing.
- */
-
-        .code32
-
-#include "video.h"
-
-# NB. String pointer on stack is modified to point past parsed digits.
-.Latoi:
-        push    %ebx
-        push    %ecx
-        push    %edx
-        push    %esi
-        xor     %ebx,%ebx       /* %ebx = accumulator */
-        mov     $10,%ecx        /* %ecx = base (default base 10) */
-        mov     16+4(%esp),%esi /* %esi = pointer into ascii string. */
-        lodsb
-        cmpb    $'0',%al
-        jne     2f
-        mov     $8,%ecx         /* Prefix '0' => octal (base 8) */
-        lodsb
-        cmpb    $'x',%al
-        jne     2f
-        mov     $16,%ecx        /* Prefix '0x' => hex (base 16) */
-1:      lodsb
-2:      sub     $'0',%al
-        jb      4f
-        cmp     $9,%al
-        jbe     3f
-        sub     $'A'-'0'-10,%al
-        jb      4f
-        cmp     $15,%al
-        jbe     3f
-        sub     $'a'-'A',%al
-        jb      4f
-3:      cmp     %cl,%al
-        jae     4f
-        movzbl  %al,%eax
-        xchg    %eax,%ebx
-        mul     %ecx
-        xchg    %eax,%ebx
-        add     %eax,%ebx
-        jmp     1b
-4:      mov     %ebx,%eax
-        dec     %esi
-        mov     %esi,16+4(%esp)
-        pop     %esi
-        pop     %edx
-        pop     %ecx
-        pop     %ebx
-        ret
-
-.Lstrstr:
-        push    %ecx
-        push    %edx
-        push    %esi
-        push    %edi
-        xor     %eax,%eax
-        xor     %ecx,%ecx
-        not     %ecx
-        mov     16+4(%esp),%esi
-        mov     16+8(%esp),%edi
-        repne   scasb
-        not     %ecx
-        dec     %ecx
-        mov     %ecx,%edx
-1:      mov     16+8(%esp),%edi
-        mov     %esi,%eax
-        mov     %edx,%ecx
-        repe    cmpsb
-        je      2f
-        xchg    %eax,%esi
-        inc     %esi
-        cmpb    $0,-1(%eax)
-        jne     1b
-        xor     %eax,%eax
-2:      pop     %edi
-        pop     %esi
-        pop     %edx
-        pop     %ecx
-        ret
-
-.Lstr_prefix:
-        push    %esi
-        push    %edi
-        mov     8+4(%esp),%esi /* 1st arg is prefix string */
-        mov     8+8(%esp),%edi /* 2nd arg is main string */
-1:      lodsb
-        test    %al,%al
-        jz      2f
-        scasb
-        je      1b
-        sbb     %eax,%eax
-        or      $1,%al
-        jmp     3f
-2:      xor     %eax,%eax
-3:      pop     %edi
-        pop     %esi
-        ret
-
-.Lstrlen:
-        push    %ecx
-        push    %esi
-        push    %edi
-        xor     %eax,%eax
-        xor     %ecx,%ecx
-        not     %ecx
-        mov     12+4(%esp),%edi
-        repne   scasb
-        not     %ecx
-        dec     %ecx
-        mov     %ecx,%eax
-        pop     %edi
-        pop     %esi
-        pop     %ecx
-        ret
-
-.Lfind_option:
-        mov     4(%esp),%eax
-        dec     %eax
-        push    %ebx
-1:      pushl   4+8(%esp)
-        inc     %eax
-        push    %eax
-        call    .Lstrstr
-        add     $8,%esp
-        test    %eax,%eax
-        jz      3f
-        cmp     %eax,4+4(%esp)
-        je      2f
-        cmpb    $' ',-1(%eax)
-        jne     1b
-2:      mov     %eax,%ebx
-        pushl   4+8(%esp)
-        call    .Lstrlen
-        add     $4,%esp
-        xadd    %eax,%ebx
-        /* NUL check (as $'\0' == 0x30 in GAS) */
-        cmpb    $0,(%ebx)
-        je      3f
-        cmpb    $' ',(%ebx)
-        je      3f
-        cmpb    $'=',(%ebx)
-        jne     1b
-3:      pop     %ebx
-        ret
-
-cmdline_parse_early:
-        pusha
-
-        /* Bail if there is no command line to parse. */
-        mov     sym_phys(multiboot_ptr),%ebx
-        mov     MB_flags(%ebx),%eax
-        test    $4,%al
-        jz      .Lcmdline_exit
-        mov     MB_cmdline(%ebx),%eax
-        test    %eax,%eax
-        jz      .Lcmdline_exit
-
-        /* Check for 'no-real-mode' command-line option. */
-        pushl   $sym_phys(.Lno_rm_opt)
-        pushl   MB_cmdline(%ebx)
-        call    .Lfind_option
-        test    %eax,%eax
-        setnz   %al
-        or      %al,sym_phys(skip_realmode)
-
-        /* Check for 'tboot=' command-line option. */
-        movl    $sym_phys(.Ltboot_opt),4(%esp)
-        call    .Lfind_option
-        test    %eax,%eax
-        setnz   %al
-        or      %al,sym_phys(skip_realmode) /* tboot= implies no-real-mode */
-
-.Lparse_edd:
-        /* Check for 'edd=' command-line option. */
-        movl    $sym_phys(.Ledd_opt),4(%esp)
-        call    .Lfind_option
-        test    %eax,%eax
-        jz      .Lparse_edid
-        cmpb    $'=',3(%eax)
-        jne     .Lparse_edid
-        add     $4,%eax
-        movb    $2,sym_phys(opt_edd)  /* opt_edd=2: edd=off */
-        cmpw    $0x666f,(%eax)            /* 0x666f == "of" */
-        je      .Lparse_edid
-        decb    sym_phys(opt_edd)     /* opt_edd=1: edd=skipmbr */
-        cmpw    $0x6b73,(%eax)            /* 0x6b73 == "sk" */
-        je      .Lparse_edid
-        decb    sym_phys(opt_edd)     /* opt_edd=0: edd=on (default) */
-
-.Lparse_edid:
-        /* Check for 'edid=' command-line option. */
-        movl    $sym_phys(.Ledid_opt),4(%esp)
-        call    .Lfind_option
-        test    %eax,%eax
-        jz      .Lparse_vga
-        cmpb    $'=',4(%eax)
-        jne     .Lparse_vga
-        add     $5,%eax
-        mov     %eax,%ebx
-        push    %ebx
-        pushl   $sym_phys(.Ledid_force)
-        call    .Lstr_prefix
-        add     $8,%esp
-        movb    $2,sym_phys(opt_edid) /* opt_edid=2: edid=force */
-        test    %eax,%eax
-        jz      .Lparse_vga
-        push    %ebx
-        pushl   $sym_phys(.Ledid_no)
-        call    .Lstr_prefix
-        add     $8,%esp
-        decb    sym_phys(opt_edid)    /* opt_edid=1: edid=no */
-        test    %eax,%eax
-        jz      .Lparse_vga
-        decb    sym_phys(opt_edid)    /* opt_edid=0: default */
-
-.Lparse_vga:
-        /* Check for 'vga=' command-line option. */
-        movl    $sym_phys(.Lvga_opt),4(%esp)
-        call    .Lfind_option
-        add     $8,%esp
-        test    %eax,%eax
-        jz      .Lcmdline_exit
-        cmpb    $'=',3(%eax)
-        jne     .Lcmdline_exit
-        add     $4,%eax
-
-        /* Found the 'vga=' option. Default option is to display vga menu. */
-        movw    $ASK_VGA,sym_phys(boot_vid_mode)
-
-        /* Check for 'vga=text-80x<rows>. */
-        mov     %eax,%ebx
-        push    %ebx
-        pushl   $sym_phys(.Lvga_text80)
-        call    .Lstr_prefix
-        add     $8,%esp
-        test    %eax,%eax
-        jnz     .Lparse_vga_gfx
-
-        /* We have 'vga=text-80x<rows>'. */
-        add     $8,%ebx
-        push    %ebx
-        call    .Latoi
-        add     $4,%esp
-        mov     %ax,%bx
-        lea     sym_phys(.Lvga_text_modes),%esi
-1:      lodsw
-        test    %ax,%ax
-        jz      .Lcmdline_exit
-        cmp     %ax,%bx
-        lodsw
-        jne     1b
-        mov     %ax,sym_phys(boot_vid_mode)
-        jmp     .Lcmdline_exit
-
-.Lparse_vga_gfx:
-        /* Check for 'vga=gfx-<width>x<height>x<depth>'. */
-        push    %ebx
-        pushl   $sym_phys(.Lvga_gfx)
-        call    .Lstr_prefix
-        add     $8,%esp
-        test    %eax,%eax
-        jnz     .Lparse_vga_mode
-
-        /* We have 'vga=gfx-<width>x<height>x<depth>'. */
-        /* skip 'gfx-' */
-        add     $4,%ebx
-        /* parse <width> */
-        push    %ebx
-        call    .Latoi
-        pop     %esi
-        mov     %ax,sym_phys(vesa_size)+0
-        /* skip 'x' */
-        lodsb
-        cmpb    $'x',%al
-        jne     .Lcmdline_exit
-        /* parse <height> */
-        push    %esi
-        call    .Latoi
-        pop     %esi
-        mov     %ax,sym_phys(vesa_size)+2
-        /* skip 'x' */
-        lodsb
-        cmpb    $'x',%al
-        jne     .Lcmdline_exit
-        /* parse <depth> */
-        push    %esi
-        call    .Latoi
-        pop     %esi
-        mov     %ax,sym_phys(vesa_size)+4
-        /* commit to vesa mode */
-        movw    $VIDEO_VESA_BY_SIZE,sym_phys(boot_vid_mode)
-        jmp     .Lcmdline_exit
-
-.Lparse_vga_mode:
-        /* Check for 'vga=mode-<mode>'. */
-        push    %ebx
-        pushl   $sym_phys(.Lvga_mode)
-        call    .Lstr_prefix
-        add     $8,%esp
-        test    %eax,%eax
-        jnz     .Lparse_vga_current
-
-        /* We have 'vga=mode-<mode>'. */
-        add     $5,%ebx
-        push    %ebx
-        call    .Latoi
-        add     $4,%esp
-        mov     %ax,sym_phys(boot_vid_mode)
-        jmp     .Lcmdline_exit
-
-.Lparse_vga_current:
-        /* Check for 'vga=current'. */
-        push    %ebx
-        pushl   $sym_phys(.Lvga_current)
-        call    .Lstr_prefix
-        add     $8,%esp
-        test    %eax,%eax
-        jnz     .Lcmdline_exit
-
-        /* We have 'vga=current'. */
-        movw    $VIDEO_CURRENT_MODE,sym_phys(boot_vid_mode)
-
-.Lcmdline_exit:
-        popa
-        ret
-
-        .pushsection .init.rodata, "a", @progbits
-
-.Lvga_text_modes: /* rows, mode_number */
-        .word   25,VIDEO_80x25
-        .word   50,VIDEO_80x50
-        .word   43,VIDEO_80x43
-        .word   28,VIDEO_80x28
-        .word   30,VIDEO_80x30
-        .word   34,VIDEO_80x34
-        .word   60,VIDEO_80x60
-        .word   0
-
-.Lvga_opt:
-        .asciz  "vga"
-.Lvga_text80:
-        .asciz  "text-80x"
-.Lvga_gfx:
-        .asciz  "gfx-"
-.Lvga_mode:
-        .asciz  "mode-"
-.Lvga_current:
-        .asciz  "current"
-.Lno_rm_opt:
-        .asciz  "no-real-mode"
-.Ltboot_opt:
-        .asciz  "tboot"
-.Ledid_opt:
-        .asciz  "edid"
-.Ledid_force:
-        .asciz  "force"
-.Ledid_no:
-        .asciz  "no"
-.Ledd_opt:
-        .asciz  "edd"
-
-        .popsection
diff --git a/xen/arch/x86/boot/cmdline.c b/xen/arch/x86/boot/cmdline.c
new file mode 100644
index 0000000..5ea50a4
--- /dev/null
+++ b/xen/arch/x86/boot/cmdline.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2015 Oracle Co.
+ *      Daniel Kiper <daniel.kiper@oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * strlen(), strncmp(), strspn() and strcspn() were copied from
+ * Linux kernel source (linux/lib/string.c).
+ *
+ * max() was copied from xen/xen/include/xen/kernel.h.
+ *
+ */
+
+/*
+ * This entry point is entered from xen/arch/x86/boot/head.S with:
+ *   - 0x4(%esp) = &cmdline,
+ *   - 0x8(%esp) = &early_boot_opts.
+ */
+asm (
+    "    .text                         \n"
+    "    .globl _start                 \n"
+    "_start:                           \n"
+    "    jmp  cmdline_parse_early      \n"
+    );
+
+#include "video.h"
+
+#define VESA_WIDTH	0
+#define VESA_HEIGHT	1
+#define VESA_DEPTH	2
+
+#define VESA_SIZE	3
+
+#define NULL	((void *)0)
+
+#define __cdecl		__attribute__((__cdecl__))
+#define __packed	__attribute__((__packed__))
+#define __text		__attribute__((__section__(".text")))
+#define __used		__attribute__((__used__))
+
+#define max(x,y) ({ \
+        const typeof(x) _x = (x);       \
+        const typeof(y) _y = (y);       \
+        (void) (&_x == &_y);            \
+        _x > _y ? _x : _y; })
+
+#define tolower(c) ((c) | 0x20)
+
+#define strlen_static(s) (sizeof(s) - 1)
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int size_t;
+
+#define U16_MAX	((u16)(~0U))
+
+/*
+ * Keep in sync with trampoline.S:early_boot_opts label!
+ */
+typedef struct __packed {
+    u8 skip_realmode;
+    u8 opt_edd;
+    u8 opt_edid;
+    u16 boot_vid_mode;
+    u16 vesa_size[VESA_SIZE];
+} early_boot_opts_t;
+
+static const char empty_chars[] __text = " \n\r\t";
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+static size_t strlen(const char *s)
+{
+    const char *sc;
+
+    for ( sc = s; *sc != '\0'; ++sc )
+        /* nothing */;
+    return sc - s;
+}
+
+/**
+ * strncmp - Compare two length-limited strings
+ * @cs: One string
+ * @ct: Another string
+ * @count: The maximum number of bytes to compare
+ */
+static int strncmp(const char *cs, const char *ct, size_t count)
+{
+    unsigned char c1, c2;
+
+    while ( count )
+    {
+        c1 = *cs++;
+        c2 = *ct++;
+        if ( c1 != c2 )
+            return c1 < c2 ? -1 : 1;
+        if ( !c1 )
+            break;
+        count--;
+    }
+    return 0;
+}
+
+/**
+ * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+static size_t strspn(const char *s, const char *accept)
+{
+    const char *p;
+    const char *a;
+    size_t count = 0;
+
+    for ( p = s; *p != '\0'; ++p )
+    {
+        for ( a = accept; *a != '\0'; ++a )
+        {
+            if ( *p == *a )
+                break;
+        }
+        if ( *a == '\0' )
+            return count;
+        ++count;
+    }
+    return count;
+}
+
+/**
+ * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
+ * @s: The string to be searched
+ * @reject: The string to avoid
+ */
+static size_t strcspn(const char *s, const char *reject)
+{
+    const char *p;
+    const char *r;
+    size_t count = 0;
+
+    for ( p = s; *p != '\0'; ++p )
+    {
+        for ( r = reject; *r != '\0'; ++r )
+        {
+            if ( *p == *r )
+                return count;
+        }
+        ++count;
+    }
+    return count;
+}
+
+static int strtoi(const char *s, const char *stop, const char **next)
+{
+    int base = 10, i, ores = 0, res = 0;
+
+    if ( *s == '0' )
+      base = (tolower(*++s) == 'x') ? (++s, 16) : 8;
+
+    for ( ; *s != '\0'; ++s )
+    {
+        for ( i = 0; stop && stop[i] != '\0'; ++i )
+            if ( *s == stop[i] )
+                goto out;
+
+        if ( *s < '0' || (*s > '7' && base == 8) )
+        {
+            res = -1;
+            goto out;
+        }
+
+        if ( *s > '9' && (base != 16 || tolower(*s) < 'a' || tolower(*s) > 'f') )
+        {
+            res = -1;
+            goto out;
+        }
+
+        res *= base;
+        res += (tolower(*s) >= 'a') ? (tolower(*s) - 'a' + 10) : (*s - '0');
+
+        if ( ores > res )
+        {
+            res = -1;
+            goto out;
+        }
+
+        ores = res;
+    }
+
+out:
+    if ( next )
+      *next = s;
+
+    return res;
+}
+
+static const char *find_opt(const char *cmdline, const char *opt, int arg)
+{
+    size_t lc, lo;
+    static const char mm[] __text = "--";
+
+    lo = strlen(opt);
+
+    for ( ; ; )
+    {
+        cmdline += strspn(cmdline, empty_chars);
+
+        if ( *cmdline == '\0' )
+            return NULL;
+
+        lc = strcspn(cmdline, empty_chars);
+
+        if ( !strncmp(cmdline, mm, max(lc, strlen_static(mm))) )
+            return NULL;
+
+        if ( !strncmp(cmdline, opt, arg ? lo : max(lc, lo)) )
+            return cmdline;
+
+        cmdline += lc;
+    }
+}
+
+static u8 skip_realmode(const char *cmdline)
+{
+    static const char nrm[] __text = "no-real-mode";
+    static const char tboot[] __text = "tboot=";
+
+    if ( find_opt(cmdline, nrm, 0) || find_opt(cmdline, tboot, 1) )
+        return 1;
+
+    return 0;
+}
+
+static u8 edd_parse(const char *cmdline)
+{
+    const char *c;
+    size_t la;
+    static const char edd[] __text = "edd=";
+    static const char edd_off[] __text = "off";
+    static const char edd_skipmbr[] __text = "skipmbr";
+
+    c = find_opt(cmdline, edd, 1);
+
+    if ( !c )
+        return 0;
+
+    c += strlen_static(edd);
+    la = strcspn(c, empty_chars);
+
+    if ( !strncmp(c, edd_off, max(la, strlen_static(edd_off))) )
+        return 2;
+    else if ( !strncmp(c, edd_skipmbr, max(la, strlen_static(edd_skipmbr))) )
+        return 1;
+
+    return 0;
+}
+
+static u8 edid_parse(const char *cmdline)
+{
+    const char *c;
+    size_t la;
+    static const char edid[] __text = "edid=";
+    static const char edid_force[] __text = "force";
+    static const char edid_no[] __text = "no";
+
+    c = find_opt(cmdline, edid, 1);
+
+    if ( !c )
+        return 0;
+
+    c += strlen_static(edid);
+    la = strcspn(c, empty_chars);
+
+    if ( !strncmp(c, edid_no, max(la, strlen_static(edid_no))) )
+        return 1;
+    else if ( !strncmp(c, edid_force, max(la, strlen_static(edid_force))) )
+        return 2;
+
+    return 0;
+}
+
+static u16 rows2vmode(int rows)
+{
+    switch ( rows )
+    {
+    case 25:
+        return VIDEO_80x25;
+
+    case 28:
+        return VIDEO_80x28;
+
+    case 30:
+        return VIDEO_80x30;
+
+    case 34:
+        return VIDEO_80x34;
+
+    case 43:
+        return VIDEO_80x43;
+
+    case 50:
+        return VIDEO_80x50;
+
+    case 60:
+        return VIDEO_80x60;
+
+    default:
+        return ASK_VGA;
+    }
+}
+
+static void vga_parse(const char *cmdline, early_boot_opts_t *ebo)
+{
+    const char *c;
+    int tmp;
+    size_t la;
+    static const char empty_chars_comma[] __text = " \n\r\t,";
+    static const char x[] __text = "x";
+    static const char vga[] __text = "vga=";
+    static const char vga_current[] __text = "current";
+    static const char vga_gfx[] __text = "gfx-";
+    static const char vga_mode[] __text = "mode-";
+    static const char vga_text_80x[] __text = "text-80x";
+
+    c = find_opt(cmdline, vga, 1);
+
+    if ( !c )
+        return;
+
+    ebo->boot_vid_mode = ASK_VGA;
+
+    c += strlen_static(vga);
+    la = strcspn(c, empty_chars_comma);
+
+    if ( !strncmp(c, vga_current, max(la, strlen_static(vga_current))) )
+        ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
+    else if ( !strncmp(c, vga_text_80x, strlen_static(vga_text_80x)) )
+    {
+        c += strlen_static(vga_text_80x);
+        ebo->boot_vid_mode = rows2vmode(strtoi(c, empty_chars_comma, NULL));
+    }
+    else if ( !strncmp(c, vga_gfx, strlen_static(vga_gfx)) )
+    {
+        tmp = strtoi(c + strlen_static(vga_gfx), x, &c);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_size[VESA_WIDTH] = tmp;
+
+        tmp = strtoi(++c, x, &c);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_size[VESA_HEIGHT] = tmp;
+
+        tmp = strtoi(++c, empty_chars_comma, NULL);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_size[VESA_DEPTH] = tmp;
+
+        ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;
+    }
+    else if ( !strncmp(c, vga_mode, strlen_static(vga_mode)) )
+    {
+        tmp = strtoi(c + strlen_static(vga_mode), empty_chars_comma, NULL);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->boot_vid_mode = tmp;
+    }
+}
+
+static void __cdecl __used cmdline_parse_early(const char *cmdline, early_boot_opts_t *ebo)
+{
+    ebo->skip_realmode = skip_realmode(cmdline);
+    ebo->opt_edd = edd_parse(cmdline);
+    ebo->opt_edid = edid_parse(cmdline);
+    vga_parse(cmdline, ebo);
+}
diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S
index 5c80da6..73371f9 100644
--- a/xen/arch/x86/boot/edd.S
+++ b/xen/arch/x86/boot/edd.S
@@ -142,9 +142,6 @@ edd_next:
 edd_done:
         ret
 
-opt_edd:
-        .byte   0                               # edd=on/off/skipmbr
-
 GLOBAL(boot_edd_info_nr)
         .byte   0
 GLOBAL(boot_mbr_signature_nr)
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 056047f..3f1054d 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -429,8 +429,24 @@ trampoline_setup:
         cmp     $sym_phys(__trampoline_seg_stop),%edi
         jb      1b
 
+        /* Do not parse command line on EFI platform here. */
+        cmpb    $1,sym_phys(skip_realmode)
+        je      1f
+
+        /* Bail if there is no command line to parse. */
+        mov     sym_phys(multiboot_ptr),%ebx
+        testl   $MBI_CMDLINE,MB_flags(%ebx)
+        jz      1f
+
+        cmpl    $0,MB_cmdline(%ebx)
+        jz      1f
+
+        pushl   $sym_phys(early_boot_opts)
+        pushl   MB_cmdline(%ebx)
         call    cmdline_parse_early
+        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
 
+1:
         /* Switch to low-memory stack.  */
         mov     sym_phys(trampoline_phys),%edi
         lea     0x10000(%edi),%esp
@@ -446,6 +462,7 @@ trampoline_setup:
         /* Jump into the relocated trampoline. */
         lret
 
+cmdline_parse_early:
 #include "cmdline.S"
 
 reloc:
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index ccb40fb..3c2714d 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -1,3 +1,5 @@
+#include "video.h"
+
         .code16
 
 /* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
@@ -201,8 +203,20 @@ trampoline_boot_cpu_entry:
         /* Jump to the common bootstrap entry point. */
         jmp     trampoline_protmode_entry
 
+/*
+ * Keep in sync with cmdline.c:early_boot_opts_t type!
+ */
+early_boot_opts:
 skip_realmode:
         .byte   0
+opt_edd:
+        .byte   0                               /* edd=on/off/skipmbr */
+opt_edid:
+        .byte   0                               /* EDID parsing option (force/no/default). */
+GLOBAL(boot_vid_mode)
+        .word   VIDEO_80x25                     /* If we don't run at all, assume basic video mode 3 at 80x25. */
+vesa_size:
+        .word   0,0,0                           /* width x depth x height */
 
 GLOBAL(kbd_shift_flags)
         .byte   0
diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S
index b238bf3..335a51c 100644
--- a/xen/arch/x86/boot/video.S
+++ b/xen/arch/x86/boot/video.S
@@ -945,7 +945,6 @@ store_edid:
 #endif
         ret
 
-opt_edid:       .byte   0       # EDID parsing option (force/no/default)
 mt_end:         .word   0       # End of video mode table if built
 edit_buf:       .space  6       # Line editor buffer
 card_name:      .word   0       # Pointer to adapter name
@@ -991,11 +990,6 @@ name_bann:      .asciz  "Video adapter: "
 
 force_size:     .word   0       # Use this size instead of the one in BIOS vars
 
-vesa_size:      .word   0,0,0   # width x depth x height
-
-/* If we don't run at all, assume basic video mode 3 at 80x25. */
-GLOBAL(boot_vid_mode)
-        .word   VIDEO_80x25
 GLOBAL(boot_vid_info)
         .byte   0, 0    /* orig_x, orig_y */
         .byte   3       /* text mode 3    */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (20 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-07-20 14:29 ` [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Every multiboot protocol (regardless of version) compatible image must
specify its load address (in ELF or multiboot header). Multiboot protocol
compatible loader have to load image at specified address. However, there
is no guarantee that the requested memory region (in case of Xen it starts
at 1 MiB and ends at 17 MiB) where image should be loaded initially is a RAM
and it is free (legacy BIOS platforms are merciful for Xen but I found at
least one EFI platform on which Xen load address conflicts with EFI boot
services; it is Dell PowerEdge R820 with latest firmware). To cope with
that problem we must make Xen early boot code relocatable. This patch does
that. However, it does not add multiboot2 protocol interface which is done
in next patch.

This patch changes following things:
  - default load address is changed from 1 MiB to 2 MiB; I did that because
    initial page tables are using 2 MiB huge pages and this way required
    updates for them are quite easy; it means that e.g. we avoid spacial
    cases for beginning and end of required memory region if it live at
    address not aligned to 2 MiB,
  - %ebp register is used as a storage for Xen image base address; this way
    we can get this value very quickly if it is needed; however, %ebp register
    is not used directly to access a given memory region,
  - %fs register is filled with segment descriptor which describes memory region
    with Xen image (it could be relocated or not); it is used to access some of
    Xen data in early boot code; potentially we can use above mentioned segment
    descriptor to access data using %ds:%esi and/or %es:%esi (e.g. movs*); however,
    I think that it could unnecessarily obfuscate code (e.g. we need at least
    to operations to reload a given segment descriptor) and current solution
    looks quite optimal.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/Makefile          |    6 +-
 xen/arch/x86/Rules.mk          |    4 +
 xen/arch/x86/boot/head.S       |  165 ++++++++++++++++++++++++++++++----------
 xen/arch/x86/boot/trampoline.S |   11 ++-
 xen/arch/x86/boot/wakeup.S     |    6 +-
 xen/arch/x86/boot/x86_64.S     |   34 ++++-----
 xen/arch/x86/setup.c           |   33 ++++----
 xen/arch/x86/x86_64/mm.c       |    2 +-
 xen/arch/x86/xen.lds.S         |    2 +-
 xen/include/asm-x86/config.h   |    3 +
 xen/include/asm-x86/page.h     |    2 +-
 11 files changed, 182 insertions(+), 86 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 82c5a93..93069a8 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -72,8 +72,10 @@ efi-$(x86_64) := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
                          echo '$(TARGET).efi'; fi)
 
 $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
-	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
-	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
+#	THIS IS UGLY HACK! PLEASE DO NOT COMPLAIN. I WILL FIX IT IN NEXT RELEASE.
+	./boot/mkelf32 $(TARGET)-syms $(TARGET) $(XEN_IMG_PHYS_START) 0xffff82d081000000
+#	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
+#	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
 
 
 ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in.o $(ALL_OBJS)
diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index 4a04a8a..7ccb8a0 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -15,6 +15,10 @@ HAS_GDBSX := y
 HAS_PDX := y
 xenoprof := y
 
+XEN_IMG_PHYS_START = 0x200000
+
+CFLAGS += -DXEN_IMG_PHYS_START=$(XEN_IMG_PHYS_START)
+
 CFLAGS += -I$(BASEDIR)/include 
 CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
 CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 3f1054d..d484f68 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -12,13 +12,15 @@
         .text
         .code32
 
-#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
+#define sym_phys(sym)     ((sym) - __XEN_VIRT_START + XEN_IMG_PHYS_START - XEN_IMG_OFFSET)
+#define sym_offset(sym)   ((sym) - __XEN_VIRT_START)
 
 #define BOOT_CS32        0x0008
 #define BOOT_CS64        0x0010
 #define BOOT_DS          0x0018
 #define BOOT_PSEUDORM_CS 0x0020
 #define BOOT_PSEUDORM_DS 0x0028
+#define BOOT_FS          0x0030
 
 #define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
 #define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
@@ -105,12 +107,13 @@ multiboot1_header_end:
 
         .word   0
 gdt_boot_descr:
-        .word   6*8-1
-        .long   sym_phys(trampoline_gdt)
+        .word   7*8-1
+gdt_boot_descr_addr:
+        .long   sym_offset(trampoline_gdt)
         .long   0 /* Needed for 64-bit lgdt */
 
 cs32_switch_addr:
-        .long   sym_phys(cs32_switch)
+        .long   sym_offset(cs32_switch)
         .word   BOOT_CS32
 
 .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
@@ -120,13 +123,13 @@ cs32_switch_addr:
         .section .init.text, "ax", @progbits
 
 bad_cpu:
-        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
+        lea     sym_offset(.Lbad_cpu_msg)(%ebp),%esi # Error message
         jmp     print_err
 not_multiboot:
-        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
+        lea     sym_offset(.Lbad_ldr_msg)(%ebp),%esi # Error message
         jmp     print_err
 mb2_too_old:
-        mov     $(sym_phys(.Lbad_mb2_ldr)),%esi # Error message
+        lea     sym_offset(.Lbad_mb2_ldr)(%ebp),%esi # Error message
 print_err:
         mov     $0xB8000,%edi  # VGA framebuffer
 1:      mov     (%esi),%bl
@@ -151,6 +154,9 @@ print_err:
 __efi64_start:
         cld
 
+        /* Load default Xen image base address. */
+        mov     $sym_phys(__image_base__),%ebp
+
         /* Check for Multiboot2 bootloader. */
         cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
         je      efi_multiboot2_proto
@@ -235,9 +241,11 @@ x86_32_switch:
         cli
 
         /* Initialise GDT. */
+        add     %ebp,gdt_boot_descr_addr(%rip)
         lgdt    gdt_boot_descr(%rip)
 
         /* Reload code selector. */
+        add     %ebp,cs32_switch_addr(%rip)
         ljmpl   *cs32_switch_addr(%rip)
 
         .code32
@@ -263,12 +271,8 @@ __start:
         cld
         cli
 
-        /* Initialise GDT and basic data segments. */
-        lgdt    %cs:sym_phys(gdt_boot_descr)
-        mov     $BOOT_DS,%ecx
-        mov     %ecx,%ds
-        mov     %ecx,%es
-        mov     %ecx,%ss
+        /* Load default Xen image base address. */
+        mov     $sym_phys(__image_base__),%ebp
 
         /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
         xor     %edx,%edx
@@ -319,6 +323,19 @@ multiboot2_proto:
         jmp     0b
 
 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
+
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -340,33 +357,58 @@ trampoline_bios_setup:
         cmovb   %edx,%ecx           /* and use the smaller */
 
 trampoline_setup:
+        mov     %ebp,%esi
+
+        /* Initialize 0-15 bits of BOOT_FS segment descriptor base address. */
+        mov     %ebp,%edx
+        shl     $16,%edx
+        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS)(%esi)
+
+        /* Initialize 16-23 bits of BOOT_FS segment descriptor base address. */
+        mov     %ebp,%edx
+        shr     $16,%edx
+        and     $0x000000ff,%edx
+        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
+
+        /* Initialize 24-31 bits of BOOT_FS segment descriptor base address. */
+        mov     %ebp,%edx
+        and     $0xff000000,%edx
+        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
+
+        /* Initialize %fs and later use it to access Xen data if possible. */
+        mov     $BOOT_FS,%edx
+        mov     %edx,%fs
+
         /* Reserve 64kb for the trampoline. */
         sub     $0x1000,%ecx
 
         /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
         xor     %cl, %cl
         shl     $4, %ecx
-        mov     %ecx,sym_phys(trampoline_phys)
+        mov     %ecx,%fs:sym_offset(trampoline_phys)
+
+        /* Save Xen image base address for later use. */
+        mov     %ebp,%fs:sym_offset(xen_img_base_phys_addr)
 
         /* Save the Multiboot info struct (after relocation) for later use. */
-        mov     $sym_phys(cpu0_stack)+1024,%esp
+        lea     (sym_offset(cpu0_stack)+1024)(%ebp),%esp
         push    %eax                /* Multiboot magic. */
         push    %ebx                /* Multiboot information address. */
         push    %ecx                /* Boot trampoline address. */
         call    reloc
         add     $12,%esp            /* Remove reloc() args from stack. */
-        mov     %eax,sym_phys(multiboot_ptr)
+        mov     %eax,%fs:sym_offset(multiboot_ptr)
 
         /*
          * Do not zero BSS on EFI platform here.
          * It was initialized earlier.
          */
-        cmpb    $1,sym_phys(skip_realmode)
+        cmpb    $1,%fs:sym_offset(skip_realmode)
         je      1f
 
         /* Initialize BSS (no nasty surprises!). */
-        mov     $sym_phys(__bss_start),%edi
-        mov     $sym_phys(__bss_end),%ecx
+        lea     sym_offset(__bss_start)(%ebp),%edi
+        lea     sym_offset(__bss_end)(%ebp),%ecx
         sub     %edi,%ecx
         shr     $2,%ecx
         xor     %eax,%eax
@@ -381,8 +423,8 @@ trampoline_setup:
         jbe     1f
         mov     $0x80000001,%eax
         cpuid
-1:      mov     %edx,sym_phys(cpuid_ext_features)
-        mov     %edx,sym_phys(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
+1:      mov     %edx,%fs:sym_offset(cpuid_ext_features)
+        mov     %edx,%fs:(sym_offset(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM))
 
         /* Check for availability of long mode. */
         bt      $X86_FEATURE_LM & 0x1f,%edx
@@ -390,72 +432,111 @@ trampoline_setup:
 
         /* Stash TSC to calculate a good approximation of time-since-boot */
         rdtsc
-        mov     %eax,sym_phys(boot_tsc_stamp)
-        mov     %edx,sym_phys(boot_tsc_stamp+4)
+        mov     %eax,%fs:sym_offset(boot_tsc_stamp)
+        mov     %edx,%fs:sym_offset(boot_tsc_stamp+4)
 
-        /* Initialise L2 boot-map page table entries (16MB). */
-        mov     $sym_phys(l2_bootmap),%edx
-        mov     $PAGE_HYPERVISOR|_PAGE_PSE,%eax
-        mov     $8,%ecx
+        /* Update frame addreses in page tables. */
+        lea     sym_offset(__page_tables_start)(%ebp),%edx
+        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
+1:      testl   $_PAGE_PRESENT,(%edx)
+        jz      2f
+        add     %ebp,(%edx)
+2:      add     $8,%edx
+        loop    1b
+
+        /* Initialise L2 boot-map page table entries (14MB). */
+        lea     sym_offset(l2_bootmap)(%ebp),%edx
+        lea     sym_offset(start)(%ebp),%eax
+        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
+        mov     %eax,%ebx
+        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
+        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
+        add     %ebx,%edx
+        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
+        mov     $7,%ecx
 1:      mov     %eax,(%edx)
         add     $8,%edx
         add     $(1<<L2_PAGETABLE_SHIFT),%eax
         loop    1b
+
         /* Initialise L3 boot-map page directory entry. */
-        mov     $sym_phys(l2_bootmap)+__PAGE_HYPERVISOR,%eax
-        mov     %eax,sym_phys(l3_bootmap) + 0*8
+        lea     (sym_offset(l2_bootmap)+__PAGE_HYPERVISOR)(%ebp),%eax
+        lea     sym_offset(l3_bootmap)(%ebp),%ebx
+        mov     $4,%ecx
+1:      mov     %eax,(%ebx)
+        add     $8,%ebx
+        add     $(L2_PAGETABLE_ENTRIES*8),%eax
+        loop    1b
+
+        /* Initialise L2 direct map page table entries (14MB). */
+        lea     sym_offset(l2_identmap)(%ebp),%edx
+        lea     sym_offset(start)(%ebp),%eax
+        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
+        mov     %eax,%ebx
+        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
+        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
+        add     %ebx,%edx
+        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
+        mov     $7,%ecx
+1:      mov     %eax,(%edx)
+        add     $8,%edx
+        add     $(1<<L2_PAGETABLE_SHIFT),%eax
+        loop    1b
+
         /* Hook 4kB mappings of first 2MB of memory into L2. */
-        mov     $sym_phys(l1_identmap)+__PAGE_HYPERVISOR,%edi
-        mov     %edi,sym_phys(l2_xenmap)
-        mov     %edi,sym_phys(l2_bootmap)
+        lea     (sym_offset(l1_identmap)+__PAGE_HYPERVISOR)(%ebp),%edi
+        mov     %edi,%fs:sym_offset(l2_bootmap)
 
         /* Apply relocations to bootstrap trampoline. */
-        mov     sym_phys(trampoline_phys),%edx
-        mov     $sym_phys(__trampoline_rel_start),%edi
+        mov     %fs:sym_offset(trampoline_phys),%edx
+        lea     sym_offset(__trampoline_rel_start)(%ebp),%edi
+        lea     sym_offset(__trampoline_rel_stop)(%ebp),%esi
 1:
         mov     (%edi),%eax
         add     %edx,(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_rel_stop),%edi
+        cmp     %esi,%edi
         jb      1b
 
         /* Patch in the trampoline segment. */
         shr     $4,%edx
-        mov     $sym_phys(__trampoline_seg_start),%edi
+        lea     sym_offset(__trampoline_seg_start)(%ebp),%edi
+        lea     sym_offset(__trampoline_seg_stop)(%ebp),%esi
 1:
         mov     (%edi),%eax
         mov     %dx,(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_seg_stop),%edi
+        cmp     %esi,%edi
         jb      1b
 
         /* Do not parse command line on EFI platform here. */
-        cmpb    $1,sym_phys(skip_realmode)
+        cmpb    $1,%fs:sym_offset(skip_realmode)
         je      1f
 
         /* Bail if there is no command line to parse. */
-        mov     sym_phys(multiboot_ptr),%ebx
+        mov     %fs:sym_offset(multiboot_ptr),%ebx
         testl   $MBI_CMDLINE,MB_flags(%ebx)
         jz      1f
 
         cmpl    $0,MB_cmdline(%ebx)
         jz      1f
 
-        pushl   $sym_phys(early_boot_opts)
+        lea     sym_offset(early_boot_opts)(%ebp),%eax
+        push    %eax
         pushl   MB_cmdline(%ebx)
         call    cmdline_parse_early
         add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
 
 1:
         /* Switch to low-memory stack.  */
-        mov     sym_phys(trampoline_phys),%edi
+        mov     %fs:sym_offset(trampoline_phys),%edi
         lea     0x10000(%edi),%esp
         lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
         pushl   $BOOT_CS32
         push    %eax
 
         /* Copy bootstrap trampoline to low memory, below 1MB. */
-        mov     $sym_phys(trampoline_start),%esi
+        lea     sym_offset(trampoline_start)(%ebp),%esi
         mov     $trampoline_end - trampoline_start,%ecx
         rep     movsb
 
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 3c2714d..a8909ce 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -52,12 +52,20 @@ trampoline_gdt:
         /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
         .long   0x0000ffff
         .long   0x00009200
+        /*
+         * 0x0030: ring 0 Xen data, 16 MiB size, base
+         * address is initialized during runtime.
+         */
+        .quad   0x00c0920000001000
 
         .pushsection .trampoline_rel, "a"
         .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
         .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
         .popsection
 
+GLOBAL(xen_img_base_phys_addr)
+        .long   0
+
 GLOBAL(cpuid_ext_features)
         .long   0
 
@@ -82,7 +90,8 @@ trampoline_protmode_entry:
         mov     %ecx,%cr4
 
         /* Load pagetable base register. */
-        mov     $sym_phys(idle_pg_table),%eax
+        mov     bootsym_rel(xen_img_base_phys_addr,4,%eax)
+        lea     sym_offset(idle_pg_table)(%eax),%eax
         add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
         mov     %eax,%cr3
 
diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S
index 08ea9b2..ff80f7f 100644
--- a/xen/arch/x86/boot/wakeup.S
+++ b/xen/arch/x86/boot/wakeup.S
@@ -119,8 +119,10 @@ wakeup_32:
         mov     %eax, %ss
         mov     $bootsym_rel(wakeup_stack, 4, %esp)
 
+        mov     bootsym_rel(xen_img_base_phys_addr, 4, %ebx)
+
         # check saved magic again
-        mov     $sym_phys(saved_magic), %eax
+        lea     sym_offset(saved_magic)(%ebx), %eax
         add     bootsym_rel(trampoline_xen_phys_start, 4, %eax)
         mov     (%eax), %eax
         cmp     $0x9abcdef0, %eax
@@ -133,7 +135,7 @@ wakeup_32:
         mov     %ecx, %cr4
 
         /* Load pagetable base register */
-        mov     $sym_phys(idle_pg_table),%eax
+        lea     sym_offset(idle_pg_table)(%ebx),%eax
         add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
         mov     %eax,%cr3
 
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index c8bf9d0..ae4bebd 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -81,7 +81,6 @@ GLOBAL(boot_cpu_compat_gdt_table)
         .quad 0x0000910000000000     /* per-CPU entry (limit == cpu)      */
         .align PAGE_SIZE, 0
 
-GLOBAL(__page_tables_start)
 /*
  * Mapping of first 2 megabytes of memory. This is mapped with 4kB mappings
  * to avoid type conflicts with fixed-range MTRRs covering the lowest megabyte
@@ -101,21 +100,18 @@ GLOBAL(l1_identmap)
         .endr
         .size l1_identmap, . - l1_identmap
 
-/* Mapping of first 16 megabytes of memory. */
+GLOBAL(__page_tables_start)
+
 GLOBAL(l2_identmap)
-        .quad sym_phys(l1_identmap) + __PAGE_HYPERVISOR
-        pfn = 0
-        .rept 7
-        pfn = pfn + (1 << PAGETABLE_ORDER)
-        .quad (pfn << PAGE_SHIFT) | PAGE_HYPERVISOR | _PAGE_PSE
-        .endr
-        .fill 4 * L2_PAGETABLE_ENTRIES - 8, 8, 0
+        .quad sym_offset(l1_identmap) + __PAGE_HYPERVISOR
+        .fill 4 * L2_PAGETABLE_ENTRIES - 1, 8, 0
         .size l2_identmap, . - l2_identmap
 
 GLOBAL(l2_xenmap)
-        idx = 0
-        .rept 8
-        .quad sym_phys(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
+        .quad 0
+        idx = 1
+        .rept 7
+        .quad sym_offset(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
         idx = idx + 1
         .endr
         .fill L2_PAGETABLE_ENTRIES - 8, 8, 0
@@ -125,7 +121,7 @@ l2_fixmap:
         idx = 0
         .rept L2_PAGETABLE_ENTRIES
         .if idx == l2_table_offset(FIXADDR_TOP - 1)
-        .quad sym_phys(l1_fixmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l1_fixmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
@@ -136,7 +132,7 @@ l2_fixmap:
 GLOBAL(l3_identmap)
         idx = 0
         .rept 4
-        .quad sym_phys(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
+        .quad sym_offset(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
         idx = idx + 1
         .endr
         .fill L3_PAGETABLE_ENTRIES - 4, 8, 0
@@ -146,9 +142,9 @@ l3_xenmap:
         idx = 0
         .rept L3_PAGETABLE_ENTRIES
         .if idx == l3_table_offset(XEN_VIRT_START)
-        .quad sym_phys(l2_xenmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l2_xenmap) + __PAGE_HYPERVISOR
         .elseif idx == l3_table_offset(FIXADDR_TOP - 1)
-        .quad sym_phys(l2_fixmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l2_fixmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
@@ -158,13 +154,13 @@ l3_xenmap:
 
 /* Top-level master (and idle-domain) page directory. */
 GLOBAL(idle_pg_table)
-        .quad sym_phys(l3_bootmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l3_bootmap) + __PAGE_HYPERVISOR
         idx = 1
         .rept L4_PAGETABLE_ENTRIES - 1
         .if idx == l4_table_offset(DIRECTMAP_VIRT_START)
-        .quad sym_phys(l3_identmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l3_identmap) + __PAGE_HYPERVISOR
         .elseif idx == l4_table_offset(XEN_VIRT_START)
-        .quad sym_phys(l3_xenmap) + __PAGE_HYPERVISOR
+        .quad sym_offset(l3_xenmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 8bec67f..8172520 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -291,9 +291,6 @@ static void *__init bootstrap_map(const module_t *mod)
     if ( start >= end )
         return NULL;
 
-    if ( end <= BOOTSTRAP_MAP_BASE )
-        return (void *)(unsigned long)start;
-
     ret = (void *)(map_cur + (unsigned long)(start & mask));
     start &= ~mask;
     end = (end + mask) & ~mask;
@@ -641,6 +638,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     printk("Command line: %s\n", cmdline);
 
+    printk("Xen image base address: 0x%08lx\n",
+           xen_phys_start ? xen_phys_start : (unsigned long)xen_img_base_phys_addr);
+
     printk("Video information:\n");
 
     /* Print VGA display mode information. */
@@ -835,10 +835,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         uint64_t s, e, mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
         uint64_t end, limit = ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT;
 
-        /* Superpage-aligned chunks from BOOTSTRAP_MAP_BASE. */
         s = (boot_e820.map[i].addr + mask) & ~mask;
         e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask;
-        s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE);
         if ( (boot_e820.map[i].type != E820_RAM) || (s >= e) )
             continue;
 
@@ -876,7 +874,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
             /* Select relocation address. */
             e = end - reloc_size;
             xen_phys_start = e;
-            bootsym(trampoline_xen_phys_start) = e;
+            bootsym(trampoline_xen_phys_start) = e - xen_img_base_phys_addr;
 
             /*
              * Perform relocation to new physical address.
@@ -886,7 +884,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
              */
             load_start = (unsigned long)_start - XEN_VIRT_START;
             barrier();
-            move_memory(e + load_start, load_start, _end - _start, 1);
+            move_memory(e + load_start, load_start + xen_img_base_phys_addr, _end - _start, 1);
 
             /* Walk initial pagetables, relocating page directory entries. */
             pl4e = __va(__pa(idle_pg_table));
@@ -895,27 +893,27 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                 if ( !(l4e_get_flags(*pl4e) & _PAGE_PRESENT) )
                     continue;
                 *pl4e = l4e_from_intpte(l4e_get_intpte(*pl4e) +
-                                        xen_phys_start);
+                                        xen_phys_start - xen_img_base_phys_addr);
                 pl3e = l4e_to_l3e(*pl4e);
                 for ( j = 0; j < L3_PAGETABLE_ENTRIES; j++, pl3e++ )
                 {
                     /* Not present, 1GB mapping, or already relocated? */
                     if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) ||
                          (l3e_get_flags(*pl3e) & _PAGE_PSE) ||
-                         (l3e_get_pfn(*pl3e) > 0x1000) )
+                         (l3e_get_pfn(*pl3e) > PFN_DOWN(xen_phys_start)) )
                         continue;
                     *pl3e = l3e_from_intpte(l3e_get_intpte(*pl3e) +
-                                            xen_phys_start);
+                                            xen_phys_start - xen_img_base_phys_addr);
                     pl2e = l3e_to_l2e(*pl3e);
                     for ( k = 0; k < L2_PAGETABLE_ENTRIES; k++, pl2e++ )
                     {
                         /* Not present, PSE, or already relocated? */
                         if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
                              (l2e_get_flags(*pl2e) & _PAGE_PSE) ||
-                             (l2e_get_pfn(*pl2e) > 0x1000) )
+                             (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)) )
                             continue;
                         *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
-                                                xen_phys_start);
+                                                xen_phys_start - xen_img_base_phys_addr);
                     }
                 }
             }
@@ -926,10 +924,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                                    PAGE_HYPERVISOR_RWX | _PAGE_PSE);
             for ( i = 1; i < L2_PAGETABLE_ENTRIES; i++, pl2e++ )
             {
-                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
+                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) || (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)))
                     continue;
                 *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
-                                        xen_phys_start);
+                                        xen_phys_start - xen_img_base_phys_addr);
             }
 
             /* Re-sync the stack and then switch to relocated pagetables. */
@@ -998,6 +996,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen.");
+
+    printk("New Xen image base address: 0x%08lx\n", xen_phys_start);
+
     reserve_e820_ram(&boot_e820, __pa(&_start), __pa(&_end));
 
     /* Late kexec reservation (dynamic start address). */
@@ -1070,14 +1071,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
         set_pdx_range(s >> PAGE_SHIFT, e >> PAGE_SHIFT);
 
-        /* Need to create mappings above BOOTSTRAP_MAP_BASE. */
-        map_s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE);
+        map_s = s;
         map_e = min_t(uint64_t, e,
                       ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT);
 
         /* Pass mapped memory to allocator /before/ creating new mappings. */
         init_boot_pages(s, min(map_s, e));
-        s = map_s;
         if ( s < map_e )
         {
             uint64_t mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
index 98310f3..baa6461 100644
--- a/xen/arch/x86/x86_64/mm.c
+++ b/xen/arch/x86/x86_64/mm.c
@@ -44,7 +44,7 @@ unsigned int __read_mostly m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START;
 
 /* Enough page directories to map into the bottom 1GB. */
 l3_pgentry_t __section(".bss.page_aligned") l3_bootmap[L3_PAGETABLE_ENTRIES];
-l2_pgentry_t __section(".bss.page_aligned") l2_bootmap[L2_PAGETABLE_ENTRIES];
+l2_pgentry_t __section(".bss.page_aligned") l2_bootmap[4 * L2_PAGETABLE_ENTRIES];
 
 l2_pgentry_t *compat_idle_pg_table_l2;
 
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index a399615..b666a3f 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -38,7 +38,7 @@ SECTIONS
   . = __XEN_VIRT_START;
   __image_base__ = .;
 #endif
-  . = __XEN_VIRT_START + MB(1);
+  . = __XEN_VIRT_START + XEN_IMG_OFFSET;
   _start = .;
   .text : {
         _stext = .;            /* Text and read-only data */
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index 3e9be83..6d21cb7 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -114,6 +114,7 @@ extern unsigned long trampoline_phys;
                  trampoline_phys-__pa(trampoline_start)))
 extern char trampoline_start[], trampoline_end[];
 extern char trampoline_realmode_entry[];
+extern unsigned int xen_img_base_phys_addr;
 extern unsigned int trampoline_xen_phys_start;
 extern unsigned char trampoline_cpu_started;
 extern char wakeup_start[];
@@ -280,6 +281,8 @@ extern unsigned char boot_edid_info[128];
 #endif
 #define DIRECTMAP_VIRT_END      (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)
 
+#define XEN_IMG_OFFSET          0x200000
+
 #ifndef __ASSEMBLY__
 
 /* This is not a fixed value, just a lower limit. */
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 87b3341..27481ac 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -283,7 +283,7 @@ extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
 extern l2_pgentry_t  *compat_idle_pg_table_l2;
 extern unsigned int   m2p_compat_vstart;
 extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
-    l2_bootmap[L2_PAGETABLE_ENTRIES];
+    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
 extern l3_pgentry_t l3_bootmap[L3_PAGETABLE_ENTRIES];
 extern l2_pgentry_t l2_identmap[4*L2_PAGETABLE_ENTRIES];
 extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES],
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (21 preceding siblings ...)
  2015-07-20 14:29 ` [PATCH v2 22/23] x86: make Xen early boot code relocatable Daniel Kiper
@ 2015-07-20 14:29 ` Daniel Kiper
  2015-08-11 16:56   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150811165658.GC32231@l.oracle.com>
       [not found] ` <1437402558-7313-3-git-send-email-daniel.kiper@oracle.com>
                   ` (14 subsequent siblings)
  37 siblings, 2 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-20 14:29 UTC (permalink / raw)
  To: xen-devel, grub-devel
  Cc: jgross, keir, ian.campbell, andrew.cooper3, stefano.stabellini,
	roy.franz, ning.sun, david.vrabel, jbeulich, phcoder, wei.liu2,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

Add multiboot2 protocol support for relocatable images. Only GRUB2
with relevant patches understands that feature. Older multiboot
protocol (regardless of version) compatible loaders ignore it
and everything works as usual.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/head.S          |   46 +++++++++++++++++++++++++++++--------
 xen/arch/x86/x86_64/asm-offsets.c |    1 +
 xen/include/xen/multiboot2.h      |   13 +++++++++++
 3 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index d484f68..2520e48 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -81,6 +81,13 @@ multiboot1_header_end:
         /* Align modules at page boundry. */
         mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
 
+        /* Load address preference. */
+        mb2ht_init MB2_HT(RELOCATABLE), MB2_HT(OPTIONAL), \
+                   sym_phys(start), /* Min load address. */ \
+                   0xffffffff, /* Max load address (4 GiB - 1). */ \
+                   0x200000, /* Load address alignment (2 MiB). */ \
+                   MULTIBOOT2_LOAD_PREFERENCE_HIGH
+
         /* Console flags tag. */
         mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
                    MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
@@ -176,30 +183,39 @@ efi_multiboot2_proto:
         lea     MB2_fixed_sizeof(%rbx),%rcx
 
 0:
+        /* Get Xen image base address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_BASE_ADDR,MB2_tag_type(%rcx)
+        jne     1f
+
+        mov     MB2_base_addr(%rcx),%ebp
+        sub     $XEN_IMG_OFFSET,%rbp
+        jmp     4f
+
+1:
         /* Get EFI SystemTable address from Multiboot2 information. */
         cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
-        jne     1f
+        jne     2f
 
         mov     MB2_efi64_st(%rcx),%rsi
 
         /* Do not go into real mode on EFI platform. */
         movb    $1,skip_realmode(%rip)
-        jmp     3f
+        jmp     4f
 
-1:
+2:
         /* Get EFI ImageHandle address from Multiboot2 information. */
         cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
-        jne     2f
+        jne     3f
 
         mov     MB2_efi64_ih(%rcx),%rdi
-        jmp     3f
+        jmp     4f
 
-2:
+3:
         /* Is it the end of Multiboot2 information? */
         cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
         je      run_bs
 
-3:
+4:
         /* Go to next Multiboot2 information tag. */
         add     MB2_tag_size(%rcx),%ecx
         add     $(MULTIBOOT2_TAG_ALIGN-1),%rcx
@@ -297,14 +313,23 @@ multiboot2_proto:
         lea     MB2_fixed_sizeof(%ebx),%ecx
 
 0:
+        /* Get Xen image base address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_BASE_ADDR,MB2_tag_type(%ecx)
+        jne     1f
+
+        mov     MB2_base_addr(%ecx),%ebp
+        sub     $XEN_IMG_OFFSET,%ebp
+        jmp     3f
+
+1:
         /* Get mem_lower from Multiboot2 information. */
         cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
-        jne     1f
+        jne     2f
 
         mov     MB2_mem_lower(%ecx),%edx
-        jmp     trampoline_bios_setup
+        jmp     3f
 
-1:
+2:
         /* EFI mode is not supported via legacy BIOS path. */
         cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
         je      mb2_too_old
@@ -316,6 +341,7 @@ multiboot2_proto:
         cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
         je      trampoline_bios_setup
 
+3:
         /* Go to next Multiboot2 information tag. */
         add     MB2_tag_size(%ecx),%ecx
         add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index b7aed49..5345a9e 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -172,6 +172,7 @@ void __dummy__(void)
     DEFINE(MB2_fixed_sizeof, sizeof(multiboot2_fixed_t));
     OFFSET(MB2_tag_type, multiboot2_tag_t, type);
     OFFSET(MB2_tag_size, multiboot2_tag_t, size);
+    OFFSET(MB2_base_addr, multiboot2_tag_base_addr_t, base_addr);
     OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
     OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer);
     OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
index 09ee64e..a63c4d6 100644
--- a/xen/include/xen/multiboot2.h
+++ b/xen/include/xen/multiboot2.h
@@ -59,11 +59,17 @@
 #define MULTIBOOT2_HEADER_TAG_EFI_BS			7
 #define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32	8
 #define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64	9
+#define MULTIBOOT2_HEADER_TAG_RELOCATABLE		10
 
 /* Header tag flags. */
 #define MULTIBOOT2_HEADER_TAG_REQUIRED	0
 #define MULTIBOOT2_HEADER_TAG_OPTIONAL	1
 
+/* Where image should be loaded (suggestion not requirement). */
+#define MULTIBOOT2_LOAD_PREFERENCE_NONE	0
+#define MULTIBOOT2_LOAD_PREFERENCE_LOW	1
+#define MULTIBOOT2_LOAD_PREFERENCE_HIGH	2
+
 /* Header console tag console_flags. */
 #define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED	1
 #define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED	2
@@ -90,6 +96,7 @@
 #define MULTIBOOT2_TAG_TYPE_EFI_BS		18
 #define MULTIBOOT2_TAG_TYPE_EFI32_IH		19
 #define MULTIBOOT2_TAG_TYPE_EFI64_IH		20
+#define MULTIBOOT2_TAG_TYPE_BASE_ADDR		21
 
 /* Multiboot 2 tag alignment. */
 #define MULTIBOOT2_TAG_ALIGN			8
@@ -120,6 +127,12 @@ typedef struct {
 typedef struct {
     u32 type;
     u32 size;
+    u32 base_addr;
+} multiboot2_tag_base_addr_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
     char string[0];
 } multiboot2_tag_string_t;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
       [not found] ` <1437402558-7313-3-git-send-email-daniel.kiper@oracle.com>
@ 2015-07-21  9:35   ` Jan Beulich
  2015-07-21 17:23     ` Daniel Kiper
  0 siblings, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-07-21  9:35 UTC (permalink / raw)
  To: Daniel Kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:

Without any explanation (description) I'm inclined to say this makes
things more fragile instead of improving the situation. As it looks
like we indeed pointlessly copy .eh_frame, but I think this would
better be avoided by suppressing its generation (i.e. add
-fno-asynchronous-unwind-tables just like Rules.mk has).

Jan

> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/arch/x86/boot/build32.mk |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
> index c208249..c83effe 100644
> --- a/xen/arch/x86/boot/build32.mk
> +++ b/xen/arch/x86/boot/build32.mk
> @@ -13,7 +13,7 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
>  	sed 's/ /,0x/g' | sed 's/,0x$$//' | sed 's/^[0-9]*,/ .long /') >$@
>  
>  %.bin: %.lnk
> -	$(OBJCOPY) -O binary $< $@
> +	$(OBJCOPY) -O binary -j .text $< $@
>  
>  %.lnk: %.o
>  	$(LD) $(LDFLAGS_DIRECT) -N -Ttext 0 -o $@ $<
> -- 
> 1.7.10.4

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
       [not found] ` <1437402558-7313-4-git-send-email-daniel.kiper@oracle.com>
@ 2015-07-21  9:37   ` Jan Beulich
  2015-07-21 18:23     ` Daniel Kiper
  0 siblings, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-07-21  9:37 UTC (permalink / raw)
  To: Daniel Kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:

... because of ??? Nowadays - with X86_FEATURE_ERMS - rep stosb
is expected to be faster than rep stosl.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 00/23] x86: multiboot2 protocol support
       [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
                   ` (24 preceding siblings ...)
       [not found] ` <1437402558-7313-4-git-send-email-daniel.kiper@oracle.com>
@ 2015-07-21  9:39 ` Jan Beulich
       [not found] ` <1437402558-7313-2-git-send-email-daniel.kiper@oracle.com>
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-07-21  9:39 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
> This series, in general, is not targeted to Xen 4.6. However, there are
> some fixes at the beginning of it which are worth considering, I think.

I looked at the first few, and didn't spot any fixes. If you meant
just cleanup or other cosmetic adjustments, then I don't view them
as candidates for going in now. If I overlooked some aspect, then
please be more precise.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
  2015-07-21  9:35   ` [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file Jan Beulich
@ 2015-07-21 17:23     ` Daniel Kiper
  2015-07-22  5:14       ` Jan Beulich
  2015-07-22  8:02       ` Jan Beulich
  0 siblings, 2 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-21 17:23 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3, keir, xen-devel

On Tue, Jul 21, 2015 at 03:35:07AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
>
> Without any explanation (description) I'm inclined to say this makes
> things more fragile instead of improving the situation. As it looks
> like we indeed pointlessly copy .eh_frame, but I think this would
> better be avoided by suppressing its generation (i.e. add
> -fno-asynchronous-unwind-tables just like Rules.mk has).

Make sense, however, there is still place for two small optimizations.

First of all ld generates .got.plt section and objcopy copy it to binary file.
It is not needed because we do not link our stuff here with shared libraries.
So, we can use -R objcopy option to remove it (if you do not like -j .text).
This way we could save 15 bytes (at least on my machines).

We could also save another 3 bytes (per one xen/arch/x86/boot C input file)
in final Xen binary in worst case :-))). We just need generate output assembly
files as string of .byte instead of .long.

Where should I stop?

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-21  9:37   ` [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb Jan Beulich
@ 2015-07-21 18:23     ` Daniel Kiper
  2015-07-22  5:18       ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-21 18:23 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3, keir, xen-devel

On Tue, Jul 21, 2015 at 03:37:48AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
>
> ... because of ??? Nowadays - with X86_FEATURE_ERMS - rep stosb
> is expected to be faster than rep stosl.

OK, I did not know about that. However, as I know this feature
was introduced in 2012 with Ivy Bridge. So, I suppose that there
are still a lot of machines in the wild which does not support it.
Anyway, because this code is not performance critical I am not going
to insist on one or another solution. However, Andrew suggested that
thing, so, please agree with him in which direction we should go.
I will do what you agree.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
  2015-07-21 17:23     ` Daniel Kiper
@ 2015-07-22  5:14       ` Jan Beulich
  2015-07-22  8:02       ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-07-22  5:14 UTC (permalink / raw)
  To: daniel.kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> Daniel Kiper <daniel.kiper@oracle.com> 07/21/15 7:24 PM >>>
>On Tue, Jul 21, 2015 at 03:35:07AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
>>
>> Without any explanation (description) I'm inclined to say this makes
>> things more fragile instead of improving the situation. As it looks
>> like we indeed pointlessly copy .eh_frame, but I think this would
>> better be avoided by suppressing its generation (i.e. add
>> -fno-asynchronous-unwind-tables just like Rules.mk has).
>
>Make sense, however, there is still place for two small optimizations.
>
>First of all ld generates .got.plt section and objcopy copy it to binary file.
>It is not needed because we do not link our stuff here with shared libraries.
>So, we can use -R objcopy option to remove it (if you do not like -j .text).
>This way we could save 15 bytes (at least on my machines).

.got.plt shouldn't be generated in the first place (and I don't recall having
seen one here - I'll double check once in the office), i.e. perhaps another
missing compiler option or a linker quirk?

>We could also save another 3 bytes (per one xen/arch/x86/boot C input file)
>in final Xen binary in worst case :-))). We just need generate output assembly
>files as string of .byte instead of .long.

If you feel it worth your time, go ahead.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-21 18:23     ` Daniel Kiper
@ 2015-07-22  5:18       ` Jan Beulich
  2015-07-22  8:42         ` Andrew Cooper
  0 siblings, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-07-22  5:18 UTC (permalink / raw)
  To: daniel.kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> Daniel Kiper <daniel.kiper@oracle.com> 07/21/15 8:23 PM >>>
>On Tue, Jul 21, 2015 at 03:37:48AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
>>
>> ... because of ??? Nowadays - with X86_FEATURE_ERMS - rep stosb
>> is expected to be faster than rep stosl.
>
>OK, I did not know about that. However, as I know this feature
>was introduced in 2012 with Ivy Bridge. So, I suppose that there
>are still a lot of machines in the wild which does not support it.
>Anyway, because this code is not performance critical I am not going
>to insist on one or another solution. However, Andrew suggested that
>thing, so, please agree with him in which direction we should go.
>I will do what you agree.

ISTR having seen a similar patch from him(?), maybe in another area
of code, before (or was it v1 of this one?), which I responded to with the
same as above.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
  2015-07-21 17:23     ` Daniel Kiper
  2015-07-22  5:14       ` Jan Beulich
@ 2015-07-22  8:02       ` Jan Beulich
  2015-07-22 13:31         ` Daniel Kiper
  1 sibling, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-07-22  8:02 UTC (permalink / raw)
  To: Daniel Kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> On 21.07.15 at 19:23, <daniel.kiper@oracle.com> wrote:
> First of all ld generates .got.plt section and objcopy copy it to binary 
> file.
> It is not needed because we do not link our stuff here with shared 
> libraries.
> So, we can use -R objcopy option to remove it (if you do not like -j .text).
> This way we could save 15 bytes (at least on my machines).

So I checked and did find no .got.plt at all on a machine using
binutils 2.25 and an empty one on a machine using an older
version. So I'm curious what you're seeing present in that
table (without any of your patches applied).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-22  5:18       ` Jan Beulich
@ 2015-07-22  8:42         ` Andrew Cooper
  2015-07-22 10:04           ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Andrew Cooper @ 2015-07-22  8:42 UTC (permalink / raw)
  To: Jan Beulich, daniel.kiper; +Cc: xen-devel, keir

On 22/07/2015 06:18, Jan Beulich wrote:
>>>> Daniel Kiper <daniel.kiper@oracle.com> 07/21/15 8:23 PM >>>
>> On Tue, Jul 21, 2015 at 03:37:48AM -0600, Jan Beulich wrote:
>>>>>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:
>>> ... because of ??? Nowadays - with X86_FEATURE_ERMS - rep stosb
>>> is expected to be faster than rep stosl.
>> OK, I did not know about that. However, as I know this feature
>> was introduced in 2012 with Ivy Bridge. So, I suppose that there
>> are still a lot of machines in the wild which does not support it.
>> Anyway, because this code is not performance critical I am not going
>> to insist on one or another solution. However, Andrew suggested that
>> thing, so, please agree with him in which direction we should go.
>> I will do what you agree.
> ISTR having seen a similar patch from him(?), maybe in another area
> of code, before (or was it v1 of this one?), which I responded to with the
> same as above.

Indeed you have, several in fact.  I had not had chance to delve into
the optimisation manuals, but have taken a peek now.  (Section 3.7.6)

In the case of having aligned source and destination on a 16-byte
boundary (which we can trivially arrange), then ERMSB (to give it its
Intel name) and rep stosl differ only in the setup cost; they still
scale at the same rate for changes in length.

Therefore, assuming we arrange for 16-byte alignment, using rep stosl
would appear to be a single 60ish cycle hit over using ERMSB, but would
be substantially more efficient than using rep stosb on a non-ERMSB system.

Overall, I think 16 byte alignment and rep stosl is the best compromise.

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-22  8:42         ` Andrew Cooper
@ 2015-07-22 10:04           ` Jan Beulich
  2015-07-22 11:22             ` Andrew Cooper
  0 siblings, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-07-22 10:04 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel, daniel.kiper, keir

>>> On 22.07.15 at 10:42, <andrew.cooper3@citrix.com> wrote:
> In the case of having aligned source and destination on a 16-byte
> boundary (which we can trivially arrange), then ERMSB (to give it its
> Intel name) and rep stosl differ only in the setup cost; they still
> scale at the same rate for changes in length.
> 
> Therefore, assuming we arrange for 16-byte alignment, using rep stosl
> would appear to be a single 60ish cycle hit over using ERMSB, but would
> be substantially more efficient than using rep stosb on a non-ERMSB system.
> 
> Overall, I think 16 byte alignment and rep stosl is the best compromise.

Or leaving such code alone, with the assumption that over time the
setup cost (on a growing number of systems) outweighs the benefits
(on a shrinking set).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-22 10:04           ` Jan Beulich
@ 2015-07-22 11:22             ` Andrew Cooper
  2015-07-22 11:48               ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Andrew Cooper @ 2015-07-22 11:22 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, daniel.kiper, keir

On 22/07/15 11:04, Jan Beulich wrote:
>>>> On 22.07.15 at 10:42, <andrew.cooper3@citrix.com> wrote:
>> In the case of having aligned source and destination on a 16-byte
>> boundary (which we can trivially arrange), then ERMSB (to give it its
>> Intel name) and rep stosl differ only in the setup cost; they still
>> scale at the same rate for changes in length.
>>
>> Therefore, assuming we arrange for 16-byte alignment, using rep stosl
>> would appear to be a single 60ish cycle hit over using ERMSB, but would
>> be substantially more efficient than using rep stosb on a non-ERMSB system.
>>
>> Overall, I think 16 byte alignment and rep stosl is the best compromise.
> Or leaving such code alone, with the assumption that over time the
> setup cost (on a growing number of systems) outweighs the benefits
> (on a shrinking set).

The BSS is large - 295k on the last compile I have from staging.  The
setup cost is lost in the nose compared to the elapsed time to write
that many zeroes to memory.

Therefore, on an ERMBS-capable system, the two options will complete in
the same amount of time.

However, on all AMD hardware and Intel hardware older than IvyBridge,
rep stosl is 4 times faster than rep stosb.

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb
  2015-07-22 11:22             ` Andrew Cooper
@ 2015-07-22 11:48               ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-07-22 11:48 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel, daniel.kiper, keir

>>> On 22.07.15 at 13:22, <andrew.cooper3@citrix.com> wrote:
> On 22/07/15 11:04, Jan Beulich wrote:
>>>>> On 22.07.15 at 10:42, <andrew.cooper3@citrix.com> wrote:
>>> In the case of having aligned source and destination on a 16-byte
>>> boundary (which we can trivially arrange), then ERMSB (to give it its
>>> Intel name) and rep stosl differ only in the setup cost; they still
>>> scale at the same rate for changes in length.
>>>
>>> Therefore, assuming we arrange for 16-byte alignment, using rep stosl
>>> would appear to be a single 60ish cycle hit over using ERMSB, but would
>>> be substantially more efficient than using rep stosb on a non-ERMSB system.
>>>
>>> Overall, I think 16 byte alignment and rep stosl is the best compromise.
>> Or leaving such code alone, with the assumption that over time the
>> setup cost (on a growing number of systems) outweighs the benefits
>> (on a shrinking set).
> 
> The BSS is large - 295k on the last compile I have from staging.  The
> setup cost is lost in the nose compared to the elapsed time to write
> that many zeroes to memory.
> 
> Therefore, on an ERMBS-capable system, the two options will complete in
> the same amount of time.
> 
> However, on all AMD hardware and Intel hardware older than IvyBridge,
> rep stosl is 4 times faster than rep stosb.

Well, okay then.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
  2015-07-22  8:02       ` Jan Beulich
@ 2015-07-22 13:31         ` Daniel Kiper
  2015-07-22 14:07           ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-07-22 13:31 UTC (permalink / raw)
  To: Jan Beulich; +Cc: andrew.cooper3, keir, xen-devel

On Wed, Jul 22, 2015 at 02:02:11AM -0600, Jan Beulich wrote:
> >>> On 21.07.15 at 19:23, <daniel.kiper@oracle.com> wrote:
> > First of all ld generates .got.plt section and objcopy copy it to binary
> > file.
> > It is not needed because we do not link our stuff here with shared
> > libraries.
> > So, we can use -R objcopy option to remove it (if you do not like -j .text).
> > This way we could save 15 bytes (at least on my machines).
>
> So I checked and did find no .got.plt at all on a machine using
> binutils 2.25 and an empty one on a machine using an older
> version. So I'm curious what you're seeing present in that
> table (without any of your patches applied).

Here it is:

[...]

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00     0   0  0
  [ 1] .text             PROGBITS        00000000 000080 000705 00 WAX 0   0 16
  [ 2] .eh_frame         PROGBITS        00000708 000788 000104 00   A 0   0  4
  [ 3] .got.plt          PROGBITS        0000080c 00088c 00000c 04  WA 0   0  4
  [ 4] .comment          PROGBITS        00000000 000898 00001c 01  MS 0   0  1
  [ 5] .debug_aranges    PROGBITS        00000000 0008b4 000020 00     0   0  1
  [ 6] .debug_info       PROGBITS        00000000 0008d4 000c2c 00     0   0  1
  [ 7] .debug_abbrev     PROGBITS        00000000 001500 000303 00     0   0  1
  [ 8] .debug_line       PROGBITS        00000000 001803 000180 00     0   0  1
  [ 9] .debug_str        PROGBITS        00000000 001983 000236 01  MS 0   0  1
  [10] .debug_loc        PROGBITS        00000000 001bb9 0007b8 00     0   0  1
  [11] .debug_ranges     PROGBITS        00000000 002371 000030 00     0   0  1
  [12] .shstrtab         STRTAB          00000000 0023a1 000096 00     0   0  1
  [13] .symtab           SYMTAB          00000000 002690 000290 10    14  36  4
  [14] .strtab           STRTAB          00000000 002920 000162 00     0   0  1

[...]

It is generated using ld from binutils 2.22.

I was thinking that -static ld option would remove .got.plt but it did not.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file
  2015-07-22 13:31         ` Daniel Kiper
@ 2015-07-22 14:07           ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-07-22 14:07 UTC (permalink / raw)
  To: Daniel Kiper; +Cc: andrew.cooper3, keir, xen-devel

>>> On 22.07.15 at 15:31, <daniel.kiper@oracle.com> wrote:
> On Wed, Jul 22, 2015 at 02:02:11AM -0600, Jan Beulich wrote:
>> >>> On 21.07.15 at 19:23, <daniel.kiper@oracle.com> wrote:
>> > First of all ld generates .got.plt section and objcopy copy it to binary
>> > file.
>> > It is not needed because we do not link our stuff here with shared
>> > libraries.
>> > So, we can use -R objcopy option to remove it (if you do not like -j .text).
>> > This way we could save 15 bytes (at least on my machines).
>>
>> So I checked and did find no .got.plt at all on a machine using
>> binutils 2.25 and an empty one on a machine using an older
>> version. So I'm curious what you're seeing present in that
>> table (without any of your patches applied).
> 
> Here it is:
> 
> [...]
> 
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
>   [ 0]                   NULL            00000000 000000 000000 00     0   0  0
>   [ 1] .text             PROGBITS        00000000 000080 000705 00 WAX 0   0 16
>   [ 2] .eh_frame         PROGBITS        00000708 000788 000104 00   A 0   0  4
>   [ 3] .got.plt          PROGBITS        0000080c 00088c 00000c 04  WA 0   0  4

But how do I know what is in there, i.e. which symbols are causing
this non-zero size? Because that's what we want to deal with instead
of arbitrarily dropping (or picking) sections.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 01/23] x86/boot: remove unneeded instruction
       [not found] ` <1437402558-7313-2-git-send-email-daniel.kiper@oracle.com>
@ 2015-07-24 16:22   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150724162257.GB2220@l.oracle.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-07-24 16:22 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, Jul 20, 2015 at 04:28:56PM +0200, Daniel Kiper wrote:
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Don't you use it in:

    /* Switch to low-memory stack.  */                                      
193         mov     sym_phys(trampoline_phys),%edi                                  
194         lea     0x10000(%edi),%esp                                              
195         lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax   
?

> ---
>  xen/arch/x86/boot/head.S |    1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index cfd59dc..f63b349 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -169,7 +169,6 @@ __start:
>          /* Apply relocations to bootstrap trampoline. */
>          mov     sym_phys(trampoline_phys),%edx
>          mov     $sym_phys(__trampoline_rel_start),%edi
> -        mov     %edx,sym_phys(trampoline_phys)
>  1:
>          mov     (%edi),%eax
>          add     %edx,(%edi,%eax)
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 01/23] x86/boot: remove unneeded instruction
       [not found]   ` <20150724162257.GB2220@l.oracle.com>
@ 2015-07-27 19:46     ` Daniel Kiper
       [not found]     ` <20150727194608.GB3492@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-07-27 19:46 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Jul 24, 2015 at 12:22:57PM -0400, Konrad Rzeszutek Wilk wrote:
> On Mon, Jul 20, 2015 at 04:28:56PM +0200, Daniel Kiper wrote:
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> Don't you use it in:
>
>     /* Switch to low-memory stack.  */
> 193         mov     sym_phys(trampoline_phys),%edi
> 194         lea     0x10000(%edi),%esp
> 195         lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
> ?

Yep, but...

> > ---
> >  xen/arch/x86/boot/head.S |    1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index cfd59dc..f63b349 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -169,7 +169,6 @@ __start:
> >          /* Apply relocations to bootstrap trampoline. */
> >          mov     sym_phys(trampoline_phys),%edx

...relevant value is stored in sym_phys(trampoline_phys) earlier then it is
read into %edx here and...

> >          mov     $sym_phys(__trampoline_rel_start),%edi
> > -        mov     %edx,sym_phys(trampoline_phys)

...it is put back to sym_phys(trampoline_phys) without any change here :-))).
So, I suppose this is remnant from something which was removed once but
somebody forgot to remove this instruction too... This patch fixes it.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 01/23] x86/boot: remove unneeded instruction
       [not found]     ` <20150727194608.GB3492@olila.local.net-space.pl>
@ 2015-08-10 16:07       ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 16:07 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, Jul 27, 2015 at 09:46:08PM +0200, Daniel Kiper wrote:
> On Fri, Jul 24, 2015 at 12:22:57PM -0400, Konrad Rzeszutek Wilk wrote:
> > On Mon, Jul 20, 2015 at 04:28:56PM +0200, Daniel Kiper wrote:
> > > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> >
> > Don't you use it in:
> >
> >     /* Switch to low-memory stack.  */
> > 193         mov     sym_phys(trampoline_phys),%edi
> > 194         lea     0x10000(%edi),%esp
> > 195         lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
> > ?
> 
> Yep, but...
> 
> > > ---
> > >  xen/arch/x86/boot/head.S |    1 -
> > >  1 file changed, 1 deletion(-)
> > >
> > > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > > index cfd59dc..f63b349 100644
> > > --- a/xen/arch/x86/boot/head.S
> > > +++ b/xen/arch/x86/boot/head.S
> > > @@ -169,7 +169,6 @@ __start:
> > >          /* Apply relocations to bootstrap trampoline. */
> > >          mov     sym_phys(trampoline_phys),%edx
> 
> ...relevant value is stored in sym_phys(trampoline_phys) earlier then it is
> read into %edx here and...
> 
> > >          mov     $sym_phys(__trampoline_rel_start),%edi
> > > -        mov     %edx,sym_phys(trampoline_phys)
> 
> ...it is put back to sym_phys(trampoline_phys) without any change here :-))).
> So, I suppose this is remnant from something which was removed once but
> somebody forgot to remove this instruction too... This patch fixes it.

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention
       [not found] ` <1437402558-7313-5-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 16:33   ` Konrad Rzeszutek Wilk
  2015-08-17 15:44   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 16:33 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:28:59PM +0200, Daniel Kiper wrote:
> Suggested-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

> ---
>  xen/arch/x86/boot/head.S  |    4 +++-
>  xen/arch/x86/boot/reloc.c |   20 ++++++++++++++++----
>  2 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index ed42782..3cbb2e6 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -119,8 +119,10 @@ __start:
>  
>          /* Save the Multiboot info struct (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
> -        push    %ebx
> +        push    %ebx                /* Multiboot information address. */
> +        push    %eax                /* Boot trampoline address. */
>          call    reloc
> +        add     $8,%esp             /* Remove reloc() args from stack. */
>          mov     %eax,sym_phys(multiboot_ptr)
>  
>          /* Initialize BSS (no nasty surprises!). */
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index 63045c0..708898f 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -10,15 +10,27 @@
>   *    Keir Fraser <keir@xen.org>
>   */
>  
> -/* entered with %eax = BOOT_TRAMPOLINE */
> +/*
> + * This entry point is entered from xen/arch/x86/boot/head.S with:
> + *   - 0x4(%esp) = BOOT_TRAMPOLINE_ADDRESS,
> + *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS.
> + */
>  asm (
>      "    .text                         \n"
>      "    .globl _start                 \n"
>      "_start:                           \n"
> +    "    push %ebp                     \n"
> +    "    mov  %esp,%ebp                \n"
>      "    call 1f                       \n"
> -    "1:  pop  %ebx                     \n"
> -    "    mov  %eax,alloc-1b(%ebx)      \n"
> -    "    jmp  reloc                    \n"
> +    "1:  pop  %ecx                     \n"
> +    "    mov  0x8(%ebp),%eax           \n"
> +    "    mov  %eax,alloc-1b(%ecx)      \n"
> +    "    mov  0xc(%ebp),%eax           \n"
> +    "    push %eax                     \n"
> +    "    call reloc                    \n"
> +    "    add  $4,%esp                  \n"
> +    "    pop  %ebp                     \n"
> +    "    ret                           \n"
>      );
>  
>  /*
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 06/23] x86/boot: use %ecx instead of %eax
       [not found] ` <1437402558-7313-7-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 16:36   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 16:36 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:01PM +0200, Daniel Kiper wrote:
> Use %ecx instead of %eax to store low memory upper limit from EBDA.
> This way we do not wipe multiboot protocol identifier. It is needed
> in reloc() to differentiate between multiboot (v1) and
> multiboot2 protocol.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
>  xen/arch/x86/boot/head.S |   24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 3cbb2e6..77e7da9 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -87,14 +87,14 @@ __start:
>          jne     not_multiboot
>  
>          /* Set up trampoline segment 64k below EBDA */
> -        movzwl  0x40e,%eax          /* EBDA segment */
> -        cmp     $0xa000,%eax        /* sanity check (high) */
> +        movzwl  0x40e,%ecx          /* EBDA segment */
> +        cmp     $0xa000,%ecx        /* sanity check (high) */
>          jae     0f
> -        cmp     $0x4000,%eax        /* sanity check (low) */
> +        cmp     $0x4000,%ecx        /* sanity check (low) */
>          jae     1f
>  0:
> -        movzwl  0x413,%eax          /* use base memory size on failure */
> -        shl     $10-4,%eax
> +        movzwl  0x413,%ecx          /* use base memory size on failure */
> +        shl     $10-4,%ecx
>  1:
>          /*
>           * Compare the value in the BDA with the information from the
> @@ -106,21 +106,21 @@ __start:
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
>          jb      2f                  /* if so, do not use it */
>          shl     $10-4,%edx
> -        cmp     %eax,%edx           /* compare with BDA value */
> -        cmovb   %edx,%eax           /* and use the smaller */
> +        cmp     %ecx,%edx           /* compare with BDA value */
> +        cmovb   %edx,%ecx           /* and use the smaller */
>  
>  2:      /* Reserve 64kb for the trampoline */
> -        sub     $0x1000,%eax
> +        sub     $0x1000,%ecx
>  
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
> -        xor     %al, %al
> -        shl     $4, %eax
> -        mov     %eax,sym_phys(trampoline_phys)
> +        xor     %cl, %cl
> +        shl     $4, %ecx
> +        mov     %ecx,sym_phys(trampoline_phys)
>  
>          /* Save the Multiboot info struct (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
>          push    %ebx                /* Multiboot information address. */
> -        push    %eax                /* Boot trampoline address. */
> +        push    %ecx                /* Boot trampoline address. */
>          call    reloc
>          add     $8,%esp             /* Remove reloc() args from stack. */
>          mov     %eax,sym_phys(multiboot_ptr)
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit
       [not found] ` <1437402558-7313-8-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 16:40   ` Konrad Rzeszutek Wilk
  2015-08-17 15:55   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 16:40 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:02PM +0200, Daniel Kiper wrote:
> Rename mbi and mbi_old variables and rearrange code a bit to make

s/mbi_old/mbi_in/

Perhaps you want to say: rename mbi_old with mbi_in, and mbi with mbi_out

or better:

Replace mbi with mbi_out and mbi_old with mbi_in and ...


> it more readable. Additionally, this way multiboot (v1) protocol
> implementation and future multiboot2 protocol implementation will
> use the same variable naming convention.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - extract this change from main mutliboot2
>      protocol implementation
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/boot/reloc.c |   39 +++++++++++++++++++++------------------
>  1 file changed, 21 insertions(+), 18 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index 09fd540..feb1d72 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -86,41 +86,44 @@ static u32 copy_string(u32 src)
>      return copy_mem(src, p - src + 1);
>  }
>  
> -multiboot_info_t *reloc(u32 mbi_old)
> +multiboot_info_t *reloc(u32 mbi_in)
>  {
> -    multiboot_info_t *mbi = (multiboot_info_t *)copy_mem(mbi_old, sizeof(*mbi));
>      int i;
> +    multiboot_info_t *mbi_out;
>  
> -    if ( mbi->flags & MBI_CMDLINE )
> -        mbi->cmdline = copy_string(mbi->cmdline);
> +    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));
>  
> -    if ( mbi->flags & MBI_MODULES )
> +    if ( mbi_out->flags & MBI_CMDLINE )
> +        mbi_out->cmdline = copy_string(mbi_out->cmdline);
> +
> +    if ( mbi_out->flags & MBI_MODULES )
>      {
>          module_t *mods;
>  
> -        mbi->mods_addr = copy_mem(mbi->mods_addr, mbi->mods_count * sizeof(module_t));
> +        mbi_out->mods_addr = copy_mem(mbi_out->mods_addr,
> +                                      mbi_out->mods_count * sizeof(module_t));
>  
> -        mods = (module_t *)mbi->mods_addr;
> +        mods = (module_t *)mbi_out->mods_addr;
>  
> -        for ( i = 0; i < mbi->mods_count; i++ )
> +        for ( i = 0; i < mbi_out->mods_count; i++ )
>          {
>              if ( mods[i].string )
>                  mods[i].string = copy_string(mods[i].string);
>          }
>      }
>  
> -    if ( mbi->flags & MBI_MEMMAP )
> -        mbi->mmap_addr = copy_mem(mbi->mmap_addr, mbi->mmap_length);
> +    if ( mbi_out->flags & MBI_MEMMAP )
> +        mbi_out->mmap_addr = copy_mem(mbi_out->mmap_addr, mbi_out->mmap_length);
>  
> -    if ( mbi->flags & MBI_LOADERNAME )
> -        mbi->boot_loader_name = copy_string(mbi->boot_loader_name);
> +    if ( mbi_out->flags & MBI_LOADERNAME )
> +        mbi_out->boot_loader_name = copy_string(mbi_out->boot_loader_name);
>  
>      /* Mask features we don't understand or don't relocate. */
> -    mbi->flags &= (MBI_MEMLIMITS |
> -                   MBI_CMDLINE |
> -                   MBI_MODULES |
> -                   MBI_MEMMAP |
> -                   MBI_LOADERNAME);
> +    mbi_out->flags &= (MBI_MEMLIMITS |
> +                       MBI_CMDLINE |
> +                       MBI_MODULES |
> +                       MBI_MEMMAP |
> +                       MBI_LOADERNAME);
>  
> -    return mbi;
> +    return mbi_out;
>  }
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
  2015-07-20 14:29 ` [PATCH v2 08/23] x86: add multiboot2 protocol support Daniel Kiper
@ 2015-08-10 19:17   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150810191747.GE13576@l.oracle.com>
  2015-08-18  8:12   ` Jan Beulich
  2 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:17 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:03PM +0200, Daniel Kiper wrote:
> Add multiboot2 protocol support. Alter min memory limit handling as we
> now may not find it from either multiboot (v1) or multiboot2.
> 
> This way we are laying the foundation for EFI + GRUB2 + Xen development.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> v2 - suggestions/fixes:
>    - generate multiboot2 header using macros
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich),
>    - simplify assembly in xen/arch/x86/boot/head.S
>      (suggested by Jan Beulich),
>    - do not include include/xen/compiler.h
>      in xen/arch/x86/boot/reloc.c
>      (suggested by Jan Beulich),
>    - do not read data beyond the end of Multiboot2 information
>      (suggested by Jan Beulich).
> 
> v2 - not fixed yet:

You have two 'v2' 

>    - dynamic dependency generation for xen/arch/x86/boot/reloc.S;
>      this requires more work; I am not sure that it pays because
>      potential patch requires more changes than addition of just
>      multiboot2.h to Makefile
>      (suggested by Jan Beulich),
>    - isolated/stray __packed attribute usage for multiboot2_memory_map_t
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/boot/Makefile        |    3 +-
>  xen/arch/x86/boot/head.S          |  105 +++++++++++++++++++++--
>  xen/arch/x86/boot/reloc.c         |  146 +++++++++++++++++++++++++++++++-
>  xen/arch/x86/x86_64/asm-offsets.c |    7 ++
>  xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 420 insertions(+), 10 deletions(-)
>  create mode 100644 xen/include/xen/multiboot2.h
> 
> diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
> index 5fdb5ae..06893d8 100644
> --- a/xen/arch/x86/boot/Makefile
> +++ b/xen/arch/x86/boot/Makefile
> @@ -1,6 +1,7 @@
>  obj-bin-y += head.o
>  
> -RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h
> +RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
> +	     $(BASEDIR)/include/xen/multiboot2.h
>  
>  head.o: reloc.S
>  
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 77e7da9..57197db 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -1,5 +1,6 @@
>  #include <xen/config.h>
>  #include <xen/multiboot.h>
> +#include <xen/multiboot2.h>
>  #include <public/xen.h>
>  #include <asm/asm_defns.h>
>  #include <asm/desc.h>
> @@ -19,6 +20,28 @@
>  #define BOOT_PSEUDORM_CS 0x0020
>  #define BOOT_PSEUDORM_DS 0x0028
>  
> +#define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
> +#define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
> +
> +        .macro mb2ht_args arg, args:vararg
> +        .long \arg
> +        .ifnb \args
> +        mb2ht_args \args
> +        .endif
> +        .endm
> +
> +        .macro mb2ht_init type, req, args:vararg
> +        .align MULTIBOOT2_TAG_ALIGN
> +        0:
> +        .short \type
> +        .short \req
> +        .long 1f - 0b
> +        .ifnb \args
> +        mb2ht_args \args
> +        .endif
> +        1:
> +        .endm
> +
>  ENTRY(start)
>          jmp     __start
>  
> @@ -34,6 +57,42 @@ multiboot1_header_start:       /*** MULTIBOOT1 HEADER ****/
>          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
>  multiboot1_header_end:
>  
> +/*** MULTIBOOT2 HEADER ****/
> +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
> +        .align  MULTIBOOT2_HEADER_ALIGN
> +
> +.Lmultiboot2_header:

How come you use .L? It makes this hidden while the multiboot1 headers
are visible? Makes it a bit harder to see the contents of this under
an debugger.

> +        /* Magic number indicating a Multiboot2 header. */
> +        .long   MULTIBOOT2_HEADER_MAGIC
> +        /* Architecture: i386. */
> +        .long   MULTIBOOT2_ARCHITECTURE_I386
> +        /* Multiboot2 header length. */
> +        .long   .Lmultiboot2_header_end - .Lmultiboot2_header
> +        /* Multiboot2 header checksum. */
> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> +                        (.Lmultiboot2_header_end - .Lmultiboot2_header))
> +
> +        /* Multiboot2 information request tag. */
> +        mb2ht_init MB2_HT(INFORMATION_REQUEST), MB2_HT(REQUIRED), \
> +                   MB2_TT(BASIC_MEMINFO), MB2_TT(MMAP)
> +
> +        /* Align modules at page boundry. */
> +        mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
> +
> +        /* Console flags tag. */
> +        mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
> +                   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> +
> +        /* Framebuffer tag. */
> +        mb2ht_init MB2_HT(FRAMEBUFFER), MB2_HT(OPTIONAL), \
> +                   0, /* Number of the columns - no preference. */ \
> +                   0, /* Number of the lines - no preference. */ \
> +                   0  /* Number of bits per pixel - no preference. */
> +
> +        /* Multiboot2 header end tag. */
> +        mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
> +.Lmultiboot2_header_end:
> +
>          .section .init.rodata, "a", @progbits
>          .align 4
>  
> @@ -82,10 +141,48 @@ __start:
>          mov     %ecx,%es
>          mov     %ecx,%ss
>  
> -        /* Check for Multiboot bootloader */
> +        /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
> +        xor     %edx,%edx
> +
> +        /* Check for Multiboot2 bootloader. */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      multiboot2_proto
> +
> +        /* Check for Multiboot bootloader. */
>          cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
>          jne     not_multiboot
>  
> +        /* Get mem_lower from Multiboot information. */
> +        testb   $MBI_MEMLIMITS,MB_flags(%ebx)
> +
> +        /* Not available? BDA value will be fine. */
> +        cmovnz  MB_mem_lower(%ebx),%edx
> +        jmp     trampoline_setup
> +
> +multiboot2_proto:
> +        /* Skip Multiboot2 information fixed part. */
> +        lea     MB2_fixed_sizeof(%ebx),%ecx

Is there any point of double checking the aligment? That is
        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx

?

Looking at the grub code it requests the memory to be aligned properly
so in practice this will never fail. But since somebody might for fun
allocate the structure to not be aligned and the fixed part could finish
on non-aligned space..
> +
> +0:
> +        /* Get mem_lower from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)

.. which would throw this off..

> +        jne     1f
> +
> +        mov     MB2_mem_lower(%ecx),%edx
> +        jmp     trampoline_setup
> +
> +1:
> +        /* Is it the end of Multiboot2 information? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
> +        je      trampoline_setup
> +
> +        /* 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
> +
> +trampoline_setup:
>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -100,9 +197,6 @@ __start:
>           * Compare the value in the BDA with the information from the
>           * multiboot structure (if available) and use the smallest.
>           */
> -        testb   $MBI_MEMLIMITS,(%ebx)
> -        jz      2f                  /* not available? BDA value will be fine */
> -        mov     MB_mem_lower(%ebx),%edx
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
>          jb      2f                  /* if so, do not use it */
>          shl     $10-4,%edx
> @@ -119,10 +213,11 @@ __start:
>  
>          /* Save the Multiboot info struct (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
> +        push    %eax                /* Multiboot magic. */
>          push    %ebx                /* Multiboot information address. */
>          push    %ecx                /* Boot trampoline address. */
>          call    reloc
> -        add     $8,%esp             /* Remove reloc() args from stack. */
> +        add     $12,%esp            /* Remove reloc() args from stack. */
>          mov     %eax,sym_phys(multiboot_ptr)
>  
>          /* Initialize BSS (no nasty surprises!). */
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index feb1d72..41b1cc0 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -5,15 +5,18 @@
>   * and modules. This is most easily done early with paging disabled.
>   *
>   * Copyright (c) 2009, Citrix Systems, Inc.
> + * Copyright (c) 2013, 2014, 2015 Oracle Co.
>   *
>   * Authors:
>   *    Keir Fraser <keir@xen.org>
> + *    Daniel Kiper <daniel.kiper@oracle.com>
>   */
>  
>  /*
>   * This entry point is entered from xen/arch/x86/boot/head.S with:
>   *   - 0x4(%esp) = BOOT_TRAMPOLINE_ADDRESS,
> - *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS.
> + *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
> + *   - 0xc(%esp) = MULTIBOOT_MAGIC.
>   */
>  asm (
>      "    .text                         \n"
> @@ -25,10 +28,12 @@ asm (
>      "1:  pop  %ecx                     \n"
>      "    mov  0x8(%ebp),%eax           \n"
>      "    mov  %eax,alloc-1b(%ecx)      \n"
> +    "    mov  0x10(%ebp),%eax          \n"
> +    "    push %eax                     \n"
>      "    mov  0xc(%ebp),%eax           \n"
>      "    push %eax                     \n"
>      "    call reloc                    \n"
> -    "    add  $4,%esp                  \n"
> +    "    add  $8,%esp                  \n"
>      "    pop  %ebp                     \n"
>      "    ret                           \n"
>      );
> @@ -43,7 +48,15 @@ asm (
>      );
>  
>  typedef unsigned int u32;
> +typedef unsigned long long u64;
> +
>  #include "../../../include/xen/multiboot.h"
> +#include "../../../include/xen/multiboot2.h"
> +
> +#define ALIGN_UP(addr, align) \
> +                (((addr) + (typeof(addr))(align) - 1) & ~((typeof(addr))(align) - 1))
> +
> +#define get_mb2_data(tag, type, member) (((type *)(tag))->member)
>  
>  static u32 alloc_mem(u32 bytes)
>  {
> @@ -61,6 +74,11 @@ static u32 alloc_mem(u32 bytes)
>      return s;
>  }
>  
> +static void zero_mem(u32 s, u32 bytes)
> +{
> +    asm volatile("rep stosb" : "+D" (s), "+c" (bytes) : "a" (0) : "memory");
> +}
> +
>  static u32 copy_mem(u32 src, u32 bytes)
>  {
>      u32 dst, dst_asm;
> @@ -86,12 +104,12 @@ static u32 copy_string(u32 src)
>      return copy_mem(src, p - src + 1);
>  }
>  
> -multiboot_info_t *reloc(u32 mbi_in)
> +static multiboot_info_t *mbi_mbi(void *mbi_in)
>  {
>      int i;
>      multiboot_info_t *mbi_out;
>  
> -    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));
> +    mbi_out = (multiboot_info_t *)copy_mem((u32)mbi_in, sizeof(*mbi_out));
>  
>      if ( mbi_out->flags & MBI_CMDLINE )
>          mbi_out->cmdline = copy_string(mbi_out->cmdline);
> @@ -127,3 +145,123 @@ multiboot_info_t *reloc(u32 mbi_in)
>  
>      return mbi_out;
>  }
> +
> +static multiboot_info_t *mbi2_mbi(void *mbi_in)
> +{
> +    /* Do not complain that mbi_out_mods is not initialized. */
> +    module_t *mbi_out_mods = (module_t *)0;
> +    memory_map_t *mmap_dst;
> +    multiboot2_memory_map_t *mmap_src;
> +    multiboot2_tag_t *tag;
> +    multiboot_info_t *mbi_out;
> +    u32 ptr;
> +    unsigned int i, mod_idx = 0;
> +
> +    mbi_out = (multiboot_info_t *)alloc_mem(sizeof(*mbi_out));
> +    zero_mem((u32)mbi_out, sizeof(*mbi_out));
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi_in + sizeof(multiboot2_fixed_t);
> +

Could you add:

/* First we need to get the number of modules: */

> +    for ( ; ; )
> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> +            ++mbi_out->mods_count;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> +        {
> +            mbi_out->flags = MBI_MODULES;
> +            mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(module_t));
> +            mbi_out_mods = (module_t *)mbi_out->mods_addr;

> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +
> +        /* Check Multiboot2 information total size just in case. */
> +	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
> +            break;

This looks to be using the wrong amount of spaces.

> +    }
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi_in + sizeof(multiboot2_fixed_t);
> +
> +    for ( ; ; )
> +    {
> +        switch ( tag->type )
> +        {
> +        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
> +            mbi_out->flags |= MBI_LOADERNAME;
> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);
> +            mbi_out->boot_loader_name = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_CMDLINE:
> +            mbi_out->flags |= MBI_CMDLINE;
> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);
> +            mbi_out->cmdline = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
> +            mbi_out->flags |= MBI_MEMLIMITS;
> +            mbi_out->mem_lower = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_lower);
> +            mbi_out->mem_upper = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_upper);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MMAP:
> +            mbi_out->flags |= MBI_MEMMAP;
> +            mbi_out->mmap_length = get_mb2_data(tag, multiboot2_tag_mmap_t, size);
> +            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
> +            mbi_out->mmap_length += sizeof(((multiboot2_tag_mmap_t){0}).entries);
> +            mbi_out->mmap_length /= get_mb2_data(tag, multiboot2_tag_mmap_t, entry_size);
> +            mbi_out->mmap_length *= sizeof(memory_map_t);
> +
> +            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);
> +
> +            mmap_src = get_mb2_data(tag, multiboot2_tag_mmap_t, entries);
> +            mmap_dst = (memory_map_t *)mbi_out->mmap_addr;
> +
> +            for ( i = 0; i < mbi_out->mmap_length / sizeof(memory_map_t); ++i )

The other loops use 'i++'. Could it be the same type?

> +            {
> +                mmap_dst[i].size = sizeof(memory_map_t);
> +                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);

Could you add a comment like this please:?

/* 'size' does not exist in MB2, but __start_xen requires it to enumerate
 * properly. */

> +                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
> +                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
> +                mmap_dst[i].length_low = (u32)mmap_src[i].len;
> +                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
> +                mmap_dst[i].type = mmap_src[i].type;
> +            }
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MODULE:
> +            mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, multiboot2_tag_module_t, mod_start);
> +            mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, multiboot2_tag_module_t, mod_end);
> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_module_t, cmdline);
> +            mbi_out_mods[mod_idx].string = copy_string(ptr);
> +            mbi_out_mods[mod_idx].reserved = 0;
> +            ++mod_idx;
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_END:
> +            return mbi_out;
> +
> +        default:
> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +
> +        /* Check Multiboot2 information total size just in case. */
> +	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
> +            return mbi_out;

Not enough spaces.

> +    }
> +}
> +
> +static multiboot_info_t __attribute__((__used__)) *reloc(void *mbi_in, u32 mb_magic)
> +{
> +    if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC )
> +        return mbi2_mbi(mbi_in);
> +    else
> +        return mbi_mbi(mbi_in);
> +}
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index 447c650..b926082 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -13,6 +13,7 @@
>  #include <asm/fixmap.h>
>  #include <asm/hardirq.h>
>  #include <xen/multiboot.h>
> +#include <xen/multiboot2.h>
>  
>  #define DEFINE(_sym, _val)                                                 \
>      asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
> @@ -166,4 +167,10 @@ void __dummy__(void)
>      OFFSET(MB_flags, multiboot_info_t, flags);
>      OFFSET(MB_cmdline, multiboot_info_t, cmdline);
>      OFFSET(MB_mem_lower, multiboot_info_t, mem_lower);
> +    BLANK();
> +
> +    DEFINE(MB2_fixed_sizeof, sizeof(multiboot2_fixed_t));
> +    OFFSET(MB2_tag_type, multiboot2_tag_t, type);
> +    OFFSET(MB2_tag_size, multiboot2_tag_t, size);
> +    OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
>  }
> diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
> new file mode 100644
> index 0000000..09ee64e
> --- /dev/null
> +++ b/xen/include/xen/multiboot2.h
> @@ -0,0 +1,169 @@
> +/*
> + *  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
> + *
> + *  multiboot2.h - Multiboot 2 header file.
> + *
> + *  Based on grub-2.00/include/multiboot2.h file.
> + *
> + *  Permission is hereby granted, free of charge, to any person obtaining a copy
> + *  of this software and associated documentation files (the "Software"), to
> + *  deal in the Software without restriction, including without limitation the
> + *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
> + *  sell copies of the Software, and to permit persons to whom the Software is
> + *  furnished to do so, subject to the following conditions:
> + *
> + *  The above copyright notice and this permission notice shall be included in
> + *  all copies or substantial portions of the Software.
> + *
> + *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
> + *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
> + *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef __MULTIBOOT2_H__
> +#define __MULTIBOOT2_H__
> +
> +/* The magic field should contain this.  */
> +#define MULTIBOOT2_HEADER_MAGIC			0xe85250d6
> +
> +/* This should be in %eax on x86 architecture.  */
> +#define MULTIBOOT2_BOOTLOADER_MAGIC		0x36d76289
> +
> +/* How many bytes from the start of the file we search for the header.  */
> +#define MULTIBOOT2_SEARCH			32768
> +
> +/* Multiboot 2 header alignment. */
> +#define MULTIBOOT2_HEADER_ALIGN			8
> +
> +/* Alignment of multiboot 2 modules.  */
> +#define MULTIBOOT2_MOD_ALIGN			0x00001000
> +
> +/* Alignment of the multiboot 2 info structure.  */
> +#define MULTIBOOT2_INFO_ALIGN			0x00000008
> +
> +/* Multiboot 2 architectures. */
> +#define MULTIBOOT2_ARCHITECTURE_I386	0
> +#define MULTIBOOT2_ARCHITECTURE_MIPS32	4
> +
> +/* Header tag types. */
> +#define MULTIBOOT2_HEADER_TAG_END			0
> +#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST	1
> +#define MULTIBOOT2_HEADER_TAG_ADDRESS			2
> +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS		3
> +#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS		4
> +#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER		5
> +#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN		6
> +#define MULTIBOOT2_HEADER_TAG_EFI_BS			7
> +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32	8
> +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64	9
> +
> +/* Header tag flags. */
> +#define MULTIBOOT2_HEADER_TAG_REQUIRED	0
> +#define MULTIBOOT2_HEADER_TAG_OPTIONAL	1
> +
> +/* Header console tag console_flags. */
> +#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED	1
> +#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED	2
> +
> +/* Flags set in the 'flags' member of the multiboot header.  */
> +#define MULTIBOOT2_TAG_TYPE_END			0
> +#define MULTIBOOT2_TAG_TYPE_CMDLINE		1
> +#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME	2
> +#define MULTIBOOT2_TAG_TYPE_MODULE		3
> +#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO	4
> +#define MULTIBOOT2_TAG_TYPE_BOOTDEV		5
> +#define MULTIBOOT2_TAG_TYPE_MMAP		6
> +#define MULTIBOOT2_TAG_TYPE_VBE			7
> +#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER		8
> +#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS	9
> +#define MULTIBOOT2_TAG_TYPE_APM			10

In the grub code those all look actually in the same column.

I presume it is due to the '2'. But perhaps we can make this
whole file have the values at around the same column?

Also for the MULTIBOOT2_BOOTLOADER_MAGIC, ..MOD_ALIGN, INFO_ALIGN, etc.

> +#define MULTIBOOT2_TAG_TYPE_EFI32		11
> +#define MULTIBOOT2_TAG_TYPE_EFI64		12
> +#define MULTIBOOT2_TAG_TYPE_SMBIOS		13
> +#define MULTIBOOT2_TAG_TYPE_ACPI_OLD		14
> +#define MULTIBOOT2_TAG_TYPE_ACPI_NEW		15
> +#define MULTIBOOT2_TAG_TYPE_NETWORK		16
> +#define MULTIBOOT2_TAG_TYPE_EFI_MMAP		17
> +#define MULTIBOOT2_TAG_TYPE_EFI_BS		18
> +#define MULTIBOOT2_TAG_TYPE_EFI32_IH		19
> +#define MULTIBOOT2_TAG_TYPE_EFI64_IH		20
> +
> +/* Multiboot 2 tag alignment. */
> +#define MULTIBOOT2_TAG_ALIGN			8
> +
> +/* Memory types. */
> +#define MULTIBOOT2_MEMORY_AVAILABLE		1
> +#define MULTIBOOT2_MEMORY_RESERVED		2
> +#define MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE	3
> +#define MULTIBOOT2_MEMORY_NVS			4
> +#define MULTIBOOT2_MEMORY_BADRAM		5
> +
> +/* Framebuffer types. */
> +#define MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED	0
> +#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB		1
> +#define MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT	2

And these.


Otherwise,

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> +
> +#ifndef __ASSEMBLY__
> +typedef struct {
> +    u32 total_size;
> +    u32 reserved;
> +} multiboot2_fixed_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +} multiboot2_tag_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    char string[0];
> +} multiboot2_tag_string_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    u32 mem_lower;
> +    u32 mem_upper;
> +} multiboot2_tag_basic_meminfo_t;
> +
> +typedef struct __packed {
> +    u64 addr;
> +    u64 len;
> +    u32 type;
> +    u32 zero;
> +} multiboot2_memory_map_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    u32 entry_size;
> +    u32 entry_version;
> +    multiboot2_memory_map_t entries[0];
> +} multiboot2_tag_mmap_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    u64 pointer;
> +} multiboot2_tag_efi64_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    u64 pointer;
> +} multiboot2_tag_efi64_ih_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
> +    u32 mod_start;
> +    u32 mod_end;
> +    char cmdline[0];
> +} multiboot2_tag_module_t;
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* __MULTIBOOT2_H__ */
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 09/23] efi: create efi_enabled()
  2015-07-20 14:29 ` [PATCH v2 09/23] efi: create efi_enabled() Daniel Kiper
@ 2015-08-10 19:20   ` Konrad Rzeszutek Wilk
  2015-08-20 15:18   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:04PM +0200, Daniel Kiper wrote:
> We need more fine grained knowledge about EFI environment and check
> for EFI platform and EFI loader separately to properly support
> multiboot2 protocol. In general Xen loaded by this protocol uses
> memory mappings and loaded modules in similar way to Xen loaded
> by multiboot (v1) protocol. Hence, create efi_enabled() which
> checks available features in efi.flags. This patch only defines
> EFI_PLATFORM feature which is equal to old efi_enabled == 1.
> Following patch will define EFI_LOADER feature accordingly.
> 
> Suggested-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
>  xen/arch/x86/dmi_scan.c    |    4 ++--
>  xen/arch/x86/domain_page.c |    2 +-
>  xen/arch/x86/efi/stub.c    |   11 ++++++++---
>  xen/arch/x86/mpparse.c     |    4 ++--
>  xen/arch/x86/setup.c       |   10 +++++-----
>  xen/arch/x86/shutdown.c    |    2 +-
>  xen/arch/x86/time.c        |    2 +-
>  xen/arch/x86/xen.lds.S     |    2 --
>  xen/common/efi/boot.c      |    4 ++++
>  xen/common/efi/runtime.c   |   17 +++++++----------
>  xen/drivers/acpi/osl.c     |    2 +-
>  xen/include/xen/efi.h      |   16 ++++++++++++++--
>  12 files changed, 46 insertions(+), 30 deletions(-)
> 
> diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
> index 269168c..95c5a77 100644
> --- a/xen/arch/x86/dmi_scan.c
> +++ b/xen/arch/x86/dmi_scan.c
> @@ -229,7 +229,7 @@ const char *__init dmi_get_table(paddr_t *base, u32 *len)
>  {
>  	static unsigned int __initdata instance;
>  
> -	if (efi_enabled) {
> +	if (efi_enabled(EFI_PLATFORM)) {
>  		if (efi_smbios3_size && !(instance & 1)) {
>  			*base = efi_smbios3_address;
>  			*len = efi_smbios3_size;
> @@ -693,7 +693,7 @@ static void __init dmi_decode(struct dmi_header *dm)
>  
>  void __init dmi_scan_machine(void)
>  {
> -	if ((!efi_enabled ? dmi_iterate(dmi_decode) :
> +	if ((!efi_enabled(EFI_PLATFORM) ? dmi_iterate(dmi_decode) :
>  	                    dmi_efi_iterate(dmi_decode)) == 0)
>   		dmi_check_system(dmi_blacklist);
>  	else
> diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
> index d86f8fe..fdf0d8a 100644
> --- a/xen/arch/x86/domain_page.c
> +++ b/xen/arch/x86/domain_page.c
> @@ -36,7 +36,7 @@ static inline struct vcpu *mapcache_current_vcpu(void)
>       * domain's page tables but current may point at another domain's VCPU.
>       * Return NULL as though current is not properly set up yet.
>       */
> -    if ( efi_enabled && efi_rs_using_pgtables() )
> +    if ( efi_enabled(EFI_PLATFORM) && efi_rs_using_pgtables() )
>          return NULL;
>  
>      /*
> diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
> index 07c2bd0..c5ae369 100644
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -4,9 +4,14 @@
>  #include <xen/lib.h>
>  #include <asm/page.h>
>  
> -#ifndef efi_enabled
> -const bool_t efi_enabled = 0;
> -#endif
> +struct efi __read_mostly efi = {
> +	.flags   = 0, /* Initialized later. */
> +	.acpi    = EFI_INVALID_TABLE_ADDR,
> +	.acpi20  = EFI_INVALID_TABLE_ADDR,
> +	.mps     = EFI_INVALID_TABLE_ADDR,
> +	.smbios  = EFI_INVALID_TABLE_ADDR,
> +	.smbios3 = EFI_INVALID_TABLE_ADDR
> +};
>  
>  void __init efi_init_memory(void) { }
>  
> diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
> index 8609f4a..5223579 100644
> --- a/xen/arch/x86/mpparse.c
> +++ b/xen/arch/x86/mpparse.c
> @@ -557,7 +557,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
>  
>  static __init void efi_unmap_mpf(void)
>  {
> -	if (efi_enabled)
> +	if (efi_enabled(EFI_PLATFORM))
>  		clear_fixmap(FIX_EFI_MPF);
>  }
>  
> @@ -715,7 +715,7 @@ void __init find_smp_config (void)
>  {
>  	unsigned int address;
>  
> -	if (efi_enabled) {
> +	if (efi_enabled(EFI_PLATFORM)) {
>  		efi_check_config();
>  		return;
>  	}
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index ff34670..bce708c 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -444,8 +444,8 @@ static void __init parse_video_info(void)
>  {
>      struct boot_video_info *bvi = &bootsym(boot_vid_info);
>  
> -    /* The EFI loader fills vga_console_info directly. */
> -    if ( efi_enabled )
> +    /* vga_console_info is filled directly on EFI platform. */
> +    if ( efi_enabled(EFI_PLATFORM) )
>          return;
>  
>      if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
> @@ -695,7 +695,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
>          panic("dom0 kernel not specified. Check bootloader configuration.");
>  
> -    if ( efi_enabled )
> +    if ( efi_enabled(EFI_PLATFORM) )
>      {
>          set_pdx_range(xen_phys_start >> PAGE_SHIFT,
>                        (xen_phys_start + BOOTSTRAP_MAP_BASE) >> PAGE_SHIFT);
> @@ -806,7 +806,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * we can relocate the dom0 kernel and other multiboot modules. Also, on
>       * x86/64, we relocate Xen to higher memory.
>       */
> -    for ( i = 0; !efi_enabled && i < mbi->mods_count; i++ )
> +    for ( i = 0; !efi_enabled(EFI_PLATFORM) && i < mbi->mods_count; i++ )
>      {
>          if ( mod[i].mod_start & (PAGE_SIZE - 1) )
>              panic("Bootloader didn't honor module alignment request.");
> @@ -994,7 +994,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      if ( !xen_phys_start )
>          panic("Not enough memory to relocate Xen.");
> -    reserve_e820_ram(&boot_e820, efi_enabled ? mbi->mem_upper : __pa(&_start),
> +    reserve_e820_ram(&boot_e820, efi_enabled(EFI_PLATFORM) ? mbi->mem_upper : __pa(&_start),
>                       __pa(&_end));
>  
>      /* Late kexec reservation (dynamic start address). */
> diff --git a/xen/arch/x86/shutdown.c b/xen/arch/x86/shutdown.c
> index 0e1499d..79dcd16 100644
> --- a/xen/arch/x86/shutdown.c
> +++ b/xen/arch/x86/shutdown.c
> @@ -116,7 +116,7 @@ void machine_halt(void)
>  static void default_reboot_type(void)
>  {
>      if ( reboot_type == BOOT_INVALID )
> -        reboot_type = efi_enabled ? BOOT_EFI
> +        reboot_type = efi_enabled(EFI_PLATFORM) ? BOOT_EFI
>                                    : acpi_disabled ? BOOT_KBD
>                                                    : BOOT_ACPI;
>  }
> diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
> index bbb7e6c..11e7e11 100644
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -690,7 +690,7 @@ static unsigned long get_cmos_time(void)
>      static bool_t __read_mostly cmos_rtc_probe;
>      boolean_param("cmos-rtc-probe", cmos_rtc_probe);
>  
> -    if ( efi_enabled )
> +    if ( efi_enabled(EFI_PLATFORM) )
>      {
>          res = efi_get_time();
>          if ( res )
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index 3e1f2af..87f3e83 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -191,8 +191,6 @@ SECTIONS
>    .pad : {
>      . = ALIGN(MB(16));
>    } :text
> -#else
> -  efi = .;
>  #endif
>  
>    /* Sections to be discarded */
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 75a939f..1f188fe 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -717,6 +717,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      char *option_str;
>      bool_t use_cfg_file;
>  
> +#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
> +    set_bit(EFI_PLATFORM, &efi.flags);
> +#endif
> +
>      efi_ih = ImageHandle;
>      efi_bs = SystemTable->BootServices;
>      efi_bs_revision = efi_bs->Hdr.Revision;
> diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
> index ae87557..aa064e7 100644
> --- a/xen/common/efi/runtime.c
> +++ b/xen/common/efi/runtime.c
> @@ -10,14 +10,10 @@ DEFINE_XEN_GUEST_HANDLE(CHAR16);
>  
>  #ifndef COMPAT
>  
> -#ifdef CONFIG_ARM  /* Disabled until runtime services implemented */
> -const bool_t efi_enabled = 0;
> -#else
> +#ifndef CONFIG_ARM
>  # include <asm/i387.h>
>  # include <asm/xstate.h>
>  # include <public/platform.h>
> -
> -const bool_t efi_enabled = 1;
>  #endif
>  
>  unsigned int __read_mostly efi_num_ct;
> @@ -42,11 +38,12 @@ UINT64 __read_mostly efi_boot_remain_var_store_size;
>  UINT64 __read_mostly efi_boot_max_var_size;
>  
>  struct efi __read_mostly efi = {
> -	.acpi   = EFI_INVALID_TABLE_ADDR,
> -	.acpi20 = EFI_INVALID_TABLE_ADDR,
> -	.mps    = EFI_INVALID_TABLE_ADDR,
> -	.smbios = EFI_INVALID_TABLE_ADDR,
> -	.smbios3 = EFI_INVALID_TABLE_ADDR,
> +	.flags   = 0, /* Initialized later. */
> +	.acpi    = EFI_INVALID_TABLE_ADDR,
> +	.acpi20  = EFI_INVALID_TABLE_ADDR,
> +	.mps     = EFI_INVALID_TABLE_ADDR,
> +	.smbios  = EFI_INVALID_TABLE_ADDR,
> +	.smbios3 = EFI_INVALID_TABLE_ADDR
>  };
>  
>  const struct efi_pci_rom *__read_mostly efi_pci_roms;
> diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
> index 4c09859..f4f6628 100644
> --- a/xen/drivers/acpi/osl.c
> +++ b/xen/drivers/acpi/osl.c
> @@ -66,7 +66,7 @@ void __init acpi_os_vprintf(const char *fmt, va_list args)
>  
>  acpi_physical_address __init acpi_os_get_root_pointer(void)
>  {
> -	if (efi_enabled) {
> +	if (efi_enabled(EFI_PLATFORM)) {
>  		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
>  			return efi.acpi20;
>  		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
> diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
> index e74dad1..318bbec 100644
> --- a/xen/include/xen/efi.h
> +++ b/xen/include/xen/efi.h
> @@ -2,15 +2,17 @@
>  #define __XEN_EFI_H__
>  
>  #ifndef __ASSEMBLY__
> +#include <xen/bitops.h>
>  #include <xen/types.h>
>  #endif
>  
> -extern const bool_t efi_enabled;
> -
>  #define EFI_INVALID_TABLE_ADDR (~0UL)
>  
> +#define EFI_PLATFORM	0
> +
>  /* Add fields here only if they need to be referenced from non-EFI code. */
>  struct efi {
> +    unsigned long flags;
>      unsigned long mps;          /* MPS table */
>      unsigned long acpi;         /* ACPI table (IA64 ext 0.71) */
>      unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
> @@ -40,6 +42,16 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *);
>  int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *);
>  int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *);
>  
> +/*
> + * Test whether the above EFI_* bits are enabled.
> + *
> + * Stolen from Linux Kernel.
> + */
> +static inline bool_t efi_enabled(int feature)
> +{
> +    return test_bit(feature, &efi.flags) != 0;
> +}
> +
>  #endif /* !__ASSEMBLY__ */
>  
>  #endif /* __XEN_EFI_H__ */
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found] ` <1437402558-7313-11-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 19:24   ` Konrad Rzeszutek Wilk
  2015-08-20 15:39   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:24 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:05PM +0200, Daniel Kiper wrote:
> Build xen.gz with EFI code. We need this to support multiboot2
> protocol on EFI platforms.
> 
> If we wish to load not ELF file using multiboot (v1) or multiboot2 then
> it must contain "linear" (or "flat") representation of code and data.
> Currently, PE file contains many sections which are not "linear" (one
> after another without any holes) or even do not have representation
> in a file (e.g. BSS). In theory there is a chance that we could build
> proper PE file using current build system. However, it means that
> xen.efi further diverge from xen ELF file (in terms of contents and
> build method). ELF have all needed properties. So, it means that this
> is good starting point for further development. Additionally, I think
> that this is also good starting point for further xen.efi code and
> build optimizations. It looks that there is a chance that finally we
> can generate xen.efi directly from xen ELF using just simple objcopy.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - build EFI code only if it is supported in a given build environment
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/Makefile     |   13 +++++--------
>  xen/arch/x86/efi/Makefile |   16 +++++++++-------
>  xen/arch/x86/mm.c         |    3 ++-
>  xen/common/efi/runtime.c  |    6 ++++++
>  4 files changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> index 5f24951..0335445 100644
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -80,7 +80,7 @@ ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in
>  
>  ifeq ($(lto),y)
>  # Gather all LTO objects together
> -prelink_lto.o: $(ALL_OBJS)
> +prelink_lto.o: $(ALL_OBJS) efi/relocs-dummy.o
>  	$(LD_LTO) -r -o $@ $^
>  
>  prelink-efi_lto.o: $(ALL_OBJS) efi/runtime.o efi/compat.o
> @@ -90,14 +90,14 @@ prelink-efi_lto.o: $(ALL_OBJS) efi/runtime.o efi/compat.o
>  prelink.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink_lto.o
>  	$(LD) $(LDFLAGS) -r -o $@ $^
>  
> -prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink-efi_lto.o efi/boot.init.o
> +prelink-efi.o: $(patsubst %/built_in.o,%/built_in_bin.o,$(ALL_OBJS)) prelink-efi_lto.o
>  	$(guard) $(LD) $(LDFLAGS) -r -o $@ $^
>  else
> -prelink.o: $(ALL_OBJS)
> +prelink.o: $(ALL_OBJS) efi/relocs-dummy.o
>  	$(LD) $(LDFLAGS) -r -o $@ $^
>  
> -prelink-efi.o: $(ALL_OBJS) efi/boot.init.o efi/runtime.o efi/compat.o
> -	$(guard) $(LD) $(LDFLAGS) -r -o $@ $(filter-out %/efi/built_in.o,$^)
> +prelink-efi.o: $(ALL_OBJS)
> +	$(guard) $(LD) $(LDFLAGS) -r -o $@ $^
>  endif
>  
>  $(BASEDIR)/common/symbols-dummy.o:
> @@ -146,9 +146,6 @@ $(TARGET).efi: prelink-efi.o efi.lds efi/relocs-dummy.o $(BASEDIR)/common/symbol
>  	if $(guard) false; then rm -f $@; echo 'EFI support disabled'; fi
>  	rm -f $(@D)/.$(@F).[0-9]*
>  
> -efi/boot.init.o efi/runtime.o efi/compat.o: $(BASEDIR)/arch/x86/efi/built_in.o
> -efi/boot.init.o efi/runtime.o efi/compat.o: ;
> -
>  asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c
>  	$(CC) $(filter-out -flto,$(CFLAGS)) -S -o $@ $<
>  
> diff --git a/xen/arch/x86/efi/Makefile b/xen/arch/x86/efi/Makefile
> index 1daa7ac..b1e8883 100644
> --- a/xen/arch/x86/efi/Makefile
> +++ b/xen/arch/x86/efi/Makefile
> @@ -1,14 +1,16 @@
>  CFLAGS += -fshort-wchar
>  
> -obj-y += stub.o
> -
> -create = test -e $(1) || touch -t 199901010000 $(1)
> -
>  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
>  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
>  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
> -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
> +efi := $(if $(efi),$(shell rm disabled)y)
>  
> -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
> +extra-y += relocs-dummy.o
>  
> -stub.o: $(extra-y)
> +ifeq ($(efi),y)
> +obj-y += boot.init.o
> +obj-y += compat.o
> +obj-y += runtime.o
> +else
> +obj-y += stub.o
> +endif

That makefile magic I skipped over, but the C code below looks good, so

Half-Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>


> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 342414f..cef2eb6 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -344,7 +344,8 @@ void __init arch_init_memory(void)
>  
>      subarch_init_memory();
>  
> -    efi_init_memory();
> +    if ( efi_enabled(EFI_PLATFORM) )
> +        efi_init_memory();
>  
>      mem_sharing_init();
>  
> diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
> index aa064e7..3eb21c1 100644
> --- a/xen/common/efi/runtime.c
> +++ b/xen/common/efi/runtime.c
> @@ -167,6 +167,9 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
>  {
>      unsigned int i, n;
>  
> +    if ( !efi_enabled(EFI_PLATFORM) )
> +        return -EOPNOTSUPP;
> +
>      switch ( idx )
>      {
>      case XEN_FW_EFI_VERSION:
> @@ -301,6 +304,9 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
>      EFI_STATUS status = EFI_NOT_STARTED;
>      int rc = 0;
>  
> +    if ( !efi_enabled(EFI_PLATFORM) )
> +        return -EOPNOTSUPP;
> +
>      switch ( op->function )
>      {
>      case XEN_EFI_get_time:
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 11/23] efi: split out efi_init()
  2015-07-20 14:29 ` [PATCH v2 11/23] efi: split out efi_init() Daniel Kiper
@ 2015-08-10 19:25   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:25 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:06PM +0200, Daniel Kiper wrote:
> ..which initializes basic EFI variables. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   28 +++++++++++++++++-----------
>  1 file changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 1f188fe..6f327cd 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -595,6 +595,22 @@ static char *__init get_value(const struct file *cfg, const char *section,
>      return NULL;
>  }
>  
> +static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    efi_ih = ImageHandle;
> +    efi_bs = SystemTable->BootServices;
> +    efi_bs_revision = efi_bs->Hdr.Revision;
> +    efi_rs = SystemTable->RuntimeServices;
> +    efi_ct = SystemTable->ConfigurationTable;
> +    efi_num_ct = SystemTable->NumberOfTableEntries;
> +    efi_version = SystemTable->Hdr.Revision;
> +    efi_fw_vendor = SystemTable->FirmwareVendor;
> +    efi_fw_revision = SystemTable->FirmwareRevision;
> +
> +    StdOut = SystemTable->ConOut;
> +    StdErr = SystemTable->StdErr ?: StdOut;
> +}
> +
>  static void __init setup_efi_pci(void)
>  {
>      EFI_STATUS status;
> @@ -721,18 +737,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      set_bit(EFI_PLATFORM, &efi.flags);
>  #endif
>  
> -    efi_ih = ImageHandle;
> -    efi_bs = SystemTable->BootServices;
> -    efi_bs_revision = efi_bs->Hdr.Revision;
> -    efi_rs = SystemTable->RuntimeServices;
> -    efi_ct = SystemTable->ConfigurationTable;
> -    efi_num_ct = SystemTable->NumberOfTableEntries;
> -    efi_version = SystemTable->Hdr.Revision;
> -    efi_fw_vendor = SystemTable->FirmwareVendor;
> -    efi_fw_revision = SystemTable->FirmwareRevision;
> +    efi_init(ImageHandle, SystemTable);
>  
> -    StdOut = SystemTable->ConOut;
> -    StdErr = SystemTable->StdErr ?: StdOut;
>      use_cfg_file = efi_arch_use_config_file(SystemTable);
>  
>      status = efi_bs->HandleProtocol(ImageHandle, &loaded_image_guid,
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 12/23] efi: split out efi_console_set_mode()
       [not found] ` <1437402558-7313-13-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 19:25   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:25 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:07PM +0200, Daniel Kiper wrote:
> ..which sets console mode. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   37 ++++++++++++++++++++-----------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 6f327cd..4614146 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -611,6 +611,25 @@ static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTabl
>      StdErr = SystemTable->StdErr ?: StdOut;
>  }
>  
> +static void __init efi_console_set_mode(void)
> +{
> +    UINTN cols, rows, size;
> +    unsigned int best, i;
> +
> +    for ( i = 0, size = 0, best = StdOut->Mode->Mode;
> +          i < StdOut->Mode->MaxMode; ++i )
> +    {
> +        if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
> +             cols * rows > size )
> +        {
> +            size = cols * rows;
> +            best = i;
> +        }
> +    }
> +    if ( best != StdOut->Mode->Mode )
> +        StdOut->SetMode(StdOut, best);
> +}
> +
>  static void __init setup_efi_pci(void)
>  {
>      EFI_STATUS status;
> @@ -799,23 +818,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>          }
>  
>          if ( !base_video )
> -        {
> -            unsigned int best;
> -            UINTN cols, rows, size;
> -
> -            for ( i = 0, size = 0, best = StdOut->Mode->Mode;
> -                  i < StdOut->Mode->MaxMode; ++i )
> -            {
> -                if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
> -                     cols * rows > size )
> -                {
> -                    size = cols * rows;
> -                    best = i;
> -                }
> -            }
> -            if ( best != StdOut->Mode->Mode )
> -                StdOut->SetMode(StdOut, best);
> -        }
> +            efi_console_set_mode();
>      }
>  
>      PrintStr(L"Xen " __stringify(XEN_VERSION) "." __stringify(XEN_SUBVERSION)
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 13/23] efi: split out efi_get_gop()
       [not found] ` <1437402558-7313-14-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 19:27   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:27 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:08PM +0200, Daniel Kiper wrote:
> ..which gets pointer to GOP device. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   59 ++++++++++++++++++++++++++++++-------------------
>  1 file changed, 36 insertions(+), 23 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 4614146..6fad230 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -630,6 +630,41 @@ static void __init efi_console_set_mode(void)
>          StdOut->SetMode(StdOut, best);
>  }
>  
> +static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
> +{
> +    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
> +    EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
> +    EFI_HANDLE *handles;
> +    EFI_STATUS status;
> +    UINTN info_size, size = 0;
> +    static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
> +    unsigned int i;
> +
> +    status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
> +    if ( status == EFI_BUFFER_TOO_SMALL )
> +        status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
> +    if ( !EFI_ERROR(status) )
> +        status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
> +                                      handles);
> +    if ( EFI_ERROR(status) )
> +        size = 0;
> +    for ( i = 0; i < size / sizeof(*handles); ++i )
> +    {
> +        status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
> +        if ( EFI_ERROR(status) )
> +            continue;
> +        status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
> +        if ( !EFI_ERROR(status) )
> +            break;
> +    }
> +    if ( handles )
> +        efi_bs->FreePool(handles);
> +    if ( EFI_ERROR(status) )
> +        gop = NULL;
> +
> +    return gop;
> +}
> +
>  static void __init setup_efi_pci(void)
>  {
>      EFI_STATUS status;
> @@ -736,14 +771,12 @@ void EFIAPI __init noreturn
>  efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  {
>      static EFI_GUID __initdata loaded_image_guid = LOADED_IMAGE_PROTOCOL;
> -    static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
>      static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
>      EFI_LOADED_IMAGE *loaded_image;
>      EFI_STATUS status;
>      unsigned int i, argc;
>      CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
>      UINTN map_key, info_size, gop_mode = ~0;
> -    EFI_HANDLE *handles = NULL;
>      EFI_SHIM_LOCK_PROTOCOL *shim_lock;
>      EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
>      EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
> @@ -837,27 +870,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>                                 &cols, &rows) == EFI_SUCCESS )
>              efi_arch_console_init(cols, rows);
>  
> -        status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
> -        if ( status == EFI_BUFFER_TOO_SMALL )
> -            status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
> -        if ( !EFI_ERROR(status) )
> -            status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
> -                                          handles);
> -        if ( EFI_ERROR(status) )
> -            size = 0;
> -        for ( i = 0; i < size / sizeof(*handles); ++i )
> -        {
> -            status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
> -            if ( EFI_ERROR(status) )
> -                continue;
> -            status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
> -            if ( !EFI_ERROR(status) )
> -                break;
> -        }
> -        if ( handles )
> -            efi_bs->FreePool(handles);
> -        if ( EFI_ERROR(status) )
> -            gop = NULL;
> +        gop = efi_get_gop();
>  
>          /* Get the file system interface. */
>          dir_handle = get_parent_handle(loaded_image, &file_name);
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 14/23] efi: split out efi_find_gop_mode()
  2015-07-20 14:29 ` [PATCH v2 14/23] efi: split out efi_find_gop_mode() Daniel Kiper
@ 2015-08-10 19:31   ` Konrad Rzeszutek Wilk
  2015-08-20 15:48   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:31 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:09PM +0200, Daniel Kiper wrote:
> ..which finds suitable GOP mode. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   94 ++++++++++++++++++++++++++++---------------------
>  1 file changed, 54 insertions(+), 40 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 6fad230..8d16470 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -665,6 +665,58 @@ static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
>      return gop;
>  }
>  
> +static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
> +                                      UINTN cols, UINTN rows, UINTN depth)
> +{
> +    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
> +    EFI_STATUS status;
> +    UINTN gop_mode = ~0, info_size, size;
> +    unsigned int i;
> +
> +    if ( !gop )
> +        return gop_mode;
> +
> +    for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
> +    {
> +        unsigned int bpp = 0;
> +
> +        status = gop->QueryMode(gop, i, &info_size, &mode_info);
> +        if ( EFI_ERROR(status) )
> +            continue;
> +        switch ( mode_info->PixelFormat )
> +        {
> +        case PixelBitMask:
> +            bpp = hweight32(mode_info->PixelInformation.RedMask |
> +                            mode_info->PixelInformation.GreenMask |
> +                            mode_info->PixelInformation.BlueMask);
> +            break;
> +        case PixelRedGreenBlueReserved8BitPerColor:
> +        case PixelBlueGreenRedReserved8BitPerColor:
> +            bpp = 24;
> +            break;
> +        default:
> +            continue;
> +        }
> +        if ( cols == mode_info->HorizontalResolution &&
> +             rows == mode_info->VerticalResolution &&
> +             (!depth || bpp == depth) )
> +        {
> +            gop_mode = i;
> +            break;
> +        }
> +        if ( !cols && !rows &&
> +             mode_info->HorizontalResolution *
> +             mode_info->VerticalResolution > size )
> +        {
> +            size = mode_info->HorizontalResolution *
> +                   mode_info->VerticalResolution;
> +            gop_mode = i;
> +        }
> +    }
> +
> +    return gop_mode;
> +}
> +
>  static void __init setup_efi_pci(void)
>  {
>      EFI_STATUS status;
> @@ -978,46 +1030,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  
>          dir_handle->Close(dir_handle);
>  
> -        if ( gop && !base_video )
> -        {
> -            for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
> -            {
> -                unsigned int bpp = 0;
> -
> -                status = gop->QueryMode(gop, i, &info_size, &mode_info);
> -                if ( EFI_ERROR(status) )
> -                    continue;
> -                switch ( mode_info->PixelFormat )
> -                {
> -                case PixelBitMask:
> -                    bpp = hweight32(mode_info->PixelInformation.RedMask |
> -                                    mode_info->PixelInformation.GreenMask |
> -                                    mode_info->PixelInformation.BlueMask);
> -                    break;
> -                case PixelRedGreenBlueReserved8BitPerColor:
> -                case PixelBlueGreenRedReserved8BitPerColor:
> -                    bpp = 24;
> -                    break;
> -                default:
> -                    continue;
> -                }
> -                if ( cols == mode_info->HorizontalResolution &&
> -                     rows == mode_info->VerticalResolution &&
> -                     (!depth || bpp == depth) )
> -                {
> -                    gop_mode = i;
> -                    break;
> -                }
> -                if ( !cols && !rows &&
> -                     mode_info->HorizontalResolution *
> -                     mode_info->VerticalResolution > size )
> -                {
> -                    size = mode_info->HorizontalResolution *
> -                           mode_info->VerticalResolution;
> -                    gop_mode = i;
> -                }
> -            }
> -        }
> +        if ( !base_video )
> +            gop_mode = efi_find_gop_mode(gop, cols, rows, depth);
>      }
>  
>      efi_arch_edd();
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 15/23] efi: split out efi_tables()
  2015-07-20 14:29 ` [PATCH v2 15/23] efi: split out efi_tables() Daniel Kiper
@ 2015-08-10 19:32   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:32 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:10PM +0200, Daniel Kiper wrote:
> ..which collects system tables data. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   61 +++++++++++++++++++++++++++----------------------
>  1 file changed, 34 insertions(+), 27 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 8d16470..fd62125 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -717,6 +717,39 @@ static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
>      return gop_mode;
>  }
>  
> +static void __init efi_tables(void)
> +{
> +    unsigned int i;
> +
> +    /* Obtain basic table pointers. */
> +    for ( i = 0; i < efi_num_ct; ++i )
> +    {
> +        static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
> +        static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
> +        static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
> +        static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
> +        static EFI_GUID __initdata smbios3_guid = SMBIOS3_TABLE_GUID;
> +
> +        if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
> +	       efi.acpi20 = (long)efi_ct[i].VendorTable;
> +        if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
> +	       efi.acpi = (long)efi_ct[i].VendorTable;
> +        if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
> +	       efi.mps = (long)efi_ct[i].VendorTable;
> +        if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
> +	       efi.smbios = (long)efi_ct[i].VendorTable;
> +        if ( match_guid(&smbios3_guid, &efi_ct[i].VendorGuid) )
> +	       efi.smbios3 = (long)efi_ct[i].VendorTable;
> +    }
> +
> +#ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
> +    dmi_efi_get_table(efi.smbios != EFI_INVALID_TABLE_ADDR
> +                      ? (void *)(long)efi.smbios : NULL,
> +                      efi.smbios3 != EFI_INVALID_TABLE_ADDR
> +                      ? (void *)(long)efi.smbios3 : NULL);
> +#endif
> +}
> +
>  static void __init setup_efi_pci(void)
>  {
>      EFI_STATUS status;
> @@ -1039,33 +1072,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      /* XXX Collect EDID info. */
>      efi_arch_cpu();
>  
> -    /* Obtain basic table pointers. */
> -    for ( i = 0; i < efi_num_ct; ++i )
> -    {
> -        static EFI_GUID __initdata acpi2_guid = ACPI_20_TABLE_GUID;
> -        static EFI_GUID __initdata acpi_guid = ACPI_TABLE_GUID;
> -        static EFI_GUID __initdata mps_guid = MPS_TABLE_GUID;
> -        static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
> -        static EFI_GUID __initdata smbios3_guid = SMBIOS3_TABLE_GUID;
> -
> -        if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
> -	       efi.acpi20 = (long)efi_ct[i].VendorTable;
> -        if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
> -	       efi.acpi = (long)efi_ct[i].VendorTable;
> -        if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
> -	       efi.mps = (long)efi_ct[i].VendorTable;
> -        if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
> -	       efi.smbios = (long)efi_ct[i].VendorTable;
> -        if ( match_guid(&smbios3_guid, &efi_ct[i].VendorGuid) )
> -	       efi.smbios3 = (long)efi_ct[i].VendorTable;
> -    }
> -
> -#ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
> -    dmi_efi_get_table(efi.smbios != EFI_INVALID_TABLE_ADDR
> -                      ? (void *)(long)efi.smbios : NULL,
> -                      efi.smbios3 != EFI_INVALID_TABLE_ADDR
> -                      ? (void *)(long)efi.smbios3 : NULL);
> -#endif
> +    efi_tables();
>  
>      /* Collect PCI ROM contents. */
>      setup_efi_pci();
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 16/23] efi: split out efi_variables()
  2015-07-20 14:29 ` [PATCH v2 16/23] efi: split out efi_variables() Daniel Kiper
@ 2015-08-10 19:34   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:34 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:11PM +0200, Daniel Kiper wrote:
> ..which collects variable store parameters. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   41 ++++++++++++++++++++++++-----------------
>  1 file changed, 24 insertions(+), 17 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index fd62125..177697a 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -837,6 +837,29 @@ static void __init setup_efi_pci(void)
>      efi_bs->FreePool(handles);
>  }
>  
> +static void __init efi_variables(void)
> +{
> +    EFI_STATUS status;
> +
> +    status = (efi_rs->Hdr.Revision >> 16) >= 2 ?
> +             efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE |
> +                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                                       EFI_VARIABLE_RUNTIME_ACCESS,
> +                                       &efi_boot_max_var_store_size,
> +                                       &efi_boot_remain_var_store_size,
> +                                       &efi_boot_max_var_size) :
> +             EFI_INCOMPATIBLE_VERSION;
> +    if ( EFI_ERROR(status) )
> +    {
> +        efi_boot_max_var_store_size = 0;
> +        efi_boot_remain_var_store_size = 0;
> +        efi_boot_max_var_size = status;
> +        PrintStr(L"Warning: Could not query variable store: ");
> +        DisplayUint(status, 0);
> +        PrintStr(newline);
> +    }
> +}
> +
>  static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
>  {
>     if ( bpp < 0 )
> @@ -1078,23 +1101,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      setup_efi_pci();
>  
>      /* Get snapshot of variable store parameters. */
> -    status = (efi_rs->Hdr.Revision >> 16) >= 2 ?
> -             efi_rs->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE |
> -                                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
> -                                       EFI_VARIABLE_RUNTIME_ACCESS,
> -                                       &efi_boot_max_var_store_size,
> -                                       &efi_boot_remain_var_store_size,
> -                                       &efi_boot_max_var_size) :
> -             EFI_INCOMPATIBLE_VERSION;
> -    if ( EFI_ERROR(status) )
> -    {
> -        efi_boot_max_var_store_size = 0;
> -        efi_boot_remain_var_store_size = 0;
> -        efi_boot_max_var_size = status;
> -        PrintStr(L"Warning: Could not query variable store: ");
> -        DisplayUint(status, 0);
> -        PrintStr(newline);
> -    }
> +    efi_variables();
>  
>      efi_arch_memory_setup();
>  
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 17/23] efi: split out efi_set_gop_mode()
  2015-07-20 14:29 ` [PATCH v2 17/23] efi: split out efi_set_gop_mode() Daniel Kiper
@ 2015-08-10 19:34   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:34 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:12PM +0200, Daniel Kiper wrote:
> ..which sets chosen GOP mode. We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   33 ++++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 13 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 177697a..04b9c7e 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -860,6 +860,25 @@ static void __init efi_variables(void)
>      }
>  }
>  
> +static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode)
> +{
> +    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
> +    EFI_STATUS status;
> +    UINTN info_size;
> +
> +    if ( !gop )
> +        return;
> +
> +    /* Set graphics mode. */
> +    if ( gop_mode < gop->Mode->MaxMode && gop_mode != gop->Mode->Mode )
> +        gop->SetMode(gop, gop_mode);
> +
> +    /* Get graphics and frame buffer info. */
> +    status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
> +    if ( !EFI_ERROR(status) )
> +        efi_arch_video_init(gop, info_size, mode_info);
> +}
> +
>  static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
>  {
>     if ( bpp < 0 )
> @@ -887,7 +906,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      UINTN map_key, info_size, gop_mode = ~0;
>      EFI_SHIM_LOCK_PROTOCOL *shim_lock;
>      EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
> -    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
>      union string section = { NULL }, name;
>      bool_t base_video = 0, retry;
>      char *option_str;
> @@ -1105,18 +1123,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  
>      efi_arch_memory_setup();
>  
> -    if ( gop )
> -    {
> -
> -        /* Set graphics mode. */
> -        if ( gop_mode < gop->Mode->MaxMode && gop_mode != gop->Mode->Mode )
> -            gop->SetMode(gop, gop_mode);
> -
> -        /* Get graphics and frame buffer info. */
> -        status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
> -        if ( !EFI_ERROR(status) )
> -            efi_arch_video_init(gop, info_size, mode_info);
> -    }
> +    efi_set_gop_mode(gop, gop_mode);
>  
>      info_size = 0;
>      efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 18/23] efi: split out efi_exit_boot()
       [not found] ` <1437402558-7313-19-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 19:36   ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:36 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:13PM +0200, Daniel Kiper wrote:
> ..which gets memory map and calls ExitBootServices(). We want to re-use this
> code to support multiboot2 protocol on EFI platforms.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/common/efi/boot.c |   92 +++++++++++++++++++++++++++----------------------
>  1 file changed, 50 insertions(+), 42 deletions(-)
> 
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 04b9c7e..bf2f198 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -879,6 +879,53 @@ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop
>          efi_arch_video_init(gop, info_size, mode_info);
>  }
>  
> +static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    EFI_STATUS status;
> +    UINTN info_size = 0, map_key;
> +    bool_t retry;
> +
> +    efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
> +                         &efi_mdesc_size, &mdesc_ver);
> +    info_size += 8 * efi_mdesc_size;
> +    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
> +    if ( !efi_memmap )
> +        blexit(L"Unable to allocate memory for EFI memory map");
> +
> +    for ( retry = 0; ; retry = 1 )
> +    {
> +        efi_memmap_size = info_size;
> +        status = SystemTable->BootServices->GetMemoryMap(&efi_memmap_size,
> +                                                         efi_memmap, &map_key,
> +                                                         &efi_mdesc_size,
> +                                                         &mdesc_ver);
> +        if ( EFI_ERROR(status) )
> +            PrintErrMesg(L"Cannot obtain memory map", status);
> +
> +        efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
> +                                    efi_mdesc_size, mdesc_ver);
> +
> +        efi_arch_pre_exit_boot();
> +
> +        status = SystemTable->BootServices->ExitBootServices(ImageHandle,
> +                                                             map_key);
> +        efi_bs = NULL;
> +        if ( status != EFI_INVALID_PARAMETER || retry )
> +            break;
> +    }
> +
> +    if ( EFI_ERROR(status) )
> +        PrintErrMesg(L"Cannot exit boot services", status);
> +
> +    /* Adjust pointers into EFI. */
> +    efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
> +#ifdef USE_SET_VIRTUAL_ADDRESS_MAP
> +    efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
> +#endif
> +    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
> +    efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
> +}
> +
>  static int __init __maybe_unused set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
>  {
>     if ( bpp < 0 )
> @@ -903,11 +950,11 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      EFI_STATUS status;
>      unsigned int i, argc;
>      CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
> -    UINTN map_key, info_size, gop_mode = ~0;
> +    UINTN gop_mode = ~0;
>      EFI_SHIM_LOCK_PROTOCOL *shim_lock;
>      EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
>      union string section = { NULL }, name;
> -    bool_t base_video = 0, retry;
> +    bool_t base_video = 0;
>      char *option_str;
>      bool_t use_cfg_file;
>  
> @@ -1125,46 +1172,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  
>      efi_set_gop_mode(gop, gop_mode);
>  
> -    info_size = 0;
> -    efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
> -                         &efi_mdesc_size, &mdesc_ver);
> -    info_size += 8 * efi_mdesc_size;
> -    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
> -    if ( !efi_memmap )
> -        blexit(L"Unable to allocate memory for EFI memory map");
> -
> -    for ( retry = 0; ; retry = 1 )
> -    {
> -        efi_memmap_size = info_size;
> -        status = SystemTable->BootServices->GetMemoryMap(&efi_memmap_size,
> -                                                         efi_memmap, &map_key,
> -                                                         &efi_mdesc_size,
> -                                                         &mdesc_ver);
> -        if ( EFI_ERROR(status) )
> -            PrintErrMesg(L"Cannot obtain memory map", status);
> -
> -        efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
> -                                    efi_mdesc_size, mdesc_ver);
> -
> -        efi_arch_pre_exit_boot();
> -
> -        status = SystemTable->BootServices->ExitBootServices(ImageHandle,
> -                                                             map_key);
> -        efi_bs = NULL;
> -        if ( status != EFI_INVALID_PARAMETER || retry )
> -            break;
> -    }
> -
> -    if ( EFI_ERROR(status) )
> -        PrintErrMesg(L"Cannot exit boot services", status);
> -
> -    /* Adjust pointers into EFI. */
> -    efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
> -#ifdef USE_SET_VIRTUAL_ADDRESS_MAP
> -    efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
> -#endif
> -    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
> -    efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
> +    efi_exit_boot(ImageHandle, SystemTable);
>  
>      efi_arch_post_exit_boot();
>      for( ; ; ); /* not reached */
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 19/23] x86/efi: create new early memory allocator
       [not found] ` <1437402558-7313-20-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 19:49   ` Konrad Rzeszutek Wilk
  2015-08-27 11:23   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 19:49 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:14PM +0200, Daniel Kiper wrote:
> There is a problem with place_string() which is used as early memory
> allocator. It gets memory chunks starting from start symbol and
> going down. Sadly this does not work when Xen is loaded using multiboot2
> protocol because start lives on 1 MiB address. So, I tried to use

s/So, I tried to use/With/
> mem_lower address calculated by GRUB2. However, it works only on some

s/GRUB2. However, //

> machines. There are machines in the wild (e.g. Dell PowerEdge R820)
> which uses first ~640 KiB for boot services code or data... :-(((
> 
> In case of multiboot2 protocol we need that place_string() only allocate

s/only/to only/
> memory chunk for EFI memory map. However, I think that it should be fixed
> instead of making another function used just in one case. I thought about
> two solutions.

s/I think ...two solutions/There are two solutions:/

> 
> 1) We could use native EFI allocation functions (e.g. AllocatePool()
>    or AllocatePages()) to get memory chunk. However, later (somewhere
>    in __start_xen()) we must copy its contents to safe place or reserve
>    this in e820 memory map and map it in Xen virtual address space.
>    In later case we must also care about conflicts with e.g. crash
>    kernel regions which could be quite difficult.
> 
> 2) We may allocate memory area statically somewhere in Xen code which
>    could be used as memory pool for early dynamic allocations. Looks
>    quite simple. Additionally, it would not depend on EFI at all and
>    could be used on legacy BIOS platforms if we need it. However, we
>    must carefully choose size of this pool. We do not want increase
>    Xen binary size too much and waste too much memory but also we must fit

Aren't we gziping the binary? In which you do not waste that much disk space.

>    at least memory map on x86 EFI platforms. As I saw on small machine,

s/at least memory map on/on small memory/

s/As I saw on small machine/For example on/

>    e.g. IBM System x3550 M2 with 8 GiB RAM, memory map may contain more
>    than 200 entries. Every entry on x86-64 platform is 40 bytes in size.

s/entries. Every entry on .. is/wherein every entry is/

>    So, it means that we need more than 8 KiB for EFI memory map only.

s/So, it means that we need more than/Brings it up to/

>    Additionally, if we want to use this memory pool for Xen and modules
>    command line storage (it would be used when xen.efi is executed as EFI
>    application) then we should add, I think, about 1 KiB. In this case,

s/,I think, //

>    to be on safe side, we should assume at least 64 KiB pool for early
>    memory allocations, which is about 4 times of our earlier calculations.
>    However, during discussion on Xen-devel Jan Beulich suggested that
>    just in case we should use 1 MiB memory pool like it was in original
>    place_string() implementation. So, let's use 1 MiB as it was proposed.

s/If we think that we should not/To not/

>    If we think that we should not waste unallocated memory in the pool
>    on running system then we can mark this region as __initdata and move
>    all required data to dynamically allocated places somewhere in __start_xen().
> 
> Now solution #2 is implemented but maybe we should consider #1 one day.

s/Now ../This patch implements #2 solution./

> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> with the
adjustments mentioned.
> ---
>  xen/arch/x86/efi/efi-boot.h |   38 ++++++++++++++++++++++++++++++--------
>  xen/arch/x86/setup.c        |    3 +--
>  2 files changed, 31 insertions(+), 10 deletions(-)
> 
> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> index 2dd69f6..3d25c48 100644
> --- a/xen/arch/x86/efi/efi-boot.h
> +++ b/xen/arch/x86/efi/efi-boot.h
> @@ -103,9 +103,36 @@ static void __init relocate_trampoline(unsigned long phys)
>          *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
>  }
>  
> +#define EBMALLOC_SIZE	MB(1)
> +
> +static char __initdata ebmalloc_mem[EBMALLOC_SIZE];
> +static char __initdata *ebmalloc_free = NULL;
> +
> +/* EFI boot allocator. */
> +static void __init *ebmalloc(size_t size)
> +{
> +    void *ptr;
> +
> +    /*
> +     * Init ebmalloc_free on runtime. Static initialization
> +     * will not work because it puts virtual address there.

And why is that bad?

> +     */
> +    if ( ebmalloc_free == NULL )
> +        ebmalloc_free = ebmalloc_mem;
> +
> +    ptr = ebmalloc_free;
> +
> +    ebmalloc_free += size;
> +
> +    if ( ebmalloc_free - ebmalloc_mem > sizeof(ebmalloc_mem) )
> +        blexit(L"Out of static memory\r\n");
> +
> +    return ptr;
> +}
> +
>  static void __init place_string(u32 *addr, const char *s)
>  {
> -    static char *__initdata alloc = start;
> +    char *alloc = NULL;
>  
>      if ( s && *s )
>      {
> @@ -113,7 +140,7 @@ static void __init place_string(u32 *addr, const char *s)
>          const char *old = (char *)(long)*addr;
>          size_t len2 = *addr ? strlen(old) + 1 : 0;
>  
> -        alloc -= len1 + len2;
> +        alloc = ebmalloc(len1 + len2);
>          /*
>           * Insert new string before already existing one. This is needed
>           * for options passed on the command line to override options from
> @@ -196,12 +223,7 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>  
>  static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>  {
> -    place_string(&mbi.mem_upper, NULL);
> -    mbi.mem_upper -= map_size;
> -    mbi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
> -    if ( mbi.mem_upper < xen_phys_start )
> -        return NULL;
> -    return (void *)(long)mbi.mem_upper;
> +    return ebmalloc(map_size);
>  }
>  
>  static void __init efi_arch_pre_exit_boot(void)
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index bce708c..a59fc4e 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -994,8 +994,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      if ( !xen_phys_start )
>          panic("Not enough memory to relocate Xen.");
> -    reserve_e820_ram(&boot_e820, efi_enabled(EFI_PLATFORM) ? mbi->mem_upper : __pa(&_start),
> -                     __pa(&_end));
> +    reserve_e820_ram(&boot_e820, __pa(&_start), __pa(&_end));
>  
>      /* Late kexec reservation (dynamic start address). */
>      kexec_reserve_area(&boot_e820);
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
  2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2015-08-10 20:07   ` Konrad Rzeszutek Wilk
  2015-08-11 15:23   ` Konrad Rzeszutek Wilk
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 20:07 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:15PM +0200, Daniel Kiper wrote:
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v2 - suggestions/fixes:
>    - generate multiboot2 header using macros
>      (suggested by Jan Beulich),
>    - switch CPU to x86_32 mode before
>      jumping to 32-bit code
>      (suggested by Andrew Cooper),
>    - reduce code changes to increase patch readability
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich),
>    - ignore MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag on EFI platform
>      and find on my own multiboot2.mem_lower value,
>    - stop execution if EFI platform is detected
>      in legacy BIOS path.
> ---
>  xen/arch/x86/boot/head.S          |  157 +++++++++++++++++++++++++++++++++++--
>  xen/arch/x86/efi/efi-boot.h       |   30 +++++++
>  xen/arch/x86/efi/stub.c           |    5 ++
>  xen/arch/x86/setup.c              |   10 ++-
>  xen/arch/x86/x86_64/asm-offsets.c |    2 +
>  xen/arch/x86/xen.lds.S            |    4 +-
>  xen/common/efi/boot.c             |   12 +++
>  xen/include/xen/efi.h             |    1 +
>  8 files changed, 210 insertions(+), 11 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 57197db..056047f 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -89,6 +89,13 @@ multiboot1_header_end:
>                     0, /* Number of the lines - no preference. */ \
>                     0  /* Number of bits per pixel - no preference. */
>  
> +        /* Do not disable EFI boot services. */

s/disable/exit/ ?

Or perhaps:

/* Inhibit GRUB2 from calling ExitBootServices. */

?

> +        mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
> +
> +        /* EFI64 entry point. */
> +        mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
> +                   sym_phys(__efi64_start)
> +
>          /* Multiboot2 header end tag. */
>          mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
>  .Lmultiboot2_header_end:
> @@ -100,9 +107,15 @@ multiboot1_header_end:
>  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)
> +        .word   BOOT_CS32
>  
>  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
>  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> +.Lbad_mb2_ldr: .asciz "ERR: Use latest Multiboot2 compatible bootloader!"

Multiboot2+EFI compatible..?
>  
>          .section .init.text, "ax", @progbits
>  
> @@ -111,6 +124,9 @@ bad_cpu:
>          jmp     print_err
>  not_multiboot:
>          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> +        jmp     print_err
> +mb2_too_old:
> +        mov     $(sym_phys(.Lbad_mb2_ldr)),%esi # Error message
>  print_err:
>          mov     $0xB8000,%edi  # VGA framebuffer
>  1:      mov     (%esi),%bl
> @@ -130,6 +146,119 @@ print_err:
>  .Lhalt: hlt
>          jmp     .Lhalt
>  
> +        .code64
> +
> +__efi64_start:
> +        cld
> +
> +        /* Check for Multiboot2 bootloader. */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      efi_multiboot2_proto
> +
> +        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
> +        lea     not_multiboot(%rip),%rdi
> +        jmp     x86_32_switch
> +
> +efi_multiboot2_proto:
> +        /*
> +         * Multiboot2 information address is 32-bit,
> +         * so, zero higher half of %rbx.
> +         */
> +        mov     %ebx,%ebx
> +
> +        /* Skip Multiboot2 information fixed part. */
> +        lea     MB2_fixed_sizeof(%rbx),%rcx

Don't want to check that the address is aligned properly?

> +
> +0:
> +        /* Get EFI SystemTable address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
> +        jne     1f
> +
> +        mov     MB2_efi64_st(%rcx),%rsi
> +
> +        /* Do not go into real mode on EFI platform. */

Add please:

/* And also inhibit clearing of BSS later on. */

> +        movb    $1,skip_realmode(%rip)
> +        jmp     3f
> +
> +1:
> +        /* Get EFI ImageHandle address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
> +        jne     2f
> +
> +        mov     MB2_efi64_ih(%rcx),%rdi
> +        jmp     3f
> +
> +2:
> +        /* Is it the end of Multiboot2 information? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
> +        je      run_bs
> +
> +3:
> +        /* Go to next Multiboot2 information tag. */
> +        add     MB2_tag_size(%rcx),%ecx
> +        add     $(MULTIBOOT2_TAG_ALIGN-1),%rcx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
> +        jmp     0b
> +
> +run_bs:
> +        push    %rax
> +        push    %rdi
> +
> +        /* Initialize BSS (no nasty surprises!). */
> +        lea     __bss_start(%rip),%rdi
> +        lea     __bss_end(%rip),%rcx
> +        sub     %rdi,%rcx
> +        shr     $3,%rcx
> +        xor     %eax,%eax
> +        rep     stosq
> +
> +        pop     %rdi
> +
> +        /*
> +         * IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable.
> +         * OUT: %rax - multiboot2.mem_lower. Do not get this value from
> +         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag. It could be bogus on
> +         * EFI platforms.
> +         */
> +        call    efi_multiboot2
> +
> +        /* Convert multiboot2.mem_lower to bytes/16. */
> +        mov     %rax,%rcx
> +        shr     $4,%rcx
> +
> +        pop     %rax
> +
> +        /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
> +        lea     trampoline_setup(%rip),%rdi
> +
> +x86_32_switch:
> +        cli
> +
> +        /* Initialise GDT. */
> +        lgdt    gdt_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
> +
> +        /* Disable paging. */
> +        mov     %cr0,%edx
> +        and     $(~X86_CR0_PG),%edx
> +        mov     %edx,%cr0
> +
> +        /* Jump to earlier loaded address. */
> +        jmp     *%edi
> +
>  __start:
>          cld
>          cli
> @@ -157,7 +286,7 @@ __start:
>  
>          /* Not available? BDA value will be fine. */
>          cmovnz  MB_mem_lower(%ebx),%edx
> -        jmp     trampoline_setup
> +        jmp     trampoline_bios_setup
>  
>  multiboot2_proto:
>          /* Skip Multiboot2 information fixed part. */
> @@ -169,12 +298,19 @@ multiboot2_proto:
>          jne     1f
>  
>          mov     MB2_mem_lower(%ecx),%edx
> -        jmp     trampoline_setup
> +        jmp     trampoline_bios_setup
>  
>  1:
> +        /* EFI mode is not supported via legacy BIOS path. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
> +        je      mb2_too_old
> +
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%ecx)
> +        je      mb2_too_old
> +
>          /* Is it the end of Multiboot2 information? */
>          cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
> -        je      trampoline_setup
> +        je      trampoline_bios_setup
>  
>          /* Go to next Multiboot2 information tag. */
>          add     MB2_tag_size(%ecx),%ecx
> @@ -182,7 +318,7 @@ multiboot2_proto:
>          and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>          jmp     0b
>  
> -trampoline_setup:
> +trampoline_bios_setup:
>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -198,12 +334,13 @@ trampoline_setup:
>           * multiboot structure (if available) and use the smallest.
>           */
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
> -        jb      2f                  /* if so, do not use it */
> +        jb      trampoline_setup    /* if so, do not use it */
>          shl     $10-4,%edx
>          cmp     %ecx,%edx           /* compare with BDA value */
>          cmovb   %edx,%ecx           /* and use the smaller */
>  
> -2:      /* Reserve 64kb for the trampoline */
> +trampoline_setup:
> +        /* Reserve 64kb for the trampoline. */
>          sub     $0x1000,%ecx
>  
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
> @@ -220,6 +357,13 @@ trampoline_setup:
>          add     $12,%esp            /* Remove reloc() args from stack. */
>          mov     %eax,sym_phys(multiboot_ptr)
>  
> +        /*
> +         * Do not zero BSS on EFI platform here.
> +         * It was initialized earlier.
> +         */
> +        cmpb    $1,sym_phys(skip_realmode)
> +        je      1f
> +
>          /* Initialize BSS (no nasty surprises!). */
>          mov     $sym_phys(__bss_start),%edi
>          mov     $sym_phys(__bss_end),%ecx
> @@ -228,6 +372,7 @@ trampoline_setup:
>          xor     %eax,%eax
>          rep     stosl
>  
> +1:
>          /* Interrogate CPU extended features via CPUID. */
>          mov     $0x80000000,%eax
>          cpuid
> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> index 3d25c48..1b25a2d 100644
> --- a/xen/arch/x86/efi/efi-boot.h
> +++ b/xen/arch/x86/efi/efi-boot.h
> @@ -228,6 +228,9 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>  
>  static void __init efi_arch_pre_exit_boot(void)
>  {
> +    if ( !efi_enabled(EFI_LOADER) )
> +        return;
> +
>      if ( !trampoline_phys )
>      {
>          if ( !cfg.addr )
> @@ -662,6 +665,33 @@ static bool_t __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
>      return 1; /* x86 always uses a config file */
>  }
>  
> +paddr_t __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
> +    UINTN cols, gop_mode = ~0, rows;
> +
> +    set_bit(EFI_PLATFORM, &efi.flags);
> +
> +    efi_init(ImageHandle, SystemTable);
> +
> +    efi_console_set_mode();
> +
> +    if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
> +                           &cols, &rows) == EFI_SUCCESS )
> +        efi_arch_console_init(cols, rows);
> +
> +    gop = efi_get_gop();
> +    gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
> +    efi_arch_edd();
> +    efi_tables();
> +    setup_efi_pci();
> +    efi_variables();
> +    efi_set_gop_mode(gop, gop_mode);
> +    efi_exit_boot(ImageHandle, SystemTable);
> +
> +    return cfg.addr;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
> index c5ae369..d30fe89 100644
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -13,6 +13,11 @@ struct efi __read_mostly efi = {
>  	.smbios3 = EFI_INVALID_TABLE_ADDR
>  };
>  
> +void __init efi_multiboot2(void)
> +{
> +    /* TODO: Fail if entered! */

Heheh. Could we add the 'ud2' instruction here?

> +}
> +
>  void __init efi_init_memory(void) { }
>  
>  void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t l4e) { }
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index a59fc4e..8bec67f 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -695,7 +695,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
>          panic("dom0 kernel not specified. Check bootloader configuration.");
>  
> -    if ( efi_enabled(EFI_PLATFORM) )
> +    if ( efi_enabled(EFI_LOADER) )
>      {
>          set_pdx_range(xen_phys_start >> PAGE_SHIFT,
>                        (xen_phys_start + BOOTSTRAP_MAP_BASE) >> PAGE_SHIFT);
> @@ -708,7 +708,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          l3_bootmap[l3_table_offset(BOOTSTRAP_MAP_BASE)] =
>              l3e_from_paddr(__pa(l2_bootmap), __PAGE_HYPERVISOR);
>  
> -        memmap_type = loader;
> +        memmap_type = "EFI";
> +    }
> +    else if ( efi_enabled(EFI_PLATFORM) )
> +    {
> +        memmap_type = "EFI";
>      }
>      else if ( e820_raw_nr != 0 )
>      {
> @@ -806,7 +810,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * we can relocate the dom0 kernel and other multiboot modules. Also, on
>       * x86/64, we relocate Xen to higher memory.
>       */
> -    for ( i = 0; !efi_enabled(EFI_PLATFORM) && i < mbi->mods_count; i++ )
> +    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
>      {
>          if ( mod[i].mod_start & (PAGE_SIZE - 1) )
>              panic("Bootloader didn't honor module alignment request.");
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index b926082..b7aed49 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -173,4 +173,6 @@ void __dummy__(void)
>      OFFSET(MB2_tag_type, multiboot2_tag_t, type);
>      OFFSET(MB2_tag_size, multiboot2_tag_t, size);
>      OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
> +    OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer);
> +    OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
>  }
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index 87f3e83..a399615 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -162,7 +162,7 @@ SECTIONS
>    . = ALIGN(STACK_SIZE);
>    __init_end = .;
>  
> -  . = ALIGN(4);
> +  . = ALIGN(8);
>    .bss : {                     /* BSS */
>         __bss_start = .;
>         *(.bss.stack_aligned)
> @@ -176,7 +176,7 @@ SECTIONS
>         *(.bss.percpu.read_mostly)
>         . = ALIGN(SMP_CACHE_BYTES);
>         __per_cpu_data_end = .;
> -       . = ALIGN(4);
> +       . = ALIGN(8);

This aligment check I presume is due to 'rep stosq'?

As such could you add a comment here please?


>         __bss_end = .;
>    } :text
>    _end = . ;
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index bf2f198..5a02e71 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -79,6 +79,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);
> +
>  static const EFI_BOOT_SERVICES *__initdata efi_bs;
>  static UINT32 __initdata efi_bs_revision;
>  static EFI_HANDLE __initdata efi_ih;
> @@ -960,6 +971,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  
>  #ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
>      set_bit(EFI_PLATFORM, &efi.flags);
> +    set_bit(EFI_LOADER, &efi.flags);
>  #endif
>  
>      efi_init(ImageHandle, SystemTable);
> diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
> index 318bbec..6b952df 100644
> --- a/xen/include/xen/efi.h
> +++ b/xen/include/xen/efi.h
> @@ -9,6 +9,7 @@
>  #define EFI_INVALID_TABLE_ADDR (~0UL)
>  
>  #define EFI_PLATFORM	0
> +#define EFI_LOADER	1
>  
>  /* Add fields here only if they need to be referenced from non-EFI code. */
>  struct efi {


With the changes above:

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found] ` <1437402558-7313-22-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-10 20:31   ` Konrad Rzeszutek Wilk
  2015-08-11 14:43   ` Konrad Rzeszutek Wilk
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-10 20:31 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:16PM +0200, Daniel Kiper wrote:
> Current early command line parser implementation in assembler
> is very difficult to change to relocatable stuff using segment
> registers. This requires a lot of changes in very weird and
> fragile code. So, reimplement this functionality in C. This
> way code will be relocatable out of the box and much easier
> to maintain.
> 
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

I did not look at the str* functions that were added in but just
at how the parameters parsing was done. Also at the assembler code and
with that

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
.. snip..
> diff --git a/xen/arch/x86/boot/cmdline.c b/xen/arch/x86/boot/cmdline.c
> new file mode 100644
> index 0000000..5ea50a4
> --- /dev/null
> +++ b/xen/arch/x86/boot/cmdline.c
> @@ -0,0 +1,396 @@
> +/*
> + * Copyright (c) 2015 Oracle Co.


Oracle Corporation.

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found] ` <1437402558-7313-22-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 20:31   ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Konrad Rzeszutek Wilk
@ 2015-08-11 14:43   ` Konrad Rzeszutek Wilk
  2015-08-27 12:43   ` Jan Beulich
       [not found]   ` <55DF221B020000780009D6C6@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-11 14:43 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

> +static void vga_parse(const char *cmdline, early_boot_opts_t *ebo)
> +{
> +    const char *c;
> +    int tmp;
> +    size_t la;
> +    static const char empty_chars_comma[] __text = " \n\r\t,";
> +    static const char x[] __text = "x";
> +    static const char vga[] __text = "vga=";
> +    static const char vga_current[] __text = "current";
> +    static const char vga_gfx[] __text = "gfx-";
> +    static const char vga_mode[] __text = "mode-";
> +    static const char vga_text_80x[] __text = "text-80x";
> +
> +    c = find_opt(cmdline, vga, 1);
> +
> +    if ( !c )
> +        return;
> +
> +    ebo->boot_vid_mode = ASK_VGA;
> +
> +    c += strlen_static(vga);
> +    la = strcspn(c, empty_chars_comma);
> +
> +    if ( !strncmp(c, vga_current, max(la, strlen_static(vga_current))) )
> +        ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
> +    else if ( !strncmp(c, vga_text_80x, strlen_static(vga_text_80x)) )
> +    {
> +        c += strlen_static(vga_text_80x);
> +        ebo->boot_vid_mode = rows2vmode(strtoi(c, empty_chars_comma, NULL));
> +    }
> +    else if ( !strncmp(c, vga_gfx, strlen_static(vga_gfx)) )
> +    {
> +        tmp = strtoi(c + strlen_static(vga_gfx), x, &c);
> +
> +        if ( tmp < 0 || tmp > U16_MAX )
> +            return;
> +
> +        ebo->vesa_size[VESA_WIDTH] = tmp;
> +
> +        tmp = strtoi(++c, x, &c);

My ancient OL5 installation:



Choked on that with:
gcc -O1 -fno-omit-frame-pointer -m32 -march=i686 -g -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes -Wdeclaration-after-statement -fno-stack-protector -fno-exceptions -Werror -fno-builtin -msoft-float  -c -fpic cmdline.c -o cmdline.o
cc1: warnings being treated as errors
cmdline.c: In function ‘vga_parse’:
cmdline.c:363: warning: operation on ‘c’ may be undefined

Moving the ++c before the tmp assigment make the compiler happy.

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

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
  2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
  2015-08-10 20:07   ` Konrad Rzeszutek Wilk
@ 2015-08-11 15:23   ` Konrad Rzeszutek Wilk
  2015-08-27 12:01   ` Jan Beulich
       [not found]   ` <55DF1836020000780009D674@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-11 15:23 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

> +run_bs:
> +        push    %rax
> +        push    %rdi
> +
> +        /* Initialize BSS (no nasty surprises!). */
> +        lea     __bss_start(%rip),%rdi
> +        lea     __bss_end(%rip),%rcx
> +        sub     %rdi,%rcx
> +        shr     $3,%rcx
> +        xor     %eax,%eax
> +        rep     stosq


This means we are using the %es segment. The multiboot1 is pretty clear
that it should cover up to 4GB.

Would it be worth adding a comment about that?

> +
> +        pop     %rdi
> +
> +        /*
> +         * IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable.
> +         * OUT: %rax - multiboot2.mem_lower. Do not get this value from
> +         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag. It could be bogus on
> +         * EFI platforms.
> +         */
> +        call    efi_multiboot2

However the function prototype for efi_multiboot2 is 'void', not 'int' - so
it would not return anything!


> +
> +        /* Convert multiboot2.mem_lower to bytes/16. */

Should we check to make sure it is valid? With those weird machines you seem to have
run into I am not actually sure what a valid value is :-(

.. snip..

> diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
> index c5ae369..d30fe89 100644
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -13,6 +13,11 @@ struct efi __read_mostly efi = {
>  	.smbios3 = EFI_INVALID_TABLE_ADDR
>  };
>  
> +void __init efi_multiboot2(void)

unsigned int __init ..
> +{
> +    /* TODO: Fail if entered! */

And maybe just 'return 0'; ?

> +}

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found] ` <1437402558-7313-23-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-11 16:48   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150811164806.GB32231@l.oracle.com>
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-11 16:48 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
> Every multiboot protocol (regardless of version) compatible image must
> specify its load address (in ELF or multiboot header). Multiboot protocol
> compatible loader have to load image at specified address. However, there
> is no guarantee that the requested memory region (in case of Xen it starts
> at 1 MiB and ends at 17 MiB) where image should be loaded initially is a RAM
> and it is free (legacy BIOS platforms are merciful for Xen but I found at
> least one EFI platform on which Xen load address conflicts with EFI boot
> services; it is Dell PowerEdge R820 with latest firmware). To cope with
> that problem we must make Xen early boot code relocatable. This patch does
> that. However, it does not add multiboot2 protocol interface which is done
> in next patch.

s/next patch/"x86: add multiboot2 protocol support for relocatable image."
> 
> This patch changes following things:
>   - default load address is changed from 1 MiB to 2 MiB; I did that because
>     initial page tables are using 2 MiB huge pages and this way required
>     updates for them are quite easy; it means that e.g. we avoid spacial
>     cases for beginning and end of required memory region if it live at
>     address not aligned to 2 MiB,
>   - %ebp register is used as a storage for Xen image base address; this way
>     we can get this value very quickly if it is needed; however, %ebp register
>     is not used directly to access a given memory region,
>   - %fs register is filled with segment descriptor which describes memory region
>     with Xen image (it could be relocated or not); it is used to access some of

'memory region with Xen image' ? Not sure I follow?

Perhaps:
segment descriptor which starts (0) at Xen image base (_start).


>     Xen data in early boot code; potentially we can use above mentioned segment
>     descriptor to access data using %ds:%esi and/or %es:%esi (e.g. movs*); however,
>     I think that it could unnecessarily obfuscate code (e.g. we need at least
>     to operations to reload a given segment descriptor) and current solution

s/to/two/ ?
>     looks quite optimal.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/arch/x86/Makefile          |    6 +-
>  xen/arch/x86/Rules.mk          |    4 +
>  xen/arch/x86/boot/head.S       |  165 ++++++++++++++++++++++++++++++----------
>  xen/arch/x86/boot/trampoline.S |   11 ++-
>  xen/arch/x86/boot/wakeup.S     |    6 +-
>  xen/arch/x86/boot/x86_64.S     |   34 ++++-----
>  xen/arch/x86/setup.c           |   33 ++++----
>  xen/arch/x86/x86_64/mm.c       |    2 +-
>  xen/arch/x86/xen.lds.S         |    2 +-
>  xen/include/asm-x86/config.h   |    3 +
>  xen/include/asm-x86/page.h     |    2 +-
>  11 files changed, 182 insertions(+), 86 deletions(-)
> 
> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> index 82c5a93..93069a8 100644
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -72,8 +72,10 @@ efi-$(x86_64) := $(shell if [ ! -r $(BASEDIR)/include/xen/compile.h -o \
>                           echo '$(TARGET).efi'; fi)
>  
>  $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
> -	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
> -	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
> +#	THIS IS UGLY HACK! PLEASE DO NOT COMPLAIN. I WILL FIX IT IN NEXT RELEASE.

OK :-)

> +	./boot/mkelf32 $(TARGET)-syms $(TARGET) $(XEN_IMG_PHYS_START) 0xffff82d081000000
> +#	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
> +#	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
>  
>  
>  ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in.o $(ALL_OBJS)
> diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
> index 4a04a8a..7ccb8a0 100644
> --- a/xen/arch/x86/Rules.mk
> +++ b/xen/arch/x86/Rules.mk
> @@ -15,6 +15,10 @@ HAS_GDBSX := y
>  HAS_PDX := y
>  xenoprof := y
>  
> +XEN_IMG_PHYS_START = 0x200000
> +
> +CFLAGS += -DXEN_IMG_PHYS_START=$(XEN_IMG_PHYS_START)
> +
>  CFLAGS += -I$(BASEDIR)/include 
>  CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
>  CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 3f1054d..d484f68 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -12,13 +12,15 @@
>          .text
>          .code32
>  
> -#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
> +#define sym_phys(sym)     ((sym) - __XEN_VIRT_START + XEN_IMG_PHYS_START - XEN_IMG_OFFSET)
> +#define sym_offset(sym)   ((sym) - __XEN_VIRT_START)
>  
>  #define BOOT_CS32        0x0008
>  #define BOOT_CS64        0x0010
>  #define BOOT_DS          0x0018
>  #define BOOT_PSEUDORM_CS 0x0020
>  #define BOOT_PSEUDORM_DS 0x0028
> +#define BOOT_FS          0x0030
>  
>  #define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
>  #define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
> @@ -105,12 +107,13 @@ multiboot1_header_end:
>  
>          .word   0
>  gdt_boot_descr:
> -        .word   6*8-1
> -        .long   sym_phys(trampoline_gdt)
> +        .word   7*8-1
> +gdt_boot_descr_addr:
> +        .long   sym_offset(trampoline_gdt)
>          .long   0 /* Needed for 64-bit lgdt */
>  
>  cs32_switch_addr:
> -        .long   sym_phys(cs32_switch)
> +        .long   sym_offset(cs32_switch)
>          .word   BOOT_CS32
>  
>  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
> @@ -120,13 +123,13 @@ cs32_switch_addr:
>          .section .init.text, "ax", @progbits
>  
>  bad_cpu:
> -        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> +        lea     sym_offset(.Lbad_cpu_msg)(%ebp),%esi # Error message
>          jmp     print_err
>  not_multiboot:
> -        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> +        lea     sym_offset(.Lbad_ldr_msg)(%ebp),%esi # Error message
>          jmp     print_err
>  mb2_too_old:
> -        mov     $(sym_phys(.Lbad_mb2_ldr)),%esi # Error message
> +        lea     sym_offset(.Lbad_mb2_ldr)(%ebp),%esi # Error message
>  print_err:
>          mov     $0xB8000,%edi  # VGA framebuffer
>  1:      mov     (%esi),%bl
> @@ -151,6 +154,9 @@ print_err:
>  __efi64_start:
>          cld
>  
> +        /* Load default Xen image base address. */
> +        mov     $sym_phys(__image_base__),%ebp
> +
>          /* Check for Multiboot2 bootloader. */
>          cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
>          je      efi_multiboot2_proto
> @@ -235,9 +241,11 @@ x86_32_switch:
>          cli
>  
>          /* Initialise GDT. */
> +        add     %ebp,gdt_boot_descr_addr(%rip)
>          lgdt    gdt_boot_descr(%rip)
>  
>          /* Reload code selector. */
> +        add     %ebp,cs32_switch_addr(%rip)
>          ljmpl   *cs32_switch_addr(%rip)
>  
>          .code32
> @@ -263,12 +271,8 @@ __start:
>          cld
>          cli
>  
> -        /* Initialise GDT and basic data segments. */
> -        lgdt    %cs:sym_phys(gdt_boot_descr)
> -        mov     $BOOT_DS,%ecx
> -        mov     %ecx,%ds
> -        mov     %ecx,%es
> -        mov     %ecx,%ss
> +        /* Load default Xen image base address. */
> +        mov     $sym_phys(__image_base__),%ebp
>  
>          /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
>          xor     %edx,%edx
> @@ -319,6 +323,19 @@ multiboot2_proto:
>          jmp     0b
>  
>  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?

Let me double-check what SYSLINUX's mboot.c32 does. Perhaps
it had done something odd in the past.

>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -340,33 +357,58 @@ trampoline_bios_setup:
>          cmovb   %edx,%ecx           /* and use the smaller */
>  
>  trampoline_setup:

Would it make sense to add:

/* Gets called from EFI (from x86_32_switch) and legacy (see above) boot loaders. */

> +        mov     %ebp,%esi
> +
> +        /* Initialize 0-15 bits of BOOT_FS segment descriptor base address. */
> +        mov     %ebp,%edx
> +        shl     $16,%edx
> +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS)(%esi)
> +
> +        /* Initialize 16-23 bits of BOOT_FS segment descriptor base address. */
> +        mov     %ebp,%edx
> +        shr     $16,%edx
> +        and     $0x000000ff,%edx
> +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
> +
> +        /* Initialize 24-31 bits of BOOT_FS segment descriptor base address. */
> +        mov     %ebp,%edx
> +        and     $0xff000000,%edx
> +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
> +
> +        /* Initialize %fs and later use it to access Xen data if possible. */
> +        mov     $BOOT_FS,%edx
> +        mov     %edx,%fs
> +

We just modified the GDT. Should we reload it (lgdt?)?

>          /* Reserve 64kb for the trampoline. */
>          sub     $0x1000,%ecx
>  
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
>          xor     %cl, %cl
>          shl     $4, %ecx
> -        mov     %ecx,sym_phys(trampoline_phys)
> +        mov     %ecx,%fs:sym_offset(trampoline_phys)
> +
> +        /* Save Xen image base address for later use. */
> +        mov     %ebp,%fs:sym_offset(xen_img_base_phys_addr)
>  
>          /* Save the Multiboot info struct (after relocation) for later use. */
> -        mov     $sym_phys(cpu0_stack)+1024,%esp
> +        lea     (sym_offset(cpu0_stack)+1024)(%ebp),%esp
>          push    %eax                /* Multiboot magic. */
>          push    %ebx                /* Multiboot information address. */
>          push    %ecx                /* Boot trampoline address. */
>          call    reloc
>          add     $12,%esp            /* Remove reloc() args from stack. */
> -        mov     %eax,sym_phys(multiboot_ptr)
> +        mov     %eax,%fs:sym_offset(multiboot_ptr)
>  
>          /*
>           * Do not zero BSS on EFI platform here.
>           * It was initialized earlier.
>           */
> -        cmpb    $1,sym_phys(skip_realmode)
> +        cmpb    $1,%fs:sym_offset(skip_realmode)
>          je      1f
>  
>          /* Initialize BSS (no nasty surprises!). */
> -        mov     $sym_phys(__bss_start),%edi
> -        mov     $sym_phys(__bss_end),%ecx
> +        lea     sym_offset(__bss_start)(%ebp),%edi
> +        lea     sym_offset(__bss_end)(%ebp),%ecx
>          sub     %edi,%ecx
>          shr     $2,%ecx
>          xor     %eax,%eax
> @@ -381,8 +423,8 @@ trampoline_setup:
>          jbe     1f
>          mov     $0x80000001,%eax
>          cpuid
> -1:      mov     %edx,sym_phys(cpuid_ext_features)
> -        mov     %edx,sym_phys(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
> +1:      mov     %edx,%fs:sym_offset(cpuid_ext_features)
> +        mov     %edx,%fs:(sym_offset(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM))
>  
>          /* Check for availability of long mode. */
>          bt      $X86_FEATURE_LM & 0x1f,%edx
> @@ -390,72 +432,111 @@ trampoline_setup:
>  
>          /* Stash TSC to calculate a good approximation of time-since-boot */
>          rdtsc
> -        mov     %eax,sym_phys(boot_tsc_stamp)
> -        mov     %edx,sym_phys(boot_tsc_stamp+4)
> +        mov     %eax,%fs:sym_offset(boot_tsc_stamp)
> +        mov     %edx,%fs:sym_offset(boot_tsc_stamp+4)
>  
> -        /* Initialise L2 boot-map page table entries (16MB). */
> -        mov     $sym_phys(l2_bootmap),%edx
> -        mov     $PAGE_HYPERVISOR|_PAGE_PSE,%eax
> -        mov     $8,%ecx
> +        /* Update frame addreses in page tables. */
> +        lea     sym_offset(__page_tables_start)(%ebp),%edx
> +        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
> +1:      testl   $_PAGE_PRESENT,(%edx)
> +        jz      2f
> +        add     %ebp,(%edx)
> +2:      add     $8,%edx
> +        loop    1b
> +
> +        /* Initialise L2 boot-map page table entries (14MB). */
> +        lea     sym_offset(l2_bootmap)(%ebp),%edx
> +        lea     sym_offset(start)(%ebp),%eax
> +        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
> +        mov     %eax,%ebx
> +        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
> +        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
> +        add     %ebx,%edx
> +        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
> +        mov     $7,%ecx
>  1:      mov     %eax,(%edx)
>          add     $8,%edx
>          add     $(1<<L2_PAGETABLE_SHIFT),%eax
>          loop    1b
> +
>          /* Initialise L3 boot-map page directory entry. */
> -        mov     $sym_phys(l2_bootmap)+__PAGE_HYPERVISOR,%eax
> -        mov     %eax,sym_phys(l3_bootmap) + 0*8
> +        lea     (sym_offset(l2_bootmap)+__PAGE_HYPERVISOR)(%ebp),%eax
> +        lea     sym_offset(l3_bootmap)(%ebp),%ebx
> +        mov     $4,%ecx
> +1:      mov     %eax,(%ebx)
> +        add     $8,%ebx
> +        add     $(L2_PAGETABLE_ENTRIES*8),%eax
> +        loop    1b
> +
> +        /* Initialise L2 direct map page table entries (14MB). */
> +        lea     sym_offset(l2_identmap)(%ebp),%edx
> +        lea     sym_offset(start)(%ebp),%eax
> +        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
> +        mov     %eax,%ebx
> +        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
> +        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
> +        add     %ebx,%edx
> +        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
> +        mov     $7,%ecx
> +1:      mov     %eax,(%edx)
> +        add     $8,%edx
> +        add     $(1<<L2_PAGETABLE_SHIFT),%eax
> +        loop    1b
> +
>          /* Hook 4kB mappings of first 2MB of memory into L2. */
> -        mov     $sym_phys(l1_identmap)+__PAGE_HYPERVISOR,%edi
> -        mov     %edi,sym_phys(l2_xenmap)
> -        mov     %edi,sym_phys(l2_bootmap)
> +        lea     (sym_offset(l1_identmap)+__PAGE_HYPERVISOR)(%ebp),%edi
> +        mov     %edi,%fs:sym_offset(l2_bootmap)

But not to l2_xenmap?

>  
>          /* Apply relocations to bootstrap trampoline. */
> -        mov     sym_phys(trampoline_phys),%edx
> -        mov     $sym_phys(__trampoline_rel_start),%edi
> +        mov     %fs:sym_offset(trampoline_phys),%edx
> +        lea     sym_offset(__trampoline_rel_start)(%ebp),%edi
> +        lea     sym_offset(__trampoline_rel_stop)(%ebp),%esi
>  1:
>          mov     (%edi),%eax
>          add     %edx,(%edi,%eax)
>          add     $4,%edi
> -        cmp     $sym_phys(__trampoline_rel_stop),%edi
> +        cmp     %esi,%edi
>          jb      1b
>  
>          /* Patch in the trampoline segment. */
>          shr     $4,%edx
> -        mov     $sym_phys(__trampoline_seg_start),%edi
> +        lea     sym_offset(__trampoline_seg_start)(%ebp),%edi
> +        lea     sym_offset(__trampoline_seg_stop)(%ebp),%esi
>  1:
>          mov     (%edi),%eax
>          mov     %dx,(%edi,%eax)
>          add     $4,%edi
> -        cmp     $sym_phys(__trampoline_seg_stop),%edi
> +        cmp     %esi,%edi
>          jb      1b
>  
>          /* Do not parse command line on EFI platform here. */
> -        cmpb    $1,sym_phys(skip_realmode)
> +        cmpb    $1,%fs:sym_offset(skip_realmode)
>          je      1f
>  
>          /* Bail if there is no command line to parse. */
> -        mov     sym_phys(multiboot_ptr),%ebx
> +        mov     %fs:sym_offset(multiboot_ptr),%ebx
>          testl   $MBI_CMDLINE,MB_flags(%ebx)
>          jz      1f
>  
>          cmpl    $0,MB_cmdline(%ebx)
>          jz      1f
>  
> -        pushl   $sym_phys(early_boot_opts)
> +        lea     sym_offset(early_boot_opts)(%ebp),%eax
> +        push    %eax
>          pushl   MB_cmdline(%ebx)
>          call    cmdline_parse_early
>          add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
>  
>  1:
>          /* Switch to low-memory stack.  */
> -        mov     sym_phys(trampoline_phys),%edi
> +        mov     %fs:sym_offset(trampoline_phys),%edi
>          lea     0x10000(%edi),%esp
>          lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
>          pushl   $BOOT_CS32
>          push    %eax
>  
>          /* Copy bootstrap trampoline to low memory, below 1MB. */
> -        mov     $sym_phys(trampoline_start),%esi
> +        lea     sym_offset(trampoline_start)(%ebp),%esi
>          mov     $trampoline_end - trampoline_start,%ecx
>          rep     movsb
>  
> diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
> index 3c2714d..a8909ce 100644
> --- a/xen/arch/x86/boot/trampoline.S
> +++ b/xen/arch/x86/boot/trampoline.S
> @@ -52,12 +52,20 @@ trampoline_gdt:
>          /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
>          .long   0x0000ffff
>          .long   0x00009200
> +        /*
> +         * 0x0030: ring 0 Xen data, 16 MiB size, base
> +         * address is initialized during runtime.

s/initialized/computed/
> +         */
> +        .quad   0x00c0920000001000
>  
>          .pushsection .trampoline_rel, "a"
>          .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
>          .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
>          .popsection
>  
> +GLOBAL(xen_img_base_phys_addr)
> +        .long   0
> +
>  GLOBAL(cpuid_ext_features)
>          .long   0
>  
> @@ -82,7 +90,8 @@ trampoline_protmode_entry:
>          mov     %ecx,%cr4
>  
>          /* Load pagetable base register. */
> -        mov     $sym_phys(idle_pg_table),%eax
> +        mov     bootsym_rel(xen_img_base_phys_addr,4,%eax)
> +        lea     sym_offset(idle_pg_table)(%eax),%eax
>          add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
>          mov     %eax,%cr3
>  
> diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S
> index 08ea9b2..ff80f7f 100644
> --- a/xen/arch/x86/boot/wakeup.S
> +++ b/xen/arch/x86/boot/wakeup.S
> @@ -119,8 +119,10 @@ wakeup_32:
>          mov     %eax, %ss
>          mov     $bootsym_rel(wakeup_stack, 4, %esp)
>  
> +        mov     bootsym_rel(xen_img_base_phys_addr, 4, %ebx)
> +
>          # check saved magic again
> -        mov     $sym_phys(saved_magic), %eax
> +        lea     sym_offset(saved_magic)(%ebx), %eax
>          add     bootsym_rel(trampoline_xen_phys_start, 4, %eax)
>          mov     (%eax), %eax
>          cmp     $0x9abcdef0, %eax
> @@ -133,7 +135,7 @@ wakeup_32:
>          mov     %ecx, %cr4
>  
>          /* Load pagetable base register */
> -        mov     $sym_phys(idle_pg_table),%eax
> +        lea     sym_offset(idle_pg_table)(%ebx),%eax
>          add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
>          mov     %eax,%cr3
>  
> diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
> index c8bf9d0..ae4bebd 100644
> --- a/xen/arch/x86/boot/x86_64.S
> +++ b/xen/arch/x86/boot/x86_64.S
> @@ -81,7 +81,6 @@ GLOBAL(boot_cpu_compat_gdt_table)
>          .quad 0x0000910000000000     /* per-CPU entry (limit == cpu)      */
>          .align PAGE_SIZE, 0
>  
> -GLOBAL(__page_tables_start)
>  /*
>   * Mapping of first 2 megabytes of memory. This is mapped with 4kB mappings
>   * to avoid type conflicts with fixed-range MTRRs covering the lowest megabyte
> @@ -101,21 +100,18 @@ GLOBAL(l1_identmap)
>          .endr
>          .size l1_identmap, . - l1_identmap
>  
> -/* Mapping of first 16 megabytes of memory. */

Don't want to just update the comment?

> +GLOBAL(__page_tables_start)
> +
>  GLOBAL(l2_identmap)

And perhaps explain how this page is being updated at runtime?

> -        .quad sym_phys(l1_identmap) + __PAGE_HYPERVISOR
> -        pfn = 0
> -        .rept 7
> -        pfn = pfn + (1 << PAGETABLE_ORDER)
> -        .quad (pfn << PAGE_SHIFT) | PAGE_HYPERVISOR | _PAGE_PSE
> -        .endr
> -        .fill 4 * L2_PAGETABLE_ENTRIES - 8, 8, 0
> +        .quad sym_offset(l1_identmap) + __PAGE_HYPERVISOR
> +        .fill 4 * L2_PAGETABLE_ENTRIES - 1, 8, 0
>          .size l2_identmap, . - l2_identmap
>  
>  GLOBAL(l2_xenmap)
> -        idx = 0
> -        .rept 8
> -        .quad sym_phys(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
> +        .quad 0
> +        idx = 1
> +        .rept 7
> +        .quad sym_offset(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
>          idx = idx + 1
>          .endr
>          .fill L2_PAGETABLE_ENTRIES - 8, 8, 0
> @@ -125,7 +121,7 @@ l2_fixmap:
>          idx = 0
>          .rept L2_PAGETABLE_ENTRIES
>          .if idx == l2_table_offset(FIXADDR_TOP - 1)
> -        .quad sym_phys(l1_fixmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l1_fixmap) + __PAGE_HYPERVISOR
>          .else
>          .quad 0
>          .endif
> @@ -136,7 +132,7 @@ l2_fixmap:
>  GLOBAL(l3_identmap)
>          idx = 0
>          .rept 4
> -        .quad sym_phys(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
>          idx = idx + 1
>          .endr
>          .fill L3_PAGETABLE_ENTRIES - 4, 8, 0
> @@ -146,9 +142,9 @@ l3_xenmap:
>          idx = 0
>          .rept L3_PAGETABLE_ENTRIES
>          .if idx == l3_table_offset(XEN_VIRT_START)
> -        .quad sym_phys(l2_xenmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l2_xenmap) + __PAGE_HYPERVISOR
>          .elseif idx == l3_table_offset(FIXADDR_TOP - 1)
> -        .quad sym_phys(l2_fixmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l2_fixmap) + __PAGE_HYPERVISOR
>          .else
>          .quad 0
>          .endif
> @@ -158,13 +154,13 @@ l3_xenmap:
>  
>  /* Top-level master (and idle-domain) page directory. */
>  GLOBAL(idle_pg_table)
> -        .quad sym_phys(l3_bootmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l3_bootmap) + __PAGE_HYPERVISOR
>          idx = 1
>          .rept L4_PAGETABLE_ENTRIES - 1
>          .if idx == l4_table_offset(DIRECTMAP_VIRT_START)
> -        .quad sym_phys(l3_identmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l3_identmap) + __PAGE_HYPERVISOR
>          .elseif idx == l4_table_offset(XEN_VIRT_START)
> -        .quad sym_phys(l3_xenmap) + __PAGE_HYPERVISOR
> +        .quad sym_offset(l3_xenmap) + __PAGE_HYPERVISOR
>          .else
>          .quad 0
>          .endif

> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 8bec67f..8172520 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -291,9 +291,6 @@ static void *__init bootstrap_map(const module_t *mod)
>      if ( start >= end )
>          return NULL;
>  
> -    if ( end <= BOOTSTRAP_MAP_BASE )
> -        return (void *)(unsigned long)start;
> -
>      ret = (void *)(map_cur + (unsigned long)(start & mask));
>      start &= ~mask;
>      end = (end + mask) & ~mask;
> @@ -641,6 +638,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      printk("Command line: %s\n", cmdline);
>  
> +    printk("Xen image base address: 0x%08lx\n",
> +           xen_phys_start ? xen_phys_start : (unsigned long)xen_img_base_phys_addr);
> +
>      printk("Video information:\n");
>  
>      /* Print VGA display mode information. */
> @@ -835,10 +835,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          uint64_t s, e, mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
>          uint64_t end, limit = ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT;
>  
> -        /* Superpage-aligned chunks from BOOTSTRAP_MAP_BASE. */
>          s = (boot_e820.map[i].addr + mask) & ~mask;
>          e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask;
> -        s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE);
>          if ( (boot_e820.map[i].type != E820_RAM) || (s >= e) )
>              continue;
>  
> @@ -876,7 +874,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>              /* Select relocation address. */
>              e = end - reloc_size;
>              xen_phys_start = e;
> -            bootsym(trampoline_xen_phys_start) = e;
> +            bootsym(trampoline_xen_phys_start) = e - xen_img_base_phys_addr;
>  
>              /*
>               * Perform relocation to new physical address.
> @@ -886,7 +884,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>               */
>              load_start = (unsigned long)_start - XEN_VIRT_START;
>              barrier();
> -            move_memory(e + load_start, load_start, _end - _start, 1);
> +            move_memory(e + load_start, load_start + xen_img_base_phys_addr, _end - _start, 1);
>  
>              /* Walk initial pagetables, relocating page directory entries. */
>              pl4e = __va(__pa(idle_pg_table));
> @@ -895,27 +893,27 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                  if ( !(l4e_get_flags(*pl4e) & _PAGE_PRESENT) )
>                      continue;
>                  *pl4e = l4e_from_intpte(l4e_get_intpte(*pl4e) +
> -                                        xen_phys_start);
> +                                        xen_phys_start - xen_img_base_phys_addr);
>                  pl3e = l4e_to_l3e(*pl4e);
>                  for ( j = 0; j < L3_PAGETABLE_ENTRIES; j++, pl3e++ )
>                  {
>                      /* Not present, 1GB mapping, or already relocated? */
>                      if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) ||
>                           (l3e_get_flags(*pl3e) & _PAGE_PSE) ||
> -                         (l3e_get_pfn(*pl3e) > 0x1000) )
> +                         (l3e_get_pfn(*pl3e) > PFN_DOWN(xen_phys_start)) )
>                          continue;
>                      *pl3e = l3e_from_intpte(l3e_get_intpte(*pl3e) +
> -                                            xen_phys_start);
> +                                            xen_phys_start - xen_img_base_phys_addr);
>                      pl2e = l3e_to_l2e(*pl3e);
>                      for ( k = 0; k < L2_PAGETABLE_ENTRIES; k++, pl2e++ )
>                      {
>                          /* Not present, PSE, or already relocated? */
>                          if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
>                               (l2e_get_flags(*pl2e) & _PAGE_PSE) ||
> -                             (l2e_get_pfn(*pl2e) > 0x1000) )
> +                             (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)) )
>                              continue;
>                          *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
> -                                                xen_phys_start);
> +                                                xen_phys_start - xen_img_base_phys_addr);
>                      }
>                  }
>              }
> @@ -926,10 +924,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                                     PAGE_HYPERVISOR_RWX | _PAGE_PSE);
>              for ( i = 1; i < L2_PAGETABLE_ENTRIES; i++, pl2e++ )
>              {
> -                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
> +                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) || (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)))

Could this be split in two lines?

>                      continue;
>                  *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
> -                                        xen_phys_start);
> +                                        xen_phys_start - xen_img_base_phys_addr);
>              }
>  
>              /* Re-sync the stack and then switch to relocated pagetables. */
> @@ -998,6 +996,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      if ( !xen_phys_start )
>          panic("Not enough memory to relocate Xen.");
> +
> +    printk("New Xen image base address: 0x%08lx\n", xen_phys_start);
> +
>      reserve_e820_ram(&boot_e820, __pa(&_start), __pa(&_end));
>  
>      /* Late kexec reservation (dynamic start address). */
> @@ -1070,14 +1071,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>          set_pdx_range(s >> PAGE_SHIFT, e >> PAGE_SHIFT);
>  
> -        /* Need to create mappings above BOOTSTRAP_MAP_BASE. */
> -        map_s = max_t(uint64_t, s, BOOTSTRAP_MAP_BASE);
> +        map_s = s;
>          map_e = min_t(uint64_t, e,
>                        ARRAY_SIZE(l2_identmap) << L2_PAGETABLE_SHIFT);
>  
>          /* Pass mapped memory to allocator /before/ creating new mappings. */
>          init_boot_pages(s, min(map_s, e));
> -        s = map_s;
>          if ( s < map_e )
>          {
>              uint64_t mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
> diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c
> index 98310f3..baa6461 100644
> --- a/xen/arch/x86/x86_64/mm.c
> +++ b/xen/arch/x86/x86_64/mm.c
> @@ -44,7 +44,7 @@ unsigned int __read_mostly m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START;
>  
>  /* Enough page directories to map into the bottom 1GB. */

>  l3_pgentry_t __section(".bss.page_aligned") l3_bootmap[L3_PAGETABLE_ENTRIES];
> -l2_pgentry_t __section(".bss.page_aligned") l2_bootmap[L2_PAGETABLE_ENTRIES];
> +l2_pgentry_t __section(".bss.page_aligned") l2_bootmap[4 * L2_PAGETABLE_ENTRIES];

16KB?

? Confused.
>  
>  l2_pgentry_t *compat_idle_pg_table_l2;
>  
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index a399615..b666a3f 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -38,7 +38,7 @@ SECTIONS
>    . = __XEN_VIRT_START;
>    __image_base__ = .;
>  #endif
> -  . = __XEN_VIRT_START + MB(1);
> +  . = __XEN_VIRT_START + XEN_IMG_OFFSET;
>    _start = .;
>    .text : {
>          _stext = .;            /* Text and read-only data */
> diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
> index 3e9be83..6d21cb7 100644
> --- a/xen/include/asm-x86/config.h
> +++ b/xen/include/asm-x86/config.h
> @@ -114,6 +114,7 @@ extern unsigned long trampoline_phys;
>                   trampoline_phys-__pa(trampoline_start)))
>  extern char trampoline_start[], trampoline_end[];
>  extern char trampoline_realmode_entry[];
> +extern unsigned int xen_img_base_phys_addr;
>  extern unsigned int trampoline_xen_phys_start;
>  extern unsigned char trampoline_cpu_started;
>  extern char wakeup_start[];
> @@ -280,6 +281,8 @@ extern unsigned char boot_edid_info[128];
>  #endif
>  #define DIRECTMAP_VIRT_END      (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)
>  
> +#define XEN_IMG_OFFSET          0x200000
> +
>  #ifndef __ASSEMBLY__
>  
>  /* This is not a fixed value, just a lower limit. */
> diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
> index 87b3341..27481ac 100644
> --- a/xen/include/asm-x86/page.h
> +++ b/xen/include/asm-x86/page.h
> @@ -283,7 +283,7 @@ extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
>  extern l2_pgentry_t  *compat_idle_pg_table_l2;
>  extern unsigned int   m2p_compat_vstart;
>  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
> -    l2_bootmap[L2_PAGETABLE_ENTRIES];
> +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];

? Why do we need to expand this to be 16kB?

>  extern l3_pgentry_t l3_bootmap[L3_PAGETABLE_ENTRIES];
>  extern l2_pgentry_t l2_identmap[4*L2_PAGETABLE_ENTRIES];
>  extern l1_pgentry_t l1_identmap[L1_PAGETABLE_ENTRIES],
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images
  2015-07-20 14:29 ` [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
@ 2015-08-11 16:56   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150811165658.GC32231@l.oracle.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-11 16:56 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, Jul 20, 2015 at 04:29:18PM +0200, Daniel Kiper wrote:
> Add multiboot2 protocol support for relocatable images. Only GRUB2
> with relevant patches understands that feature. Older multiboot

You may want to enumerate what those 'relevant' patches are.

> protocol (regardless of version) compatible loaders ignore it
> and everything works as usual.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/arch/x86/boot/head.S          |   46 +++++++++++++++++++++++++++++--------
>  xen/arch/x86/x86_64/asm-offsets.c |    1 +
>  xen/include/xen/multiboot2.h      |   13 +++++++++++
>  3 files changed, 50 insertions(+), 10 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index d484f68..2520e48 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -81,6 +81,13 @@ multiboot1_header_end:
>          /* Align modules at page boundry. */
>          mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
>  
> +        /* Load address preference. */
> +        mb2ht_init MB2_HT(RELOCATABLE), MB2_HT(OPTIONAL), \
> +                   sym_phys(start), /* Min load address. */ \

We could go straight to __start?

> +                   0xffffffff, /* Max load address (4 GiB - 1). */ \
> +                   0x200000, /* Load address alignment (2 MiB). */ \
> +                   MULTIBOOT2_LOAD_PREFERENCE_HIGH
> +
>          /* Console flags tag. */
>          mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
>                     MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> @@ -176,30 +183,39 @@ efi_multiboot2_proto:
>          lea     MB2_fixed_sizeof(%rbx),%rcx
>  
>  0:
> +        /* Get Xen image base address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASE_ADDR,MB2_tag_type(%rcx)
> +        jne     1f
> +
> +        mov     MB2_base_addr(%rcx),%ebp
> +        sub     $XEN_IMG_OFFSET,%rbp
> +        jmp     4f
> +
> +1:
>          /* Get EFI SystemTable address from Multiboot2 information. */
>          cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
> -        jne     1f
> +        jne     2f
>  
>          mov     MB2_efi64_st(%rcx),%rsi
>  
>          /* Do not go into real mode on EFI platform. */
>          movb    $1,skip_realmode(%rip)
> -        jmp     3f
> +        jmp     4f
>  
> -1:
> +2:
>          /* Get EFI ImageHandle address from Multiboot2 information. */
>          cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
> -        jne     2f
> +        jne     3f
>  
>          mov     MB2_efi64_ih(%rcx),%rdi
> -        jmp     3f
> +        jmp     4f
>  
> -2:
> +3:
>          /* Is it the end of Multiboot2 information? */
>          cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
>          je      run_bs
>  
> -3:
> +4:
>          /* Go to next Multiboot2 information tag. */
>          add     MB2_tag_size(%rcx),%ecx
>          add     $(MULTIBOOT2_TAG_ALIGN-1),%rcx
> @@ -297,14 +313,23 @@ multiboot2_proto:
>          lea     MB2_fixed_sizeof(%ebx),%ecx
>  
>  0:
> +        /* Get Xen image base address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASE_ADDR,MB2_tag_type(%ecx)
> +        jne     1f
> +
> +        mov     MB2_base_addr(%ecx),%ebp
> +        sub     $XEN_IMG_OFFSET,%ebp
> +        jmp     3f
> +
> +1:
>          /* Get mem_lower from Multiboot2 information. */
>          cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
> -        jne     1f
> +        jne     2f
>  
>          mov     MB2_mem_lower(%ecx),%edx
> -        jmp     trampoline_bios_setup
> +        jmp     3f
>  
> -1:
> +2:
>          /* EFI mode is not supported via legacy BIOS path. */
>          cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
>          je      mb2_too_old
> @@ -316,6 +341,7 @@ multiboot2_proto:
>          cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
>          je      trampoline_bios_setup
>  
> +3:
>          /* Go to next Multiboot2 information tag. */
>          add     MB2_tag_size(%ecx),%ecx
>          add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index b7aed49..5345a9e 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -172,6 +172,7 @@ void __dummy__(void)
>      DEFINE(MB2_fixed_sizeof, sizeof(multiboot2_fixed_t));
>      OFFSET(MB2_tag_type, multiboot2_tag_t, type);
>      OFFSET(MB2_tag_size, multiboot2_tag_t, size);
> +    OFFSET(MB2_base_addr, multiboot2_tag_base_addr_t, base_addr);
>      OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
>      OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer);
>      OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
> diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
> index 09ee64e..a63c4d6 100644
> --- a/xen/include/xen/multiboot2.h
> +++ b/xen/include/xen/multiboot2.h
> @@ -59,11 +59,17 @@
>  #define MULTIBOOT2_HEADER_TAG_EFI_BS			7
>  #define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32	8
>  #define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64	9
> +#define MULTIBOOT2_HEADER_TAG_RELOCATABLE		10
>  
>  /* Header tag flags. */
>  #define MULTIBOOT2_HEADER_TAG_REQUIRED	0
>  #define MULTIBOOT2_HEADER_TAG_OPTIONAL	1
>  
> +/* Where image should be loaded (suggestion not requirement). */
> +#define MULTIBOOT2_LOAD_PREFERENCE_NONE	0
> +#define MULTIBOOT2_LOAD_PREFERENCE_LOW	1
> +#define MULTIBOOT2_LOAD_PREFERENCE_HIGH	2


Would be good for all of this (with the other MULTIBOOT2..)
to be aligned on the same column-ish.

> +
>  /* Header console tag console_flags. */
>  #define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED	1
>  #define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED	2
> @@ -90,6 +96,7 @@
>  #define MULTIBOOT2_TAG_TYPE_EFI_BS		18
>  #define MULTIBOOT2_TAG_TYPE_EFI32_IH		19
>  #define MULTIBOOT2_TAG_TYPE_EFI64_IH		20
> +#define MULTIBOOT2_TAG_TYPE_BASE_ADDR		21
>  
>  /* Multiboot 2 tag alignment. */
>  #define MULTIBOOT2_TAG_ALIGN			8
> @@ -120,6 +127,12 @@ typedef struct {
>  typedef struct {
>      u32 type;
>      u32 size;
> +    u32 base_addr;
> +} multiboot2_tag_base_addr_t;
> +
> +typedef struct {
> +    u32 type;
> +    u32 size;
>      char string[0];
>  } multiboot2_tag_string_t;
>  
> -- 
> 1.7.10.4
> 

Otherwise, Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
       [not found]   ` <20150810191747.GE13576@l.oracle.com>
@ 2015-08-13 19:22     ` Daniel Kiper
       [not found]     ` <20150813192212.GI3503@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-13 19:22 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Mon, Aug 10, 2015 at 03:17:48PM -0400, Konrad Rzeszutek Wilk wrote:
> On Mon, Jul 20, 2015 at 04:29:03PM +0200, Daniel Kiper wrote:
> > Add multiboot2 protocol support. Alter min memory limit handling as we
> > now may not find it from either multiboot (v1) or multiboot2.
> >
> > This way we are laying the foundation for EFI + GRUB2 + Xen development.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> > ---
> > v2 - suggestions/fixes:
> >    - generate multiboot2 header using macros
> >      (suggested by Jan Beulich),
> >    - improve comments
> >      (suggested by Jan Beulich),
> >    - simplify assembly in xen/arch/x86/boot/head.S
> >      (suggested by Jan Beulich),
> >    - do not include include/xen/compiler.h
> >      in xen/arch/x86/boot/reloc.c
> >      (suggested by Jan Beulich),
> >    - do not read data beyond the end of Multiboot2 information
> >      (suggested by Jan Beulich).
> >
> > v2 - not fixed yet:
>
> You have two 'v2'

Yep, but it says "not fixed in v2".

> >    - dynamic dependency generation for xen/arch/x86/boot/reloc.S;
> >      this requires more work; I am not sure that it pays because
> >      potential patch requires more changes than addition of just
> >      multiboot2.h to Makefile
> >      (suggested by Jan Beulich),
> >    - isolated/stray __packed attribute usage for multiboot2_memory_map_t
> >      (suggested by Jan Beulich).
> > ---
> >  xen/arch/x86/boot/Makefile        |    3 +-
> >  xen/arch/x86/boot/head.S          |  105 +++++++++++++++++++++--
> >  xen/arch/x86/boot/reloc.c         |  146 +++++++++++++++++++++++++++++++-
> >  xen/arch/x86/x86_64/asm-offsets.c |    7 ++
> >  xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
> >  5 files changed, 420 insertions(+), 10 deletions(-)
> >  create mode 100644 xen/include/xen/multiboot2.h
> >
> > diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
> > index 5fdb5ae..06893d8 100644
> > --- a/xen/arch/x86/boot/Makefile
> > +++ b/xen/arch/x86/boot/Makefile
> > @@ -1,6 +1,7 @@
> >  obj-bin-y += head.o
> >
> > -RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h
> > +RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
> > +	     $(BASEDIR)/include/xen/multiboot2.h
> >
> >  head.o: reloc.S
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index 77e7da9..57197db 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -1,5 +1,6 @@
> >  #include <xen/config.h>
> >  #include <xen/multiboot.h>
> > +#include <xen/multiboot2.h>
> >  #include <public/xen.h>
> >  #include <asm/asm_defns.h>
> >  #include <asm/desc.h>
> > @@ -19,6 +20,28 @@
> >  #define BOOT_PSEUDORM_CS 0x0020
> >  #define BOOT_PSEUDORM_DS 0x0028
> >
> > +#define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
> > +#define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
> > +
> > +        .macro mb2ht_args arg, args:vararg
> > +        .long \arg
> > +        .ifnb \args
> > +        mb2ht_args \args
> > +        .endif
> > +        .endm
> > +
> > +        .macro mb2ht_init type, req, args:vararg
> > +        .align MULTIBOOT2_TAG_ALIGN
> > +        0:
> > +        .short \type
> > +        .short \req
> > +        .long 1f - 0b
> > +        .ifnb \args
> > +        mb2ht_args \args
> > +        .endif
> > +        1:
> > +        .endm
> > +
> >  ENTRY(start)
> >          jmp     __start
> >
> > @@ -34,6 +57,42 @@ multiboot1_header_start:       /*** MULTIBOOT1 HEADER ****/
> >          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
> >  multiboot1_header_end:
> >
> > +/*** MULTIBOOT2 HEADER ****/
> > +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
> > +        .align  MULTIBOOT2_HEADER_ALIGN
> > +
> > +.Lmultiboot2_header:
>
> How come you use .L? It makes this hidden while the multiboot1 headers
> are visible? Makes it a bit harder to see the contents of this under
> an debugger.

Good point. IIRC, Jan asked about that. I will remove .L if he does not object.

> > +        /* Magic number indicating a Multiboot2 header. */
> > +        .long   MULTIBOOT2_HEADER_MAGIC
> > +        /* Architecture: i386. */
> > +        .long   MULTIBOOT2_ARCHITECTURE_I386
> > +        /* Multiboot2 header length. */
> > +        .long   .Lmultiboot2_header_end - .Lmultiboot2_header
> > +        /* Multiboot2 header checksum. */
> > +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> > +                        (.Lmultiboot2_header_end - .Lmultiboot2_header))
> > +
> > +        /* Multiboot2 information request tag. */
> > +        mb2ht_init MB2_HT(INFORMATION_REQUEST), MB2_HT(REQUIRED), \
> > +                   MB2_TT(BASIC_MEMINFO), MB2_TT(MMAP)
> > +
> > +        /* Align modules at page boundry. */
> > +        mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
> > +
> > +        /* Console flags tag. */
> > +        mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \
> > +                   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> > +
> > +        /* Framebuffer tag. */
> > +        mb2ht_init MB2_HT(FRAMEBUFFER), MB2_HT(OPTIONAL), \
> > +                   0, /* Number of the columns - no preference. */ \
> > +                   0, /* Number of the lines - no preference. */ \
> > +                   0  /* Number of bits per pixel - no preference. */
> > +
> > +        /* Multiboot2 header end tag. */
> > +        mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
> > +.Lmultiboot2_header_end:
> > +
> >          .section .init.rodata, "a", @progbits
> >          .align 4
> >
> > @@ -82,10 +141,48 @@ __start:
> >          mov     %ecx,%es
> >          mov     %ecx,%ss
> >
> > -        /* Check for Multiboot bootloader */
> > +        /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
> > +        xor     %edx,%edx
> > +
> > +        /* Check for Multiboot2 bootloader. */
> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +        je      multiboot2_proto
> > +
> > +        /* Check for Multiboot bootloader. */
> >          cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> >          jne     not_multiboot
> >
> > +        /* Get mem_lower from Multiboot information. */
> > +        testb   $MBI_MEMLIMITS,MB_flags(%ebx)
> > +
> > +        /* Not available? BDA value will be fine. */
> > +        cmovnz  MB_mem_lower(%ebx),%edx
> > +        jmp     trampoline_setup
> > +
> > +multiboot2_proto:
> > +        /* Skip Multiboot2 information fixed part. */
> > +        lea     MB2_fixed_sizeof(%ebx),%ecx
>
> Is there any point of double checking the aligment? That is
>         and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>
> ?
>
> Looking at the grub code it requests the memory to be aligned properly
> so in practice this will never fail. But since somebody might for fun
> allocate the structure to not be aligned and the fixed part could finish
> on non-aligned space..

You are right, we should check it. multiboot2 spec states:

3.4.2 Basic tags structure

Boot information consists of fixed part and a series of tags. Its start
is 8-bytes aligned.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
       [not found]     ` <20150813192212.GI3503@olila.local.net-space.pl>
@ 2015-08-14 10:03       ` Jan Beulich
       [not found]       ` <55CDD8F4020000780009AF3C@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-14 10:03 UTC (permalink / raw)
  To: Daniel Kiper, Konrad Rzeszutek Wilk
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 13.08.15 at 21:22, <daniel.kiper@oracle.com> wrote:
> On Mon, Aug 10, 2015 at 03:17:48PM -0400, Konrad Rzeszutek Wilk wrote:
>> On Mon, Jul 20, 2015 at 04:29:03PM +0200, Daniel Kiper wrote:
>> > @@ -34,6 +57,42 @@ multiboot1_header_start:       /*** MULTIBOOT1 HEADER ****/
>> >          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
>> >  multiboot1_header_end:
>> >
>> > +/*** MULTIBOOT2 HEADER ****/
>> > +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
>> > +        .align  MULTIBOOT2_HEADER_ALIGN
>> > +
>> > +.Lmultiboot2_header:
>>
>> How come you use .L? It makes this hidden while the multiboot1 headers
>> are visible? Makes it a bit harder to see the contents of this under
>> an debugger.
> 
> Good point. IIRC, Jan asked about that. I will remove .L if he does not 
> object.

For this particular one I think it's okay to drop the .L, but generally
I'd like to see .L used more widely for any auxiliary labels (i.e. only
"main" labels - function entry points and data objects - should have
their labels present in the final symbol table).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]   ` <20150811164806.GB32231@l.oracle.com>
@ 2015-08-14 11:52     ` Daniel Kiper
       [not found]     ` <20150814115205.GA8034@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-14 11:52 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
> > Every multiboot protocol (regardless of version) compatible image must
> > specify its load address (in ELF or multiboot header). Multiboot protocol
> > compatible loader have to load image at specified address. However, there
> > is no guarantee that the requested memory region (in case of Xen it starts
> > at 1 MiB and ends at 17 MiB) where image should be loaded initially is a RAM
> > and it is free (legacy BIOS platforms are merciful for Xen but I found at
> > least one EFI platform on which Xen load address conflicts with EFI boot
> > services; it is Dell PowerEdge R820 with latest firmware). To cope with
> > that problem we must make Xen early boot code relocatable. This patch does
> > that. However, it does not add multiboot2 protocol interface which is done
> > in next patch.
>
> s/next patch/"x86: add multiboot2 protocol support for relocatable image."
> >
> > This patch changes following things:
> >   - default load address is changed from 1 MiB to 2 MiB; I did that because
> >     initial page tables are using 2 MiB huge pages and this way required
> >     updates for them are quite easy; it means that e.g. we avoid spacial
> >     cases for beginning and end of required memory region if it live at
> >     address not aligned to 2 MiB,
> >   - %ebp register is used as a storage for Xen image base address; this way
> >     we can get this value very quickly if it is needed; however, %ebp register
> >     is not used directly to access a given memory region,
> >   - %fs register is filled with segment descriptor which describes memory region
> >     with Xen image (it could be relocated or not); it is used to access some of
>
> 'memory region with Xen image' ? Not sure I follow?
>
> Perhaps:
> segment descriptor which starts (0) at Xen image base (_start).
>
>
> >     Xen data in early boot code; potentially we can use above mentioned segment
> >     descriptor to access data using %ds:%esi and/or %es:%esi (e.g. movs*); however,
> >     I think that it could unnecessarily obfuscate code (e.g. we need at least
> >     to operations to reload a given segment descriptor) and current solution
>
> s/to/two/ ?
> >     looks quite optimal.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

[...]

> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index 3f1054d..d484f68 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S

[...]

> >  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?

This is very good question. I was asking myself about that thing at
least once. Sadly, I cannot find real explanation.

> Let me double-check what SYSLINUX's mboot.c32 does. Perhaps
> it had done something odd in the past.

Good idea!

> >          /* Set up trampoline segment 64k below EBDA */
> >          movzwl  0x40e,%ecx          /* EBDA segment */
> >          cmp     $0xa000,%ecx        /* sanity check (high) */
> > @@ -340,33 +357,58 @@ trampoline_bios_setup:
> >          cmovb   %edx,%ecx           /* and use the smaller */
> >
> >  trampoline_setup:
>
> Would it make sense to add:
>
> /* Gets called from EFI (from x86_32_switch) and legacy (see above) boot loaders. */
>
> > +        mov     %ebp,%esi
> > +
> > +        /* Initialize 0-15 bits of BOOT_FS segment descriptor base address. */
> > +        mov     %ebp,%edx
> > +        shl     $16,%edx
> > +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS)(%esi)
> > +
> > +        /* Initialize 16-23 bits of BOOT_FS segment descriptor base address. */
> > +        mov     %ebp,%edx
> > +        shr     $16,%edx
> > +        and     $0x000000ff,%edx
> > +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
> > +
> > +        /* Initialize 24-31 bits of BOOT_FS segment descriptor base address. */
> > +        mov     %ebp,%edx
> > +        and     $0xff000000,%edx
> > +        or      %edx,(sym_offset(trampoline_gdt)+BOOT_FS+4)(%esi)
> > +
> > +        /* Initialize %fs and later use it to access Xen data if possible. */
> > +        mov     $BOOT_FS,%edx
> > +        mov     %edx,%fs
> > +
>
> We just modified the GDT. Should we reload it (lgdt?)?

I do not think it is needed.

Intel 64 and IA-32 Architectures Software Developer’s Manual,
Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z says:

LGDT ... Loads the values in the source operand into the global
descriptor table register (GDTR)...

...and ...

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
selector and segment descriptor information is validated (see the
"Operation" algorithm below). The segment descriptor data is obtained
from the GDT or LDT entry for the specified segment selector.

Additionally, Intel 64 and IA-32 Architectures Software Developer’s
Manual Volume 3 (3A, 3B & 3C): System Programming Guide, section 3.4.3,
Segment Registers says:

Every segment register has a "visible" part and a "hidden" part. (The
hidden part is sometimes referred to as a "descriptor cache" or a
"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 access
control information from the segment descriptor pointed to by the segment
selector. The information cached in the segment register (visible and
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 note:
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.

AIUI, only GDT address and limit are loaded into GDTR when lgdt is executed.
Segment descriptor is loaded directly from memory into segment register
(hiden part) only when relevant load instruction is used (e.g. mov %edx,%fs).
Though GDT content probably could be stored in CPU cache but nothing suggest
that CPU caching interfere in one way or another with segment descriptor load.
So, it looks that every change in active GDT is immediately available for
relevant segment descriptor load instruction.

I was not able to find anything which invalidates above. So, everything
suggest that we do not need an extra lgdt.

> >          /* Reserve 64kb for the trampoline. */
> >          sub     $0x1000,%ecx

[...]

> >          /* Hook 4kB mappings of first 2MB of memory into L2. */
> > -        mov     $sym_phys(l1_identmap)+__PAGE_HYPERVISOR,%edi
> > -        mov     %edi,sym_phys(l2_xenmap)
> > -        mov     %edi,sym_phys(l2_bootmap)
> > +        lea     (sym_offset(l1_identmap)+__PAGE_HYPERVISOR)(%ebp),%edi
> > +        mov     %edi,%fs:sym_offset(l2_bootmap)
>
> But not to l2_xenmap?

No, l?_xenmap maps Xen code and data only.

> >          /* Apply relocations to bootstrap trampoline. */
> > -        mov     sym_phys(trampoline_phys),%edx
> > -        mov     $sym_phys(__trampoline_rel_start),%edi
> > +        mov     %fs:sym_offset(trampoline_phys),%edx
> > +        lea     sym_offset(__trampoline_rel_start)(%ebp),%edi
> > +        lea     sym_offset(__trampoline_rel_stop)(%ebp),%esi

[...]

> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
> > index 87b3341..27481ac 100644
> > --- a/xen/include/asm-x86/page.h
> > +++ b/xen/include/asm-x86/page.h
> > @@ -283,7 +283,7 @@ extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
> >  extern unsigned int   m2p_compat_vstart;
> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
>
> ? Why do we need to expand this to be 16kB?

TBH, we need 8 KiB in the worst case. The worst case is when
next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
of Xen image. In this situation we must hook up lower l2_bootmap
table with lower l3_bootmap entry, higher l2_bootmap table with
higher l3_bootmap entry and finally fill l2_bootmap relevant
tables in proper way. Sadly, this method requires more calculations.
To avoid that I have added 3 l2_bootmap tables and simply hook up
one after another with relevant l3_bootmap entries. However, if
you wish we can reduce number of l2_bootmap tables to two. This
way code will be more complicated but we will save about 8 KiB.

Daniel

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

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images
       [not found]   ` <20150811165658.GC32231@l.oracle.com>
@ 2015-08-14 11:57     ` Daniel Kiper
       [not found]     ` <20150814115701.GB8034@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-14 11:57 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, Aug 11, 2015 at 12:56:58PM -0400, Konrad Rzeszutek Wilk wrote:
> On Mon, Jul 20, 2015 at 04:29:18PM +0200, Daniel Kiper wrote:
> > Add multiboot2 protocol support for relocatable images. Only GRUB2
> > with relevant patches understands that feature. Older multiboot
>
> You may want to enumerate what those 'relevant' patches are.
>
> > protocol (regardless of version) compatible loaders ignore it
> > and everything works as usual.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > ---
> >  xen/arch/x86/boot/head.S          |   46 +++++++++++++++++++++++++++++--------
> >  xen/arch/x86/x86_64/asm-offsets.c |    1 +
> >  xen/include/xen/multiboot2.h      |   13 +++++++++++
> >  3 files changed, 50 insertions(+), 10 deletions(-)
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index d484f68..2520e48 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -81,6 +81,13 @@ multiboot1_header_end:
> >          /* Align modules at page boundry. */
> >          mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
> >
> > +        /* Load address preference. */
> > +        mb2ht_init MB2_HT(RELOCATABLE), MB2_HT(OPTIONAL), \
> > +                   sym_phys(start), /* Min load address. */ \
>
> We could go straight to __start?

This specifies lowest load address not entry point.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]     ` <20150814115205.GA8034@olila.local.net-space.pl>
@ 2015-08-14 12:49       ` Jan Beulich
       [not found]       ` <55CDFFEE020000780009B0B0@prv-mh.provo.novell.com>
  2015-08-14 15:20       ` Konrad Rzeszutek Wilk
  2 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-14 12:49 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 14.08.15 at 13:52, <daniel.kiper@oracle.com> wrote:
> On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
>> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
>> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
>> > index 87b3341..27481ac 100644
>> > --- a/xen/include/asm-x86/page.h
>> > +++ b/xen/include/asm-x86/page.h
>> > @@ -283,7 +283,7 @@ extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
>> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
>> >  extern unsigned int   m2p_compat_vstart;
>> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
>> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
>> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
>>
>> ? Why do we need to expand this to be 16kB?
> 
> TBH, we need 8 KiB in the worst case. The worst case is when
> next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
> of Xen image. In this situation we must hook up lower l2_bootmap
> table with lower l3_bootmap entry, higher l2_bootmap table with
> higher l3_bootmap entry and finally fill l2_bootmap relevant
> tables in proper way. Sadly, this method requires more calculations.
> To avoid that I have added 3 l2_bootmap tables and simply hook up
> one after another with relevant l3_bootmap entries. However, if
> you wish we can reduce number of l2_bootmap tables to two. This
> way code will be more complicated but we will save about 8 KiB.

Wouldn't it be better (simpler) to enforce, say, 16Mb alignment
in the PE32+ header (which the EFI loader would then honor)?

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images
       [not found]     ` <20150814115701.GB8034@olila.local.net-space.pl>
@ 2015-08-14 13:43       ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-14 13:43 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, wei.liu2, keir, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, jbeulich, phcoder, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Aug 14, 2015 at 01:57:01PM +0200, Daniel Kiper wrote:
> On Tue, Aug 11, 2015 at 12:56:58PM -0400, Konrad Rzeszutek Wilk wrote:
> > On Mon, Jul 20, 2015 at 04:29:18PM +0200, Daniel Kiper wrote:
> > > Add multiboot2 protocol support for relocatable images. Only GRUB2
> > > with relevant patches understands that feature. Older multiboot
> >
> > You may want to enumerate what those 'relevant' patches are.
> >
> > > protocol (regardless of version) compatible loaders ignore it
> > > and everything works as usual.
> > >
> > > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > > ---
> > >  xen/arch/x86/boot/head.S          |   46 +++++++++++++++++++++++++++++--------
> > >  xen/arch/x86/x86_64/asm-offsets.c |    1 +
> > >  xen/include/xen/multiboot2.h      |   13 +++++++++++
> > >  3 files changed, 50 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > > index d484f68..2520e48 100644
> > > --- a/xen/arch/x86/boot/head.S
> > > +++ b/xen/arch/x86/boot/head.S
> > > @@ -81,6 +81,13 @@ multiboot1_header_end:
> > >          /* Align modules at page boundry. */
> > >          mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED)
> > >
> > > +        /* Load address preference. */
> > > +        mb2ht_init MB2_HT(RELOCATABLE), MB2_HT(OPTIONAL), \
> > > +                   sym_phys(start), /* Min load address. */ \
> >
> > We could go straight to __start?
> 
> This specifies lowest load address not entry point.

Ah right. And the __start can be moved somewhere inside the .text
code, while 'start' is always at offset 0. Thank you!

> 
> Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]       ` <55CDFFEE020000780009B0B0@prv-mh.provo.novell.com>
@ 2015-08-14 13:59         ` Daniel Kiper
       [not found]         ` <20150814135904.GC8034@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-14 13:59 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Aug 14, 2015 at 06:49:18AM -0600, Jan Beulich wrote:
> >>> On 14.08.15 at 13:52, <daniel.kiper@oracle.com> wrote:
> > On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
> >> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
> >> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
> >> > index 87b3341..27481ac 100644
> >> > --- a/xen/include/asm-x86/page.h
> >> > +++ b/xen/include/asm-x86/page.h
> >> > @@ -283,7 +283,7 @@ extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES];
> >> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
> >> >  extern unsigned int   m2p_compat_vstart;
> >> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
> >> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
> >> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
> >>
> >> ? Why do we need to expand this to be 16kB?
> >
> > TBH, we need 8 KiB in the worst case. The worst case is when
> > next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
> > of Xen image. In this situation we must hook up lower l2_bootmap
> > table with lower l3_bootmap entry, higher l2_bootmap table with
> > higher l3_bootmap entry and finally fill l2_bootmap relevant
> > tables in proper way. Sadly, this method requires more calculations.
> > To avoid that I have added 3 l2_bootmap tables and simply hook up
> > one after another with relevant l3_bootmap entries. However, if
> > you wish we can reduce number of l2_bootmap tables to two. This
> > way code will be more complicated but we will save about 8 KiB.
>
> Wouldn't it be better (simpler) to enforce, say, 16Mb alignment
> in the PE32+ header (which the EFI loader would then honor)?

Good idea but then we must enforce this for multiboot protocol (v1 and v2) too.
multiboot2 with my patches supports that solution. However, multiboot (v1) could
be a bit problematic because it means that we must set load address to 16 MiB.
Are we sure that this region is available on all machines like region starting
at 1 MiB?

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]         ` <20150814135904.GC8034@olila.local.net-space.pl>
@ 2015-08-14 14:32           ` Jan Beulich
       [not found]           ` <55CE1805020000780009B1C0@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-14 14:32 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 14.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
> On Fri, Aug 14, 2015 at 06:49:18AM -0600, Jan Beulich wrote:
>> >>> On 14.08.15 at 13:52, <daniel.kiper@oracle.com> wrote:
>> > On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
>> >> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
>> >> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
>> >> > index 87b3341..27481ac 100644
>> >> > --- a/xen/include/asm-x86/page.h
>> >> > +++ b/xen/include/asm-x86/page.h
>> >> > @@ -283,7 +283,7 @@ extern root_pgentry_t 
> idle_pg_table[ROOT_PAGETABLE_ENTRIES];
>> >> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
>> >> >  extern unsigned int   m2p_compat_vstart;
>> >> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
>> >> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
>> >> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
>> >>
>> >> ? Why do we need to expand this to be 16kB?
>> >
>> > TBH, we need 8 KiB in the worst case. The worst case is when
>> > next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
>> > of Xen image. In this situation we must hook up lower l2_bootmap
>> > table with lower l3_bootmap entry, higher l2_bootmap table with
>> > higher l3_bootmap entry and finally fill l2_bootmap relevant
>> > tables in proper way. Sadly, this method requires more calculations.
>> > To avoid that I have added 3 l2_bootmap tables and simply hook up
>> > one after another with relevant l3_bootmap entries. However, if
>> > you wish we can reduce number of l2_bootmap tables to two. This
>> > way code will be more complicated but we will save about 8 KiB.
>>
>> Wouldn't it be better (simpler) to enforce, say, 16Mb alignment
>> in the PE32+ header (which the EFI loader would then honor)?
> 
> Good idea but then we must enforce this for multiboot protocol (v1 and v2) 
> too.
> multiboot2 with my patches supports that solution. However, multiboot (v1) 
> could
> be a bit problematic because it means that we must set load address to 16 
> MiB.
> Are we sure that this region is available on all machines like region 
> starting
> at 1 MiB?

"This region" being which one?

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]           ` <55CE1805020000780009B1C0@prv-mh.provo.novell.com>
@ 2015-08-14 14:37             ` Daniel Kiper
       [not found]             ` <20150814143729.GE8034@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-14 14:37 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Aug 14, 2015 at 08:32:05AM -0600, Jan Beulich wrote:
> >>> On 14.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
> > On Fri, Aug 14, 2015 at 06:49:18AM -0600, Jan Beulich wrote:
> >> >>> On 14.08.15 at 13:52, <daniel.kiper@oracle.com> wrote:
> >> > On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
> >> >> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
> >> >> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
> >> >> > index 87b3341..27481ac 100644
> >> >> > --- a/xen/include/asm-x86/page.h
> >> >> > +++ b/xen/include/asm-x86/page.h
> >> >> > @@ -283,7 +283,7 @@ extern root_pgentry_t
> > idle_pg_table[ROOT_PAGETABLE_ENTRIES];
> >> >> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
> >> >> >  extern unsigned int   m2p_compat_vstart;
> >> >> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
> >> >> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
> >> >> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
> >> >>
> >> >> ? Why do we need to expand this to be 16kB?
> >> >
> >> > TBH, we need 8 KiB in the worst case. The worst case is when
> >> > next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
> >> > of Xen image. In this situation we must hook up lower l2_bootmap
> >> > table with lower l3_bootmap entry, higher l2_bootmap table with
> >> > higher l3_bootmap entry and finally fill l2_bootmap relevant
> >> > tables in proper way. Sadly, this method requires more calculations.
> >> > To avoid that I have added 3 l2_bootmap tables and simply hook up
> >> > one after another with relevant l3_bootmap entries. However, if
> >> > you wish we can reduce number of l2_bootmap tables to two. This
> >> > way code will be more complicated but we will save about 8 KiB.
> >>
> >> Wouldn't it be better (simpler) to enforce, say, 16Mb alignment
> >> in the PE32+ header (which the EFI loader would then honor)?
> >
> > Good idea but then we must enforce this for multiboot protocol (v1 and v2)
> > too.
> > multiboot2 with my patches supports that solution. However, multiboot (v1)
> > could
> > be a bit problematic because it means that we must set load address to 16
> > MiB.
> > Are we sure that this region is available on all machines like region
> > starting
> > at 1 MiB?
>
> "This region" being which one?

16 MiB - 32 MiB.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]             ` <20150814143729.GE8034@olila.local.net-space.pl>
@ 2015-08-14 15:12               ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-14 15:12 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 14.08.15 at 16:37, <daniel.kiper@oracle.com> wrote:
> On Fri, Aug 14, 2015 at 08:32:05AM -0600, Jan Beulich wrote:
>> >>> On 14.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
>> > On Fri, Aug 14, 2015 at 06:49:18AM -0600, Jan Beulich wrote:
>> >> >>> On 14.08.15 at 13:52, <daniel.kiper@oracle.com> wrote:
>> >> > On Tue, Aug 11, 2015 at 12:48:06PM -0400, Konrad Rzeszutek Wilk wrote:
>> >> >> On Mon, Jul 20, 2015 at 04:29:17PM +0200, Daniel Kiper wrote:
>> >> >> > diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
>> >> >> > index 87b3341..27481ac 100644
>> >> >> > --- a/xen/include/asm-x86/page.h
>> >> >> > +++ b/xen/include/asm-x86/page.h
>> >> >> > @@ -283,7 +283,7 @@ extern root_pgentry_t
>> > idle_pg_table[ROOT_PAGETABLE_ENTRIES];
>> >> >> >  extern l2_pgentry_t  *compat_idle_pg_table_l2;
>> >> >> >  extern unsigned int   m2p_compat_vstart;
>> >> >> >  extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES],
>> >> >> > -    l2_bootmap[L2_PAGETABLE_ENTRIES];
>> >> >> > +    l2_bootmap[4*L2_PAGETABLE_ENTRIES];
>> >> >>
>> >> >> ? Why do we need to expand this to be 16kB?
>> >> >
>> >> > TBH, we need 8 KiB in the worst case. The worst case is when
>> >> > next GiB starts (e.g. 1 GiB ends and 2 GiB starts) in the middle
>> >> > of Xen image. In this situation we must hook up lower l2_bootmap
>> >> > table with lower l3_bootmap entry, higher l2_bootmap table with
>> >> > higher l3_bootmap entry and finally fill l2_bootmap relevant
>> >> > tables in proper way. Sadly, this method requires more calculations.
>> >> > To avoid that I have added 3 l2_bootmap tables and simply hook up
>> >> > one after another with relevant l3_bootmap entries. However, if
>> >> > you wish we can reduce number of l2_bootmap tables to two. This
>> >> > way code will be more complicated but we will save about 8 KiB.
>> >>
>> >> Wouldn't it be better (simpler) to enforce, say, 16Mb alignment
>> >> in the PE32+ header (which the EFI loader would then honor)?
>> >
>> > Good idea but then we must enforce this for multiboot protocol (v1 and v2)
>> > too.
>> > multiboot2 with my patches supports that solution. However, multiboot (v1)
>> > could
>> > be a bit problematic because it means that we must set load address to 16
>> > MiB.
>> > Are we sure that this region is available on all machines like region
>> > starting
>> > at 1 MiB?
>>
>> "This region" being which one?
> 
> 16 MiB - 32 MiB.

While I think all systems where Xen can reasonably run on would
have memory in that range, I'd really prefer not to touch the MB1
case (i.e. find a way for it to continue to load at 1Mb). Perhaps
the 16Mb alignment could be specified only in the PE32+ header,
but not enforced in the ELF one?

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]     ` <20150814115205.GA8034@olila.local.net-space.pl>
  2015-08-14 12:49       ` Jan Beulich
       [not found]       ` <55CDFFEE020000780009B0B0@prv-mh.provo.novell.com>
@ 2015-08-14 15:20       ` Konrad Rzeszutek Wilk
  2 siblings, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-14 15:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, grub-devel, keir, ian.campbell, stefano.stabellini,
	andrew.cooper3, gang.wei, roy.franz, ning.sun, david.vrabel,
	jbeulich, phcoder, xen-devel, wei.liu2, richard.l.maliszewski,
	qiaowei.ren, fu.wei

> > >  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?
> 
> This is very good question. I was asking myself about that thing at
> least once. Sadly, I cannot find real explanation.
> 
> > Let me double-check what SYSLINUX's mboot.c32 does. Perhaps
> > it had done something odd in the past.
> 
> 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  

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 possible. */
> > > +        mov     $BOOT_FS,%edx
> > > +        mov     %edx,%fs
> > > +
> >
> > We just modified the GDT. Should we reload it (lgdt?)?
> 
> I do not think it is needed.
> 
> Intel 64 and IA-32 Architectures Software Developer’s Manual,
> Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z says:
> 
> LGDT ... Loads the values in the source operand into the global
> descriptor table register (GDTR)...
> 
> ...and ...
> 
> 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 access
> control information from the segment descriptor pointed to by the segment
> 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 note:
> 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.
> 
> AIUI, only GDT address and limit are loaded into GDTR when lgdt is executed.
> 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!

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

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
       [not found]       ` <55CDD8F4020000780009AF3C@prv-mh.provo.novell.com>
@ 2015-08-15  6:00         ` Andrew Cooper
  0 siblings, 0 replies; 116+ messages in thread
From: Andrew Cooper @ 2015-08-15  6:00 UTC (permalink / raw)
  To: Jan Beulich, Daniel Kiper, Konrad Rzeszutek Wilk
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, roy.franz, ning.sun, david.vrabel,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	fu.wei



On 14/08/15 11:03, Jan Beulich wrote:
>>>> On 13.08.15 at 21:22, <daniel.kiper@oracle.com> wrote:
>> On Mon, Aug 10, 2015 at 03:17:48PM -0400, Konrad Rzeszutek Wilk wrote:
>>> On Mon, Jul 20, 2015 at 04:29:03PM +0200, Daniel Kiper wrote:
>>>> @@ -34,6 +57,42 @@ multiboot1_header_start:       /*** MULTIBOOT1 HEADER ****/
>>>>           .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
>>>>   multiboot1_header_end:
>>>>
>>>> +/*** MULTIBOOT2 HEADER ****/
>>>> +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
>>>> +        .align  MULTIBOOT2_HEADER_ALIGN
>>>> +
>>>> +.Lmultiboot2_header:
>>> How come you use .L? It makes this hidden while the multiboot1 headers
>>> are visible? Makes it a bit harder to see the contents of this under
>>> an debugger.
>> Good point. IIRC, Jan asked about that. I will remove .L if he does not
>> object.
> For this particular one I think it's okay to drop the .L, but generally
> I'd like to see .L used more widely for any auxiliary labels (i.e. only
> "main" labels - function entry points and data objects - should have
> their labels present in the final symbol table).

In general I would agree.

However, the multiboot 1 and 2 headers are special.  They are binary 
data included in the .text section, so having non-local lables makes the 
disassembly easier to read.

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention
       [not found] ` <1437402558-7313-5-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 16:33   ` [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention Konrad Rzeszutek Wilk
@ 2015-08-17 15:44   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-17 15:44 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:28, <daniel.kiper@oracle.com> wrote:

An empty description leaves us guess at the "why".

> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -10,15 +10,27 @@
>   *    Keir Fraser <keir@xen.org>
>   */
>  
> -/* entered with %eax = BOOT_TRAMPOLINE */
> +/*
> + * This entry point is entered from xen/arch/x86/boot/head.S with:
> + *   - 0x4(%esp) = BOOT_TRAMPOLINE_ADDRESS,
> + *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS.
> + */
>  asm (
>      "    .text                         \n"
>      "    .globl _start                 \n"
>      "_start:                           \n"
> +    "    push %ebp                     \n"
> +    "    mov  %esp,%ebp                \n"

What do you need this for?

>      "    call 1f                       \n"
> -    "1:  pop  %ebx                     \n"
> -    "    mov  %eax,alloc-1b(%ebx)      \n"
> -    "    jmp  reloc                    \n"
> +    "1:  pop  %ecx                     \n"
> +    "    mov  0x8(%ebp),%eax           \n"
> +    "    mov  %eax,alloc-1b(%ecx)      \n"
> +    "    mov  0xc(%ebp),%eax           \n"
> +    "    push %eax                     \n"

    push 12(%ebp)

> +    "    call reloc                    \n"
> +    "    add  $4,%esp                  \n"

If you already copy %esp to %ebp at the top,

    mov %ebp, %esp

would be the better alternative.

> +    "    pop  %ebp                     \n"

Or even just

    leave

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions
       [not found] ` <1437402558-7313-6-git-send-email-daniel.kiper@oracle.com>
@ 2015-08-17 15:51   ` Jan Beulich
       [not found]   ` <55D21F3E020000780009B716@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-17 15:51 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> Create generic alloc and copy functions. We need
> separate tools for memory allocation and copy to
> provide multiboot2 protocol support.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> v2 - suggestions/fixes:
>    - generalize new functions names
>      (suggested by Jan Beulich),
>    - reduce number of casts
>      (suggested by Jan Beulich).

This contradicts retaining Andrew's R-b tag. Please remember to
drop tags for everything you make non-trivial changes to.

> @@ -55,50 +56,64 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
>      "    sub  %1,%0                   \n"
>      "    and  $~15,%0                 \n"
>      "    mov  %0,alloc-1b(%%edx)      \n"
> -    "    mov  %0,%%edi                \n"
> -    "    rep  movsb                   \n"
> -       : "=&r" (new), "+c" (bytes), "+S" (old)
> -	: : "edx", "edi", "memory");
> -    return new;
> +       : "=&r" (s) : "r" (bytes) : "edx", "memory");

Can't "bytes" use a simple "g" constraint now?

Preferably (i.e. if correct) this changed
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit
       [not found] ` <1437402558-7313-8-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 16:40   ` [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit Konrad Rzeszutek Wilk
@ 2015-08-17 15:55   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-17 15:55 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> Rename mbi and mbi_old variables and rearrange code a bit to make
> it more readable. Additionally, this way multiboot (v1) protocol
> implementation and future multiboot2 protocol implementation will
> use the same variable naming convention.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Acked-by: Jan Beulich <jbeulich@suse.com>

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions
       [not found]   ` <55D21F3E020000780009B716@prv-mh.provo.novell.com>
@ 2015-08-17 22:03     ` Daniel Kiper
  0 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-17 22:03 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, Aug 17, 2015 at 09:51:58AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> > Create generic alloc and copy functions. We need
> > separate tools for memory allocation and copy to
> > provide multiboot2 protocol support.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
> > ---
> > v2 - suggestions/fixes:
> >    - generalize new functions names
> >      (suggested by Jan Beulich),
> >    - reduce number of casts
> >      (suggested by Jan Beulich).
>
> This contradicts retaining Andrew's R-b tag. Please remember to
> drop tags for everything you make non-trivial changes to.

OK.

> > @@ -55,50 +56,64 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
> >      "    sub  %1,%0                   \n"
> >      "    and  $~15,%0                 \n"
> >      "    mov  %0,alloc-1b(%%edx)      \n"
> > -    "    mov  %0,%%edi                \n"
> > -    "    rep  movsb                   \n"
> > -       : "=&r" (new), "+c" (bytes), "+S" (old)
> > -	: : "edx", "edi", "memory");
> > -    return new;
> > +       : "=&r" (s) : "r" (bytes) : "edx", "memory");
>
> Can't "bytes" use a simple "g" constraint now?

Works...

> Preferably (i.e. if correct) this changed

..., so, I will change that.

> Acked-by: Jan Beulich <jbeulich@suse.com>

Thanks!

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
  2015-07-20 14:29 ` [PATCH v2 08/23] x86: add multiboot2 protocol support Daniel Kiper
  2015-08-10 19:17   ` Konrad Rzeszutek Wilk
       [not found]   ` <20150810191747.GE13576@l.oracle.com>
@ 2015-08-18  8:12   ` Jan Beulich
  2015-08-18 12:00     ` Daniel Kiper
  2 siblings, 1 reply; 116+ messages in thread
From: Jan Beulich @ 2015-08-18  8:12 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> v2 - not fixed yet:
>    - dynamic dependency generation for xen/arch/x86/boot/reloc.S;
>      this requires more work; I am not sure that it pays because
>      potential patch requires more changes than addition of just
>      multiboot2.h to Makefile
>      (suggested by Jan Beulich),

With the compiler.h inclusion done I don't think this is as necessary
anymore as it was previously.

>    - isolated/stray __packed attribute usage for multiboot2_memory_map_t
>      (suggested by Jan Beulich).

This one I don't, however, see why you didn't address. And with
un-addressed issues I think you should have tagged this RFC).

> @@ -19,6 +20,28 @@
>  #define BOOT_PSEUDORM_CS 0x0020
>  #define BOOT_PSEUDORM_DS 0x0028
>  
> +#define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
> +#define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
> +
> +        .macro mb2ht_args arg, args:vararg

Please make sure the oldest binutils we support allow for this
(introduced in 2.17; the oldest supported SLE seems to have it,
but I'm not sure about RHEL).

> +        .long \arg
> +        .ifnb \args
> +        mb2ht_args \args
> +        .endif
> +        .endm
> +
> +        .macro mb2ht_init type, req, args:vararg
> +        .align MULTIBOOT2_TAG_ALIGN
> +        0:

Labels belong in the first column. Also I generally recommend against
using numeric labels in macros (due to the risk of conflict with label
uses around the macro use sites) - use \@ instead to make labels
unique (again provided the oldest supported binutils handle this).

> @@ -119,10 +213,11 @@ __start:
>  
>          /* Save the Multiboot info struct (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
> +        push    %eax                /* Multiboot magic. */
>          push    %ebx                /* Multiboot information address. */
>          push    %ecx                /* Boot trampoline address. */
>          call    reloc
> -        add     $8,%esp             /* Remove reloc() args from stack. */
> +        add     $12,%esp            /* Remove reloc() args from stack. */

The latest now it becomes clear that the arguments passed are
kind of backwards: One would expect the qualifying value (i.e.
the magic) to come first, then the info pointer, and last the
trampoline address.

> @@ -86,12 +104,12 @@ static u32 copy_string(u32 src)
>      return copy_mem(src, p - src + 1);
>  }
>  
> -multiboot_info_t *reloc(u32 mbi_in)
> +static multiboot_info_t *mbi_mbi(void *mbi_in)

I don't see why this needs to become a pointer all of the sudden, ...

>  {
>      int i;
>      multiboot_info_t *mbi_out;
>  
> -    mbi_out = (multiboot_info_t *)copy_mem(mbi_in, sizeof(*mbi_out));
> +    mbi_out = (multiboot_info_t *)copy_mem((u32)mbi_in, sizeof(*mbi_out));

... adding back a cast that we'd better avoid here.

> @@ -127,3 +145,123 @@ multiboot_info_t *reloc(u32 mbi_in)
>  
>      return mbi_out;
>  }
> +
> +static multiboot_info_t *mbi2_mbi(void *mbi_in)

Why not "const multiboot2_fixed_t *"?

> +{
> +    /* Do not complain that mbi_out_mods is not initialized. */
> +    module_t *mbi_out_mods = (module_t *)0;
> +    memory_map_t *mmap_dst;
> +    multiboot2_memory_map_t *mmap_src;

const

> +    multiboot2_tag_t *tag;

const?

> +    multiboot_info_t *mbi_out;
> +    u32 ptr;
> +    unsigned int i, mod_idx = 0;
> +
> +    mbi_out = (multiboot_info_t *)alloc_mem(sizeof(*mbi_out));
> +    zero_mem((u32)mbi_out, sizeof(*mbi_out));

Please avoid one of the two casts (e.g. by using "ptr" as intermediate
storage for the alloc_mem() result.

> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi_in + sizeof(multiboot2_fixed_t);
> +
> +    for ( ; ; )
> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> +            ++mbi_out->mods_count;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> +        {
> +            mbi_out->flags = MBI_MODULES;
> +            mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(module_t));
> +            mbi_out_mods = (module_t *)mbi_out->mods_addr;

Even if we don't expect Xen to be booted without any modules,
wouldn't you better do this only when mbi_out->mods_count > 0?

> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));

Please drop the stray pair of parentheses around the invocation of
ALIGN_UP(). Also - long line.

> +        /* Check Multiboot2 information total size just in case. */
> +	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )

Hard tab.

> +            break;
> +    }
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi_in + sizeof(multiboot2_fixed_t);
> +
> +    for ( ; ; )
> +    {
> +        switch ( tag->type )
> +        {
> +        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
> +            mbi_out->flags |= MBI_LOADERNAME;
> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);

Please consider adding a get_mb2_string() wrapping get_mb2_data()
but eliminating the recurring casts from all use sites.

> +            mbi_out->boot_loader_name = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_CMDLINE:
> +            mbi_out->flags |= MBI_CMDLINE;
> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_string_t, string);
> +            mbi_out->cmdline = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
> +            mbi_out->flags |= MBI_MEMLIMITS;
> +            mbi_out->mem_lower = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_lower);
> +            mbi_out->mem_upper = get_mb2_data(tag, multiboot2_tag_basic_meminfo_t, mem_upper);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MMAP:
> +            mbi_out->flags |= MBI_MEMMAP;
> +            mbi_out->mmap_length = get_mb2_data(tag, multiboot2_tag_mmap_t, size);
> +            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
> +            mbi_out->mmap_length += sizeof(((multiboot2_tag_mmap_t){0}).entries);

Afaict this sizeof() evaluates to zero. And even if it didn't I can't see
what the line is good for.

> +            mbi_out->mmap_length /= get_mb2_data(tag, multiboot2_tag_mmap_t, entry_size);
> +            mbi_out->mmap_length *= sizeof(memory_map_t);
> +
> +            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);
> +
> +            mmap_src = get_mb2_data(tag, multiboot2_tag_mmap_t, entries);
> +            mmap_dst = (memory_map_t *)mbi_out->mmap_addr;
> +
> +            for ( i = 0; i < mbi_out->mmap_length / sizeof(memory_map_t); ++i )
> +            {
> +                mmap_dst[i].size = sizeof(memory_map_t);
> +                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
> +                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
> +                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
> +                mmap_dst[i].length_low = (u32)mmap_src[i].len;
> +                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
> +                mmap_dst[i].type = mmap_src[i].type;
> +            }

So in the calculations ahead of the loop you're careful to honor
entry_size. Why do you ignore it in the loop (assuming entry_size ==
sizeof(multiboot2_memory_map_t))?

> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MODULE:
> +            mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, multiboot2_tag_module_t, mod_start);
> +            mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, multiboot2_tag_module_t, mod_end);

Long lines. Also by now the redundancy of the multiboot2_tag_ prefix
and the _t suffix in each of the invocations tells us that it would be
quite nice if attaching them to the actually relevant part of the name
would better be done inside the macro.

> +            ptr = (u32)get_mb2_data(tag, multiboot2_tag_module_t, cmdline);
> +            mbi_out_mods[mod_idx].string = copy_string(ptr);
> +            mbi_out_mods[mod_idx].reserved = 0;
> +            ++mod_idx;
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_END:
> +            return mbi_out;
> +
> +        default:
> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +
> +        /* Check Multiboot2 information total size just in case. */
> +	if ( (void *)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )

Hard tab again.

> +static multiboot_info_t __attribute__((__used__)) *reloc(void *mbi_in, u32 mb_magic)

Dropping the "static" would permit to also drop the "used" attribute.
Since it was that way before, why didn't you keep it that way?

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
  2015-08-18  8:12   ` Jan Beulich
@ 2015-08-18 12:00     ` Daniel Kiper
  2015-08-18 14:20       ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-08-18 12:00 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, Aug 18, 2015 at 02:12:58AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:

[...]

> > @@ -119,10 +213,11 @@ __start:
> >
> >          /* Save the Multiboot info struct (after relocation) for later use. */
> >          mov     $sym_phys(cpu0_stack)+1024,%esp
> > +        push    %eax                /* Multiboot magic. */
> >          push    %ebx                /* Multiboot information address. */
> >          push    %ecx                /* Boot trampoline address. */
> >          call    reloc
> > -        add     $8,%esp             /* Remove reloc() args from stack. */
> > +        add     $12,%esp            /* Remove reloc() args from stack. */
>
> The latest now it becomes clear that the arguments passed are
> kind of backwards: One would expect the qualifying value (i.e.
> the magic) to come first, then the info pointer, and last the
> trampoline address.

Yep, you are right. However, I wanted to avoid changing order of arguments
to not confuse reader. If you wish I can change that thing.

[...]

> > +        case MULTIBOOT2_TAG_TYPE_MMAP:
> > +            mbi_out->flags |= MBI_MEMMAP;
> > +            mbi_out->mmap_length = get_mb2_data(tag, multiboot2_tag_mmap_t, size);
> > +            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
> > +            mbi_out->mmap_length += sizeof(((multiboot2_tag_mmap_t){0}).entries);
>
> Afaict this sizeof() evaluates to zero. And even if it didn't I can't see
> what the line is good for.

Right, I have missed that. However, if it does not evaluate to zero then
you must add back relevant number of entries which you subtracted one
line above. Otherwise count of entries will be incorrect.

[...]

> Dropping the "static" would permit to also drop the "used" attribute.
> Since it was that way before, why didn't you keep it that way?

Yep, but I do not like this solution. Lack of static suggests that this function
is used elsewhere. I prefer to explicitly say that there are not external users
of that function and silence compiler warnings with __used.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 08/23] x86: add multiboot2 protocol support
  2015-08-18 12:00     ` Daniel Kiper
@ 2015-08-18 14:20       ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-18 14:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 18.08.15 at 14:00, <daniel.kiper@oracle.com> wrote:
> On Tue, Aug 18, 2015 at 02:12:58AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> > @@ -119,10 +213,11 @@ __start:
>> >
>> >          /* Save the Multiboot info struct (after relocation) for later use. */
>> >          mov     $sym_phys(cpu0_stack)+1024,%esp
>> > +        push    %eax                /* Multiboot magic. */
>> >          push    %ebx                /* Multiboot information address. */
>> >          push    %ecx                /* Boot trampoline address. */
>> >          call    reloc
>> > -        add     $8,%esp             /* Remove reloc() args from stack. */
>> > +        add     $12,%esp            /* Remove reloc() args from stack. */
>>
>> The latest now it becomes clear that the arguments passed are
>> kind of backwards: One would expect the qualifying value (i.e.
>> the magic) to come first, then the info pointer, and last the
>> trampoline address.
> 
> Yep, you are right. However, I wanted to avoid changing order of arguments
> to not confuse reader. If you wish I can change that thing.

Yes please: Between confusing the reader of the patch and the reader
of the resulting code, the former is the less problematic one. Furthermore
with the function having just one argument before your series you have
all options to avoid confusing the reader of the patches - just insert the
new arguments at the right slot in each patch adding one.

>> > +        case MULTIBOOT2_TAG_TYPE_MMAP:
>> > +            mbi_out->flags |= MBI_MEMMAP;
>> > +            mbi_out->mmap_length = get_mb2_data(tag, multiboot2_tag_mmap_t, size);
>> > +            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
>> > +            mbi_out->mmap_length += sizeof(((multiboot2_tag_mmap_t){0}).entries);
>>
>> Afaict this sizeof() evaluates to zero. And even if it didn't I can't see
>> what the line is good for.
> 
> Right, I have missed that. However, if it does not evaluate to zero then
> you must add back relevant number of entries which you subtracted one
> line above. Otherwise count of entries will be incorrect.

There's no count being subtracted afaict - what is being subtracted
is the size of the rest of the structure.

>> Dropping the "static" would permit to also drop the "used" attribute.
>> Since it was that way before, why didn't you keep it that way?
> 
> Yep, but I do not like this solution. Lack of static suggests that this 
> function
> is used elsewhere. I prefer to explicitly say that there are not external 
> users
> of that function and silence compiler warnings with __used.

If you want to do this, then not in the middle of some already big
patch doing something completely different, but in a separate
cleanup patch explaining what you explained above (which is not
to say that I'm convinced, and hence I can't promise such a change
to ultimately go in).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 09/23] efi: create efi_enabled()
  2015-07-20 14:29 ` [PATCH v2 09/23] efi: create efi_enabled() Daniel Kiper
  2015-08-10 19:20   ` Konrad Rzeszutek Wilk
@ 2015-08-20 15:18   ` Jan Beulich
  2015-08-22 12:33     ` Daniel Kiper
       [not found]     ` <20150822123359.GX7143@olila.local.net-space.pl>
  1 sibling, 2 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-20 15:18 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -4,9 +4,14 @@
>  #include <xen/lib.h>
>  #include <asm/page.h>
>  
> -#ifndef efi_enabled
> -const bool_t efi_enabled = 0;
> -#endif
> +struct efi __read_mostly efi = {
> +	.flags   = 0, /* Initialized later. */
> +	.acpi    = EFI_INVALID_TABLE_ADDR,
> +	.acpi20  = EFI_INVALID_TABLE_ADDR,
> +	.mps     = EFI_INVALID_TABLE_ADDR,
> +	.smbios  = EFI_INVALID_TABLE_ADDR,
> +	.smbios3 = EFI_INVALID_TABLE_ADDR
> +};

How is this change related to the subject of the patch?

> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -191,8 +191,6 @@ SECTIONS
>    .pad : {
>      . = ALIGN(MB(16));
>    } :text
> -#else
> -  efi = .;
>  #endif

Same here.

> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -717,6 +717,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
> *SystemTable)
>      char *option_str;
>      bool_t use_cfg_file;
>  
> +#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
> +    set_bit(EFI_PLATFORM, &efi.flags);
> +#endif

Just for this to work? I don't see the need for all the pointers in
the stub case - why can't this be a separate variable? We don't
need to follow Linux with where the flags actually live...

> --- a/xen/common/efi/runtime.c
> +++ b/xen/common/efi/runtime.c
> @@ -10,14 +10,10 @@ DEFINE_XEN_GUEST_HANDLE(CHAR16);
>  
>  #ifndef COMPAT
>  
> -#ifdef CONFIG_ARM  /* Disabled until runtime services implemented */
> -const bool_t efi_enabled = 0;
> -#else
> +#ifndef CONFIG_ARM
>  # include <asm/i387.h>
>  # include <asm/xstate.h>
>  # include <public/platform.h>
> -
> -const bool_t efi_enabled = 1;
>  #endif

Afaict the proper replacement (at least at this point in the series) for
this would be to statically initialize the flag set in this xen.efi case.

> @@ -40,6 +42,16 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *);
>  int efi_compat_get_info(uint32_t idx, union compat_pf_efi_info *);
>  int efi_compat_runtime_call(struct compat_pf_efi_runtime_call *);
>  
> +/*
> + * Test whether the above EFI_* bits are enabled.
> + *
> + * Stolen from Linux Kernel.

I don't think this second part of the comment makes a lot of sense
for a minor piece of functionality like this.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found] ` <1437402558-7313-11-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 19:24   ` [PATCH v2 10/23] efi: build xen.gz with EFI code Konrad Rzeszutek Wilk
@ 2015-08-20 15:39   ` Jan Beulich
  2015-08-22 13:59     ` Daniel Kiper
       [not found]     ` <20150822135919.GY7143@olila.local.net-space.pl>
  1 sibling, 2 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-20 15:39 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> Build xen.gz with EFI code. We need this to support multiboot2
> protocol on EFI platforms.
> 
> If we wish to load not ELF file using multiboot (v1) or multiboot2 then

DYM "a non-ELF file"?

> it must contain "linear" (or "flat") representation of code and data.

Why? Please don't just put out statements, but also reasons (i.e.
at least which component is unable to deal with the current [valid
afaict] PE image we have).

> Currently, PE file contains many sections which are not "linear" (one
> after another without any holes) or even do not have representation
> in a file (e.g. BSS). In theory there is a chance that we could build
> proper PE file using current build system. However, it means that

What is "improper" about the currently built PE file? And if there is
anything improper, did you inform the binutils maintainers of the
problem?

> --- a/xen/arch/x86/efi/Makefile
> +++ b/xen/arch/x86/efi/Makefile
> @@ -1,14 +1,16 @@
>  CFLAGS += -fshort-wchar
>  
> -obj-y += stub.o
> -
> -create = test -e $(1) || touch -t 199901010000 $(1)
> -
>  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
>  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
>  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
> -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
> +efi := $(if $(efi),$(shell rm disabled)y)
>  
> -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
> +extra-y += relocs-dummy.o

Why is this no longer extra-$(efi)?

> -stub.o: $(extra-y)

With this dependency removed (instead of perhaps replaced or
extended) - what will trigger relocs-dummy.o to be (re)built?

> +ifeq ($(efi),y)
> +obj-y += boot.init.o
> +obj-y += compat.o
> +obj-y += runtime.o
> +else
> +obj-y += stub.o
> +endif

obj-y := stub.o
obj-$(efi) := boot.init.o compat.o runtime.o

> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -344,7 +344,8 @@ void __init arch_init_memory(void)
>  
>      subarch_init_memory();
>  
> -    efi_init_memory();
> +    if ( efi_enabled(EFI_PLATFORM) )
> +        efi_init_memory();

I think I'd prefer such checks to be constrained to EFI code where
possible, i.e. in this case do the check inside efi_init_memory().

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 14/23] efi: split out efi_find_gop_mode()
  2015-07-20 14:29 ` [PATCH v2 14/23] efi: split out efi_find_gop_mode() Daniel Kiper
  2015-08-10 19:31   ` Konrad Rzeszutek Wilk
@ 2015-08-20 15:48   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-20 15:48 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -665,6 +665,58 @@ static EFI_GRAPHICS_OUTPUT_PROTOCOL __init *efi_get_gop(void)
>      return gop;
>  }
>  
> +static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
> +                                      UINTN cols, UINTN rows, UINTN depth)
> +{
> +    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
> +    EFI_STATUS status;
> +    UINTN gop_mode = ~0, info_size, size;
> +    unsigned int i;
> +
> +    if ( !gop )
> +        return gop_mode;

Please drop this in favor of ...

> @@ -978,46 +1030,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  
>          dir_handle->Close(dir_handle);
>  
> -        if ( gop && !base_video )

... keeping the original check here.

Similarly in patch 17.

With these minor adjustments, all the "efi: split out efi_..." patches
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 09/23] efi: create efi_enabled()
  2015-08-20 15:18   ` Jan Beulich
@ 2015-08-22 12:33     ` Daniel Kiper
       [not found]     ` <20150822123359.GX7143@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-22 12:33 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Aug 20, 2015 at 09:18:17AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> > --- a/xen/arch/x86/efi/stub.c
> > +++ b/xen/arch/x86/efi/stub.c
> > @@ -4,9 +4,14 @@
> >  #include <xen/lib.h>
> >  #include <asm/page.h>
> >
> > -#ifndef efi_enabled
> > -const bool_t efi_enabled = 0;
> > -#endif
> > +struct efi __read_mostly efi = {
> > +	.flags   = 0, /* Initialized later. */
> > +	.acpi    = EFI_INVALID_TABLE_ADDR,
> > +	.acpi20  = EFI_INVALID_TABLE_ADDR,
> > +	.mps     = EFI_INVALID_TABLE_ADDR,
> > +	.smbios  = EFI_INVALID_TABLE_ADDR,
> > +	.smbios3 = EFI_INVALID_TABLE_ADDR
> > +};
>
> How is this change related to the subject of the patch?

I need to add this struct because...

> > --- a/xen/arch/x86/xen.lds.S
> > +++ b/xen/arch/x86/xen.lds.S
> > @@ -191,8 +191,6 @@ SECTIONS
> >    .pad : {
> >      . = ALIGN(MB(16));
> >    } :text
> > -#else
> > -  efi = .;
> >  #endif
>
> Same here.

...this creates efi symbol to just satisfy linker and I am removing it.
However, existing solution does not allocate space for this symbol and
any references to acpi20, etc. does not make sense. As I saw any efi.*
references are protected by relevant ifs but we should not do that because
it makes code very fragile. If somebody does not know how efi symbol is
created he/she may assume that it always represent valid structure and
do invalid references somewhere. So, I still think that stub.c should
define efi struct properly even if we assume that flags should not be
there. However, I agree that this could be separate patch.

By the way why did you choose so strange way to satisfy liker needs?

> > --- a/xen/common/efi/boot.c
> > +++ b/xen/common/efi/boot.c
> > @@ -717,6 +717,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE
> > *SystemTable)
> >      char *option_str;
> >      bool_t use_cfg_file;
> >
> > +#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
> > +    set_bit(EFI_PLATFORM, &efi.flags);
> > +#endif
>
> Just for this to work? I don't see the need for all the pointers in
> the stub case - why can't this be a separate variable? We don't

Could be but if we create struct with so generic name like just simple
efi it suggest that this is good place to put flags there. If it is not
how to call it? efi_flags? Or maybe we should rename efi to efi_tables
too. Then everything will be clear.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
  2015-08-20 15:39   ` Jan Beulich
@ 2015-08-22 13:59     ` Daniel Kiper
       [not found]     ` <20150822135919.GY7143@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-22 13:59 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> > Build xen.gz with EFI code. We need this to support multiboot2
> > protocol on EFI platforms.
> >
> > If we wish to load not ELF file using multiboot (v1) or multiboot2 then
>
> DYM "a non-ELF file"?
>
> > it must contain "linear" (or "flat") representation of code and data.
>
> Why? Please don't just put out statements, but also reasons (i.e.
> at least which component is unable to deal with the current [valid
> afaict] PE image we have).

This is a requirement of multiboot (v1) or multiboot2 protocol. They both
know nothing about PE image format.

> > Currently, PE file contains many sections which are not "linear" (one
> > after another without any holes) or even do not have representation
> > in a file (e.g. BSS). In theory there is a chance that we could build
> > proper PE file using current build system. However, it means that
>
> What is "improper" about the currently built PE file? And if there is
> anything improper, did you inform the binutils maintainers of the
> problem?

>From PE loader point of view everything is OK. However, current Xen PE
image (at least build on my machines) is not usable by multiboot (v1)
or multiboot2 protocol compatible loader because it is not linear (one
section does not live immediately after another without any voids).
Potentially we can change that (probably by playing with linker script
or using objcopy or just simply building proper PE file ourselves; I did
some experiments once but they are not exhaustive and I am not able to
tell which solution will be the best in our case), however, this is next
step and it will be investigated after applying this patch series to
Xen source.

> > --- a/xen/arch/x86/efi/Makefile
> > +++ b/xen/arch/x86/efi/Makefile
> > @@ -1,14 +1,16 @@
> >  CFLAGS += -fshort-wchar
> >
> > -obj-y += stub.o
> > -
> > -create = test -e $(1) || touch -t 199901010000 $(1)
> > -
> >  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
> >  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
> >  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o 2>disabled && echo y))
> > -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
> > +efi := $(if $(efi),$(shell rm disabled)y)
> >
> > -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
> > +extra-y += relocs-dummy.o
>
> Why is this no longer extra-$(efi)?

Because we need proper EFI code in xen.gz to support boot
via multiboot2 on EFI platforms.

> > -stub.o: $(extra-y)
>
> With this dependency removed (instead of perhaps replaced or
> extended) - what will trigger relocs-dummy.o to be (re)built?

It is triggered by prelink.o build rule in xen/arch/x86/Makefile.
Looks that it will suffice but I am not sure right now this is
good solution. Hmmm... If it is OK then we can remove
"extra-y += relocs-dummy.o".

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 09/23] efi: create efi_enabled()
       [not found]     ` <20150822123359.GX7143@olila.local.net-space.pl>
@ 2015-08-24 11:29       ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-24 11:29 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 22.08.15 at 14:33, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 20, 2015 at 09:18:17AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> > --- a/xen/arch/x86/efi/stub.c
>> > +++ b/xen/arch/x86/efi/stub.c
>> > @@ -4,9 +4,14 @@
>> >  #include <xen/lib.h>
>> >  #include <asm/page.h>
>> >
>> > -#ifndef efi_enabled
>> > -const bool_t efi_enabled = 0;
>> > -#endif
>> > +struct efi __read_mostly efi = {
>> > +	.flags   = 0, /* Initialized later. */
>> > +	.acpi    = EFI_INVALID_TABLE_ADDR,
>> > +	.acpi20  = EFI_INVALID_TABLE_ADDR,
>> > +	.mps     = EFI_INVALID_TABLE_ADDR,
>> > +	.smbios  = EFI_INVALID_TABLE_ADDR,
>> > +	.smbios3 = EFI_INVALID_TABLE_ADDR
>> > +};
>>
>> How is this change related to the subject of the patch?
> 
> I need to add this struct because...
> 
>> > --- a/xen/arch/x86/xen.lds.S
>> > +++ b/xen/arch/x86/xen.lds.S
>> > @@ -191,8 +191,6 @@ SECTIONS
>> >    .pad : {
>> >      . = ALIGN(MB(16));
>> >    } :text
>> > -#else
>> > -  efi = .;
>> >  #endif
>>
>> Same here.
> 
> ...this creates efi symbol to just satisfy linker and I am removing it.
> However, existing solution does not allocate space for this symbol and
> any references to acpi20, etc. does not make sense. As I saw any efi.*
> references are protected by relevant ifs but we should not do that because
> it makes code very fragile. If somebody does not know how efi symbol is
> created he/she may assume that it always represent valid structure and
> do invalid references somewhere. So, I still think that stub.c should
> define efi struct properly even if we assume that flags should not be
> there. However, I agree that this could be separate patch.
> 
> By the way why did you choose so strange way to satisfy liker needs?

To me there's nothing strange about it: I want a symbol that
occupies no space in memory.

>> > --- a/xen/common/efi/boot.c
>> > +++ b/xen/common/efi/boot.c
>> > @@ -717,6 +717,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE
>> > *SystemTable)
>> >      char *option_str;
>> >      bool_t use_cfg_file;
>> >
>> > +#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
>> > +    set_bit(EFI_PLATFORM, &efi.flags);
>> > +#endif
>>
>> Just for this to work? I don't see the need for all the pointers in
>> the stub case - why can't this be a separate variable? We don't
> 
> Could be but if we create struct with so generic name like just simple
> efi it suggest that this is good place to put flags there. If it is not
> how to call it? efi_flags? Or maybe we should rename efi to efi_tables
> too. Then everything will be clear.

I agree that this may be matter of taste, but to me the current
naming looks quite fine. And yes, efi_flags of efi_state would be
a fine name. In general I wouldn't even mind it to be a field in
the structure, if only that resulted in the _full_ structure to be
allocated even in the no-EFI build case. I admit though that with
the goal of always building EFI code (unless the tool chain
doesn't support doing so) this becomes less of an issue; otoh us
probably wanting some Kconfig-like mechanism sooner or later to
{en,dis}able certain features would call for this to remain separable.
And yes, at that point it could be done by #ifdef-ing out everything
by the flags member.

So based on the above I'm withdrawing my implied objection, but
please make sure you write better patch descriptions explaining
what is done and _why_.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]     ` <20150822135919.GY7143@olila.local.net-space.pl>
@ 2015-08-24 11:35       ` Jan Beulich
  2015-08-24 20:54         ` Daniel Kiper
       [not found]         ` <20150824205445.GG7143@olila.local.net-space.pl>
  0 siblings, 2 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-24 11:35 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 22.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> > Build xen.gz with EFI code. We need this to support multiboot2
>> > protocol on EFI platforms.
>> >
>> > If we wish to load not ELF file using multiboot (v1) or multiboot2 then
>>
>> DYM "a non-ELF file"?
>>
>> > it must contain "linear" (or "flat") representation of code and data.
>>
>> Why? Please don't just put out statements, but also reasons (i.e.
>> at least which component is unable to deal with the current [valid
>> afaict] PE image we have).
> 
> This is a requirement of multiboot (v1) or multiboot2 protocol. They both
> know nothing about PE image format.

And hence how specifically we arrange data inside the image should
be benign to them, as they won't be able to load the file _anyway_.

>> > Currently, PE file contains many sections which are not "linear" (one
>> > after another without any holes) or even do not have representation
>> > in a file (e.g. BSS). In theory there is a chance that we could build
>> > proper PE file using current build system. However, it means that
>>
>> What is "improper" about the currently built PE file? And if there is
>> anything improper, did you inform the binutils maintainers of the
>> problem?
> 
> From PE loader point of view everything is OK. However, current Xen PE
> image (at least build on my machines) is not usable by multiboot (v1)
> or multiboot2 protocol compatible loader because it is not linear (one
> section does not live immediately after another without any voids).

Again - either I'm missing something (and then your explanation is
not good enough) or this is (as said above) a pointless adjustment.

>> > --- a/xen/arch/x86/efi/Makefile
>> > +++ b/xen/arch/x86/efi/Makefile
>> > @@ -1,14 +1,16 @@
>> >  CFLAGS += -fshort-wchar
>> >
>> > -obj-y += stub.o
>> > -
>> > -create = test -e $(1) || touch -t 199901010000 $(1)
>> > -
>> >  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
>> >  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
>> >  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o >disabled && echo y))
>> > -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
>> > +efi := $(if $(efi),$(shell rm disabled)y)
>> >
>> > -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
>> > +extra-y += relocs-dummy.o
>>
>> Why is this no longer extra-$(efi)?
> 
> Because we need proper EFI code in xen.gz to support boot
> via multiboot2 on EFI platforms.

What would we need that for when not building an EFI-capable
binary anyway?

>> > -stub.o: $(extra-y)
>>
>> With this dependency removed (instead of perhaps replaced or
>> extended) - what will trigger relocs-dummy.o to be (re)built?
> 
> It is triggered by prelink.o build rule in xen/arch/x86/Makefile.

No. Or better - if it is, then this is wrong. With the way our build
logic works, unless there are exceptional circumstances things in
a certain directory should be built _only_ when recursion reaches
that particular directory (i.e. not from any of its parents).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
  2015-08-24 11:35       ` Jan Beulich
@ 2015-08-24 20:54         ` Daniel Kiper
       [not found]         ` <20150824205445.GG7143@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-24 20:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, Aug 24, 2015 at 05:35:21AM -0600, Jan Beulich wrote:
> >>> On 22.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
> > On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
> >> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> >> > Build xen.gz with EFI code. We need this to support multiboot2
> >> > protocol on EFI platforms.
> >> >
> >> > If we wish to load not ELF file using multiboot (v1) or multiboot2 then
> >>
> >> DYM "a non-ELF file"?
> >>
> >> > it must contain "linear" (or "flat") representation of code and data.
> >>
> >> Why? Please don't just put out statements, but also reasons (i.e.
> >> at least which component is unable to deal with the current [valid
> >> afaict] PE image we have).
> >
> > This is a requirement of multiboot (v1) or multiboot2 protocol. They both
> > know nothing about PE image format.
>
> And hence how specifically we arrange data inside the image should
> be benign to them, as they won't be able to load the file _anyway_.
>
> >> > Currently, PE file contains many sections which are not "linear" (one
> >> > after another without any holes) or even do not have representation
> >> > in a file (e.g. BSS). In theory there is a chance that we could build
> >> > proper PE file using current build system. However, it means that
> >>
> >> What is "improper" about the currently built PE file? And if there is
> >> anything improper, did you inform the binutils maintainers of the
> >> problem?
> >
> > From PE loader point of view everything is OK. However, current Xen PE
> > image (at least build on my machines) is not usable by multiboot (v1)
> > or multiboot2 protocol compatible loader because it is not linear (one
> > section does not live immediately after another without any voids).
>
> Again - either I'm missing something (and then your explanation is
> not good enough) or this is (as said above) a pointless adjustment.

Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
in discussed case). In general multiboot2 is able to load any file which has:
  1. proper multiboot2 header in first 32 KiB of a given file,
  2. "the text and data segments must be consecutive in the OS image"
     (The Multiboot Specification version 1.6).

This implies that we can e.g. build valid ELF file which is also multiboot2
protocol compatible image. And we does. However, we can go further.
Potentially we can build valid PE image which is also valid multiboot2
protocol image. Although current build method does not satisfy requirement
number 2 because, e.g.:

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         001513d0  ffff82d080200000  ffff82d080200000  00001000  2**12
                                      ^^^^^^                    ^^^^^^^^
                  CONTENTS, ALLOC, LOAD, CODE
  1 .rodata       0004de12  ffff82d0803513e0  ffff82d0803513e0  00153000  2**5
                                      ^^^^^^                    ^^^^^^^^
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

Hence, we must use special method to build PE image (I discussed that in
my earlier email in that topic) to do it compatible with multiboot2 protocol.
This way one file could be loaded by native PE loader, mulitboot (v1) protocol
(it requires relevant header but it does not interfere with PE and multiboot2
protocol stuff) and mutliboot2 protocol compatible loaders. Additionally,
if it is signed with Secure Boot signature then potentially signature could
be verified by UEFI itself and e.g. GRUB2. However, as I said earlier this
requires more work and this is next step which I am going to do after applying
this series. Currently I am going to embed EFI support into ELF file because
it is easy (less changes; currently used ELF file has required properties
because multiboot (v1) which we use has similar requirements like multiboot2
protocol) to make it compatible with multiboot2 protocol.

I hope that helps.

> >> > --- a/xen/arch/x86/efi/Makefile
> >> > +++ b/xen/arch/x86/efi/Makefile
> >> > @@ -1,14 +1,16 @@
> >> >  CFLAGS += -fshort-wchar
> >> >
> >> > -obj-y += stub.o
> >> > -
> >> > -create = test -e $(1) || touch -t 199901010000 $(1)
> >> > -
> >> >  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
> >> >  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
> >> >  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi check.o >disabled && echo y))
> >> > -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
> >> > +efi := $(if $(efi),$(shell rm disabled)y)
> >> >
> >> > -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
> >> > +extra-y += relocs-dummy.o
> >>
> >> Why is this no longer extra-$(efi)?
> >
> > Because we need proper EFI code in xen.gz to support boot
> > via multiboot2 on EFI platforms.
>
> What would we need that for when not building an EFI-capable
> binary anyway?

xen/arch/x86/efi/stub.c

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]         ` <20150824205445.GG7143@olila.local.net-space.pl>
@ 2015-08-25 10:50           ` Andrew Cooper
  2015-08-25 12:09           ` Jan Beulich
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Andrew Cooper @ 2015-08-25 10:50 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, roy.franz, ning.sun, david.vrabel,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	fu.wei

On 24/08/15 21:54, Daniel Kiper wrote:
>
>>>>> Currently, PE file contains many sections which are not "linear" (one
>>>>> after another without any holes) or even do not have representation
>>>>> in a file (e.g. BSS). In theory there is a chance that we could build
>>>>> proper PE file using current build system. However, it means that
>>>> What is "improper" about the currently built PE file? And if there is
>>>> anything improper, did you inform the binutils maintainers of the
>>>> problem?
>>> From PE loader point of view everything is OK. However, current Xen PE
>>> image (at least build on my machines) is not usable by multiboot (v1)
>>> or multiboot2 protocol compatible loader because it is not linear (one
>>> section does not live immediately after another without any voids).
>> Again - either I'm missing something (and then your explanation is
>> not good enough) or this is (as said above) a pointless adjustment.
> Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
> in discussed case). In general multiboot2 is able to load any file which has:
>   1. proper multiboot2 header in first 32 KiB of a given file,
>   2. "the text and data segments must be consecutive in the OS image"
>      (The Multiboot Specification version 1.6).

What is the reasoning for the restriction in 2. ?

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]         ` <20150824205445.GG7143@olila.local.net-space.pl>
  2015-08-25 10:50           ` Andrew Cooper
@ 2015-08-25 12:09           ` Jan Beulich
       [not found]           ` <55DC485D.4030904@citrix.com>
       [not found]           ` <55DC7705020000780009CE76@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-25 12:09 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 24.08.15 at 22:54, <daniel.kiper@oracle.com> wrote:
> On Mon, Aug 24, 2015 at 05:35:21AM -0600, Jan Beulich wrote:
>> >>> On 22.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
>> > On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
>> >> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> >> > Currently, PE file contains many sections which are not "linear" (one
>> >> > after another without any holes) or even do not have representation
>> >> > in a file (e.g. BSS). In theory there is a chance that we could build
>> >> > proper PE file using current build system. However, it means that
>> >>
>> >> What is "improper" about the currently built PE file? And if there is
>> >> anything improper, did you inform the binutils maintainers of the
>> >> problem?
>> >
>> > From PE loader point of view everything is OK. However, current Xen PE
>> > image (at least build on my machines) is not usable by multiboot (v1)
>> > or multiboot2 protocol compatible loader because it is not linear (one
>> > section does not live immediately after another without any voids).
>>
>> Again - either I'm missing something (and then your explanation is
>> not good enough) or this is (as said above) a pointless adjustment.
> 
> Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
> in discussed case). In general multiboot2 is able to load any file which 
> has:
>   1. proper multiboot2 header in first 32 KiB of a given file,
>   2. "the text and data segments must be consecutive in the OS image"
>      (The Multiboot Specification version 1.6).
> 
> This implies that we can e.g. build valid ELF file which is also multiboot2
> protocol compatible image. And we does. However, we can go further.
> Potentially we can build valid PE image which is also valid multiboot2
> protocol image. Although current build method does not satisfy requirement
> number 2 because, e.g.:
> 
> Sections:
> Idx Name          Size      VMA               LMA               File off  
> Algn
>   0 .text         001513d0  ffff82d080200000  ffff82d080200000  00001000  
> 2**12
>                                       ^^^^^^                    ^^^^^^^^
>                   CONTENTS, ALLOC, LOAD, CODE
>   1 .rodata       0004de12  ffff82d0803513e0  ffff82d0803513e0  00153000  
> 2**5
>                                       ^^^^^^                    ^^^^^^^^
>                   CONTENTS, ALLOC, LOAD, READONLY, DATA
> 
> Hence, we must use special method to build PE image (I discussed that in
> my earlier email in that topic) to do it compatible with multiboot2 
> protocol.

And you realize that we use a "special method" for building the
current "flat" ELF image too?

> This way one file could be loaded by native PE loader, mulitboot (v1) 
> protocol
> (it requires relevant header but it does not interfere with PE and 
> multiboot2
> protocol stuff) and mutliboot2 protocol compatible loaders. Additionally,
> if it is signed with Secure Boot signature then potentially signature could
> be verified by UEFI itself and e.g. GRUB2. However, as I said earlier this
> requires more work and this is next step which I am going to do after 
> applying
> this series. Currently I am going to embed EFI support into ELF file because
> it is easy (less changes; currently used ELF file has required properties
> because multiboot (v1) which we use has similar requirements like multiboot2
> protocol) to make it compatible with multiboot2 protocol.

I think whether what you do now makes sense depends on the
ultimate goal: If we want a single binary usable for all three cases,
then while yes, having EFI code available in the ELF image makes
sense, using an ELF Image won't work. And we can't have an
image being both ELF and PE. Hence the goal ought to be to have
a single PE image, and with that the direction you move seems
wrong.

>> >> > --- a/xen/arch/x86/efi/Makefile
>> >> > +++ b/xen/arch/x86/efi/Makefile
>> >> > @@ -1,14 +1,16 @@
>> >> >  CFLAGS += -fshort-wchar
>> >> >
>> >> > -obj-y += stub.o
>> >> > -
>> >> > -create = test -e $(1) || touch -t 199901010000 $(1)
>> >> > -
>> >> >  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
>> >> >  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
>> >> >  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi heck.o >disabled && echo y))
>> >> > -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
>> >> > +efi := $(if $(efi),$(shell rm disabled)y)
>> >> >
>> >> > -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
>> >> > +extra-y += relocs-dummy.o
>> >>
>> >> Why is this no longer extra-$(efi)?
>> >
>> > Because we need proper EFI code in xen.gz to support boot
>> > via multiboot2 on EFI platforms.
>>
>> What would we need that for when not building an EFI-capable
>> binary anyway?
> 
> xen/arch/x86/efi/stub.c

This is still too unspecific: I can't see any reference from that file
to any of the symbols relocs-dummy.S provides.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]           ` <55DC485D.4030904@citrix.com>
@ 2015-08-25 15:39             ` Daniel Kiper
  0 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-25 15:39 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, roy.franz, ning.sun, david.vrabel,
	Jan Beulich, xen-devel, qiaowei.ren, keir, richard.l.maliszewski,
	gang.wei, fu.wei

On Tue, Aug 25, 2015 at 11:50:05AM +0100, Andrew Cooper wrote:
> On 24/08/15 21:54, Daniel Kiper wrote:
> >
> >>>>> Currently, PE file contains many sections which are not "linear" (one
> >>>>> after another without any holes) or even do not have representation
> >>>>> in a file (e.g. BSS). In theory there is a chance that we could build
> >>>>> proper PE file using current build system. However, it means that
> >>>> What is "improper" about the currently built PE file? And if there is
> >>>> anything improper, did you inform the binutils maintainers of the
> >>>> problem?
> >>> From PE loader point of view everything is OK. However, current Xen PE
> >>> image (at least build on my machines) is not usable by multiboot (v1)
> >>> or multiboot2 protocol compatible loader because it is not linear (one
> >>> section does not live immediately after another without any voids).
> >> Again - either I'm missing something (and then your explanation is
> >> not good enough) or this is (as said above) a pointless adjustment.
> > Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
> > in discussed case). In general multiboot2 is able to load any file which has:
> >   1. proper multiboot2 header in first 32 KiB of a given file,
> >   2. "the text and data segments must be consecutive in the OS image"
> >      (The Multiboot Specification version 1.6).
>
> What is the reasoning for the restriction in 2. ?

You are able to describe following segments using only multiboot2 features:
  1) text and data segment bundled into one thing; in general boot loader
     does not care a lot about its internal structure; it should be just
     string of bytes which is loaded as is into memory (without any
     conversion, mangling, etc.),
  2) BSS segment which follows one mentioned above; it does not have any
     representation in image; boot loader just reserve and zero memory
     of a given size.

So, as you can see Xen text and data segment must live in one place in file
to satisfy multiboot2 protocol requirements. However, it does not mean that
from Xen point of view image cannot have more then one section/segment with
required alignments, etc.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]           ` <55DC7705020000780009CE76@prv-mh.provo.novell.com>
@ 2015-08-25 16:31             ` Daniel Kiper
       [not found]             ` <20150825163141.GJ7143@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-25 16:31 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, Aug 25, 2015 at 06:09:09AM -0600, Jan Beulich wrote:
> >>> On 24.08.15 at 22:54, <daniel.kiper@oracle.com> wrote:
> > On Mon, Aug 24, 2015 at 05:35:21AM -0600, Jan Beulich wrote:
> >> >>> On 22.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
> >> > On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
> >> >> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> >> >> > Currently, PE file contains many sections which are not "linear" (one
> >> >> > after another without any holes) or even do not have representation
> >> >> > in a file (e.g. BSS). In theory there is a chance that we could build
> >> >> > proper PE file using current build system. However, it means that
> >> >>
> >> >> What is "improper" about the currently built PE file? And if there is
> >> >> anything improper, did you inform the binutils maintainers of the
> >> >> problem?
> >> >
> >> > From PE loader point of view everything is OK. However, current Xen PE
> >> > image (at least build on my machines) is not usable by multiboot (v1)
> >> > or multiboot2 protocol compatible loader because it is not linear (one
> >> > section does not live immediately after another without any voids).
> >>
> >> Again - either I'm missing something (and then your explanation is
> >> not good enough) or this is (as said above) a pointless adjustment.
> >
> > Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
> > in discussed case). In general multiboot2 is able to load any file which
> > has:
> >   1. proper multiboot2 header in first 32 KiB of a given file,
> >   2. "the text and data segments must be consecutive in the OS image"
> >      (The Multiboot Specification version 1.6).
> >
> > This implies that we can e.g. build valid ELF file which is also multiboot2
> > protocol compatible image. And we does. However, we can go further.
> > Potentially we can build valid PE image which is also valid multiboot2
> > protocol image. Although current build method does not satisfy requirement
> > number 2 because, e.g.:
> >
> > Sections:
> > Idx Name          Size      VMA               LMA               File off
> > Algn
> >   0 .text         001513d0  ffff82d080200000  ffff82d080200000  00001000
> > 2**12
> >                                       ^^^^^^                    ^^^^^^^^
> >                   CONTENTS, ALLOC, LOAD, CODE
> >   1 .rodata       0004de12  ffff82d0803513e0  ffff82d0803513e0  00153000
> > 2**5
> >                                       ^^^^^^                    ^^^^^^^^
> >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
> >
> > Hence, we must use special method to build PE image (I discussed that in
> > my earlier email in that topic) to do it compatible with multiboot2
> > protocol.
>
> And you realize that we use a "special method" for building the
> current "flat" ELF image too?

Yes, I know about that.

> > This way one file could be loaded by native PE loader, mulitboot (v1)
> > protocol
> > (it requires relevant header but it does not interfere with PE and
> > multiboot2
> > protocol stuff) and mutliboot2 protocol compatible loaders. Additionally,
> > if it is signed with Secure Boot signature then potentially signature could
> > be verified by UEFI itself and e.g. GRUB2. However, as I said earlier this
> > requires more work and this is next step which I am going to do after
> > applying
> > this series. Currently I am going to embed EFI support into ELF file because
> > it is easy (less changes; currently used ELF file has required properties
> > because multiboot (v1) which we use has similar requirements like multiboot2
> > protocol) to make it compatible with multiboot2 protocol.
>
> I think whether what you do now makes sense depends on the
> ultimate goal: If we want a single binary usable for all three cases,
> then while yes, having EFI code available in the ELF image makes
> sense, using an ELF Image won't work. And we can't have an
> image being both ELF and PE. Hence the goal ought to be to have
> a single PE image, and with that the direction you move seems
> wrong.

It depends how we want to generate proper PE file. There are two options.

We can put manually proper PE header into xen/arch/x86/boot/head.S (maybe
with some additional needed stuff). Then after build we will have ELF file
which is loadable by multiboot protocols and has extra PE header. Of course
it is unusable directly by EFI loader. However, using simple objcopy we can
extract all interesting stuff from ELF file. This way we get proper PE file
which is usable by three different boot protocols. Going that way we can
also remove strict dependency on exact version of binutils which must have
enabled i386pep support if we wish to build PE image.

Potentially we can choose second way and build proper PE image using ld and
objcopy/objdump tools with proper options. However, this require more work
(maybe we will be forced to build something similar to mkelf32) and we bind
Xen build machinery more tightly with exact version of binutils which is
not nice.

So, I decided to choose option #1. It looks simpler because we have a lot of
needed stuff in place (e.g. Xen ELF image is currently in format usable by
multiboot protocols). However, I think that in first step we should add EFI
code to xen.gz because we want to load Xen using GRUB2 on EFI platforms ASAP.
This patch allows us to do that. Later after getting this feature into upstream
we can focus on building proper PE image with multiboot protocols support
embedded in it.

> >> >> > --- a/xen/arch/x86/efi/Makefile
> >> >> > +++ b/xen/arch/x86/efi/Makefile
> >> >> > @@ -1,14 +1,16 @@
> >> >> >  CFLAGS += -fshort-wchar
> >> >> >
> >> >> > -obj-y += stub.o
> >> >> > -
> >> >> > -create = test -e $(1) || touch -t 199901010000 $(1)
> >> >> > -
> >> >> >  efi := $(filter y,$(x86_64)$(shell rm -f disabled))
> >> >> >  efi := $(if $(efi),$(shell $(CC) $(filter-out $(CFLAGS-y) .%.d,$(CFLAGS)) -c check.c 2>disabled && echo y))
> >> >> >  efi := $(if $(efi),$(shell $(LD) -mi386pep --subsystem=10 -o check.efi heck.o >disabled && echo y))
> >> >> > -efi := $(if $(efi),$(shell rm disabled)y,$(shell $(call create,boot.init.o); $(call create,runtime.o)))
> >> >> > +efi := $(if $(efi),$(shell rm disabled)y)
> >> >> >
> >> >> > -extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o
> >> >> > +extra-y += relocs-dummy.o
> >> >>
> >> >> Why is this no longer extra-$(efi)?
> >> >
> >> > Because we need proper EFI code in xen.gz to support boot
> >> > via multiboot2 on EFI platforms.
> >>
> >> What would we need that for when not building an EFI-capable
> >> binary anyway?
> >
> > xen/arch/x86/efi/stub.c
>
> This is still too unspecific: I can't see any reference from that file
> to any of the symbols relocs-dummy.S provides.

Ahh... You are right, we do not need relocs-dummy.S to build
Xen image without EFI support. I will fix it.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]             ` <20150825163141.GJ7143@olila.local.net-space.pl>
@ 2015-08-26  6:46               ` Jan Beulich
       [not found]               ` <55DD7CDE020000780009D086@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-26  6:46 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.08.15 at 18:31, <daniel.kiper@oracle.com> wrote:
> On Tue, Aug 25, 2015 at 06:09:09AM -0600, Jan Beulich wrote:
>> >>> On 24.08.15 at 22:54, <daniel.kiper@oracle.com> wrote:
>> > On Mon, Aug 24, 2015 at 05:35:21AM -0600, Jan Beulich wrote:
>> >> >>> On 22.08.15 at 15:59, <daniel.kiper@oracle.com> wrote:
>> >> > On Thu, Aug 20, 2015 at 09:39:39AM -0600, Jan Beulich wrote:
>> >> >> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> >> >> > Currently, PE file contains many sections which are not "linear" (one
>> >> >> > after another without any holes) or even do not have representation
>> >> >> > in a file (e.g. BSS). In theory there is a chance that we could build
>> >> >> > proper PE file using current build system. However, it means that
>> >> >>
>> >> >> What is "improper" about the currently built PE file? And if there is
>> >> >> anything improper, did you inform the binutils maintainers of the
>> >> >> problem?
>> >> >
>> >> > From PE loader point of view everything is OK. However, current Xen PE
>> >> > image (at least build on my machines) is not usable by multiboot (v1)
>> >> > or multiboot2 protocol compatible loader because it is not linear (one
>> >> > section does not live immediately after another without any voids).
>> >>
>> >> Again - either I'm missing something (and then your explanation is
>> >> not good enough) or this is (as said above) a pointless adjustment.
>> >
>> > Let's focus on multiboot2 protocol (multiboot (v1) is similar to multiboot2
>> > in discussed case). In general multiboot2 is able to load any file which
>> > has:
>> >   1. proper multiboot2 header in first 32 KiB of a given file,
>> >   2. "the text and data segments must be consecutive in the OS image"
>> >      (The Multiboot Specification version 1.6).
>> >
>> > This implies that we can e.g. build valid ELF file which is also multiboot2
>> > protocol compatible image. And we does. However, we can go further.
>> > Potentially we can build valid PE image which is also valid multiboot2
>> > protocol image. Although current build method does not satisfy requirement
>> > number 2 because, e.g.:
>> >
>> > Sections:
>> > Idx Name          Size      VMA               LMA               File off
>> > Algn
>> >   0 .text         001513d0  ffff82d080200000  ffff82d080200000  00001000
>> > 2**12
>> >                                       ^^^^^^                    ^^^^^^^^
>> >                   CONTENTS, ALLOC, LOAD, CODE
>> >   1 .rodata       0004de12  ffff82d0803513e0  ffff82d0803513e0  00153000
>> > 2**5
>> >                                       ^^^^^^                    ^^^^^^^^
>> >                   CONTENTS, ALLOC, LOAD, READONLY, DATA
>> >
>> > Hence, we must use special method to build PE image (I discussed that in
>> > my earlier email in that topic) to do it compatible with multiboot2
>> > protocol.
>>
>> And you realize that we use a "special method" for building the
>> current "flat" ELF image too?
> 
> Yes, I know about that.

And with that I wonder ...

>> > This way one file could be loaded by native PE loader, mulitboot (v1)
>> > protocol
>> > (it requires relevant header but it does not interfere with PE and
>> > multiboot2
>> > protocol stuff) and mutliboot2 protocol compatible loaders. Additionally,
>> > if it is signed with Secure Boot signature then potentially signature could
>> > be verified by UEFI itself and e.g. GRUB2. However, as I said earlier this
>> > requires more work and this is next step which I am going to do after
>> > applying
>> > this series. Currently I am going to embed EFI support into ELF file because
>> > it is easy (less changes; currently used ELF file has required properties
>> > because multiboot (v1) which we use has similar requirements like multiboot2
>> > protocol) to make it compatible with multiboot2 protocol.
>>
>> I think whether what you do now makes sense depends on the
>> ultimate goal: If we want a single binary usable for all three cases,
>> then while yes, having EFI code available in the ELF image makes
>> sense, using an ELF Image won't work. And we can't have an
>> image being both ELF and PE. Hence the goal ought to be to have
>> a single PE image, and with that the direction you move seems
>> wrong.
> 
> It depends how we want to generate proper PE file. There are two options.
> 
> We can put manually proper PE header into xen/arch/x86/boot/head.S (maybe
> with some additional needed stuff). Then after build we will have ELF file
> which is loadable by multiboot protocols and has extra PE header. Of course
> it is unusable directly by EFI loader. However, using simple objcopy we can
> extract all interesting stuff from ELF file. This way we get proper PE file
> which is usable by three different boot protocols. Going that way we can
> also remove strict dependency on exact version of binutils which must have
> enabled i386pep support if we wish to build PE image.
> 
> Potentially we can choose second way and build proper PE image using ld and
> objcopy/objdump tools with proper options. However, this require more work
> (maybe we will be forced to build something similar to mkelf32) and we bind
> Xen build machinery more tightly with exact version of binutils which is
> not nice.
> 
> So, I decided to choose option #1.

... why there's no option #3 here: Build a suitable PE image using a
tool similar to mkelf32 _without_ involving ld/objcopy (i.e. straight
from the full ELF binary that mkelf32 today uses as its input).

> It looks simpler because we have a lot of
> needed stuff in place (e.g. Xen ELF image is currently in format usable by
> multiboot protocols). However, I think that in first step we should add EFI
> code to xen.gz because we want to load Xen using GRUB2 on EFI platforms 
> ASAP.
> This patch allows us to do that. Later after getting this feature into 
> upstream
> we can focus on building proper PE image with multiboot protocols support
> embedded in it.

But for whatever we do now we should keep in mind what the end
goal is, and at least avoid making it more cumbersome to reach that
end goal. And in the end I'm not sure not going the full way at once
will actually turn out to be the easier route.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]               ` <55DD7CDE020000780009D086@prv-mh.provo.novell.com>
@ 2015-08-26 12:33                 ` Daniel Kiper
       [not found]                 ` <20150826123356.GB10861@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-26 12:33 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Aug 26, 2015 at 12:46:22AM -0600, Jan Beulich wrote:
> >>> On 25.08.15 at 18:31, <daniel.kiper@oracle.com> wrote:
> > On Tue, Aug 25, 2015 at 06:09:09AM -0600, Jan Beulich wrote:
> >> >>> On 24.08.15 at 22:54, <daniel.kiper@oracle.com> wrote:

[...]

> >> And you realize that we use a "special method" for building the
> >> current "flat" ELF image too?
> >
> > Yes, I know about that.
>
> And with that I wonder ...
>
> >> > This way one file could be loaded by native PE loader, mulitboot (v1)
> >> > protocol
> >> > (it requires relevant header but it does not interfere with PE and
> >> > multiboot2
> >> > protocol stuff) and mutliboot2 protocol compatible loaders. Additionally,
> >> > if it is signed with Secure Boot signature then potentially signature could
> >> > be verified by UEFI itself and e.g. GRUB2. However, as I said earlier this
> >> > requires more work and this is next step which I am going to do after
> >> > applying
> >> > this series. Currently I am going to embed EFI support into ELF file because
> >> > it is easy (less changes; currently used ELF file has required properties
> >> > because multiboot (v1) which we use has similar requirements like multiboot2
> >> > protocol) to make it compatible with multiboot2 protocol.
> >>
> >> I think whether what you do now makes sense depends on the
> >> ultimate goal: If we want a single binary usable for all three cases,
> >> then while yes, having EFI code available in the ELF image makes
> >> sense, using an ELF Image won't work. And we can't have an
> >> image being both ELF and PE. Hence the goal ought to be to have
> >> a single PE image, and with that the direction you move seems
> >> wrong.
> >
> > It depends how we want to generate proper PE file. There are two options.
> >
> > We can put manually proper PE header into xen/arch/x86/boot/head.S (maybe
> > with some additional needed stuff). Then after build we will have ELF file
> > which is loadable by multiboot protocols and has extra PE header. Of course
> > it is unusable directly by EFI loader. However, using simple objcopy we can
> > extract all interesting stuff from ELF file. This way we get proper PE file
> > which is usable by three different boot protocols. Going that way we can
> > also remove strict dependency on exact version of binutils which must have
> > enabled i386pep support if we wish to build PE image.
> >
> > Potentially we can choose second way and build proper PE image using ld and
> > objcopy/objdump tools with proper options. However, this require more work
> > (maybe we will be forced to build something similar to mkelf32) and we bind
> > Xen build machinery more tightly with exact version of binutils which is
> > not nice.
> >
> > So, I decided to choose option #1.
>
> ... why there's no option #3 here: Build a suitable PE image using a
> tool similar to mkelf32 _without_ involving ld/objcopy (i.e. straight
> from the full ELF binary that mkelf32 today uses as its input).

This is variant of #1 and make sense too. However, this way we do not get
extra PE header in ELF file which is also good.

> > It looks simpler because we have a lot of
> > needed stuff in place (e.g. Xen ELF image is currently in format usable by
> > multiboot protocols). However, I think that in first step we should add EFI
> > code to xen.gz because we want to load Xen using GRUB2 on EFI platforms
> > ASAP.
> > This patch allows us to do that. Later after getting this feature into
> > upstream
> > we can focus on building proper PE image with multiboot protocols support
> > embedded in it.
>
> But for whatever we do now we should keep in mind what the end
> goal is, and at least avoid making it more cumbersome to reach that
> end goal. And in the end I'm not sure not going the full way at once

#1 and #3 need EFI code in xen.gz. So, I do not think that we do anything
wrong adding this functionality here because we need it for GRUB2 support
on EFI platforms too. Hence, both things benefit from that change but one
does not depend on another.

> will actually turn out to be the easier route.

Do you suggest that I should put this functionality (PE with multiboot
headers) on top of this patch series? Well, it is possible but this
series is big and I would like to avoid to make it bigger. I prefer to
get current patches into Xen tree and then work on new features (it
should not take so long because as I can see we almost agreed most
of stuff in that case). Or if at least half patches of current series
will be accepted (as I can see there is a chance to do that with v3)
then I can work on this functionality and put it on top of second not
applied part. Does it make sense?

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]                 ` <20150826123356.GB10861@olila.local.net-space.pl>
@ 2015-08-26 12:40                   ` Jan Beulich
       [not found]                   ` <55DDCFD6020000780009D226@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-26 12:40 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 26.08.15 at 14:33, <daniel.kiper@oracle.com> wrote:
> Do you suggest that I should put this functionality (PE with multiboot
> headers) on top of this patch series? Well, it is possible but this
> series is big and I would like to avoid to make it bigger. I prefer to
> get current patches into Xen tree and then work on new features (it
> should not take so long because as I can see we almost agreed most
> of stuff in that case). Or if at least half patches of current series
> will be accepted (as I can see there is a chance to do that with v3)
> then I can work on this functionality and put it on top of second not
> applied part. Does it make sense?

Yes. I'm not objecting to deferring that part. All I want is you to make
sure not to submit any changes potentially conflicting with the end
goal of having a single binary (which as I understand it can only be a
PE one).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 10/23] efi: build xen.gz with EFI code
       [not found]                   ` <55DDCFD6020000780009D226@prv-mh.provo.novell.com>
@ 2015-08-26 12:58                     ` Daniel Kiper
  0 siblings, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-26 12:58 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Aug 26, 2015 at 06:40:22AM -0600, Jan Beulich wrote:
> >>> On 26.08.15 at 14:33, <daniel.kiper@oracle.com> wrote:
> > Do you suggest that I should put this functionality (PE with multiboot
> > headers) on top of this patch series? Well, it is possible but this
> > series is big and I would like to avoid to make it bigger. I prefer to
> > get current patches into Xen tree and then work on new features (it
> > should not take so long because as I can see we almost agreed most
> > of stuff in that case). Or if at least half patches of current series
> > will be accepted (as I can see there is a chance to do that with v3)
> > then I can work on this functionality and put it on top of second not
> > applied part. Does it make sense?
>
> Yes. I'm not objecting to deferring that part. All I want is you to make

Great!

> sure not to submit any changes potentially conflicting with the end

OK.

> goal of having a single binary (which as I understand it can only be a
> PE one).

This is the end goal but I think that we should have transitional phase
when both formats (ELF and PE) are avaibale for users. Just in case.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 19/23] x86/efi: create new early memory allocator
       [not found] ` <1437402558-7313-20-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 19:49   ` [PATCH v2 19/23] x86/efi: create new early memory allocator Konrad Rzeszutek Wilk
@ 2015-08-27 11:23   ` Jan Beulich
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-27 11:23 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> There is a problem with place_string() which is used as early memory
> allocator. It gets memory chunks starting from start symbol and
> going down. Sadly this does not work when Xen is loaded using multiboot2
> protocol because start lives on 1 MiB address. So, I tried to use
> mem_lower address calculated by GRUB2. However, it works only on some
> machines. There are machines in the wild (e.g. Dell PowerEdge R820)
> which uses first ~640 KiB for boot services code or data... :-(((
> 
> In case of multiboot2 protocol we need that place_string() only allocate
> memory chunk for EFI memory map. However, I think that it should be fixed
> instead of making another function used just in one case. I thought about
> two solutions.
> 
> 1) We could use native EFI allocation functions (e.g. AllocatePool()
>    or AllocatePages()) to get memory chunk. However, later (somewhere
>    in __start_xen()) we must copy its contents to safe place or reserve
>    this in e820 memory map and map it in Xen virtual address space.
>    In later case we must also care about conflicts with e.g. crash
>    kernel regions which could be quite difficult.

1b) Do away with efi_arch_allocate_mmap_buffer() and use 
AllocatePages() uniformly, perhaps with a per-arch specified
memory type (by means of which you can control whether the
memory contents will remain preserved until the time you want
to look at it). That will eliminate the only place_string() you're
concerned about, with a patch with better diffstat (largely due
to the questionable arch hook gone).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
  2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
  2015-08-10 20:07   ` Konrad Rzeszutek Wilk
  2015-08-11 15:23   ` Konrad Rzeszutek Wilk
@ 2015-08-27 12:01   ` Jan Beulich
       [not found]   ` <55DF1836020000780009D674@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-27 12:01 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

For a patch of this size, no description at all seems rather
problematic.

> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -89,6 +89,13 @@ multiboot1_header_end:
>                     0, /* Number of the lines - no preference. */ \
>                     0  /* Number of bits per pixel - no preference. */
>  
> +        /* Do not disable EFI boot services. */
> +        mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
> +
> +        /* EFI64 entry point. */
> +        mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
> +                   sym_phys(__efi64_start)

Iirc at least one of those two is what upstream doesn't have yet,
or not all earlier grub2 versions might have. If so - what happens
if the resulting Xen gets booted on an incapable grub? Silent death
(with black screen)? Or at least some note to the user that the
grub2 version is not suitable?

> @@ -130,6 +146,119 @@ print_err:
>  .Lhalt: hlt
>          jmp     .Lhalt
>  
> +        .code64
> +
> +__efi64_start:
> +        cld
> +
> +        /* Check for Multiboot2 bootloader. */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      efi_multiboot2_proto
> +
> +        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
> +        lea     not_multiboot(%rip),%rdi
> +        jmp     x86_32_switch
> +
> +efi_multiboot2_proto:

.L

> +run_bs:

Again.

> +x86_32_switch:
> +        cli
> +
> +        /* Initialise GDT. */
> +        lgdt    gdt_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

I see no point in loading %fs and %gs with other than nul selectors.
I also think %ss should be loaded first. Which reminds me - what
about %rsp? Is it guaranteed to have its upper 32 bits clear, so you
can re-use the stack in 32-bit mode? (If it is, saying so in a comment
would be very desirable.)

> @@ -182,7 +318,7 @@ multiboot2_proto:
>          and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>          jmp     0b
>  
> -trampoline_setup:
> +trampoline_bios_setup:

Another .L candidate.

>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -198,12 +334,13 @@ trampoline_setup:
>           * multiboot structure (if available) and use the smallest.
>           */
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
> -        jb      2f                  /* if so, do not use it */
> +        jb      trampoline_setup    /* if so, do not use it */
>          shl     $10-4,%edx
>          cmp     %ecx,%edx           /* compare with BDA value */
>          cmovb   %edx,%ecx           /* and use the smaller */
>  
> -2:      /* Reserve 64kb for the trampoline */
> +trampoline_setup:
> +        /* Reserve 64kb for the trampoline. */

And one more.

> @@ -220,6 +357,13 @@ trampoline_setup:
>          add     $12,%esp            /* Remove reloc() args from stack. */
>          mov     %eax,sym_phys(multiboot_ptr)
>  
> +        /*
> +         * Do not zero BSS on EFI platform here.
> +         * It was initialized earlier.
> +         */
> +        cmpb    $1,sym_phys(skip_realmode)
> +        je      1f

So why can't this be done uniformly here? I didn't see you write any
variable in .bss by now. And if there was any, moving it to .data
would avoid zeroing .bss in two different places. Or wait - I see, it's
the C code in efi_multiboot2() that you need to take care of. Well,
probably okay then this way, but please extend the comment at the
new zeroing site to say _why_ it needs to be done differently/earlier.

> +paddr_t __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
> +    UINTN cols, gop_mode = ~0, rows;
> +
> +    set_bit(EFI_PLATFORM, &efi.flags);
> +
> +    efi_init(ImageHandle, SystemTable);
> +
> +    efi_console_set_mode();
> +
> +    if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
> +                           &cols, &rows) == EFI_SUCCESS )
> +        efi_arch_console_init(cols, rows);
> +
> +    gop = efi_get_gop();
> +    gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
> +    efi_arch_edd();
> +    efi_tables();
> +    setup_efi_pci();
> +    efi_variables();
> +    efi_set_gop_mode(gop, gop_mode);
> +    efi_exit_boot(ImageHandle, SystemTable);
> +
> +    return cfg.addr;

With all the refactoring in the earlier patches it is now almost impossible
to know what cfg.addr holds at this point - it looks to me as if this is
entirely unrelated to the mem_lower value the caller wants to derive
from this. Please at least add a brief comment.

> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -13,6 +13,11 @@ struct efi __read_mostly efi = {
>  	.smbios3 = EFI_INVALID_TABLE_ADDR
>  };
>  
> +void __init efi_multiboot2(void)
> +{
> +    /* TODO: Fail if entered! */

No "TODO" or alike please in non-RFC patch submissions (unless there
are exceptional circumstances). Here - BUG() (or panic() if there was
a remote chance of this being reached).

> @@ -708,7 +708,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          l3_bootmap[l3_table_offset(BOOTSTRAP_MAP_BASE)] =
>              l3e_from_paddr(__pa(l2_bootmap), __PAGE_HYPERVISOR);
>  
> -        memmap_type = loader;
> +        memmap_type = "EFI";

What's wrong with keeping this line as is?

> +    }
> +    else if ( efi_enabled(EFI_PLATFORM) )
> +    {
> +        memmap_type = "EFI";
>      }

The braces are now pointless here.

> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -79,6 +79,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);

This is ugly; I'm sure there is a way to avoid these declarations.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found] ` <1437402558-7313-22-git-send-email-daniel.kiper@oracle.com>
  2015-08-10 20:31   ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Konrad Rzeszutek Wilk
  2015-08-11 14:43   ` Konrad Rzeszutek Wilk
@ 2015-08-27 12:43   ` Jan Beulich
       [not found]   ` <55DF221B020000780009D6C6@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-27 12:43 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> Current early command line parser implementation in assembler
> is very difficult to change to relocatable stuff using segment
> registers. This requires a lot of changes in very weird and
> fragile code. So, reimplement this functionality in C. This
> way code will be relocatable out of the box and much easier
> to maintain.

All appreciated and nice, but the goal of making the code
relocatable by playing with segment registers sounds fragile:
This breaks assumptions the compiler may validly make.

>  xen/arch/x86/boot/cmdline.S    |  367 -------------------------------------
>  xen/arch/x86/boot/cmdline.c    |  396 ++++++++++++++++++++++++++++++++++++++++

A fundamental expectation I would have had is for the C file to be
noticeably smaller than the assembly file.

> --- /dev/null
> +++ b/xen/arch/x86/boot/cmdline.c
>[...]
> +#define VESA_WIDTH	0
> +#define VESA_HEIGHT	1
> +#define VESA_DEPTH	2
> +
> +#define VESA_SIZE	3

These should go away in favor of using individual (sub)structure fields.

> +#define __cdecl		__attribute__((__cdecl__))

???

> +#define __packed	__attribute__((__packed__))
> +#define __text		__attribute__((__section__(".text")))
> +#define __used		__attribute__((__used__))

Likely better to include compiler.h instead.

> +#define max(x,y) ({ \
> +        const typeof(x) _x = (x);       \
> +        const typeof(y) _y = (y);       \
> +        (void) (&_x == &_y);            \
> +        _x > _y ? _x : _y; })

I also wonder whether -imacros .../xen/kernel.h wouldn't be a better
approach here. Please really think hard on how to avoid duplications
like these.

> +#define strlen_static(s) (sizeof(s) - 1)

What is this good for? A decent compiler should be able to deal with
strlen("..."). Plus your macro is longer that what it tries to "abbreviate".

> +static const char empty_chars[] __text = " \n\r\t";

What is empty about them? DYM blank or (white) space or separator
or delimiter? I also wonder whether \n and \r are actually usefully here,
as they should (if at all) only end the line.

> +/**
> + * strlen - Find the length of a string
> + * @s: The string to be sized
> + */
> +static size_t strlen(const char *s)

Comments are certainly nice, but in this special case I'd rather suggest
against bloating the code by commenting standard library functions.

> +static int strtoi(const char *s, const char *stop, const char **next)
> +{
> +    int base = 10, i, ores = 0, res = 0;
> +
> +    if ( *s == '0' )
> +      base = (tolower(*++s) == 'x') ? (++s, 16) : 8;
> +
> +    for ( ; *s != '\0'; ++s )
> +    {
> +        for ( i = 0; stop && stop[i] != '\0'; ++i )
> +            if ( *s == stop[i] )
> +                goto out;
> +
> +        if ( *s < '0' || (*s > '7' && base == 8) )
> +        {
> +            res = -1;
> +            goto out;
> +        }
> +
> +        if ( *s > '9' && (base != 16 || tolower(*s) < 'a' || tolower(*s) > 'f') )
> +        {
> +            res = -1;
> +            goto out;
> +        }
> +
> +        res *= base;
> +        res += (tolower(*s) >= 'a') ? (tolower(*s) - 'a' + 10) : (*s - '0');
> +
> +        if ( ores > res )
> +        {
> +            res = -1;
> +            goto out;
> +        }
> +
> +        ores = res;
> +    }
> +
> +out:

C labels intended by at least one space please.

> +static const char *find_opt(const char *cmdline, const char *opt, int arg)
> +{
> +    size_t lc, lo;
> +    static const char mm[] __text = "--";

I'd be surprised if there weren't compiler/assembler versions
complaining about a section type conflict here. I can see why you
want everything in one section, but I'd rather suggest achieving
this at the linking step (which I would suppose to already be taking
care of this).

> +static u8 skip_realmode(const char *cmdline)
> +{
> +    static const char nrm[] __text = "no-real-mode";
> +    static const char tboot[] __text = "tboot=";
> +
> +    if ( find_opt(cmdline, nrm, 0) || find_opt(cmdline, tboot, 1) )
> +        return 1;
> +
> +    return 0;

return find_opt(cmdline, nrm, 0) || find_opt(cmdline, tboot, 1);

> +static u8 edd_parse(const char *cmdline)
> +{
> +    const char *c;
> +    size_t la;
> +    static const char edd[] __text = "edd=";
> +    static const char edd_off[] __text = "off";
> +    static const char edd_skipmbr[] __text = "skipmbr";
> +
> +    c = find_opt(cmdline, edd, 1);
> +
> +    if ( !c )
> +        return 0;
> +
> +    c += strlen_static(edd);
> +    la = strcspn(c, empty_chars);
> +
> +    if ( !strncmp(c, edd_off, max(la, strlen_static(edd_off))) )
> +        return 2;
> +    else if ( !strncmp(c, edd_skipmbr, max(la, strlen_static(edd_skipmbr))) )

Pointless else.

> +        return 1;
> +
> +    return 0;

And the last two returns can be folded again anyway.

> +static void __cdecl __used cmdline_parse_early(const char *cmdline, early_boot_opts_t *ebo)

I don't see the point of the __cdecl, and (as said before) dislike the
static __used pair.

> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -429,8 +429,24 @@ trampoline_setup:
>          cmp     $sym_phys(__trampoline_seg_stop),%edi
>          jb      1b
>  
> +        /* Do not parse command line on EFI platform here. */
> +        cmpb    $1,sym_phys(skip_realmode)

Is there a reason you can't look at efi.flags instead here (and in
the other case you abuse skip_realmode as meaning EFI)?

> --- a/xen/arch/x86/boot/trampoline.S
> +++ b/xen/arch/x86/boot/trampoline.S
> @@ -1,3 +1,5 @@
> +#include "video.h"

Please move this farther down, making invisible all its definitions to
code not supposed to use them.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found] ` <1437402558-7313-23-git-send-email-daniel.kiper@oracle.com>
  2015-08-11 16:48   ` [PATCH v2 22/23] x86: make Xen early boot code relocatable Konrad Rzeszutek Wilk
       [not found]   ` <20150811164806.GB32231@l.oracle.com>
@ 2015-08-27 13:12   ` Jan Beulich
       [not found]   ` <55DF28E6020000780009D6E4@prv-mh.provo.novell.com>
  3 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-27 13:12 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>   - %fs register is filled with segment descriptor which describes memory region
>     with Xen image (it could be relocated or not);

This is too fuzzy. Please be very precise which region it is that %fs
is supposed to point to (so that reviewers have a chance to validate
uses).

> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -72,8 +72,10 @@ efi-$(x86_64) := $(shell if [ ! -r 
> $(BASEDIR)/include/xen/compile.h -o \
>                           echo '$(TARGET).efi'; fi)
>  
>  $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
> -	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
> -	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
> +#	THIS IS UGLY HACK! PLEASE DO NOT COMPLAIN. I WILL FIX IT IN NEXT RELEASE.
> +	./boot/mkelf32 $(TARGET)-syms $(TARGET) $(XEN_IMG_PHYS_START) 0xffff82d081000000
> +#	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 \
> +#	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`

I do complain nevertheless: Such a patch should be tagged RFC. And
with such a hack in place I'm not even sure it's worth reviewing.

> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -12,13 +12,15 @@
>          .text
>          .code32
>  
> -#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
> +#define sym_phys(sym)     ((sym) - __XEN_VIRT_START + XEN_IMG_PHYS_START - XEN_IMG_OFFSET)
> +#define sym_offset(sym)   ((sym) - __XEN_VIRT_START)

With XEN_IMG_PHYS_START == XEN_IMG_OFFSET - what's the point?
(If there is a point, then there's obviously a comment missing here
explaining things, including when to use which.)

> @@ -105,12 +107,13 @@ multiboot1_header_end:
>  
>          .word   0
>  gdt_boot_descr:
> -        .word   6*8-1
> -        .long   sym_phys(trampoline_gdt)
> +        .word   7*8-1
> +gdt_boot_descr_addr:

gdt_boot_base would seem a better name; with C in mind what
you use currently could be easily mistaken for a variable holding
&gdt_boot_descr.

> @@ -263,12 +271,8 @@ __start:
>          cld
>          cli
>  
> -        /* Initialise GDT and basic data segments. */
> -        lgdt    %cs:sym_phys(gdt_boot_descr)
> -        mov     $BOOT_DS,%ecx
> -        mov     %ecx,%ds
> -        mov     %ecx,%es
> -        mov     %ecx,%ss
> +        /* Load default Xen image base address. */
> +        mov     $sym_phys(__image_base__),%ebp

Isn't this always zero? I.e. wouldn't you better use "xor %ebp,%ebp"?

>          /* Save the Multiboot info struct (after relocation) for later use. */
> -        mov     $sym_phys(cpu0_stack)+1024,%esp
> +        lea     (sym_offset(cpu0_stack)+1024)(%ebp),%esp

Please avoid obfuscating the code by adding pointless parentheses.

> @@ -390,72 +432,111 @@ trampoline_setup:
>  
>          /* Stash TSC to calculate a good approximation of time-since-boot */
>          rdtsc
> -        mov     %eax,sym_phys(boot_tsc_stamp)
> -        mov     %edx,sym_phys(boot_tsc_stamp+4)
> +        mov     %eax,%fs:sym_offset(boot_tsc_stamp)
> +        mov     %edx,%fs:sym_offset(boot_tsc_stamp+4)
>  
> -        /* Initialise L2 boot-map page table entries (16MB). */
> -        mov     $sym_phys(l2_bootmap),%edx
> -        mov     $PAGE_HYPERVISOR|_PAGE_PSE,%eax
> -        mov     $8,%ecx
> +        /* Update frame addreses in page tables. */
> +        lea     sym_offset(__page_tables_start)(%ebp),%edx
> +        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
> +1:      testl   $_PAGE_PRESENT,(%edx)
> +        jz      2f
> +        add     %ebp,(%edx)
> +2:      add     $8,%edx
> +        loop    1b
> +
> +        /* Initialise L2 boot-map page table entries (14MB). */
> +        lea     sym_offset(l2_bootmap)(%ebp),%edx
> +        lea     sym_offset(start)(%ebp),%eax
> +        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
> +        mov     %eax,%ebx
> +        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
> +        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
> +        add     %ebx,%edx
> +        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
> +        mov     $7,%ecx
>  1:      mov     %eax,(%edx)
>          add     $8,%edx
>          add     $(1<<L2_PAGETABLE_SHIFT),%eax
>          loop    1b
> +
>          /* Initialise L3 boot-map page directory entry. */
> -        mov     $sym_phys(l2_bootmap)+__PAGE_HYPERVISOR,%eax
> -        mov     %eax,sym_phys(l3_bootmap) + 0*8
> +        lea     (sym_offset(l2_bootmap)+__PAGE_HYPERVISOR)(%ebp),%eax
> +        lea     sym_offset(l3_bootmap)(%ebp),%ebx
> +        mov     $4,%ecx
> +1:      mov     %eax,(%ebx)
> +        add     $8,%ebx
> +        add     $(L2_PAGETABLE_ENTRIES*8),%eax
> +        loop    1b
> +
> +        /* Initialise L2 direct map page table entries (14MB). */
> +        lea     sym_offset(l2_identmap)(%ebp),%edx
> +        lea     sym_offset(start)(%ebp),%eax
> +        and     $~((1<<L2_PAGETABLE_SHIFT)-1),%eax
> +        mov     %eax,%ebx
> +        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
> +        and     $(L2_PAGETABLE_ENTRIES*4*8-1),%ebx
> +        add     %ebx,%edx
> +        add     $(PAGE_HYPERVISOR|_PAGE_PSE),%eax
> +        mov     $7,%ecx
> +1:      mov     %eax,(%edx)
> +        add     $8,%edx
> +        add     $(1<<L2_PAGETABLE_SHIFT),%eax
> +        loop    1b
> +
>          /* Hook 4kB mappings of first 2MB of memory into L2. */
> -        mov     $sym_phys(l1_identmap)+__PAGE_HYPERVISOR,%edi
> -        mov     %edi,sym_phys(l2_xenmap)
> -        mov     %edi,sym_phys(l2_bootmap)
> +        lea     (sym_offset(l1_identmap)+__PAGE_HYPERVISOR)(%ebp),%edi
> +        mov     %edi,%fs:sym_offset(l2_bootmap)
>  
>          /* Apply relocations to bootstrap trampoline. */
> -        mov     sym_phys(trampoline_phys),%edx
> -        mov     $sym_phys(__trampoline_rel_start),%edi
> +        mov     %fs:sym_offset(trampoline_phys),%edx
> +        lea     sym_offset(__trampoline_rel_start)(%ebp),%edi
> +        lea     sym_offset(__trampoline_rel_stop)(%ebp),%esi
>  1:
>          mov     (%edi),%eax
>          add     %edx,(%edi,%eax)
>          add     $4,%edi
> -        cmp     $sym_phys(__trampoline_rel_stop),%edi
> +        cmp     %esi,%edi
>          jb      1b
>  
>          /* Patch in the trampoline segment. */
>          shr     $4,%edx
> -        mov     $sym_phys(__trampoline_seg_start),%edi
> +        lea     sym_offset(__trampoline_seg_start)(%ebp),%edi
> +        lea     sym_offset(__trampoline_seg_stop)(%ebp),%esi
>  1:
>          mov     (%edi),%eax
>          mov     %dx,(%edi,%eax)
>          add     $4,%edi
> -        cmp     $sym_phys(__trampoline_seg_stop),%edi
> +        cmp     %esi,%edi
>          jb      1b
>  
>          /* Do not parse command line on EFI platform here. */
> -        cmpb    $1,sym_phys(skip_realmode)
> +        cmpb    $1,%fs:sym_offset(skip_realmode)
>          je      1f
>  
>          /* Bail if there is no command line to parse. */
> -        mov     sym_phys(multiboot_ptr),%ebx
> +        mov     %fs:sym_offset(multiboot_ptr),%ebx
>          testl   $MBI_CMDLINE,MB_flags(%ebx)
>          jz      1f
>  
>          cmpl    $0,MB_cmdline(%ebx)
>          jz      1f
>  
> -        pushl   $sym_phys(early_boot_opts)
> +        lea     sym_offset(early_boot_opts)(%ebp),%eax
> +        push    %eax
>          pushl   MB_cmdline(%ebx)
>          call    cmdline_parse_early
>          add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
>  
>  1:
>          /* Switch to low-memory stack.  */
> -        mov     sym_phys(trampoline_phys),%edi
> +        mov     %fs:sym_offset(trampoline_phys),%edi
>          lea     0x10000(%edi),%esp
>          lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
>          pushl   $BOOT_CS32
>          push    %eax
>  
>          /* Copy bootstrap trampoline to low memory, below 1MB. */
> -        mov     $sym_phys(trampoline_start),%esi
> +        lea     sym_offset(trampoline_start)(%ebp),%esi
>          mov     $trampoline_end - trampoline_start,%ecx
>          rep     movsb
>  

The latest at this final hunk I'm getting tired (and upset). I'd much
rather not touch all this code in these fragile ways, and instead
require Xen to be booted without grub2 on badly written firmware
like the one on the machine you quote in the description.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]   ` <55DF28E6020000780009D6E4@prv-mh.provo.novell.com>
@ 2015-08-27 15:10     ` Daniel Kiper
       [not found]     ` <20150827151054.GI10944@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-27 15:10 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Aug 27, 2015 at 07:12:38AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:

[...]

> >          /* Copy bootstrap trampoline to low memory, below 1MB. */
> > -        mov     $sym_phys(trampoline_start),%esi
> > +        lea     sym_offset(trampoline_start)(%ebp),%esi
> >          mov     $trampoline_end - trampoline_start,%ecx
> >          rep     movsb
> >
>
> The latest at this final hunk I'm getting tired (and upset). I'd much
> rather not touch all this code in these fragile ways, and instead
> require Xen to be booted without grub2 on badly written firmware
> like the one on the machine you quote in the description.

Let's start discussion from here. My further work on this patch series
is pointless until we do not agree details in this case.

So, I agree that any software (including firmware) should not use
precious resources (i.e. low memory in that case) if it is not strictly
required. And I do not think so that latest UEFI implementations
on new hardware really need this low memory to survive (at least page
tables could be put anywhere above low memory). However, in case of
UEFI it is a wish of smart people not requirement set by spec. I was
checking UEFI docs a few times but I was not able to find anything
which says that e.g. "...developer MUST allocate memory outside of low
memory ...". Even I have not found any suggestion about that. However,
I must admit that I do not know whole UEFI spec, so, if you know something
which is similar to above please tell me where it is (title, revision,
page, paragraph, etc.). Hence, if there is not strict requirement in
regards to memory allocation in specs we are lost. Of course we can
encourage people to not do nasty things but I do not believe that many
will listen. So, sadly, I suppose that we will see more and more machines
in the wild which are "broken" (well, let's say do not align to good practices).

On the other hand I think that we should not assume that a given memory
region (in our case starting at 1 MiB) is (or will be) available in every
machine. I have not seen anything which says that it is true. We should
stop doing that even if it works right now. I think that it works by
chance and there is a chance that it will stop working one day because
somebody will discover that he or she can put there e.g. device or hole.

Last but not least. I suppose that Xen users and especially distros will
complain when they are not able to use GRUB2 with Xen on every platform
just because somebody (i.e. platform designers, developers, or whatever)
do not accept our beliefs or we require that platform must obey rules
(i.e. memory map requirements) which are specified nowhere.

So, I think that early Xen boot code should be relocatable. However, I agree
that there is a chance that may solution is not perfect. So, I suppose,
taking into account above, we should discuss how to improve it instead
of discussing whether we should do it.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]     ` <20150827151054.GI10944@olila.local.net-space.pl>
@ 2015-08-27 15:29       ` Jan Beulich
       [not found]       ` <55DF48FB020000780009D83F@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-27 15:29 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 27.08.15 at 17:10, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 27, 2015 at 07:12:38AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> >          /* Copy bootstrap trampoline to low memory, below 1MB. */
>> > -        mov     $sym_phys(trampoline_start),%esi
>> > +        lea     sym_offset(trampoline_start)(%ebp),%esi
>> >          mov     $trampoline_end - trampoline_start,%ecx
>> >          rep     movsb
>> >
>>
>> The latest at this final hunk I'm getting tired (and upset). I'd much
>> rather not touch all this code in these fragile ways, and instead
>> require Xen to be booted without grub2 on badly written firmware
>> like the one on the machine you quote in the description.
> 
> Let's start discussion from here. My further work on this patch series
> is pointless until we do not agree details in this case.
> 
> So, I agree that any software (including firmware) should not use
> precious resources (i.e. low memory in that case) if it is not strictly
> required. And I do not think so that latest UEFI implementations
> on new hardware really need this low memory to survive (at least page
> tables could be put anywhere above low memory). However, in case of
> UEFI it is a wish of smart people not requirement set by spec. I was
> checking UEFI docs a few times but I was not able to find anything
> which says that e.g. "...developer MUST allocate memory outside of low
> memory ...". Even I have not found any suggestion about that. However,
> I must admit that I do not know whole UEFI spec, so, if you know something
> which is similar to above please tell me where it is (title, revision,
> page, paragraph, etc.). Hence, if there is not strict requirement in
> regards to memory allocation in specs we are lost. Of course we can
> encourage people to not do nasty things but I do not believe that many
> will listen. So, sadly, I suppose that we will see more and more machines
> in the wild which are "broken" (well, let's say do not align to good 
> practices).
> 
> On the other hand I think that we should not assume that a given memory
> region (in our case starting at 1 MiB) is (or will be) available in every
> machine. I have not seen anything which says that it is true. We should
> stop doing that even if it works right now. I think that it works by
> chance and there is a chance that it will stop working one day because
> somebody will discover that he or she can put there e.g. device or hole.
> 
> Last but not least. I suppose that Xen users and especially distros will
> complain when they are not able to use GRUB2 with Xen on every platform
> just because somebody (i.e. platform designers, developers, or whatever)
> do not accept our beliefs or we require that platform must obey rules
> (i.e. memory map requirements) which are specified nowhere.

You're right, there's no such requirement on memory use in the spec.
But you're missing the point. Supporting grub2 on UEFI is already a
hack (ignoring all intentions EFI had from its first days). And now
you've found an environment where that hack needs another hack
(in Xen) to actually work. That's too much hackery for my taste, the
more that things on this system can (afaict) work quite okay (without
grub2, or with using its chainloader mechanism).

So no, I'm still not convinced of the need for this patch.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]       ` <55DF48FB020000780009D83F@prv-mh.provo.novell.com>
@ 2015-08-27 17:56         ` Ben Hildred
  2015-08-27 18:04         ` Andrew Cooper
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 116+ messages in thread
From: Ben Hildred @ 2015-08-27 17:56 UTC (permalink / raw)
  To: The development of GNU GRUB
  Cc: Juergen Gross, wei.liu2, Ian Campbell, Stefano Stabellini,
	andrew.cooper3, Daniel Kiper, Roy Franz, ning.sun, david.vrabel,
	Vladimir Serbinenko, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, Fu Wei


[-- Attachment #1.1: Type: text/plain, Size: 4829 bytes --]

On Thu, Aug 27, 2015 at 9:29 AM, Jan Beulich <JBeulich@suse.com> wrote:

> >>> On 27.08.15 at 17:10, <daniel.kiper@oracle.com> wrote:
> > On Thu, Aug 27, 2015 at 07:12:38AM -0600, Jan Beulich wrote:
> >> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> >> >          /* Copy bootstrap trampoline to low memory, below 1MB. */
> >> > -        mov     $sym_phys(trampoline_start),%esi
> >> > +        lea     sym_offset(trampoline_start)(%ebp),%esi
> >> >          mov     $trampoline_end - trampoline_start,%ecx
> >> >          rep     movsb
> >> >
> >>
> >> The latest at this final hunk I'm getting tired (and upset). I'd much
> >> rather not touch all this code in these fragile ways, and instead
> >> require Xen to be booted without grub2 on badly written firmware
> >> like the one on the machine you quote in the description.
> >
> > Let's start discussion from here. My further work on this patch series
> > is pointless until we do not agree details in this case.
> >
> > So, I agree that any software (including firmware) should not use
> > precious resources (i.e. low memory in that case) if it is not strictly
> > required. And I do not think so that latest UEFI implementations
> > on new hardware really need this low memory to survive (at least page
> > tables could be put anywhere above low memory). However, in case of
> > UEFI it is a wish of smart people not requirement set by spec. I was
> > checking UEFI docs a few times but I was not able to find anything
> > which says that e.g. "...developer MUST allocate memory outside of low
> > memory ...". Even I have not found any suggestion about that. However,
> > I must admit that I do not know whole UEFI spec, so, if you know
> something
> > which is similar to above please tell me where it is (title, revision,
> > page, paragraph, etc.). Hence, if there is not strict requirement in
> > regards to memory allocation in specs we are lost. Of course we can
> > encourage people to not do nasty things but I do not believe that many
> > will listen. So, sadly, I suppose that we will see more and more machines
> > in the wild which are "broken" (well, let's say do not align to good
> > practices).
> >
> > On the other hand I think that we should not assume that a given memory
> > region (in our case starting at 1 MiB) is (or will be) available in every
> > machine. I have not seen anything which says that it is true. We should
> > stop doing that even if it works right now. I think that it works by
> > chance and there is a chance that it will stop working one day because
> > somebody will discover that he or she can put there e.g. device or hole.
> >
> > Last but not least. I suppose that Xen users and especially distros will
> > complain when they are not able to use GRUB2 with Xen on every platform
> > just because somebody (i.e. platform designers, developers, or whatever)
> > do not accept our beliefs or we require that platform must obey rules
> > (i.e. memory map requirements) which are specified nowhere.
>
> You're right, there's no such requirement on memory use in the spec.
> But you're missing the point. Supporting grub2 on UEFI is already a
> hack (ignoring all intentions EFI had from its first days). And now
> you've found an environment where that hack needs another hack
> (in Xen) to actually work. That's too much hackery for my taste, the
> more that things on this system can (afaict) work quite okay (without
> grub2, or with using its chainloader mechanism).
>
> If you advocate direct booting ( no boot loader)  on production machines I
wont argue much, as long as there is good recovery tools to deal with
failed boots (grub does this very well, I am not aware of anything
comparable that is pure efi). however the other use case which care more
about is dual booting. I am a novice when it comes to Xen, although
otherwise competent. The test machines I have for playing with Xen are also
used for other tests, some of which require raw hardware support, so I want
the ability to use a boot menu. I am aware of refit, but it does not have
serial support which makes automating testing more difficult. and I have
not yet got ipxe to successfully boot Xen (although this is purely because
I have not yet devoted enough time to that project and I am not yet
familiar with how Xen boots).

So no, I'm still not convinced of the need for this patch.
>

I am at a loss for alternatives. Yes grub on efi violates the spirit of
efi. Propose a better way forward rather than deriding those who have found
a successful, portable way around the limitations of efi implementations.

>
> Jan
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
--
Ben Hildred
Automation Support Services
303 815 6721

[-- Attachment #1.2: Type: text/html, Size: 6430 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]       ` <55DF48FB020000780009D83F@prv-mh.provo.novell.com>
  2015-08-27 17:56         ` Ben Hildred
@ 2015-08-27 18:04         ` Andrew Cooper
       [not found]         ` <55DF5125.20708@citrix.com>
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 116+ messages in thread
From: Andrew Cooper @ 2015-08-27 18:04 UTC (permalink / raw)
  To: Jan Beulich, Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, roy.franz, ning.sun, david.vrabel,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	fu.wei

On 27/08/15 16:29, Jan Beulich wrote:
>>>> On 27.08.15 at 17:10, <daniel.kiper@oracle.com> wrote:
>> On Thu, Aug 27, 2015 at 07:12:38AM -0600, Jan Beulich wrote:
>>>>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>>>>          /* Copy bootstrap trampoline to low memory, below 1MB. */
>>>> -        mov     $sym_phys(trampoline_start),%esi
>>>> +        lea     sym_offset(trampoline_start)(%ebp),%esi
>>>>          mov     $trampoline_end - trampoline_start,%ecx
>>>>          rep     movsb
>>>>
>>> The latest at this final hunk I'm getting tired (and upset). I'd much
>>> rather not touch all this code in these fragile ways, and instead
>>> require Xen to be booted without grub2 on badly written firmware
>>> like the one on the machine you quote in the description.
>> Let's start discussion from here. My further work on this patch series
>> is pointless until we do not agree details in this case.
>>
>> So, I agree that any software (including firmware) should not use
>> precious resources (i.e. low memory in that case) if it is not strictly
>> required. And I do not think so that latest UEFI implementations
>> on new hardware really need this low memory to survive (at least page
>> tables could be put anywhere above low memory). However, in case of
>> UEFI it is a wish of smart people not requirement set by spec. I was
>> checking UEFI docs a few times but I was not able to find anything
>> which says that e.g. "...developer MUST allocate memory outside of low
>> memory ...". Even I have not found any suggestion about that. However,
>> I must admit that I do not know whole UEFI spec, so, if you know something
>> which is similar to above please tell me where it is (title, revision,
>> page, paragraph, etc.). Hence, if there is not strict requirement in
>> regards to memory allocation in specs we are lost. Of course we can
>> encourage people to not do nasty things but I do not believe that many
>> will listen. So, sadly, I suppose that we will see more and more machines
>> in the wild which are "broken" (well, let's say do not align to good 
>> practices).
>>
>> On the other hand I think that we should not assume that a given memory
>> region (in our case starting at 1 MiB) is (or will be) available in every
>> machine. I have not seen anything which says that it is true. We should
>> stop doing that even if it works right now. I think that it works by
>> chance and there is a chance that it will stop working one day because
>> somebody will discover that he or she can put there e.g. device or hole.
>>
>> Last but not least. I suppose that Xen users and especially distros will
>> complain when they are not able to use GRUB2 with Xen on every platform
>> just because somebody (i.e. platform designers, developers, or whatever)
>> do not accept our beliefs or we require that platform must obey rules
>> (i.e. memory map requirements) which are specified nowhere.
> You're right, there's no such requirement on memory use in the spec.
> But you're missing the point. Supporting grub2 on UEFI is already a
> hack (ignoring all intentions EFI had from its first days). And now
> you've found an environment where that hack needs another hack
> (in Xen) to actually work. That's too much hackery for my taste, the
> more that things on this system can (afaict) work quite okay (without
> grub2, or with using its chainloader mechanism).
>
> So no, I'm still not convinced of the need for this patch.

I disagree.  There are many things a grub environment gives us which
plain EFI doesn't, most notably a familiar booting environment and
recovery facilities for users (which vastly trumps how EFI expects to
run things).

Furthermore, it offers common management of /boot in the dom0 filesystem
between legacy and EFI boots.

Therefore I am very much +1 get grub working.

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]         ` <55DF5125.20708@citrix.com>
@ 2015-08-28  6:54           ` Jan Beulich
       [not found]           ` <55E021C4020000780009DA95@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-28  6:54 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, Daniel Kiper, roy.franz, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 27.08.15 at 20:04, <andrew.cooper3@citrix.com> wrote:
> On 27/08/15 16:29, Jan Beulich wrote:
>>>>> On 27.08.15 at 17:10, <daniel.kiper@oracle.com> wrote:
>>> On Thu, Aug 27, 2015 at 07:12:38AM -0600, Jan Beulich wrote:
>>>>>>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>>>>>          /* Copy bootstrap trampoline to low memory, below 1MB. */
>>>>> -        mov     $sym_phys(trampoline_start),%esi
>>>>> +        lea     sym_offset(trampoline_start)(%ebp),%esi
>>>>>          mov     $trampoline_end - trampoline_start,%ecx
>>>>>          rep     movsb
>>>>>
>>>> The latest at this final hunk I'm getting tired (and upset). I'd much
>>>> rather not touch all this code in these fragile ways, and instead
>>>> require Xen to be booted without grub2 on badly written firmware
>>>> like the one on the machine you quote in the description.
>>> Let's start discussion from here. My further work on this patch series
>>> is pointless until we do not agree details in this case.
>>>
>>> So, I agree that any software (including firmware) should not use
>>> precious resources (i.e. low memory in that case) if it is not strictly
>>> required. And I do not think so that latest UEFI implementations
>>> on new hardware really need this low memory to survive (at least page
>>> tables could be put anywhere above low memory). However, in case of
>>> UEFI it is a wish of smart people not requirement set by spec. I was
>>> checking UEFI docs a few times but I was not able to find anything
>>> which says that e.g. "...developer MUST allocate memory outside of low
>>> memory ...". Even I have not found any suggestion about that. However,
>>> I must admit that I do not know whole UEFI spec, so, if you know something
>>> which is similar to above please tell me where it is (title, revision,
>>> page, paragraph, etc.). Hence, if there is not strict requirement in
>>> regards to memory allocation in specs we are lost. Of course we can
>>> encourage people to not do nasty things but I do not believe that many
>>> will listen. So, sadly, I suppose that we will see more and more machines
>>> in the wild which are "broken" (well, let's say do not align to good 
>>> practices).
>>>
>>> On the other hand I think that we should not assume that a given memory
>>> region (in our case starting at 1 MiB) is (or will be) available in every
>>> machine. I have not seen anything which says that it is true. We should
>>> stop doing that even if it works right now. I think that it works by
>>> chance and there is a chance that it will stop working one day because
>>> somebody will discover that he or she can put there e.g. device or hole.
>>>
>>> Last but not least. I suppose that Xen users and especially distros will
>>> complain when they are not able to use GRUB2 with Xen on every platform
>>> just because somebody (i.e. platform designers, developers, or whatever)
>>> do not accept our beliefs or we require that platform must obey rules
>>> (i.e. memory map requirements) which are specified nowhere.
>> You're right, there's no such requirement on memory use in the spec.
>> But you're missing the point. Supporting grub2 on UEFI is already a
>> hack (ignoring all intentions EFI had from its first days). And now
>> you've found an environment where that hack needs another hack
>> (in Xen) to actually work. That's too much hackery for my taste, the
>> more that things on this system can (afaict) work quite okay (without
>> grub2, or with using its chainloader mechanism).
>>
>> So no, I'm still not convinced of the need for this patch.
> 
> I disagree.  There are many things a grub environment gives us which
> plain EFI doesn't, most notably a familiar booting environment and
> recovery facilities for users (which vastly trumps how EFI expects to
> run things).

"Familiar booting environment"? I knew of EFI's much earlier than
I saw grub for the first time, so to me EFI's is more familiar if you
so will.

> Furthermore, it offers common management of /boot in the dom0 filesystem
> between legacy and EFI boots.

Which is an argument for porting suitable file system drivers to EFI,
not an argument to layer multiple boot loaders. Plus booting _is_
(naturally) different between platforms. Plus if EFI was ported to
architectures of interest (see ARM), the difference between
platforms would decrease too (which btw was one of the original
goals of EFI). Are you btw saying that ARM should use grub2 too?
I didn't hear that mentioned as a goal anywhere so far...

> Therefore I am very much +1 get grub working.

Then you kind of misunderstood: I'm not against getting grub2
working (i.e. patches prior to this one are fine in principle). What
I'm against is hacking around firmware+grub2 combinations not
suitable for Xen's purposes (where one could argue which of the
three is really at fault, and I'm far from convinced it's Xen).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]         ` <CAKcyEGpdnJUXA=uW4cNdcLn9xS7fUDowzzCbhn6c1yTh4WkPGg@mail.gmail.com>
@ 2015-08-28  8:22           ` Jan Beulich
       [not found]           ` <55E03676020000780009DAFB@prv-mh.provo.novell.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-28  8:22 UTC (permalink / raw)
  To: Ben Hildred
  Cc: Juergen Gross, The development of GNU GRUB, wei.liu2,
	Ian Campbell, Stefano Stabellini, andrew.cooper3, Daniel Kiper,
	Roy Franz, ning.sun, david.vrabel, Vladimir Serbinenko,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	Fu Wei

>>> On 27.08.15 at 19:56, <42656e@gmail.com> wrote:
>> If you advocate direct booting ( no boot loader)  on production machines I
> wont argue much, as long as there is good recovery tools to deal with
> failed boots (grub does this very well, I am not aware of anything
> comparable that is pure efi). however the other use case which care more
> about is dual booting. I am a novice when it comes to Xen, although
> otherwise competent. The test machines I have for playing with Xen are also
> used for other tests, some of which require raw hardware support, so I want
> the ability to use a boot menu.

All EFI systems that I've seen so far have a boot manager. Are you
saying there are vendors who remove that?

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]           ` <55E021C4020000780009DA95@prv-mh.provo.novell.com>
@ 2015-08-28 11:59             ` Andrew Cooper
  0 siblings, 0 replies; 116+ messages in thread
From: Andrew Cooper @ 2015-08-28 11:59 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, phcoder, Daniel Kiper, roy.franz, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On 28/08/15 07:54, Jan Beulich wrote:
>
>> Therefore I am very much +1 get grub working.
> Then you kind of misunderstood: I'm not against getting grub2
> working (i.e. patches prior to this one are fine in principle). What
> I'm against is hacking around firmware+grub2 combinations not
> suitable for Xen's purposes (where one could argue which of the
> three is really at fault, and I'm far from convinced it's Xen).

Irrespective of the EFI angle, there are other good reasons for making
Xens boot code position-independent and able to be located elsewhere.

The region of memory between 0x10000 and 0x10fffe is at increased risk
of clobbering from buggy firmwares.  I have submitted bugfixes to Xen
before, and there are further investigations which didn't result in
anything upstream.

Moving the Xen text section out of this high risk region would make even
legacy boot more reliable.  Currently IMO it is a Xen bug that it
strictly must be placed at the 1MB boundary to boot.

~Andrew

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]           ` <55E03676020000780009DAFB@prv-mh.provo.novell.com>
@ 2015-08-28 13:42             ` Konrad Rzeszutek Wilk
       [not found]             ` <20150828134214.GC2412@l.oracle.com>
  1 sibling, 0 replies; 116+ messages in thread
From: Konrad Rzeszutek Wilk @ 2015-08-28 13:42 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, The development of GNU GRUB, wei.liu2,
	Ian Campbell, Stefano Stabellini, andrew.cooper3, Daniel Kiper,
	ning.sun, Roy Franz, Ben Hildred, david.vrabel,
	Vladimir Serbinenko, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, Fu Wei

On Fri, Aug 28, 2015 at 02:22:46AM -0600, Jan Beulich wrote:
> >>> On 27.08.15 at 19:56, <42656e@gmail.com> wrote:
> >> If you advocate direct booting ( no boot loader)  on production machines I
> > wont argue much, as long as there is good recovery tools to deal with
> > failed boots (grub does this very well, I am not aware of anything
> > comparable that is pure efi). however the other use case which care more
> > about is dual booting. I am a novice when it comes to Xen, although
> > otherwise competent. The test machines I have for playing with Xen are also
> > used for other tests, some of which require raw hardware support, so I want
> > the ability to use a boot menu.
> 
> All EFI systems that I've seen so far have a boot manager. Are you
> saying there are vendors who remove that?

Worst. There are some where the boot managers <cough>certain families of 
AMI based BIOSes</cough> which delete all but the last boot entry to
only have _one_ boot entry per ESP. No DualBoot for you!

The 'boot manager' in question is an boot entry (F8 or F12), which does not
allow any changes (change the parameters, etc) - just select the entry.

Furthermore my recollection is Microsoft has a 'boot configuration manager'
after EFI boots - you hit F8 and you can select which options you want to
boot Windows with.

We need that functionality and we can't depend on EFI getting it right - 
hence need GRUB. It would be fantastic if everybody fixed their EFI firmware
but since some of these for SMI have 'O.E.M vendor should
put information here' (or whatever it says) - it makes me think they
don't care the sligthest after the product has been released.

And I am not comfortable to say 'GRUB2+Xen cannot run on this hardware
because your firmware vendor is not following the EFI spec in spirit.'

Now that said - do you have suggestions on how to make this work
with GRUB in the picture?

Thank you.

> Jan
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]             ` <20150828134214.GC2412@l.oracle.com>
@ 2015-08-28 14:16               ` Jan Beulich
  2015-08-31 19:49                 ` Daniel Kiper
       [not found]                 ` <20150831194956.GJ4530@olila.local.net-space.pl>
  0 siblings, 2 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-28 14:16 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: Juergen Gross, The development of GNU GRUB, wei.liu2,
	Ian Campbell, Stefano Stabellini, andrew.cooper3, Daniel Kiper,
	ning.sun, Roy Franz, Ben Hildred, david.vrabel,
	Vladimir Serbinenko, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, Fu Wei

>>> On 28.08.15 at 15:42, <konrad.wilk@oracle.com> wrote:
> And I am not comfortable to say 'GRUB2+Xen cannot run on this hardware
> because your firmware vendor is not following the EFI spec in spirit.'

Well, not the least since I don't really agree with this (albeit I can
see where you're coming from) ...

> Now that said - do you have suggestions on how to make this work
> with GRUB in the picture?

... I don't think I'm the one to make suggestions on how to make
things work with grub in the picture when I continue to be of the
opinion that it shouldn't have been brought into the picture in the
first place.

But for the purely technical (patch) aspect: Anything (e.g.
macroization such that at least some sym_phys() uses can remain
untouched) allowing to limit the impact of said patch on the source
code (thus helping review and perhaps also long term
maintainability) would be a step towards talking me into
withdrawing my objection.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]       ` <55DF48FB020000780009D83F@prv-mh.provo.novell.com>
                           ` (3 preceding siblings ...)
       [not found]         ` <CAKcyEGpdnJUXA=uW4cNdcLn9xS7fUDowzzCbhn6c1yTh4WkPGg@mail.gmail.com>
@ 2015-08-28 14:24         ` Jan Beulich
  4 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-08-28 14:24 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 27.08.15 at 17:29, <JBeulich@suse.com> wrote:
> You're right, there's no such requirement on memory use in the spec.
> But you're missing the point. Supporting grub2 on UEFI is already a
> hack (ignoring all intentions EFI had from its first days). And now
> you've found an environment where that hack needs another hack
> (in Xen) to actually work. That's too much hackery for my taste, the
> more that things on this system can (afaict) work quite okay (without
> grub2, or with using its chainloader mechanism).

It has been brought to my attention that the use of the work "hack"
above could have been understood as an offense. It certainly
wasn't meant so, and I'd like to apologize if it came over that way. I
simply used it not finding a better term while writing; perhaps I could
have used "misguided" and "workaround" respectively, but I'm not
sure that would have been received much better.

In any event - I didn't mean to insult you or anyone else.

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
  2015-08-28 14:16               ` Jan Beulich
@ 2015-08-31 19:49                 ` Daniel Kiper
       [not found]                 ` <20150831194956.GJ4530@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-08-31 19:49 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, The development of GNU GRUB, wei.liu2,
	Ian Campbell, Stefano Stabellini, andrew.cooper3, ning.sun,
	Roy Franz, Ben Hildred, david.vrabel, Vladimir Serbinenko,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	Fu Wei

On Fri, Aug 28, 2015 at 08:16:05AM -0600, Jan Beulich wrote:
> >>> On 28.08.15 at 15:42, <konrad.wilk@oracle.com> wrote:
> > And I am not comfortable to say 'GRUB2+Xen cannot run on this hardware
> > because your firmware vendor is not following the EFI spec in spirit.'
>
> Well, not the least since I don't really agree with this (albeit I can
> see where you're coming from) ...
>
> > Now that said - do you have suggestions on how to make this work
> > with GRUB in the picture?
>
> ... I don't think I'm the one to make suggestions on how to make
> things work with grub in the picture when I continue to be of the
> opinion that it shouldn't have been brought into the picture in the
> first place.

Could you be more specific what is wrong with this patch or at least last
hunk which you reviewed? What is real technical reason that it could not
be accepted? If idea is wrong in general please tell me where and why.
Otherwise I am not able to work out other better solution.

By the way, once I have put 3 (IIRC) proposals for this problem on the table.
Even we discussed this issue in Shanghai. You and Andrew approved more or
less this one. So, I am a bit disappointed that you withdraw your approval
(yes, partial but still the approval) at this stage with just vague explanations.
Though I am not trying to argue that this patch is fully correct. For sure
it could be improved but I do not think that this invalidates idea as whole.

> But for the purely technical (patch) aspect: Anything (e.g.
> macroization such that at least some sym_phys() uses can remain
> untouched) allowing to limit the impact of said patch on the source
> code (thus helping review and perhaps also long term
> maintainability) would be a step towards talking me into
> withdrawing my objection.

Ditto. This is too vague. So, I will be very grateful if you review this
patch until the end or at least tell me what (if you add why it will be
nice) exactly should be fixed.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 22/23] x86: make Xen early boot code relocatable
       [not found]                 ` <20150831194956.GJ4530@olila.local.net-space.pl>
@ 2015-09-01  6:59                   ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-09-01  6:59 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, The development of GNU GRUB, wei.liu2,
	Ian Campbell, Stefano Stabellini, andrew.cooper3, ning.sun,
	Roy Franz, Ben Hildred, david.vrabel, Vladimir Serbinenko,
	xen-devel, qiaowei.ren, keir, richard.l.maliszewski, gang.wei,
	Fu Wei

>>> On 31.08.15 at 21:49, <daniel.kiper@oracle.com> wrote:
> On Fri, Aug 28, 2015 at 08:16:05AM -0600, Jan Beulich wrote:
>> >>> On 28.08.15 at 15:42, <konrad.wilk@oracle.com> wrote:
>> > Now that said - do you have suggestions on how to make this work
>> > with GRUB in the picture?
>>
>> ... I don't think I'm the one to make suggestions on how to make
>> things work with grub in the picture when I continue to be of the
>> opinion that it shouldn't have been brought into the picture in the
>> first place.
> 
> Could you be more specific what is wrong with this patch or at least last
> hunk which you reviewed? What is real technical reason that it could not
> be accepted? If idea is wrong in general please tell me where and why.
> Otherwise I am not able to work out other better solution.

The patch may not be wrong technically (and I never said so), it is
just that the way you carry things out is too intrusive for my taste.
Since Andrew is happy with the change in principle, I think I wouldn't
veto it going in with his R-b.

> By the way, once I have put 3 (IIRC) proposals for this problem on the 
> table.
> Even we discussed this issue in Shanghai. You and Andrew approved more or
> less this one. So, I am a bit disappointed that you withdraw your approval
> (yes, partial but still the approval) at this stage with just vague 
> explanations.

I've never approved of anything here. At the hackathon we've only
hashed out possible options.

>> But for the purely technical (patch) aspect: Anything (e.g.
>> macroization such that at least some sym_phys() uses can remain
>> untouched) allowing to limit the impact of said patch on the source
>> code (thus helping review and perhaps also long term
>> maintainability) would be a step towards talking me into
>> withdrawing my objection.
> 
> Ditto. This is too vague. So, I will be very grateful if you review this
> patch until the end or at least tell me what (if you add why it will be
> nice) exactly should be fixed.

How is this to vague? I gave a possible direction (macroization) as
well as the criteria (less impact on existing code; to be slightly more
precise I'd specifically like to see most of the open coded %fs: uses
gone).

Again - if Andrew thinks this is the right thing to do, I'll defer to him
for reviewing these final few patches of the series, since as said
before to me this is a workaround for a misguided design, and as
such I'm not willing to accept as intrusive a patch as this one is. (And
no, I don't really buy his argument of Xen boot code needing to be
relocatable anyway - the legacy boot path doesn't really need to
fear there not being free memory right above 1Mb. At least I have
seen no proof of there being any system [supporting legacy boot]
where Xen can't boot that way. And even if there was, it would
still need to be determined whether this is legitimately so, or again
due to poorly written firmware.)

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
       [not found]   ` <55DF1836020000780009D674@prv-mh.provo.novell.com>
@ 2015-09-22 15:21     ` Daniel Kiper
  2015-09-22 15:58       ` Jan Beulich
  0 siblings, 1 reply; 116+ messages in thread
From: Daniel Kiper @ 2015-09-22 15:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Aug 27, 2015 at 06:01:26AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> For a patch of this size, no description at all seems rather
> problematic.
>
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -89,6 +89,13 @@ multiboot1_header_end:
> >                     0, /* Number of the lines - no preference. */ \
> >                     0  /* Number of bits per pixel - no preference. */
> >
> > +        /* Do not disable EFI boot services. */
> > +        mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
> > +
> > +        /* EFI64 entry point. */
> > +        mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
> > +                   sym_phys(__efi64_start)
>
> Iirc at least one of those two is what upstream doesn't have yet,
> or not all earlier grub2 versions might have. If so - what happens
> if the resulting Xen gets booted on an incapable grub? Silent death
> (with black screen)? Or at least some note to the user that the
> grub2 version is not suitable?

There is the code below which sends relevant message to COM1 and...
...well, VGA which of course does not make sense and should be fixed.

> > @@ -130,6 +146,119 @@ print_err:
> >  .Lhalt: hlt
> >          jmp     .Lhalt
> >
> > +        .code64
> > +
> > +__efi64_start:
> > +        cld
> > +
> > +        /* Check for Multiboot2 bootloader. */
> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +        je      efi_multiboot2_proto
> > +
> > +        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
> > +        lea     not_multiboot(%rip),%rdi
> > +        jmp     x86_32_switch
> > +
> > +efi_multiboot2_proto:
>
> .L

Why do you want to hide labels which could be useful during debugging?

> > +run_bs:
>
> Again.

Ditto.

> > +x86_32_switch:
> > +        cli
> > +
> > +        /* Initialise GDT. */
> > +        lgdt    gdt_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
>
> I see no point in loading %fs and %gs with other than nul selectors.
> I also think %ss should be loaded first. Which reminds me - what
> about %rsp? Is it guaranteed to have its upper 32 bits clear, so you
> can re-use the stack in 32-bit mode? (If it is, saying so in a comment
> would be very desirable.)

I am not reusing %rsp value. %esp is initialized later in 32-bit code.
Stack is not used until %esp is not initialized.

[...]

> > --- a/xen/common/efi/boot.c
> > +++ b/xen/common/efi/boot.c
> > @@ -79,6 +79,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);
>
> This is ugly; I'm sure there is a way to avoid these declarations.

This probably requires play with '#include "efi-boot.h"' and move
somewhere before efi_start(). Maybe something else. If it is not
a problem for you I can do that.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms
  2015-09-22 15:21     ` Daniel Kiper
@ 2015-09-22 15:58       ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-09-22 15:58 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 22.09.15 at 17:21, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 27, 2015 at 06:01:26AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> > @@ -130,6 +146,119 @@ print_err:
>> >  .Lhalt: hlt
>> >          jmp     .Lhalt
>> >
>> > +        .code64
>> > +
>> > +__efi64_start:
>> > +        cld
>> > +
>> > +        /* Check for Multiboot2 bootloader. */
>> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
>> > +        je      efi_multiboot2_proto
>> > +
>> > +        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
>> > +        lea     not_multiboot(%rip),%rdi
>> > +        jmp     x86_32_switch
>> > +
>> > +efi_multiboot2_proto:
>>
>> .L
> 
> Why do you want to hide labels which could be useful during debugging?

With a few exceptions, assembly code should follow C and other
high level languages: Symbol table entries only at function
boundaries (or whatever their suitable counterparts in assembly
are).

>> > +x86_32_switch:
>> > +        cli
>> > +
>> > +        /* Initialise GDT. */
>> > +        lgdt    gdt_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
>>
>> I see no point in loading %fs and %gs with other than nul selectors.
>> I also think %ss should be loaded first. Which reminds me - what
>> about %rsp? Is it guaranteed to have its upper 32 bits clear, so you
>> can re-use the stack in 32-bit mode? (If it is, saying so in a comment
>> would be very desirable.)
> 
> I am not reusing %rsp value. %esp is initialized later in 32-bit code.
> Stack is not used until %esp is not initialized.

If you load %ss without loading the stack pointer, you should imo
at least add a comment saying when/where the other half will be
done.

>> > --- a/xen/common/efi/boot.c
>> > +++ b/xen/common/efi/boot.c
>> > @@ -79,6 +79,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);
>>
>> This is ugly; I'm sure there is a way to avoid these declarations.
> 
> This probably requires play with '#include "efi-boot.h"' and move
> somewhere before efi_start(). Maybe something else. If it is not
> a problem for you I can do that.

Indeed moving an #include would seem far better than adding almost
a dozen declarations (any of which will need to get touched if the
respective definition changes, i.e. arranging for future churn).

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found]   ` <55DF221B020000780009D6C6@prv-mh.provo.novell.com>
@ 2015-09-22 17:03     ` Daniel Kiper
       [not found]     ` <20150922170332.GH3501@olila.local.net-space.pl>
  1 sibling, 0 replies; 116+ messages in thread
From: Daniel Kiper @ 2015-09-22 17:03 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Aug 27, 2015 at 06:43:39AM -0600, Jan Beulich wrote:
> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
> > Current early command line parser implementation in assembler
> > is very difficult to change to relocatable stuff using segment
> > registers. This requires a lot of changes in very weird and
> > fragile code. So, reimplement this functionality in C. This
> > way code will be relocatable out of the box and much easier
> > to maintain.
>
> All appreciated and nice, but the goal of making the code
> relocatable by playing with segment registers sounds fragile:
> This breaks assumptions the compiler may validly make.

Well, it looks that this sentence is not precise. I should fix this.
Anyway, I am not playing with segment registers in C code because
it is not needed and as you pointed out it is dangerous.

> >  xen/arch/x86/boot/cmdline.S    |  367 -------------------------------------
> >  xen/arch/x86/boot/cmdline.c    |  396 ++++++++++++++++++++++++++++++++++++++++
>
> A fundamental expectation I would have had is for the C file to be
> noticeably smaller than the assembly file.
>
> > --- /dev/null
> > +++ b/xen/arch/x86/boot/cmdline.c
> >[...]
> > +#define VESA_WIDTH	0
> > +#define VESA_HEIGHT	1
> > +#define VESA_DEPTH	2
> > +
> > +#define VESA_SIZE	3
>
> These should go away in favor of using individual (sub)structure fields.
>
> > +#define __cdecl		__attribute__((__cdecl__))
>
> ???

Please look below.

> > +#define __packed	__attribute__((__packed__))
> > +#define __text		__attribute__((__section__(".text")))
> > +#define __used		__attribute__((__used__))
>
> Likely better to include compiler.h instead.

As I know you do not like to include such headers in early C files
because it makes code fragile and it looks strange. I agree with you
to some extent. So, I decided to define needed constants ourselves.
Whatever we do we should be consistent. Hence, if we include compiler.h
here we should do the same in reloc.c too if it is required.

> > +#define max(x,y) ({ \
> > +        const typeof(x) _x = (x);       \
> > +        const typeof(y) _y = (y);       \
> > +        (void) (&_x == &_y);            \
> > +        _x > _y ? _x : _y; })
>
> I also wonder whether -imacros .../xen/kernel.h wouldn't be a better
> approach here. Please really think hard on how to avoid duplications
> like these.

Ditto. So, what is your decision? Include or define? If include then
we should think how to generate relevant dependencies automatically.

> > +#define strlen_static(s) (sizeof(s) - 1)
>
> What is this good for? A decent compiler should be able to deal with
> strlen("..."). Plus your macro is longer that what it tries to "abbreviate".

I thought that it is true but it is not. Sadly, without this binary is bigger... :-(((
However, you are right that the name could be better.

> > +static const char empty_chars[] __text = " \n\r\t";
>
> What is empty about them? DYM blank or (white) space or separator
> or delimiter? I also wonder whether \n and \r are actually usefully here,

Yep, delimiter or something like that looks better.

> as they should (if at all) only end the line.

Yes, I included them just in case and they should not appear in command line.

> > +static const char *find_opt(const char *cmdline, const char *opt, int arg)
> > +{
> > +    size_t lc, lo;
> > +    static const char mm[] __text = "--";
>
> I'd be surprised if there weren't compiler/assembler versions
> complaining about a section type conflict here. I can see why you
> want everything in one section, but I'd rather suggest achieving
> this at the linking step (which I would suppose to already be taking
> care of this).

Nope, it does not work in that way. However, I discovered that newer GCC
versions generate .rodata for switch/case. So, anyway we must cope with
at least two different sections and link them properly.

> > +static u8 skip_realmode(const char *cmdline)
> > +{
> > +    static const char nrm[] __text = "no-real-mode";
> > +    static const char tboot[] __text = "tboot=";
> > +
> > +    if ( find_opt(cmdline, nrm, 0) || find_opt(cmdline, tboot, 1) )
> > +        return 1;
> > +
> > +    return 0;
>
> return find_opt(cmdline, nrm, 0) || find_opt(cmdline, tboot, 1);
>
> > +static u8 edd_parse(const char *cmdline)
> > +{
> > +    const char *c;
> > +    size_t la;
> > +    static const char edd[] __text = "edd=";
> > +    static const char edd_off[] __text = "off";
> > +    static const char edd_skipmbr[] __text = "skipmbr";
> > +
> > +    c = find_opt(cmdline, edd, 1);
> > +
> > +    if ( !c )
> > +        return 0;
> > +
> > +    c += strlen_static(edd);
> > +    la = strcspn(c, empty_chars);
> > +
> > +    if ( !strncmp(c, edd_off, max(la, strlen_static(edd_off))) )
> > +        return 2;
> > +    else if ( !strncmp(c, edd_skipmbr, max(la, strlen_static(edd_skipmbr))) )
>
> Pointless else.
>
> > +        return 1;
> > +
> > +    return 0;
>
> And the last two returns can be folded again anyway.
>
> > +static void __cdecl __used cmdline_parse_early(const char *cmdline, early_boot_opts_t *ebo)
>
> I don't see the point of the __cdecl, and (as said before) dislike the
> static __used pair.

Are you sure that without __cdecl compiler will not try to optimize
cmdline_parse_early() call and try to pass arguments using registers
or anything else not conforming to cdecl calling convention? Right
now I am not sure about that. However, I suppose that if we remove
static then there is a chance that function will be always called
according to cdecl (I must check this). Anyway, I think that we
should retain (even add in case of reloc.c:reloc(), others?) __cdecl
before 32-bit functions which are called from assembly. Just in case.

Daniel

^ permalink raw reply	[flat|nested] 116+ messages in thread

* Re: [PATCH v2 21/23] x86/boot: implement early command line parser in C
       [not found]     ` <20150922170332.GH3501@olila.local.net-space.pl>
@ 2015-09-23  7:25       ` Jan Beulich
  0 siblings, 0 replies; 116+ messages in thread
From: Jan Beulich @ 2015-09-23  7:25 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, grub-devel, wei.liu2, ian.campbell,
	stefano.stabellini, andrew.cooper3, roy.franz, ning.sun,
	david.vrabel, phcoder, xen-devel, qiaowei.ren, keir,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 22.09.15 at 19:03, <daniel.kiper@oracle.com> wrote:
> On Thu, Aug 27, 2015 at 06:43:39AM -0600, Jan Beulich wrote:
>> >>> On 20.07.15 at 16:29, <daniel.kiper@oracle.com> wrote:
>> > +#define __packed	__attribute__((__packed__))
>> > +#define __text		__attribute__((__section__(".text")))
>> > +#define __used		__attribute__((__used__))
>>
>> Likely better to include compiler.h instead.
> 
> As I know you do not like to include such headers in early C files
> because it makes code fragile and it looks strange. I agree with you
> to some extent. So, I decided to define needed constants ourselves.
> Whatever we do we should be consistent. Hence, if we include compiler.h
> here we should do the same in reloc.c too if it is required.

I disagree - reloc.c serves a completely different purpose, and
hence may have different considerations applied when it comes
to what to (not) include.

>> > +#define max(x,y) ({ \
>> > +        const typeof(x) _x = (x);       \
>> > +        const typeof(y) _y = (y);       \
>> > +        (void) (&_x == &_y);            \
>> > +        _x > _y ? _x : _y; })
>>
>> I also wonder whether -imacros .../xen/kernel.h wouldn't be a better
>> approach here. Please really think hard on how to avoid duplications
>> like these.
> 
> Ditto. So, what is your decision? Include or define? If include then
> we should think how to generate relevant dependencies automatically.

I think the question should rather be whether we can't make cmdline.c
build the normal way, not the reloc.c one.

>> > +#define strlen_static(s) (sizeof(s) - 1)
>>
>> What is this good for? A decent compiler should be able to deal with
>> strlen("..."). Plus your macro is longer that what it tries to "abbreviate".
> 
> I thought that it is true but it is not. Sadly, without this binary is 
> bigger... :-(((

Perhaps as a result of some (missing) option(s)?

> However, you are right that the name could be better.

Or just drop the macro.

>> > +static const char empty_chars[] __text = " \n\r\t";
>>
>> What is empty about them? DYM blank or (white) space or separator
>> or delimiter? I also wonder whether \n and \r are actually usefully here,
> 
> Yep, delimiter or something like that looks better.
> 
>> as they should (if at all) only end the line.
> 
> Yes, I included them just in case and they should not appear in command 
> line.

If you mean to retain characters in that array that aren't obviously
needed, please explain such in a comment so people won't have to
guess whether to delete them, or will know it is (relatively) safe to
delete them in case their presence causes problems. But even better
would be to just have the obvious blank characters (space and tab)
there.

>> > +static void __cdecl __used cmdline_parse_early(const char *cmdline, 
> early_boot_opts_t *ebo)
>>
>> I don't see the point of the __cdecl, and (as said before) dislike the
>> static __used pair.
> 
> Are you sure that without __cdecl compiler will not try to optimize
> cmdline_parse_early() call and try to pass arguments using registers
> or anything else not conforming to cdecl calling convention?

Yes, I am - the moment you drop the "static". At that point the
compiler has no choice, unless it is being told on the command line
to use a different calling convention

Jan

^ permalink raw reply	[flat|nested] 116+ messages in thread

end of thread, other threads:[~2015-09-23  7:25 UTC | newest]

Thread overview: 116+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1437402558-7313-1-git-send-email-daniel.kiper@oracle.com>
2015-07-20 14:28 ` [PATCH v2 01/23] x86/boot: remove unneeded instruction Daniel Kiper
2015-07-20 14:28 ` [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file Daniel Kiper
2015-07-20 14:28 ` [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb Daniel Kiper
2015-07-20 14:28 ` [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 06/23] x86/boot: use %ecx instead of %eax Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 08/23] x86: add multiboot2 protocol support Daniel Kiper
2015-08-10 19:17   ` Konrad Rzeszutek Wilk
     [not found]   ` <20150810191747.GE13576@l.oracle.com>
2015-08-13 19:22     ` Daniel Kiper
     [not found]     ` <20150813192212.GI3503@olila.local.net-space.pl>
2015-08-14 10:03       ` Jan Beulich
     [not found]       ` <55CDD8F4020000780009AF3C@prv-mh.provo.novell.com>
2015-08-15  6:00         ` Andrew Cooper
2015-08-18  8:12   ` Jan Beulich
2015-08-18 12:00     ` Daniel Kiper
2015-08-18 14:20       ` Jan Beulich
2015-07-20 14:29 ` [PATCH v2 09/23] efi: create efi_enabled() Daniel Kiper
2015-08-10 19:20   ` Konrad Rzeszutek Wilk
2015-08-20 15:18   ` Jan Beulich
2015-08-22 12:33     ` Daniel Kiper
     [not found]     ` <20150822123359.GX7143@olila.local.net-space.pl>
2015-08-24 11:29       ` Jan Beulich
2015-07-20 14:29 ` [PATCH v2 10/23] efi: build xen.gz with EFI code Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 11/23] efi: split out efi_init() Daniel Kiper
2015-08-10 19:25   ` Konrad Rzeszutek Wilk
2015-07-20 14:29 ` [PATCH v2 12/23] efi: split out efi_console_set_mode() Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 13/23] efi: split out efi_get_gop() Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 14/23] efi: split out efi_find_gop_mode() Daniel Kiper
2015-08-10 19:31   ` Konrad Rzeszutek Wilk
2015-08-20 15:48   ` Jan Beulich
2015-07-20 14:29 ` [PATCH v2 15/23] efi: split out efi_tables() Daniel Kiper
2015-08-10 19:32   ` Konrad Rzeszutek Wilk
2015-07-20 14:29 ` [PATCH v2 16/23] efi: split out efi_variables() Daniel Kiper
2015-08-10 19:34   ` Konrad Rzeszutek Wilk
2015-07-20 14:29 ` [PATCH v2 17/23] efi: split out efi_set_gop_mode() Daniel Kiper
2015-08-10 19:34   ` Konrad Rzeszutek Wilk
2015-07-20 14:29 ` [PATCH v2 18/23] efi: split out efi_exit_boot() Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 19/23] x86/efi: create new early memory allocator Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 20/23] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
2015-08-10 20:07   ` Konrad Rzeszutek Wilk
2015-08-11 15:23   ` Konrad Rzeszutek Wilk
2015-08-27 12:01   ` Jan Beulich
     [not found]   ` <55DF1836020000780009D674@prv-mh.provo.novell.com>
2015-09-22 15:21     ` Daniel Kiper
2015-09-22 15:58       ` Jan Beulich
2015-07-20 14:29 ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 22/23] x86: make Xen early boot code relocatable Daniel Kiper
2015-07-20 14:29 ` [PATCH v2 23/23] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
2015-08-11 16:56   ` Konrad Rzeszutek Wilk
     [not found]   ` <20150811165658.GC32231@l.oracle.com>
2015-08-14 11:57     ` Daniel Kiper
     [not found]     ` <20150814115701.GB8034@olila.local.net-space.pl>
2015-08-14 13:43       ` Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-3-git-send-email-daniel.kiper@oracle.com>
2015-07-21  9:35   ` [PATCH v2 02/23] x86/boot: copy only text section from *.lnk file to *.bin file Jan Beulich
2015-07-21 17:23     ` Daniel Kiper
2015-07-22  5:14       ` Jan Beulich
2015-07-22  8:02       ` Jan Beulich
2015-07-22 13:31         ` Daniel Kiper
2015-07-22 14:07           ` Jan Beulich
     [not found] ` <1437402558-7313-4-git-send-email-daniel.kiper@oracle.com>
2015-07-21  9:37   ` [PATCH v2 03/23] x86: zero BSS using stosl instead of stosb Jan Beulich
2015-07-21 18:23     ` Daniel Kiper
2015-07-22  5:18       ` Jan Beulich
2015-07-22  8:42         ` Andrew Cooper
2015-07-22 10:04           ` Jan Beulich
2015-07-22 11:22             ` Andrew Cooper
2015-07-22 11:48               ` Jan Beulich
2015-07-21  9:39 ` [PATCH v2 00/23] x86: multiboot2 protocol support Jan Beulich
     [not found] ` <1437402558-7313-2-git-send-email-daniel.kiper@oracle.com>
2015-07-24 16:22   ` [PATCH v2 01/23] x86/boot: remove unneeded instruction Konrad Rzeszutek Wilk
     [not found]   ` <20150724162257.GB2220@l.oracle.com>
2015-07-27 19:46     ` Daniel Kiper
     [not found]     ` <20150727194608.GB3492@olila.local.net-space.pl>
2015-08-10 16:07       ` Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-5-git-send-email-daniel.kiper@oracle.com>
2015-08-10 16:33   ` [PATCH v2 04/23] x86/boot: call reloc() using cdecl calling convention Konrad Rzeszutek Wilk
2015-08-17 15:44   ` Jan Beulich
     [not found] ` <1437402558-7313-7-git-send-email-daniel.kiper@oracle.com>
2015-08-10 16:36   ` [PATCH v2 06/23] x86/boot: use %ecx instead of %eax Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-8-git-send-email-daniel.kiper@oracle.com>
2015-08-10 16:40   ` [PATCH v2 07/23] x86/boot/reloc: Rename some variables and rearrange code a bit Konrad Rzeszutek Wilk
2015-08-17 15:55   ` Jan Beulich
     [not found] ` <1437402558-7313-11-git-send-email-daniel.kiper@oracle.com>
2015-08-10 19:24   ` [PATCH v2 10/23] efi: build xen.gz with EFI code Konrad Rzeszutek Wilk
2015-08-20 15:39   ` Jan Beulich
2015-08-22 13:59     ` Daniel Kiper
     [not found]     ` <20150822135919.GY7143@olila.local.net-space.pl>
2015-08-24 11:35       ` Jan Beulich
2015-08-24 20:54         ` Daniel Kiper
     [not found]         ` <20150824205445.GG7143@olila.local.net-space.pl>
2015-08-25 10:50           ` Andrew Cooper
2015-08-25 12:09           ` Jan Beulich
     [not found]           ` <55DC485D.4030904@citrix.com>
2015-08-25 15:39             ` Daniel Kiper
     [not found]           ` <55DC7705020000780009CE76@prv-mh.provo.novell.com>
2015-08-25 16:31             ` Daniel Kiper
     [not found]             ` <20150825163141.GJ7143@olila.local.net-space.pl>
2015-08-26  6:46               ` Jan Beulich
     [not found]               ` <55DD7CDE020000780009D086@prv-mh.provo.novell.com>
2015-08-26 12:33                 ` Daniel Kiper
     [not found]                 ` <20150826123356.GB10861@olila.local.net-space.pl>
2015-08-26 12:40                   ` Jan Beulich
     [not found]                   ` <55DDCFD6020000780009D226@prv-mh.provo.novell.com>
2015-08-26 12:58                     ` Daniel Kiper
     [not found] ` <1437402558-7313-13-git-send-email-daniel.kiper@oracle.com>
2015-08-10 19:25   ` [PATCH v2 12/23] efi: split out efi_console_set_mode() Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-14-git-send-email-daniel.kiper@oracle.com>
2015-08-10 19:27   ` [PATCH v2 13/23] efi: split out efi_get_gop() Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-19-git-send-email-daniel.kiper@oracle.com>
2015-08-10 19:36   ` [PATCH v2 18/23] efi: split out efi_exit_boot() Konrad Rzeszutek Wilk
     [not found] ` <1437402558-7313-20-git-send-email-daniel.kiper@oracle.com>
2015-08-10 19:49   ` [PATCH v2 19/23] x86/efi: create new early memory allocator Konrad Rzeszutek Wilk
2015-08-27 11:23   ` Jan Beulich
     [not found] ` <1437402558-7313-6-git-send-email-daniel.kiper@oracle.com>
2015-08-17 15:51   ` [PATCH v2 05/23] x86/boot/reloc: create generic alloc and copy functions Jan Beulich
     [not found]   ` <55D21F3E020000780009B716@prv-mh.provo.novell.com>
2015-08-17 22:03     ` Daniel Kiper
     [not found] ` <1437402558-7313-22-git-send-email-daniel.kiper@oracle.com>
2015-08-10 20:31   ` [PATCH v2 21/23] x86/boot: implement early command line parser in C Konrad Rzeszutek Wilk
2015-08-11 14:43   ` Konrad Rzeszutek Wilk
2015-08-27 12:43   ` Jan Beulich
     [not found]   ` <55DF221B020000780009D6C6@prv-mh.provo.novell.com>
2015-09-22 17:03     ` Daniel Kiper
     [not found]     ` <20150922170332.GH3501@olila.local.net-space.pl>
2015-09-23  7:25       ` Jan Beulich
     [not found] ` <1437402558-7313-23-git-send-email-daniel.kiper@oracle.com>
2015-08-11 16:48   ` [PATCH v2 22/23] x86: make Xen early boot code relocatable Konrad Rzeszutek Wilk
     [not found]   ` <20150811164806.GB32231@l.oracle.com>
2015-08-14 11:52     ` Daniel Kiper
     [not found]     ` <20150814115205.GA8034@olila.local.net-space.pl>
2015-08-14 12:49       ` Jan Beulich
     [not found]       ` <55CDFFEE020000780009B0B0@prv-mh.provo.novell.com>
2015-08-14 13:59         ` Daniel Kiper
     [not found]         ` <20150814135904.GC8034@olila.local.net-space.pl>
2015-08-14 14:32           ` Jan Beulich
     [not found]           ` <55CE1805020000780009B1C0@prv-mh.provo.novell.com>
2015-08-14 14:37             ` Daniel Kiper
     [not found]             ` <20150814143729.GE8034@olila.local.net-space.pl>
2015-08-14 15:12               ` Jan Beulich
2015-08-14 15:20       ` Konrad Rzeszutek Wilk
2015-08-27 13:12   ` Jan Beulich
     [not found]   ` <55DF28E6020000780009D6E4@prv-mh.provo.novell.com>
2015-08-27 15:10     ` Daniel Kiper
     [not found]     ` <20150827151054.GI10944@olila.local.net-space.pl>
2015-08-27 15:29       ` Jan Beulich
     [not found]       ` <55DF48FB020000780009D83F@prv-mh.provo.novell.com>
2015-08-27 17:56         ` Ben Hildred
2015-08-27 18:04         ` Andrew Cooper
     [not found]         ` <55DF5125.20708@citrix.com>
2015-08-28  6:54           ` Jan Beulich
     [not found]           ` <55E021C4020000780009DA95@prv-mh.provo.novell.com>
2015-08-28 11:59             ` Andrew Cooper
     [not found]         ` <CAKcyEGpdnJUXA=uW4cNdcLn9xS7fUDowzzCbhn6c1yTh4WkPGg@mail.gmail.com>
2015-08-28  8:22           ` Jan Beulich
     [not found]           ` <55E03676020000780009DAFB@prv-mh.provo.novell.com>
2015-08-28 13:42             ` Konrad Rzeszutek Wilk
     [not found]             ` <20150828134214.GC2412@l.oracle.com>
2015-08-28 14:16               ` Jan Beulich
2015-08-31 19:49                 ` Daniel Kiper
     [not found]                 ` <20150831194956.GJ4530@olila.local.net-space.pl>
2015-09-01  6:59                   ` Jan Beulich
2015-08-28 14:24         ` Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).