xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/16] x86: multiboot2 protocol support
@ 2016-04-15 12:33 Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 01/16] x86/boot: do not create unwind tables Daniel Kiper
                   ` (15 more replies)
  0 siblings, 16 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Hi,

I am sending, long awaited, third version of multiboot2 protocol
support for legacy BIOS and EFI platforms. It fixes all major issues
discovered until now. There are still some minor problems which should
be fixed in one way or another. I will address them in next releases.

The final goal is xen.efi binary file which could be loaded by EFI
loader, multiboot (v1) protocol (only on legacy BIOS platforms) and
multiboot2 protocol. This way we will have:
  - smaller Xen code base,
  - one code base for xen.gz and xen.efi,
  - one build method for xen.gz and xen.efi;
    xen.efi will be extracted from xen(-syms)
    file using objcopy or special custom tool,
  - xen.efi build will not so strongly depend
    on a given GCC and binutils version.

Here are short list of changes:
  - new patches: 01, 07, 09,
  - changed patches: 02, 03, 04, 06, 08, 10, 11, 13, 14, 15, 16,
  - RFC patches: 12, 13, 15; if it is needed we could discuss at
    least #12 and #15 at Xen Project Hackathon in Cambridge.

This patch series was build with following tools:
  - gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
    and binutils 2.17-3+etch1,
  - gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
    and binutils 2.23.2-2.el6,
  - gcc version 4.7.2 (Debian 4.7.2-5)
    and binutils 2.22-8,
  - gcc version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC)
    and binutils 2.25-9.fc22.

I hope that starting from now there will be faster turnaround
of this patch series.

If you are not interested in this patch series at all please
drop me a line and I will remove you from distribution list.

Daniel

 .gitignore                        |    5 +-
 xen/arch/x86/Makefile             |    8 +-
 xen/arch/x86/Rules.mk             |    4 +
 xen/arch/x86/boot/Makefile        |   10 +-
 xen/arch/x86/boot/build32.lds     |   50 +++++++++
 xen/arch/x86/boot/build32.mk      |   14 ++-
 xen/arch/x86/boot/cmdline.S       |  367 --------------------------------------------------------------
 xen/arch/x86/boot/cmdline.c       |  357 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/edd.S           |    3 -
 xen/arch/x86/boot/head.S          |  481 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 xen/arch/x86/boot/reloc.c         |  246 +++++++++++++++++++++++++++++++++++-------
 xen/arch/x86/boot/trampoline.S    |   18 +++-
 xen/arch/x86/boot/video.S         |    6 --
 xen/arch/x86/boot/wakeup.S        |    6 +-
 xen/arch/x86/boot/x86_64.S        |   44 +++-----
 xen/arch/x86/dmi_scan.c           |    4 +-
 xen/arch/x86/domain_page.c        |    2 +-
 xen/arch/x86/efi/Makefile         |   11 +-
 xen/arch/x86/efi/efi-boot.h       |   81 ++++++++++++--
 xen/arch/x86/efi/stub.c           |   16 ++-
 xen/arch/x86/mpparse.c            |    4 +-
 xen/arch/x86/setup.c              |   61 ++++++-----
 xen/arch/x86/shutdown.c           |    2 +-
 xen/arch/x86/time.c               |    2 +-
 xen/arch/x86/x86_64/asm-offsets.c |   10 ++
 xen/arch/x86/xen.lds.S            |    7 +-
 xen/common/efi/boot.c             |   19 ++++
 xen/common/efi/runtime.c          |   23 ++--
 xen/drivers/acpi/osl.c            |    2 +-
 xen/include/asm-x86/config.h      |    1 +
 xen/include/asm-x86/page.h        |    2 +-
 xen/include/xen/efi.h             |   13 ++-
 xen/include/xen/multiboot2.h      |  182 +++++++++++++++++++++++++++++++
 33 files changed, 1491 insertions(+), 570 deletions(-)

Daniel Kiper (16):
      x86/boot: do not create unwind tables
      x86: zero BSS using stosl instead of stosb
      x86/boot: call reloc() using cdecl calling convention
      x86/boot/reloc: create generic alloc and copy functions
      x86/boot: use %ecx instead of %eax
      x86/boot/reloc: Rename some variables and rearrange code a bit
      x86/boot: create *.lnk files with linker script
      x86: add multiboot2 protocol support
      efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
      efi: create efi_enabled()
      efi: build xen.gz with EFI code
      x86/efi: create new early memory allocator
      x86: add multiboot2 protocol support for EFI platforms
      x86/boot: implement early command line parser in C
      x86: make Xen early boot code relocatable
      x86: add multiboot2 protocol support for relocatable images


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

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

* [PATCH v3 01/16] x86/boot: do not create unwind tables
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 15:45   ` Andrew Cooper
  2016-04-15 12:33 ` [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb Daniel Kiper
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

This way .eh_frame section is not included in *.lnk and *.bin files.
Hence, final e.g. reloc.bin file size is reduced from 408 bytes to
272 bytes and it contains only used code and data.

Suggested-by: Jan Beulich <jbeulich@suse.com>
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 4a1421f..4a7d388 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -4,7 +4,7 @@ include $(XEN_ROOT)/Config.mk
 
 $(call cc-options-add,CFLAGS,CC,$(EMBEDDED_EXTRA_CFLAGS))
 
-CFLAGS += -Werror -fno-builtin -msoft-float
+CFLAGS += -Werror -fno-asynchronous-unwind-tables -fno-builtin -msoft-float
 CFLAGS := $(filter-out -flto,$(CFLAGS)) 
 
 # NB. awk invocation is a portable alternative to 'head -n -1'
-- 
1.7.10.4


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

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

* [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 01/16] x86/boot: do not create unwind tables Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 13:57   ` Konrad Rzeszutek Wilk
  2016-04-15 15:48   ` Andrew Cooper
  2016-04-15 12:33 ` [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
                   ` (13 subsequent siblings)
  15 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Speedup BSS initialization by using stosl instead of stosb.

Some may argue that Intel Ivy Bridge and later provide ERMSB feature.
This means that "rep stosb" gives better throughput than "rep stosl" on
above mentioned CPUs. However, this feature is only available on newer
Intel processors and e.g. AMD does not provide it at all. So, stosb will
just give real benefits and even beat stosl only on limited number of
machines. On the other hand stosl will speedup BSS initialization on
all x86 platforms. Hence, use stosl instead of stosb.

Additionally, align relevant comment to coding style.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - improve comments
     (suggested by Konrad Rzeszutek Wilk),
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/head.S |    5 +++--
 xen/arch/x86/xen.lds.S   |    3 +++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index f3501fd..32a54a0 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 961f48f..6802da1 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -191,6 +191,8 @@ SECTIONS
        CONSTRUCTORS
   } :text
 
+  /* Align BSS to speedup its initialization. */
+  . = ALIGN(4);
   .bss : {                     /* BSS */
        . = ALIGN(STACK_SIZE);
        __bss_start = .;
@@ -205,6 +207,7 @@ SECTIONS
        *(.bss.percpu.read_mostly)
        . = ALIGN(SMP_CACHE_BYTES);
        __per_cpu_data_end = .;
+       . = ALIGN(4);
        __bss_end = .;
   } :text
   _end = . ;
-- 
1.7.10.4


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

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

* [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 01/16] x86/boot: do not create unwind tables Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 15:56   ` Andrew Cooper
  2016-05-24  8:42   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 04/16] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
                   ` (12 subsequent siblings)
  15 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

reloc() is not called according to cdecl calling convention.
This makes confusion and does not scale well for more arguments.
And patch adding multiboot2 protocol support have to pass 3
arguments instead of 2. Hence, move reloc() call to cdecl
calling convention.

I add push %ebp/mov %esp,%ebp/leave instructions here. Though they
are not strictly needed in this patch. However, then assembly code
in patch adding multiboot2 protocol support is easier to read.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - simplify assembly in xen/arch/x86/boot/reloc.c file
     (suggested by Jan Beulich),
   - reorder arguments for reloc() call from xen/arch/x86/boot/head.S
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/head.S  |    4 +++-
 xen/arch/x86/boot/reloc.c |   18 ++++++++++++++----
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 32a54a0..28ac721 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    %eax                /* Boot trampoline address. */
+        push    %ebx                /* Multiboot information 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..006f41d 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -10,15 +10,25 @@
  *    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) = MULTIBOOT_INFORMATION_ADDRESS,
+ *   - 0x8(%esp) = BOOT_TRAMPOLINE_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  0xc(%ebp),%eax           \n"
+    "    mov  %eax,alloc-1b(%ecx)      \n"
+    "    push 0x8(%ebp)                \n"
+    "    call reloc                    \n"
+    "    leave                         \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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 04/16] x86/boot/reloc: create generic alloc and copy functions
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (2 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 05/16] x86/boot: use %ecx instead of %eax Daniel Kiper
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v3 - suggestions/fixes:
   - use "g" constraint instead of "r" for alloc_mem() bytes argument
     (suggested by Jan Beulich).

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 006f41d..d60a078 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -43,9 +43,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"
@@ -53,50 +54,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) : "g" (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


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

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

* [PATCH v3 05/16] x86/boot: use %ecx instead of %eax
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (3 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 04/16] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 06/16] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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>
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 28ac721..1ff5937 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,20 +106,20 @@ __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    %eax                /* Boot trampoline address. */
+        push    %ecx                /* Boot trampoline address. */
         push    %ebx                /* Multiboot information address. */
         call    reloc
         add     $8,%esp             /* Remove reloc() args from stack. */
-- 
1.7.10.4


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

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

* [PATCH v3 06/16] x86/boot/reloc: Rename some variables and rearrange code a bit
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (4 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 05/16] x86/boot: use %ecx instead of %eax Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 07/16] x86/boot: create *.lnk files with linker script Daniel Kiper
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Replace mbi with mbi_out and mbi_old with mbi_in 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>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v3 - suggestions/fixes:
   - improve commit message
     (suggested by Konrad Rzeszutek Wilk).

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 d60a078..93b3845 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -84,41 +84,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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (5 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 06/16] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-04-15 14:04   ` Konrad Rzeszutek Wilk
  2016-05-24  9:05   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 08/16] x86: add multiboot2 protocol support Daniel Kiper
                   ` (8 subsequent siblings)
  15 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Newer GCC (e.g. gcc version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC)) does
some code optimizations by creating data sections (e.g. jump addresses
for C switch/case are calculated using data in .rodata section). This
thing is not accepted by *.lnk build recipe which requires that only .text
section lives in output. Potentially we can inhibit this GCC behavior by
using special options, e.g. -fno-tree-switch-conversion. However, this
does not guarantee that in the future new similar optimizations or anything
which creates not accepted sections will not break our build recipes again.
Additionally, I do not mention that probably this is not good idea to just
disable random optimizations. So, take over full control on *.lnk linking
process by using linker script and merge all text and data sections into
one .text section.

Additionally, remove .got.plt section which is not used in our final code.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/build32.lds |   49 +++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/build32.mk  |   10 ++++++---
 2 files changed, 56 insertions(+), 3 deletions(-)
 create mode 100644 xen/arch/x86/boot/build32.lds

diff --git a/xen/arch/x86/boot/build32.lds b/xen/arch/x86/boot/build32.lds
new file mode 100644
index 0000000..47db9c4
--- /dev/null
+++ b/xen/arch/x86/boot/build32.lds
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ *      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/>.
+ */
+
+ENTRY(_start)
+
+SECTIONS
+{
+  /* Merge code and data into one section. */
+  .text : {
+        *(.text)
+        *(.text.*)
+        *(.rodata)
+  }
+
+  /DISCARD/ : {
+        /*
+         * .got.plt section is used only by dynamic linker
+         * and our output is not supposed to be loaded by
+         * dynamic linker. Additionally, it just contains
+         * .PLT0 which is referenced from nowhere. So, we
+         * can safely drop .got.plt here.
+         *
+         * Ha! This should be really discarded here. However,
+         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
+         * symbol too and it is used as a reference for relative
+         * addressing (and only for that thing). Hence, ld
+         * complains if we remove that section because it
+         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
+         * section during conversion to plain binary format.
+         * Please check build32.mk for more details.
+         */
+        /* *(.got.plt) */
+  }
+}
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index 4a7d388..eb02b4b 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -12,20 +12,24 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
 	(od -v -t x $< | tr -s ' ' | awk 'NR > 1 {print s} {s=$$0}' | \
 	sed 's/ /,0x/g' | sed 's/,0x$$//' | sed 's/^[0-9]*,/ .long /') >$@
 
+#
+# Drop .got.plt during conversion to plain binary format.
+# Please check build32.lds for more details.
+#
 %.bin: %.lnk
-	$(OBJCOPY) -O binary $< $@
+	$(OBJCOPY) -O binary -R .got.plt $< $@
 
 %.lnk: %.o
 	$(OBJDUMP) -h $< | sed -n '/[0-9]/{s,00*,0,g;p;}' |\
 		while read idx name sz rest; do \
 			case "$$name" in \
-			.data|.data.*|.rodata|.rodata.*|.bss|.bss.*) \
+			.data|.data.*|.rodata.*|.bss|.bss.*) \
 				test $$sz != 0 || continue; \
 				echo "Error: non-empty $$name: 0x$$sz" >&2; \
 				exit $$(expr $$idx + 1);; \
 			esac; \
 		done
-	$(LD) $(LDFLAGS_DIRECT) -N -Ttext 0 -o $@ $<
+	$(LD) $(LDFLAGS_DIRECT) -N -T build32.lds -o $@ $<
 
 %.o: %.c
 	$(CC) $(CFLAGS) -c -fpic $< -o $@
-- 
1.7.10.4


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

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

* [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (6 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 07/16] x86/boot: create *.lnk files with linker script Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-24 15:46   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c Daniel Kiper
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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>
---
v3 - suggestions/fixes:
   - reorder reloc() arguments
     (suggested by Jan Beulich),
   - remove .L from multiboot2 header labels
     (suggested by Andrew Cooper, Jan Beulich and Konrad Rzeszutek Wilk),
   - take into account alignment when skipping multiboot2 fixed part
     (suggested by Konrad Rzeszutek Wilk),
   - create modules data if modules count != 0
     (suggested by Jan Beulich),
   - improve macros
     (suggested by Jan Beulich),
   - reduce number of casts
     (suggested by Jan Beulich),
   - use const if possible
     (suggested by Jan Beulich),
   - drop static and __used__ attribute from reloc()
     (suggested by Jan Beulich),
   - remove isolated/stray __packed attribute from
     multiboot2_memory_map_t type definition
     (suggested by Jan Beulich),
   - reformat xen/include/xen/multiboot2.h
     (suggested by Konrad Rzeszutek Wilk),
   - improve comments
     (suggested by Konrad Rzeszutek Wilk),
   - remove hard tabs
     (suggested by Jan Beulich and Konrad Rzeszutek Wilk).

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          |  106 +++++++++++++++++++++--
 xen/arch/x86/boot/reloc.c         |  152 ++++++++++++++++++++++++++++++++-
 xen/arch/x86/x86_64/asm-offsets.c |    7 ++
 xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
 5 files changed, 427 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 1ff5937..e46d691 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
+.Lmb2ht_init_start\@:
+        .short \type
+        .short \req
+        .long .Lmb2ht_init_end\@ - .Lmb2ht_init_start\@
+        .ifnb \args
+        mb2ht_args \args
+        .endif
+.Lmb2ht_init_end\@:
+        .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
+
+multiboot2_header_start:
+        /* Magic number indicating a Multiboot2 header. */
+        .long   MULTIBOOT2_HEADER_MAGIC
+        /* Architecture: i386. */
+        .long   MULTIBOOT2_ARCHITECTURE_I386
+        /* Multiboot2 header length. */
+        .long   multiboot2_header_end - multiboot2_header_start
+        /* Multiboot2 header checksum. */
+        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
+                        (multiboot2_header_end - multiboot2_header_start))
+
+        /* 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)
+multiboot2_header_end:
+
         .section .init.rodata, "a", @progbits
         .align 4
 
@@ -82,10 +141,49 @@ __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+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%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 +198,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
@@ -121,8 +216,9 @@ __start:
         mov     $sym_phys(cpu0_stack)+1024,%esp
         push    %ecx                /* Boot trampoline address. */
         push    %ebx                /* Multiboot information address. */
+        push    %eax                /* Multiboot magic. */
         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 93b3845..84f6073 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-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * 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) = MULTIBOOT_INFORMATION_ADDRESS,
- *   - 0x8(%esp) = BOOT_TRAMPOLINE_ADDRESS.
+ *   - 0x4(%esp) = MULTIBOOT_MAGIC,
+ *   - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
+ *   - 0xc(%esp) = BOOT_TRAMPOLINE_ADDRESS.
  */
 asm (
     "    .text                         \n"
@@ -23,8 +26,9 @@ asm (
     "    mov  %esp,%ebp                \n"
     "    call 1f                       \n"
     "1:  pop  %ecx                     \n"
-    "    mov  0xc(%ebp),%eax           \n"
+    "    mov  0x10(%ebp),%eax          \n"
     "    mov  %eax,alloc-1b(%ecx)      \n"
+    "    push 0xc(%ebp)                \n"
     "    push 0x8(%ebp)                \n"
     "    call reloc                    \n"
     "    leave                         \n"
@@ -41,7 +45,16 @@ 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)   (((multiboot2_tag_##type##_t *)(tag))->member)
+#define get_mb2_string(tag, type, member) ((u32)get_mb2_data(tag, type, member))
 
 static u32 alloc_mem(u32 bytes)
 {
@@ -59,6 +72,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;
@@ -84,7 +102,7 @@ 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(u32 mbi_in)
 {
     int i;
     multiboot_info_t *mbi_out;
@@ -125,3 +143,129 @@ multiboot_info_t *reloc(u32 mbi_in)
 
     return mbi_out;
 }
+
+static multiboot_info_t *mbi2_mbi(u32 mbi_in)
+{
+    const multiboot2_memory_map_t *mmap_src;
+    const multiboot2_tag_t *tag;
+    /* Do not complain that mbi_out_mods is not initialized. */
+    module_t *mbi_out_mods = (module_t *)0;
+    memory_map_t *mmap_dst;
+    multiboot_info_t *mbi_out;
+    u32 ptr;
+    unsigned int i, mod_idx = 0;
+
+    ptr = alloc_mem(sizeof(*mbi_out));
+    mbi_out = (multiboot_info_t *)ptr;
+    zero_mem(ptr, sizeof(*mbi_out));
+
+    /* Skip Multiboot2 information fixed part. */
+    ptr = ALIGN_UP(mbi_in + sizeof(multiboot2_fixed_t), MULTIBOOT2_TAG_ALIGN);
+
+    /* Get the number of modules. */
+    for ( tag = (multiboot2_tag_t *)ptr; ; )
+    {
+        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
+            ++mbi_out->mods_count;
+        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
+            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 ( (u32)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
+            break;
+    }
+
+    if ( mbi_out->mods_count )
+    {
+        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;
+    }
+
+    /* Skip Multiboot2 information fixed part. */
+    ptr = ALIGN_UP(mbi_in + sizeof(multiboot2_fixed_t), MULTIBOOT2_TAG_ALIGN);
+
+    /* Put all needed data into mbi_out. */
+    for ( tag = (multiboot2_tag_t *)ptr; ; )
+    {
+        switch ( tag->type )
+        {
+        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
+            mbi_out->flags |= MBI_LOADERNAME;
+            ptr = get_mb2_string(tag, string, string);
+            mbi_out->boot_loader_name = copy_string(ptr);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_CMDLINE:
+            mbi_out->flags |= MBI_CMDLINE;
+            ptr = get_mb2_string(tag, string, 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, basic_meminfo, mem_lower);
+            mbi_out->mem_upper = get_mb2_data(tag, basic_meminfo, mem_upper);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MMAP:
+            mbi_out->flags |= MBI_MEMMAP;
+            mbi_out->mmap_length = get_mb2_data(tag, mmap, size);
+            mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t);
+            mbi_out->mmap_length /= get_mb2_data(tag, mmap, 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, mmap, entries);
+            mmap_dst = (memory_map_t *)mbi_out->mmap_addr;
+
+            for ( i = 0; i < mbi_out->mmap_length / sizeof(memory_map_t); i++ )
+            {
+                /* Init size member properly. */
+                mmap_dst[i].size = sizeof(memory_map_t);
+                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
+                /* Now copy a given region data. */
+                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, module, mod_start);
+            mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, module, mod_end);
+            ptr = get_mb2_string(tag, module, 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 ( (u32)tag - mbi_in >= ((multiboot2_fixed_t *)mbi_in)->total_size )
+            return mbi_out;
+    }
+}
+
+multiboot_info_t *reloc(u32 mb_magic, u32 mbi_in)
+{
+    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..0f113f1
--- /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 {
+    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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (7 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 08/16] x86: add multiboot2 protocol support Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25  7:03   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 10/16] efi: create efi_enabled() Daniel Kiper
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

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.

Additionally, following patch adds efi struct flags member which
is used during runtime to differentiate between legacy BIOS and
EFI platforms and multiboot2 and EFI native loader. So, efi symbol
have to proper representation in ELF and PE Xen image. Hence,
define efi struct in xen/arch/x86/efi/stub.c and remove efi
symbol from ld script.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/efi/stub.c |    8 ++++++++
 xen/arch/x86/xen.lds.S  |    2 --
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
index 07c2bd0..e6c99b5 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -8,6 +8,14 @@
 const bool_t efi_enabled = 0;
 #endif
 
+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
+};
+
 void __init efi_init_memory(void) { }
 
 void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t l4e) { }
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 6802da1..6376bfa 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -227,8 +227,6 @@ SECTIONS
   .pad : {
     . = ALIGN(MB(16));
   } :text
-#else
-  efi = .;
 #endif
 
   /* Sections to be discarded */
-- 
1.7.10.4


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

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

* [PATCH v3 10/16] efi: create efi_enabled()
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (8 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25  7:20   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 11/16] efi: build xen.gz with EFI code Daniel Kiper
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

First of all we need to differentiate between legacy BIOS
and EFI platforms during runtime, not during build, because
one image will have legacy and EFI code and can be executed
on both platforms. Additionally, 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>
---
v3 - suggestions/fixes:
   - define efi struct in xen/arch/x86/efi/stub.c
     in earlier patch
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/arch/x86/dmi_scan.c    |    4 ++--
 xen/arch/x86/domain_page.c |    2 +-
 xen/arch/x86/efi/stub.c    |    5 +----
 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/common/efi/boot.c      |    4 ++++
 xen/common/efi/runtime.c   |   17 +++++++----------
 xen/drivers/acpi/osl.c     |    2 +-
 xen/include/xen/efi.h      |   12 ++++++++++--
 11 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index 8e07f8d..4cd38c8 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -238,7 +238,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;
@@ -702,7 +702,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 e6c99b5..c5ae369 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -4,11 +4,8 @@
 #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,
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index ef6557c..ff26b5a 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -564,7 +564,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);
 }
 
@@ -722,7 +722,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 c5c332d..5d80868 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -434,8 +434,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) )
@@ -715,7 +715,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);
@@ -826,7 +826,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.");
@@ -1057,7 +1057,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 687e39b..ffd39b2 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -686,7 +686,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/common/efi/boot.c b/xen/common/efi/boot.c
index 125c9ce..f006575 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -934,6 +934,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_init(ImageHandle, SystemTable);
 
     use_cfg_file = efi_arch_use_config_file(SystemTable);
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 8a28d87..eb8bc12 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..659c7c4 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,12 @@ 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. */
+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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (9 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 10/16] efi: create efi_enabled() Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25  7:53   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator Daniel Kiper
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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 non-ELF file using multiboot (v1) or multiboot2 then
it must contain "linear" (or "flat") representation of code and data.
This is requirement of both boot protocols. 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). From EFI point
of view everything is OK and works. However, this file layout cannot be
properly interpreted by multiboot protocols family. In theory there is
a chance that we could build proper PE file (from multiboot protocols POV)
using current build system. However, it means that xen.efi further diverge
from Xen ELF file (in terms of contents and build method). On the other
hand ELF has 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 or other tool. This way we will have one
Xen binary which can be loaded by three boot protocols: EFI native loader,
multiboot (v1) and multiboot2.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - check for EFI platform in EFI code
     (suggested by Jan Beulich),
   - fix Makefiles
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich).

v2 - suggestions/fixes:
   - build EFI code only if it is supported in a given build environment
     (suggested by Jan Beulich).
---
 xen/arch/x86/efi/Makefile |   11 +++--------
 xen/common/efi/boot.c     |    3 +++
 xen/common/efi/runtime.c  |    6 ++++++
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/efi/Makefile b/xen/arch/x86/efi/Makefile
index 5099430..2a7d3e5 100644
--- a/xen/arch/x86/efi/Makefile
+++ b/xen/arch/x86/efi/Makefile
@@ -1,14 +1,9 @@
 CFLAGS += -fshort-wchar
 
-obj-y += stub.o
-
-create = test -e $(1) || touch -t 199901010000 $(1)
-
 efi := y$(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
-
-stub.o: $(extra-y)
+obj-y := stub.o
+obj-$(efi) := boot.init.o compat.o relocs-dummy.o runtime.o
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index f006575..d10c0ab 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
     } *extra, *extra_head = NULL;
 #endif
 
+    if ( !efi_enabled(EFI_PLATFORM) )
+        return;
+
     printk(XENLOG_INFO "EFI memory map:%s\n",
            map_bs ? " (mapping BootServices)" : "");
     for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (10 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 11/16] efi: build xen.gz with EFI code Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25  8:39   ` Jan Beulich
  2016-07-05 18:26   ` Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
                   ` (3 subsequent siblings)
  15 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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.

Jan Beulich added 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).

However, this solution does not solve conflicts problem described in #1
because EFI memory map is needed during Xen runtime after init phase.
So, finally we would get back to #1. Hmmm... Should I check how Linux
and others cope with that problem?

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 6dbb14d..84afffa 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 5d80868..4eb8572 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1057,8 +1057,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 related	[flat|nested] 94+ messages in thread

* [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (11 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25  9:32   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 14/16] x86/boot: implement early command line parser in C Daniel Kiper
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

This way Xen can be loaded on EFI platforms using GRUB2 and
other boot loaders which support multiboot2 protocol.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - take into account alignment when skipping multiboot2 fixed part
     (suggested by Konrad Rzeszutek Wilk),
   - improve segment registers initialization
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich and Konrad Rzeszutek Wilk),
   - improve commit message
     (suggested by Jan Beulich).

v3 - not fixed yet:
   - xen/arch/x86/efi/stub.c:efi_multiboot2()
     should print error message and halt system.

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          |  177 +++++++++++++++++++++++++++++++++++--
 xen/arch/x86/efi/efi-boot.h       |   43 +++++++++
 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, 240 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index e46d691..efb0614 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -89,6 +89,13 @@ multiboot2_header_start:
                    0, /* Number of the lines - no preference. */ \
                    0  /* Number of bits per pixel - no preference. */
 
+        /* Inhibit bootloader 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)
 multiboot2_header_end:
@@ -100,19 +107,29 @@ multiboot2_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_ldr_mb2: .asciz "ERR: On EFI platform use latest Multiboot2 compatible bootloader!"
 
         .section .init.text, "ax", @progbits
 
 bad_cpu:
         mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
-        jmp     print_err
+        mov     $0xB8000,%edi                   # VGA framebuffer
+        jmp     1f
 not_multiboot:
         mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
-print_err:
-        mov     $0xB8000,%edi  # VGA framebuffer
+        mov     $0xB8000,%edi                   # VGA framebuffer
+        jmp     1f
+mb2_too_old:
+        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
+        xor     %edi,%edi                       # No VGA framebuffer
 1:      mov     (%esi),%bl
         test    %bl,%bl        # Terminate on '\0' sentinel
         je      .Lhalt
@@ -123,6 +140,8 @@ print_err:
         mov     $0x3f8+0,%dx   # UART Transmit Holding Register
         mov     %bl,%al
         out     %al,%dx        # Send a character over the serial line
+        test    %edi,%edi      # Is VGA framebuffer available?
+        jz      1b
         movsb                  # Write a character to the VGA framebuffer
         mov     $7,%al
         stosb                  # Write an attribute to the VGA framebuffer
@@ -130,6 +149,130 @@ 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+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%rcx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%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 clear BSS twice and do not go into real mode. */
+        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!).
+         * It must be done earlier than in BIOS case
+         * because efi_multiboot2() touches it.
+         */
+        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 - Highest available memory address below 1 MiB.
+         *
+         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag is not provided
+         * on EFI platforms. Hence, it could not be used like
+         * on legacy BIOS platforms.
+         */
+        call    efi_multiboot2
+
+        /* Convert memory address to bytes/16 and store it in safe place. */
+        shr     $4,%rax
+        mov     %rax,%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,%ss
+        /* %esp is initialised later. */
+
+        /* Load null descriptor to unused segment registers. */
+        xor     %edx,%edx
+        mov     %edx,%fs
+        mov     %edx,%gs
+
+        /* 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 +300,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. */
@@ -170,12 +313,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
@@ -183,7 +333,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) */
@@ -199,12 +349,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! */
@@ -221,6 +372,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
@@ -229,6 +387,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 84afffa..b311b7c 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 )
@@ -665,6 +668,46 @@ static bool_t __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
 
 static void efi_arch_flush_dcache_area(const void *vaddr, UINTN size) { }
 
+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();
+
+    if ( gop )
+        gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
+
+    efi_arch_edd();
+
+    /*
+     * efi_arch_cpu() is not needed here. boot_cpu_data
+     * is set later in xen/arch/x86/boot/head.S.
+     */
+
+    efi_tables();
+    setup_efi_pci();
+    efi_variables();
+
+    if ( gop )
+        efi_set_gop_mode(gop, gop_mode);
+
+    efi_exit_boot(ImageHandle, SystemTable);
+
+    /* Return highest available memory address below 1 MiB. */
+    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 4eb8572..21bbe6a 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -715,7 +715,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);
@@ -728,7 +728,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 )
     {
@@ -826,7 +830,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 6376bfa..fa1da37 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -192,7 +192,7 @@ SECTIONS
   } :text
 
   /* Align BSS to speedup its initialization. */
-  . = ALIGN(4);
+  . = ALIGN(8);
   .bss : {                     /* BSS */
        . = ALIGN(STACK_SIZE);
        __bss_start = .;
@@ -207,7 +207,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 d10c0ab..129512f 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;
@@ -936,6 +947,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 659c7c4..7b0a7ca 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


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

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

* [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (12 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25 10:33   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable Daniel Kiper
  2016-04-15 12:33 ` [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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 (without playing
with segment registers) and much easier to maintain.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - optimize some code
     (suggested by Jan Beulich),
   - put VESA data into early_boot_opts_t members
     (suggested by Jan Beulich),
   - rename some functions and variables
     (suggested by Jan Beulich),
   - move around video.h include in xen/arch/x86/boot/trampoline.S
     (suggested by Jan Beulich),
   - fix coding style
     (suggested by Jan Beulich),
   - fix build with older GCC
     (suggested by Konrad Rzeszutek Wilk),
   - remove redundant comments
     (suggested by Jan Beulich),
   - add some comments
   - improve commit message
     (suggested by Jan Beulich).
---
 .gitignore                     |    5 +-
 xen/arch/x86/Makefile          |    2 +-
 xen/arch/x86/boot/Makefile     |    7 +-
 xen/arch/x86/boot/build32.lds  |    1 +
 xen/arch/x86/boot/build32.mk   |    4 +-
 xen/arch/x86/boot/cmdline.S    |  367 ----------------------------------------
 xen/arch/x86/boot/cmdline.c    |  357 ++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/edd.S        |    3 -
 xen/arch/x86/boot/head.S       |   17 ++
 xen/arch/x86/boot/trampoline.S |   12 ++
 xen/arch/x86/boot/video.S      |    6 -
 11 files changed, 400 insertions(+), 381 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 91f690c..6919546 100644
--- a/.gitignore
+++ b/.gitignore
@@ -237,9 +237,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 1bcb08b..32d2407 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -176,4 +176,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.lds b/xen/arch/x86/boot/build32.lds
index 47db9c4..6a234ea 100644
--- a/xen/arch/x86/boot/build32.lds
+++ b/xen/arch/x86/boot/build32.lds
@@ -25,6 +25,7 @@ SECTIONS
         *(.text)
         *(.text.*)
         *(.rodata)
+        *(.rodata.*)
   }
 
   /DISCARD/ : {
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index eb02b4b..58e27e1 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -23,7 +23,7 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
 	$(OBJDUMP) -h $< | sed -n '/[0-9]/{s,00*,0,g;p;}' |\
 		while read idx name sz rest; do \
 			case "$$name" in \
-			.data|.data.*|.rodata.*|.bss|.bss.*) \
+			.data|.data.*|.bss|.bss.*) \
 				test $$sz != 0 || continue; \
 				echo "Error: non-empty $$name: 0x$$sz" >&2; \
 				exit $$(expr $$idx + 1);; \
@@ -34,6 +34,8 @@ CFLAGS := $(filter-out -flto,$(CFLAGS))
 %.o: %.c
 	$(CC) $(CFLAGS) -c -fpic $< -o $@
 
+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..a624fa9
--- /dev/null
+++ b/xen/arch/x86/boot/cmdline.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ *      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 NULL	((void *)0)
+
+/*
+ * Space and TAB are obvious delimiters. However, I am
+ * adding "\n" and "\r" here too. Just in case when
+ * crazy bootloader/user put them somewhere.
+ */
+#define DELIM_CHARS		" \n\r\t"
+#define DELIM_CHARS_COMMA	DELIM_CHARS ","
+
+#define __packed	__attribute__((__packed__))
+
+#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)
+
+/*
+ * Compiler is not able to optimize regular strlen()
+ * if argument is well known string during build.
+ * Hence, introduce optimized strlen_opt().
+ */
+#define strlen_opt(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_width;
+    u16 vesa_height;
+    u16 vesa_depth;
+} early_boot_opts_t;
+
+static size_t strlen(const char *s)
+{
+    const char *sc;
+
+    for ( sc = s; *sc != '\0'; ++sc )
+        /* nothing */;
+    return sc - s;
+}
+
+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;
+}
+
+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;
+}
+
+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 int strmaxcmp(const char *cs, const char *ct, const char *delim_chars)
+{
+    return strncmp(cs, ct, max(strcspn(cs, delim_chars), strlen(ct)));
+}
+
+static int strsubcmp(const char *cs, const char *ct)
+{
+    return strncmp(cs, ct, strlen(ct));
+}
+
+static const char *find_opt(const char *cmdline, const char *opt, int arg)
+{
+    size_t lc, lo;
+
+    lo = strlen(opt);
+
+    for ( ; ; )
+    {
+        cmdline += strspn(cmdline, DELIM_CHARS);
+
+        if ( *cmdline == '\0' )
+            return NULL;
+
+        if ( !strmaxcmp(cmdline, "--", DELIM_CHARS) )
+            return NULL;
+
+        lc = strcspn(cmdline, DELIM_CHARS);
+
+        if ( !strncmp(cmdline, opt, arg ? lo : max(lc, lo)) )
+            return cmdline + lo;
+
+        cmdline += lc;
+    }
+}
+
+static u8 skip_realmode(const char *cmdline)
+{
+    return !!find_opt(cmdline, "no-real-mode", 0) || !!find_opt(cmdline, "tboot=", 1);
+}
+
+static u8 edd_parse(const char *cmdline)
+{
+    const char *c;
+
+    c = find_opt(cmdline, "edd=", 1);
+
+    if ( !c )
+        return 0;
+
+    if ( !strmaxcmp(c, "off", DELIM_CHARS) )
+        return 2;
+
+    return !strmaxcmp(c, "skipmbr", DELIM_CHARS);
+}
+
+static u8 edid_parse(const char *cmdline)
+{
+    const char *c;
+
+    c = find_opt(cmdline, "edid=", 1);
+
+    if ( !c )
+        return 0;
+
+    if ( !strmaxcmp(c, "force", DELIM_CHARS) )
+        return 2;
+
+    return !strmaxcmp(c, "no", DELIM_CHARS);
+}
+
+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;
+
+    c = find_opt(cmdline, "vga=", 1);
+
+    if ( !c )
+        return;
+
+    ebo->boot_vid_mode = ASK_VGA;
+
+    if ( !strmaxcmp(c, "current", DELIM_CHARS_COMMA) )
+        ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
+    else if ( !strsubcmp(c, "text-80x") )
+    {
+        c += strlen_opt("text-80x");
+        ebo->boot_vid_mode = rows2vmode(strtoi(c, DELIM_CHARS_COMMA, NULL));
+    }
+    else if ( !strsubcmp(c, "gfx-") )
+    {
+        tmp = strtoi(c + strlen_opt("gfx-"), "x", &c);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_width = tmp;
+
+        /*
+         * Increment c outside of strtoi() because otherwise some
+         * compiler may complain with following message:
+         * warning: operation on ‘c’ may be undefined.
+         */
+        ++c;
+        tmp = strtoi(c, "x", &c);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_height = tmp;
+
+        tmp = strtoi(++c, DELIM_CHARS_COMMA, NULL);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->vesa_depth = tmp;
+
+        ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;
+    }
+    else if ( !strsubcmp(c, "mode-") )
+    {
+        tmp = strtoi(c + strlen_opt("mode-"), DELIM_CHARS_COMMA, NULL);
+
+        if ( tmp < 0 || tmp > U16_MAX )
+            return;
+
+        ebo->boot_vid_mode = tmp;
+    }
+}
+
+void 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 efb0614..964851b 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -436,8 +436,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
@@ -453,6 +469,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 b013614..8a32728 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -220,8 +220,20 @@ trampoline_boot_cpu_entry:
         /* Jump to the common bootstrap entry point. */
         jmp     trampoline_protmode_entry
 
+#include "video.h"
+
+/* 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


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

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

* [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (13 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 14/16] x86/boot: implement early command line parser in C Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25 10:48   ` Jan Beulich
  2016-04-15 12:33 ` [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, 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 "x86: add multiboot2 protocol support for relocatable images" 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 start and end of required memory region if it live at address
    not aligned to 2 MiB,
  - %esi and %r15d registers are used as a storage for Xen image load base
    address (%r15d shortly because %rsi is used for EFI SystemTable address
    in 64-bit code); both registers are (%esi is mostly) unused in early
    boot code and preserved during C functions calls,
  - %esi is used as base for Xen data relative addressing in 32-bit code.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3 - suggestions/fixes:
   - improve segment registers initialization
     (suggested by Jan Beulich),
   - simplify Xen image load base address calculation
     (suggested by Jan Beulich),
   - use %esi and %r15d instead of %ebp to store
     Xen image load base address,
   - use %esi instead of %fs for relative addressing;
     this way we get shorter and simpler code,
   - rename some variables and constants
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Konrad Rzeszutek Wilk),
   - improve commit message
     (suggested by Jan Beulich).

v3 - not fixed yet:
   - small issue with remapping code in xen/arch/x86/setup.c,
   - <final-exec-addr> mkelf32 argument should
     be calculated dynamically; this issue has
     minimal impact on other parts of this patch.
---
 xen/arch/x86/Makefile          |    6 +-
 xen/arch/x86/Rules.mk          |    4 +
 xen/arch/x86/boot/head.S       |  162 ++++++++++++++++++++++++++++++----------
 xen/arch/x86/boot/trampoline.S |    6 +-
 xen/arch/x86/boot/wakeup.S     |    6 +-
 xen/arch/x86/boot/x86_64.S     |   44 +++++------
 xen/arch/x86/setup.c           |   44 ++++++-----
 xen/arch/x86/xen.lds.S         |    2 +-
 xen/include/asm-x86/config.h   |    1 +
 xen/include/asm-x86/page.h     |    2 +-
 10 files changed, 186 insertions(+), 91 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 32d2407..0cc6f5f 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -71,8 +71,10 @@ efi-y := $(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_OFFSET) 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 3139886..7c76f80 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -1,6 +1,10 @@
 ########################################
 # x86-specific definitions
 
+XEN_IMG_OFFSET = 0x200000
+
+CFLAGS += -DXEN_IMG_OFFSET=$(XEN_IMG_OFFSET)
+
 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 964851b..e322270 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -12,7 +12,7 @@
         .text
         .code32
 
-#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
+#define sym_offset(sym)   ((sym) - __XEN_VIRT_START)
 
 #define BOOT_CS32        0x0008
 #define BOOT_CS64        0x0010
@@ -94,7 +94,7 @@ multiboot2_header_start:
 
         /* EFI64 entry point. */
         mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
-                   sym_phys(__efi64_start)
+                   sym_offset(__efi64_start)
 
         /* Multiboot2 header end tag. */
         mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
@@ -106,11 +106,12 @@ multiboot2_header_end:
         .word   0
 gdt_boot_descr:
         .word   6*8-1
-        .long   sym_phys(trampoline_gdt)
+gdt_boot_base:
+        .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,16 +121,16 @@ cs32_switch_addr:
         .section .init.text, "ax", @progbits
 
 bad_cpu:
-        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
-        mov     $0xB8000,%edi                   # VGA framebuffer
+        lea     sym_offset(.Lbad_cpu_msg)(%esi),%esi # Error message
+        mov     $0xB8000,%edi                        # VGA framebuffer
         jmp     1f
 not_multiboot:
-        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
-        mov     $0xB8000,%edi                   # VGA framebuffer
+        lea     sym_offset(.Lbad_ldr_msg)(%esi),%esi # Error message
+        mov     $0xB8000,%edi                        # VGA framebuffer
         jmp     1f
 mb2_too_old:
-        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
-        xor     %edi,%edi                       # No VGA framebuffer
+        lea     sym_offset(.Lbad_ldr_mb2)(%esi),%esi # Error message
+        xor     %edi,%edi                            # No VGA framebuffer
 1:      mov     (%esi),%bl
         test    %bl,%bl        # Terminate on '\0' sentinel
         je      .Lhalt
@@ -154,6 +155,9 @@ mb2_too_old:
 __efi64_start:
         cld
 
+        /* Load default Xen image load base address. */
+        mov     $sym_offset(__image_base__),%r15d
+
         /* Check for Multiboot2 bootloader. */
         cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
         je      efi_multiboot2_proto
@@ -238,6 +242,9 @@ run_bs:
 
         pop     %rax
 
+        /* Store Xen image load base address in place accessible for 32-bit code. */
+        mov     %r15d,%esi
+
         /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
         lea     trampoline_setup(%rip),%rdi
 
@@ -245,9 +252,11 @@ x86_32_switch:
         cli
 
         /* Initialise GDT. */
+        add     %esi,gdt_boot_base(%rip)
         lgdt    gdt_boot_descr(%rip)
 
         /* Reload code selector. */
+        add     %esi,cs32_switch_addr(%rip)
         ljmpl   *cs32_switch_addr(%rip)
 
         .code32
@@ -277,12 +286,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 load base address. */
+        mov     $sym_offset(__image_base__),%esi
 
         /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
         xor     %edx,%edx
@@ -334,6 +339,25 @@ multiboot2_proto:
         jmp     0b
 
 trampoline_bios_setup:
+        /*
+         * Called on legacy BIOS platforms only.
+         *
+         * Initialise GDT and basic data segments.
+         */
+        add     %esi,sym_offset(gdt_boot_base)(%esi)
+        lgdt    sym_offset(gdt_boot_descr)(%esi)
+
+        mov     $BOOT_DS,%ecx
+        mov     %ecx,%ds
+        mov     %ecx,%es
+        mov     %ecx,%ss
+        /* %esp is initialised later. */
+
+        /* Load null descriptor to unused segment registers. */
+        xor     %ecx,%ecx
+        mov     %ecx,%fs
+        mov     %ecx,%gs
+
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -355,33 +379,42 @@ trampoline_bios_setup:
         cmovb   %edx,%ecx           /* and use the smaller */
 
 trampoline_setup:
-        /* Reserve 64kb for the trampoline. */
+        /*
+         * Called on legacy BIOS and EFI platforms.
+         *
+         * 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,sym_offset(trampoline_phys)(%esi)
+
+        /* Save Xen image load base address for later use. */
+        mov     %esi,sym_offset(xen_img_load_base_addr)(%esi)
+
+        /* Setup stack. %ss was initialized earlier. */
+        lea     (sym_offset(cpu0_stack)+1024)(%esi),%esp
 
         /* Save the Multiboot info struct (after relocation) for later use. */
-        mov     $sym_phys(cpu0_stack)+1024,%esp
         push    %ecx                /* Boot trampoline address. */
         push    %ebx                /* Multiboot information address. */
         push    %eax                /* Multiboot magic. */
         call    reloc
         add     $12,%esp            /* Remove reloc() args from stack. */
-        mov     %eax,sym_phys(multiboot_ptr)
+        mov     %eax,sym_offset(multiboot_ptr)(%esi)
 
         /*
          * Do not zero BSS on EFI platform here.
          * It was initialized earlier.
          */
-        cmpb    $1,sym_phys(skip_realmode)
+        cmpb    $1,sym_offset(skip_realmode)(%esi)
         je      1f
 
         /* Initialize BSS (no nasty surprises!). */
-        mov     $sym_phys(__bss_start),%edi
-        mov     $sym_phys(__bss_end),%ecx
+        lea     sym_offset(__bss_start)(%esi),%edi
+        lea     sym_offset(__bss_end)(%esi),%ecx
         sub     %edi,%ecx
         shr     $2,%ecx
         xor     %eax,%eax
@@ -396,8 +429,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,sym_offset(cpuid_ext_features)(%esi)
+        mov     %edx,sym_offset(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)(%esi)
 
         /* Check for availability of long mode. */
         bt      $cpufeat_bit(X86_FEATURE_LM),%edx
@@ -405,64 +438,115 @@ 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,sym_offset(boot_tsc_stamp)(%esi)
+        mov     %edx,sym_offset(boot_tsc_stamp+4)(%esi)
+
+        /* Update frame addreses in page tables. */
+        lea     sym_offset(__page_tables_start)(%esi),%edx
+        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
+1:      testl   $_PAGE_PRESENT,(%edx)
+        jz      2f
+        add     %esi,(%edx)
+2:      add     $8,%edx
+        loop    1b
+
+        /* Initialise L2 boot-map page table entries (14MB). */
+        lea     sym_offset(l2_bootmap)(%esi),%edx
+        lea     sym_offset(start)(%esi),%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. */
+        lea     sym_offset(l2_bootmap)+__PAGE_HYPERVISOR(%esi),%eax
+        lea     sym_offset(l3_bootmap)(%esi),%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)(%esi),%edx
+        lea     sym_offset(start)(%esi),%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
 
         /*
          * During boot, hook 4kB mappings of first 2MB of memory into L2.
          * This avoids mixing cachability for the legacy VGA region, and is
          * corrected when Xen relocates itself.
          */
-        mov     $sym_phys(l1_identmap)+__PAGE_HYPERVISOR,%edi
-        mov     %edi,sym_phys(l2_xenmap)
+        lea     (sym_offset(l1_identmap)+__PAGE_HYPERVISOR)(%esi),%edi
+        mov     %edi,sym_offset(l2_bootmap)(%esi)
 
         /* Apply relocations to bootstrap trampoline. */
-        mov     sym_phys(trampoline_phys),%edx
-        mov     $sym_phys(__trampoline_rel_start),%edi
+        mov     sym_offset(trampoline_phys)(%esi),%edx
+        lea     sym_offset(__trampoline_rel_start)(%esi),%edi
+        lea     sym_offset(__trampoline_rel_stop)(%esi),%ebx
 1:
         mov     (%edi),%eax
         add     %edx,(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_rel_stop),%edi
+        cmp     %ebx,%edi
         jb      1b
 
         /* Patch in the trampoline segment. */
         shr     $4,%edx
-        mov     $sym_phys(__trampoline_seg_start),%edi
+        lea     sym_offset(__trampoline_seg_start)(%esi),%edi
+        lea     sym_offset(__trampoline_seg_stop)(%esi),%ebx
 1:
         mov     (%edi),%eax
         mov     %dx,(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_seg_stop),%edi
+        cmp     %ebx,%edi
         jb      1b
 
         /* Do not parse command line on EFI platform here. */
-        cmpb    $1,sym_phys(skip_realmode)
+        cmpb    $1,sym_offset(skip_realmode)(%esi)
         je      1f
 
         /* Bail if there is no command line to parse. */
-        mov     sym_phys(multiboot_ptr),%ebx
+        mov     sym_offset(multiboot_ptr)(%esi),%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)(%esi),%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     sym_offset(trampoline_phys)(%esi),%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)(%esi),%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 8a32728..47dd65a 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -60,6 +60,9 @@ trampoline_gdt:
         .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
         .popsection
 
+GLOBAL(xen_img_load_base_addr)
+        .long   0
+
 GLOBAL(trampoline_misc_enable_off)
         .quad   0
 
@@ -87,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_load_base_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..61c1261 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_load_base_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 9ab9231..30d2eba 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,18 +100,15 @@ GLOBAL(l1_identmap)
         .endr
         .size l1_identmap, . - l1_identmap
 
+GLOBAL(__page_tables_start)
+
 /*
  * Space for mapping the first 4GB of memory, with the first 16 megabytes
  * actualy mapped (mostly using superpages).  Uses 4x 4k pages.
  */
 GLOBAL(l2_identmap)
-        .quad sym_phys(l1_identmap) + __PAGE_HYPERVISOR
-        idx = 1
-        .rept 7
-        .quad (idx << L2_PAGETABLE_SHIFT) | PAGE_HYPERVISOR | _PAGE_PSE
-        idx = idx + 1
-        .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
 
 /*
@@ -121,9 +117,10 @@ GLOBAL(l2_identmap)
  * page.
  */
 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
@@ -134,7 +131,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
@@ -146,7 +143,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
@@ -157,9 +154,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
@@ -169,13 +166,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
@@ -190,16 +187,9 @@ GLOBAL(__page_tables_end)
         .align PAGE_SIZE, 0
 
 GLOBAL(l2_bootmap)
-        .quad sym_phys(l1_identmap) + __PAGE_HYPERVISOR
-        idx = 1
-        .rept 7
-        .quad (idx << L2_PAGETABLE_SHIFT) | __PAGE_HYPERVISOR | _PAGE_PSE
-        idx = idx + 1
-        .endr
-        .fill L2_PAGETABLE_ENTRIES - 8, 8, 0
+        .fill 4 * L2_PAGETABLE_ENTRIES, 8, 0
         .size l2_bootmap, . - l2_bootmap
 
 GLOBAL(l3_bootmap)
-        .quad sym_phys(l2_bootmap) + __PAGE_HYPERVISOR
-        .fill L3_PAGETABLE_ENTRIES - 1, 8, 0
+        .fill L3_PAGETABLE_ENTRIES, 8, 0
         .size l3_bootmap, . - l3_bootmap
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 21bbe6a..f6d2fa0 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -281,9 +281,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;
@@ -661,6 +658,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_load_base_addr);
+
     printk("Video information:\n");
 
     /* Print VGA display mode information. */
@@ -855,10 +855,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;
 
@@ -896,7 +894,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_load_base_addr;
 
             /*
              * Perform relocation to new physical address.
@@ -906,7 +904,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_load_base_addr, _end - _start, 1);
 
             /* Walk initial pagetables, relocating page directory entries. */
             pl4e = __va(__pa(idle_pg_table));
@@ -915,27 +913,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_load_base_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_load_base_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_load_base_addr);
                     }
                 }
             }
@@ -946,21 +944,30 @@ void __init noreturn __start_xen(unsigned long mbi_p)
              * Undo the temporary-hooking of the l1_identmap.  __2M_text_start
              * is contained in this PTE.
              */
+#if 0
+            /*
+             * Should BUG_ON() be run only if Xen is
+             * loaded with EFI loadedr (xen.efi)?
+             */
             BUG_ON(l2_table_offset((unsigned long)_erodata) ==
                    l2_table_offset((unsigned long)_stext));
             *pl2e++ = l2e_from_pfn(xen_phys_start >> PAGE_SHIFT,
                                    PAGE_HYPERVISOR_RX | _PAGE_PSE);
+#else
+            pl2e++;
+#endif
             for ( i = 1; i < L2_PAGETABLE_ENTRIES; i++, pl2e++ )
             {
                 unsigned int flags;
 
-                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
+                if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) ||
+                     (l2e_get_pfn(*pl2e) > PFN_DOWN(xen_phys_start)) )
                     continue;
 
                 if ( !using_2M_mapping() )
                 {
                     *pl2e = l2e_from_intpte(l2e_get_intpte(*pl2e) +
-                                            xen_phys_start);
+                                            xen_phys_start - xen_img_load_base_addr);
                     continue;
                 }
 
@@ -990,7 +997,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                 }
 
                 *pl2e = l2e_from_paddr(
-                    l2e_get_paddr(*pl2e) + xen_phys_start, flags);
+                    l2e_get_paddr(*pl2e) + xen_phys_start - xen_img_load_base_addr, flags);
             }
 
             /* Re-sync the stack and then switch to relocated pagetables. */
@@ -1061,6 +1068,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). */
@@ -1133,14 +1143,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/xen.lds.S b/xen/arch/x86/xen.lds.S
index fa1da37..8d2ad9f 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -41,7 +41,7 @@ SECTIONS
 
   __2M_text_start = .;         /* Start of 2M superpages, mapped RX. */
 
-  . = __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 4527ce3..bb8c9db 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -97,6 +97,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_load_base_addr;
 extern unsigned int trampoline_xen_phys_start;
 extern unsigned char trampoline_cpu_started;
 extern char wakeup_start[];
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 224852a..4abd2ea 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -288,7 +288,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


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

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

* [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
                   ` (14 preceding siblings ...)
  2016-04-15 12:33 ` [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable Daniel Kiper
@ 2016-04-15 12:33 ` Daniel Kiper
  2016-05-25 11:03   ` Jan Beulich
  15 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-04-15 12:33 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Add multiboot2 protocol support for relocatable images. Only GRUB2 with
"multiboot2: Add support for relocatable images" patch 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>
---
v3 - suggestions/fixes:
   - use %esi and %r15d instead of %ebp to store
     Xen image load base address,
   - rename some types and constants,
   - reformat xen/include/xen/multiboot2.h
     (suggested by Konrad Rzeszutek Wilk),
   - improve comments,
   - improve commit message
     (suggested by Konrad Rzeszutek Wilk).
---
 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 e322270..dbf2555 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -79,6 +79,13 @@ multiboot2_header_start:
         /* 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_offset(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
@@ -178,30 +185,39 @@ efi_multiboot2_proto:
         and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
 
 0:
+        /* Get Xen image load base address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
+        jne     1f
+
+        mov     MB2_load_base_addr(%rcx),%r15d
+        sub     $XEN_IMG_OFFSET,%r15
+        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 clear BSS twice and do not go into real mode. */
         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
@@ -313,14 +329,23 @@ multiboot2_proto:
         and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
 
 0:
+        /* Get Xen image load base address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%ecx)
+        jne     1f
+
+        mov     MB2_load_base_addr(%ecx),%esi
+        sub     $XEN_IMG_OFFSET,%esi
+        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
@@ -332,6 +357,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..d227f28 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_load_base_addr, multiboot2_tag_load_base_addr_t, load_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 0f113f1..a1d355c 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_LOAD_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 load_base_addr;
+} multiboot2_tag_load_base_addr_t;
+
+typedef struct {
+    u32 type;
+    u32 size;
     char string[0];
 } multiboot2_tag_string_t;
 
-- 
1.7.10.4


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

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

* Re: [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb
  2016-04-15 12:33 ` [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb Daniel Kiper
@ 2016-04-15 13:57   ` Konrad Rzeszutek Wilk
  2016-04-15 15:48   ` Andrew Cooper
  1 sibling, 0 replies; 94+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-04-15 13:57 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, stefano.stabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Apr 15, 2016 at 02:33:02PM +0200, Daniel Kiper wrote:
> Speedup BSS initialization by using stosl instead of stosb.
> 
> Some may argue that Intel Ivy Bridge and later provide ERMSB feature.
> This means that "rep stosb" gives better throughput than "rep stosl" on
> above mentioned CPUs. However, this feature is only available on newer
> Intel processors and e.g. AMD does not provide it at all. So, stosb will
> just give real benefits and even beat stosl only on limited number of
> machines. On the other hand stosl will speedup BSS initialization on
> all x86 platforms. Hence, use stosl instead of stosb.
> 
> Additionally, align relevant comment to coding style.
> 
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
> v3 - suggestions/fixes:
>    - improve comments
>      (suggested by Konrad Rzeszutek Wilk),
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/boot/head.S |    5 +++--
>  xen/arch/x86/xen.lds.S   |    3 +++
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index f3501fd..32a54a0 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 961f48f..6802da1 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -191,6 +191,8 @@ SECTIONS
>         CONSTRUCTORS
>    } :text
>  
> +  /* Align BSS to speedup its initialization. */
> +  . = ALIGN(4);
>    .bss : {                     /* BSS */
>         . = ALIGN(STACK_SIZE);
>         __bss_start = .;
> @@ -205,6 +207,7 @@ SECTIONS
>         *(.bss.percpu.read_mostly)
>         . = ALIGN(SMP_CACHE_BYTES);
>         __per_cpu_data_end = .;
> +       . = ALIGN(4);
>         __bss_end = .;
>    } :text
>    _end = . ;
> -- 
> 1.7.10.4
> 

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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-04-15 12:33 ` [PATCH v3 07/16] x86/boot: create *.lnk files with linker script Daniel Kiper
@ 2016-04-15 14:04   ` Konrad Rzeszutek Wilk
  2016-05-24  9:05   ` Jan Beulich
  1 sibling, 0 replies; 94+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-04-15 14:04 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, stefano.stabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

> diff --git a/xen/arch/x86/boot/build32.lds b/xen/arch/x86/boot/build32.lds
> new file mode 100644
> index 0000000..47db9c4
> --- /dev/null
> +++ b/xen/arch/x86/boot/build32.lds
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
> + *      Daniel Kiper <daniel.kiper@oracle.com>

Drop the 'Daniel Kiper' part. Just Copyright (c) 2016 Oracle.

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

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

* Re: [PATCH v3 01/16] x86/boot: do not create unwind tables
  2016-04-15 12:33 ` [PATCH v3 01/16] x86/boot: do not create unwind tables Daniel Kiper
@ 2016-04-15 15:45   ` Andrew Cooper
  0 siblings, 0 replies; 94+ messages in thread
From: Andrew Cooper @ 2016-04-15 15:45 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, jbeulich, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 15/04/16 13:33, Daniel Kiper wrote:
> This way .eh_frame section is not included in *.lnk and *.bin files.
> Hence, final e.g. reloc.bin file size is reduced from 408 bytes to
> 272 bytes and it contains only used code and data.
>
> Suggested-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

(Although this entire series is 4.8 material now)

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

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

* Re: [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb
  2016-04-15 12:33 ` [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb Daniel Kiper
  2016-04-15 13:57   ` Konrad Rzeszutek Wilk
@ 2016-04-15 15:48   ` Andrew Cooper
  1 sibling, 0 replies; 94+ messages in thread
From: Andrew Cooper @ 2016-04-15 15:48 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, jbeulich, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 15/04/16 13:33, Daniel Kiper wrote:
> Speedup BSS initialization by using stosl instead of stosb.
>
> Some may argue that Intel Ivy Bridge and later provide ERMSB feature.
> This means that "rep stosb" gives better throughput than "rep stosl" on
> above mentioned CPUs. However, this feature is only available on newer
> Intel processors and e.g. AMD does not provide it at all. So, stosb will
> just give real benefits and even beat stosl only on limited number of
> machines. On the other hand stosl will speedup BSS initialization on
> all x86 platforms. Hence, use stosl instead of stosb.
>
> Additionally, align relevant comment to coding style.
>
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v3 - suggestions/fixes:
>    - improve comments
>      (suggested by Konrad Rzeszutek Wilk),
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/boot/head.S |    5 +++--
>  xen/arch/x86/xen.lds.S   |    3 +++
>  2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index f3501fd..32a54a0 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 961f48f..6802da1 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -191,6 +191,8 @@ SECTIONS
>         CONSTRUCTORS
>    } :text
>  
> +  /* Align BSS to speedup its initialization. */
> +  . = ALIGN(4);

This is not needed.  There is already appropriate alignment before
__bss_start.

Also, you need to rebase this series onto staging - there are a lot of
changes you are missing.

~Andrew

>    .bss : {                     /* BSS */
>         . = ALIGN(STACK_SIZE);
>         __bss_start = .;
> @@ -205,6 +207,7 @@ SECTIONS
>         *(.bss.percpu.read_mostly)
>         . = ALIGN(SMP_CACHE_BYTES);
>         __per_cpu_data_end = .;
> +       . = ALIGN(4);
>         __bss_end = .;
>    } :text
>    _end = . ;


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

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

* Re: [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention
  2016-04-15 12:33 ` [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
@ 2016-04-15 15:56   ` Andrew Cooper
  2016-06-17  8:41     ` Daniel Kiper
  2016-05-24  8:42   ` Jan Beulich
  1 sibling, 1 reply; 94+ messages in thread
From: Andrew Cooper @ 2016-04-15 15:56 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, jbeulich, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 15/04/16 13:33, Daniel Kiper wrote:
> reloc() is not called according to cdecl calling convention.
> This makes confusion and does not scale well for more arguments.
> And patch adding multiboot2 protocol support have to pass 3
> arguments instead of 2. Hence, move reloc() call to cdecl
> calling convention.
>
> I add push %ebp/mov %esp,%ebp/leave instructions here. Though they
> are not strictly needed in this patch. However, then assembly code
> in patch adding multiboot2 protocol support is easier to read.
>
> Suggested-by: Jan Beulich <jbeulich@suse.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v3 - suggestions/fixes:
>    - simplify assembly in xen/arch/x86/boot/reloc.c file
>      (suggested by Jan Beulich),
>    - reorder arguments for reloc() call from xen/arch/x86/boot/head.S
>      (suggested by Jan Beulich),
>    - improve commit message
>      (suggested by Jan Beulich).
> ---
>  xen/arch/x86/boot/head.S  |    4 +++-
>  xen/arch/x86/boot/reloc.c |   18 ++++++++++++++----
>  2 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 32a54a0..28ac721 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    %eax                /* Boot trampoline address. */
> +        push    %ebx                /* Multiboot information 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..006f41d 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -10,15 +10,25 @@
>   *    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) = MULTIBOOT_INFORMATION_ADDRESS,
> + *   - 0x8(%esp) = BOOT_TRAMPOLINE_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  0xc(%ebp),%eax           \n"
> +    "    mov  %eax,alloc-1b(%ecx)      \n"
> +    "    push 0x8(%ebp)                \n"
> +    "    call reloc                    \n"
> +    "    leave                         \n"
> +    "    ret                           \n"
>      );
>  
>  /*

Come to think of this, why are we playing asm games like this at all?

This object file gets linked with head.o anyway, and the reloc()
function is safe to live anywhere in .init.text.  It might be worth
giving it a more descriptive name, as it would become a global symbol. 
How about relocate_trampoline_32bit() ?

~Andrew

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

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

* Re: [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention
  2016-04-15 12:33 ` [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
  2016-04-15 15:56   ` Andrew Cooper
@ 2016-05-24  8:42   ` Jan Beulich
  1 sibling, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-24  8:42 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -10,15 +10,25 @@
>   *    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) = MULTIBOOT_INFORMATION_ADDRESS,
> + *   - 0x8(%esp) = BOOT_TRAMPOLINE_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  0xc(%ebp),%eax           \n"
> +    "    mov  %eax,alloc-1b(%ecx)      \n"
> +    "    push 0x8(%ebp)                \n"
> +    "    call reloc                    \n"
> +    "    leave                         \n"
> +    "    ret                           \n"
>      );

If Andrew's suggestion to remove this asm() altogether doesn't
work out, then I do not see justification for adding a frame
pointer here - addressing through %esp should be quite fine.
Which in turn would eliminate the need to convert jmp to call.

Jan


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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-04-15 12:33 ` [PATCH v3 07/16] x86/boot: create *.lnk files with linker script Daniel Kiper
  2016-04-15 14:04   ` Konrad Rzeszutek Wilk
@ 2016-05-24  9:05   ` Jan Beulich
  2016-05-24 12:28     ` Daniel Kiper
  1 sibling, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-24  9:05 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> --- /dev/null
> +++ b/xen/arch/x86/boot/build32.lds
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
> + *      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/>.
> + */
> +
> +ENTRY(_start)
> +
> +SECTIONS
> +{
> +  /* Merge code and data into one section. */
> +  .text : {
> +        *(.text)
> +        *(.text.*)
> +        *(.rodata)

This (and the respective %.lnk rule change below) is not in line with
the patch description. It's further suspicious that you only handle
.rodata but not also .rodata.* here.

> +  }
> +
> +  /DISCARD/ : {
> +        /*
> +         * .got.plt section is used only by dynamic linker
> +         * and our output is not supposed to be loaded by
> +         * dynamic linker. Additionally, it just contains
> +         * .PLT0 which is referenced from nowhere. So, we
> +         * can safely drop .got.plt here.
> +         *
> +         * Ha! This should be really discarded here. However,
> +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
> +         * symbol too and it is used as a reference for relative
> +         * addressing (and only for that thing). Hence, ld
> +         * complains if we remove that section because it
> +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
> +         * section during conversion to plain binary format.
> +         * Please check build32.mk for more details.
> +         */
> +        /* *(.got.plt) */
> +  }

I'm afraid this needs more investigation: Afaik there should be no
reason for the linker to create an otherwise empty .got.plt in the
first place. And discarding it without being sure it is empty is not
that good an idea anyway.

Jan


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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-05-24  9:05   ` Jan Beulich
@ 2016-05-24 12:28     ` Daniel Kiper
  2016-05-24 12:52       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-24 12:28 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, May 24, 2016 at 03:05:06AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > --- /dev/null
> > +++ b/xen/arch/x86/boot/build32.lds
> > @@ -0,0 +1,49 @@
> > +/*
> > + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
> > + *      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/>.
> > + */
> > +
> > +ENTRY(_start)
> > +
> > +SECTIONS
> > +{
> > +  /* Merge code and data into one section. */
> > +  .text : {
> > +        *(.text)
> > +        *(.text.*)
> > +        *(.rodata)
>
> This (and the respective %.lnk rule change below) is not in line with
> the patch description. It's further suspicious that you only handle

I am not sure what exactly do you mean by that.

> .rodata but not also .rodata.* here.

I did this deliberately. I just want to take only these sections which I know that
contain required code and data. Nothing more. If in the future we find out that
.rodata.* (or anything else) is needed then we can add it later.

> > +  }
> > +
> > +  /DISCARD/ : {
> > +        /*
> > +         * .got.plt section is used only by dynamic linker
> > +         * and our output is not supposed to be loaded by
> > +         * dynamic linker. Additionally, it just contains
> > +         * .PLT0 which is referenced from nowhere. So, we
> > +         * can safely drop .got.plt here.
> > +         *
> > +         * Ha! This should be really discarded here. However,
> > +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
> > +         * symbol too and it is used as a reference for relative
> > +         * addressing (and only for that thing). Hence, ld
> > +         * complains if we remove that section because it
> > +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
> > +         * section during conversion to plain binary format.
> > +         * Please check build32.mk for more details.
> > +         */
> > +        /* *(.got.plt) */
> > +  }
>
> I'm afraid this needs more investigation: Afaik there should be no

I am not sure what else we should look for.

> reason for the linker to create an otherwise empty .got.plt in the

As I wrote above. It contains _GLOBAL_OFFSET_TABLE_ which is used
as a reference for relative addressing.

> first place. And discarding it without being sure it is empty is not
> that good an idea anyway.

Good point! Potentially we can check is it empty, excluding _GLOBAL_OFFSET_TABLE_
symbol, in build32.mk.

Anyway, there is a chance that these tricks will not be needed at all. I will
try to link 32-bit code directly into Xen binary using objcopy, etc. which
we discussed during hackathon.

Daniel

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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-05-24 12:28     ` Daniel Kiper
@ 2016-05-24 12:52       ` Jan Beulich
  2016-06-17  9:06         ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-24 12:52 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 24.05.16 at 14:28, <daniel.kiper@oracle.com> wrote:
> On Tue, May 24, 2016 at 03:05:06AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > --- /dev/null
>> > +++ b/xen/arch/x86/boot/build32.lds
>> > @@ -0,0 +1,49 @@
>> > +/*
>> > + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
>> > + *      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/>.
>> > + */
>> > +
>> > +ENTRY(_start)
>> > +
>> > +SECTIONS
>> > +{
>> > +  /* Merge code and data into one section. */
>> > +  .text : {
>> > +        *(.text)
>> > +        *(.text.*)
>> > +        *(.rodata)
>>
>> This (and the respective %.lnk rule change below) is not in line with
>> the patch description. It's further suspicious that you only handle
> 
> I am not sure what exactly do you mean by that.

Quoting your commit message: "...  merge all text and data sections
into one .text section." Contrast this to the limited set of sections
above.

>> .rodata but not also .rodata.* here.
> 
> I did this deliberately. I just want to take only these sections which I 
> know that
> contain required code and data. Nothing more. If in the future we find out 
> that
> .rodata.* (or anything else) is needed then we can add it later.
> 
>> > +  }
>> > +
>> > +  /DISCARD/ : {
>> > +        /*
>> > +         * .got.plt section is used only by dynamic linker
>> > +         * and our output is not supposed to be loaded by
>> > +         * dynamic linker. Additionally, it just contains
>> > +         * .PLT0 which is referenced from nowhere. So, we
>> > +         * can safely drop .got.plt here.
>> > +         *
>> > +         * Ha! This should be really discarded here. However,
>> > +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
>> > +         * symbol too and it is used as a reference for relative
>> > +         * addressing (and only for that thing). Hence, ld
>> > +         * complains if we remove that section because it
>> > +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
>> > +         * section during conversion to plain binary format.
>> > +         * Please check build32.mk for more details.
>> > +         */
>> > +        /* *(.got.plt) */
>> > +  }
>>
>> I'm afraid this needs more investigation: Afaik there should be no
> 
> I am not sure what else we should look for.

The reason why such an empty .got.plt gets created in the first place.
If e.g. that turns out to be a bug in (some versions of) binutils, then
that bug should be named here as the reason.

>> reason for the linker to create an otherwise empty .got.plt in the
> 
> As I wrote above. It contains _GLOBAL_OFFSET_TABLE_ which is used
> as a reference for relative addressing.

But we don't use any such, so without being needed I don't think
the symbol needs to be created.

>> first place. And discarding it without being sure it is empty is not
>> that good an idea anyway.
> 
> Good point! Potentially we can check is it empty, excluding 
> _GLOBAL_OFFSET_TABLE_ symbol, in build32.mk.

Well, your comment above says it have .PLT0, which means it's not
exactly empty.

Jan


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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-04-15 12:33 ` [PATCH v3 08/16] x86: add multiboot2 protocol support Daniel Kiper
@ 2016-05-24 15:46   ` Jan Beulich
  2016-05-25 16:34     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-24 15:46 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> @@ -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

If you already use :vararg here and above, please also use :req on
the other macro arguments.

> @@ -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
> +
> +multiboot2_header_start:
> +        /* Magic number indicating a Multiboot2 header. */
> +        .long   MULTIBOOT2_HEADER_MAGIC
> +        /* Architecture: i386. */
> +        .long   MULTIBOOT2_ARCHITECTURE_I386
> +        /* Multiboot2 header length. */
> +        .long   multiboot2_header_end - multiboot2_header_start
> +        /* Multiboot2 header checksum. */
> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> +                        (multiboot2_header_end - multiboot2_header_start))
> +
> +        /* 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)
> +multiboot2_header_end:

Imo "end" labels should always preferably be .L-prefixed, to avoid
them getting used by a consumer instead of another "proper" label
starting whatever comes next.

> @@ -82,10 +141,49 @@ __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+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%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

I'm missing a total size check, matching what meanwhile got added
to the C equivalent(s) of this loop. There's little point in doing it
there if it doesn't also get done here.

> @@ -41,7 +45,16 @@ 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))

What is the left typeof() needed for here? (I can see the point of
the right one.)

> +static multiboot_info_t *mbi2_mbi(u32 mbi_in)
> +{
> +    const multiboot2_memory_map_t *mmap_src;
> +    const multiboot2_tag_t *tag;
> +    /* Do not complain that mbi_out_mods is not initialized. */
> +    module_t *mbi_out_mods = (module_t *)0;

Do we not have a proper NULL available in this environment?

> +/* Multiboot 2 architectures. */
> +#define MULTIBOOT2_ARCHITECTURE_I386			0
> +#define MULTIBOOT2_ARCHITECTURE_MIPS32			4

What's the latter good for? I can't imagine this is a complete list...

Jan

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-04-15 12:33 ` [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c Daniel Kiper
@ 2016-05-25  7:03   ` Jan Beulich
  2016-05-25 16:45     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25  7:03 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> 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.

I do not view this as a valid reason for the change.

> Additionally, following patch adds efi struct flags member which
> is used during runtime to differentiate between legacy BIOS and
> EFI platforms and multiboot2 and EFI native loader. So, efi symbol
> have to proper representation in ELF and PE Xen image. Hence,
> define efi struct in xen/arch/x86/efi/stub.c and remove efi
> symbol from ld script.

Only this one is, afaic. The only request here would be to replace
"following" by e.g. "a subsequent", to make the description
independent of whether the two patches get committed together.

> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -8,6 +8,14 @@
>  const bool_t efi_enabled = 0;
>  #endif
>  
> +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
> +};

I don't view duplicating this here as a good approach - you'd better
move the existing instance elsewhere. If this was a temporary thing
(until a later patch), it might be acceptable, but since building without
EFI support will need to remain an option (for people using older tool
chains), I don't expect a later patch to remove this.

Jan


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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-04-15 12:33 ` [PATCH v3 10/16] efi: create efi_enabled() Daniel Kiper
@ 2016-05-25  7:20   ` Jan Beulich
  2016-05-25 17:15     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25  7:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -4,11 +4,8 @@
>  #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. */

This is pointless to add - the field will get zero-initialized anyway.

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

Surely this can be __set_bit()? It's also hard to see what setting this
flag has got to do with runtime services. But more on this below.

> @@ -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
>  };

This, again, is an unnecessary hunk. And in no case should you drop
the trailing comma - that's there for a reason.

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

So what does "platform" mean? Did you consider using the more fine
grained set of flags Linux uses nowadays? That would also eliminate
the odd connection to runtime services mentioned earlier.

And please add a comment making clear that these values are bit
positions to be used in the flags field below. I might also help to
move this right next to the structure field.

> @@ -40,6 +42,12 @@ 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. */

The comment leaves open which EFI_* values you actually refer to.
Hence another option would be to move those #define-s here.

> +static inline bool_t efi_enabled(int feature)

unsigned int

> +{
> +    return test_bit(feature, &efi.flags) != 0;
> +}

Please use the more conventional !! found elsewhere in our code.

Jan


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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-04-15 12:33 ` [PATCH v3 11/16] efi: build xen.gz with EFI code Daniel Kiper
@ 2016-05-25  7:53   ` Jan Beulich
  2016-05-25 19:07     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25  7:53 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> --- a/xen/arch/x86/efi/Makefile
> +++ b/xen/arch/x86/efi/Makefile
> @@ -1,14 +1,9 @@
>  CFLAGS += -fshort-wchar
>  
> -obj-y += stub.o
> -
> -create = test -e $(1) || touch -t 199901010000 $(1)
> -
>  efi := y$(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
> -
> -stub.o: $(extra-y)
> +obj-y := stub.o
> +obj-$(efi) := boot.init.o compat.o relocs-dummy.o runtime.o

I assume/hope all these adjustments work for all intended cases, but
they quite clearly leave stale bits in xen/arch/x86/Rules.mk: Its
references to efi/*.o should all go away now afaict.

> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
>      } *extra, *extra_head = NULL;
>  #endif
>  
> +    if ( !efi_enabled(EFI_PLATFORM) )
> +        return;

Arguably such checks would then better be put at the call site,
allowing the respective stubs to just BUG().

Also - what's your rule for where to put such efi_enabled() checks?
I would have expected them to get added to everything that has
a counterpart in stubs.c, but things like efi_get_time() or
efi_{halt,reset}_system() don't get any added. If those are
unreachable, I'd at least expect respective ASSERT()s to get added
there.

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

Please do not introduce behavioral differences to the current stub
implementations: This and ...

> @@ -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;

... this return -ENOSYS there.

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-04-15 12:33 ` [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator Daniel Kiper
@ 2016-05-25  8:39   ` Jan Beulich
  2016-05-25 19:48     ` Daniel Kiper
  2016-07-05 18:26   ` Daniel Kiper
  1 sibling, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25  8:39 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <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.

I don't see why that would be: Simply use an allocation type that
doesn't lead to the area getting consumed as normal RAM. Nor do
I see the kexec collision potential. Furthermore (and I think I've
said so before) ARM is already using AllocatePool() - just with an
unsuitable memory type -, so doing so on x86 too would allow for
efi_arch_allocate_mmap_buffer() to go away.

> Jan Beulich added 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).
> 
> However, this solution does not solve conflicts problem described in #1
> because EFI memory map is needed during Xen runtime after init phase.
> So, finally we would get back to #1. Hmmm... Should I check how Linux
> and others cope with that problem?

Ah, here you mention it actually. Yet you don't explain what conflict
potential you see once using EfiRuntimeServicesData for the allocation.

Jan


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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-04-15 12:33 ` [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2016-05-25  9:32   ` Jan Beulich
  2016-05-25 10:29     ` Jan Beulich
  2016-05-25 21:02     ` Daniel Kiper
  0 siblings, 2 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-25  9:32 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> @@ -100,19 +107,29 @@ multiboot2_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_ldr_mb2: .asciz "ERR: On EFI platform use latest Multiboot2 compatible bootloader!"

What is "latest" going to mean 5 years from now?

>          .section .init.text, "ax", @progbits
>  
>  bad_cpu:
>          mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> -        jmp     print_err
> +        mov     $0xB8000,%edi                   # VGA framebuffer
> +        jmp     1f
>  not_multiboot:
>          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> -print_err:
> -        mov     $0xB8000,%edi  # VGA framebuffer
> +        mov     $0xB8000,%edi                   # VGA framebuffer
> +        jmp     1f
> +mb2_too_old:
> +        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
> +        xor     %edi,%edi                       # No VGA framebuffer

Leaving aside that "framebuffer" really is a bad term here (we're
talking of text mode output after all), limiting the output to serial
isn't going to be very helpful in the field, I'm afraid. Even more so
that there's no guarantee for a UART to be at port 0x3f8. That's
not much of a problem for the other two messages as people are
unlikely to try to boot Xen on an unsuitable system, but I view it
as quite possible for Xen to be tried to get booted with an
unsuitable grub2.

IOW - this needs a better solution, presumably using EFI boot
service output functions.

> @@ -130,6 +149,130 @@ print_err:
>  .Lhalt: hlt
>          jmp     .Lhalt
>  
> +        .code64
> +
> +__efi64_start:

As long as we have split files under boot/, I think I'd prefer 64-bit
code to only go into x86_64.S.

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

What I've said above would also eliminate the need to switch to
32-bit mode just for emitting an error message and halting the
system.

> +efi_multiboot2_proto:

.Lefi_multiboot2_proto

> +        /*
> +         * Multiboot2 information address is 32-bit,
> +         * so, zero higher half of %rbx.
> +         */
> +        mov     %ebx,%ebx

Wait, no - that's a protocol bug then. We're being entered in 64-bit
mode here, so registers should be in 64-bit clean state.

> +        /* Skip Multiboot2 information fixed part. */
> +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%rcx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx

Or if there really was a reason to do the above, and if there is a
reason not to assume this data is located below 4Gb, then
calculations like this could avoid the REX64 prefix by using %ecx.

> +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 clear BSS twice and do not go into real mode. */
> +        movb    $1,skip_realmode(%rip)

How is the setting of skip_realmode related to the clearing of BSS?
Oh, I've found the connection below (albeit see there for its
validity), but I think mentioning this here is more confusing than
clarifying.

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

At least down to here it looks like this would better live in a C helper
function. Did you consider this?

> +run_bs:
> +        push    %rax
> +        push    %rdi
> +
> +        /*
> +         * Initialize BSS (no nasty surprises!).
> +         * It must be done earlier than in BIOS case
> +         * because efi_multiboot2() touches it.
> +         */
> +        lea     __bss_start(%rip),%rdi
> +        lea     __bss_end(%rip),%rcx
> +        sub     %rdi,%rcx
> +        shr     $3,%rcx
> +        xor     %eax,%eax
> +        rep     stosq

Please let's not repeat pre-existing mistakes: REP is not an
instruction, and STOSB is not an operand. IOW there should be
just a single space between the two.

> +        pop     %rdi
> +
> +        /*
> +         * IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable.
> +         * OUT: %rax - Highest available memory address below 1 MiB.
> +         *
> +         * MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO tag is not provided
> +         * on EFI platforms. Hence, it could not be used like
> +         * on legacy BIOS platforms.
> +         */
> +        call    efi_multiboot2
> +
> +        /* Convert memory address to bytes/16 and store it in safe place. */
> +        shr     $4,%rax
> +        mov     %rax,%rcx

Again, considering that the starting value in %rax here is an
address below 1Mb, no need to do the calculations on 64-bit
registers.

> +        pop     %rax
> +
> +        /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
> +        lea     trampoline_setup(%rip),%rdi

Same here - the branch below uses %edi only anyway.

> @@ -170,12 +313,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

According to the comment we're on the legacy BIOS boot path
here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
now even confused about the output handling there.

> @@ -221,6 +372,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 what if skip_realmode is set on a legacy BIOS system because
of the command line option or the use of TBOOT?

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

Please connect the two if()-s - afaiu you really only care about the
trampoline handling to not be done. Otherwise the new conditional
would probably rather belong on the (arch-independent) call site.

> +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);

__set_bit()

> +    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();
> +
> +    if ( gop )
> +        gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
> +
> +    efi_arch_edd();
> +
> +    /*
> +     * efi_arch_cpu() is not needed here. boot_cpu_data
> +     * is set later in xen/arch/x86/boot/head.S.
> +     */

That's not a good explanation. Is there any harm in calling it? If not,
I'd suggest calling it here just to avoid missing a dependency on what
it does in any of the functions called subsequently. If there is, the
precise details of that is what you should say here.

> +    efi_tables();
> +    setup_efi_pci();
> +    efi_variables();
> +
> +    if ( gop )
> +        efi_set_gop_mode(gop, gop_mode);
> +
> +    efi_exit_boot(ImageHandle, SystemTable);
> +
> +    /* Return highest available memory address below 1 MiB. */
> +    return cfg.addr;

Didn't you say on some systems all of the memory below 640k is in
use by boot/loader code/data? If so, what meaning has the value
you return here (I don't recall the consumer side special casing any
error value)?

> --- 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! */
> +}

Why not just BUG()? What exactly you do here doesn't seem to
matter, as the symbol is unreachable in this case anyway (you
only need it to please the linker).

> @@ -728,7 +728,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";
>      }

Stray braces.

> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -192,7 +192,7 @@ SECTIONS
>    } :text
>  
>    /* Align BSS to speedup its initialization. */
> -  . = ALIGN(4);
> +  . = ALIGN(8);
>    .bss : {                     /* BSS */
>         . = ALIGN(STACK_SIZE);
>         __bss_start = .;
> @@ -207,7 +207,7 @@ SECTIONS
>         *(.bss.percpu.read_mostly)
>         . = ALIGN(SMP_CACHE_BYTES);
>         __per_cpu_data_end = .;
> -       . = ALIGN(4);
> +       . = ALIGN(8);
>         __bss_end = .;

Is that really worth it? I.e. is going from STOSD to STOSQ really a
meaningful win?

> @@ -936,6 +947,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

So _neither_ of the two bits get set for ARM? I'm even more puzzled
now, and hence think even more that this can't be fine grained enough.

Jan

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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-05-25  9:32   ` Jan Beulich
@ 2016-05-25 10:29     ` Jan Beulich
  2016-05-25 21:02     ` Daniel Kiper
  1 sibling, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-25 10:29 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 11:32, <JBeulich@suse.com> wrote:
>>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> @@ -221,6 +372,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 what if skip_realmode is set on a legacy BIOS system because
> of the command line option or the use of TBOOT?

Oh, I see - this is still before command line parsing ran. The
commentary on this double purpose should be improved, I
think.

Jan


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

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

* Re: [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-04-15 12:33 ` [PATCH v3 14/16] x86/boot: implement early command line parser in C Daniel Kiper
@ 2016-05-25 10:33   ` Jan Beulich
  2016-05-25 21:36     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25 10:33 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> --- a/xen/arch/x86/boot/build32.lds
> +++ b/xen/arch/x86/boot/build32.lds
> @@ -25,6 +25,7 @@ SECTIONS
>          *(.text)
>          *(.text.*)
>          *(.rodata)
> +        *(.rodata.*)
>    }

Interesting - didn't you say you don't want this for now?

> --- /dev/null
> +++ b/xen/arch/x86/boot/cmdline.c
> @@ -0,0 +1,357 @@
> +/*
> + * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
> + *      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).

Any reason you can't just #include ".../common/string.c" here?

> +/*
> + * Space and TAB are obvious delimiters. However, I am
> + * adding "\n" and "\r" here too. Just in case when
> + * crazy bootloader/user put them somewhere.
> + */
> +#define DELIM_CHARS		" \n\r\t"
> +#define DELIM_CHARS_COMMA	DELIM_CHARS ","

static const char[] variables (or really just one, with the comma put
first and the non-comma variant indexing into that variable by 1)?

> +#define __packed	__attribute__((__packed__))

No way to include compiler.h here?

> +/*
> + * Compiler is not able to optimize regular strlen()
> + * if argument is well known string during build.
> + * Hence, introduce optimized strlen_opt().
> + */
> +#define strlen_opt(s) (sizeof(s) - 1)

Do we really care in this code?

> +/* 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_width;
> +    u16 vesa_height;
> +    u16 vesa_depth;
> +} early_boot_opts_t;

This "keeping in sync" should be automated in some way, e.g. via
a new header and suitable macroization.

> +static int strtoi(const char *s, const char *stop, const char **next)
> +{
> +    int base = 10, i, ores = 0, res = 0;

You don't even handle a '-' on the numbers here, so all the variables
and the function return type should be unsigned int afaict. And the
function name perhaps be strtoui().

> +    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;

strchr()?

> +        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');

With the four instances, how about latching tolower(*s) into a local
variable?

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

The || makes the two !! pointless.

Also please settle on which type you want to use for boolean
(find_opt()'s last parameter is "int", yet here you use "u8"), and
perhaps make yourself a bool_t.

> +static void vga_parse(const char *cmdline, early_boot_opts_t *ebo)
> +{
> +    const char *c;
> +    int tmp;
> +
> +    c = find_opt(cmdline, "vga=", 1);
> +
> +    if ( !c )
> +        return;
> +
> +    ebo->boot_vid_mode = ASK_VGA;
> +
> +    if ( !strmaxcmp(c, "current", DELIM_CHARS_COMMA) )
> +        ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
> +    else if ( !strsubcmp(c, "text-80x") )
> +    {
> +        c += strlen_opt("text-80x");
> +        ebo->boot_vid_mode = rows2vmode(strtoi(c, DELIM_CHARS_COMMA, NULL));
> +    }
> +    else if ( !strsubcmp(c, "gfx-") )
> +    {
> +        tmp = strtoi(c + strlen_opt("gfx-"), "x", &c);
> +
> +        if ( tmp < 0 || tmp > U16_MAX )
> +            return;
> +
> +        ebo->vesa_width = tmp;
> +
> +        /*
> +         * Increment c outside of strtoi() because otherwise some
> +         * compiler may complain with following message:
> +         * warning: operation on ‘c’ may be undefined.
> +         */
> +        ++c;
> +        tmp = strtoi(c, "x", &c);

The comment is pointless - the operation is firmly undefined if you
put it in the strtoi() invocation.

> +        if ( tmp < 0 || tmp > U16_MAX )
> +            return;
> +
> +        ebo->vesa_height = tmp;
> +
> +        tmp = strtoi(++c, DELIM_CHARS_COMMA, NULL);
> +
> +        if ( tmp < 0 || tmp > U16_MAX )
> +            return;
> +
> +        ebo->vesa_depth = tmp;
> +
> +        ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;

I realize this is reflecting original behavior, but now that you do it in
C, please leverage that fact and defer storing width and height until
you know the entire option was good.

> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -436,8 +436,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

Doesn't this belong in an earlier patch? It certainly doesn't get
moved here from cmdline.S.

> +        /* 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

Any reason not to leave at least this check to the C code?

> +        pushl   $sym_phys(early_boot_opts)
> +        pushl   MB_cmdline(%ebx)
>          call    cmdline_parse_early
> +        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */

I don't think such a comment is really useful (seems like I overlooked
a similar one in an earlier patch, on the reloc() invocation).

Jan

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

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

* Re: [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable
  2016-04-15 12:33 ` [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable Daniel Kiper
@ 2016-05-25 10:48   ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-25 10:48 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> 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.

I don't follow: If we have to specify a load address, and if the
loader is required to put us there or fail, how does the code being
made relocatable help? And how does moving ourselves from 1Mb
to 2Mb make it any less likely that the designated address range is
actually free? Perhaps it's just the description that's misleading
here...

Even with that resolved I expect - as a result of the discussion on
the hackathon - quite a bit of change to this patch, so I don't view
actually reviewing the code as usefully spent time.

Jan


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

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

* Re: [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-04-15 12:33 ` [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
@ 2016-05-25 11:03   ` Jan Beulich
  2016-06-01 13:35     ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-25 11:03 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> Add multiboot2 protocol support for relocatable images. Only GRUB2 with
> "multiboot2: Add support for relocatable images" patch understands
> that feature. Older multiboot protocol (regardless of version)
> compatible loaders ignore it and everything works as usual.

So with that I'm now sure that the previous patch is in need of a
better description.

> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -79,6 +79,13 @@ multiboot2_header_start:
>          /* 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_offset(start), /* Min load address. */ \
> +                   0xffffffff, /* Max load address (4 GiB - 1). */ \

Hardly - that would allow us to be loaded at 4G - 2M, no matter
how large the image. Or else the comment is misleading.

> @@ -178,30 +185,39 @@ efi_multiboot2_proto:
>          and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
>  
>  0:
> +        /* Get Xen image load base address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
> +        jne     1f
> +
> +        mov     MB2_load_base_addr(%rcx),%r15d
> +        sub     $XEN_IMG_OFFSET,%r15
> +        jmp     4f

Why do we need to read this from the table? Can't we easily calculate
this ourselves?

> +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 clear BSS twice and do not go into real mode. */
>          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

See why numeric labels are bad in situations like this? The (much)
earlier patch should use .L labels here, and the patch here then
should simply follow suit.

> @@ -313,14 +329,23 @@ multiboot2_proto:
>          and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>  
>  0:
> +        /* Get Xen image load base address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%ecx)
> +        jne     1f
> +
> +        mov     MB2_load_base_addr(%ecx),%esi
> +        sub     $XEN_IMG_OFFSET,%esi
> +        jmp     3f

The redundancy once again suggests some form of abstraction
(helper function, macro, ...).

Jan


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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-24 15:46   ` Jan Beulich
@ 2016-05-25 16:34     ` Daniel Kiper
  2016-05-26 10:28       ` Andrew Cooper
  2016-05-27  8:11       ` Jan Beulich
  0 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 16:34 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, May 24, 2016 at 09:46:13AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > @@ -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
>
> If you already use :vararg here and above, please also use :req on
> the other macro arguments.

Why?

> > @@ -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
> > +
> > +multiboot2_header_start:
> > +        /* Magic number indicating a Multiboot2 header. */
> > +        .long   MULTIBOOT2_HEADER_MAGIC
> > +        /* Architecture: i386. */
> > +        .long   MULTIBOOT2_ARCHITECTURE_I386
> > +        /* Multiboot2 header length. */
> > +        .long   multiboot2_header_end - multiboot2_header_start
> > +        /* Multiboot2 header checksum. */
> > +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> > +                        (multiboot2_header_end - multiboot2_header_start))
> > +
> > +        /* 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)
> > +multiboot2_header_end:
>
> Imo "end" labels should always preferably be .L-prefixed, to avoid
> them getting used by a consumer instead of another "proper" label
> starting whatever comes next.

Make sense, however, I am in line with multiboot1_header_end label here.
So, if we wish .L here then we should change multiboot1_header_end label
above too. Of course in separate patch.

> > @@ -82,10 +141,49 @@ __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+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
> > +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%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
>
> I'm missing a total size check, matching what meanwhile got added
> to the C equivalent(s) of this loop. There's little point in doing it
> there if it doesn't also get done here.

OK.

> > @@ -41,7 +45,16 @@ 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))
>
> What is the left typeof() needed for here? (I can see the point of
> the right one.)

AIUI, right typeof() is needed for "~" but it looks that left one is not
needed and could be safely removed.

> > +static multiboot_info_t *mbi2_mbi(u32 mbi_in)
> > +{
> > +    const multiboot2_memory_map_t *mmap_src;
> > +    const multiboot2_tag_t *tag;
> > +    /* Do not complain that mbi_out_mods is not initialized. */
> > +    module_t *mbi_out_mods = (module_t *)0;
>
> Do we not have a proper NULL available in this environment?

No, we should define it or include relevant header file.

> > +/* Multiboot 2 architectures. */
> > +#define MULTIBOOT2_ARCHITECTURE_I386			0
> > +#define MULTIBOOT2_ARCHITECTURE_MIPS32			4
>
> What's the latter good for? I can't imagine this is a complete list...

Surprisingly it is! However, TBH, it is not really used by us. Just
copied from GRUB2 multiboot2.h file for completeness.

Daniel

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-05-25  7:03   ` Jan Beulich
@ 2016-05-25 16:45     ` Daniel Kiper
  2016-05-27  8:16       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 16:45 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > 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.
>
> I do not view this as a valid reason for the change.

Why?

> > Additionally, following patch adds efi struct flags member which
> > is used during runtime to differentiate between legacy BIOS and
> > EFI platforms and multiboot2 and EFI native loader. So, efi symbol
> > have to proper representation in ELF and PE Xen image. Hence,
> > define efi struct in xen/arch/x86/efi/stub.c and remove efi
> > symbol from ld script.
>
> Only this one is, afaic. The only request here would be to replace
> "following" by e.g. "a subsequent", to make the description
> independent of whether the two patches get committed together.

OK.

> > --- a/xen/arch/x86/efi/stub.c
> > +++ b/xen/arch/x86/efi/stub.c
> > @@ -8,6 +8,14 @@
> >  const bool_t efi_enabled = 0;
> >  #endif
> >
> > +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
> > +};
>
> I don't view duplicating this here as a good approach - you'd better
> move the existing instance elsewhere. If this was a temporary thing
> (until a later patch), it might be acceptable, but since building without
> EFI support will need to remain an option (for people using older tool
> chains), I don't expect a later patch to remove this.

Do you think about separate C file which should contain efi struct
and should be included in stub.c and runtime.c? Or anything else?

Daniel

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-05-25  7:20   ` Jan Beulich
@ 2016-05-25 17:15     ` Daniel Kiper
  2016-05-26 10:31       ` Andrew Cooper
  2016-05-27  8:22       ` Jan Beulich
  0 siblings, 2 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 17:15 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > --- a/xen/arch/x86/efi/stub.c
> > +++ b/xen/arch/x86/efi/stub.c
> > @@ -4,11 +4,8 @@
> >  #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. */
>
> This is pointless to add - the field will get zero-initialized anyway.

Sure thing. However, I think that we should be clear here that
there is no default value for .flags (well, it is 0). Though if
you wish I can remove that.

> > --- a/xen/common/efi/boot.c
> > +++ b/xen/common/efi/boot.c
> > @@ -934,6 +934,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
>
> Surely this can be __set_bit()? It's also hard to see what setting this

OK.

> flag has got to do with runtime services. But more on this below.

Well, comment is not the best one here... I will fix it.

> > @@ -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
> >  };
>
> This, again, is an unnecessary hunk. And in no case should you drop

Ditto.

> the trailing comma - that's there for a reason.

What is the reason for trailing comma?

> > --- 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
>
> So what does "platform" mean? Did you consider using the more fine

It means "EFI platform". It differentiates from "legacy BIOS platform".

> grained set of flags Linux uses nowadays? That would also eliminate

I wish to use just basic idea. However, I am not going to copy all
stuff from Linux. We do not need that.

> the odd connection to runtime services mentioned earlier.

That is good point. I will think how to solve that in good way.

> And please add a comment making clear that these values are bit
> positions to be used in the flags field below. I might also help to
> move this right next to the structure field.

OK.

Daniel

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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-05-25  7:53   ` Jan Beulich
@ 2016-05-25 19:07     ` Daniel Kiper
  2016-05-27  8:31       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 19:07 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 01:53:31AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > --- a/xen/arch/x86/efi/Makefile
> > +++ b/xen/arch/x86/efi/Makefile
> > @@ -1,14 +1,9 @@
> >  CFLAGS += -fshort-wchar
> >
> > -obj-y += stub.o
> > -
> > -create = test -e $(1) || touch -t 199901010000 $(1)
> > -
> >  efi := y$(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
> > -
> > -stub.o: $(extra-y)
> > +obj-y := stub.o
> > +obj-$(efi) := boot.init.o compat.o relocs-dummy.o runtime.o
>
> I assume/hope all these adjustments work for all intended cases, but

I have done some tests and it looks that everything works.

> they quite clearly leave stale bits in xen/arch/x86/Rules.mk: Its

I suppose that you were thinking about xen/arch/x86/Makefile.

> references to efi/*.o should all go away now afaict.

OK.

> > --- a/xen/common/efi/boot.c
> > +++ b/xen/common/efi/boot.c
> > @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
> >      } *extra, *extra_head = NULL;
> >  #endif
> >
> > +    if ( !efi_enabled(EFI_PLATFORM) )
> > +        return;
>
> Arguably such checks would then better be put at the call site,
> allowing the respective stubs to just BUG().

Ugh... I am confused. Here http://lists.xen.org/archives/html/xen-devel/2015-08/msg01790.html
you asked for what is done above. So, what is your final decision?

> Also - what's your rule for where to put such efi_enabled() checks?
> I would have expected them to get added to everything that has
> a counterpart in stubs.c, but things like efi_get_time() or
> efi_{halt,reset}_system() don't get any added. If those are
> unreachable, I'd at least expect respective ASSERT()s to get added
> there.

I have added checks to functions which are called from common EFI/BIOS code.

> > --- 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;
>
> Please do not introduce behavioral differences to the current stub
> implementations: This and ...
>
> > @@ -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;
>
> ... this return -ENOSYS there.

OK.

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-05-25  8:39   ` Jan Beulich
@ 2016-05-25 19:48     ` Daniel Kiper
  2016-05-27  8:37       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 19:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <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.
>
> I don't see why that would be: Simply use an allocation type that
> doesn't lead to the area getting consumed as normal RAM. Nor do
> I see the kexec collision potential. Furthermore (and I think I've
> said so before) ARM is already using AllocatePool() - just with an
> unsuitable memory type -, so doing so on x86 too would allow for

Nope, they are using standard EfiLoaderData.

> efi_arch_allocate_mmap_buffer() to go away.

That would be great, so, I will think how to solve this issue.

> > Jan Beulich added 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).
> >
> > However, this solution does not solve conflicts problem described in #1
> > because EFI memory map is needed during Xen runtime after init phase.
> > So, finally we would get back to #1. Hmmm... Should I check how Linux
> > and others cope with that problem?
>
> Ah, here you mention it actually. Yet you don't explain what conflict
> potential you see once using EfiRuntimeServicesData for the allocation.

Good point! IMO, if crash kernel region conflicts with EfiRuntimeServices*
then we should display warning that it cannot be allocated. By the way,
once you mentioned that you have in your queue (I suppose that it is
extremely long) kdump patch which adds functionality to automatically
establish crash kernel region placement. I think that could solve (at
least partially) problem with conflicts. Could you post it?

Daniel

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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-05-25  9:32   ` Jan Beulich
  2016-05-25 10:29     ` Jan Beulich
@ 2016-05-25 21:02     ` Daniel Kiper
  2016-05-27  9:02       ` Jan Beulich
  1 sibling, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 21:02 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 03:32:37AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > @@ -100,19 +107,29 @@ multiboot2_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_ldr_mb2: .asciz "ERR: On EFI platform use latest Multiboot2 compatible bootloader!"
>
> What is "latest" going to mean 5 years from now?

:-))) I will try to fix it.

> >          .section .init.text, "ax", @progbits
> >
> >  bad_cpu:
> >          mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> > -        jmp     print_err
> > +        mov     $0xB8000,%edi                   # VGA framebuffer
> > +        jmp     1f
> >  not_multiboot:
> >          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> > -print_err:
> > -        mov     $0xB8000,%edi  # VGA framebuffer
> > +        mov     $0xB8000,%edi                   # VGA framebuffer
> > +        jmp     1f
> > +mb2_too_old:
> > +        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
> > +        xor     %edi,%edi                       # No VGA framebuffer
>
> Leaving aside that "framebuffer" really is a bad term here (we're
> talking of text mode output after all), limiting the output to serial

Yep, but then we should change this in other places too. Maybe in separate patch.

> isn't going to be very helpful in the field, I'm afraid. Even more so
> that there's no guarantee for a UART to be at port 0x3f8. That's

Right but we do not have big choice here at very early boot stage... :-(((

> not much of a problem for the other two messages as people are
> unlikely to try to boot Xen on an unsuitable system, but I view it
> as quite possible for Xen to be tried to get booted with an
> unsuitable grub2.
>
> IOW - this needs a better solution, presumably using EFI boot
> service output functions.

No way, here boot services are dead. GRUB2 (or other loader)
shutdown them... :-(((

> > @@ -130,6 +149,130 @@ print_err:
> >  .Lhalt: hlt
> >          jmp     .Lhalt
> >
> > +        .code64
> > +
> > +__efi64_start:
>
> As long as we have split files under boot/, I think I'd prefer 64-bit
> code to only go into x86_64.S.
>
> > +        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
>
> What I've said above would also eliminate the need to switch to
> 32-bit mode just for emitting an error message and halting the
> system.

It is not possible. We just know that we run on EFI platform here.
However, we are not able to get EFI SystemTable pointer.

> > +efi_multiboot2_proto:
>
> .Lefi_multiboot2_proto

OK if you insist. However, I think that we are loosing helpful
debug information this way.

> > +        /*
> > +         * Multiboot2 information address is 32-bit,
> > +         * so, zero higher half of %rbx.
> > +         */
> > +        mov     %ebx,%ebx
>
> Wait, no - that's a protocol bug then. We're being entered in 64-bit
> mode here, so registers should be in 64-bit clean state.

You mean higher half cleared. Right? This is not guaranteed.
Please check this: http://lists.gnu.org/archive/html/grub-devel/2016-03/msg00304.html

> > +        /* Skip Multiboot2 information fixed part. */
> > +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%rcx
> > +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
>
> Or if there really was a reason to do the above, and if there is a
> reason not to assume this data is located below 4Gb, then
> calculations like this could avoid the REX64 prefix by using %ecx.

Here you said something different:
  http://lists.xen.org/archives/html/xen-devel/2015-03/msg03557.html

So?

> > +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 clear BSS twice and do not go into real mode. */
> > +        movb    $1,skip_realmode(%rip)
>
> How is the setting of skip_realmode related to the clearing of BSS?
> Oh, I've found the connection below (albeit see there for its
> validity), but I think mentioning this here is more confusing than
> clarifying.

In general I have a problem skip_realmode. The name itself is confusing
here and there. Probably it should be changed. However, I do not have
idea for good compact name describing all skip_realmode usages. And I do
not think that we should add another variable which will be used in similar
way but with different name to clarify situation.

> > +        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
>
> At least down to here it looks like this would better live in a C helper
> function. Did you consider this?

I will think about it.

> > +run_bs:
> > +        push    %rax
> > +        push    %rdi
> > +
> > +        /*
> > +         * Initialize BSS (no nasty surprises!).
> > +         * It must be done earlier than in BIOS case
> > +         * because efi_multiboot2() touches it.
> > +         */
> > +        lea     __bss_start(%rip),%rdi
> > +        lea     __bss_end(%rip),%rcx
> > +        sub     %rdi,%rcx
> > +        shr     $3,%rcx
> > +        xor     %eax,%eax
> > +        rep     stosq
>
> Please let's not repeat pre-existing mistakes: REP is not an
> instruction, and STOSB is not an operand. IOW there should be
> just a single space between the two.

OK.

[...]

> > @@ -170,12 +313,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
>
> According to the comment we're on the legacy BIOS boot path
> here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
> now even confused about the output handling there.

It is correct. Old GRUB2 (or other legacy multiboot2 compatible boot
loader) which runs on EFI platform and does not have my features will
jump into that path. And we do not support that, so, we should fail
in the best possible way here.

Your comment suggest that code comment should be improved and
phrased precisely. I will do that.

> > @@ -221,6 +372,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 what if skip_realmode is set on a legacy BIOS system because
> of the command line option or the use of TBOOT?
>
> > --- 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 )
>
> Please connect the two if()-s - afaiu you really only care about the
> trampoline handling to not be done. Otherwise the new conditional
> would probably rather belong on the (arch-independent) call site.
>
> > +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);
>
> __set_bit()
>
> > +    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();
> > +
> > +    if ( gop )
> > +        gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
> > +
> > +    efi_arch_edd();
> > +
> > +    /*
> > +     * efi_arch_cpu() is not needed here. boot_cpu_data
> > +     * is set later in xen/arch/x86/boot/head.S.
> > +     */
>
> That's not a good explanation. Is there any harm in calling it? If not,
> I'd suggest calling it here just to avoid missing a dependency on what
> it does in any of the functions called subsequently. If there is, the
> precise details of that is what you should say here.

It looks that it should work. However, probably there was an reason for
which this call was disabled. So, I will reinvestigate the issue.

> > +    efi_tables();
> > +    setup_efi_pci();
> > +    efi_variables();
> > +
> > +    if ( gop )
> > +        efi_set_gop_mode(gop, gop_mode);
> > +
> > +    efi_exit_boot(ImageHandle, SystemTable);
> > +
> > +    /* Return highest available memory address below 1 MiB. */
> > +    return cfg.addr;
>
> Didn't you say on some systems all of the memory below 640k is in
> use by boot/loader code/data? If so, what meaning has the value
> you return here (I don't recall the consumer side special casing any
> error value)?

It is usually correct because boot services are dead here. However, if it
does not (e.g. somebody called Xen with mapbs argument) then we should fail
because there is no memory for trampoline.

> > --- 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! */
> > +}
>
> Why not just BUG()? What exactly you do here doesn't seem to
> matter, as the symbol is unreachable in this case anyway (you
> only need it to please the linker).

We should print meaningful message here using boot services.
To do that we need a few line of assembly probably. And BUG()
is not solution here.

> > @@ -728,7 +728,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";
> >      }
>
> Stray braces.
>
> > --- a/xen/arch/x86/xen.lds.S
> > +++ b/xen/arch/x86/xen.lds.S
> > @@ -192,7 +192,7 @@ SECTIONS
> >    } :text
> >
> >    /* Align BSS to speedup its initialization. */
> > -  . = ALIGN(4);
> > +  . = ALIGN(8);
> >    .bss : {                     /* BSS */
> >         . = ALIGN(STACK_SIZE);
> >         __bss_start = .;
> > @@ -207,7 +207,7 @@ SECTIONS
> >         *(.bss.percpu.read_mostly)
> >         . = ALIGN(SMP_CACHE_BYTES);
> >         __per_cpu_data_end = .;
> > -       . = ALIGN(4);
> > +       . = ALIGN(8);
> >         __bss_end = .;
>
> Is that really worth it? I.e. is going from STOSD to STOSQ really a
> meaningful win?

Probably yes but I do not think that anybody will be see boot time
difference. On the other hand why not do that? It does not cost a lot.

> > @@ -936,6 +947,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
>
> So _neither_ of the two bits get set for ARM? I'm even more puzzled
> now, and hence think even more that this can't be fine grained enough.

As I saw code around old efi_enabled, which was replaced by EFI_PLATFORM,
was changed recently. So, I must rethink this stuff too.

Daniel

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

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

* Re: [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-05-25 10:33   ` Jan Beulich
@ 2016-05-25 21:36     ` Daniel Kiper
  2016-05-27  9:33       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-05-25 21:36 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 04:33:54AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > --- a/xen/arch/x86/boot/build32.lds
> > +++ b/xen/arch/x86/boot/build32.lds
> > @@ -25,6 +25,7 @@ SECTIONS
> >          *(.text)
> >          *(.text.*)
> >          *(.rodata)
> > +        *(.rodata.*)
> >    }
>
> Interesting - didn't you say you don't want this for now?

Yep, however, I also said that we should add "*(.rodata.*)"
if it is needed. And it is needed here.

> > --- /dev/null
> > +++ b/xen/arch/x86/boot/cmdline.c
> > @@ -0,0 +1,357 @@
> > +/*
> > + * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
> > + *      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).
>
> Any reason you can't just #include ".../common/string.c" here?

I am confused. Sometimes you request to reduce number of such strange
includes and sometimes you ask me to do something contrary? So, what
is the rule behind these requests?

Additionally, there is a chance that final xen ELF file will be
unnecessary larger because it will contain unused functions. Wait,
maybe there is a linker option which allows us to remove unreferenced
objects from final output.

> > +/*
> > + * Space and TAB are obvious delimiters. However, I am
> > + * adding "\n" and "\r" here too. Just in case when
> > + * crazy bootloader/user put them somewhere.
> > + */
> > +#define DELIM_CHARS		" \n\r\t"
> > +#define DELIM_CHARS_COMMA	DELIM_CHARS ","
>
> static const char[] variables (or really just one, with the comma put
> first and the non-comma variant indexing into that variable by 1)?

OK.

> > +#define __packed	__attribute__((__packed__))
>
> No way to include compiler.h here?

Ditto.

> > +/*
> > + * Compiler is not able to optimize regular strlen()
> > + * if argument is well known string during build.
> > + * Hence, introduce optimized strlen_opt().
> > + */
> > +#define strlen_opt(s) (sizeof(s) - 1)
>
> Do we really care in this code?

Not to strongly but why not?

> > +/* 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_width;
> > +    u16 vesa_height;
> > +    u16 vesa_depth;
> > +} early_boot_opts_t;
>
> This "keeping in sync" should be automated in some way, e.g. via
> a new header and suitable macroization.

OK.

> > +static int strtoi(const char *s, const char *stop, const char **next)
> > +{
> > +    int base = 10, i, ores = 0, res = 0;
>
> You don't even handle a '-' on the numbers here, so all the variables

Yep, however, ...

> and the function return type should be unsigned int afaict. And the
> function name perhaps be strtoui().

... we return -1 in case of error.

> > +    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;
>
> strchr()?

Could be.

> > +        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');
>
> With the four instances, how about latching tolower(*s) into a local
> variable?

Make sense.

> > +static u8 skip_realmode(const char *cmdline)
> > +{
> > +    return !!find_opt(cmdline, "no-real-mode", 0) || !!find_opt(cmdline, "tboot=", 1);
>
> The || makes the two !! pointless.
>
> Also please settle on which type you want to use for boolean
> (find_opt()'s last parameter is "int", yet here you use "u8"), and

Could be u8.

> perhaps make yourself a bool_t.

I do not think it make sense here.

> > +static void vga_parse(const char *cmdline, early_boot_opts_t *ebo)
> > +{
> > +    const char *c;
> > +    int tmp;
> > +
> > +    c = find_opt(cmdline, "vga=", 1);
> > +
> > +    if ( !c )
> > +        return;
> > +
> > +    ebo->boot_vid_mode = ASK_VGA;
> > +
> > +    if ( !strmaxcmp(c, "current", DELIM_CHARS_COMMA) )
> > +        ebo->boot_vid_mode = VIDEO_CURRENT_MODE;
> > +    else if ( !strsubcmp(c, "text-80x") )
> > +    {
> > +        c += strlen_opt("text-80x");
> > +        ebo->boot_vid_mode = rows2vmode(strtoi(c, DELIM_CHARS_COMMA, NULL));
> > +    }
> > +    else if ( !strsubcmp(c, "gfx-") )
> > +    {
> > +        tmp = strtoi(c + strlen_opt("gfx-"), "x", &c);
> > +
> > +        if ( tmp < 0 || tmp > U16_MAX )
> > +            return;
> > +
> > +        ebo->vesa_width = tmp;
> > +
> > +        /*
> > +         * Increment c outside of strtoi() because otherwise some
> > +         * compiler may complain with following message:
> > +         * warning: operation on ‘c’ may be undefined.
> > +         */
> > +        ++c;
> > +        tmp = strtoi(c, "x", &c);
>
> The comment is pointless - the operation is firmly undefined if you
> put it in the strtoi() invocation.

In terms of C spec you are right. However, it is quite surprising that older
GCC complains and newer ones do not. Should not we investigate this?

> > +        if ( tmp < 0 || tmp > U16_MAX )
> > +            return;
> > +
> > +        ebo->vesa_height = tmp;
> > +
> > +        tmp = strtoi(++c, DELIM_CHARS_COMMA, NULL);
> > +
> > +        if ( tmp < 0 || tmp > U16_MAX )
> > +            return;
> > +
> > +        ebo->vesa_depth = tmp;
> > +
> > +        ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;
>
> I realize this is reflecting original behavior, but now that you do it in
> C, please leverage that fact and defer storing width and height until
> you know the entire option was good.

OK.

> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -436,8 +436,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
>
> Doesn't this belong in an earlier patch? It certainly doesn't get
> moved here from cmdline.S.

Potentially.

> > +        /* 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
>
> Any reason not to leave at least this check to the C code?

OK.

> > +        pushl   $sym_phys(early_boot_opts)
> > +        pushl   MB_cmdline(%ebx)
> >          call    cmdline_parse_early
> > +        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
>
> I don't think such a comment is really useful (seems like I overlooked
> a similar one in an earlier patch, on the reloc() invocation).

This thing is quite obvious but I do not think that this comment hurts.

Daniel

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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-25 16:34     ` Daniel Kiper
@ 2016-05-26 10:28       ` Andrew Cooper
  2016-05-27  8:08         ` Jan Beulich
  2016-05-27  8:11       ` Jan Beulich
  1 sibling, 1 reply; 94+ messages in thread
From: Andrew Cooper @ 2016-05-26 10:28 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei


>>> @@ -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
>>> +
>>> +multiboot2_header_start:
>>> +        /* Magic number indicating a Multiboot2 header. */
>>> +        .long   MULTIBOOT2_HEADER_MAGIC
>>> +        /* Architecture: i386. */
>>> +        .long   MULTIBOOT2_ARCHITECTURE_I386
>>> +        /* Multiboot2 header length. */
>>> +        .long   multiboot2_header_end - multiboot2_header_start
>>> +        /* Multiboot2 header checksum. */
>>> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
>>> +                        (multiboot2_header_end - multiboot2_header_start))
>>> +
>>> +        /* 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)
>>> +multiboot2_header_end:
>> Imo "end" labels should always preferably be .L-prefixed, to avoid
>> them getting used by a consumer instead of another "proper" label
>> starting whatever comes next.
> Make sense, however, I am in line with multiboot1_header_end label here.
> So, if we wish .L here then we should change multiboot1_header_end label
> above too. Of course in separate patch.

The multiboot1 header is very specifically not a local label, so you can
distinguish the actual header from the 3 nops following it in the
disassembly.

~Andrew

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-05-25 17:15     ` Daniel Kiper
@ 2016-05-26 10:31       ` Andrew Cooper
  2016-05-27  8:22       ` Jan Beulich
  1 sibling, 0 replies; 94+ messages in thread
From: Andrew Cooper @ 2016-05-26 10:31 UTC (permalink / raw)
  To: Daniel Kiper, Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei


>>> @@ -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
>>>  };
>> This, again, is an unnecessary hunk. And in no case should you drop
> Ditto.
>
>> the trailing comma - that's there for a reason.
> What is the reason for trailing comma?

If you put in a trailing comma, subsequent patches to add a further item
become a 1 line addition, rather than a 1 subtraction and 2 addition.

It makes patches for future additions smaller and more clear.

~Andrew

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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-26 10:28       ` Andrew Cooper
@ 2016-05-27  8:08         ` Jan Beulich
  2016-05-27  8:13           ` Andrew Cooper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:08 UTC (permalink / raw)
  To: Andrew Cooper, Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 26.05.16 at 12:28, <andrew.cooper3@citrix.com> 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
>>>> +
>>>> +multiboot2_header_start:
>>>> +        /* Magic number indicating a Multiboot2 header. */
>>>> +        .long   MULTIBOOT2_HEADER_MAGIC
>>>> +        /* Architecture: i386. */
>>>> +        .long   MULTIBOOT2_ARCHITECTURE_I386
>>>> +        /* Multiboot2 header length. */
>>>> +        .long   multiboot2_header_end - multiboot2_header_start
>>>> +        /* Multiboot2 header checksum. */
>>>> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + 
> \
>>>> +                        (multiboot2_header_end - multiboot2_header_start))
>>>> +
>>>> +        /* 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)
>>>> +multiboot2_header_end:
>>> Imo "end" labels should always preferably be .L-prefixed, to avoid
>>> them getting used by a consumer instead of another "proper" label
>>> starting whatever comes next.
>> Make sense, however, I am in line with multiboot1_header_end label here.
>> So, if we wish .L here then we should change multiboot1_header_end label
>> above too. Of course in separate patch.
> 
> The multiboot1 header is very specifically not a local label, so you can
> distinguish the actual header from the 3 nops following it in the
> disassembly.

I don't follow: Those NOPs (also not sure why you think it's three of
them) are there just for padding (alignment), so no need to label
them. Plus with the patch in place they would now appear after the
multiboot2 header.

Jan


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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-25 16:34     ` Daniel Kiper
  2016-05-26 10:28       ` Andrew Cooper
@ 2016-05-27  8:11       ` Jan Beulich
  1 sibling, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:11 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 18:34, <daniel.kiper@oracle.com> wrote:
> On Tue, May 24, 2016 at 09:46:13AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > @@ -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
>>
>> If you already use :vararg here and above, please also use :req on
>> the other macro arguments.
> 
> Why?

Because they're not allowed to be blank, yet it looks like if they
are left blank no error would otherwise be reported by gas?

>> > @@ -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
>> > +
>> > +multiboot2_header_start:
>> > +        /* Magic number indicating a Multiboot2 header. */
>> > +        .long   MULTIBOOT2_HEADER_MAGIC
>> > +        /* Architecture: i386. */
>> > +        .long   MULTIBOOT2_ARCHITECTURE_I386
>> > +        /* Multiboot2 header length. */
>> > +        .long   multiboot2_header_end - multiboot2_header_start
>> > +        /* Multiboot2 header checksum. */
>> > +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
>> > +                        (multiboot2_header_end - multiboot2_header_start))
>> > +
>> > +        /* 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)
>> > +multiboot2_header_end:
>>
>> Imo "end" labels should always preferably be .L-prefixed, to avoid
>> them getting used by a consumer instead of another "proper" label
>> starting whatever comes next.
> 
> Make sense, however, I am in line with multiboot1_header_end label here.
> So, if we wish .L here then we should change multiboot1_header_end label
> above too. Of course in separate patch.

Sure. My main point (as always) is that stuff that's there without a
good reason shouldn't be cloned. At least the clone should be done
right from the beginning. Cleaning up existing code is appreciated,
but secondary.

Jan


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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-27  8:08         ` Jan Beulich
@ 2016-05-27  8:13           ` Andrew Cooper
  2016-05-27  8:24             ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Andrew Cooper @ 2016-05-27  8:13 UTC (permalink / raw)
  To: Jan Beulich, Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 27/05/16 09:08, Jan Beulich wrote:
>>>> On 26.05.16 at 12:28, <andrew.cooper3@citrix.com> 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
>>>>> +
>>>>> +multiboot2_header_start:
>>>>> +        /* Magic number indicating a Multiboot2 header. */
>>>>> +        .long   MULTIBOOT2_HEADER_MAGIC
>>>>> +        /* Architecture: i386. */
>>>>> +        .long   MULTIBOOT2_ARCHITECTURE_I386
>>>>> +        /* Multiboot2 header length. */
>>>>> +        .long   multiboot2_header_end - multiboot2_header_start
>>>>> +        /* Multiboot2 header checksum. */
>>>>> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + 
>> \
>>>>> +                        (multiboot2_header_end - multiboot2_header_start))
>>>>> +
>>>>> +        /* 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)
>>>>> +multiboot2_header_end:
>>>> Imo "end" labels should always preferably be .L-prefixed, to avoid
>>>> them getting used by a consumer instead of another "proper" label
>>>> starting whatever comes next.
>>> Make sense, however, I am in line with multiboot1_header_end label here.
>>> So, if we wish .L here then we should change multiboot1_header_end label
>>> above too. Of course in separate patch.
>> The multiboot1 header is very specifically not a local label, so you can
>> distinguish the actual header from the 3 nops following it in the
>> disassembly.
> I don't follow: Those NOPs (also not sure why you think it's three of
> them) are there just for padding (alignment), so no need to label
> them.

That wasn't the point I was trying to make.

This is data in a code segment, so objdump/gdb disassembly tries to
disassemble the data as instructions.

While the instruction decode of the header is definitely junk, having
the end label proves an exact boundary for the data in terms of reported
raw bytes, as well as prevent the following nops being subsumed into the
bogus decode.

~Andrew

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-05-25 16:45     ` Daniel Kiper
@ 2016-05-27  8:16       ` Jan Beulich
  2016-06-01 15:07         ` Daniel Kiper
  2016-07-05 18:33         ` Daniel Kiper
  0 siblings, 2 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:16 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > 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.
>>
>> I do not view this as a valid reason for the change.
> 
> Why?

Because there are no accesses to the structure in non-EFI builds?
Even if it's just a small table, I'm generally opposed to adding dead
code or data. I simply do not like the attitude of "memory is cheap"
these days. Following that model leads to quite a bit of useless
bloat. Plus no matter whether memory is cheap, cache and TLB
bandwidth are precious, and both may get pressure added by such
dead elements.

>> > --- a/xen/arch/x86/efi/stub.c
>> > +++ b/xen/arch/x86/efi/stub.c
>> > @@ -8,6 +8,14 @@
>> >  const bool_t efi_enabled = 0;
>> >  #endif
>> >
>> > +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
>> > +};
>>
>> I don't view duplicating this here as a good approach - you'd better
>> move the existing instance elsewhere. If this was a temporary thing
>> (until a later patch), it might be acceptable, but since building without
>> EFI support will need to remain an option (for people using older tool
>> chains), I don't expect a later patch to remove this.
> 
> Do you think about separate C file which should contain efi struct
> and should be included in stub.c and runtime.c? Or anything else?

A separate file seems to be overkill. Just move it to some other
existing file; I'm sure some sensible place can be found.

Jan


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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-05-25 17:15     ` Daniel Kiper
  2016-05-26 10:31       ` Andrew Cooper
@ 2016-05-27  8:22       ` Jan Beulich
  2016-06-01 15:23         ` Daniel Kiper
  1 sibling, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:22 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 19:15, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > --- a/xen/arch/x86/efi/stub.c
>> > +++ b/xen/arch/x86/efi/stub.c
>> > @@ -4,11 +4,8 @@
>> >  #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. */
>>
>> This is pointless to add - the field will get zero-initialized anyway.
> 
> Sure thing. However, I think that we should be clear here that
> there is no default value for .flags (well, it is 0). Though if
> you wish I can remove that.

As you say, the initial value for flags is zero, with or without your
addition. Hence the addition is pointless.

>> > --- 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
>>
>> So what does "platform" mean? Did you consider using the more fine
> 
> It means "EFI platform". It differentiates from "legacy BIOS platform".

Well, that's what was clear from the beginning. The question however
was (taken together with the second one) what it means functionality
wise. The later addition makes clear it doesn't mean "loaded directly
from EFI". But looking at the various flags Linux has here, what
functionality does it imply? Does it e.g. mean runtime services are to
be used? If so, the flag would need to be cleared when their use if
being suppressed.

>> grained set of flags Linux uses nowadays? That would also eliminate
> 
> I wish to use just basic idea. However, I am not going to copy all
> stuff from Linux. We do not need that.

We don't need all of it, sure. But some more fine grained
identification of what functionality is available / to be used
would surely benefit us as a whole and your patch series in
particular.

Jan


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

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

* Re: [PATCH v3 08/16] x86: add multiboot2 protocol support
  2016-05-27  8:13           ` Andrew Cooper
@ 2016-05-27  8:24             ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:24 UTC (permalink / raw)
  To: Andrew Cooper, Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 27.05.16 at 10:13, <andrew.cooper3@citrix.com> wrote:
> On 27/05/16 09:08, Jan Beulich wrote:
>>>>> On 26.05.16 at 12:28, <andrew.cooper3@citrix.com> 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
>>>>>> +
>>>>>> +multiboot2_header_start:
>>>>>> +        /* Magic number indicating a Multiboot2 header. */
>>>>>> +        .long   MULTIBOOT2_HEADER_MAGIC
>>>>>> +        /* Architecture: i386. */
>>>>>> +        .long   MULTIBOOT2_ARCHITECTURE_I386
>>>>>> +        /* Multiboot2 header length. */
>>>>>> +        .long   multiboot2_header_end - multiboot2_header_start
>>>>>> +        /* Multiboot2 header checksum. */
>>>>>> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + 
>>> \
>>>>>> +                        (multiboot2_header_end - multiboot2_header_start))
>>>>>> +
>>>>>> +        /* 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)
>>>>>> +multiboot2_header_end:
>>>>> Imo "end" labels should always preferably be .L-prefixed, to avoid
>>>>> them getting used by a consumer instead of another "proper" label
>>>>> starting whatever comes next.
>>>> Make sense, however, I am in line with multiboot1_header_end label here.
>>>> So, if we wish .L here then we should change multiboot1_header_end label
>>>> above too. Of course in separate patch.
>>> The multiboot1 header is very specifically not a local label, so you can
>>> distinguish the actual header from the 3 nops following it in the
>>> disassembly.
>> I don't follow: Those NOPs (also not sure why you think it's three of
>> them) are there just for padding (alignment), so no need to label
>> them.
> 
> That wasn't the point I was trying to make.
> 
> This is data in a code segment, so objdump/gdb disassembly tries to
> disassemble the data as instructions.
> 
> While the instruction decode of the header is definitely junk, having
> the end label proves an exact boundary for the data in terms of reported
> raw bytes, as well as prevent the following nops being subsumed into the
> bogus decode.

Where the NOPs go doesn't matter. The only relevant thing for
disassembly is that the next actual instruction gets decoded
correctly. And that next instruction follows its own label
(__high_start). Let's please not carry more symbols at runtime
than are really useful.

Jan


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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-05-25 19:07     ` Daniel Kiper
@ 2016-05-27  8:31       ` Jan Beulich
  2016-06-01 15:48         ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:31 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 21:07, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 01:53:31AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > --- a/xen/arch/x86/efi/Makefile
>> > +++ b/xen/arch/x86/efi/Makefile
>> > @@ -1,14 +1,9 @@
>> >  CFLAGS += -fshort-wchar
>> >
>> > -obj-y += stub.o
>> > -
>> > -create = test -e $(1) || touch -t 199901010000 $(1)
>> > -
>> >  efi := y$(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
>> > -
>> > -stub.o: $(extra-y)
>> > +obj-y := stub.o
>> > +obj-$(efi) := boot.init.o compat.o relocs-dummy.o runtime.o
>>
>> I assume/hope all these adjustments work for all intended cases, but
> 
> I have done some tests and it looks that everything works.
> 
>> they quite clearly leave stale bits in xen/arch/x86/Rules.mk: Its
> 
> I suppose that you were thinking about xen/arch/x86/Makefile.

Oh, yes, of course.

>> references to efi/*.o should all go away now afaict.
> 
> OK.
> 
>> > --- a/xen/common/efi/boot.c
>> > +++ b/xen/common/efi/boot.c
>> > @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
>> >      } *extra, *extra_head = NULL;
>> >  #endif
>> >
>> > +    if ( !efi_enabled(EFI_PLATFORM) )
>> > +        return;
>>
>> Arguably such checks would then better be put at the call site,
>> allowing the respective stubs to just BUG().
> 
> Ugh... I am confused. Here 
> http://lists.xen.org/archives/html/xen-devel/2015-08/msg01790.html 
> you asked for what is done above. So, what is your final decision?

Well, in v2 you didn't alter stubs.c at all. It's that connection
which makes me think using that earlier approach might be better.
The more that, from a purely abstract pov, it could even allow to
remove some or all of stubs.c in a truly non-EFI build, provided we
never build with -O0.

But in the end, starting the sens with "arguably" I mean to express
that this isn't all that important.

>> Also - what's your rule for where to put such efi_enabled() checks?
>> I would have expected them to get added to everything that has
>> a counterpart in stubs.c, but things like efi_get_time() or
>> efi_{halt,reset}_system() don't get any added. If those are
>> unreachable, I'd at least expect respective ASSERT()s to get added
>> there.
> 
> I have added checks to functions which are called from common EFI/BIOS code.

And how are the ones I named not called from "common" code?

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-05-25 19:48     ` Daniel Kiper
@ 2016-05-27  8:37       ` Jan Beulich
  2016-06-01 15:58         ` Daniel Kiper
  2016-06-01 16:01         ` Daniel Kiper
  0 siblings, 2 replies; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  8:37 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <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.
>>
>> I don't see why that would be: Simply use an allocation type that
>> doesn't lead to the area getting consumed as normal RAM. Nor do
>> I see the kexec collision potential. Furthermore (and I think I've
>> said so before) ARM is already using AllocatePool() - just with an
>> unsuitable memory type -, so doing so on x86 too would allow for
> 
> Nope, they are using standard EfiLoaderData.

Note how I said "just with an unsuitable memory type"?

>> > Jan Beulich added 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).
>> >
>> > However, this solution does not solve conflicts problem described in #1
>> > because EFI memory map is needed during Xen runtime after init phase.
>> > So, finally we would get back to #1. Hmmm... Should I check how Linux
>> > and others cope with that problem?
>>
>> Ah, here you mention it actually. Yet you don't explain what conflict
>> potential you see once using EfiRuntimeServicesData for the allocation.
> 
> Good point! IMO, if crash kernel region conflicts with EfiRuntimeServices*
> then we should display warning that it cannot be allocated. By the way,
> once you mentioned that you have in your queue (I suppose that it is
> extremely long) kdump patch which adds functionality to automatically
> establish crash kernel region placement. I think that could solve (at
> least partially) problem with conflicts. Could you post it?

For one, unless asked to be at a specific location, we already dynamically
place that area. The patch that I believe you think of just enhances the
placement to have something between "fully dynamic" and "at a fixed
place". I've never posted it (or even ported it to -unstable) because I've
never got positive feedback on it by those who it was originally created
for. If you think it could be useful, I can certainly revive it.

Jan


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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-05-25 21:02     ` Daniel Kiper
@ 2016-05-27  9:02       ` Jan Beulich
  2016-06-01 19:03         ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  9:02 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 23:02, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 03:32:37AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >  bad_cpu:
>> >          mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
>> > -        jmp     print_err
>> > +        mov     $0xB8000,%edi                   # VGA framebuffer
>> > +        jmp     1f
>> >  not_multiboot:
>> >          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
>> > -print_err:
>> > -        mov     $0xB8000,%edi  # VGA framebuffer
>> > +        mov     $0xB8000,%edi                   # VGA framebuffer
>> > +        jmp     1f
>> > +mb2_too_old:
>> > +        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
>> > +        xor     %edi,%edi                       # No VGA framebuffer
>>
>> Leaving aside that "framebuffer" really is a bad term here (we're
>> talking of text mode output after all), limiting the output to serial
> 
> Yep, but then we should change this in other places too. Maybe in separate 
> patch.

Since you touch (move) it, replacing the word "framebuffer" wouldn't
seem like something making the patch any more difficult to understand.

>> isn't going to be very helpful in the field, I'm afraid. Even more so
>> that there's no guarantee for a UART to be at port 0x3f8. That's
> 
> Right but we do not have big choice here at very early boot stage... :-(((

Excuse me? You're running on EFI, so you have full infrastructure
available to you. As much as in a normal BIOS scenario (and on a
half way normal system) we can assume a text mode screen with
video memory mapped at B8000, under EFI we can assume output
capabilities (whichever the system owner set up in the firmware
setup).

>> not much of a problem for the other two messages as people are
>> unlikely to try to boot Xen on an unsuitable system, but I view it
>> as quite possible for Xen to be tried to get booted with an
>> unsuitable grub2.
>>
>> IOW - this needs a better solution, presumably using EFI boot
>> service output functions.
> 
> No way, here boot services are dead. GRUB2 (or other loader)
> shutdown them... :-(((

Wasn't one of your grub2 changes being precisely the deferral of
that to Xen?

>> > +        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
>>
>> What I've said above would also eliminate the need to switch to
>> 32-bit mode just for emitting an error message and halting the
>> system.
> 
> It is not possible. We just know that we run on EFI platform here.
> However, we are not able to get EFI SystemTable pointer.

How are we not able? Later C code does it afair, so why would it not
be possible here?

>> > +efi_multiboot2_proto:
>>
>> .Lefi_multiboot2_proto
> 
> OK if you insist. However, I think that we are loosing helpful
> debug information this way.

I don't see why or how. Labels persisting in the final symbol table
are useful only for generating stack traces, yet if you crash this
early there won't be any stack trace anyway - you don't even
have an IDT set up yet.

>> > +        /*
>> > +         * Multiboot2 information address is 32-bit,
>> > +         * so, zero higher half of %rbx.
>> > +         */
>> > +        mov     %ebx,%ebx
>>
>> Wait, no - that's a protocol bug then. We're being entered in 64-bit
>> mode here, so registers should be in 64-bit clean state.
> 
> You mean higher half cleared. Right? This is not guaranteed.

Hence me saying "that's a protocol bug then".

> Please check this: 
> http://lists.gnu.org/archive/html/grub-devel/2016-03/msg00304.html 

Other than the description of the patch I can't see anything like that,
in particular
- no occurrence of "ebx" in any of the added or changed code
- MULTIBOOT_EFI_MBI_REGISTER getting #define-d as rbx

>> > +        /* Skip Multiboot2 information fixed part. */
>> > +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%rcx
>> > +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
>>
>> Or if there really was a reason to do the above, and if there is a
>> reason not to assume this data is located below 4Gb, then
>> calculations like this could avoid the REX64 prefix by using %ecx.
> 
> Here you said something different:
>   http://lists.xen.org/archives/html/xen-devel/2015-03/msg03557.html 
> 
> So?

So? You simply went too far: There talk was of memory accesses,
i.e. the (%rbx) part of the instruction above. Using (%ebx) there
would cause a pointless address size override prefix emitted. Now
in the new form above you force a pointless REX prefix to be
emitted. The whole point of both of my requests is - avoid prefixes
if you don't really need them.

>> > +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 clear BSS twice and do not go into real mode. */
>> > +        movb    $1,skip_realmode(%rip)
>>
>> How is the setting of skip_realmode related to the clearing of BSS?
>> Oh, I've found the connection below (albeit see there for its
>> validity), but I think mentioning this here is more confusing than
>> clarifying.
> 
> In general I have a problem skip_realmode. The name itself is confusing
> here and there. Probably it should be changed. However, I do not have
> idea for good compact name describing all skip_realmode usages. And I do
> not think that we should add another variable which will be used in similar
> way but with different name to clarify situation.

Just clarify things by suitable (brief) comments?

>> > @@ -170,12 +313,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
>>
>> According to the comment we're on the legacy BIOS boot path
>> here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
>> now even confused about the output handling there.
> 
> It is correct. Old GRUB2 (or other legacy multiboot2 compatible boot
> loader) which runs on EFI platform and does not have my features will
> jump into that path. And we do not support that, so, we should fail
> in the best possible way here.
> 
> Your comment suggest that code comment should be improved and
> phrased precisely. I will do that.

Not necessarily: First of all you didn't clarify what video mode we're
in in that old-grub2 case. Do we have text mode? If so, output should
not be avoided. And if we're in a graphical mode without any vga=
option that grub2 may have chosen to interpret, that would smell like
a bug in grub2.

>> > +    efi_tables();
>> > +    setup_efi_pci();
>> > +    efi_variables();
>> > +
>> > +    if ( gop )
>> > +        efi_set_gop_mode(gop, gop_mode);
>> > +
>> > +    efi_exit_boot(ImageHandle, SystemTable);

(Btw, regarding your earlier statement of boot services being
unavailable in the early assembly entry code: Here is the
exit-boot-services place, i.e. up to here boot services can be used,
which therefore includes the assembly part of the boot path.)

>> > --- 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! */
>> > +}
>>
>> Why not just BUG()? What exactly you do here doesn't seem to
>> matter, as the symbol is unreachable in this case anyway (you
>> only need it to please the linker).
> 
> We should print meaningful message here using boot services.

Which boot services? We're not running on EFI if we get here. And
as said, this function is unreachable on non-EFI afaict, so ...

> To do that we need a few line of assembly probably. And BUG()
> is not solution here.

... I don't follow you here.

>> > --- a/xen/arch/x86/xen.lds.S
>> > +++ b/xen/arch/x86/xen.lds.S
>> > @@ -192,7 +192,7 @@ SECTIONS
>> >    } :text
>> >
>> >    /* Align BSS to speedup its initialization. */
>> > -  . = ALIGN(4);
>> > +  . = ALIGN(8);
>> >    .bss : {                     /* BSS */
>> >         . = ALIGN(STACK_SIZE);
>> >         __bss_start = .;
>> > @@ -207,7 +207,7 @@ SECTIONS
>> >         *(.bss.percpu.read_mostly)
>> >         . = ALIGN(SMP_CACHE_BYTES);
>> >         __per_cpu_data_end = .;
>> > -       . = ALIGN(4);
>> > +       . = ALIGN(8);
>> >         __bss_end = .;
>>
>> Is that really worth it? I.e. is going from STOSD to STOSQ really a
>> meaningful win?
> 
> Probably yes but I do not think that anybody will be see boot time
> difference. On the other hand why not do that? It does not cost a lot.

But it grows an already largish patch.

Jan

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

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

* Re: [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-05-25 21:36     ` Daniel Kiper
@ 2016-05-27  9:33       ` Jan Beulich
  2016-06-02  8:15         ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-05-27  9:33 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 25.05.16 at 23:36, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 04:33:54AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > --- /dev/null
>> > +++ b/xen/arch/x86/boot/cmdline.c
>> > @@ -0,0 +1,357 @@
>> > +/*
>> > + * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
>> > + *      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).
>>
>> Any reason you can't just #include ".../common/string.c" here?
> 
> I am confused. Sometimes you request to reduce number of such strange
> includes and sometimes you ask me to do something contrary? So, what
> is the rule behind these requests?

The rule is "whatever fits best for the current purpose". Such
"strange" includes should be avoided if their purpose can be
fulfilled by other means. Them being avoided at the price of
quite a bit of code duplication, otoh, doesn't seem well advised
to me.

>> > +/*
>> > + * Compiler is not able to optimize regular strlen()
>> > + * if argument is well known string during build.
>> > + * Hence, introduce optimized strlen_opt().
>> > + */
>> > +#define strlen_opt(s) (sizeof(s) - 1)
>>
>> Do we really care in this code?
> 
> Not to strongly but why not?

Keep things as readable as possible. In fact I wouldn't mind hard
coded literal numbers for the string lengths, if they sit right next
to the respective string literal.

>> > +static int strtoi(const char *s, const char *stop, const char **next)
>> > +{
>> > +    int base = 10, i, ores = 0, res = 0;
>>
>> You don't even handle a '-' on the numbers here, so all the variables
> 
> Yep, however, ...
> 
>> and the function return type should be unsigned int afaict. And the
>> function name perhaps be strtoui().
> 
> ... we return -1 in case of error.

Which - having looked at some of the callers - could easily be
UINT_MAX as it seems.

>> > +static u8 skip_realmode(const char *cmdline)
>> > +{
>> > +    return !!find_opt(cmdline, "no-real-mode", 0) || !!find_opt(cmdline, 
> "tboot=", 1);
>>
>> The || makes the two !! pointless.
>>
>> Also please settle on which type you want to use for boolean
>> (find_opt()'s last parameter is "int", yet here you use "u8"), and
> 
> Could be u8.
> 
>> perhaps make yourself a bool_t.
> 
> I do not think it make sense here.

I think it makes as much or as little sense as having NULL available.

>> > +        /*
>> > +         * Increment c outside of strtoi() because otherwise some
>> > +         * compiler may complain with following message:
>> > +         * warning: operation on ‘c’ may be undefined.
>> > +         */
>> > +        ++c;
>> > +        tmp = strtoi(c, "x", &c);
>>
>> The comment is pointless - the operation is firmly undefined if you
>> put it in the strtoi() invocation.
> 
> In terms of C spec you are right. However, it is quite surprising that older
> GCC complains and newer ones do not. Should not we investigate this?

Actually I think I was wrong here. A function call like func(c++, c)
would be undefined, but func(c++, &c) isn't. So I guess if there are
compiler versions getting this wrong, then you should just disregard
my comment.

>> > +        pushl   $sym_phys(early_boot_opts)
>> > +        pushl   MB_cmdline(%ebx)
>> >          call    cmdline_parse_early
>> > +        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
>>
>> I don't think such a comment is really useful (seems like I overlooked
>> a similar one in an earlier patch, on the reloc() invocation).
> 
> This thing is quite obvious but I do not think that this comment hurts.

It may not really hurt, but it draws needless attention to something
that is to b expected after any function call getting arguments
passed on the stack. You could, btw., make cmdline_parse_early
a stdcall function, so you wouldn't have to do that adjustment
here.

Jan

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

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

* Re: [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-05-25 11:03   ` Jan Beulich
@ 2016-06-01 13:35     ` Daniel Kiper
  2016-06-01 14:44       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 13:35 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, May 25, 2016 at 05:03:20AM -0600, Jan Beulich wrote:
> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> > Add multiboot2 protocol support for relocatable images. Only GRUB2 with
> > "multiboot2: Add support for relocatable images" patch understands
> > that feature. Older multiboot protocol (regardless of version)
> > compatible loaders ignore it and everything works as usual.
>
> So with that I'm now sure that the previous patch is in need of a
> better description.

OK.

> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -79,6 +79,13 @@ multiboot2_header_start:
> >          /* 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_offset(start), /* Min load address. */ \
> > +                   0xffffffff, /* Max load address (4 GiB - 1). */ \
>
> Hardly - that would allow us to be loaded at 4G - 2M, no matter
> how large the image. Or else the comment is misleading.

This is the highest address at which memory region allocated for image
may end. You should remember that image itself can be smaller (Xen
image is smaller) than its initial memory requirements.

> > @@ -178,30 +185,39 @@ efi_multiboot2_proto:
> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
> >
> >  0:
> > +        /* Get Xen image load base address from Multiboot2 information. */
> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
> > +        jne     1f
> > +
> > +        mov     MB2_load_base_addr(%rcx),%r15d
> > +        sub     $XEN_IMG_OFFSET,%r15
> > +        jmp     4f
>
> Why do we need to read this from the table? Can't we easily calculate
> this ourselves?

Potentially yes but why do not use data from boot loader?

> > +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 clear BSS twice and do not go into real mode. */
> >          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
>
> See why numeric labels are bad in situations like this? The (much)
> earlier patch should use .L labels here, and the patch here then
> should simply follow suit.

Then we should change legacy multiboot (v1) code too. Just to be in line
new stuff here. Does it pays? And I am not sure that patching convenience
overweight convenience of numeric labels here.

> > @@ -313,14 +329,23 @@ multiboot2_proto:
> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> >
> >  0:
> > +        /* Get Xen image load base address from Multiboot2 information. */
> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%ecx)
> > +        jne     1f
> > +
> > +        mov     MB2_load_base_addr(%ecx),%esi
> > +        sub     $XEN_IMG_OFFSET,%esi
> > +        jmp     3f
>
> The redundancy once again suggests some form of abstraction
> (helper function, macro, ...).

Do you suggest that we should macroize multiboot2 header accesses?

Daniel

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

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

* Re: [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-06-01 13:35     ` Daniel Kiper
@ 2016-06-01 14:44       ` Jan Beulich
  2016-06-01 19:16         ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-01 14:44 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 15:35, <daniel.kiper@oracle.com> wrote:
> On Wed, May 25, 2016 at 05:03:20AM -0600, Jan Beulich wrote:
>> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> > --- a/xen/arch/x86/boot/head.S
>> > +++ b/xen/arch/x86/boot/head.S
>> > @@ -79,6 +79,13 @@ multiboot2_header_start:
>> >          /* 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_offset(start), /* Min load address. */ \
>> > +                   0xffffffff, /* Max load address (4 GiB - 1). */ \
>>
>> Hardly - that would allow us to be loaded at 4G - 2M, no matter
>> how large the image. Or else the comment is misleading.
> 
> This is the highest address at which memory region allocated for image
> may end.

You saying "end" then means the comment is misleading.

>> > @@ -178,30 +185,39 @@ efi_multiboot2_proto:
>> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
>> >
>> >  0:
>> > +        /* Get Xen image load base address from Multiboot2 information. */
>> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
>> > +        jne     1f
>> > +
>> > +        mov     MB2_load_base_addr(%rcx),%r15d
>> > +        sub     $XEN_IMG_OFFSET,%r15
>> > +        jmp     4f
>>
>> Why do we need to read this from the table? Can't we easily calculate
>> this ourselves?
> 
> Potentially yes but why do not use data from boot loader?

Because it's (a) likely easier to just calculate and (b) we should
perhaps trust ourselves more than an external entity?

>> > +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 clear BSS twice and do not go into real mode. */
>> >          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
>>
>> See why numeric labels are bad in situations like this? The (much)
>> earlier patch should use .L labels here, and the patch here then
>> should simply follow suit.
> 
> Then we should change legacy multiboot (v1) code too. Just to be in line
> new stuff here. Does it pays? And I am not sure that patching convenience
> overweight convenience of numeric labels here.

Well, it's always this same discussion: Bad examples shouldn't be
used as excuse to add further bad examples. If you feel like also
changing the mb1 code - go for it. But if you don't, I'm fine with
just new code avoiding old mistakes.

>> > @@ -313,14 +329,23 @@ multiboot2_proto:
>> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
>> >
>> >  0:
>> > +        /* Get Xen image load base address from Multiboot2 information. */
>> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%ecx)
>> > +        jne     1f
>> > +
>> > +        mov     MB2_load_base_addr(%ecx),%esi
>> > +        sub     $XEN_IMG_OFFSET,%esi
>> > +        jmp     3f
>>
>> The redundancy once again suggests some form of abstraction
>> (helper function, macro, ...).
> 
> Do you suggest that we should macroize multiboot2 header accesses?

The whole logic here. And if macros (rather than functions), then
I'm thinking of assembler macros more than of C ones. All I really
wish is that we don't have the same kind of code in multiple places,
even more so when we talk about assembly code.

Jan

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-05-27  8:16       ` Jan Beulich
@ 2016-06-01 15:07         ` Daniel Kiper
  2016-07-05 18:33         ` Daniel Kiper
  1 sibling, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 15:07 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> > 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.
> >>
> >> I do not view this as a valid reason for the change.
> >
> > Why?
>
> Because there are no accesses to the structure in non-EFI builds?
> Even if it's just a small table, I'm generally opposed to adding dead
> code or data. I simply do not like the attitude of "memory is cheap"
> these days. Following that model leads to quite a bit of useless

I concur!

> bloat. Plus no matter whether memory is cheap, cache and TLB
> bandwidth are precious, and both may get pressure added by such
> dead elements.

OK, but in the future please add a few words of comment in such
cases because it is not obvious why just looking at code.

Daniel

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-05-27  8:22       ` Jan Beulich
@ 2016-06-01 15:23         ` Daniel Kiper
  2016-06-01 15:41           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 15:23 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:22:39AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 19:15, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:

[...]

> >> > --- 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
> >>
> >> So what does "platform" mean? Did you consider using the more fine
> >
> > It means "EFI platform". It differentiates from "legacy BIOS platform".
>
> Well, that's what was clear from the beginning. The question however
> was (taken together with the second one) what it means functionality
> wise. The later addition makes clear it doesn't mean "loaded directly

This means that we run on EFI platform and we can use its features,
e.g. runtime services, get info from it about ACPI, SMBIOS, etc.

> from EFI". But looking at the various flags Linux has here, what

Yep.

> functionality does it imply? Does it e.g. mean runtime services are to
> be used? If so, the flag would need to be cleared when their use if

As above: not only.

> being suppressed.

If we need that (e.g. for ARM) then we should create e.g. EFI_RS.

> >> grained set of flags Linux uses nowadays? That would also eliminate
> >
> > I wish to use just basic idea. However, I am not going to copy all
> > stuff from Linux. We do not need that.
>
> We don't need all of it, sure. But some more fine grained
> identification of what functionality is available / to be used
> would surely benefit us as a whole and your patch series in
> particular.

As above.

Daniel

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-06-01 15:23         ` Daniel Kiper
@ 2016-06-01 15:41           ` Jan Beulich
  2016-06-01 19:28             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-01 15:41 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 17:23, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 02:22:39AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 19:15, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> 
> [...]
> 
>> >> > --- 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
>> >>
>> >> So what does "platform" mean? Did you consider using the more fine
>> >
>> > It means "EFI platform". It differentiates from "legacy BIOS platform".
>>
>> Well, that's what was clear from the beginning. The question however
>> was (taken together with the second one) what it means functionality
>> wise. The later addition makes clear it doesn't mean "loaded directly
> 
> This means that we run on EFI platform and we can use its features,
> e.g. runtime services, get info from it about ACPI, SMBIOS, etc.
> 
>> from EFI". But looking at the various flags Linux has here, what
> 
> Yep.
> 
>> functionality does it imply? Does it e.g. mean runtime services are to
>> be used? If so, the flag would need to be cleared when their use if
> 
> As above: not only.

I.e. we're back at me asking you to make this at least a little more
fine grained.

>> being suppressed.
> 
> If we need that (e.g. for ARM) then we should create e.g. EFI_RS.

Why only then? We already can suppress the use of runtime services.

>> >> grained set of flags Linux uses nowadays? That would also eliminate
>> >
>> > I wish to use just basic idea. However, I am not going to copy all
>> > stuff from Linux. We do not need that.
>>
>> We don't need all of it, sure. But some more fine grained
>> identification of what functionality is available / to be used
>> would surely benefit us as a whole and your patch series in
>> particular.
> 
> As above.

Well, above you don't really reason on why this coarse granularity
is good enough. Hence my response can only be: As above.

Jan


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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-05-27  8:31       ` Jan Beulich
@ 2016-06-01 15:48         ` Daniel Kiper
  2016-06-01 15:58           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 15:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:31:52AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 21:07, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 01:53:31AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:

[...]

> >> > --- a/xen/common/efi/boot.c
> >> > +++ b/xen/common/efi/boot.c
> >> > @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
> >> >      } *extra, *extra_head = NULL;
> >> >  #endif
> >> >
> >> > +    if ( !efi_enabled(EFI_PLATFORM) )
> >> > +        return;
> >>
> >> Arguably such checks would then better be put at the call site,
> >> allowing the respective stubs to just BUG().
> >
> > Ugh... I am confused. Here
> > http://lists.xen.org/archives/html/xen-devel/2015-08/msg01790.html
> > you asked for what is done above. So, what is your final decision?
>
> Well, in v2 you didn't alter stubs.c at all. It's that connection
> which makes me think using that earlier approach might be better.
> The more that, from a purely abstract pov, it could even allow to
> remove some or all of stubs.c in a truly non-EFI build, provided we
> never build with -O0.

I am not sure why "provided we never build with -O0".

> But in the end, starting the sens with "arguably" I mean to express
> that this isn't all that important.

OK.

> >> Also - what's your rule for where to put such efi_enabled() checks?
> >> I would have expected them to get added to everything that has
> >> a counterpart in stubs.c, but things like efi_get_time() or
> >> efi_{halt,reset}_system() don't get any added. If those are
> >> unreachable, I'd at least expect respective ASSERT()s to get added
> >> there.
> >
> > I have added checks to functions which are called from common EFI/BIOS code.
>
> And how are the ones I named not called from "common" code?

efi_get_time() call is protected by "if ( efi_enabled(EFI_PLATFORM) )"
in xen/arch/x86/time.c. efi_halt_system() is called from nowhere, so,
it can be removed. I will do that. efi_reset_system() call is protected
by different means but EFI related. So, all of them are not called
from "common" code during runtime on BIOS platforms.

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-05-27  8:37       ` Jan Beulich
@ 2016-06-01 15:58         ` Daniel Kiper
  2016-06-01 16:02           ` Jan Beulich
  2016-06-01 16:01         ` Daniel Kiper
  1 sibling, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 15:58 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <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.
> >>
> >> I don't see why that would be: Simply use an allocation type that
> >> doesn't lead to the area getting consumed as normal RAM. Nor do
> >> I see the kexec collision potential. Furthermore (and I think I've
> >> said so before) ARM is already using AllocatePool() - just with an
> >> unsuitable memory type -, so doing so on x86 too would allow for
> >
> > Nope, they are using standard EfiLoaderData.
>
> Note how I said "just with an unsuitable memory type"?

Could you be more precise?

Daniel

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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-06-01 15:48         ` Daniel Kiper
@ 2016-06-01 15:58           ` Jan Beulich
  2016-06-01 19:39             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-01 15:58 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 17:48, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 02:31:52AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 21:07, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 01:53:31AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> > --- a/xen/common/efi/boot.c
>> >> > +++ b/xen/common/efi/boot.c
>> >> > @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
>> >> >      } *extra, *extra_head = NULL;
>> >> >  #endif
>> >> >
>> >> > +    if ( !efi_enabled(EFI_PLATFORM) )
>> >> > +        return;
>> >>
>> >> Arguably such checks would then better be put at the call site,
>> >> allowing the respective stubs to just BUG().
>> >
>> > Ugh... I am confused. Here
>> > http://lists.xen.org/archives/html/xen-devel/2015-08/msg01790.html 
>> > you asked for what is done above. So, what is your final decision?
>>
>> Well, in v2 you didn't alter stubs.c at all. It's that connection
>> which makes me think using that earlier approach might be better.
>> The more that, from a purely abstract pov, it could even allow to
>> remove some or all of stubs.c in a truly non-EFI build, provided we
>> never build with -O0.
> 
> I am not sure why "provided we never build with -O0".

Because a minimal amount of optimization is necessary for dead
calls to actually get eliminated.

>> >> Also - what's your rule for where to put such efi_enabled() checks?
>> >> I would have expected them to get added to everything that has
>> >> a counterpart in stubs.c, but things like efi_get_time() or
>> >> efi_{halt,reset}_system() don't get any added. If those are
>> >> unreachable, I'd at least expect respective ASSERT()s to get added
>> >> there.
>> >
>> > I have added checks to functions which are called from common EFI/BIOS 
> code.
>>
>> And how are the ones I named not called from "common" code?
> 
> efi_get_time() call is protected by "if ( efi_enabled(EFI_PLATFORM) )"
> in xen/arch/x86/time.c. efi_halt_system() is called from nowhere, so,
> it can be removed. I will do that.

Please don't. Instead it should get wired up properly (in
machine_halt()).

> efi_reset_system() call is protected
> by different means but EFI related.

Where is that being protected? Nothing prevents anyone to boot
with "reboot=efi" on a non-EFI system. That's silly, but shouldn't
result in a crash during reboot. Right now its stub is intentionally
doing nothing (instead of BUG()ing).

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-05-27  8:37       ` Jan Beulich
  2016-06-01 15:58         ` Daniel Kiper
@ 2016-06-01 16:01         ` Daniel Kiper
  1 sibling, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 16:01 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:

[...]

> >> > Jan Beulich added 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).
> >> >
> >> > However, this solution does not solve conflicts problem described in #1
> >> > because EFI memory map is needed during Xen runtime after init phase.
> >> > So, finally we would get back to #1. Hmmm... Should I check how Linux
> >> > and others cope with that problem?
> >>
> >> Ah, here you mention it actually. Yet you don't explain what conflict
> >> potential you see once using EfiRuntimeServicesData for the allocation.
> >
> > Good point! IMO, if crash kernel region conflicts with EfiRuntimeServices*
> > then we should display warning that it cannot be allocated. By the way,
> > once you mentioned that you have in your queue (I suppose that it is
> > extremely long) kdump patch which adds functionality to automatically
> > establish crash kernel region placement. I think that could solve (at
> > least partially) problem with conflicts. Could you post it?
>
> For one, unless asked to be at a specific location, we already dynamically
> place that area. The patch that I believe you think of just enhances the

Hmmm... I do not know why I always thought that it is not supported in Xen.

> placement to have something between "fully dynamic" and "at a fixed
> place". I've never posted it (or even ported it to -unstable) because I've
> never got positive feedback on it by those who it was originally created
> for. If you think it could be useful, I can certainly revive it.

Once again, thanks for doing that.

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-06-01 15:58         ` Daniel Kiper
@ 2016-06-01 16:02           ` Jan Beulich
  2016-06-01 19:53             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-01 16:02 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 17:58, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <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.
>> >>
>> >> I don't see why that would be: Simply use an allocation type that
>> >> doesn't lead to the area getting consumed as normal RAM. Nor do
>> >> I see the kexec collision potential. Furthermore (and I think I've
>> >> said so before) ARM is already using AllocatePool() - just with an
>> >> unsuitable memory type -, so doing so on x86 too would allow for
>> >
>> > Nope, they are using standard EfiLoaderData.
>>
>> Note how I said "just with an unsuitable memory type"?
> 
> Could you be more precise?

What else do you need? Just have the arch specify the memory type to
be used (if ARM really _means_ to use that seemingly wrong type), and
make the rest of the code common.

Jan


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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-05-27  9:02       ` Jan Beulich
@ 2016-06-01 19:03         ` Daniel Kiper
  2016-06-02  8:34           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 19:03 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 03:02:25AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 23:02, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 03:32:37AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> >  bad_cpu:
> >> >          mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> >> > -        jmp     print_err
> >> > +        mov     $0xB8000,%edi                   # VGA framebuffer
> >> > +        jmp     1f
> >> >  not_multiboot:
> >> >          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> >> > -print_err:
> >> > -        mov     $0xB8000,%edi  # VGA framebuffer
> >> > +        mov     $0xB8000,%edi                   # VGA framebuffer
> >> > +        jmp     1f
> >> > +mb2_too_old:
> >> > +        mov     $(sym_phys(.Lbad_ldr_mb2)),%esi # Error message
> >> > +        xor     %edi,%edi                       # No VGA framebuffer
> >>
> >> Leaving aside that "framebuffer" really is a bad term here (we're
> >> talking of text mode output after all), limiting the output to serial
> >
> > Yep, but then we should change this in other places too. Maybe in separate
> > patch.
>
> Since you touch (move) it, replacing the word "framebuffer" wouldn't
> seem like something making the patch any more difficult to understand.
>
> >> isn't going to be very helpful in the field, I'm afraid. Even more so
> >> that there's no guarantee for a UART to be at port 0x3f8. That's
> >
> > Right but we do not have big choice here at very early boot stage... :-(((
>
> Excuse me? You're running on EFI, so you have full infrastructure
> available to you. As much as in a normal BIOS scenario (and on a
> half way normal system) we can assume a text mode screen with
> video memory mapped at B8000, under EFI we can assume output
> capabilities (whichever the system owner set up in the firmware
> setup).

Potentially we can do that for bad_cpu only. However, does it pays?
I suppose that most, if not all, platforms with UEFI have CPUs with
X86_FEATURE_LM.

Sadly, It it not feasible for not_multiboot and mb2_too_old. Former
means that we were loaded by unknown boot loader and interface is
not defined. Hence, we are not able to get anything from EFI. Latter
means that we were booted via older multiboot2 version which shutdown
boot services.

> >> not much of a problem for the other two messages as people are
> >> unlikely to try to boot Xen on an unsuitable system, but I view it
> >> as quite possible for Xen to be tried to get booted with an
> >> unsuitable grub2.
> >>
> >> IOW - this needs a better solution, presumably using EFI boot
> >> service output functions.
> >
> > No way, here boot services are dead. GRUB2 (or other loader)
> > shutdown them... :-(((
>
> Wasn't one of your grub2 changes being precisely the deferral of
> that to Xen?

Sure, but if we are here then it means that we were loaded by earlier multiboot2
protocol version which does not understand features added by me.

> >> > +        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
> >>
> >> What I've said above would also eliminate the need to switch to
> >> 32-bit mode just for emitting an error message and halting the
> >> system.
> >
> > It is not possible. We just know that we run on EFI platform here.
> > However, we are not able to get EFI SystemTable pointer.
>
> How are we not able? Later C code does it afair, so why would it not
> be possible here?

Ditto.

> >> > +efi_multiboot2_proto:
> >>
> >> .Lefi_multiboot2_proto
> >
> > OK if you insist. However, I think that we are loosing helpful
> > debug information this way.
>
> I don't see why or how. Labels persisting in the final symbol table
> are useful only for generating stack traces, yet if you crash this
> early there won't be any stack trace anyway - you don't even
> have an IDT set up yet.

OK, but it is much easier to identify addresses for breakpoints if you
have proper labels. And this one looks quite useful.

> >> > +        /*
> >> > +         * Multiboot2 information address is 32-bit,
> >> > +         * so, zero higher half of %rbx.
> >> > +         */
> >> > +        mov     %ebx,%ebx
> >>
> >> Wait, no - that's a protocol bug then. We're being entered in 64-bit
> >> mode here, so registers should be in 64-bit clean state.
> >
> > You mean higher half cleared. Right? This is not guaranteed.
>
> Hence me saying "that's a protocol bug then".

Why? Protocol strictly says that "this is not guaranteed".
What is the problem with that? Potentially loader can set
%rbx higher half to e.g. 0 but I do not think it is needed.

> > Please check this:
> > http://lists.gnu.org/archive/html/grub-devel/2016-03/msg00304.html
>
> Other than the description of the patch I can't see anything like that,
> in particular
> - no occurrence of "ebx" in any of the added or changed code
> - MULTIBOOT_EFI_MBI_REGISTER getting #define-d as rbx

Please check multiboot2 spec, section 3.2, Machine state. It is not
freshest one (I am working on EFI updates right now) but I hope that it,
together with patch comment, will shed some light.

> >> > +        /* Skip Multiboot2 information fixed part. */
> >> > +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%rcx
> >> > +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
> >>
> >> Or if there really was a reason to do the above, and if there is a
> >> reason not to assume this data is located below 4Gb, then
> >> calculations like this could avoid the REX64 prefix by using %ecx.
> >
> > Here you said something different:
> >   http://lists.xen.org/archives/html/xen-devel/2015-03/msg03557.html
> >
> > So?
>
> So? You simply went too far: There talk was of memory accesses,
> i.e. the (%rbx) part of the instruction above. Using (%ebx) there
> would cause a pointless address size override prefix emitted. Now
> in the new form above you force a pointless REX prefix to be
> emitted. The whole point of both of my requests is - avoid prefixes
> if you don't really need them.

Wilco! Thanks for explanation.

> >> > +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 clear BSS twice and do not go into real mode. */
> >> > +        movb    $1,skip_realmode(%rip)
> >>
> >> How is the setting of skip_realmode related to the clearing of BSS?
> >> Oh, I've found the connection below (albeit see there for its
> >> validity), but I think mentioning this here is more confusing than
> >> clarifying.
> >
> > In general I have a problem skip_realmode. The name itself is confusing
> > here and there. Probably it should be changed. However, I do not have
> > idea for good compact name describing all skip_realmode usages. And I do
> > not think that we should add another variable which will be used in similar
> > way but with different name to clarify situation.
>
> Just clarify things by suitable (brief) comments?

If it is acceptable by you guys then OK.

> >> > @@ -170,12 +313,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
> >>
> >> According to the comment we're on the legacy BIOS boot path
> >> here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
> >> now even confused about the output handling there.
> >
> > It is correct. Old GRUB2 (or other legacy multiboot2 compatible boot
> > loader) which runs on EFI platform and does not have my features will
> > jump into that path. And we do not support that, so, we should fail
> > in the best possible way here.
> >
> > Your comment suggest that code comment should be improved and
> > phrased precisely. I will do that.
>
> Not necessarily: First of all you didn't clarify what video mode we're
> in in that old-grub2 case. Do we have text mode? If so, output should
> not be avoided. And if we're in a graphical mode without any vga=
> option that grub2 may have chosen to interpret, that would smell like
> a bug in grub2.

Here boot services are dead. They were shutdown by GRUB2 (or other
legacy boot loader). So, we do not have simple access to GOP or
anything like that. Am I missing something?

> >> > +    efi_tables();
> >> > +    setup_efi_pci();
> >> > +    efi_variables();
> >> > +
> >> > +    if ( gop )
> >> > +        efi_set_gop_mode(gop, gop_mode);
> >> > +
> >> > +    efi_exit_boot(ImageHandle, SystemTable);
>
> (Btw, regarding your earlier statement of boot services being
> unavailable in the early assembly entry code: Here is the
> exit-boot-services place, i.e. up to here boot services can be used,
> which therefore includes the assembly part of the boot path.)

This is reachable if everything went OK. If it does not very early
then UEFI stuff is unavailable. Please look above for more details.

> >> > --- 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! */
> >> > +}
> >>
> >> Why not just BUG()? What exactly you do here doesn't seem to
> >> matter, as the symbol is unreachable in this case anyway (you
> >> only need it to please the linker).
> >
> > We should print meaningful message here using boot services.
>
> Which boot services? We're not running on EFI if we get here. And
> as said, this function is unreachable on non-EFI afaict, so ...

It is. Assembly code in head.S is build unconditionally.

> > To do that we need a few line of assembly probably. And BUG()
> > is not solution here.
>
> ... I don't follow you here.
>
> >> > --- a/xen/arch/x86/xen.lds.S
> >> > +++ b/xen/arch/x86/xen.lds.S
> >> > @@ -192,7 +192,7 @@ SECTIONS
> >> >    } :text
> >> >
> >> >    /* Align BSS to speedup its initialization. */
> >> > -  . = ALIGN(4);
> >> > +  . = ALIGN(8);
> >> >    .bss : {                     /* BSS */
> >> >         . = ALIGN(STACK_SIZE);
> >> >         __bss_start = .;
> >> > @@ -207,7 +207,7 @@ SECTIONS
> >> >         *(.bss.percpu.read_mostly)
> >> >         . = ALIGN(SMP_CACHE_BYTES);
> >> >         __per_cpu_data_end = .;
> >> > -       . = ALIGN(4);
> >> > +       . = ALIGN(8);
> >> >         __bss_end = .;
> >>
> >> Is that really worth it? I.e. is going from STOSD to STOSQ really a
> >> meaningful win?
> >
> > Probably yes but I do not think that anybody will be see boot time
> > difference. On the other hand why not do that? It does not cost a lot.
>
> But it grows an already largish patch.

If Andrew do not object I can leave/use stosd/stosl as is.

Daniel

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

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

* Re: [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-06-01 14:44       ` Jan Beulich
@ 2016-06-01 19:16         ` Daniel Kiper
  2016-06-02  8:41           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 19:16 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Jun 01, 2016 at 08:44:31AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 15:35, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 05:03:20AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> > --- a/xen/arch/x86/boot/head.S
> >> > +++ b/xen/arch/x86/boot/head.S
> >> > @@ -79,6 +79,13 @@ multiboot2_header_start:
> >> >          /* 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_offset(start), /* Min load address. */ \
> >> > +                   0xffffffff, /* Max load address (4 GiB - 1). */ \
> >>
> >> Hardly - that would allow us to be loaded at 4G - 2M, no matter
> >> how large the image. Or else the comment is misleading.
> >
> > This is the highest address at which memory region allocated for image
> > may end.
>
> You saying "end" then means the comment is misleading.
>
> >> > @@ -178,30 +185,39 @@ efi_multiboot2_proto:
> >> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
> >> >
> >> >  0:
> >> > +        /* Get Xen image load base address from Multiboot2 information. */
> >> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
> >> > +        jne     1f
> >> > +
> >> > +        mov     MB2_load_base_addr(%rcx),%r15d
> >> > +        sub     $XEN_IMG_OFFSET,%r15
> >> > +        jmp     4f
> >>
> >> Why do we need to read this from the table? Can't we easily calculate
> >> this ourselves?
> >
> > Potentially yes but why do not use data from boot loader?
>
> Because it's (a) likely easier to just calculate and (b) we should

In 64-bit mode yes but 32-bit mode requires additional call and pop.
Is it OK for you?

> perhaps trust ourselves more than an external entity?

:-)))

> >> > +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 clear BSS twice and do not go into real mode. */
> >> >          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
> >>
> >> See why numeric labels are bad in situations like this? The (much)
> >> earlier patch should use .L labels here, and the patch here then
> >> should simply follow suit.
> >
> > Then we should change legacy multiboot (v1) code too. Just to be in line
> > new stuff here. Does it pays? And I am not sure that patching convenience
> > overweight convenience of numeric labels here.
>
> Well, it's always this same discussion: Bad examples shouldn't be
> used as excuse to add further bad examples. If you feel like also
> changing the mb1 code - go for it. But if you don't, I'm fine with
> just new code avoiding old mistakes.

Make sense. However, do you suggest that I should avoid numeric labels at all?
Probably they are useful in some situations.

Daniel

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-06-01 15:41           ` Jan Beulich
@ 2016-06-01 19:28             ` Daniel Kiper
  2016-06-02  8:06               ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 19:28 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Jun 01, 2016 at 09:41:42AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 17:23, <daniel.kiper@oracle.com> wrote:
> > On Fri, May 27, 2016 at 02:22:39AM -0600, Jan Beulich wrote:
> >> >>> On 25.05.16 at 19:15, <daniel.kiper@oracle.com> wrote:
> >> > On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >
> > [...]
> >
> >> >> > --- 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
> >> >>
> >> >> So what does "platform" mean? Did you consider using the more fine
> >> >
> >> > It means "EFI platform". It differentiates from "legacy BIOS platform".
> >>
> >> Well, that's what was clear from the beginning. The question however
> >> was (taken together with the second one) what it means functionality
> >> wise. The later addition makes clear it doesn't mean "loaded directly
> >
> > This means that we run on EFI platform and we can use its features,
> > e.g. runtime services, get info from it about ACPI, SMBIOS, etc.
> >
> >> from EFI". But looking at the various flags Linux has here, what
> >
> > Yep.
> >
> >> functionality does it imply? Does it e.g. mean runtime services are to
> >> be used? If so, the flag would need to be cleared when their use if
> >
> > As above: not only.
>
> I.e. we're back at me asking you to make this at least a little more
> fine grained.

You mean EFI_PLATFORM, EFI_LOADER and EFI_RS? Is it OK for you?
Anything else?

> >> being suppressed.
> >
> > If we need that (e.g. for ARM) then we should create e.g. EFI_RS.
>
> Why only then? We already can suppress the use of runtime services.

Sorry, I forgot about that.

Daniel

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

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

* Re: [PATCH v3 11/16] efi: build xen.gz with EFI code
  2016-06-01 15:58           ` Jan Beulich
@ 2016-06-01 19:39             ` Daniel Kiper
  0 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 19:39 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Jun 01, 2016 at 09:58:25AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 17:48, <daniel.kiper@oracle.com> wrote:
> > On Fri, May 27, 2016 at 02:31:52AM -0600, Jan Beulich wrote:
> >> >>> On 25.05.16 at 21:07, <daniel.kiper@oracle.com> wrote:
> >> > On Wed, May 25, 2016 at 01:53:31AM -0600, Jan Beulich wrote:
> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> >> > --- a/xen/common/efi/boot.c
> >> >> > +++ b/xen/common/efi/boot.c
> >> >> > @@ -1244,6 +1244,9 @@ void __init efi_init_memory(void)
> >> >> >      } *extra, *extra_head = NULL;
> >> >> >  #endif
> >> >> >
> >> >> > +    if ( !efi_enabled(EFI_PLATFORM) )
> >> >> > +        return;
> >> >>
> >> >> Arguably such checks would then better be put at the call site,
> >> >> allowing the respective stubs to just BUG().
> >> >
> >> > Ugh... I am confused. Here
> >> > http://lists.xen.org/archives/html/xen-devel/2015-08/msg01790.html
> >> > you asked for what is done above. So, what is your final decision?
> >>
> >> Well, in v2 you didn't alter stubs.c at all. It's that connection
> >> which makes me think using that earlier approach might be better.
> >> The more that, from a purely abstract pov, it could even allow to
> >> remove some or all of stubs.c in a truly non-EFI build, provided we
> >> never build with -O0.
> >
> > I am not sure why "provided we never build with -O0".
>
> Because a minimal amount of optimization is necessary for dead
> calls to actually get eliminated.
>
> >> >> Also - what's your rule for where to put such efi_enabled() checks?
> >> >> I would have expected them to get added to everything that has
> >> >> a counterpart in stubs.c, but things like efi_get_time() or
> >> >> efi_{halt,reset}_system() don't get any added. If those are
> >> >> unreachable, I'd at least expect respective ASSERT()s to get added
> >> >> there.
> >> >
> >> > I have added checks to functions which are called from common EFI/BIOS
> > code.
> >>
> >> And how are the ones I named not called from "common" code?
> >
> > efi_get_time() call is protected by "if ( efi_enabled(EFI_PLATFORM) )"
> > in xen/arch/x86/time.c. efi_halt_system() is called from nowhere, so,
> > it can be removed. I will do that.
>
> Please don't. Instead it should get wired up properly (in
> machine_halt()).

OK, I will try to fix it. Hmmm... Probably efi_halt_system() call was
somewhere but it was removed once. It is interesting why?

> > efi_reset_system() call is protected
> > by different means but EFI related.
>
> Where is that being protected? Nothing prevents anyone to boot
> with "reboot=efi" on a non-EFI system. That's silly, but shouldn't

Then it means that on non-EFI platforms we should not accept that, print
relevant warning and automatically choose reboot method which make sense.

> result in a crash during reboot. Right now its stub is intentionally
> doing nothing (instead of BUG()ing).

Above should solve that problem.

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-06-01 16:02           ` Jan Beulich
@ 2016-06-01 19:53             ` Daniel Kiper
  2016-06-02  8:11               ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-01 19:53 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Jun 01, 2016 at 10:02:51AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 17:58, <daniel.kiper@oracle.com> wrote:
> > On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
> >> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
> >> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
> >> >> >>> On 15.04.16 at 14:33, <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.
> >> >>
> >> >> I don't see why that would be: Simply use an allocation type that
> >> >> doesn't lead to the area getting consumed as normal RAM. Nor do
> >> >> I see the kexec collision potential. Furthermore (and I think I've
> >> >> said so before) ARM is already using AllocatePool() - just with an
> >> >> unsuitable memory type -, so doing so on x86 too would allow for
> >> >
> >> > Nope, they are using standard EfiLoaderData.
> >>
> >> Note how I said "just with an unsuitable memory type"?
> >
> > Could you be more precise?
>
> What else do you need? Just have the arch specify the memory type to
> be used (if ARM really _means_ to use that seemingly wrong type), and
> make the rest of the code common.

This is not the problem. I am not sure how do you understand "seemingly
wrong type". Anything outside of the UEFI spec? Or maybe
EfiReservedMemoryType or something like that?

Daniel

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

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

* Re: [PATCH v3 10/16] efi: create efi_enabled()
  2016-06-01 19:28             ` Daniel Kiper
@ 2016-06-02  8:06               ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-06-02  8:06 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 21:28, <daniel.kiper@oracle.com> wrote:
> On Wed, Jun 01, 2016 at 09:41:42AM -0600, Jan Beulich wrote:
>> >>> On 01.06.16 at 17:23, <daniel.kiper@oracle.com> wrote:
>> > On Fri, May 27, 2016 at 02:22:39AM -0600, Jan Beulich wrote:
>> >> >>> On 25.05.16 at 19:15, <daniel.kiper@oracle.com> wrote:
>> >> > On Wed, May 25, 2016 at 01:20:23AM -0600, Jan Beulich wrote:
>> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> >> > --- 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
>> >> >>
>> >> >> So what does "platform" mean? Did you consider using the more fine
>> >> >
>> >> > It means "EFI platform". It differentiates from "legacy BIOS platform".
>> >>
>> >> Well, that's what was clear from the beginning. The question however
>> >> was (taken together with the second one) what it means functionality
>> >> wise. The later addition makes clear it doesn't mean "loaded directly
>> >
>> > This means that we run on EFI platform and we can use its features,
>> > e.g. runtime services, get info from it about ACPI, SMBIOS, etc.
>> >
>> >> from EFI". But looking at the various flags Linux has here, what
>> >
>> > Yep.
>> >
>> >> functionality does it imply? Does it e.g. mean runtime services are to
>> >> be used? If so, the flag would need to be cleared when their use if
>> >
>> > As above: not only.
>>
>> I.e. we're back at me asking you to make this at least a little more
>> fine grained.
> 
> You mean EFI_PLATFORM, EFI_LOADER and EFI_RS? Is it OK for you?
> Anything else?

Probably that's enough for a first cut, looking at Linux'es. But please
use EFI_RUNTIME_SERVICES and EFI_BOOT (the latter for one of
the first two you mention, perhaps the first, as imo "platform", as
mentioned above, is giving too little description).

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-06-01 19:53             ` Daniel Kiper
@ 2016-06-02  8:11               ` Jan Beulich
  2016-06-02 10:43                 ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-02  8:11 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 21:53, <daniel.kiper@oracle.com> wrote:
> On Wed, Jun 01, 2016 at 10:02:51AM -0600, Jan Beulich wrote:
>> >>> On 01.06.16 at 17:58, <daniel.kiper@oracle.com> wrote:
>> > On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
>> >> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
>> >> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
>> >> >> >>> On 15.04.16 at 14:33, <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.
>> >> >>
>> >> >> I don't see why that would be: Simply use an allocation type that
>> >> >> doesn't lead to the area getting consumed as normal RAM. Nor do
>> >> >> I see the kexec collision potential. Furthermore (and I think I've
>> >> >> said so before) ARM is already using AllocatePool() - just with an
>> >> >> unsuitable memory type -, so doing so on x86 too would allow for
>> >> >
>> >> > Nope, they are using standard EfiLoaderData.
>> >>
>> >> Note how I said "just with an unsuitable memory type"?
>> >
>> > Could you be more precise?
>>
>> What else do you need? Just have the arch specify the memory type to
>> be used (if ARM really _means_ to use that seemingly wrong type), and
>> make the rest of the code common.
> 
> This is not the problem. I am not sure how do you understand "seemingly
> wrong type". Anything outside of the UEFI spec? Or maybe
> EfiReservedMemoryType or something like that?

No, the type is apparently wrong because quite likely, just like on
x86, they want the memory map to persist past ExitBootServices().
Sooner or later at least some parts of efi_init_memory() (or some
equivalent thereof) will be needed on ARM afaict, and accessing the
memory map at that time will require a change to the memory type.

Jan


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

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

* Re: [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-05-27  9:33       ` Jan Beulich
@ 2016-06-02  8:15         ` Daniel Kiper
  2016-06-02  8:39           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-02  8:15 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 03:33:49AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 23:36, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 04:33:54AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:

[...]

> >> > +/*
> >> > + * Compiler is not able to optimize regular strlen()
> >> > + * if argument is well known string during build.
> >> > + * Hence, introduce optimized strlen_opt().
> >> > + */
> >> > +#define strlen_opt(s) (sizeof(s) - 1)
> >>
> >> Do we really care in this code?
> >
> > Not to strongly but why not?
>
> Keep things as readable as possible. In fact I wouldn't mind hard
> coded literal numbers for the string lengths, if they sit right next
> to the respective string literal.

As separate variable? Does it pays? I prefer standard strlen() call
instead of that.

> >> > +static int strtoi(const char *s, const char *stop, const char **next)
> >> > +{
> >> > +    int base = 10, i, ores = 0, res = 0;
> >>
> >> You don't even handle a '-' on the numbers here, so all the variables
> >
> > Yep, however, ...
> >
> >> and the function return type should be unsigned int afaict. And the
> >> function name perhaps be strtoui().
> >
> > ... we return -1 in case of error.
>
> Which - having looked at some of the callers - could easily be
> UINT_MAX as it seems.

Here it looks safe.

> >> > +static u8 skip_realmode(const char *cmdline)
> >> > +{
> >> > +    return !!find_opt(cmdline, "no-real-mode", 0) || !!find_opt(cmdline,
> > "tboot=", 1);
> >>
> >> The || makes the two !! pointless.
> >>
> >> Also please settle on which type you want to use for boolean
> >> (find_opt()'s last parameter is "int", yet here you use "u8"), and
> >
> > Could be u8.
> >
> >> perhaps make yourself a bool_t.
> >
> > I do not think it make sense here.
>
> I think it makes as much or as little sense as having NULL available.

:-)))

> >> > +        /*
> >> > +         * Increment c outside of strtoi() because otherwise some
> >> > +         * compiler may complain with following message:
> >> > +         * warning: operation on ‘c’ may be undefined.
> >> > +         */
> >> > +        ++c;
> >> > +        tmp = strtoi(c, "x", &c);
> >>
> >> The comment is pointless - the operation is firmly undefined if you
> >> put it in the strtoi() invocation.
> >
> > In terms of C spec you are right. However, it is quite surprising that older
> > GCC complains and newer ones do not. Should not we investigate this?
>
> Actually I think I was wrong here. A function call like func(c++, c)

Because argument evaluation order is undefined in C. Am I correct?

> would be undefined, but func(c++, &c) isn't. So I guess if there are
> compiler versions getting this wrong, then you should just disregard
> my comment.

By the way, here is quite good description of these problems:
  http://en.cppreference.com/w/c/language/eval_order

> >> > +        pushl   $sym_phys(early_boot_opts)
> >> > +        pushl   MB_cmdline(%ebx)
> >> >          call    cmdline_parse_early
> >> > +        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
> >>
> >> I don't think such a comment is really useful (seems like I overlooked
> >> a similar one in an earlier patch, on the reloc() invocation).
> >
> > This thing is quite obvious but I do not think that this comment hurts.
>
> It may not really hurt, but it draws needless attention to something
> that is to b expected after any function call getting arguments
> passed on the stack. You could, btw., make cmdline_parse_early
> a stdcall function, so you wouldn't have to do that adjustment
> here.

If it is acceptable by you then I can do that.

Daniel

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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-06-01 19:03         ` Daniel Kiper
@ 2016-06-02  8:34           ` Jan Beulich
  2016-06-02 16:12             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-02  8:34 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 21:03, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 03:02:25AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 23:02, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 03:32:37AM -0600, Jan Beulich wrote:
>> >> isn't going to be very helpful in the field, I'm afraid. Even more so
>> >> that there's no guarantee for a UART to be at port 0x3f8. That's
>> >
>> > Right but we do not have big choice here at very early boot stage... :-(((
>>
>> Excuse me? You're running on EFI, so you have full infrastructure
>> available to you. As much as in a normal BIOS scenario (and on a
>> half way normal system) we can assume a text mode screen with
>> video memory mapped at B8000, under EFI we can assume output
>> capabilities (whichever the system owner set up in the firmware
>> setup).
> 
> Potentially we can do that for bad_cpu only. However, does it pays?
> I suppose that most, if not all, platforms with UEFI have CPUs with
> X86_FEATURE_LM.

I'm not sure about that, keeping various Atoms in mind.

> Sadly, It it not feasible for not_multiboot and mb2_too_old. Former
> means that we were loaded by unknown boot loader and interface is
> not defined.

Hence we may at least assume accessing VGA memory won't do
much bad.

> Hence, we are not able to get anything from EFI. Latter
> means that we were booted via older multiboot2 version which shutdown
> boot services.

Hmm, that's certainly one of the possibilities, yes. I wonder then
whether we wouldn't better do away with all of those output
attempts then.

>> >> > +efi_multiboot2_proto:
>> >>
>> >> .Lefi_multiboot2_proto
>> >
>> > OK if you insist. However, I think that we are loosing helpful
>> > debug information this way.
>>
>> I don't see why or how. Labels persisting in the final symbol table
>> are useful only for generating stack traces, yet if you crash this
>> early there won't be any stack trace anyway - you don't even
>> have an IDT set up yet.
> 
> OK, but it is much easier to identify addresses for breakpoints if you
> have proper labels. And this one looks quite useful.

I disagree, especially to the "much".

>> >> > +        /*
>> >> > +         * Multiboot2 information address is 32-bit,
>> >> > +         * so, zero higher half of %rbx.
>> >> > +         */
>> >> > +        mov     %ebx,%ebx
>> >>
>> >> Wait, no - that's a protocol bug then. We're being entered in 64-bit
>> >> mode here, so registers should be in 64-bit clean state.
>> >
>> > You mean higher half cleared. Right? This is not guaranteed.
>>
>> Hence me saying "that's a protocol bug then".
> 
> Why? Protocol strictly says that "this is not guaranteed".
> What is the problem with that? Potentially loader can set
> %rbx higher half to e.g. 0 but I do not think it is needed.

A 64-bit interface shouldn't specify values to live only in halves
of registers, in my opinion. Remember that the architecture
guarantees high halves to get zeroed for 32-bit writes to
registers, so I don't even see any complication for the provider
side of the interface (which necessarily runs in 64-bit mode).

>> > Please check this:
>> > http://lists.gnu.org/archive/html/grub-devel/2016-03/msg00304.html 
>>
>> Other than the description of the patch I can't see anything like that,
>> in particular
>> - no occurrence of "ebx" in any of the added or changed code
>> - MULTIBOOT_EFI_MBI_REGISTER getting #define-d as rbx
> 
> Please check multiboot2 spec, section 3.2, Machine state. It is not
> freshest one (I am working on EFI updates right now) but I hope that it,
> together with patch comment, will shed some light.

May I refer you back to you, in another patch, adding just two
architecture defines for MB2: i386 and MIPS? That's a pretty
clear indication that there can't be much consistency to be
expected when talk comes to x86-64 (which most definitely is
not i386).

>> >> > @@ -170,12 +313,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
>> >>
>> >> According to the comment we're on the legacy BIOS boot path
>> >> here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
>> >> now even confused about the output handling there.
>> >
>> > It is correct. Old GRUB2 (or other legacy multiboot2 compatible boot
>> > loader) which runs on EFI platform and does not have my features will
>> > jump into that path. And we do not support that, so, we should fail
>> > in the best possible way here.
>> >
>> > Your comment suggest that code comment should be improved and
>> > phrased precisely. I will do that.
>>
>> Not necessarily: First of all you didn't clarify what video mode we're
>> in in that old-grub2 case. Do we have text mode? If so, output should
>> not be avoided. And if we're in a graphical mode without any vga=
>> option that grub2 may have chosen to interpret, that would smell like
>> a bug in grub2.
> 
> Here boot services are dead. They were shutdown by GRUB2 (or other
> legacy boot loader). So, we do not have simple access to GOP or
> anything like that. Am I missing something?

How are boot services coming into the picture here? As the code
comment still visible above says, we're on the legacy boot path
here. And legacy boot, from all I know, implies a text mode on
the primary VGA (if any).

>> >> > --- 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! */
>> >> > +}
>> >>
>> >> Why not just BUG()? What exactly you do here doesn't seem to
>> >> matter, as the symbol is unreachable in this case anyway (you
>> >> only need it to please the linker).
>> >
>> > We should print meaningful message here using boot services.
>>
>> Which boot services? We're not running on EFI if we get here. And
>> as said, this function is unreachable on non-EFI afaict, so ...
> 
> It is. Assembly code in head.S is build unconditionally.

Oh, I see - a new-style xen.gz which doesn't have EFI support
enabled due to tool chain issues but gets booted from EFI/grub2.

Jan

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

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

* Re: [PATCH v3 14/16] x86/boot: implement early command line parser in C
  2016-06-02  8:15         ` Daniel Kiper
@ 2016-06-02  8:39           ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-06-02  8:39 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 02.06.16 at 10:15, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 03:33:49AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 23:36, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 04:33:54AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> > +/*
>> >> > + * Compiler is not able to optimize regular strlen()
>> >> > + * if argument is well known string during build.
>> >> > + * Hence, introduce optimized strlen_opt().
>> >> > + */
>> >> > +#define strlen_opt(s) (sizeof(s) - 1)
>> >>
>> >> Do we really care in this code?
>> >
>> > Not to strongly but why not?
>>
>> Keep things as readable as possible. In fact I wouldn't mind hard
>> coded literal numbers for the string lengths, if they sit right next
>> to the respective string literal.
> 
> As separate variable? Does it pays? I prefer standard strlen() call
> instead of that.

Variable? I said literal numbers. As in

	strncmp(str, "xyz", 3);

From such code it is visible at the first glance what the 3 stands for,
and is imo better readable than

	strncmp(str, "xyz", strlen("xyz"));

>> >> > +        pushl   $sym_phys(early_boot_opts)
>> >> > +        pushl   MB_cmdline(%ebx)
>> >> >          call    cmdline_parse_early
>> >> > +        add     $8,%esp             /* Remove cmdline_parse_early() args from stack. */
>> >>
>> >> I don't think such a comment is really useful (seems like I overlooked
>> >> a similar one in an earlier patch, on the reloc() invocation).
>> >
>> > This thing is quite obvious but I do not think that this comment hurts.
>>
>> It may not really hurt, but it draws needless attention to something
>> that is to b expected after any function call getting arguments
>> passed on the stack. You could, btw., make cmdline_parse_early
>> a stdcall function, so you wouldn't have to do that adjustment
>> here.
> 
> If it is acceptable by you then I can do that.

There are two possible issues, which would need checking (which
I only thought of after having written that reply):
- Do all gcc versions we care about support stdcall?
- What's the disposition of those asm() stubs on the callee side?
  (Remember that Andrew had asked for them to get dropped?)

Jan


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

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

* Re: [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images
  2016-06-01 19:16         ` Daniel Kiper
@ 2016-06-02  8:41           ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-06-02  8:41 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 01.06.16 at 21:16, <daniel.kiper@oracle.com> wrote:
> On Wed, Jun 01, 2016 at 08:44:31AM -0600, Jan Beulich wrote:
>> >>> On 01.06.16 at 15:35, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 05:03:20AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> > @@ -178,30 +185,39 @@ efi_multiboot2_proto:
>> >> >          and     $~(MULTIBOOT2_TAG_ALIGN-1),%rcx
>> >> >
>> >> >  0:
>> >> > +        /* Get Xen image load base address from Multiboot2 information. */
>> >> > +        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%rcx)
>> >> > +        jne     1f
>> >> > +
>> >> > +        mov     MB2_load_base_addr(%rcx),%r15d
>> >> > +        sub     $XEN_IMG_OFFSET,%r15
>> >> > +        jmp     4f
>> >>
>> >> Why do we need to read this from the table? Can't we easily calculate
>> >> this ourselves?
>> >
>> > Potentially yes but why do not use data from boot loader?
>>
>> Because it's (a) likely easier to just calculate and (b) we should
> 
> In 64-bit mode yes but 32-bit mode requires additional call and pop.
> Is it OK for you?

If you don't already calculate that offset somewhere - sure.

>> >> > +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 clear BSS twice and do not go into real mode. */
>> >> >          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
>> >>
>> >> See why numeric labels are bad in situations like this? The (much)
>> >> earlier patch should use .L labels here, and the patch here then
>> >> should simply follow suit.
>> >
>> > Then we should change legacy multiboot (v1) code too. Just to be in line
>> > new stuff here. Does it pays? And I am not sure that patching convenience
>> > overweight convenience of numeric labels here.
>>
>> Well, it's always this same discussion: Bad examples shouldn't be
>> used as excuse to add further bad examples. If you feel like also
>> changing the mb1 code - go for it. But if you don't, I'm fine with
>> just new code avoiding old mistakes.
> 
> Make sense. However, do you suggest that I should avoid numeric labels at 
> all?
> Probably they are useful in some situations.

Yes, they are. So I'm not asking to do away with them altogether.

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-06-02  8:11               ` Jan Beulich
@ 2016-06-02 10:43                 ` Daniel Kiper
  2016-06-02 11:10                   ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-02 10:43 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Jun 02, 2016 at 02:11:32AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 21:53, <daniel.kiper@oracle.com> wrote:
> > On Wed, Jun 01, 2016 at 10:02:51AM -0600, Jan Beulich wrote:
> >> >>> On 01.06.16 at 17:58, <daniel.kiper@oracle.com> wrote:
> >> > On Fri, May 27, 2016 at 02:37:06AM -0600, Jan Beulich wrote:
> >> >> >>> On 25.05.16 at 21:48, <daniel.kiper@oracle.com> wrote:
> >> >> > On Wed, May 25, 2016 at 02:39:57AM -0600, Jan Beulich wrote:
> >> >> >> >>> On 15.04.16 at 14:33, <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.
> >> >> >>
> >> >> >> I don't see why that would be: Simply use an allocation type that
> >> >> >> doesn't lead to the area getting consumed as normal RAM. Nor do
> >> >> >> I see the kexec collision potential. Furthermore (and I think I've
> >> >> >> said so before) ARM is already using AllocatePool() - just with an
> >> >> >> unsuitable memory type -, so doing so on x86 too would allow for
> >> >> >
> >> >> > Nope, they are using standard EfiLoaderData.
> >> >>
> >> >> Note how I said "just with an unsuitable memory type"?
> >> >
> >> > Could you be more precise?
> >>
> >> What else do you need? Just have the arch specify the memory type to
> >> be used (if ARM really _means_ to use that seemingly wrong type), and
> >> make the rest of the code common.
> >
> > This is not the problem. I am not sure how do you understand "seemingly
> > wrong type". Anything outside of the UEFI spec? Or maybe
> > EfiReservedMemoryType or something like that?
>
> No, the type is apparently wrong because quite likely, just like on
> x86, they want the memory map to persist past ExitBootServices().
> Sooner or later at least some parts of efi_init_memory() (or some
> equivalent thereof) will be needed on ARM afaict, and accessing the
> memory map at that time will require a change to the memory type.

I have checked the code once again. On ARM we allocate memory using
EfiLoaderData (not only for memory map) and later deliberately do not
take over these regions. This means that memory map persists. However,
this also means that we are not able to use a lot of memory which is
free from Xen point of view (for more details please check Unified
Extensible Firmware Interface Specification, Version 2.6, section 6.2,
Memory Allocation Services). Why? AFAICT, EfiLoaderCode/EfiLoaderData
types are used very often by EFI applications to allocate memory
dynamically. Most of these applications are dead after ExitBootServices().
So, there is pretty good chance that we are loosing quite big chunk
of memory which simply contains junk except of small portion with memory
map. And on ARM, especially on embedded, this could be painful.

On x86 we take over EfiLoaderCode/EfiLoaderData regions. And I do not
think we should change that behavior. Even maybe we should change
behavior on ARM. Hmmm... Is it possible? Was there a reason to not
take over EfiLoaderCode/EfiLoaderData regions on ARM?

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-06-02 10:43                 ` Daniel Kiper
@ 2016-06-02 11:10                   ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-06-02 11:10 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 02.06.16 at 12:43, <daniel.kiper@oracle.com> wrote:
> I have checked the code once again. On ARM we allocate memory using
> EfiLoaderData (not only for memory map) and later deliberately do not
> take over these regions. This means that memory map persists. However,
> this also means that we are not able to use a lot of memory which is
> free from Xen point of view (for more details please check Unified
> Extensible Firmware Interface Specification, Version 2.6, section 6.2,
> Memory Allocation Services). Why? AFAICT, EfiLoaderCode/EfiLoaderData
> types are used very often by EFI applications to allocate memory
> dynamically. Most of these applications are dead after ExitBootServices().
> So, there is pretty good chance that we are loosing quite big chunk
> of memory which simply contains junk except of small portion with memory
> map. And on ARM, especially on embedded, this could be painful.
> 
> On x86 we take over EfiLoaderCode/EfiLoaderData regions. And I do not
> think we should change that behavior. Even maybe we should change
> behavior on ARM. Hmmm... Is it possible? Was there a reason to not
> take over EfiLoaderCode/EfiLoaderData regions on ARM?

That's not a question to me, I suppose (despite me being the only
one on the To list)?

Jan


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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-06-02  8:34           ` Jan Beulich
@ 2016-06-02 16:12             ` Daniel Kiper
  2016-06-03  9:26               ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-02 16:12 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Thu, Jun 02, 2016 at 02:34:28AM -0600, Jan Beulich wrote:
> >>> On 01.06.16 at 21:03, <daniel.kiper@oracle.com> wrote:
> > On Fri, May 27, 2016 at 03:02:25AM -0600, Jan Beulich wrote:
> >> >>> On 25.05.16 at 23:02, <daniel.kiper@oracle.com> wrote:
> >> > On Wed, May 25, 2016 at 03:32:37AM -0600, Jan Beulich wrote:
> >> >> isn't going to be very helpful in the field, I'm afraid. Even more so
> >> >> that there's no guarantee for a UART to be at port 0x3f8. That's
> >> >
> >> > Right but we do not have big choice here at very early boot stage... :-(((
> >>
> >> Excuse me? You're running on EFI, so you have full infrastructure
> >> available to you. As much as in a normal BIOS scenario (and on a
> >> half way normal system) we can assume a text mode screen with
> >> video memory mapped at B8000, under EFI we can assume output
> >> capabilities (whichever the system owner set up in the firmware
> >> setup).
> >
> > Potentially we can do that for bad_cpu only. However, does it pays?
> > I suppose that most, if not all, platforms with UEFI have CPUs with
> > X86_FEATURE_LM.
>
> I'm not sure about that, keeping various Atoms in mind.

OK.

> > Sadly, It it not feasible for not_multiboot and mb2_too_old. Former
> > means that we were loaded by unknown boot loader and interface is
> > not defined.
>
> Hence we may at least assume accessing VGA memory won't do
> much bad.

Well, we are in black hole here but I am not sure that even in that
situation we should blindly poke VGA memory region. Especially on
EFI platforms behavior can be at least undefined.

> > Hence, we are not able to get anything from EFI. Latter
> > means that we were booted via older multiboot2 version which shutdown
> > boot services.
>
> Hmm, that's certainly one of the possibilities, yes. I wonder then
> whether we wouldn't better do away with all of those output
> attempts then.

This is one option. However, IMO, not nice. Maybe we should stay with
serial plus VGA on legacy BIOS platforms. Serials looks quite well
defined even on EFI platforms. However, if it is not available x86
out instruction should not do any harm. Though if we wish to increase
chance of reaching interested parties I would send error messages to
0x3f8 and 0x2f8 at once. AFAICT, on many machines usually at least one
if not both standard/legacy serial ports are available.

[...]

> >> >> > +        /*
> >> >> > +         * Multiboot2 information address is 32-bit,
> >> >> > +         * so, zero higher half of %rbx.
> >> >> > +         */
> >> >> > +        mov     %ebx,%ebx
> >> >>
> >> >> Wait, no - that's a protocol bug then. We're being entered in 64-bit
> >> >> mode here, so registers should be in 64-bit clean state.
> >> >
> >> > You mean higher half cleared. Right? This is not guaranteed.
> >>
> >> Hence me saying "that's a protocol bug then".
> >
> > Why? Protocol strictly says that "this is not guaranteed".
> > What is the problem with that? Potentially loader can set
> > %rbx higher half to e.g. 0 but I do not think it is needed.
>
> A 64-bit interface shouldn't specify values to live only in halves
> of registers, in my opinion. Remember that the architecture
> guarantees high halves to get zeroed for 32-bit writes to
> registers, so I don't even see any complication for the provider
> side of the interface (which necessarily runs in 64-bit mode).

OK, you convinced me. I will update GRUB2 patches.

> >> > Please check this:
> >> > http://lists.gnu.org/archive/html/grub-devel/2016-03/msg00304.html
> >>
> >> Other than the description of the patch I can't see anything like that,
> >> in particular
> >> - no occurrence of "ebx" in any of the added or changed code
> >> - MULTIBOOT_EFI_MBI_REGISTER getting #define-d as rbx
> >
> > Please check multiboot2 spec, section 3.2, Machine state. It is not
> > freshest one (I am working on EFI updates right now) but I hope that it,
> > together with patch comment, will shed some light.
>
> May I refer you back to you, in another patch, adding just two
> architecture defines for MB2: i386 and MIPS? That's a pretty
> clear indication that there can't be much consistency to be
> expected when talk comes to x86-64 (which most definitely is
> not i386).
>
> >> >> > @@ -170,12 +313,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
> >> >>
> >> >> According to the comment we're on the legacy BIOS boot path
> >> >> here, yet at mb2_too_old you assume no text mode VGA. I.e. I'm
> >> >> now even confused about the output handling there.
> >> >
> >> > It is correct. Old GRUB2 (or other legacy multiboot2 compatible boot
> >> > loader) which runs on EFI platform and does not have my features will
> >> > jump into that path. And we do not support that, so, we should fail
> >> > in the best possible way here.
> >> >
> >> > Your comment suggest that code comment should be improved and
> >> > phrased precisely. I will do that.
> >>
> >> Not necessarily: First of all you didn't clarify what video mode we're
> >> in in that old-grub2 case. Do we have text mode? If so, output should
> >> not be avoided. And if we're in a graphical mode without any vga=
> >> option that grub2 may have chosen to interpret, that would smell like
> >> a bug in grub2.
> >
> > Here boot services are dead. They were shutdown by GRUB2 (or other
> > legacy boot loader). So, we do not have simple access to GOP or
> > anything like that. Am I missing something?
>
> How are boot services coming into the picture here? As the code
> comment still visible above says, we're on the legacy boot path
> here. And legacy boot, from all I know, implies a text mode on
> the primary VGA (if any).

Old multiboot2 protocol (without my features) used one path for legacy
BIOS and EFI platforms. If we are here then we are sure that:
  - we are running on EFI platform,
  - we were loaded by old multiboot2 protocol,
  - EFI boot services are shutdown,
  - there is no VGA here.

Daniel

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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-06-02 16:12             ` Daniel Kiper
@ 2016-06-03  9:26               ` Jan Beulich
  2016-06-03 17:06                 ` Konrad Rzeszutek Wilk
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-03  9:26 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 02.06.16 at 18:12, <daniel.kiper@oracle.com> wrote:
> On Thu, Jun 02, 2016 at 02:34:28AM -0600, Jan Beulich wrote:
>> >>> On 01.06.16 at 21:03, <daniel.kiper@oracle.com> wrote:
>> > Hence, we are not able to get anything from EFI. Latter
>> > means that we were booted via older multiboot2 version which shutdown
>> > boot services.
>>
>> Hmm, that's certainly one of the possibilities, yes. I wonder then
>> whether we wouldn't better do away with all of those output
>> attempts then.
> 
> This is one option. However, IMO, not nice. Maybe we should stay with
> serial plus VGA on legacy BIOS platforms. Serials looks quite well
> defined even on EFI platforms. However, if it is not available x86
> out instruction should not do any harm. Though if we wish to increase
> chance of reaching interested parties I would send error messages to
> 0x3f8 and 0x2f8 at once. AFAICT, on many machines usually at least one
> if not both standard/legacy serial ports are available.

On many _older_ machines you mean. Any new machines I got
hold of in the last couple of years didn't have any serial ports
anymore (some still have them implemented in the LPC, but not
wired through, but legacy free systems wouldn't have them at all
anymore).

Jan


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

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

* Re: [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms
  2016-06-03  9:26               ` Jan Beulich
@ 2016-06-03 17:06                 ` Konrad Rzeszutek Wilk
  0 siblings, 0 replies; 94+ messages in thread
From: Konrad Rzeszutek Wilk @ 2016-06-03 17:06 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, Daniel Kiper,
	cardoe, pgnet.dev, ning.sun, david.vrabel, xen-devel,
	qiaowei.ren, richard.l.maliszewski, gang.wei, fu.wei

On Fri, Jun 03, 2016 at 03:26:59AM -0600, Jan Beulich wrote:
> >>> On 02.06.16 at 18:12, <daniel.kiper@oracle.com> wrote:
> > On Thu, Jun 02, 2016 at 02:34:28AM -0600, Jan Beulich wrote:
> >> >>> On 01.06.16 at 21:03, <daniel.kiper@oracle.com> wrote:
> >> > Hence, we are not able to get anything from EFI. Latter
> >> > means that we were booted via older multiboot2 version which shutdown
> >> > boot services.
> >>
> >> Hmm, that's certainly one of the possibilities, yes. I wonder then
> >> whether we wouldn't better do away with all of those output
> >> attempts then.
> > 
> > This is one option. However, IMO, not nice. Maybe we should stay with
> > serial plus VGA on legacy BIOS platforms. Serials looks quite well
> > defined even on EFI platforms. However, if it is not available x86
> > out instruction should not do any harm. Though if we wish to increase
> > chance of reaching interested parties I would send error messages to
> > 0x3f8 and 0x2f8 at once. AFAICT, on many machines usually at least one
> > if not both standard/legacy serial ports are available.
> 
> On many _older_ machines you mean. Any new machines I got
> hold of in the last couple of years didn't have any serial ports
> anymore (some still have them implemented in the LPC, but not
> wired through, but legacy free systems wouldn't have them at all
> anymore).

And there are also new EFI machines that have no VGA whatsoever but
only serial.

> 
> Jan
> 

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

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

* Re: [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention
  2016-04-15 15:56   ` Andrew Cooper
@ 2016-06-17  8:41     ` Daniel Kiper
  2016-06-17  9:30       ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-17  8:41 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: jgross, stefano.stabellini, cardoe, pgnet.dev, ning.sun,
	david.vrabel, jbeulich, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Apr 15, 2016 at 04:56:26PM +0100, Andrew Cooper wrote:
> On 15/04/16 13:33, Daniel Kiper wrote:
> > reloc() is not called according to cdecl calling convention.
> > This makes confusion and does not scale well for more arguments.
> > And patch adding multiboot2 protocol support have to pass 3
> > arguments instead of 2. Hence, move reloc() call to cdecl
> > calling convention.
> >
> > I add push %ebp/mov %esp,%ebp/leave instructions here. Though they
> > are not strictly needed in this patch. However, then assembly code
> > in patch adding multiboot2 protocol support is easier to read.
> >
> > Suggested-by: Jan Beulich <jbeulich@suse.com>
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > ---
> > v3 - suggestions/fixes:
> >    - simplify assembly in xen/arch/x86/boot/reloc.c file
> >      (suggested by Jan Beulich),
> >    - reorder arguments for reloc() call from xen/arch/x86/boot/head.S
> >      (suggested by Jan Beulich),
> >    - improve commit message
> >      (suggested by Jan Beulich).
> > ---
> >  xen/arch/x86/boot/head.S  |    4 +++-
> >  xen/arch/x86/boot/reloc.c |   18 ++++++++++++++----
> >  2 files changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index 32a54a0..28ac721 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    %eax                /* Boot trampoline address. */
> > +        push    %ebx                /* Multiboot information 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..006f41d 100644
> > --- a/xen/arch/x86/boot/reloc.c
> > +++ b/xen/arch/x86/boot/reloc.c
> > @@ -10,15 +10,25 @@
> >   *    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) = MULTIBOOT_INFORMATION_ADDRESS,
> > + *   - 0x8(%esp) = BOOT_TRAMPOLINE_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  0xc(%ebp),%eax           \n"
> > +    "    mov  %eax,alloc-1b(%ecx)      \n"
> > +    "    push 0x8(%ebp)                \n"
> > +    "    call reloc                    \n"
> > +    "    leave                         \n"
> > +    "    ret                           \n"
> >      );
> >
> >  /*
>
> Come to think of this, why are we playing asm games like this at all?
>
> This object file gets linked with head.o anyway, and the reloc()
> function is safe to live anywhere in .init.text.  It might be worth

It does not. reloc.c is converted to asm and then included in head.S. However,
as we discussed during hackhaton I tried to link reloc.o directly with other
objects. As we expected it is easy to convert 32-bit ELF to 64-bit ELF file.
Though ld fails. As I saw the main problem is that virtual addresses start at
0xffff82d080200000. This value simply overflows 32-bit relocations, e.g.:

prelink.o: In function `reloc':
(.text+0x359): relocation truncated to fit: R_X86_64_32 against `.text'

There is a chance that we can fix it by changing virtual addresses to
physical addresses. At first sight it should work because final 32-bit
ELF image contains only physical addresses in ELF headers. However, I am
not sure that this way we will not break something. Hmmm... I have just
realized that at least debugging and crash analysis of hypervisor memory
could be more difficult. Am I missing anything else?

Additionally, there is a lack of _GLOBAL_OFFSET_TABLE_ symbol and ld
complains in that way:

prelink.o: In function `reloc':
(.text+0x36c): undefined reference to `_GLOBAL_OFFSET_TABLE_'

Probably we can fix this issue by putting above mentioned symbol somewhere
into xen.lds or something like that.

Andrew, IIRC, you told us that you linked 32-bit code wrapped into 64-bit
ELF file successfully. How did you do that?

Daniel

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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-05-24 12:52       ` Jan Beulich
@ 2016-06-17  9:06         ` Daniel Kiper
  2016-06-17 10:04           ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-06-17  9:06 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Tue, May 24, 2016 at 06:52:39AM -0600, Jan Beulich wrote:
> >>> On 24.05.16 at 14:28, <daniel.kiper@oracle.com> wrote:
> > On Tue, May 24, 2016 at 03:05:06AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> > --- /dev/null
> >> > +++ b/xen/arch/x86/boot/build32.lds
> >> > @@ -0,0 +1,49 @@
> >> > +/*
> >> > + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
> >> > + *      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/>.
> >> > + */
> >> > +
> >> > +ENTRY(_start)
> >> > +
> >> > +SECTIONS
> >> > +{
> >> > +  /* Merge code and data into one section. */
> >> > +  .text : {
> >> > +        *(.text)
> >> > +        *(.text.*)
> >> > +        *(.rodata)
> >>
> >> This (and the respective %.lnk rule change below) is not in line with
> >> the patch description. It's further suspicious that you only handle
> >
> > I am not sure what exactly do you mean by that.
>
> Quoting your commit message: "...  merge all text and data sections
> into one .text section." Contrast this to the limited set of sections
> above.
>
> >> .rodata but not also .rodata.* here.
> >
> > I did this deliberately. I just want to take only these sections which I
> > know that
> > contain required code and data. Nothing more. If in the future we find out
> > that
> > .rodata.* (or anything else) is needed then we can add it later.
> >
> >> > +  }
> >> > +
> >> > +  /DISCARD/ : {
> >> > +        /*
> >> > +         * .got.plt section is used only by dynamic linker
> >> > +         * and our output is not supposed to be loaded by
> >> > +         * dynamic linker. Additionally, it just contains
> >> > +         * .PLT0 which is referenced from nowhere. So, we
> >> > +         * can safely drop .got.plt here.
> >> > +         *
> >> > +         * Ha! This should be really discarded here. However,
> >> > +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
> >> > +         * symbol too and it is used as a reference for relative
> >> > +         * addressing (and only for that thing). Hence, ld
> >> > +         * complains if we remove that section because it
> >> > +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
> >> > +         * section during conversion to plain binary format.
> >> > +         * Please check build32.mk for more details.
> >> > +         */
> >> > +        /* *(.got.plt) */
> >> > +  }
> >>
> >> I'm afraid this needs more investigation: Afaik there should be no
> >
> > I am not sure what else we should look for.
>
> The reason why such an empty .got.plt gets created in the first place.
> If e.g. that turns out to be a bug in (some versions of) binutils, then
> that bug should be named here as the reason.

If PIC/PIE code is build then .got.plt exists in executable even if it
is not linked with dynamic libraries. Then it is just placeholder for
_GLOBAL_OFFSET_TABLE_ symbol and .PLT0. .PLT0 is filled by dynamic
linker and our code is not supposed to be loaded by dynamic linker.
So, from our point of view .PLT0 is unused.

> >> reason for the linker to create an otherwise empty .got.plt in the
> >
> > As I wrote above. It contains _GLOBAL_OFFSET_TABLE_ which is used
> > as a reference for relative addressing.
>
> But we don't use any such, so without being needed I don't think
> the symbol needs to be created.

R_386_GOTPC and R_386_GOTOFF relocations use address of _GLOBAL_OFFSET_TABLE_
as a reference. So, it is needed during linking phase. However, later it is
not needed.  Hence, .got.plt with _GLOBAL_OFFSET_TABLE_ and .PLT0 can safely
be dropped.

> >> first place. And discarding it without being sure it is empty is not
> >> that good an idea anyway.
> >
> > Good point! Potentially we can check is it empty, excluding
> > _GLOBAL_OFFSET_TABLE_ symbol, in build32.mk.
>
> Well, your comment above says it have .PLT0, which means it's not
> exactly empty.

Ditto. And right know I do not think that we need any safety checks here.

Daniel

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

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

* Re: [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention
  2016-06-17  8:41     ` Daniel Kiper
@ 2016-06-17  9:30       ` Jan Beulich
  0 siblings, 0 replies; 94+ messages in thread
From: Jan Beulich @ 2016-06-17  9:30 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, Andrew Cooper, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 17.06.16 at 10:41, <daniel.kiper@oracle.com> wrote:
> On Fri, Apr 15, 2016 at 04:56:26PM +0100, Andrew Cooper wrote:
>> On 15/04/16 13:33, Daniel Kiper wrote:
>> > reloc() is not called according to cdecl calling convention.
>> > This makes confusion and does not scale well for more arguments.
>> > And patch adding multiboot2 protocol support have to pass 3
>> > arguments instead of 2. Hence, move reloc() call to cdecl
>> > calling convention.
>> >
>> > I add push %ebp/mov %esp,%ebp/leave instructions here. Though they
>> > are not strictly needed in this patch. However, then assembly code
>> > in patch adding multiboot2 protocol support is easier to read.
>> >
>> > Suggested-by: Jan Beulich <jbeulich@suse.com>
>> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>> > ---
>> > v3 - suggestions/fixes:
>> >    - simplify assembly in xen/arch/x86/boot/reloc.c file
>> >      (suggested by Jan Beulich),
>> >    - reorder arguments for reloc() call from xen/arch/x86/boot/head.S
>> >      (suggested by Jan Beulich),
>> >    - improve commit message
>> >      (suggested by Jan Beulich).
>> > ---
>> >  xen/arch/x86/boot/head.S  |    4 +++-
>> >  xen/arch/x86/boot/reloc.c |   18 ++++++++++++++----
>> >  2 files changed, 17 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
>> > index 32a54a0..28ac721 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    %eax                /* Boot trampoline address. */
>> > +        push    %ebx                /* Multiboot information 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..006f41d 100644
>> > --- a/xen/arch/x86/boot/reloc.c
>> > +++ b/xen/arch/x86/boot/reloc.c
>> > @@ -10,15 +10,25 @@
>> >   *    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) = MULTIBOOT_INFORMATION_ADDRESS,
>> > + *   - 0x8(%esp) = BOOT_TRAMPOLINE_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  0xc(%ebp),%eax           \n"
>> > +    "    mov  %eax,alloc-1b(%ecx)      \n"
>> > +    "    push 0x8(%ebp)                \n"
>> > +    "    call reloc                    \n"
>> > +    "    leave                         \n"
>> > +    "    ret                           \n"
>> >      );
>> >
>> >  /*
>>
>> Come to think of this, why are we playing asm games like this at all?
>>
>> This object file gets linked with head.o anyway, and the reloc()
>> function is safe to live anywhere in .init.text.  It might be worth
> 
> It does not. reloc.c is converted to asm and then included in head.S. 
> However,
> as we discussed during hackhaton I tried to link reloc.o directly with other
> objects. As we expected it is easy to convert 32-bit ELF to 64-bit ELF file.
> Though ld fails. As I saw the main problem is that virtual addresses start at
> 0xffff82d080200000. This value simply overflows 32-bit relocations, e.g.:
> 
> prelink.o: In function `reloc':
> (.text+0x359): relocation truncated to fit: R_X86_64_32 against `.text'
> 
> There is a chance that we can fix it by changing virtual addresses to
> physical addresses. At first sight it should work because final 32-bit
> ELF image contains only physical addresses in ELF headers. However, I am
> not sure that this way we will not break something. Hmmm... I have just
> realized that at least debugging and crash analysis of hypervisor memory
> could be more difficult. Am I missing anything else?

I don't think you can switch the linking process to use physical
addresses: The final image has to have proper virtual addresses
used for any involved relocations. This would only be benign if
_all_ relocations were relative ones.

Jan

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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-06-17  9:06         ` Daniel Kiper
@ 2016-06-17 10:04           ` Jan Beulich
  2016-06-17 10:34             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-06-17 10:04 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 17.06.16 at 11:06, <daniel.kiper@oracle.com> wrote:
> On Tue, May 24, 2016 at 06:52:39AM -0600, Jan Beulich wrote:
>> >>> On 24.05.16 at 14:28, <daniel.kiper@oracle.com> wrote:
>> > On Tue, May 24, 2016 at 03:05:06AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> > +  /DISCARD/ : {
>> >> > +        /*
>> >> > +         * .got.plt section is used only by dynamic linker
>> >> > +         * and our output is not supposed to be loaded by
>> >> > +         * dynamic linker. Additionally, it just contains
>> >> > +         * .PLT0 which is referenced from nowhere. So, we
>> >> > +         * can safely drop .got.plt here.
>> >> > +         *
>> >> > +         * Ha! This should be really discarded here. However,
>> >> > +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
>> >> > +         * symbol too and it is used as a reference for relative
>> >> > +         * addressing (and only for that thing). Hence, ld
>> >> > +         * complains if we remove that section because it
>> >> > +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
>> >> > +         * section during conversion to plain binary format.
>> >> > +         * Please check build32.mk for more details.
>> >> > +         */
>> >> > +        /* *(.got.plt) */
>> >> > +  }
>> >>
>> >> I'm afraid this needs more investigation: Afaik there should be no
>> >
>> > I am not sure what else we should look for.
>>
>> The reason why such an empty .got.plt gets created in the first place.
>> If e.g. that turns out to be a bug in (some versions of) binutils, then
>> that bug should be named here as the reason.
> 
> If PIC/PIE code is build then .got.plt exists in executable even if it
> is not linked with dynamic libraries.

Well - then just don't force -fPIC or -fPIE for the compilation of this
code?

>> >> reason for the linker to create an otherwise empty .got.plt in the
>> >
>> > As I wrote above. It contains _GLOBAL_OFFSET_TABLE_ which is used
>> > as a reference for relative addressing.
>>
>> But we don't use any such, so without being needed I don't think
>> the symbol needs to be created.
> 
> R_386_GOTPC and R_386_GOTOFF relocations use address of 
> _GLOBAL_OFFSET_TABLE_
> as a reference. So, it is needed during linking phase. However, later it is
> not needed.  Hence, .got.plt with _GLOBAL_OFFSET_TABLE_ and .PLT0 can safely
> be dropped.

These two relocation types should not appear for non-PIC/PIE code.

Jan


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

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

* Re: [PATCH v3 07/16] x86/boot: create *.lnk files with linker script
  2016-06-17 10:04           ` Jan Beulich
@ 2016-06-17 10:34             ` Daniel Kiper
  0 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-06-17 10:34 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Jun 17, 2016 at 04:04:20AM -0600, Jan Beulich wrote:
> >>> On 17.06.16 at 11:06, <daniel.kiper@oracle.com> wrote:
> > On Tue, May 24, 2016 at 06:52:39AM -0600, Jan Beulich wrote:
> >> >>> On 24.05.16 at 14:28, <daniel.kiper@oracle.com> wrote:
> >> > On Tue, May 24, 2016 at 03:05:06AM -0600, Jan Beulich wrote:
> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> >> > +  /DISCARD/ : {
> >> >> > +        /*
> >> >> > +         * .got.plt section is used only by dynamic linker
> >> >> > +         * and our output is not supposed to be loaded by
> >> >> > +         * dynamic linker. Additionally, it just contains
> >> >> > +         * .PLT0 which is referenced from nowhere. So, we
> >> >> > +         * can safely drop .got.plt here.
> >> >> > +         *
> >> >> > +         * Ha! This should be really discarded here. However,
> >> >> > +         * .got.plt section contains _GLOBAL_OFFSET_TABLE_
> >> >> > +         * symbol too and it is used as a reference for relative
> >> >> > +         * addressing (and only for that thing). Hence, ld
> >> >> > +         * complains if we remove that section because it
> >> >> > +         * cannot find _GLOBAL_OFFSET_TABLE_. So, drop .got.plt
> >> >> > +         * section during conversion to plain binary format.
> >> >> > +         * Please check build32.mk for more details.
> >> >> > +         */
> >> >> > +        /* *(.got.plt) */
> >> >> > +  }
> >> >>
> >> >> I'm afraid this needs more investigation: Afaik there should be no
> >> >
> >> > I am not sure what else we should look for.
> >>
> >> The reason why such an empty .got.plt gets created in the first place.
> >> If e.g. that turns out to be a bug in (some versions of) binutils, then
> >> that bug should be named here as the reason.
> >
> > If PIC/PIE code is build then .got.plt exists in executable even if it
> > is not linked with dynamic libraries.
>
> Well - then just don't force -fPIC or -fPIE for the compilation of this
> code?

No way. Then final code is not relocatable. And this code must be relocatable.

> >> >> reason for the linker to create an otherwise empty .got.plt in the
> >> >
> >> > As I wrote above. It contains _GLOBAL_OFFSET_TABLE_ which is used
> >> > as a reference for relative addressing.
> >>
> >> But we don't use any such, so without being needed I don't think
> >> the symbol needs to be created.
> >
> > R_386_GOTPC and R_386_GOTOFF relocations use address of
> > _GLOBAL_OFFSET_TABLE_
> > as a reference. So, it is needed during linking phase. However, later it is
> > not needed.  Hence, .got.plt with _GLOBAL_OFFSET_TABLE_ and .PLT0 can safely
> > be dropped.
>
> These two relocation types should not appear for non-PIC/PIE code.

Sure but as above.

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-04-15 12:33 ` [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator Daniel Kiper
  2016-05-25  8:39   ` Jan Beulich
@ 2016-07-05 18:26   ` Daniel Kiper
  2016-07-06  7:22     ` Jan Beulich
  1 sibling, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-07-05 18:26 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, andrew.cooper3, stefano.stabellini, cardoe, pgnet.dev,
	ning.sun, david.vrabel, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, Apr 15, 2016 at 02:33:12PM +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
> 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.

I have done more experiments, read more code, etc. You can find results below.

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

I have checked Linux kernel code. It allocates buffer for memory map using
EFI API and later reserve it in e820 memory map. Simple. This should work
for us too but...

>    In later case we must also care about conflicts with e.g. crash
>    kernel regions which could be quite difficult.

This is not a problem since Xen can choose dynamically placement of kdump
region during boot phase and there is no requirement to specify it in boot
command line. This means that it will avoid all allocated/reserved regions
including EFI memory map. However, there is one potential problem which
cannot be avoided simply with current EFI spec. I think about conflicts
with trampoline. It must live below 1 MiB. However, there is not something
similar to "AllocateMaxAddress" option for AllocatePages() which would
ask EFI to allocate memory above a given address (Hmmm... Why UEFI designers
did not added such option, e.g. "AllocateMinAddress"? For me it is obvious
thing if we have "AllocateMaxAddress"). So, it means that we cannot simply
say "give me a memory chunk above 1 MiB". AIUI, Linux guys do not care,
hope that all EFI platforms are smart and AllocatePages() tries hard to
avoid everything below 1 MiB. We can go this way too. However, I am almost
sure that sooner or later we will find crazy platforms which allocate memory
from 0-1 MiB region. We can avoid this by getting EFI memory map, looking for
free regions above 1 MiB and then trying to allocate memory chunk using
AllocatePages() with "AllocateAddress". Does it make sense?

> 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().

2a) We can create something like .init.bss and put this thing at the end of
    regular .bss section. Then allocate memory chunks starting from lowest
    address. After init phase we can free unused memory as in case of .init.text
    or .init.data sections. This way we do not need allocate any space in
    image file and freeing of unused memory should be simple. What do you
    think about that one?

Daniel

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-05-27  8:16       ` Jan Beulich
  2016-06-01 15:07         ` Daniel Kiper
@ 2016-07-05 18:33         ` Daniel Kiper
  2016-07-06  6:55           ` Jan Beulich
  1 sibling, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-07-05 18:33 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> > 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.
> >>
> >> I do not view this as a valid reason for the change.
> >
> > Why?
>
> Because there are no accesses to the structure in non-EFI builds?
> Even if it's just a small table, I'm generally opposed to adding dead
> code or data. I simply do not like the attitude of "memory is cheap"
> these days. Following that model leads to quite a bit of useless
> bloat. Plus no matter whether memory is cheap, cache and TLB
> bandwidth are precious, and both may get pressure added by such
> dead elements.
>
> >> > --- a/xen/arch/x86/efi/stub.c
> >> > +++ b/xen/arch/x86/efi/stub.c
> >> > @@ -8,6 +8,14 @@
> >> >  const bool_t efi_enabled = 0;
> >> >  #endif
> >> >
> >> > +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
> >> > +};
> >>
> >> I don't view duplicating this here as a good approach - you'd better
> >> move the existing instance elsewhere. If this was a temporary thing
> >> (until a later patch), it might be acceptable, but since building without
> >> EFI support will need to remain an option (for people using older tool
> >> chains), I don't expect a later patch to remove this.
> >
> > Do you think about separate C file which should contain efi struct
> > and should be included in stub.c and runtime.c? Or anything else?
>
> A separate file seems to be overkill. Just move it to some other
> existing file; I'm sure some sensible place can be found.

This solution is not perfect, however, I cannot find better place for
efi struct. If you have one then drop me a line.

Daniel

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-07-05 18:33         ` Daniel Kiper
@ 2016-07-06  6:55           ` Jan Beulich
  2016-07-06 10:27             ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-07-06  6:55 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 05.07.16 at 20:33, <daniel.kiper@oracle.com> wrote:
> On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
>> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
>> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
>> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> > --- a/xen/arch/x86/efi/stub.c
>> >> > +++ b/xen/arch/x86/efi/stub.c
>> >> > @@ -8,6 +8,14 @@
>> >> >  const bool_t efi_enabled = 0;
>> >> >  #endif
>> >> >
>> >> > +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
>> >> > +};
>> >>
>> >> I don't view duplicating this here as a good approach - you'd better
>> >> move the existing instance elsewhere. If this was a temporary thing
>> >> (until a later patch), it might be acceptable, but since building without
>> >> EFI support will need to remain an option (for people using older tool
>> >> chains), I don't expect a later patch to remove this.
>> >
>> > Do you think about separate C file which should contain efi struct
>> > and should be included in stub.c and runtime.c? Or anything else?
>>
>> A separate file seems to be overkill. Just move it to some other
>> existing file; I'm sure some sensible place can be found.
> 
> This solution is not perfect, however, I cannot find better place for
> efi struct. If you have one then drop me a line.

common/kernel.c or common/lib.c.

Jan


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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-07-05 18:26   ` Daniel Kiper
@ 2016-07-06  7:22     ` Jan Beulich
  2016-07-06 11:15       ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-07-06  7:22 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 05.07.16 at 20:26, <daniel.kiper@oracle.com> wrote:
> On Fri, Apr 15, 2016 at 02:33:12PM +0200, Daniel Kiper wrote:
>> 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.
> 
> I have checked Linux kernel code. It allocates buffer for memory map using
> EFI API and later reserve it in e820 memory map. Simple. This should work
> for us too but...
> 
>>    In later case we must also care about conflicts with e.g. crash
>>    kernel regions which could be quite difficult.
> 
> This is not a problem since Xen can choose dynamically placement of kdump
> region during boot phase and there is no requirement to specify it in boot
> command line. This means that it will avoid all allocated/reserved regions
> including EFI memory map. However, there is one potential problem which
> cannot be avoided simply with current EFI spec. I think about conflicts
> with trampoline. It must live below 1 MiB. However, there is not something
> similar to "AllocateMaxAddress" option for AllocatePages() which would
> ask EFI to allocate memory above a given address (Hmmm... Why UEFI designers
> did not added such option, e.g. "AllocateMinAddress"? For me it is obvious
> thing if we have "AllocateMaxAddress").

Not obvious to me at all. Allowing an upper bound is natural (for
both DMA purposes and arbitrary other addressing restrictions).
Allowing a lower bound to be specified isn't.

> So, it means that we cannot simply
> say "give me a memory chunk above 1 MiB". AIUI, Linux guys do not care,
> hope that all EFI platforms are smart and AllocatePages() tries hard to
> avoid everything below 1 MiB. We can go this way too. However, I am almost
> sure that sooner or later we will find crazy platforms which allocate memory
> from 0-1 MiB region. We can avoid this by getting EFI memory map, looking for
> free regions above 1 MiB and then trying to allocate memory chunk using
> AllocatePages() with "AllocateAddress". Does it make sense?

I don't see the point of all that, as I don't see why any EFI
implementation would want to deviate from the first line principle
of satisfying allocation requests as high as possible.

Apart from that using (only) EFI allocation mechanisms for
obtaining the trampoline area won't work anyway, as we already
know there are systems where all of the memory below 1Mb is
in use by EFI (mostly with boot kind allocations, i.e. becoming
available after ExitBootServices()).

>> 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().
> 
> 2a) We can create something like .init.bss and put this thing at the end of
>     regular .bss section. Then allocate memory chunks starting from lowest
>     address. After init phase we can free unused memory as in case of .init.text
>     or .init.data sections. This way we do not need allocate any space in
>     image file and freeing of unused memory should be simple. What do you
>     think about that one?

With (again) the caveat of how to size such a region.

Bottom line - I continue to be unconvinced that we need something
"new" here at all.

Jan

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-07-06  6:55           ` Jan Beulich
@ 2016-07-06 10:27             ` Daniel Kiper
  2016-07-06 12:00               ` Jan Beulich
  0 siblings, 1 reply; 94+ messages in thread
From: Daniel Kiper @ 2016-07-06 10:27 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, Jul 06, 2016 at 12:55:42AM -0600, Jan Beulich wrote:
> >>> On 05.07.16 at 20:33, <daniel.kiper@oracle.com> wrote:
> > On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
> >> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
> >> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> >> > --- a/xen/arch/x86/efi/stub.c
> >> >> > +++ b/xen/arch/x86/efi/stub.c
> >> >> > @@ -8,6 +8,14 @@
> >> >> >  const bool_t efi_enabled = 0;
> >> >> >  #endif
> >> >> >
> >> >> > +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
> >> >> > +};
> >> >>
> >> >> I don't view duplicating this here as a good approach - you'd better
> >> >> move the existing instance elsewhere. If this was a temporary thing
> >> >> (until a later patch), it might be acceptable, but since building without
> >> >> EFI support will need to remain an option (for people using older tool
> >> >> chains), I don't expect a later patch to remove this.
> >> >
> >> > Do you think about separate C file which should contain efi struct
> >> > and should be included in stub.c and runtime.c? Or anything else?
> >>
> >> A separate file seems to be overkill. Just move it to some other
> >> existing file; I'm sure some sensible place can be found.
> >
> > This solution is not perfect, however, I cannot find better place for
> > efi struct. If you have one then drop me a line.
>
> common/kernel.c or common/lib.c.

This means that we must delete efi struct initialization from
xen/common/efi/runtime.c and xen/arch/x86/efi/stub.c and put
it in one of both files mentioned by you. Is it OK for you?

Daniel

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

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

* Re: [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator
  2016-07-06  7:22     ` Jan Beulich
@ 2016-07-06 11:15       ` Daniel Kiper
  0 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-07-06 11:15 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Wed, Jul 06, 2016 at 01:22:24AM -0600, Jan Beulich wrote:
> >>> On 05.07.16 at 20:26, <daniel.kiper@oracle.com> wrote:
> > On Fri, Apr 15, 2016 at 02:33:12PM +0200, Daniel Kiper wrote:
> >> 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.
> >
> > I have checked Linux kernel code. It allocates buffer for memory map using
> > EFI API and later reserve it in e820 memory map. Simple. This should work
> > for us too but...
> >
> >>    In later case we must also care about conflicts with e.g. crash
> >>    kernel regions which could be quite difficult.
> >
> > This is not a problem since Xen can choose dynamically placement of kdump
> > region during boot phase and there is no requirement to specify it in boot
> > command line. This means that it will avoid all allocated/reserved regions
> > including EFI memory map. However, there is one potential problem which
> > cannot be avoided simply with current EFI spec. I think about conflicts
> > with trampoline. It must live below 1 MiB. However, there is not something
> > similar to "AllocateMaxAddress" option for AllocatePages() which would
> > ask EFI to allocate memory above a given address (Hmmm... Why UEFI designers
> > did not added such option, e.g. "AllocateMinAddress"? For me it is obvious
> > thing if we have "AllocateMaxAddress").
>
> Not obvious to me at all. Allowing an upper bound is natural (for
> both DMA purposes and arbitrary other addressing restrictions).
> Allowing a lower bound to be specified isn't.

I think that I have shown above that on some platforms this could be useful option.

> > So, it means that we cannot simply
> > say "give me a memory chunk above 1 MiB". AIUI, Linux guys do not care,
> > hope that all EFI platforms are smart and AllocatePages() tries hard to
> > avoid everything below 1 MiB. We can go this way too. However, I am almost
> > sure that sooner or later we will find crazy platforms which allocate memory
> > from 0-1 MiB region. We can avoid this by getting EFI memory map, looking for
> > free regions above 1 MiB and then trying to allocate memory chunk using
> > AllocatePages() with "AllocateAddress". Does it make sense?
>
> I don't see the point of all that, as I don't see why any EFI
> implementation would want to deviate from the first line principle
> of satisfying allocation requests as high as possible.

In general this is good idea. However, I have not seen such requirement in
UEFI spec. So, I suppose that bad things may happen on some EFI implementations
and that is why I proposed a bit "smarter" approach. On the other hand if Linux
does allocations in "simple" way (just AllocatePages() call) then it means that
this solution works on most platforms if not all. So, probably "simple" solution
would work for us too.

Anyway, I think that it is worth considering all potential issues if we are
aware of them in advance.

> Apart from that using (only) EFI allocation mechanisms for
> obtaining the trampoline area won't work anyway, as we already
> know there are systems where all of the memory below 1Mb is
> in use by EFI (mostly with boot kind allocations, i.e. becoming
> available after ExitBootServices()).

I know about that. However, I am talking here about memory allocation
for EFI memory map. As I said above this region may potentially (well,
it looks that probability is low but as I said earlier we should think
and discuss this issue here) conflict with trampoline region. Though
I am not saying how this region (for trampoline) should be allocated
because current solution works well.

> >> 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().
> >
> > 2a) We can create something like .init.bss and put this thing at the end of
> >     regular .bss section. Then allocate memory chunks starting from lowest
> >     address. After init phase we can free unused memory as in case of .init.text
> >     or .init.data sections. This way we do not need allocate any space in
> >     image file and freeing of unused memory should be simple. What do you
> >     think about that one?
>
> With (again) the caveat of how to size such a region.

Yep, you are right.

> Bottom line - I continue to be unconvinced that we need something
> "new" here at all.

Why? I think that I have shown all currently existing issues related
to place_string() usage. Am I missing something? And please remember
that we are talking here about allocating memory for EFI memory map
not for trampoline.

Daniel

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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-07-06 10:27             ` Daniel Kiper
@ 2016-07-06 12:00               ` Jan Beulich
  2016-07-06 12:55                 ` Daniel Kiper
  0 siblings, 1 reply; 94+ messages in thread
From: Jan Beulich @ 2016-07-06 12:00 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, stefano.stabellini, andrew.cooper3, cardoe,
	pgnet.dev, ning.sun, david.vrabel, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 06.07.16 at 12:27, <daniel.kiper@oracle.com> wrote:
> On Wed, Jul 06, 2016 at 12:55:42AM -0600, Jan Beulich wrote:
>> >>> On 05.07.16 at 20:33, <daniel.kiper@oracle.com> wrote:
>> > On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
>> >> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
>> >> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
>> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
>> >> >> > --- a/xen/arch/x86/efi/stub.c
>> >> >> > +++ b/xen/arch/x86/efi/stub.c
>> >> >> > @@ -8,6 +8,14 @@
>> >> >> >  const bool_t efi_enabled = 0;
>> >> >> >  #endif
>> >> >> >
>> >> >> > +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
>> >> >> > +};
>> >> >>
>> >> >> I don't view duplicating this here as a good approach - you'd better
>> >> >> move the existing instance elsewhere. If this was a temporary thing
>> >> >> (until a later patch), it might be acceptable, but since building without
>> >> >> EFI support will need to remain an option (for people using older tool
>> >> >> chains), I don't expect a later patch to remove this.
>> >> >
>> >> > Do you think about separate C file which should contain efi struct
>> >> > and should be included in stub.c and runtime.c? Or anything else?
>> >>
>> >> A separate file seems to be overkill. Just move it to some other
>> >> existing file; I'm sure some sensible place can be found.
>> >
>> > This solution is not perfect, however, I cannot find better place for
>> > efi struct. If you have one then drop me a line.
>>
>> common/kernel.c or common/lib.c.
> 
> This means that we must delete efi struct initialization from
> xen/common/efi/runtime.c and xen/arch/x86/efi/stub.c and put
> it in one of both files mentioned by you. Is it OK for you?

Note how in my original reply I said "move the existing instance
elsewhere".

Jan


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

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

* Re: [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c
  2016-07-06 12:00               ` Jan Beulich
@ 2016-07-06 12:55                 ` Daniel Kiper
  0 siblings, 0 replies; 94+ messages in thread
From: Daniel Kiper @ 2016-07-06 12:55 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	david.vrabel, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Wed, Jul 06, 2016 at 06:00:47AM -0600, Jan Beulich wrote:
> >>> On 06.07.16 at 12:27, <daniel.kiper@oracle.com> wrote:
> > On Wed, Jul 06, 2016 at 12:55:42AM -0600, Jan Beulich wrote:
> >> >>> On 05.07.16 at 20:33, <daniel.kiper@oracle.com> wrote:
> >> > On Fri, May 27, 2016 at 02:16:09AM -0600, Jan Beulich wrote:
> >> >> >>> On 25.05.16 at 18:45, <daniel.kiper@oracle.com> wrote:
> >> >> > On Wed, May 25, 2016 at 01:03:42AM -0600, Jan Beulich wrote:
> >> >> >> >>> On 15.04.16 at 14:33, <daniel.kiper@oracle.com> wrote:
> >> >> >> > --- a/xen/arch/x86/efi/stub.c
> >> >> >> > +++ b/xen/arch/x86/efi/stub.c
> >> >> >> > @@ -8,6 +8,14 @@
> >> >> >> >  const bool_t efi_enabled = 0;
> >> >> >> >  #endif
> >> >> >> >
> >> >> >> > +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
> >> >> >> > +};
> >> >> >>
> >> >> >> I don't view duplicating this here as a good approach - you'd better
> >> >> >> move the existing instance elsewhere. If this was a temporary thing
> >> >> >> (until a later patch), it might be acceptable, but since building without
> >> >> >> EFI support will need to remain an option (for people using older tool
> >> >> >> chains), I don't expect a later patch to remove this.
> >> >> >
> >> >> > Do you think about separate C file which should contain efi struct
> >> >> > and should be included in stub.c and runtime.c? Or anything else?
> >> >>
> >> >> A separate file seems to be overkill. Just move it to some other
> >> >> existing file; I'm sure some sensible place can be found.
> >> >
> >> > This solution is not perfect, however, I cannot find better place for
> >> > efi struct. If you have one then drop me a line.
> >>
> >> common/kernel.c or common/lib.c.
> >
> > This means that we must delete efi struct initialization from
> > xen/common/efi/runtime.c and xen/arch/x86/efi/stub.c and put
> > it in one of both files mentioned by you. Is it OK for you?
>
> Note how in my original reply I said "move the existing instance
> elsewhere".

OK, thanks. I will do that.

Daniel

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

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

end of thread, other threads:[~2016-07-06 12:56 UTC | newest]

Thread overview: 94+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-15 12:33 [PATCH v3 00/16] x86: multiboot2 protocol support Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 01/16] x86/boot: do not create unwind tables Daniel Kiper
2016-04-15 15:45   ` Andrew Cooper
2016-04-15 12:33 ` [PATCH v3 02/16] x86: zero BSS using stosl instead of stosb Daniel Kiper
2016-04-15 13:57   ` Konrad Rzeszutek Wilk
2016-04-15 15:48   ` Andrew Cooper
2016-04-15 12:33 ` [PATCH v3 03/16] x86/boot: call reloc() using cdecl calling convention Daniel Kiper
2016-04-15 15:56   ` Andrew Cooper
2016-06-17  8:41     ` Daniel Kiper
2016-06-17  9:30       ` Jan Beulich
2016-05-24  8:42   ` Jan Beulich
2016-04-15 12:33 ` [PATCH v3 04/16] x86/boot/reloc: create generic alloc and copy functions Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 05/16] x86/boot: use %ecx instead of %eax Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 06/16] x86/boot/reloc: Rename some variables and rearrange code a bit Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 07/16] x86/boot: create *.lnk files with linker script Daniel Kiper
2016-04-15 14:04   ` Konrad Rzeszutek Wilk
2016-05-24  9:05   ` Jan Beulich
2016-05-24 12:28     ` Daniel Kiper
2016-05-24 12:52       ` Jan Beulich
2016-06-17  9:06         ` Daniel Kiper
2016-06-17 10:04           ` Jan Beulich
2016-06-17 10:34             ` Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 08/16] x86: add multiboot2 protocol support Daniel Kiper
2016-05-24 15:46   ` Jan Beulich
2016-05-25 16:34     ` Daniel Kiper
2016-05-26 10:28       ` Andrew Cooper
2016-05-27  8:08         ` Jan Beulich
2016-05-27  8:13           ` Andrew Cooper
2016-05-27  8:24             ` Jan Beulich
2016-05-27  8:11       ` Jan Beulich
2016-04-15 12:33 ` [PATCH v3 09/16] efi: explicitly define efi struct in xen/arch/x86/efi/stub.c Daniel Kiper
2016-05-25  7:03   ` Jan Beulich
2016-05-25 16:45     ` Daniel Kiper
2016-05-27  8:16       ` Jan Beulich
2016-06-01 15:07         ` Daniel Kiper
2016-07-05 18:33         ` Daniel Kiper
2016-07-06  6:55           ` Jan Beulich
2016-07-06 10:27             ` Daniel Kiper
2016-07-06 12:00               ` Jan Beulich
2016-07-06 12:55                 ` Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 10/16] efi: create efi_enabled() Daniel Kiper
2016-05-25  7:20   ` Jan Beulich
2016-05-25 17:15     ` Daniel Kiper
2016-05-26 10:31       ` Andrew Cooper
2016-05-27  8:22       ` Jan Beulich
2016-06-01 15:23         ` Daniel Kiper
2016-06-01 15:41           ` Jan Beulich
2016-06-01 19:28             ` Daniel Kiper
2016-06-02  8:06               ` Jan Beulich
2016-04-15 12:33 ` [PATCH v3 11/16] efi: build xen.gz with EFI code Daniel Kiper
2016-05-25  7:53   ` Jan Beulich
2016-05-25 19:07     ` Daniel Kiper
2016-05-27  8:31       ` Jan Beulich
2016-06-01 15:48         ` Daniel Kiper
2016-06-01 15:58           ` Jan Beulich
2016-06-01 19:39             ` Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator Daniel Kiper
2016-05-25  8:39   ` Jan Beulich
2016-05-25 19:48     ` Daniel Kiper
2016-05-27  8:37       ` Jan Beulich
2016-06-01 15:58         ` Daniel Kiper
2016-06-01 16:02           ` Jan Beulich
2016-06-01 19:53             ` Daniel Kiper
2016-06-02  8:11               ` Jan Beulich
2016-06-02 10:43                 ` Daniel Kiper
2016-06-02 11:10                   ` Jan Beulich
2016-06-01 16:01         ` Daniel Kiper
2016-07-05 18:26   ` Daniel Kiper
2016-07-06  7:22     ` Jan Beulich
2016-07-06 11:15       ` Daniel Kiper
2016-04-15 12:33 ` [PATCH v3 13/16 - RFC] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
2016-05-25  9:32   ` Jan Beulich
2016-05-25 10:29     ` Jan Beulich
2016-05-25 21:02     ` Daniel Kiper
2016-05-27  9:02       ` Jan Beulich
2016-06-01 19:03         ` Daniel Kiper
2016-06-02  8:34           ` Jan Beulich
2016-06-02 16:12             ` Daniel Kiper
2016-06-03  9:26               ` Jan Beulich
2016-06-03 17:06                 ` Konrad Rzeszutek Wilk
2016-04-15 12:33 ` [PATCH v3 14/16] x86/boot: implement early command line parser in C Daniel Kiper
2016-05-25 10:33   ` Jan Beulich
2016-05-25 21:36     ` Daniel Kiper
2016-05-27  9:33       ` Jan Beulich
2016-06-02  8:15         ` Daniel Kiper
2016-06-02  8:39           ` Jan Beulich
2016-04-15 12:33 ` [PATCH v3 15/16 - RFC] x86: make Xen early boot code relocatable Daniel Kiper
2016-05-25 10:48   ` Jan Beulich
2016-04-15 12:33 ` [PATCH v3 16/16] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
2016-05-25 11:03   ` Jan Beulich
2016-06-01 13:35     ` Daniel Kiper
2016-06-01 14:44       ` Jan Beulich
2016-06-01 19:16         ` Daniel Kiper
2016-06-02  8:41           ` 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).