All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v11 00/13] x86: multiboot2 protocol support
@ 2016-12-05 22:25 Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 01/13] x86: add " Daniel Kiper
                   ` (16 more replies)
  0 siblings, 17 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

Hi,

I am sending eleventh version of multiboot2 protocol support for
legacy BIOS and EFI platforms. This patch series release contains
fixes for all known issues.

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 is short list of changes since v10:
  - changed patches: 06 (small change suggested by Jan).

This is Xen 4.9 material.

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             |    3 +
 xen/arch/x86/boot/Makefile        |   12 +-
 xen/arch/x86/boot/build32.mk      |    2 +
 xen/arch/x86/boot/cmdline.S       |  367 --------------------------------------------------------
 xen/arch/x86/boot/cmdline.c       |  340 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/defs.h          |   58 +++++++++
 xen/arch/x86/boot/edd.S           |    3 -
 xen/arch/x86/boot/head.S          |  540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 xen/arch/x86/boot/reloc.c         |  151 +++++++++++++++++++++--
 xen/arch/x86/boot/trampoline.S    |   22 +++-
 xen/arch/x86/boot/video.S         |    7 --
 xen/arch/x86/boot/wakeup.S        |    4 +-
 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         |   12 +-
 xen/arch/x86/efi/efi-boot.h       |   65 +++++++---
 xen/arch/x86/efi/stub.c           |   46 ++++++-
 xen/arch/x86/mpparse.c            |    4 +-
 xen/arch/x86/setup.c              |   34 +++---
 xen/arch/x86/shutdown.c           |    5 +-
 xen/arch/x86/time.c               |    2 +-
 xen/arch/x86/x86_64/asm-offsets.c |   15 +++
 xen/arch/x86/xen.lds.S            |   10 +-
 xen/common/efi/boot.c             |   83 ++++++++++++-
 xen/common/efi/runtime.c          |   23 +++-
 xen/common/version.c              |    2 +-
 xen/drivers/acpi/osl.c            |    2 +-
 xen/include/asm-x86/page.h        |    2 +-
 xen/include/xen/efi.h             |    8 +-
 xen/include/xen/multiboot2.h      |  182 ++++++++++++++++++++++++++++
 33 files changed, 1528 insertions(+), 539 deletions(-)

Daniel Kiper (13):
      x86: add multiboot2 protocol support
      efi: create efi_enabled()
      x86: allow EFI reboot method neither on EFI platforms...
      x86: properly calculate xen ELF end of image address
      efi: build xen.gz with EFI code
      efi: create new early memory allocator
      x86: add multiboot2 protocol support for EFI platforms
      x86/boot: implement early command line parser in C
      x86: change default load address from 1 MiB to 2 MiB
      x86/setup: use XEN_IMG_OFFSET instead of...
      x86: make Xen early boot code relocatable
      x86/boot: rename sym_phys() to sym_offs()
      x86: add multiboot2 protocol support for relocatable images


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

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

* [PATCH v11 01/13] x86: add multiboot2 protocol support
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2017-01-10  1:21   ` Doug Goldstein
  2016-12-05 22:25 ` [PATCH v11 02/13] efi: create efi_enabled() Daniel Kiper
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

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

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

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v9 - suggestions/fixes:
   - use .L label instead of numeric one in multiboot2 data scanning loop;
     I hope that this change does not invalidate Jan's Reviewed-by
     (suggested by Jan Beulich).

v8 - suggestions/fixes:
   - use sizeof(<var>/<expr>) instead of sizeof(<type>)
     if it is possible
     (suggested by Jan Beulich).

v7 - suggestions/fixes:
   - rename mbi_mbi/mbi2_mbi to mbi_reloc/mbi2_reloc respectively
     (suggested by Jan Beulich),
   - initialize mbi_out->flags using "|=" instead of "="
     (suggested by Jan Beulich),
   - use sizeof(*mmap_dst) instead of sizeof(memory_map_t)
     if it makes sense
     (suggested by Jan Beulich).

v6 - suggestions/fixes:
   - properly index multiboot2_tag_mmap_t.entries[]
     (suggested by Jan Beulich),
   - do not index mbi_out_mods[] beyond its end
     (suggested by Andrew Cooper),
   - reduce number of casts
     (suggested by Andrew Cooper and Jan Beulich),
   - add braces to increase code readability
     (suggested by Andrew Cooper).

v5 - suggestions/fixes:
   - check multiboot2_tag_mmap_t.entry_size before
     multiboot2_tag_mmap_t.entries[] use
     (suggested by Jan Beulich),
   - properly index multiboot2_tag_mmap_t.entries[]
     (suggested by Jan Beulich),
   - use "type name[]" instad of "type name[0]"
     in xen/include/xen/multiboot2.h
     (suggested by Jan Beulich),
   - remove unneeded comment
     (suggested by Jan Beulich).

v4 - suggestions/fixes:
   - avoid assembly usage in xen/arch/x86/boot/reloc.c,
   - fix boundary check issue and optimize
     for() loops in mbi2_mbi(),
   - move to stdcall calling convention,
   - remove unneeded typeof() from ALIGN_UP() macro
     (suggested by Jan Beulich),
   - add and use NULL definition in xen/arch/x86/boot/reloc.c
     (suggested by Jan Beulich),
   - do not read data beyond the end of multiboot2
     information in xen/arch/x86/boot/head.S
     (suggested by Jan Beulich),
   - add :req to some .macro arguments
     (suggested by Jan Beulich),
   - use cmovcc if possible,
   - add .L to multiboot2_header_end label
     (suggested by Jan Beulich),
   - add .L to multiboot2_proto label
     (suggested by Jan Beulich),
   - improve label names
     (suggested by Jan Beulich).

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          |  107 ++++++++++++++++++++++-
 xen/arch/x86/boot/reloc.c         |  148 ++++++++++++++++++++++++++++++--
 xen/arch/x86/x86_64/asm-offsets.c |    9 ++
 xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
 5 files changed, 426 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 6f2c668..d423fd8 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:req, args:vararg
+        .long \arg
+        .ifnb \args
+        mb2ht_args \args
+        .endif
+        .endm
+
+        .macro mb2ht_init type:req, req: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   .Lmultiboot2_header_end - multiboot2_header_start
+        /* Multiboot2 header checksum. */
+        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
+                        (.Lmultiboot2_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)
+.Lmultiboot2_header_end:
+
         .section .init.rodata, "a", @progbits
         .align 4
 
@@ -82,10 +141,52 @@ __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      .Lmultiboot2_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
+
+.Lmultiboot2_proto:
+        /* Skip Multiboot2 information fixed part. */
+        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
+
+.Lmb2_tsize:
+        /* Check Multiboot2 information total size. */
+        mov     %ecx,%edi
+        sub     %ebx,%edi
+        cmp     %edi,MB2_fixed_total_size(%ebx)
+        jbe     trampoline_setup
+
+        /* Get mem_lower from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
+        cmove   MB2_mem_lower(%ecx),%edx
+        je      trampoline_setup
+
+        /* 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     .Lmb2_tsize
+
+trampoline_setup:
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -100,9 +201,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,6 +219,7 @@ __start:
         mov     $sym_phys(cpu0_stack)+1024,%esp
         push    %ecx                /* Boot trampoline address. */
         push    %ebx                /* Multiboot information address. */
+        push    %eax                /* Multiboot magic. */
         call    reloc
         mov     %eax,sym_phys(multiboot_ptr)
 
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index ea8cb37..b22bf1e 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,7 +26,12 @@ asm (
     );
 
 typedef unsigned int u32;
+typedef unsigned long long u64;
+
 #include "../../../include/xen/multiboot.h"
+#include "../../../include/xen/multiboot2.h"
+
+#define NULL		((void *)0)
 
 #define __stdcall	__attribute__((__stdcall__))
 
@@ -32,6 +40,9 @@ typedef unsigned int u32;
 
 #define _p(val)		((void *)(unsigned long)(val))
 
+#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;
 
 static u32 alloc_mem(u32 bytes)
@@ -39,6 +50,12 @@ static u32 alloc_mem(u32 bytes)
     return alloc -= ALIGN_UP(bytes, 16);
 }
 
+static void zero_mem(u32 s, u32 bytes)
+{
+    while ( bytes-- )
+        *(char *)s++ = 0;
+}
+
 static u32 copy_mem(u32 src, u32 bytes)
 {
     u32 dst, dst_ret;
@@ -65,13 +82,11 @@ static u32 copy_string(u32 src)
     return copy_mem(src, p - src + 1);
 }
 
-multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline)
+static multiboot_info_t *mbi_reloc(u32 mbi_in)
 {
     int i;
     multiboot_info_t *mbi_out;
 
-    alloc = trampoline;
-
     mbi_out = _p(copy_mem(mbi_in, sizeof(*mbi_out)));
 
     if ( mbi_out->flags & MBI_CMDLINE )
@@ -108,3 +123,126 @@ multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline)
 
     return mbi_out;
 }
+
+static multiboot_info_t *mbi2_reloc(u32 mbi_in)
+{
+    const multiboot2_fixed_t *mbi_fix = _p(mbi_in);
+    const multiboot2_memory_map_t *mmap_src;
+    const multiboot2_tag_t *tag;
+    module_t *mbi_out_mods = NULL;
+    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 = _p(ptr);
+    zero_mem(ptr, sizeof(*mbi_out));
+
+    /* Skip Multiboot2 information fixed part. */
+    ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN);
+
+    /* Get the number of modules. */
+    for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size;
+          tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) )
+    {
+        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
+            ++mbi_out->mods_count;
+        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
+            break;
+    }
+
+    if ( mbi_out->mods_count )
+    {
+        mbi_out->flags |= MBI_MODULES;
+        mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(*mbi_out_mods));
+        mbi_out_mods = _p(mbi_out->mods_addr);
+    }
+
+    /* Skip Multiboot2 information fixed part. */
+    ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN);
+
+    /* Put all needed data into mbi_out. */
+    for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size;
+          tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) )
+        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:
+            if ( get_mb2_data(tag, mmap, entry_size) < sizeof(*mmap_src) )
+                break;
+
+            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(*mmap_dst);
+
+            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);
+
+            mmap_src = get_mb2_data(tag, mmap, entries);
+            mmap_dst = _p(mbi_out->mmap_addr);
+
+            for ( i = 0; i < mbi_out->mmap_length / sizeof(*mmap_dst); i++ )
+            {
+                /* Init size member properly. */
+                mmap_dst[i].size = sizeof(*mmap_dst);
+                mmap_dst[i].size -= sizeof(mmap_dst[i].size);
+                /* Now copy a given region data. */
+                mmap_dst[i].base_addr_low = (u32)mmap_src->addr;
+                mmap_dst[i].base_addr_high = (u32)(mmap_src->addr >> 32);
+                mmap_dst[i].length_low = (u32)mmap_src->len;
+                mmap_dst[i].length_high = (u32)(mmap_src->len >> 32);
+                mmap_dst[i].type = mmap_src->type;
+                mmap_src = _p(mmap_src) + get_mb2_data(tag, mmap, entry_size);
+            }
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MODULE:
+            if ( mod_idx >= mbi_out->mods_count )
+                break;
+
+            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;
+        }
+
+    return mbi_out;
+}
+
+multiboot_info_t __stdcall *reloc(u32 mb_magic, u32 mbi_in, u32 trampoline)
+{
+    alloc = trampoline;
+
+    if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC )
+        return mbi2_reloc(mbi_in);
+    else
+        return mbi_reloc(mbi_in);
+}
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index 64905c6..b437a8f 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 " */<==\"" \
@@ -167,6 +168,14 @@ 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_fixed_total_size, multiboot2_fixed_t, total_size);
+    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);
+    BLANK();
 
     OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
 }
diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
new file mode 100644
index 0000000..8dd5800
--- /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[];
+} 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[];
+} 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[];
+} multiboot2_tag_module_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MULTIBOOT2_H__ */
-- 
1.7.10.4


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

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

* [PATCH v11 02/13] efi: create efi_enabled()
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 01/13] x86: add " Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms Daniel Kiper
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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 defines
EFI_BOOT, EFI_LOADER and EFI_RS features. EFI_BOOT is equal
to old efi_enabled == 1. EFI_RS ease control on runtime
services usage. EFI_LOADER tells that Xen was loaded
directly from EFI as PE executable.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v7 - suggestions/fixes:
   - remove efi_enabled(EFI_RS) check from mapcache_current_vcpu()
     (suggested by Daniel Kiper and Jan Beulich),
   - remove BUG() from xen/arch/x86/efi/stub.c:efi_rs_using_pgtables()
     (suggested by Daniel Kiper and Jan Beulich).

v6 - suggestions/fixes:
   - define efi_enabled() as "bool efi_enabled(unsigned int feature)"
     instead of "bool_t efi_enabled(int feature)"
     (suggested by Jan Beulich),
   - define efi_flags as unsigned int
     (suggested by Jan Beulich),
   - various minor cleanups and fixes
     (suggested by Jan Beulich).

v5 - suggestions/fixes:
   - squash three patches into one
     (suggested by Jan Beulich),
   - introduce all features at once
     (suggested by Jan Beulich),
   - efi_enabled() returns bool_t
     instead of unsigned int
     (suggested by Jan Beulich),
   - update commit message.

v4 - suggestions/fixes:
   - rename EFI_PLATFORM to EFI_BOOT
     (suggested by Jan Beulich),
   - move EFI_BOOT definition to efi struct definition
     (suggested by Jan Beulich),
   - remove unneeded efi.flags initialization
     (suggested by Jan Beulich),
   - use __set_bit() instead of set_bit() if possible
     (suggested by Jan Beulich),
   - do efi_enabled() cleanup
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - improve commit message.

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    |    8 ++++----
 xen/arch/x86/mpparse.c     |    4 ++--
 xen/arch/x86/setup.c       |   12 +++++++-----
 xen/arch/x86/shutdown.c    |    2 +-
 xen/arch/x86/time.c        |    2 +-
 xen/common/efi/boot.c      |   19 +++++++++++++++----
 xen/common/efi/runtime.c   |   14 ++++++++------
 xen/common/version.c       |    2 +-
 xen/drivers/acpi/osl.c     |    2 +-
 xen/include/xen/efi.h      |    8 ++++++--
 12 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index b049e31..8dcb640 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_BOOT)) {
 		if (efi_smbios3_size && !(instance & 1)) {
 			*base = efi_smbios3_address;
 			*len = efi_smbios3_size;
@@ -696,7 +696,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_BOOT) ? 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..a58ef8e 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_rs_using_pgtables() )
         return NULL;
 
     /*
diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
index 07c2bd0..4158124 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -4,9 +4,10 @@
 #include <xen/lib.h>
 #include <asm/page.h>
 
-#ifndef efi_enabled
-const bool_t efi_enabled = 0;
-#endif
+bool efi_enabled(unsigned int feature)
+{
+    return false;
+}
 
 void __init efi_init_memory(void) { }
 
@@ -14,7 +15,6 @@ void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t l4e) { }
 
 bool_t efi_rs_using_pgtables(void)
 {
-    BUG();
     return 0;
 }
 
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index ef6557c..c3d5bdc 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_BOOT))
 		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_BOOT)) {
 		efi_check_config();
 		return;
 	}
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index b130671..d473ac8 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -483,8 +483,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_BOOT) )
         return;
 
     if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
@@ -770,7 +770,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_LOADER) )
     {
         set_pdx_range(xen_phys_start >> PAGE_SHIFT,
                       (xen_phys_start + BOOTSTRAP_MAP_BASE) >> PAGE_SHIFT);
@@ -785,6 +785,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
         memmap_type = loader;
     }
+    else if ( efi_enabled(EFI_BOOT) )
+        memmap_type = "EFI";
     else if ( e820_raw_nr != 0 )
     {
         memmap_type = "Xen-e820";
@@ -881,7 +883,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_LOADER) && i < mbi->mods_count; i++ )
     {
         if ( mod[i].mod_start & (PAGE_SIZE - 1) )
             panic("Bootloader didn't honor module alignment request.");
@@ -1122,7 +1124,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_LOADER) ? 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 cb2442a7..7a1a73a 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_RS) ? BOOT_EFI
                                   : acpi_disabled ? BOOT_KBD
                                                   : BOOT_ACPI;
 }
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index dda89d8..15c3657 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -814,7 +814,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_RS) )
     {
         res = efi_get_time();
         if ( res )
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 125c9ce..56544dc 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -934,6 +934,13 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     char *option_str;
     bool_t use_cfg_file;
 
+    __set_bit(EFI_BOOT, &efi_flags);
+    __set_bit(EFI_LOADER, &efi_flags);
+
+#ifndef CONFIG_ARM /* Disabled until runtime services implemented. */
+    __set_bit(EFI_RS, &efi_flags);
+#endif
+
     efi_init(ImageHandle, SystemTable);
 
     use_cfg_file = efi_arch_use_config_file(SystemTable);
@@ -1153,7 +1160,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
 #ifndef CONFIG_ARM /* TODO - runtime service support */
 
-static bool_t __initdata efi_rs_enable = 1;
 static bool_t __initdata efi_map_uc;
 
 static void __init parse_efi_param(char *s)
@@ -1171,7 +1177,12 @@ static void __init parse_efi_param(char *s)
             *ss = '\0';
 
         if ( !strcmp(s, "rs") )
-            efi_rs_enable = val;
+        {
+            if ( val )
+                __set_bit(EFI_RS, &efi_flags);
+            else
+                __clear_bit(EFI_RS, &efi_flags);
+        }
         else if ( !strcmp(s, "attr=uc") )
             efi_map_uc = val;
 
@@ -1254,7 +1265,7 @@ void __init efi_init_memory(void)
                desc->PhysicalStart, desc->PhysicalStart + len - 1,
                desc->Type, desc->Attribute);
 
-        if ( !efi_rs_enable ||
+        if ( !efi_enabled(EFI_RS) ||
              (!(desc->Attribute & EFI_MEMORY_RUNTIME) &&
               (!map_bs ||
                (desc->Type != EfiBootServicesCode &&
@@ -1328,7 +1339,7 @@ void __init efi_init_memory(void)
         }
     }
 
-    if ( !efi_rs_enable )
+    if ( !efi_enabled(EFI_RS) )
     {
         efi_fw_vendor = NULL;
         return;
diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index 4064620..8c44835 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -29,12 +29,6 @@ void efi_rs_leave(struct efi_rs_state *);
 
 #ifndef COMPAT
 
-/*
- * Currently runtime services are not implemented on ARM. To boot Xen with ACPI,
- * set efi_enabled to 1, so that Xen can get the ACPI root pointer from EFI.
- */
-const bool_t efi_enabled = 1;
-
 #ifndef CONFIG_ARM
 # include <asm/i387.h>
 # include <asm/xstate.h>
@@ -62,6 +56,9 @@ UINT64 __read_mostly efi_boot_max_var_store_size;
 UINT64 __read_mostly efi_boot_remain_var_store_size;
 UINT64 __read_mostly efi_boot_max_var_size;
 
+/* Bit field representing available EFI features/properties. */
+unsigned int efi_flags;
+
 struct efi __read_mostly efi = {
 	.acpi   = EFI_INVALID_TABLE_ADDR,
 	.acpi20 = EFI_INVALID_TABLE_ADDR,
@@ -72,6 +69,11 @@ struct efi __read_mostly efi = {
 
 const struct efi_pci_rom *__read_mostly efi_pci_roms;
 
+bool efi_enabled(unsigned int feature)
+{
+    return test_bit(feature, &efi_flags);
+}
+
 #ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */
 
 struct efi_rs_state efi_rs_enter(void)
diff --git a/xen/common/version.c b/xen/common/version.c
index 0d31e38..223cb52 100644
--- a/xen/common/version.c
+++ b/xen/common/version.c
@@ -160,7 +160,7 @@ static int __init xen_build_init(void)
 
 #ifdef CONFIG_X86
     /* Alternatively we may have a CodeView record from an EFI build. */
-    if ( rc && efi_enabled )
+    if ( rc && efi_enabled(EFI_LOADER) )
     {
         const struct pe_external_debug_directory *dir = (const void *)n;
 
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
index 9a49029..3616dfd 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_BOOT)) {
 		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..68c68a8 100644
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -5,10 +5,13 @@
 #include <xen/types.h>
 #endif
 
-extern const bool_t efi_enabled;
-
 #define EFI_INVALID_TABLE_ADDR (~0UL)
 
+extern unsigned int efi_flags;
+#define EFI_BOOT	0	/* Were we booted from EFI? */
+#define EFI_LOADER	1	/* Were we booted directly from EFI loader? */
+#define EFI_RS		2	/* Can we use runtime services? */
+
 /* Add fields here only if they need to be referenced from non-EFI code. */
 struct efi {
     unsigned long mps;          /* MPS table */
@@ -28,6 +31,7 @@ union compat_pf_efi_info;
 struct xenpf_efi_runtime_call;
 struct compat_pf_efi_runtime_call;
 
+bool efi_enabled(unsigned int feature);
 void efi_init_memory(void);
 bool_t efi_rs_using_pgtables(void);
 unsigned long efi_get_time(void);
-- 
1.7.10.4


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

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

* [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms...
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 01/13] x86: add " Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 02/13] efi: create efi_enabled() Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-07 13:18   ` Jan Beulich
  2016-12-05 22:25 ` [PATCH v11 04/13] x86: properly calculate xen ELF end of image address Daniel Kiper
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

..nor EFI platforms with runtime services enabled.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v6 - suggestions/fixes:
   - move this commit behind "efi: create efi_enabled()" commit
     (suggested by Jan Beulich).

v5 - suggestions/fixes:
   - fix build error
     (suggested by Jan Beulich),
   - improve commit message.
---
 xen/arch/x86/shutdown.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/arch/x86/shutdown.c b/xen/arch/x86/shutdown.c
index 7a1a73a..55f6840 100644
--- a/xen/arch/x86/shutdown.c
+++ b/xen/arch/x86/shutdown.c
@@ -80,6 +80,9 @@ static void __init set_reboot_type(char *str)
             break;
         str++;
     }
+
+    if ( reboot_type == BOOT_EFI && !efi_enabled(EFI_RS) )
+        reboot_type = BOOT_INVALID;
 }
 custom_param("reboot", set_reboot_type);
 
-- 
1.7.10.4


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

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

* [PATCH v11 04/13] x86: properly calculate xen ELF end of image address
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (2 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 05/13] efi: build xen.gz with EFI code Daniel Kiper
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

This patch is prereq for "efi: build xen.gz with EFI code" patch which adds,
among others, xen/arch/x86/efi/relocs-dummy.S to xen.gz output. Below there
is a description why it is needed.

Currently xen ELF end of image address is calculated using first line from
"nm -nr xen/xen-syms" output. However, potentially it may contain symbol
address not related to the end of image in any way. It can happen if a symbol
is introduced with address larger than _end symbol address. Such situation
encountered when I linked xen ELF binary with xen/arch/x86/efi/relocs-dummy.S.
Then first line from "nm -nr xen/xen-syms" contained "ffff82d0c0000000 A ALT_START"
and xen ELF image memory size was silently set to 1023 MiB. This issue happened
because there is no check which symbol address is used to calculate end of
image address. So, let's fix it and take ELF end of image address by reading
__2M_rwdata_end symbol address from nm output. This way xen ELF image build
process is not prone to changes in order of nm output.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v9 - suggestions/fixes:
   - use __2M_rwdata_end symbol instead of _end symbol
     (suggested by Jan Beulich),
   - really fix indention
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich).

v8 - suggestions/fixes:
   - use spaces instead of tab in indentation
     (suggested by Jan Beulich and Konrad Rzeszutek Wilk),
   - improve commit message
     (suggested by Jan Beulich).

v7 - suggestions/fixes:
   - use sed instead of awk
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/arch/x86/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 931917d..e40897f 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -91,7 +91,7 @@ endif
 
 $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
 	./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) 0x100000 \
-	`$(NM) -nr $(TARGET)-syms | head -n 1 | sed -e 's/^\([^ ]*\).*/0x\1/'`
+	               `$(NM) $(TARGET)-syms | sed -ne 's/^\([^ ]*\) . __2M_rwdata_end$$/0x\1/p'`
 
 ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o $(BASEDIR)/arch/x86/efi/built_in.o $(ALL_OBJS)
 
-- 
1.7.10.4


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

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

* [PATCH v11 05/13] efi: build xen.gz with EFI code
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (3 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 04/13] x86: properly calculate xen ELF end of image address Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 06/13] efi: create new early memory allocator Daniel Kiper
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v6 - suggestions/fixes:
   - improve efi_enabled() checks in efi_runtime_call()
     (suggested by Jan Beulich).

v5 - suggestions/fixes:
   - properly calculate efi symbol address in
     xen/arch/x86/xen.lds.S (I hope that this
     change does not invalidate Jan's ACK).

v4 - suggestions/fixes:
   - functions should return -ENOSYS instead
     of -EOPNOTSUPP if EFI runtime services
     are not available
     (suggested by Jan Beulich),
   - remove stale bits from xen/arch/x86/Makefile
     (suggested by Jan Beulich).

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/Makefile     |    2 +-
 xen/arch/x86/efi/Makefile |   12 ++++--------
 xen/arch/x86/xen.lds.S    |    4 ++--
 xen/common/efi/boot.c     |    3 +++
 xen/common/efi/runtime.c  |    9 +++++++++
 5 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index e40897f..2a0781a 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -219,6 +219,6 @@ efi/mkreloc: efi/mkreloc.c
 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 $(BASEDIR)/.xen.efi.[0-9]* efi/*.efi efi/disabled efi/mkreloc
 	rm -f boot/reloc.S boot/reloc.lnk boot/reloc.bin
 	rm -f note.o
diff --git a/xen/arch/x86/efi/Makefile b/xen/arch/x86/efi/Makefile
index ad3fdf7..442f3fc 100644
--- a/xen/arch/x86/efi/Makefile
+++ b/xen/arch/x86/efi/Makefile
@@ -1,18 +1,14 @@
 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)))
-
-extra-$(efi) += boot.init.o relocs-dummy.o runtime.o compat.o buildid.o
+efi := $(if $(efi),$(shell rm disabled)y)
 
 %.o: %.ihex
 	$(OBJCOPY) -I ihex -O binary $< $@
 
-stub.o: $(extra-y)
+obj-y := stub.o
+obj-$(efi) := boot.init.o compat.o relocs-dummy.o runtime.o
+extra-$(efi) += buildid.o
 nogcov-$(efi) += stub.o
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 7676de9..b0b1c9b 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -270,10 +270,10 @@ SECTIONS
   .pad : {
     . = ALIGN(MB(16));
   } :text
-#else
-  efi = .;
 #endif
 
+  efi = DEFINED(efi) ? efi : .;
+
   /* Sections to be discarded */
   /DISCARD/ : {
        *(.exit.text)
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 56544dc..1ef5d0b 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -1251,6 +1251,9 @@ void __init efi_init_memory(void)
     } *extra, *extra_head = NULL;
 #endif
 
+    if ( !efi_enabled(EFI_BOOT) )
+        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 8c44835..25323de 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -196,6 +196,9 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
 {
     unsigned int i, n;
 
+    if ( !efi_enabled(EFI_BOOT) )
+        return -ENOSYS;
+
     switch ( idx )
     {
     case XEN_FW_EFI_VERSION:
@@ -331,6 +334,12 @@ int efi_runtime_call(struct xenpf_efi_runtime_call *op)
     EFI_STATUS status = EFI_NOT_STARTED;
     int rc = 0;
 
+    if ( !efi_enabled(EFI_BOOT) )
+        return -ENOSYS;
+
+    if ( !efi_enabled(EFI_RS) )
+        return -EOPNOTSUPP;
+
     switch ( op->function )
     {
     case XEN_EFI_get_time:
-- 
1.7.10.4


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

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

* [PATCH v11 06/13] efi: create new early memory allocator
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (4 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 05/13] efi: build xen.gz with EFI code Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-06  8:27   ` Jan Beulich
  2016-12-09 18:03   ` Julien Grall
  2016-12-05 22:25 ` [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
                   ` (10 subsequent siblings)
  16 siblings, 2 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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 goes
down. Sadly this does not work when Xen is loaded using multiboot2
protocol because then the start lives on 1 MiB address and we should
not allocate a memory from below of it. So, I tried to use mem_lower
address calculated by GRUB2. However, this solution 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... :-(((
Hence, we need new memory allocator for Xen EFI boot code which is
quite simple and generic and could be used by place_string() and
efi_arch_allocate_mmap_buffer(). I think about following 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
   it in e820 memory map and map it in Xen virtual address space. This
   means that the code referring to Xen command line, loaded modules and
   EFI memory map, mostly in __start_xen(), will be further complicated
   and diverge from legacy BIOS cases. Additionally, both former things
   have to be placed below 4 GiB because their addresses are stored in
   multiboot_info_t structure which has 32-bit relevant members.

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 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 is 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 could put memory pool into .bss.page_aligned section. Then allocate
    memory chunks starting from the lowest address. After init phase we can
    free unused portion of the memory pool as in case of .init.text or .init.data
    sections. This way we do not need to allocate any space in image file and
    freeing of unused area in the memory pool is very simple.

Now #2a solution is implemented because it is quite simple and requires
limited number of changes, especially in __start_xen().

New allocator is quite generic and can be used on ARM platforms too.
Though it is not enabled on ARM yet due to lack of some prereq.
List of them is placed before ebmalloc code.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v11 - suggestions/fixes:
    - #ifdef only EBMALLOC_SIZE from ebmalloc machinery
      (suggested by Jan Beulich).

v10 - suggestions/fixes:
    - remove unneeded ARM free_ebmalloc_unused_mem() stub.

v9 - suggestions/fixes:
   - call free_ebmalloc_unused_mem() from efi_init_memory()
     instead of xen/arch/arm/setup.c:init_done()
     (suggested by Jan Beulich),
   - improve comments.

v8 - suggestions/fixes:
   - disable whole ebmalloc machinery on ARM platforms,
   - add comment saying what should be done before
     enabling ebmalloc on ARM,
     (suggested by Julien Grall),
   - move ebmalloc code before efi-boot.h inclusion and
     remove unneeded forward declaration
     (suggested by Jan Beulich),
   - remove free_ebmalloc_unused_mem() call from
     xen/arch/arm/setup.c:init_done()
     (suggested by Julien Grall),
   - improve commit message.

v7 - suggestions/fixes:
   - enable most of ebmalloc machinery on ARM platforms
     (suggested by Jan Beulich),
   - remove unneeded cast
     (suggested by Jan Beulich),
   - wrap long line
     (suggested by Jan Beulich),
   - improve commit message.

v6 - suggestions/fixes:
   - optimize ebmalloc allocator,
   - move ebmalloc machinery to xen/common/efi/boot.c
     (suggested by Jan Beulich),
   - enforce PAGE_SIZE ebmalloc_mem alignment
     (suggested by Jan Beulich),
   - ebmalloc() must allocate properly
     aligned memory regions
     (suggested by Jan Beulich),
   - printk() should use XENLOG_INFO
     (suggested by Jan Beulich).

v4 - suggestions/fixes:
   - move from #2 solution to #2a solution,
   - improve commit message.
---
 xen/arch/x86/efi/efi-boot.h |   11 +++-------
 xen/arch/x86/setup.c        |    3 +--
 xen/common/efi/boot.c       |   50 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 388c4ea..62c010e 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -114,7 +114,7 @@ static void __init relocate_trampoline(unsigned long phys)
 
 static void __init place_string(u32 *addr, const char *s)
 {
-    static char *__initdata alloc = start;
+    char *alloc = NULL;
 
     if ( s && *s )
     {
@@ -122,7 +122,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
@@ -205,12 +205,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 d473ac8..3a7d21e 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1124,8 +1124,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_LOADER) ? 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);
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 1ef5d0b..0a93e61 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -98,6 +98,54 @@ static CHAR16 __initdata newline[] = L"\r\n";
 #define PrintStr(s) StdOut->OutputString(StdOut, s)
 #define PrintErr(s) StdErr->OutputString(StdErr, s)
 
+#ifdef CONFIG_ARM
+/*
+ * TODO: Enable EFI boot allocator on ARM.
+ * This code can be common for x86 and ARM.
+ * Things TODO on ARM before enabling ebmalloc:
+ *   - estimate required EBMALLOC_SIZE value,
+ *   - where (in which section) ebmalloc_mem[] should live; if in
+ *     .bss.page_aligned, as it is right now, then whole BSS zeroing
+ *     have to be disabled in xen/arch/arm/arm64/head.S; though BSS
+ *     should be initialized somehow before use of variables living there,
+ *   - use ebmalloc() in ARM/common EFI boot code,
+ *   - call free_ebmalloc_unused_mem() somewhere in init code.
+ */
+#define EBMALLOC_SIZE	MB(0)
+#else
+#define EBMALLOC_SIZE	MB(1)
+#endif
+
+static char __section(".bss.page_aligned") __aligned(PAGE_SIZE)
+    ebmalloc_mem[EBMALLOC_SIZE];
+static unsigned long __initdata ebmalloc_allocated;
+
+/* EFI boot allocator. */
+static void __init __maybe_unused *ebmalloc(size_t size)
+{
+    void *ptr = ebmalloc_mem + ebmalloc_allocated;
+
+    ebmalloc_allocated += (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+
+    if ( ebmalloc_allocated > sizeof(ebmalloc_mem) )
+        blexit(L"Out of static memory\r\n");
+
+    return ptr;
+}
+
+static void __init __maybe_unused free_ebmalloc_unused_mem(void)
+{
+    unsigned long start, end;
+
+    start = (unsigned long)ebmalloc_mem + PAGE_ALIGN(ebmalloc_allocated);
+    end = (unsigned long)ebmalloc_mem + sizeof(ebmalloc_mem);
+
+    destroy_xen_mappings(start, end);
+    init_xenheap_pages(__pa(start), __pa(end));
+
+    printk(XENLOG_INFO "Freed %lukB unused BSS memory\n", (end - start) >> 10);
+}
+
 /*
  * Include architecture specific implementation here, which references the
  * static globals defined above.
@@ -1251,6 +1299,8 @@ void __init efi_init_memory(void)
     } *extra, *extra_head = NULL;
 #endif
 
+    free_ebmalloc_unused_mem();
+
     if ( !efi_enabled(EFI_BOOT) )
         return;
 
-- 
1.7.10.4


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

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

* [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (5 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 06/13] efi: create new early memory allocator Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-16 13:38   ` Andrew Cooper
  2017-01-10  1:37   ` Doug Goldstein
  2016-12-05 22:25 ` [PATCH v11 08/13] x86/boot: implement early command line parser in C Daniel Kiper
                   ` (9 subsequent siblings)
  16 siblings, 2 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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>
---
v10 - suggestions/fixes:
    - replace ljmpl with lretq
      (suggested by Andrew Cooper),
    - introduce efi_platform to increase code readability
      (suggested by Andrew Cooper).

v9 - suggestions/fixes:
   - use .L labels instead of numeric ones in multiboot2 data scanning loops
     (suggested by Jan Beulich).

v8 - suggestions/fixes:
   - use __bss_start(%rip)/__bss_end(%rip) instead of
     of .startof.(.bss)(%rip)/$.sizeof.(.bss) because
     latter is not tested extensively in different
     built environments yet
     (suggested by Andrew Cooper),
   - fix multiboot2 data scanning loop in x86_32 code
     (suggested by Jan Beulich),
   - add check for extra mem for mbi data if Xen is loaded
     via multiboot2 protocol on EFI platform
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich).

v7 - suggestions/fixes:
   - do not allocate twice memory for trampoline if we were
     loaded via multiboot2 protocol on EFI platform,
   - wrap long line
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich).

v6 - suggestions/fixes:
   - improve label names in assembly
     error printing code
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - various minor cleanups and fixes
     (suggested by Jan Beulich).

v4 - suggestions/fixes:
   - remove redundant BSS alignment,
   - update BSS alignment check,
   - use __set_bit() instead of set_bit() if possible
     (suggested by Jan Beulich),
   - call efi_arch_cpu() from efi_multiboot2()
     even if the same work is done later in
     other place right now
     (suggested by Jan Beulich),
   - xen/arch/x86/efi/stub.c:efi_multiboot2()
     fail properly on EFI platforms,
   - do not read data beyond the end of multiboot2
     information in xen/arch/x86/boot/head.S
     (suggested by Jan Beulich),
   - use 32-bit registers in x86_64 code if possible
     (suggested by Jan Beulich),
   - multiboot2 information address is 64-bit
     in x86_64 code, so, treat it is as is
     (suggested by Jan Beulich),
   - use cmovcc if possible,
   - leave only one space between rep and stosq
     (suggested by Jan Beulich),
   - improve error handling,
   - improve early error messages,
     (suggested by Jan Beulich),
   - improve early error messages printing code,
   - improve label names
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - various minor cleanups.

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

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          |  263 ++++++++++++++++++++++++++++++++++---
 xen/arch/x86/efi/efi-boot.h       |   54 +++++++-
 xen/arch/x86/efi/stub.c           |   38 ++++++
 xen/arch/x86/x86_64/asm-offsets.c |    2 +
 xen/arch/x86/xen.lds.S            |    4 +-
 xen/common/efi/boot.c             |   11 ++
 6 files changed, 349 insertions(+), 23 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index d423fd8..ac93df0 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)
 .Lmultiboot2_header_end:
@@ -100,20 +107,48 @@ multiboot2_header_start:
 gdt_boot_descr:
         .word   6*8-1
         .long   sym_phys(trampoline_gdt)
+        .long   0 /* Needed for 64-bit lgdt */
+
+        .align 4
+vga_text_buffer:
+        .long   0xb8000
+
+efi_platform:
+        .byte   0
 
 .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
 .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
+.Lbad_ldr_nbs: .asciz "ERR: Bootloader shutdown EFI x64 boot services!"
+.Lbad_ldr_nst: .asciz "ERR: EFI SystemTable is not provided by bootloader!"
+.Lbad_ldr_nih: .asciz "ERR: EFI ImageHandle is not provided by bootloader!"
+.Lbad_efi_msg: .asciz "ERR: EFI IA-32 platforms are not supported!"
 
         .section .init.text, "ax", @progbits
 
 bad_cpu:
         mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
-        jmp     print_err
+        jmp     .Lget_vtb
 not_multiboot:
         mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
-print_err:
-        mov     $0xB8000,%edi  # VGA framebuffer
-1:      mov     (%esi),%bl
+        jmp     .Lget_vtb
+.Lmb2_no_st:
+        mov     $(sym_phys(.Lbad_ldr_nst)),%esi # Error message
+        jmp     .Lget_vtb
+.Lmb2_no_ih:
+        mov     $(sym_phys(.Lbad_ldr_nih)),%esi # Error message
+        jmp     .Lget_vtb
+.Lmb2_no_bs:
+        mov     $(sym_phys(.Lbad_ldr_nbs)),%esi # Error message
+        xor     %edi,%edi                       # No VGA text buffer
+        jmp     .Lsend_chr
+.Lmb2_efi_ia_32:
+        mov     $(sym_phys(.Lbad_efi_msg)),%esi # Error message
+        xor     %edi,%edi                       # No VGA text buffer
+        jmp     .Lsend_chr
+.Lget_vtb:
+        mov     sym_phys(vga_text_buffer),%edi
+.Lsend_chr:
+        mov     (%esi),%bl
         test    %bl,%bl        # Terminate on '\0' sentinel
         je      .Lhalt
         mov     $0x3f8+5,%dx   # UART Line Status Register
@@ -123,13 +158,186 @@ print_err:
         mov     $0x3f8+0,%dx   # UART Transmit Holding Register
         mov     %bl,%al
         out     %al,%dx        # Send a character over the serial line
-        movsb                  # Write a character to the VGA framebuffer
+        test    %edi,%edi      # Is the VGA text buffer available?
+        jz      .Lsend_chr
+        movsb                  # Write a character to the VGA text buffer
         mov     $7,%al
-        stosb                  # Write an attribute to the VGA framebuffer
-        jmp     1b
+        stosb                  # Write an attribute to the VGA text buffer
+        jmp     .Lsend_chr
 .Lhalt: hlt
         jmp     .Lhalt
 
+        .code64
+
+__efi64_start:
+        cld
+
+        /* VGA is not available on EFI platforms. */
+        movl   $0,vga_text_buffer(%rip)
+
+        /* Check for Multiboot2 bootloader. */
+        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+        je      .Lefi_multiboot2_proto
+
+        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
+        lea     not_multiboot(%rip),%edi
+        jmp     x86_32_switch
+
+.Lefi_multiboot2_proto:
+        /* Zero EFI SystemTable and EFI ImageHandle addresses. */
+        xor     %esi,%esi
+        xor     %edi,%edi
+
+        /* Skip Multiboot2 information fixed part. */
+        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
+
+.Lefi_mb2_tsize:
+        /* Check Multiboot2 information total size. */
+        mov     %ecx,%r8d
+        sub     %ebx,%r8d
+        cmp     %r8d,MB2_fixed_total_size(%rbx)
+        jbe     run_bs
+
+        /* Are EFI boot services available? */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI_BS,MB2_tag_type(%rcx)
+        jne     .Lefi_mb2_st
+
+        /* We are on EFI platform and EFI boot services are available. */
+        incb    efi_platform(%rip)
+
+        /*
+         * Disable real mode and other legacy stuff which should not
+         * be run on EFI platforms.
+         */
+        incb    skip_realmode(%rip)
+        jmp     .Lefi_mb2_next_tag
+
+.Lefi_mb2_st:
+        /* Get EFI SystemTable address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
+        cmove   MB2_efi64_st(%rcx),%rsi
+        je      .Lefi_mb2_next_tag
+
+        /* Get EFI ImageHandle address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
+        cmove   MB2_efi64_ih(%rcx),%rdi
+        je      .Lefi_mb2_next_tag
+
+        /* Is it the end of Multiboot2 information? */
+        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
+        je      run_bs
+
+.Lefi_mb2_next_tag:
+        /* Go to next Multiboot2 information tag. */
+        add     MB2_tag_size(%rcx),%ecx
+        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
+        jmp     .Lefi_mb2_tsize
+
+run_bs:
+        /* Are EFI boot services available? */
+        cmpb    $0,efi_platform(%rip)
+        jnz     0f
+
+        /* Jump to .Lmb2_no_bs after switching CPU to x86_32 mode. */
+        lea     .Lmb2_no_bs(%rip),%edi
+        jmp     x86_32_switch
+
+0:
+        /* Is EFI SystemTable address provided by boot loader? */
+        test    %rsi,%rsi
+        jnz     1f
+
+        /* Jump to .Lmb2_no_st after switching CPU to x86_32 mode. */
+        lea     .Lmb2_no_st(%rip),%edi
+        jmp     x86_32_switch
+
+1:
+        /* Is EFI ImageHandle address provided by boot loader? */
+        test    %rdi,%rdi
+        jnz     2f
+
+        /* Jump to .Lmb2_no_ih after switching CPU to x86_32 mode. */
+        lea     .Lmb2_no_ih(%rip),%edi
+        jmp     x86_32_switch
+
+2:
+        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),%edi
+        lea     __bss_end(%rip),%ecx
+        sub     %edi,%ecx
+        shr     $3,%ecx
+        xor     %eax,%eax
+        rep stosq
+
+        pop     %rdi
+
+        /*
+         * efi_multiboot2() is called according to System V AMD64 ABI:
+         *   - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable,
+         *   - OUT: %rax - highest usable memory address below 1 MiB;
+         *                 memory above this address is reserved for trampoline;
+         *                 memory below this address is used as a storage for
+         *                 mbi struct created in reloc().
+         *
+         * 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,%eax
+        mov     %eax,%ecx
+
+        pop     %rax
+
+        /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
+        lea     trampoline_setup(%rip),%edi
+
+x86_32_switch:
+        cli
+
+        /* Initialize GDTR. */
+        lgdt    gdt_boot_descr(%rip)
+
+        /* Reload code selector. */
+        pushq   $BOOT_CS32
+        lea     cs32_switch(%rip),%edx
+        push    %rdx
+        lretq
+
+        .code32
+
+cs32_switch:
+        /* Initialize basic data segments. */
+        mov     $BOOT_DS,%edx
+        mov     %edx,%ds
+        mov     %edx,%es
+        mov     %edx,%ss
+        /* %esp is initialized 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 +365,7 @@ __start:
 
         /* Not available? BDA value will be fine. */
         cmovnz  MB_mem_lower(%ebx),%edx
-        jmp     trampoline_setup
+        jmp     trampoline_bios_setup
 
 .Lmultiboot2_proto:
         /* Skip Multiboot2 information fixed part. */
@@ -169,24 +377,33 @@ __start:
         mov     %ecx,%edi
         sub     %ebx,%edi
         cmp     %edi,MB2_fixed_total_size(%ebx)
-        jbe     trampoline_setup
+        jbe     trampoline_bios_setup
 
         /* Get mem_lower from Multiboot2 information. */
         cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
         cmove   MB2_mem_lower(%ecx),%edx
-        je      trampoline_setup
+        je      .Lmb2_next_tag
+
+        /* EFI IA-32 platforms are not supported. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
+        je      .Lmb2_efi_ia_32
+
+        /* Bootloader shutdown EFI x64 boot services. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%ecx)
+        je      .Lmb2_no_bs
 
         /* Is it the end of Multiboot2 information? */
         cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
-        je      trampoline_setup
+        je      trampoline_bios_setup
 
+.Lmb2_next_tag:
         /* 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     .Lmb2_tsize
 
-trampoline_setup:
+trampoline_bios_setup:
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
@@ -202,16 +419,19 @@ 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 */
+        /* Reserve 64kb for the trampoline. */
         sub     $0x1000,%ecx
 
         /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
         xor     %cl, %cl
+
+trampoline_setup:
+        /* Save trampoline address for later use. */
         shl     $4, %ecx
         mov     %ecx,sym_phys(trampoline_phys)
 
@@ -223,7 +443,14 @@ trampoline_setup:
         call    reloc
         mov     %eax,sym_phys(multiboot_ptr)
 
-        /* Initialize BSS (no nasty surprises!) */
+        /*
+         * Do not zero BSS on EFI platform here.
+         * It was initialized earlier.
+         */
+        cmpb    $0,sym_phys(efi_platform)
+        jnz     1f
+
+        /* Initialize BSS (no nasty surprises!). */
         mov     $sym_phys(__bss_start),%edi
         mov     $sym_phys(__bss_end),%ecx
         sub     %edi,%ecx
@@ -231,6 +458,7 @@ trampoline_setup:
         shr     $2,%ecx
         rep stosl
 
+1:
         /* Interrogate CPU extended features via CPUID. */
         mov     $0x80000000,%eax
         cpuid
@@ -282,8 +510,13 @@ trampoline_setup:
         cmp     $sym_phys(__trampoline_seg_stop),%edi
         jb      1b
 
+        /* Do not parse command line on EFI platform here. */
+        cmpb    $0,sym_phys(efi_platform)
+        jnz     1f
+
         call    cmdline_parse_early
 
+1:
         /* Switch to low-memory stack.  */
         mov     sym_phys(trampoline_phys),%edi
         lea     0x10000(%edi),%esp
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 62c010e..dc857d8 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
 {
     struct e820entry *e;
     unsigned int i;
+    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
+    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
 
     /* Populate E820 table and check trampoline area availability. */
     e = e820map - 1;
@@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             /* fall through */
         case EfiConventionalMemory:
             if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
-                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
+                 len >= cfg.size + extra_mem &&
+                 desc->PhysicalStart + len > cfg.addr )
                 cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
             /* fall through */
         case EfiLoaderCode:
@@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
 
 static void __init efi_arch_pre_exit_boot(void)
 {
-    if ( !trampoline_phys )
-    {
-        if ( !cfg.addr )
-            blexit(L"No memory for trampoline");
+    if ( trampoline_phys )
+        return;
+
+    if ( !cfg.addr )
+        blexit(L"No memory for trampoline");
+
+    if ( efi_enabled(EFI_LOADER) )
         relocate_trampoline(cfg.addr);
-    }
 }
 
 static void __init noreturn efi_arch_post_exit_boot(void)
@@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
+    __set_bit(EFI_RS, &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();
+
+    efi_tables();
+    setup_efi_pci();
+    efi_variables();
+
+    if ( gop )
+        efi_set_gop_mode(gop, gop_mode);
+
+    efi_exit_boot(ImageHandle, SystemTable);
+
+    /* Return highest usable 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 4158124..6ea6aa1 100644
--- a/xen/arch/x86/efi/stub.c
+++ b/xen/arch/x86/efi/stub.c
@@ -3,6 +3,44 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <asm/page.h>
+#include <asm/efibind.h>
+#include <efi/efidef.h>
+#include <efi/eficapsule.h>
+#include <efi/eficon.h>
+#include <efi/efidevp.h>
+#include <efi/efiapi.h>
+
+/*
+ * Here we are in EFI stub. EFI calls are not supported due to lack
+ * of relevant functionality in compiler and/or linker.
+ *
+ * efi_multiboot2() is an exception. Please look below for more details.
+ */
+
+paddr_t __init noreturn efi_multiboot2(EFI_HANDLE ImageHandle,
+                                       EFI_SYSTEM_TABLE *SystemTable)
+{
+    CHAR16 *err = L"Xen does not have EFI code build in!!!\r\nSystem halted!!!\r\n";
+    SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
+
+    StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
+
+    /*
+     * Print error message and halt the system.
+     *
+     * We have to open code MS x64 calling convention
+     * in assembly because here this convention may
+     * not be directly supported by C compiler.
+     */
+    asm volatile(
+    "    call %2                      \n"
+    "0:  hlt                          \n"
+    "    jmp  0b                      \n"
+       : "+c" (StdErr), "+d" (err) : "g" (StdErr->OutputString)
+       : "rax", "r8", "r9", "r10", "r11", "memory");
+
+    unreachable();
+}
 
 bool efi_enabled(unsigned int feature)
 {
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index b437a8f..2a22659 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -175,6 +175,8 @@ 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);
     BLANK();
 
     OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index b0b1c9b..e0e2529 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -331,5 +331,5 @@ ASSERT(IS_ALIGNED(__init_end,   PAGE_SIZE), "__init_end misaligned")
 
 ASSERT(IS_ALIGNED(trampoline_start, 4), "trampoline_start misaligned")
 ASSERT(IS_ALIGNED(trampoline_end,   4), "trampoline_end misaligned")
-ASSERT(IS_ALIGNED(__bss_start,      4), "__bss_start misaligned")
-ASSERT(IS_ALIGNED(__bss_end,        4), "__bss_end misaligned")
+ASSERT(IS_ALIGNED(__bss_start,      8), "__bss_start misaligned")
+ASSERT(IS_ALIGNED(__bss_end,        8), "__bss_end misaligned")
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index 0a93e61..70ed836 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;
-- 
1.7.10.4


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

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

* [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (6 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-07 13:43   ` Jan Beulich
  2016-12-05 22:25 ` [PATCH v11 09/13] x86: change default load address from 1 MiB to 2 MiB Daniel Kiper
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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.

Additionally, put all common cmdline.c and reloc.c definitions
into defs.h header. This way we do not duplicate needlessly
some stuff.

And finally remove unused xen/include/asm-x86/config.h
header from reloc.c dependencies.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v7 - suggestions/fixes:
   - add min() macro
     (suggested by Jan Beulich),
   - add padding to early_boot_opts_t
     in more standard way
     (suggested by Jan Beulich),
   - simplify defs.h dependencies
     (suggested by Jan Beulich).

v6 - suggestions/fixes:
   - put common cmdline.c and reloc.c
     definitions into defs.h header
     (suggested by Jan Beulich),
   - use xen/include/xen/stdbool.h
     and bool type from it instead
     of own defined bool_t
     (suggested by Jan Beulich),
   - define delim_chars as constant
     (suggested by Jan Beulich),
   - properly align trampoline.S:early_boot_opts struct
     (suggested by Jan Beulich),
   - fix overflow check in strtoui()
     (suggested by Jan Beulich),
   - remove unused xen/include/asm-x86/config.h
     header from reloc.c dependencies,
   - improve commit message.

v4 - suggestions/fixes:
   - move to stdcall calling convention
     (suggested by Jan Beulich),
   - define bool_t and use it properly
     (suggested by Jan Beulich),
   - put list of delimiter chars into
     static const char[]
     (suggested by Jan Beulich),
   - use strlen() instead of strlen_opt()
     (suggested by Jan Beulich),
   - change strtoi() to strtoui() and
     optimize it a bit
     (suggested by Jan Beulich),
   - define strchr() and use it in strtoui()
     (suggested by Jan Beulich),
   - optimize vga_parse()
     (suggested by Jan Beulich),
   - move !cmdline check from assembly to C
     (suggested by Jan Beulich),
   - remove my name from copyright (Oracle requirement)
     (suggested by Konrad Rzeszutek Wilk).

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     |   11 +-
 xen/arch/x86/boot/build32.mk   |    2 +
 xen/arch/x86/boot/cmdline.S    |  367 ----------------------------------------
 xen/arch/x86/boot/cmdline.c    |  340 +++++++++++++++++++++++++++++++++++++
 xen/arch/x86/boot/defs.h       |   58 +++++++
 xen/arch/x86/boot/edd.S        |    3 -
 xen/arch/x86/boot/head.S       |    8 +
 xen/arch/x86/boot/reloc.c      |   13 +-
 xen/arch/x86/boot/trampoline.S |   15 ++
 xen/arch/x86/boot/video.S      |    7 -
 12 files changed, 437 insertions(+), 394 deletions(-)
 delete mode 100644 xen/arch/x86/boot/cmdline.S
 create mode 100644 xen/arch/x86/boot/cmdline.c
 create mode 100644 xen/arch/x86/boot/defs.h

diff --git a/.gitignore b/.gitignore
index a2f34a1..d2967d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -250,9 +250,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 2a0781a..e74fe62 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -220,5 +220,5 @@ 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/*.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
 	rm -f note.o
diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile
index 06893d8..c6246c8 100644
--- a/xen/arch/x86/boot/Makefile
+++ b/xen/arch/x86/boot/Makefile
@@ -1,9 +1,16 @@
 obj-bin-y += head.o
 
-RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \
+DEFS_H_DEPS = defs.h $(BASEDIR)/include/xen/stdbool.h
+
+CMDLINE_DEPS = $(DEFS_H_DEPS) video.h
+
+RELOC_DEPS = $(DEFS_H_DEPS) $(BASEDIR)/include/xen/multiboot.h \
 	     $(BASEDIR)/include/xen/multiboot2.h
 
-head.o: reloc.S
+head.o: cmdline.S reloc.S
+
+cmdline.S: cmdline.c $(CMDLINE_DEPS)
+	$(MAKE) -f build32.mk $@ CMDLINE_DEPS="$(CMDLINE_DEPS)"
 
 reloc.S: reloc.c $(RELOC_DEPS)
 	$(MAKE) -f build32.mk $@ RELOC_DEPS="$(RELOC_DEPS)"
diff --git a/xen/arch/x86/boot/build32.mk b/xen/arch/x86/boot/build32.mk
index 39e6453..3d01698 100644
--- a/xen/arch/x86/boot/build32.mk
+++ b/xen/arch/x86/boot/build32.mk
@@ -32,6 +32,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..06aa064
--- /dev/null
+++ b/xen/arch/x86/boot/cmdline.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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(), strchr(), strspn() and strcspn() were copied from
+ * Linux kernel source (linux/lib/string.c).
+ */
+
+/*
+ * 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 "defs.h"
+#include "video.h"
+
+/* Keep in sync with trampoline.S:early_boot_opts label! */
+typedef struct __packed {
+    u8 skip_realmode;
+    u8 opt_edd;
+    u8 opt_edid;
+    u8 padding;
+    u16 boot_vid_mode;
+    u16 vesa_width;
+    u16 vesa_height;
+    u16 vesa_depth;
+} early_boot_opts_t;
+
+/*
+ * Space and TAB are obvious delimiters. However, I am
+ * adding "\n" and "\r" here too. Just in case when
+ * crazy bootloader/user puts them somewhere.
+ */
+static const char delim_chars_comma[] = ", \n\r\t";
+
+#define delim_chars	(delim_chars_comma + 1)
+
+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 char *strchr(const char *s, int c)
+{
+    for ( ; *s != (char)c; ++s )
+        if ( *s == '\0' )
+            return NULL;
+    return (char *)s;
+}
+
+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 unsigned int strtoui(const char *s, const char *stop, const char **next)
+{
+    char base = 10, l;
+    unsigned long long res = 0;
+
+    if ( *s == '0' )
+      base = (tolower(*++s) == 'x') ? (++s, 16) : 8;
+
+    for ( ; *s != '\0'; ++s )
+    {
+        if ( stop && strchr(stop, *s) )
+            goto out;
+
+        if ( *s < '0' || (*s > '7' && base == 8) )
+        {
+            res = UINT_MAX;
+            goto out;
+        }
+
+        l = tolower(*s);
+
+        if ( *s > '9' && (base != 16 || l < 'a' || l > 'f') )
+        {
+            res = UINT_MAX;
+            goto out;
+        }
+
+        res *= base;
+        res += (l >= 'a') ? (l - 'a' + 10) : (*s - '0');
+
+        if ( res >= UINT_MAX )
+        {
+            res = UINT_MAX;
+            goto out;
+        }
+    }
+
+ 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, bool 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 bool skip_realmode(const char *cmdline)
+{
+    return find_opt(cmdline, "no-real-mode", false) || find_opt(cmdline, "tboot=", true);
+}
+
+static u8 edd_parse(const char *cmdline)
+{
+    const char *c;
+
+    c = find_opt(cmdline, "edd=", true);
+
+    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=", true);
+
+    if ( !c )
+        return 0;
+
+    if ( !strmaxcmp(c, "force", delim_chars) )
+        return 2;
+
+    return !strmaxcmp(c, "no", delim_chars);
+}
+
+static u16 rows2vmode(unsigned 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;
+    unsigned int tmp, vesa_depth, vesa_height, vesa_width;
+
+    c = find_opt(cmdline, "vga=", true);
+
+    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("text-80x");
+        ebo->boot_vid_mode = rows2vmode(strtoui(c, delim_chars_comma, NULL));
+    }
+    else if ( !strsubcmp(c, "gfx-") )
+    {
+        vesa_width = strtoui(c + strlen("gfx-"), "x", &c);
+
+        if ( vesa_width > U16_MAX )
+            return;
+
+        /*
+         * Increment c outside of strtoui() because otherwise some
+         * compiler may complain with following message:
+         * warning: operation on 'c' may be undefined.
+         */
+        ++c;
+        vesa_height = strtoui(c, "x", &c);
+
+        if ( vesa_height > U16_MAX )
+            return;
+
+        vesa_depth = strtoui(++c, delim_chars_comma, NULL);
+
+        if ( vesa_depth > U16_MAX )
+            return;
+
+        ebo->vesa_width = vesa_width;
+        ebo->vesa_height = vesa_height;
+        ebo->vesa_depth = vesa_depth;
+        ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE;
+    }
+    else if ( !strsubcmp(c, "mode-") )
+    {
+        tmp = strtoui(c + strlen("mode-"), delim_chars_comma, NULL);
+
+        if ( tmp > U16_MAX )
+            return;
+
+        ebo->boot_vid_mode = tmp;
+    }
+}
+
+void __stdcall cmdline_parse_early(const char *cmdline, early_boot_opts_t *ebo)
+{
+    if ( !cmdline )
+        return;
+
+    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/defs.h b/xen/arch/x86/boot/defs.h
new file mode 100644
index 0000000..6abdc15
--- /dev/null
+++ b/xen/arch/x86/boot/defs.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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/>.
+ *
+ * max() was copied from xen/xen/include/xen/kernel.h.
+ */
+
+#ifndef __BOOT_DEFS_H__
+#define __BOOT_DEFS_H__
+
+#include "../../../include/xen/stdbool.h"
+
+#define __packed	__attribute__((__packed__))
+#define __stdcall	__attribute__((__stdcall__))
+
+#define NULL		((void *)0)
+
+#define ALIGN_UP(arg, align) \
+                (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))
+
+#define min(x,y) ({ \
+        const typeof(x) _x = (x);       \
+        const typeof(y) _y = (y);       \
+        (void) (&_x == &_y);            \
+        _x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+        const typeof(x) _x = (x);       \
+        const typeof(y) _y = (y);       \
+        (void) (&_x == &_y);            \
+        _x > _y ? _x : _y; })
+
+#define _p(val)		((void *)(unsigned long)(val))
+
+#define tolower(c)	((c) | 0x20)
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef unsigned int size_t;
+
+#define U16_MAX		((u16)(~0U))
+#define UINT_MAX	(~0U)
+
+#endif /* __BOOT_DEFS_H__ */
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 ac93df0..6c97e1f 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -514,6 +514,13 @@ trampoline_setup:
         cmpb    $0,sym_phys(efi_platform)
         jnz     1f
 
+        /* Bail if there is no command line to parse. */
+        mov     sym_phys(multiboot_ptr),%ebx
+        testl   $MBI_CMDLINE,MB_flags(%ebx)
+        jz      1f
+
+        pushl   $sym_phys(early_boot_opts)
+        pushl   MB_cmdline(%ebx)
         call    cmdline_parse_early
 
 1:
@@ -532,6 +539,7 @@ trampoline_setup:
         /* Jump into the relocated trampoline. */
         lret
 
+cmdline_parse_early:
 #include "cmdline.S"
 
 reloc:
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index b22bf1e..0f2e372 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -25,21 +25,10 @@ asm (
     "    jmp  reloc                    \n"
     );
 
-typedef unsigned int u32;
-typedef unsigned long long u64;
-
+#include "defs.h"
 #include "../../../include/xen/multiboot.h"
 #include "../../../include/xen/multiboot2.h"
 
-#define NULL		((void *)0)
-
-#define __stdcall	__attribute__((__stdcall__))
-
-#define ALIGN_UP(arg, align) \
-                (((arg) + (align) - 1) & ~((typeof(arg))(align) - 1))
-
-#define _p(val)		((void *)(unsigned long)(val))
-
 #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))
 
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index b013614..2715d17 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -220,8 +220,23 @@ trampoline_boot_cpu_entry:
         /* Jump to the common bootstrap entry point. */
         jmp     trampoline_protmode_entry
 
+#include "video.h"
+
+        .align  2
+/* 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). */
+/* Padding. */
+        .byte   0
+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 2aafbeb..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,12 +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. */
-        .align  2
-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
https://lists.xen.org/xen-devel

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

* [PATCH v11 09/13] x86: change default load address from 1 MiB to 2 MiB
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (7 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 08/13] x86/boot: implement early command line parser in C Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 10/13] x86/setup: use XEN_IMG_OFFSET instead of Daniel Kiper
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

Subsequent patches introducing relocatable early boot code play with
page tables using 2 MiB huge pages. If load address is not aligned at
2 MiB then code touching such page tables must have special cases for
start and end of Xen image memory region. So, let's make life easier
and move default load address from 1 MiB to 2 MiB. This way page table
code will be nice and easy. Hence, there is a chance that it will be
less error prone too... :-)))

Additionally, drop first 2 MiB mapping from Xen image mapping.
It is no longer needed.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
v8 - suggestions/fixes:
   - drop first 2 MiB mapping from Xen image mapping
     (suggested by Jan Beulich),
   - improve commit message.

v7 - suggestions/fixes:
   - minor cleanups
     (suggested by Jan Beulich).
---
 xen/arch/x86/Makefile      |    2 +-
 xen/arch/x86/Rules.mk      |    3 +++
 xen/arch/x86/boot/head.S   |    8 --------
 xen/arch/x86/boot/x86_64.S |    5 +++--
 xen/arch/x86/setup.c       |    3 ++-
 xen/arch/x86/xen.lds.S     |    2 +-
 6 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index e74fe62..d5d0651 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -90,7 +90,7 @@ all_symbols =
 endif
 
 $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32
-	./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) 0x100000 \
+	./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) $(XEN_IMG_OFFSET) \
 	               `$(NM) $(TARGET)-syms | sed -ne 's/^\([^ ]*\) . __2M_rwdata_end$$/0x\1/p'`
 
 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 42be4bc..36e6386 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -1,9 +1,12 @@
 ########################################
 # x86-specific definitions
 
+XEN_IMG_OFFSET := 0x200000
+
 CFLAGS += -I$(BASEDIR)/include
 CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
 CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
+CFLAGS += -DXEN_IMG_OFFSET=$(XEN_IMG_OFFSET)
 CFLAGS += '-D__OBJECT_LABEL__=$(subst /,$$,$(subst -,_,$(subst $(BASEDIR)/,,$(CURDIR))/$@))'
 
 # Prevent floating-point variables from creeping into Xen.
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 6c97e1f..a7bc467 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -482,14 +482,6 @@ trampoline_setup:
         mov     %eax,sym_phys(boot_tsc_stamp)
         mov     %edx,sym_phys(boot_tsc_stamp+4)
 
-        /*
-         * 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)
-
         /* Apply relocations to bootstrap trampoline. */
         mov     sym_phys(trampoline_phys),%edx
         mov     $sym_phys(__trampoline_rel_start),%edi
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 139b2ca..7890374 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -121,8 +121,9 @@ GLOBAL(l2_identmap)
  * page.
  */
 GLOBAL(l2_xenmap)
-        idx = 0
-        .rept 8
+        .quad 0
+        idx = 1
+        .rept 7
         .quad sym_phys(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
         idx = idx + 1
         .endr
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 3a7d21e..fa808ef 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -999,7 +999,8 @@ 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.
              */
-            BUG_ON(l2_table_offset((unsigned long)_erodata) ==
+            BUG_ON(using_2M_mapping() &&
+                   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);
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index e0e2529..45251fd 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -55,7 +55,7 @@ SECTIONS
   __2M_text_start = .;         /* Start of 2M superpages, mapped RX. */
 #endif
 
-  . = __XEN_VIRT_START + MB(1);
+  . = __XEN_VIRT_START + XEN_IMG_OFFSET;
   _start = .;
   .text : {
         _stext = .;            /* Text and read-only data */
-- 
1.7.10.4


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

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

* [PATCH v11 10/13] x86/setup: use XEN_IMG_OFFSET instead of...
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (8 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 09/13] x86: change default load address from 1 MiB to 2 MiB Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 11/13] x86: make Xen early boot code relocatable Daniel Kiper
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

..calculating its value during runtime.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/setup.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index fa808ef..5d0830e 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -943,7 +943,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
             l4_pgentry_t *pl4e;
             l3_pgentry_t *pl3e;
             l2_pgentry_t *pl2e;
-            uint64_t load_start;
             int i, j, k;
 
             /* Select relocation address. */
@@ -957,9 +956,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
              * with a barrier(). After this we must *not* modify static/global
              * data until after we have switched to the relocated pagetables!
              */
-            load_start = (unsigned long)_start - XEN_VIRT_START;
             barrier();
-            move_memory(e + load_start, load_start, _end - _start, 1);
+            move_memory(e + XEN_IMG_OFFSET, XEN_IMG_OFFSET, _end - _start, 1);
 
             /* Walk initial pagetables, relocating page directory entries. */
             pl4e = __va(__pa(idle_pg_table));
-- 
1.7.10.4


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

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

* [PATCH v11 11/13] x86: make Xen early boot code relocatable
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (9 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 10/13] x86/setup: use XEN_IMG_OFFSET instead of Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2017-01-10  2:05   ` Doug Goldstein
  2016-12-05 22:25 ` [PATCH v11 12/13] x86/boot: rename sym_phys() to sym_offs() Daniel Kiper
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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 2 MiB and ends at ~5 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 and help boot loader to
relocate image in proper way by suggesting, not requesting specific load
addresses as it is right now, allowed address ranges. This patch does former.
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:
  - %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 in 32-bit code
    and %r15d in 64-bit code),
  - %fs is used as base for Xen data relative addressing in 32-bit code
    if it is possible; %esi is used for that thing during error printing
    because it is not always possible to properly and efficiently
    initialize %fs.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v8 - suggestions/fixes:
   - use shld instead of mov and shr in BOOT_FS segment
     descriptor base address initialization
     (suggested by Jan Beulich),
   - simplify code updating frame addresses in page tables
     (suggested by Jan Beulich),
   - print Xen image base addresses using "%#lx" format
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich).

v6 - suggestions/fixes:
   - leave static mapping of first
     16 MiB in l2_identmap as is
     (suggested by Jan Beulich),
   - use xen_phys_start instead of xen_img_load_base_addr
     (suggested by Daniel Kiper and Jan Beulich),
   - simplify BOOT_FS segment descriptor
     base address initialization
     (suggested by Jan Beulich),
   - fix BOOT_FS segment limit
     (suggested by Jan Beulich),
   - do not rename sym_phys in this patch
     (suggested by Jan Beulich),
   - rename esi_offset/fs_offset to
     sym_esi/sym_fs respectively
     (suggested by Jan Beulich),
   - use add instead of lea in assembly
     error printing code
     (suggested by Jan Beulich),
   - improve comments
     (suggested by Jan Beulich),
   - improve commit message
     (suggested by Jan Beulich),
   - various minor cleanups and fixes
     (suggested by Jan Beulich).

v4 - suggestions/fixes:
   - do not relocate Xen image if boot loader did work for us
     (suggested by Andrew Cooper and Jan Beulich),
   - initialize xen_img_load_base_addr in EFI boot code too,
   - properly initialize trampoline_xen_phys_start,
   - calculate Xen image load base address in
     x86_64 code ourselves,
     (suggested by Jan Beulich),
   - change how and when Xen image base address is printed,
   - use %fs instead of %esi for relative addressing
     (suggested by Andrew Cooper and Jan Beulich),
   - create esi_offset and fs_offset() macros in assembly,
   - calculate <final-exec-addr> mkelf32 argument automatically,
   - optimize and cleanup code,
   - improve comments,
   - improve commit message.

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).
---
 xen/arch/x86/boot/head.S          |  160 +++++++++++++++++++++++++++++--------
 xen/arch/x86/boot/trampoline.S    |    5 ++
 xen/arch/x86/boot/x86_64.S        |   21 +++--
 xen/arch/x86/setup.c              |   14 ++--
 xen/arch/x86/x86_64/asm-offsets.c |    3 +
 xen/include/asm-x86/page.h        |    2 +-
 6 files changed, 155 insertions(+), 50 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index a7bc467..d992a95 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -13,12 +13,15 @@
         .code32
 
 #define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
+#define sym_esi(sym)      sym_phys(sym)(%esi)
+#define sym_fs(sym)       %fs:sym_phys(sym)
 
 #define BOOT_CS32        0x0008
 #define BOOT_CS64        0x0010
 #define BOOT_DS          0x0018
 #define BOOT_PSEUDORM_CS 0x0020
 #define BOOT_PSEUDORM_DS 0x0028
+#define BOOT_FS          0x0030
 
 #define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
 #define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
@@ -105,7 +108,8 @@ multiboot2_header_start:
 
         .word   0
 gdt_boot_descr:
-        .word   6*8-1
+        .word   7*8-1
+gdt_boot_base:
         .long   sym_phys(trampoline_gdt)
         .long   0 /* Needed for 64-bit lgdt */
 
@@ -126,27 +130,27 @@ efi_platform:
         .section .init.text, "ax", @progbits
 
 bad_cpu:
-        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
+        add     $sym_phys(.Lbad_cpu_msg),%esi   # Error message
         jmp     .Lget_vtb
 not_multiboot:
-        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
+        add     $sym_phys(.Lbad_ldr_msg),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_st:
-        mov     $(sym_phys(.Lbad_ldr_nst)),%esi # Error message
+        add     $sym_phys(.Lbad_ldr_nst),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_ih:
-        mov     $(sym_phys(.Lbad_ldr_nih)),%esi # Error message
+        add     $sym_phys(.Lbad_ldr_nih),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_bs:
-        mov     $(sym_phys(.Lbad_ldr_nbs)),%esi # Error message
+        add     $sym_phys(.Lbad_ldr_nbs),%esi   # Error message
         xor     %edi,%edi                       # No VGA text buffer
         jmp     .Lsend_chr
 .Lmb2_efi_ia_32:
-        mov     $(sym_phys(.Lbad_efi_msg)),%esi # Error message
+        add     $sym_phys(.Lbad_efi_msg),%esi   # Error message
         xor     %edi,%edi                       # No VGA text buffer
         jmp     .Lsend_chr
 .Lget_vtb:
-        mov     sym_phys(vga_text_buffer),%edi
+        mov     sym_esi(vga_text_buffer),%edi
 .Lsend_chr:
         mov     (%esi),%bl
         test    %bl,%bl        # Terminate on '\0' sentinel
@@ -175,6 +179,9 @@ __efi64_start:
         /* VGA is not available on EFI platforms. */
         movl   $0,vga_text_buffer(%rip)
 
+        /* Load Xen image load base address. */
+        lea     __image_base__(%rip),%r15d
+
         /* Check for Multiboot2 bootloader. */
         cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
         je      .Lefi_multiboot2_proto
@@ -300,6 +307,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),%edi
 
@@ -307,6 +317,7 @@ x86_32_switch:
         cli
 
         /* Initialize GDTR. */
+        add     %esi,gdt_boot_base(%rip)
         lgdt    gdt_boot_descr(%rip)
 
         /* Reload code selector. */
@@ -342,12 +353,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_phys(__image_base__),%esi
 
         /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
         xor     %edx,%edx
@@ -404,6 +411,25 @@ __start:
         jmp     .Lmb2_tsize
 
 trampoline_bios_setup:
+        /*
+         * Called on legacy BIOS platforms only.
+         *
+         * Initialize GDTR and basic data segments.
+         */
+        add     %esi,sym_esi(gdt_boot_base)
+        lgdt    sym_esi(gdt_boot_descr)
+
+        mov     $BOOT_DS,%ecx
+        mov     %ecx,%ds
+        mov     %ecx,%es
+        mov     %ecx,%ss
+        /* %esp is initialized 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) */
@@ -431,32 +457,64 @@ trampoline_bios_setup:
         xor     %cl, %cl
 
 trampoline_setup:
+        /*
+         * Called on legacy BIOS and EFI platforms.
+         *
+         * Initialize 0-15 bits of BOOT_FS segment descriptor base address.
+         */
+        mov     %si,BOOT_FS+2+sym_esi(trampoline_gdt)
+
+        /* Initialize 16-23 bits of BOOT_FS segment descriptor base address. */
+        shld    $16,%esi,%edx
+        mov     %dl,BOOT_FS+4+sym_esi(trampoline_gdt)
+
+        /* Initialize 24-31 bits of BOOT_FS segment descriptor base address. */
+        mov     %dh,BOOT_FS+7+sym_esi(trampoline_gdt)
+
+        /*
+         * Initialize %fs and later use it to access Xen data if possible.
+         * According to Intel 64 and IA-32 Architectures Software Developer's
+         * Manual it is safe to do that without reloading GDTR before.
+         */
+        mov     $BOOT_FS,%edx
+        mov     %edx,%fs
+
         /* Save trampoline address for later use. */
         shl     $4, %ecx
-        mov     %ecx,sym_phys(trampoline_phys)
+        mov     %ecx,sym_fs(trampoline_phys)
+
+        /* Save Xen image load base address for later use. */
+        mov     %esi,sym_fs(xen_phys_start)
+        mov     %esi,sym_fs(trampoline_xen_phys_start)
+
+        /* Setup stack. %ss was initialized earlier. */
+        lea     1024+sym_esi(cpu0_stack),%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
-        mov     %eax,sym_phys(multiboot_ptr)
+        mov     %eax,sym_fs(multiboot_ptr)
 
         /*
          * Do not zero BSS on EFI platform here.
          * It was initialized earlier.
          */
-        cmpb    $0,sym_phys(efi_platform)
+        cmpb    $0,sym_fs(efi_platform)
         jnz     1f
 
         /* Initialize BSS (no nasty surprises!). */
         mov     $sym_phys(__bss_start),%edi
         mov     $sym_phys(__bss_end),%ecx
+        push    %fs
+        pop     %es
         sub     %edi,%ecx
         xor     %eax,%eax
         shr     $2,%ecx
         rep stosl
+        push    %ds
+        pop     %es
 
 1:
         /* Interrogate CPU extended features via CPUID. */
@@ -470,8 +528,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_fs(cpuid_ext_features)
+        mov     %edx,sym_fs(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
 
         /* Check for availability of long mode. */
         bt      $cpufeat_bit(X86_FEATURE_LM),%edx
@@ -479,15 +537,52 @@ 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_fs(boot_tsc_stamp)
+        mov     %edx,sym_fs(boot_tsc_stamp)+4
+
+        /*
+         * Update frame addresses in page tables excluding l2_identmap
+         * without its first entry which points to l1_identmap.
+         */
+        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
+        mov     $(((l2_identmap-__page_tables_start)/8)+1),%edx
+1:      cmp     $((l2_identmap+l2_identmap_sizeof-__page_tables_start)/8),%ecx
+        cmove   %edx,%ecx
+        testl   $_PAGE_PRESENT,sym_fs(__page_tables_start)-8(,%ecx,8)
+        jz      2f
+        add     %esi,sym_fs(__page_tables_start)-8(,%ecx,8)
+2:      loop    1b
+
+        /* Initialize L2 boot-map/direct map page table entries (16MB). */
+        lea     sym_esi(start),%ebx
+        lea     (1<<L2_PAGETABLE_SHIFT)*7+(PAGE_HYPERVISOR|_PAGE_PSE)(%ebx),%eax
+        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
+        mov     $8,%ecx
+1:      mov     %eax,sym_fs(l2_bootmap)-8(%ebx,%ecx,8)
+        mov     %eax,sym_fs(l2_identmap)-8(%ebx,%ecx,8)
+        sub     $(1<<L2_PAGETABLE_SHIFT),%eax
+        loop    1b
+
+        /* Initialize L3 boot-map page directory entry. */
+        lea     __PAGE_HYPERVISOR+(L2_PAGETABLE_ENTRIES*8)*3+sym_esi(l2_bootmap),%eax
+        mov     $4,%ecx
+1:      mov     %eax,sym_fs(l3_bootmap)-8(,%ecx,8)
+        sub     $(L2_PAGETABLE_ENTRIES*8),%eax
+        loop    1b
+
+        /*
+         * During boot, hook 4kB mappings of first 2MB of memory into L2.
+         * This avoids mixing cachability for the legacy VGA region.
+         */
+        lea     __PAGE_HYPERVISOR+sym_esi(l1_identmap),%edi
+        mov     %edi,sym_fs(l2_bootmap)
 
         /* Apply relocations to bootstrap trampoline. */
-        mov     sym_phys(trampoline_phys),%edx
+        mov     sym_fs(trampoline_phys),%edx
         mov     $sym_phys(__trampoline_rel_start),%edi
 1:
-        mov     (%edi),%eax
-        add     %edx,(%edi,%eax)
+        mov     %fs:(%edi),%eax
+        add     %edx,%fs:(%edi,%eax)
         add     $4,%edi
         cmp     $sym_phys(__trampoline_rel_stop),%edi
         jb      1b
@@ -496,28 +591,29 @@ trampoline_setup:
         shr     $4,%edx
         mov     $sym_phys(__trampoline_seg_start),%edi
 1:
-        mov     (%edi),%eax
-        mov     %dx,(%edi,%eax)
+        mov     %fs:(%edi),%eax
+        mov     %dx,%fs:(%edi,%eax)
         add     $4,%edi
         cmp     $sym_phys(__trampoline_seg_stop),%edi
         jb      1b
 
         /* Do not parse command line on EFI platform here. */
-        cmpb    $0,sym_phys(efi_platform)
+        cmpb    $0,sym_fs(efi_platform)
         jnz     1f
 
         /* Bail if there is no command line to parse. */
-        mov     sym_phys(multiboot_ptr),%ebx
+        mov     sym_fs(multiboot_ptr),%ebx
         testl   $MBI_CMDLINE,MB_flags(%ebx)
         jz      1f
 
-        pushl   $sym_phys(early_boot_opts)
+        lea     sym_esi(early_boot_opts),%eax
+        push    %eax
         pushl   MB_cmdline(%ebx)
         call    cmdline_parse_early
 
 1:
         /* Switch to low-memory stack.  */
-        mov     sym_phys(trampoline_phys),%edi
+        mov     sym_fs(trampoline_phys),%edi
         lea     0x10000(%edi),%esp
         lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
         pushl   $BOOT_CS32
@@ -526,7 +622,7 @@ trampoline_setup:
         /* Copy bootstrap trampoline to low memory, below 1MB. */
         mov     $sym_phys(trampoline_start),%esi
         mov     $((trampoline_end - trampoline_start) / 4),%ecx
-        rep movsl
+        rep movsl %fs:(%esi),%es:(%edi)
 
         /* Jump into the relocated trampoline. */
         lret
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 2715d17..64f8efd 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -54,6 +54,11 @@ trampoline_gdt:
         /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
         .long   0x0000ffff
         .long   0x00009200
+        /*
+         * 0x0030: ring 0 Xen data, 16 MiB size, base
+         * address is computed during runtime.
+         */
+        .quad   0x00c0920000000fff
 
         .pushsection .trampoline_rel, "a"
         .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 7890374..7392004 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
@@ -102,6 +101,13 @@ l1_identmap:
         .size l1_identmap, . - l1_identmap
 
 /*
+ * __page_tables_start does not cover l1_identmap because it (l1_identmap)
+ * contains 1-1 mappings. This means that frame addresses of these mappings
+ * are static and should not be updated during runtime.
+ */
+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.
  */
@@ -186,21 +192,14 @@ GLOBAL(idle_pg_table)
 
 GLOBAL(__page_tables_end)
 
-/* Init pagetables.  Enough page directories to map into the bottom 1GB. */
+/* Init pagetables. Enough page directories to map into 4GB. */
         .section .init.data, "a", @progbits
         .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 5d0830e..561a139 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -330,9 +330,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;
@@ -716,6 +713,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     printk("Command line: %s\n", cmdline);
 
+    printk("Xen image load base address: %#lx\n", xen_phys_start);
+
     printk("Video information:\n");
 
     /* Print VGA display mode information. */
@@ -973,7 +972,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                     /* 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);
@@ -983,7 +982,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                         /* 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);
@@ -1006,7 +1005,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
             {
                 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() )
@@ -1060,6 +1060,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                 : "memory" );
 
             bootstrap_map(NULL);
+
+            printk("New Xen image base address: %#lx\n", xen_phys_start);
         }
 
         /* Is the region suitable for relocating the multiboot modules? */
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index 2a22659..5d7a8e5 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -179,5 +179,8 @@ void __dummy__(void)
     OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
     BLANK();
 
+    DEFINE(l2_identmap_sizeof, sizeof(l2_identmap));
+    BLANK();
+
     OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
 }
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index af7d3e8..a54fdd1 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_fixmap[L1_PAGETABLE_ENTRIES];
-- 
1.7.10.4


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

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

* [PATCH v11 12/13] x86/boot: rename sym_phys() to sym_offs()
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (10 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 11/13] x86: make Xen early boot code relocatable Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-05 22:25 ` [PATCH v11 13/13] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

This way macro name better describes its function.
Currently it is used to calculate symbol offset in
relation to the beginning of Xen image mapping.
However, value returned by sym_offs() for a given
symbol is not always equal its physical address.

There is no functional change.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v8 - suggestions/fixes:
   - improve commit message
     (suggested by Jan Beulich).
---
 xen/arch/x86/boot/head.S       |   38 +++++++++++++++++++-------------------
 xen/arch/x86/boot/trampoline.S |    2 +-
 xen/arch/x86/boot/wakeup.S     |    4 ++--
 xen/arch/x86/boot/x86_64.S     |   18 +++++++++---------
 4 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index d992a95..390f72d 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -12,9 +12,9 @@
         .text
         .code32
 
-#define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
-#define sym_esi(sym)      sym_phys(sym)(%esi)
-#define sym_fs(sym)       %fs:sym_phys(sym)
+#define sym_offs(sym)     ((sym) - __XEN_VIRT_START)
+#define sym_esi(sym)      sym_offs(sym)(%esi)
+#define sym_fs(sym)       %fs:sym_offs(sym)
 
 #define BOOT_CS32        0x0008
 #define BOOT_CS64        0x0010
@@ -97,7 +97,7 @@ multiboot2_header_start:
 
         /* EFI64 entry point. */
         mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
-                   sym_phys(__efi64_start)
+                   sym_offs(__efi64_start)
 
         /* Multiboot2 header end tag. */
         mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
@@ -110,7 +110,7 @@ multiboot2_header_start:
 gdt_boot_descr:
         .word   7*8-1
 gdt_boot_base:
-        .long   sym_phys(trampoline_gdt)
+        .long   sym_offs(trampoline_gdt)
         .long   0 /* Needed for 64-bit lgdt */
 
         .align 4
@@ -130,23 +130,23 @@ efi_platform:
         .section .init.text, "ax", @progbits
 
 bad_cpu:
-        add     $sym_phys(.Lbad_cpu_msg),%esi   # Error message
+        add     $sym_offs(.Lbad_cpu_msg),%esi   # Error message
         jmp     .Lget_vtb
 not_multiboot:
-        add     $sym_phys(.Lbad_ldr_msg),%esi   # Error message
+        add     $sym_offs(.Lbad_ldr_msg),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_st:
-        add     $sym_phys(.Lbad_ldr_nst),%esi   # Error message
+        add     $sym_offs(.Lbad_ldr_nst),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_ih:
-        add     $sym_phys(.Lbad_ldr_nih),%esi   # Error message
+        add     $sym_offs(.Lbad_ldr_nih),%esi   # Error message
         jmp     .Lget_vtb
 .Lmb2_no_bs:
-        add     $sym_phys(.Lbad_ldr_nbs),%esi   # Error message
+        add     $sym_offs(.Lbad_ldr_nbs),%esi   # Error message
         xor     %edi,%edi                       # No VGA text buffer
         jmp     .Lsend_chr
 .Lmb2_efi_ia_32:
-        add     $sym_phys(.Lbad_efi_msg),%esi   # Error message
+        add     $sym_offs(.Lbad_efi_msg),%esi   # Error message
         xor     %edi,%edi                       # No VGA text buffer
         jmp     .Lsend_chr
 .Lget_vtb:
@@ -354,7 +354,7 @@ __start:
         cli
 
         /* Load default Xen image load base address. */
-        mov     $sym_phys(__image_base__),%esi
+        mov     $sym_offs(__image_base__),%esi
 
         /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
         xor     %edx,%edx
@@ -505,8 +505,8 @@ trampoline_setup:
         jnz     1f
 
         /* Initialize BSS (no nasty surprises!). */
-        mov     $sym_phys(__bss_start),%edi
-        mov     $sym_phys(__bss_end),%ecx
+        mov     $sym_offs(__bss_start),%edi
+        mov     $sym_offs(__bss_end),%ecx
         push    %fs
         pop     %es
         sub     %edi,%ecx
@@ -579,22 +579,22 @@ trampoline_setup:
 
         /* Apply relocations to bootstrap trampoline. */
         mov     sym_fs(trampoline_phys),%edx
-        mov     $sym_phys(__trampoline_rel_start),%edi
+        mov     $sym_offs(__trampoline_rel_start),%edi
 1:
         mov     %fs:(%edi),%eax
         add     %edx,%fs:(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_rel_stop),%edi
+        cmp     $sym_offs(__trampoline_rel_stop),%edi
         jb      1b
 
         /* Patch in the trampoline segment. */
         shr     $4,%edx
-        mov     $sym_phys(__trampoline_seg_start),%edi
+        mov     $sym_offs(__trampoline_seg_start),%edi
 1:
         mov     %fs:(%edi),%eax
         mov     %dx,%fs:(%edi,%eax)
         add     $4,%edi
-        cmp     $sym_phys(__trampoline_seg_stop),%edi
+        cmp     $sym_offs(__trampoline_seg_stop),%edi
         jb      1b
 
         /* Do not parse command line on EFI platform here. */
@@ -620,7 +620,7 @@ trampoline_setup:
         push    %eax
 
         /* Copy bootstrap trampoline to low memory, below 1MB. */
-        mov     $sym_phys(trampoline_start),%esi
+        mov     $sym_offs(trampoline_start),%esi
         mov     $((trampoline_end - trampoline_start) / 4),%ecx
         rep movsl %fs:(%esi),%es:(%edi)
 
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 64f8efd..b96607a 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -92,7 +92,7 @@ trampoline_protmode_entry:
         mov     %ecx,%cr4
 
         /* Load pagetable base register. */
-        mov     $sym_phys(idle_pg_table),%eax
+        mov     $sym_offs(idle_pg_table),%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..42d57ab 100644
--- a/xen/arch/x86/boot/wakeup.S
+++ b/xen/arch/x86/boot/wakeup.S
@@ -120,7 +120,7 @@ wakeup_32:
         mov     $bootsym_rel(wakeup_stack, 4, %esp)
 
         # check saved magic again
-        mov     $sym_phys(saved_magic), %eax
+        mov     $sym_offs(saved_magic),%eax
         add     bootsym_rel(trampoline_xen_phys_start, 4, %eax)
         mov     (%eax), %eax
         cmp     $0x9abcdef0, %eax
@@ -133,7 +133,7 @@ wakeup_32:
         mov     %ecx, %cr4
 
         /* Load pagetable base register */
-        mov     $sym_phys(idle_pg_table),%eax
+        mov     $sym_offs(idle_pg_table),%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 7392004..86d3775 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -112,7 +112,7 @@ GLOBAL(__page_tables_start)
  * actualy mapped (mostly using superpages).  Uses 4x 4k pages.
  */
 GLOBAL(l2_identmap)
-        .quad sym_phys(l1_identmap) + __PAGE_HYPERVISOR
+        .quad sym_offs(l1_identmap) + __PAGE_HYPERVISOR
         idx = 1
         .rept 7
         .quad (idx << L2_PAGETABLE_SHIFT) | PAGE_HYPERVISOR | _PAGE_PSE
@@ -130,7 +130,7 @@ GLOBAL(l2_xenmap)
         .quad 0
         idx = 1
         .rept 7
-        .quad sym_phys(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
+        .quad sym_offs(__image_base__) + (idx << L2_PAGETABLE_SHIFT) + (PAGE_HYPERVISOR | _PAGE_PSE)
         idx = idx + 1
         .endr
         .fill L2_PAGETABLE_ENTRIES - 8, 8, 0
@@ -141,7 +141,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_offs(l1_fixmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
@@ -153,7 +153,7 @@ l2_fixmap:
 l3_identmap:
         idx = 0
         .rept 4
-        .quad sym_phys(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
+        .quad sym_offs(l2_identmap) + (idx << PAGE_SHIFT) + __PAGE_HYPERVISOR
         idx = idx + 1
         .endr
         .fill L3_PAGETABLE_ENTRIES - 4, 8, 0
@@ -164,9 +164,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_offs(l2_xenmap) + __PAGE_HYPERVISOR
         .elseif idx == l3_table_offset(FIXADDR_TOP - 1)
-        .quad sym_phys(l2_fixmap) + __PAGE_HYPERVISOR
+        .quad sym_offs(l2_fixmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
@@ -176,13 +176,13 @@ l3_xenmap:
 
 /* Top-level master (and idle-domain) page directory. */
 GLOBAL(idle_pg_table)
-        .quad sym_phys(l3_bootmap) + __PAGE_HYPERVISOR
+        .quad sym_offs(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_offs(l3_identmap) + __PAGE_HYPERVISOR
         .elseif idx == l4_table_offset(XEN_VIRT_START)
-        .quad sym_phys(l3_xenmap) + __PAGE_HYPERVISOR
+        .quad sym_offs(l3_xenmap) + __PAGE_HYPERVISOR
         .else
         .quad 0
         .endif
-- 
1.7.10.4


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

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

* [PATCH v11 13/13] x86: add multiboot2 protocol support for relocatable images
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (11 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 12/13] x86/boot: rename sym_phys() to sym_offs() Daniel Kiper
@ 2016-12-05 22:25 ` Daniel Kiper
  2016-12-16 15:59 ` [PATCH v11 00/13] x86: multiboot2 protocol support Doug Goldstein
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-05 22:25 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, 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>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v9 - suggestions/fixes:
   - use .L labels instead of numeric ones in multiboot2 data scanning loop
     (suggested by Jan Beulich).

v4 - suggestions/fixes:
   - do not get Xen image load base address from
     multiboot2 information in x86_64 code
     (suggested by Jan Beulich),
   - improve label names
     (suggested by Jan Beulich),
   - improve comments,
     (suggested by Jan Beulich).

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          |   16 ++++++++++++++++
 xen/arch/x86/x86_64/asm-offsets.c |    1 +
 xen/include/xen/multiboot2.h      |   13 +++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 390f72d..fabfa97 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -82,6 +82,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_offs(start), /* Min load address. */ \
+                   0xffffffff, /* The end of image 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
@@ -386,6 +393,15 @@ __start:
         cmp     %edi,MB2_fixed_total_size(%ebx)
         jbe     trampoline_bios_setup
 
+        /* Get Xen image load base address from Multiboot2 information. */
+        cmpl    $MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR,MB2_tag_type(%ecx)
+        jne     .Lmb2_mem_lower
+
+        mov     MB2_load_base_addr(%ecx),%esi
+        sub     $XEN_IMG_OFFSET,%esi
+        jmp     .Lmb2_next_tag
+
+.Lmb2_mem_lower:
         /* Get mem_lower from Multiboot2 information. */
         cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
         cmove   MB2_mem_lower(%ecx),%edx
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index 5d7a8e5..beac5ca 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -174,6 +174,7 @@ void __dummy__(void)
     OFFSET(MB2_fixed_total_size, multiboot2_fixed_t, total_size);
     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 8dd5800..feb4297 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[];
 } multiboot2_tag_string_t;
 
-- 
1.7.10.4


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

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

* Re: [PATCH v11 06/13] efi: create new early memory allocator
  2016-12-05 22:25 ` [PATCH v11 06/13] efi: create new early memory allocator Daniel Kiper
@ 2016-12-06  8:27   ` Jan Beulich
  2016-12-09 18:03   ` Julien Grall
  1 sibling, 0 replies; 64+ messages in thread
From: Jan Beulich @ 2016-12-06  8:27 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

>>> On 05.12.16 at 23:25, <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 goes
> down. Sadly this does not work when Xen is loaded using multiboot2
> protocol because then the start lives on 1 MiB address and we should
> not allocate a memory from below of it. So, I tried to use mem_lower
> address calculated by GRUB2. However, this solution 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... :-(((
> Hence, we need new memory allocator for Xen EFI boot code which is
> quite simple and generic and could be used by place_string() and
> efi_arch_allocate_mmap_buffer(). I think about following 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
>    it in e820 memory map and map it in Xen virtual address space. This
>    means that the code referring to Xen command line, loaded modules and
>    EFI memory map, mostly in __start_xen(), will be further complicated
>    and diverge from legacy BIOS cases. Additionally, both former things
>    have to be placed below 4 GiB because their addresses are stored in
>    multiboot_info_t structure which has 32-bit relevant members.
> 
> 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 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 is 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 could put memory pool into .bss.page_aligned section. Then allocate
>     memory chunks starting from the lowest address. After init phase we can
>     free unused portion of the memory pool as in case of .init.text or .init.data
>     sections. This way we do not need to allocate any space in image file and
>     freeing of unused area in the memory pool is very simple.
> 
> Now #2a solution is implemented because it is quite simple and requires
> limited number of changes, especially in __start_xen().
> 
> New allocator is quite generic and can be used on ARM platforms too.
> Though it is not enabled on ARM yet due to lack of some prereq.
> List of them is placed before ebmalloc code.

This last paragraph is now slightly stale, but anyway ...

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

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


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

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

* Re: [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms...
  2016-12-05 22:25 ` [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms Daniel Kiper
@ 2016-12-07 13:18   ` Jan Beulich
  2016-12-07 17:25     ` Daniel Kiper
  2017-01-10  1:24     ` Doug Goldstein
  0 siblings, 2 replies; 64+ messages in thread
From: Jan Beulich @ 2016-12-07 13:18 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

>>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
> ..nor EFI platforms with runtime services enabled.

Btw, was the title meant to read "... neither on non-EFI platforms ..."?

Jan


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

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

* Re: [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-05 22:25 ` [PATCH v11 08/13] x86/boot: implement early command line parser in C Daniel Kiper
@ 2016-12-07 13:43   ` Jan Beulich
  2016-12-07 17:27     ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2016-12-07 13:43 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

>>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
> Current early command line parser implementation in assembler
> is very difficult to change to relocatable stuff using segment
> registers. This requires a lot of changes in very weird and
> fragile code. So, reimplement this functionality in C. This
> way code will be relocatable out of the box (without playing
> with segment registers) and much easier to maintain.
> 
> Additionally, put all common cmdline.c and reloc.c definitions
> into defs.h header. This way we do not duplicate needlessly
> some stuff.
> 
> And finally remove unused xen/include/asm-x86/config.h
> header from reloc.c dependencies.
> 
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>

As you may have seen I've applied patches 2..4. I would also
have applied this one, but it fails to apply cleanly. Whether
that's because it needs re-basing or because it can't be applied
out of order I can't tell. In order for you to not have to re-submit
the whole series all the time it would help if you moved
uncontroversial patches which make sense to be applied without
the rest of the series to the beginning of the series.

Jan


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

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

* Re: [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms...
  2016-12-07 13:18   ` Jan Beulich
@ 2016-12-07 17:25     ` Daniel Kiper
  2017-01-10  1:24     ` Doug Goldstein
  1 sibling, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-07 17:25 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Dec 07, 2016 at 06:18:19AM -0700, Jan Beulich wrote:
> >>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
> > ..nor EFI platforms with runtime services enabled.
>
> Btw, was the title meant to read "... neither on non-EFI platforms ..."?

Right, thanks for pointing this out.

Daniel

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

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

* Re: [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-07 13:43   ` Jan Beulich
@ 2016-12-07 17:27     ` Daniel Kiper
  2016-12-08 23:08       ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-07 17:27 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Dec 07, 2016 at 06:43:40AM -0700, Jan Beulich wrote:
> >>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
> > Current early command line parser implementation in assembler
> > is very difficult to change to relocatable stuff using segment
> > registers. This requires a lot of changes in very weird and
> > fragile code. So, reimplement this functionality in C. This
> > way code will be relocatable out of the box (without playing
> > with segment registers) and much easier to maintain.
> >
> > Additionally, put all common cmdline.c and reloc.c definitions
> > into defs.h header. This way we do not duplicate needlessly
> > some stuff.
> >
> > And finally remove unused xen/include/asm-x86/config.h
> > header from reloc.c dependencies.
> >
> > Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > Acked-by: Jan Beulich <jbeulich@suse.com>
>
> As you may have seen I've applied patches 2..4. I would also

Great! Thanks a lot!

> have applied this one, but it fails to apply cleanly. Whether
> that's because it needs re-basing or because it can't be applied
> out of order I can't tell. In order for you to not have to re-submit
> the whole series all the time it would help if you moved
> uncontroversial patches which make sense to be applied without
> the rest of the series to the beginning of the series.

Will do!

Daniel

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

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

* Re: [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-07 17:27     ` Daniel Kiper
@ 2016-12-08 23:08       ` Daniel Kiper
  2016-12-09  8:19         ` Jan Beulich
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2016-12-08 23:08 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Dec 07, 2016 at 06:27:58PM +0100, Daniel Kiper wrote:
> On Wed, Dec 07, 2016 at 06:43:40AM -0700, Jan Beulich wrote:
> > >>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
> > > Current early command line parser implementation in assembler
> > > is very difficult to change to relocatable stuff using segment
> > > registers. This requires a lot of changes in very weird and
> > > fragile code. So, reimplement this functionality in C. This
> > > way code will be relocatable out of the box (without playing
> > > with segment registers) and much easier to maintain.
> > >
> > > Additionally, put all common cmdline.c and reloc.c definitions
> > > into defs.h header. This way we do not duplicate needlessly
> > > some stuff.
> > >
> > > And finally remove unused xen/include/asm-x86/config.h
> > > header from reloc.c dependencies.
> > >
> > > Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> > > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > > Acked-by: Jan Beulich <jbeulich@suse.com>
> >
> > As you may have seen I've applied patches 2..4. I would also
>
> Great! Thanks a lot!
>
> > have applied this one, but it fails to apply cleanly. Whether
> > that's because it needs re-basing or because it can't be applied
> > out of order I can't tell. In order for you to not have to re-submit

I have checked it. It requires at least some changes made by patch #1 which
has "Reviewed-by: Jan Beulich <jbeulich@suse.com>". Of course I can change
this but then I think that I should drop your Reviewed-by from #1 and your
Acked-by from #8. Does it pays? I think that we can do that in a bit different
way. If there are no more comments please apply everything as is. If any new
comment, worth taking into account, pop up I can rearrange patches order and
drop your Reviewed-by/Acked-by too. Does it work for you?

Daniel

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

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

* Re: [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-08 23:08       ` Daniel Kiper
@ 2016-12-09  8:19         ` Jan Beulich
  2016-12-09 13:32           ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2016-12-09  8:19 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

>>> On 09.12.16 at 00:08, <daniel.kiper@oracle.com> wrote:
> On Wed, Dec 07, 2016 at 06:27:58PM +0100, Daniel Kiper wrote:
>> On Wed, Dec 07, 2016 at 06:43:40AM -0700, Jan Beulich wrote:
>> > >>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
>> > > Current early command line parser implementation in assembler
>> > > is very difficult to change to relocatable stuff using segment
>> > > registers. This requires a lot of changes in very weird and
>> > > fragile code. So, reimplement this functionality in C. This
>> > > way code will be relocatable out of the box (without playing
>> > > with segment registers) and much easier to maintain.
>> > >
>> > > Additionally, put all common cmdline.c and reloc.c definitions
>> > > into defs.h header. This way we do not duplicate needlessly
>> > > some stuff.
>> > >
>> > > And finally remove unused xen/include/asm-x86/config.h
>> > > header from reloc.c dependencies.
>> > >
>> > > Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> > > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>> > > Acked-by: Jan Beulich <jbeulich@suse.com>
>> >
>> > As you may have seen I've applied patches 2..4. I would also
>>
>> Great! Thanks a lot!
>>
>> > have applied this one, but it fails to apply cleanly. Whether
>> > that's because it needs re-basing or because it can't be applied
>> > out of order I can't tell. In order for you to not have to re-submit
> 
> I have checked it. It requires at least some changes made by patch #1 which
> has "Reviewed-by: Jan Beulich <jbeulich@suse.com>". Of course I can change
> this but then I think that I should drop your Reviewed-by from #1 and your
> Acked-by from #8.

Unless you change the structure of the code you move, I don't think
either of the tags would require dropping.

> Does it pays? I think that we can do that in a bit different
> way. If there are no more comments please apply everything as is.

I think Andrew and I are in agreement that we're not at the point
yet where everything can go in as is. Please be patient - this has
taken so long to get where it is now that I don't think there's a
reason to rush anything now. And you may have noticed that
there have been quite a few other patch submissions which also
all want dealing with. Andrew and I should also be allowed some
room to actually do some work of our own ...

Jan


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

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

* Re: [PATCH v11 08/13] x86/boot: implement early command line parser in C
  2016-12-09  8:19         ` Jan Beulich
@ 2016-12-09 13:32           ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-09 13:32 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, sstabellini, andrew.cooper3, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Fri, Dec 09, 2016 at 01:19:24AM -0700, Jan Beulich wrote:
> >>> On 09.12.16 at 00:08, <daniel.kiper@oracle.com> wrote:

[...]

> > I have checked it. It requires at least some changes made by patch #1 which
> > has "Reviewed-by: Jan Beulich <jbeulich@suse.com>". Of course I can change
> > this but then I think that I should drop your Reviewed-by from #1 and your
> > Acked-by from #8.
>
> Unless you change the structure of the code you move, I don't think
> either of the tags would require dropping.

I think that code move will be sufficient and logic should not change.
So, if it works in that way I will leave your tags as is.

> > Does it pays? I think that we can do that in a bit different
> > way. If there are no more comments please apply everything as is.
>
> I think Andrew and I are in agreement that we're not at the point
> yet where everything can go in as is. Please be patient - this has
> taken so long to get where it is now that I don't think there's a
> reason to rush anything now. And you may have noticed that
> there have been quite a few other patch submissions which also
> all want dealing with. Andrew and I should also be allowed some
> room to actually do some work of our own ...

I understand that. This is not a problem for me. However, I would like to see
my patches in 4.9. Otherwise I am spinning around and cannot efficiently
continue my work which partially depends on this patch series.

Daniel

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

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

* Re: [PATCH v11 06/13] efi: create new early memory allocator
  2016-12-05 22:25 ` [PATCH v11 06/13] efi: create new early memory allocator Daniel Kiper
  2016-12-06  8:27   ` Jan Beulich
@ 2016-12-09 18:03   ` Julien Grall
  2016-12-12 14:27     ` Daniel Kiper
  1 sibling, 1 reply; 64+ messages in thread
From: Julien Grall @ 2016-12-09 18:03 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	jbeulich, qiaowei.ren, gang.wei, fu.wei

Hi Daniel,

On 05/12/16 22:25, 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 goes
> down. Sadly this does not work when Xen is loaded using multiboot2
> protocol because then the start lives on 1 MiB address and we should
> not allocate a memory from below of it. So, I tried to use mem_lower
> address calculated by GRUB2. However, this solution 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... :-(((
> Hence, we need new memory allocator for Xen EFI boot code which is
> quite simple and generic and could be used by place_string() and
> efi_arch_allocate_mmap_buffer(). I think about following 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
>    it in e820 memory map and map it in Xen virtual address space. This
>    means that the code referring to Xen command line, loaded modules and
>    EFI memory map, mostly in __start_xen(), will be further complicated
>    and diverge from legacy BIOS cases. Additionally, both former things
>    have to be placed below 4 GiB because their addresses are stored in
>    multiboot_info_t structure which has 32-bit relevant members.
>
> 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 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 is 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 could put memory pool into .bss.page_aligned section. Then allocate
>     memory chunks starting from the lowest address. After init phase we can
>     free unused portion of the memory pool as in case of .init.text or .init.data
>     sections. This way we do not need to allocate any space in image file and
>     freeing of unused area in the memory pool is very simple.
>
> Now #2a solution is implemented because it is quite simple and requires
> limited number of changes, especially in __start_xen().
>
> New allocator is quite generic and can be used on ARM platforms too.
> Though it is not enabled on ARM yet due to lack of some prereq.
> List of them is placed before ebmalloc code.
>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

FWIW,

Acked-by: Julien Grall <julien.grall@arm.com>

-- 
Julien Grall

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

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

* Re: [PATCH v11 06/13] efi: create new early memory allocator
  2016-12-09 18:03   ` Julien Grall
@ 2016-12-12 14:27     ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2016-12-12 14:27 UTC (permalink / raw)
  To: Julien Grall
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Fri, Dec 09, 2016 at 06:03:06PM +0000, Julien Grall wrote:
> Hi Daniel,
>
> On 05/12/16 22:25, 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 goes
> >down. Sadly this does not work when Xen is loaded using multiboot2
> >protocol because then the start lives on 1 MiB address and we should
> >not allocate a memory from below of it. So, I tried to use mem_lower
> >address calculated by GRUB2. However, this solution 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... :-(((
> >Hence, we need new memory allocator for Xen EFI boot code which is
> >quite simple and generic and could be used by place_string() and
> >efi_arch_allocate_mmap_buffer(). I think about following 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
> >   it in e820 memory map and map it in Xen virtual address space. This
> >   means that the code referring to Xen command line, loaded modules and
> >   EFI memory map, mostly in __start_xen(), will be further complicated
> >   and diverge from legacy BIOS cases. Additionally, both former things
> >   have to be placed below 4 GiB because their addresses are stored in
> >   multiboot_info_t structure which has 32-bit relevant members.
> >
> >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 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 is 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 could put memory pool into .bss.page_aligned section. Then allocate
> >    memory chunks starting from the lowest address. After init phase we can
> >    free unused portion of the memory pool as in case of .init.text or .init.data
> >    sections. This way we do not need to allocate any space in image file and
> >    freeing of unused area in the memory pool is very simple.
> >
> >Now #2a solution is implemented because it is quite simple and requires
> >limited number of changes, especially in __start_xen().
> >
> >New allocator is quite generic and can be used on ARM platforms too.
> >Though it is not enabled on ARM yet due to lack of some prereq.
> >List of them is placed before ebmalloc code.
> >
> >Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> FWIW,
>
> Acked-by: Julien Grall <julien.grall@arm.com>

Thanks a lot!

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2016-12-05 22:25 ` [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
@ 2016-12-16 13:38   ` Andrew Cooper
  2016-12-16 13:50     ` Jan Beulich
  2017-01-10  1:37   ` Doug Goldstein
  1 sibling, 1 reply; 64+ messages in thread
From: Andrew Cooper @ 2016-12-16 13:38 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, cardoe, pgnet.dev, ning.sun, julien.grall,
	jbeulich, qiaowei.ren, gang.wei, fu.wei

On 05/12/16 22:25, Daniel Kiper wrote:
> diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
> index 4158124..6ea6aa1 100644
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -3,6 +3,44 @@
>  #include <xen/init.h>
>  #include <xen/lib.h>
>  #include <asm/page.h>
> +#include <asm/efibind.h>
> +#include <efi/efidef.h>
> +#include <efi/eficapsule.h>
> +#include <efi/eficon.h>
> +#include <efi/efidevp.h>
> +#include <efi/efiapi.h>
> +
> +/*
> + * Here we are in EFI stub. EFI calls are not supported due to lack
> + * of relevant functionality in compiler and/or linker.
> + *
> + * efi_multiboot2() is an exception. Please look below for more details.
> + */
> +
> +paddr_t __init noreturn efi_multiboot2(EFI_HANDLE ImageHandle,
> +                                       EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    CHAR16 *err = L"Xen does not have EFI code build in!!!\r\nSystem halted!!!\r\n";
> +    SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
> +
> +    StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
> +
> +    /*
> +     * Print error message and halt the system.
> +     *
> +     * We have to open code MS x64 calling convention
> +     * in assembly because here this convention may
> +     * not be directly supported by C compiler.
> +     */
> +    asm volatile(
> +    "    call %2                      \n"

This should be `call *%2`, because otherwise gcc complains with:

stub.c: Assembler messages:
stub.c:35: Warning: indirect call without `*'

Interestingly, it isn't fatal to the build which is why I didn't spot it
earlier.  I also can't work out why it isn't fatal to the build, because
I'd have thought the -Werror should have been enough.

~Andrew

> +    "0:  hlt                          \n"
> +    "    jmp  0b                      \n"
> +       : "+c" (StdErr), "+d" (err) : "g" (StdErr->OutputString)
> +       : "rax", "r8", "r9", "r10", "r11", "memory");
> +
> +    unreachable();
> +}
>  
>  bool efi_enabled(unsigned int feature)
>  {


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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2016-12-16 13:38   ` Andrew Cooper
@ 2016-12-16 13:50     ` Jan Beulich
  0 siblings, 0 replies; 64+ messages in thread
From: Jan Beulich @ 2016-12-16 13:50 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Juergen Gross, sstabellini, Daniel Kiper, cardoe, pgnet.dev,
	ning.sun, julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei

>>> On 16.12.16 at 14:38, <andrew.cooper3@citrix.com> wrote:
> On 05/12/16 22:25, Daniel Kiper wrote:
>> diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c
>> index 4158124..6ea6aa1 100644
>> --- a/xen/arch/x86/efi/stub.c
>> +++ b/xen/arch/x86/efi/stub.c
>> @@ -3,6 +3,44 @@
>>  #include <xen/init.h>
>>  #include <xen/lib.h>
>>  #include <asm/page.h>
>> +#include <asm/efibind.h>
>> +#include <efi/efidef.h>
>> +#include <efi/eficapsule.h>
>> +#include <efi/eficon.h>
>> +#include <efi/efidevp.h>
>> +#include <efi/efiapi.h>
>> +
>> +/*
>> + * Here we are in EFI stub. EFI calls are not supported due to lack
>> + * of relevant functionality in compiler and/or linker.
>> + *
>> + * efi_multiboot2() is an exception. Please look below for more details.
>> + */
>> +
>> +paddr_t __init noreturn efi_multiboot2(EFI_HANDLE ImageHandle,
>> +                                       EFI_SYSTEM_TABLE *SystemTable)
>> +{
>> +    CHAR16 *err = L"Xen does not have EFI code build in!!!\r\nSystem halted!!!\r\n";
>> +    SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
>> +
>> +    StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
>> +
>> +    /*
>> +     * Print error message and halt the system.
>> +     *
>> +     * We have to open code MS x64 calling convention
>> +     * in assembly because here this convention may
>> +     * not be directly supported by C compiler.
>> +     */
>> +    asm volatile(
>> +    "    call %2                      \n"
> 
> This should be `call *%2`, because otherwise gcc complains with:
> 
> stub.c: Assembler messages:
> stub.c:35: Warning: indirect call without `*'
> 
> Interestingly, it isn't fatal to the build which is why I didn't spot it
> earlier.  I also can't work out why it isn't fatal to the build, because
> I'd have thought the -Werror should have been enough.

-Werror only affects compiler warnings. The compiler doesn't try
to interpret assembler diagnostics.

Jan


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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (12 preceding siblings ...)
  2016-12-05 22:25 ` [PATCH v11 13/13] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
@ 2016-12-16 15:59 ` Doug Goldstein
  2017-01-10 23:12 ` [PATCH 2/??] memory allocation fix Doug Goldstein
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2016-12-16 15:59 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, Jonathan Creekmore, qiaowei.ren,
	gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 1467 bytes --]

On 12/5/16 4:25 PM, Daniel Kiper wrote:
> Hi,
> 
> I am sending eleventh version of multiboot2 protocol support for
> legacy BIOS and EFI platforms. This patch series release contains
> fixes for all known issues.
> 
> 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 is short list of changes since v10:
>   - changed patches: 06 (small change suggested by Jan).
> 
> This is Xen 4.9 material.
> 
> If you are not interested in this patch series at all please
> drop me a line and I will remove you from distribution list.
> 

Feel free to add:

Reviewed-by: Doug Goldstein <cardoe@cardoe.com>

I'm running this series (plus Andrew's fix in patch 7) in my 4.8 based
version. We're currently only booting this with multiboot1 but are in
the process of adding multiboot2 support to iPXE.

If booting it with multiboot1 is sufficient then I'm not opposed to adding:

Tested-by: Doug Goldstein <cardoe@cardoe.com>

I'll report back when I do more testing.
-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 01/13] x86: add multiboot2 protocol support
  2016-12-05 22:25 ` [PATCH v11 01/13] x86: add " Daniel Kiper
@ 2017-01-10  1:21   ` Doug Goldstein
  2017-01-10  8:38     ` Jan Beulich
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10  1:21 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 26335 bytes --]

On 12/5/16 4:25 PM, Daniel Kiper wrote:
> Add multiboot2 protocol support. Alter min memory limit handling as we
> now may not find it from either multiboot (v1) or multiboot2.
> 
> This way we are laying the foundation for EFI + GRUB2 + Xen development.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> ---
> v9 - suggestions/fixes:
>    - use .L label instead of numeric one in multiboot2 data scanning loop;
>      I hope that this change does not invalidate Jan's Reviewed-by
>      (suggested by Jan Beulich).
> 
> v8 - suggestions/fixes:
>    - use sizeof(<var>/<expr>) instead of sizeof(<type>)
>      if it is possible
>      (suggested by Jan Beulich).
> 
> v7 - suggestions/fixes:
>    - rename mbi_mbi/mbi2_mbi to mbi_reloc/mbi2_reloc respectively
>      (suggested by Jan Beulich),
>    - initialize mbi_out->flags using "|=" instead of "="
>      (suggested by Jan Beulich),
>    - use sizeof(*mmap_dst) instead of sizeof(memory_map_t)
>      if it makes sense
>      (suggested by Jan Beulich).
> 
> v6 - suggestions/fixes:
>    - properly index multiboot2_tag_mmap_t.entries[]
>      (suggested by Jan Beulich),
>    - do not index mbi_out_mods[] beyond its end
>      (suggested by Andrew Cooper),
>    - reduce number of casts
>      (suggested by Andrew Cooper and Jan Beulich),
>    - add braces to increase code readability
>      (suggested by Andrew Cooper).
> 
> v5 - suggestions/fixes:
>    - check multiboot2_tag_mmap_t.entry_size before
>      multiboot2_tag_mmap_t.entries[] use
>      (suggested by Jan Beulich),
>    - properly index multiboot2_tag_mmap_t.entries[]
>      (suggested by Jan Beulich),
>    - use "type name[]" instad of "type name[0]"
>      in xen/include/xen/multiboot2.h
>      (suggested by Jan Beulich),
>    - remove unneeded comment
>      (suggested by Jan Beulich).
> 
> v4 - suggestions/fixes:
>    - avoid assembly usage in xen/arch/x86/boot/reloc.c,
>    - fix boundary check issue and optimize
>      for() loops in mbi2_mbi(),
>    - move to stdcall calling convention,
>    - remove unneeded typeof() from ALIGN_UP() macro
>      (suggested by Jan Beulich),
>    - add and use NULL definition in xen/arch/x86/boot/reloc.c
>      (suggested by Jan Beulich),
>    - do not read data beyond the end of multiboot2
>      information in xen/arch/x86/boot/head.S
>      (suggested by Jan Beulich),
>    - add :req to some .macro arguments
>      (suggested by Jan Beulich),
>    - use cmovcc if possible,
>    - add .L to multiboot2_header_end label
>      (suggested by Jan Beulich),
>    - add .L to multiboot2_proto label
>      (suggested by Jan Beulich),
>    - improve label names
>      (suggested by Jan Beulich).
> 
> 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          |  107 ++++++++++++++++++++++-
>  xen/arch/x86/boot/reloc.c         |  148 ++++++++++++++++++++++++++++++--
>  xen/arch/x86/x86_64/asm-offsets.c |    9 ++
>  xen/include/xen/multiboot2.h      |  169 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 426 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 6f2c668..d423fd8 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:req, args:vararg
> +        .long \arg
> +        .ifnb \args
> +        mb2ht_args \args
> +        .endif
> +        .endm
> +
> +        .macro mb2ht_init type:req, req: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   .Lmultiboot2_header_end - multiboot2_header_start
> +        /* Multiboot2 header checksum. */
> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> +                        (.Lmultiboot2_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)
> +.Lmultiboot2_header_end:
> +
>          .section .init.rodata, "a", @progbits
>          .align 4
>  
> @@ -82,10 +141,52 @@ __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      .Lmultiboot2_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
> +
> +.Lmultiboot2_proto:
> +        /* Skip Multiboot2 information fixed part. */
> +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +
> +.Lmb2_tsize:
> +        /* Check Multiboot2 information total size. */
> +        mov     %ecx,%edi
> +        sub     %ebx,%edi
> +        cmp     %edi,MB2_fixed_total_size(%ebx)
> +        jbe     trampoline_setup
> +
> +        /* Get mem_lower from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
> +        cmove   MB2_mem_lower(%ecx),%edx
> +        je      trampoline_setup
> +
> +        /* 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     .Lmb2_tsize
> +
> +trampoline_setup:
>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -100,9 +201,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,6 +219,7 @@ __start:
>          mov     $sym_phys(cpu0_stack)+1024,%esp
>          push    %ecx                /* Boot trampoline address. */
>          push    %ebx                /* Multiboot information address. */
> +        push    %eax                /* Multiboot magic. */
>          call    reloc
>          mov     %eax,sym_phys(multiboot_ptr)
>  
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index ea8cb37..b22bf1e 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,7 +26,12 @@ asm (
>      );
>  
>  typedef unsigned int u32;
> +typedef unsigned long long u64;
> +
>  #include "../../../include/xen/multiboot.h"
> +#include "../../../include/xen/multiboot2.h"
> +
> +#define NULL		((void *)0)
>  
>  #define __stdcall	__attribute__((__stdcall__))
>  
> @@ -32,6 +40,9 @@ typedef unsigned int u32;
>  
>  #define _p(val)		((void *)(unsigned long)(val))
>  
> +#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;
>  
>  static u32 alloc_mem(u32 bytes)
> @@ -39,6 +50,12 @@ static u32 alloc_mem(u32 bytes)
>      return alloc -= ALIGN_UP(bytes, 16);
>  }
>  
> +static void zero_mem(u32 s, u32 bytes)
> +{
> +    while ( bytes-- )
> +        *(char *)s++ = 0;
> +}
> +
>  static u32 copy_mem(u32 src, u32 bytes)
>  {
>      u32 dst, dst_ret;
> @@ -65,13 +82,11 @@ static u32 copy_string(u32 src)
>      return copy_mem(src, p - src + 1);
>  }
>  
> -multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline)
> +static multiboot_info_t *mbi_reloc(u32 mbi_in)
>  {
>      int i;
>      multiboot_info_t *mbi_out;
>  
> -    alloc = trampoline;
> -
>      mbi_out = _p(copy_mem(mbi_in, sizeof(*mbi_out)));
>  
>      if ( mbi_out->flags & MBI_CMDLINE )
> @@ -108,3 +123,126 @@ multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline)
>  
>      return mbi_out;
>  }
> +
> +static multiboot_info_t *mbi2_reloc(u32 mbi_in)
> +{
> +    const multiboot2_fixed_t *mbi_fix = _p(mbi_in);
> +    const multiboot2_memory_map_t *mmap_src;
> +    const multiboot2_tag_t *tag;
> +    module_t *mbi_out_mods = NULL;
> +    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 = _p(ptr);
> +    zero_mem(ptr, sizeof(*mbi_out));
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN);
> +
> +    /* Get the number of modules. */
> +    for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size;
> +          tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) )
> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> +            ++mbi_out->mods_count;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> +            break;
> +    }
> +
> +    if ( mbi_out->mods_count )
> +    {
> +        mbi_out->flags |= MBI_MODULES;
> +        mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(*mbi_out_mods));
> +        mbi_out_mods = _p(mbi_out->mods_addr);
> +    }
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN);
> +
> +    /* Put all needed data into mbi_out. */
> +    for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size;
> +          tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) )
> +        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:
> +            if ( get_mb2_data(tag, mmap, entry_size) < sizeof(*mmap_src) )
> +                break;
> +
> +            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(*mmap_dst);
> +
> +            mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length);
> +
> +            mmap_src = get_mb2_data(tag, mmap, entries);
> +            mmap_dst = _p(mbi_out->mmap_addr);
> +
> +            for ( i = 0; i < mbi_out->mmap_length / sizeof(*mmap_dst); i++ )
> +            {
> +                /* Init size member properly. */
> +                mmap_dst[i].size = sizeof(*mmap_dst);
> +                mmap_dst[i].size -= sizeof(mmap_dst[i].size);
> +                /* Now copy a given region data. */
> +                mmap_dst[i].base_addr_low = (u32)mmap_src->addr;
> +                mmap_dst[i].base_addr_high = (u32)(mmap_src->addr >> 32);
> +                mmap_dst[i].length_low = (u32)mmap_src->len;
> +                mmap_dst[i].length_high = (u32)(mmap_src->len >> 32);
> +                mmap_dst[i].type = mmap_src->type;
> +                mmap_src = _p(mmap_src) + get_mb2_data(tag, mmap, entry_size);
> +            }
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MODULE:
> +            if ( mod_idx >= mbi_out->mods_count )
> +                break;
> +
> +            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;
> +        }
> +
> +    return mbi_out;
> +}
> +
> +multiboot_info_t __stdcall *reloc(u32 mb_magic, u32 mbi_in, u32 trampoline)
> +{
> +    alloc = trampoline;
> +
> +    if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC )
> +        return mbi2_reloc(mbi_in);
> +    else
> +        return mbi_reloc(mbi_in);
> +}
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index 64905c6..b437a8f 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 " */<==\"" \
> @@ -167,6 +168,14 @@ 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_fixed_total_size, multiboot2_fixed_t, total_size);
> +    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);
> +    BLANK();
>  
>      OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
>  }
> diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
> new file mode 100644
> index 0000000..8dd5800
> --- /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

Nitpicky but it would be nice if these lined up.

> +#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[];
> +} 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[];
> +} 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[];
> +} multiboot2_tag_module_t;
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* __MULTIBOOT2_H__ */
> 


-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms...
  2016-12-07 13:18   ` Jan Beulich
  2016-12-07 17:25     ` Daniel Kiper
@ 2017-01-10  1:24     ` Doug Goldstein
  2017-01-10  8:21       ` Jan Beulich
  1 sibling, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10  1:24 UTC (permalink / raw)
  To: Jan Beulich, Daniel Kiper
  Cc: Juergen Gross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 394 bytes --]

On 12/7/16 7:18 AM, Jan Beulich wrote:
>>>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
>> ..nor EFI platforms with runtime services enabled.
> 
> Btw, was the title meant to read "... neither on non-EFI platforms ..."?
> 
> Jan
> 

Could we reduce the amount of negatives?

"disallow EFI reboot method on EFI platforms without runtime services"

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2016-12-05 22:25 ` [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
  2016-12-16 13:38   ` Andrew Cooper
@ 2017-01-10  1:37   ` Doug Goldstein
  2017-01-10 20:51     ` Doug Goldstein
  2017-01-11 19:08     ` Daniel Kiper
  1 sibling, 2 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10  1:37 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 25887 bytes --]

On 12/5/16 4:25 PM, Daniel Kiper wrote:
> 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>
> ---
> v10 - suggestions/fixes:
>     - replace ljmpl with lretq
>       (suggested by Andrew Cooper),
>     - introduce efi_platform to increase code readability
>       (suggested by Andrew Cooper).
> 
> v9 - suggestions/fixes:
>    - use .L labels instead of numeric ones in multiboot2 data scanning loops
>      (suggested by Jan Beulich).
> 
> v8 - suggestions/fixes:
>    - use __bss_start(%rip)/__bss_end(%rip) instead of
>      of .startof.(.bss)(%rip)/$.sizeof.(.bss) because
>      latter is not tested extensively in different
>      built environments yet
>      (suggested by Andrew Cooper),
>    - fix multiboot2 data scanning loop in x86_32 code
>      (suggested by Jan Beulich),
>    - add check for extra mem for mbi data if Xen is loaded
>      via multiboot2 protocol on EFI platform
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich).
> 
> v7 - suggestions/fixes:
>    - do not allocate twice memory for trampoline if we were
>      loaded via multiboot2 protocol on EFI platform,
>    - wrap long line
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich).
> 
> v6 - suggestions/fixes:
>    - improve label names in assembly
>      error printing code
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich),
>    - various minor cleanups and fixes
>      (suggested by Jan Beulich).
> 
> v4 - suggestions/fixes:
>    - remove redundant BSS alignment,
>    - update BSS alignment check,
>    - use __set_bit() instead of set_bit() if possible
>      (suggested by Jan Beulich),
>    - call efi_arch_cpu() from efi_multiboot2()
>      even if the same work is done later in
>      other place right now
>      (suggested by Jan Beulich),
>    - xen/arch/x86/efi/stub.c:efi_multiboot2()
>      fail properly on EFI platforms,
>    - do not read data beyond the end of multiboot2
>      information in xen/arch/x86/boot/head.S
>      (suggested by Jan Beulich),
>    - use 32-bit registers in x86_64 code if possible
>      (suggested by Jan Beulich),
>    - multiboot2 information address is 64-bit
>      in x86_64 code, so, treat it is as is
>      (suggested by Jan Beulich),
>    - use cmovcc if possible,
>    - leave only one space between rep and stosq
>      (suggested by Jan Beulich),
>    - improve error handling,
>    - improve early error messages,
>      (suggested by Jan Beulich),
>    - improve early error messages printing code,
>    - improve label names
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich),
>    - various minor cleanups.
> 
> 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).
> 
> 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          |  263 ++++++++++++++++++++++++++++++++++---
>  xen/arch/x86/efi/efi-boot.h       |   54 +++++++-
>  xen/arch/x86/efi/stub.c           |   38 ++++++
>  xen/arch/x86/x86_64/asm-offsets.c |    2 +
>  xen/arch/x86/xen.lds.S            |    4 +-
>  xen/common/efi/boot.c             |   11 ++
>  6 files changed, 349 insertions(+), 23 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index d423fd8..ac93df0 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)
>  .Lmultiboot2_header_end:
> @@ -100,20 +107,48 @@ multiboot2_header_start:
>  gdt_boot_descr:
>          .word   6*8-1
>          .long   sym_phys(trampoline_gdt)
> +        .long   0 /* Needed for 64-bit lgdt */
> +
> +        .align 4
> +vga_text_buffer:
> +        .long   0xb8000
> +
> +efi_platform:
> +        .byte   0
>  
>  .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
>  .Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
> +.Lbad_ldr_nbs: .asciz "ERR: Bootloader shutdown EFI x64 boot services!"
> +.Lbad_ldr_nst: .asciz "ERR: EFI SystemTable is not provided by bootloader!"
> +.Lbad_ldr_nih: .asciz "ERR: EFI ImageHandle is not provided by bootloader!"
> +.Lbad_efi_msg: .asciz "ERR: EFI IA-32 platforms are not supported!"
>  
>          .section .init.text, "ax", @progbits
>  
>  bad_cpu:
>          mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> -        jmp     print_err
> +        jmp     .Lget_vtb
>  not_multiboot:
>          mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> -print_err:
> -        mov     $0xB8000,%edi  # VGA framebuffer
> -1:      mov     (%esi),%bl
> +        jmp     .Lget_vtb
> +.Lmb2_no_st:
> +        mov     $(sym_phys(.Lbad_ldr_nst)),%esi # Error message
> +        jmp     .Lget_vtb
> +.Lmb2_no_ih:
> +        mov     $(sym_phys(.Lbad_ldr_nih)),%esi # Error message
> +        jmp     .Lget_vtb
> +.Lmb2_no_bs:
> +        mov     $(sym_phys(.Lbad_ldr_nbs)),%esi # Error message
> +        xor     %edi,%edi                       # No VGA text buffer
> +        jmp     .Lsend_chr
> +.Lmb2_efi_ia_32:
> +        mov     $(sym_phys(.Lbad_efi_msg)),%esi # Error message
> +        xor     %edi,%edi                       # No VGA text buffer
> +        jmp     .Lsend_chr
> +.Lget_vtb:
> +        mov     sym_phys(vga_text_buffer),%edi
> +.Lsend_chr:
> +        mov     (%esi),%bl
>          test    %bl,%bl        # Terminate on '\0' sentinel
>          je      .Lhalt
>          mov     $0x3f8+5,%dx   # UART Line Status Register
> @@ -123,13 +158,186 @@ print_err:
>          mov     $0x3f8+0,%dx   # UART Transmit Holding Register
>          mov     %bl,%al
>          out     %al,%dx        # Send a character over the serial line
> -        movsb                  # Write a character to the VGA framebuffer
> +        test    %edi,%edi      # Is the VGA text buffer available?
> +        jz      .Lsend_chr
> +        movsb                  # Write a character to the VGA text buffer
>          mov     $7,%al
> -        stosb                  # Write an attribute to the VGA framebuffer
> -        jmp     1b
> +        stosb                  # Write an attribute to the VGA text buffer
> +        jmp     .Lsend_chr
>  .Lhalt: hlt
>          jmp     .Lhalt
>  
> +        .code64
> +
> +__efi64_start:
> +        cld
> +
> +        /* VGA is not available on EFI platforms. */
> +        movl   $0,vga_text_buffer(%rip)
> +
> +        /* Check for Multiboot2 bootloader. */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      .Lefi_multiboot2_proto
> +
> +        /* Jump to not_multiboot after switching CPU to x86_32 mode. */
> +        lea     not_multiboot(%rip),%edi
> +        jmp     x86_32_switch
> +
> +.Lefi_multiboot2_proto:
> +        /* Zero EFI SystemTable and EFI ImageHandle addresses. */
> +        xor     %esi,%esi
> +        xor     %edi,%edi
> +
> +        /* Skip Multiboot2 information fixed part. */
> +        lea     (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +
> +.Lefi_mb2_tsize:
> +        /* Check Multiboot2 information total size. */
> +        mov     %ecx,%r8d
> +        sub     %ebx,%r8d
> +        cmp     %r8d,MB2_fixed_total_size(%rbx)
> +        jbe     run_bs
> +
> +        /* Are EFI boot services available? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI_BS,MB2_tag_type(%rcx)
> +        jne     .Lefi_mb2_st
> +
> +        /* We are on EFI platform and EFI boot services are available. */
> +        incb    efi_platform(%rip)
> +
> +        /*
> +         * Disable real mode and other legacy stuff which should not
> +         * be run on EFI platforms.
> +         */
> +        incb    skip_realmode(%rip)
> +        jmp     .Lefi_mb2_next_tag
> +
> +.Lefi_mb2_st:
> +        /* Get EFI SystemTable address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
> +        cmove   MB2_efi64_st(%rcx),%rsi
> +        je      .Lefi_mb2_next_tag
> +
> +        /* Get EFI ImageHandle address from Multiboot2 information. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
> +        cmove   MB2_efi64_ih(%rcx),%rdi
> +        je      .Lefi_mb2_next_tag
> +
> +        /* Is it the end of Multiboot2 information? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
> +        je      run_bs
> +
> +.Lefi_mb2_next_tag:
> +        /* Go to next Multiboot2 information tag. */
> +        add     MB2_tag_size(%rcx),%ecx
> +        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        jmp     .Lefi_mb2_tsize
> +
> +run_bs:
> +        /* Are EFI boot services available? */
> +        cmpb    $0,efi_platform(%rip)
> +        jnz     0f
> +
> +        /* Jump to .Lmb2_no_bs after switching CPU to x86_32 mode. */
> +        lea     .Lmb2_no_bs(%rip),%edi
> +        jmp     x86_32_switch
> +
> +0:
> +        /* Is EFI SystemTable address provided by boot loader? */
> +        test    %rsi,%rsi
> +        jnz     1f
> +
> +        /* Jump to .Lmb2_no_st after switching CPU to x86_32 mode. */
> +        lea     .Lmb2_no_st(%rip),%edi
> +        jmp     x86_32_switch
> +
> +1:
> +        /* Is EFI ImageHandle address provided by boot loader? */
> +        test    %rdi,%rdi
> +        jnz     2f
> +
> +        /* Jump to .Lmb2_no_ih after switching CPU to x86_32 mode. */
> +        lea     .Lmb2_no_ih(%rip),%edi
> +        jmp     x86_32_switch
> +
> +2:
> +        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),%edi
> +        lea     __bss_end(%rip),%ecx
> +        sub     %edi,%ecx
> +        shr     $3,%ecx
> +        xor     %eax,%eax
> +        rep stosq
> +
> +        pop     %rdi
> +
> +        /*
> +         * efi_multiboot2() is called according to System V AMD64 ABI:
> +         *   - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable,
> +         *   - OUT: %rax - highest usable memory address below 1 MiB;
> +         *                 memory above this address is reserved for trampoline;
> +         *                 memory below this address is used as a storage for
> +         *                 mbi struct created in reloc().
> +         *
> +         * 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,%eax
> +        mov     %eax,%ecx
> +
> +        pop     %rax
> +
> +        /* Jump to trampoline_setup after switching CPU to x86_32 mode. */
> +        lea     trampoline_setup(%rip),%edi
> +
> +x86_32_switch:
> +        cli
> +
> +        /* Initialize GDTR. */
> +        lgdt    gdt_boot_descr(%rip)
> +
> +        /* Reload code selector. */
> +        pushq   $BOOT_CS32
> +        lea     cs32_switch(%rip),%edx
> +        push    %rdx
> +        lretq
> +
> +        .code32
> +
> +cs32_switch:
> +        /* Initialize basic data segments. */
> +        mov     $BOOT_DS,%edx
> +        mov     %edx,%ds
> +        mov     %edx,%es
> +        mov     %edx,%ss
> +        /* %esp is initialized 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 +365,7 @@ __start:
>  
>          /* Not available? BDA value will be fine. */
>          cmovnz  MB_mem_lower(%ebx),%edx
> -        jmp     trampoline_setup
> +        jmp     trampoline_bios_setup
>  
>  .Lmultiboot2_proto:
>          /* Skip Multiboot2 information fixed part. */
> @@ -169,24 +377,33 @@ __start:
>          mov     %ecx,%edi
>          sub     %ebx,%edi
>          cmp     %edi,MB2_fixed_total_size(%ebx)
> -        jbe     trampoline_setup
> +        jbe     trampoline_bios_setup
>  
>          /* Get mem_lower from Multiboot2 information. */
>          cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
>          cmove   MB2_mem_lower(%ecx),%edx
> -        je      trampoline_setup
> +        je      .Lmb2_next_tag
> +
> +        /* EFI IA-32 platforms are not supported. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
> +        je      .Lmb2_efi_ia_32
> +
> +        /* Bootloader shutdown EFI x64 boot services. */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%ecx)
> +        je      .Lmb2_no_bs
>  
>          /* Is it the end of Multiboot2 information? */
>          cmpl    $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
> -        je      trampoline_setup
> +        je      trampoline_bios_setup
>  
> +.Lmb2_next_tag:
>          /* 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     .Lmb2_tsize
>  
> -trampoline_setup:
> +trampoline_bios_setup:
>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> @@ -202,16 +419,19 @@ 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 */
> +        /* Reserve 64kb for the trampoline. */
>          sub     $0x1000,%ecx
>  
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
>          xor     %cl, %cl
> +
> +trampoline_setup:
> +        /* Save trampoline address for later use. */
>          shl     $4, %ecx
>          mov     %ecx,sym_phys(trampoline_phys)
>  
> @@ -223,7 +443,14 @@ trampoline_setup:
>          call    reloc
>          mov     %eax,sym_phys(multiboot_ptr)
>  
> -        /* Initialize BSS (no nasty surprises!) */
> +        /*
> +         * Do not zero BSS on EFI platform here.
> +         * It was initialized earlier.
> +         */
> +        cmpb    $0,sym_phys(efi_platform)
> +        jnz     1f
> +
> +        /* Initialize BSS (no nasty surprises!). */
>          mov     $sym_phys(__bss_start),%edi
>          mov     $sym_phys(__bss_end),%ecx
>          sub     %edi,%ecx
> @@ -231,6 +458,7 @@ trampoline_setup:
>          shr     $2,%ecx
>          rep stosl
>  
> +1:
>          /* Interrogate CPU extended features via CPUID. */
>          mov     $0x80000000,%eax
>          cpuid
> @@ -282,8 +510,13 @@ trampoline_setup:
>          cmp     $sym_phys(__trampoline_seg_stop),%edi
>          jb      1b
>  
> +        /* Do not parse command line on EFI platform here. */
> +        cmpb    $0,sym_phys(efi_platform)
> +        jnz     1f
> +
>          call    cmdline_parse_early
>  
> +1:
>          /* Switch to low-memory stack.  */
>          mov     sym_phys(trampoline_phys),%edi
>          lea     0x10000(%edi),%esp
> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> index 62c010e..dc857d8 100644
> --- a/xen/arch/x86/efi/efi-boot.h
> +++ b/xen/arch/x86/efi/efi-boot.h
> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>  {
>      struct e820entry *e;
>      unsigned int i;
> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);

Just wondering where the constant came from? And if there should be a
little bit of information about it. To me its just weird to shift 64.

>  
>      /* Populate E820 table and check trampoline area availability. */
>      e = e820map - 1;
> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>              /* fall through */
>          case EfiConventionalMemory:
>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> +                 len >= cfg.size + extra_mem &&
> +                 desc->PhysicalStart + len > cfg.addr )
>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;

So this is where the current series blows up and fails on real hardware.
No where in the EFI + MB2 code path is cfg.size ever initialized. Its
only initialized in the straight EFI case. The result is that cfg.addr
is set to the section immediately following this. Took a bit to
trackdown because I checked for memory overlaps with where Xen was
loaded and where it was relocated to but forgot to check for overlaps
with the trampoline code. This is the address where the trampoline jumps
are copied.

Personally I'd like to see an ASSERT added or the code swizzled around
in such a way that its not possible to get into a bad state. But this is
probably another patch series.

>              /* fall through */
>          case EfiLoaderCode:
> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>  
>  static void __init efi_arch_pre_exit_boot(void)
>  {
> -    if ( !trampoline_phys )
> -    {
> -        if ( !cfg.addr )
> -            blexit(L"No memory for trampoline");
> +    if ( trampoline_phys )
> +        return;
> +
> +    if ( !cfg.addr )
> +        blexit(L"No memory for trampoline");
> +
> +    if ( efi_enabled(EFI_LOADER) )
>          relocate_trampoline(cfg.addr);
> -    }
>  }
>  
>  static void __init noreturn efi_arch_post_exit_boot(void)
> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
> +    __set_bit(EFI_RS, &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();
> +
> +    efi_tables();
> +    setup_efi_pci();
> +    efi_variables();

This is probably where you missed the call to "efi_arch_memory_setup();"
that gave me hell above.


> +
> +    if ( gop )
> +        efi_set_gop_mode(gop, gop_mode);
> +
> +    efi_exit_boot(ImageHandle, SystemTable);
> +
> +    /* Return highest usable 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 4158124..6ea6aa1 100644
> --- a/xen/arch/x86/efi/stub.c
> +++ b/xen/arch/x86/efi/stub.c
> @@ -3,6 +3,44 @@
>  #include <xen/init.h>
>  #include <xen/lib.h>
>  #include <asm/page.h>
> +#include <asm/efibind.h>
> +#include <efi/efidef.h>
> +#include <efi/eficapsule.h>
> +#include <efi/eficon.h>
> +#include <efi/efidevp.h>
> +#include <efi/efiapi.h>
> +
> +/*
> + * Here we are in EFI stub. EFI calls are not supported due to lack
> + * of relevant functionality in compiler and/or linker.
> + *
> + * efi_multiboot2() is an exception. Please look below for more details.
> + */
> +
> +paddr_t __init noreturn efi_multiboot2(EFI_HANDLE ImageHandle,
> +                                       EFI_SYSTEM_TABLE *SystemTable)
> +{
> +    CHAR16 *err = L"Xen does not have EFI code build in!!!\r\nSystem halted!!!\r\n";
> +    SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
> +
> +    StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
> +
> +    /*
> +     * Print error message and halt the system.
> +     *
> +     * We have to open code MS x64 calling convention
> +     * in assembly because here this convention may
> +     * not be directly supported by C compiler.
> +     */
> +    asm volatile(
> +    "    call %2                      \n"
> +    "0:  hlt                          \n"
> +    "    jmp  0b                      \n"
> +       : "+c" (StdErr), "+d" (err) : "g" (StdErr->OutputString)
> +       : "rax", "r8", "r9", "r10", "r11", "memory");
> +
> +    unreachable();
> +}
>  
>  bool efi_enabled(unsigned int feature)
>  {
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index b437a8f..2a22659 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -175,6 +175,8 @@ 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);
>      BLANK();
>  
>      OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index b0b1c9b..e0e2529 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -331,5 +331,5 @@ ASSERT(IS_ALIGNED(__init_end,   PAGE_SIZE), "__init_end misaligned")
>  
>  ASSERT(IS_ALIGNED(trampoline_start, 4), "trampoline_start misaligned")
>  ASSERT(IS_ALIGNED(trampoline_end,   4), "trampoline_end misaligned")
> -ASSERT(IS_ALIGNED(__bss_start,      4), "__bss_start misaligned")
> -ASSERT(IS_ALIGNED(__bss_end,        4), "__bss_end misaligned")
> +ASSERT(IS_ALIGNED(__bss_start,      8), "__bss_start misaligned")
> +ASSERT(IS_ALIGNED(__bss_end,        8), "__bss_end misaligned")
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index 0a93e61..70ed836 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;
> 

So as an aside, IMHO this is where the series should end and the next
set of patches should be a follow on.
-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 11/13] x86: make Xen early boot code relocatable
  2016-12-05 22:25 ` [PATCH v11 11/13] x86: make Xen early boot code relocatable Daniel Kiper
@ 2017-01-10  2:05   ` Doug Goldstein
  2017-01-11 20:05     ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10  2:05 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 24498 bytes --]

On 12/5/16 4:25 PM, Daniel Kiper wrote:
> Every multiboot protocol (regardless of version) compatible image must
> specify its load address (in ELF or multiboot header). Multiboot protocol
> compatible loader have to load image at specified address. However, there
> is no guarantee that the requested memory region (in case of Xen it starts
> at 2 MiB and ends at ~5 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 and help boot loader to
> relocate image in proper way by suggesting, not requesting specific load
> addresses as it is right now, allowed address ranges. This patch does former.
> 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:
>   - %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 in 32-bit code
>     and %r15d in 64-bit code),
>   - %fs is used as base for Xen data relative addressing in 32-bit code
>     if it is possible; %esi is used for that thing during error printing
>     because it is not always possible to properly and efficiently
>     initialize %fs.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
> v8 - suggestions/fixes:
>    - use shld instead of mov and shr in BOOT_FS segment
>      descriptor base address initialization
>      (suggested by Jan Beulich),
>    - simplify code updating frame addresses in page tables
>      (suggested by Jan Beulich),
>    - print Xen image base addresses using "%#lx" format
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich).
> 
> v6 - suggestions/fixes:
>    - leave static mapping of first
>      16 MiB in l2_identmap as is
>      (suggested by Jan Beulich),
>    - use xen_phys_start instead of xen_img_load_base_addr
>      (suggested by Daniel Kiper and Jan Beulich),
>    - simplify BOOT_FS segment descriptor
>      base address initialization
>      (suggested by Jan Beulich),
>    - fix BOOT_FS segment limit
>      (suggested by Jan Beulich),
>    - do not rename sym_phys in this patch
>      (suggested by Jan Beulich),
>    - rename esi_offset/fs_offset to
>      sym_esi/sym_fs respectively
>      (suggested by Jan Beulich),
>    - use add instead of lea in assembly
>      error printing code
>      (suggested by Jan Beulich),
>    - improve comments
>      (suggested by Jan Beulich),
>    - improve commit message
>      (suggested by Jan Beulich),
>    - various minor cleanups and fixes
>      (suggested by Jan Beulich).
> 
> v4 - suggestions/fixes:
>    - do not relocate Xen image if boot loader did work for us
>      (suggested by Andrew Cooper and Jan Beulich),
>    - initialize xen_img_load_base_addr in EFI boot code too,
>    - properly initialize trampoline_xen_phys_start,
>    - calculate Xen image load base address in
>      x86_64 code ourselves,
>      (suggested by Jan Beulich),
>    - change how and when Xen image base address is printed,
>    - use %fs instead of %esi for relative addressing
>      (suggested by Andrew Cooper and Jan Beulich),
>    - create esi_offset and fs_offset() macros in assembly,
>    - calculate <final-exec-addr> mkelf32 argument automatically,
>    - optimize and cleanup code,
>    - improve comments,
>    - improve commit message.
> 
> 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).
> ---
>  xen/arch/x86/boot/head.S          |  160 +++++++++++++++++++++++++++++--------
>  xen/arch/x86/boot/trampoline.S    |    5 ++
>  xen/arch/x86/boot/x86_64.S        |   21 +++--
>  xen/arch/x86/setup.c              |   14 ++--
>  xen/arch/x86/x86_64/asm-offsets.c |    3 +
>  xen/include/asm-x86/page.h        |    2 +-
>  6 files changed, 155 insertions(+), 50 deletions(-)
> 
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index a7bc467..d992a95 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -13,12 +13,15 @@
>          .code32
>  
>  #define sym_phys(sym)     ((sym) - __XEN_VIRT_START)
> +#define sym_esi(sym)      sym_phys(sym)(%esi)
> +#define sym_fs(sym)       %fs:sym_phys(sym)
>  
>  #define BOOT_CS32        0x0008
>  #define BOOT_CS64        0x0010
>  #define BOOT_DS          0x0018
>  #define BOOT_PSEUDORM_CS 0x0020
>  #define BOOT_PSEUDORM_DS 0x0028
> +#define BOOT_FS          0x0030
>  
>  #define MB2_HT(name)      (MULTIBOOT2_HEADER_TAG_##name)
>  #define MB2_TT(name)      (MULTIBOOT2_TAG_TYPE_##name)
> @@ -105,7 +108,8 @@ multiboot2_header_start:
>  
>          .word   0
>  gdt_boot_descr:
> -        .word   6*8-1
> +        .word   7*8-1
> +gdt_boot_base:
>          .long   sym_phys(trampoline_gdt)
>          .long   0 /* Needed for 64-bit lgdt */
>  
> @@ -126,27 +130,27 @@ efi_platform:
>          .section .init.text, "ax", @progbits
>  
>  bad_cpu:
> -        mov     $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
> +        add     $sym_phys(.Lbad_cpu_msg),%esi   # Error message
>          jmp     .Lget_vtb
>  not_multiboot:
> -        mov     $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
> +        add     $sym_phys(.Lbad_ldr_msg),%esi   # Error message
>          jmp     .Lget_vtb
>  .Lmb2_no_st:
> -        mov     $(sym_phys(.Lbad_ldr_nst)),%esi # Error message
> +        add     $sym_phys(.Lbad_ldr_nst),%esi   # Error message
>          jmp     .Lget_vtb
>  .Lmb2_no_ih:
> -        mov     $(sym_phys(.Lbad_ldr_nih)),%esi # Error message
> +        add     $sym_phys(.Lbad_ldr_nih),%esi   # Error message
>          jmp     .Lget_vtb
>  .Lmb2_no_bs:
> -        mov     $(sym_phys(.Lbad_ldr_nbs)),%esi # Error message
> +        add     $sym_phys(.Lbad_ldr_nbs),%esi   # Error message
>          xor     %edi,%edi                       # No VGA text buffer
>          jmp     .Lsend_chr
>  .Lmb2_efi_ia_32:
> -        mov     $(sym_phys(.Lbad_efi_msg)),%esi # Error message
> +        add     $sym_phys(.Lbad_efi_msg),%esi   # Error message
>          xor     %edi,%edi                       # No VGA text buffer
>          jmp     .Lsend_chr
>  .Lget_vtb:
> -        mov     sym_phys(vga_text_buffer),%edi
> +        mov     sym_esi(vga_text_buffer),%edi
>  .Lsend_chr:
>          mov     (%esi),%bl
>          test    %bl,%bl        # Terminate on '\0' sentinel
> @@ -175,6 +179,9 @@ __efi64_start:
>          /* VGA is not available on EFI platforms. */
>          movl   $0,vga_text_buffer(%rip)
>  
> +        /* Load Xen image load base address. */
> +        lea     __image_base__(%rip),%r15d
> +
>          /* Check for Multiboot2 bootloader. */
>          cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
>          je      .Lefi_multiboot2_proto
> @@ -300,6 +307,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),%edi
>  
> @@ -307,6 +317,7 @@ x86_32_switch:
>          cli
>  
>          /* Initialize GDTR. */
> +        add     %esi,gdt_boot_base(%rip)
>          lgdt    gdt_boot_descr(%rip)
>  
>          /* Reload code selector. */
> @@ -342,12 +353,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_phys(__image_base__),%esi
>  
>          /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
>          xor     %edx,%edx
> @@ -404,6 +411,25 @@ __start:
>          jmp     .Lmb2_tsize
>  
>  trampoline_bios_setup:
> +        /*
> +         * Called on legacy BIOS platforms only.
> +         *
> +         * Initialize GDTR and basic data segments.
> +         */
> +        add     %esi,sym_esi(gdt_boot_base)
> +        lgdt    sym_esi(gdt_boot_descr)
> +
> +        mov     $BOOT_DS,%ecx
> +        mov     %ecx,%ds
> +        mov     %ecx,%es
> +        mov     %ecx,%ss
> +        /* %esp is initialized 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) */
> @@ -431,32 +457,64 @@ trampoline_bios_setup:
>          xor     %cl, %cl
>  
>  trampoline_setup:
> +        /*
> +         * Called on legacy BIOS and EFI platforms.
> +         *
> +         * Initialize 0-15 bits of BOOT_FS segment descriptor base address.
> +         */
> +        mov     %si,BOOT_FS+2+sym_esi(trampoline_gdt)
> +
> +        /* Initialize 16-23 bits of BOOT_FS segment descriptor base address. */
> +        shld    $16,%esi,%edx
> +        mov     %dl,BOOT_FS+4+sym_esi(trampoline_gdt)
> +
> +        /* Initialize 24-31 bits of BOOT_FS segment descriptor base address. */
> +        mov     %dh,BOOT_FS+7+sym_esi(trampoline_gdt)
> +
> +        /*
> +         * Initialize %fs and later use it to access Xen data if possible.
> +         * According to Intel 64 and IA-32 Architectures Software Developer's
> +         * Manual it is safe to do that without reloading GDTR before.
> +         */
> +        mov     $BOOT_FS,%edx
> +        mov     %edx,%fs
> +
>          /* Save trampoline address for later use. */
>          shl     $4, %ecx
> -        mov     %ecx,sym_phys(trampoline_phys)
> +        mov     %ecx,sym_fs(trampoline_phys)
> +
> +        /* Save Xen image load base address for later use. */
> +        mov     %esi,sym_fs(xen_phys_start)
> +        mov     %esi,sym_fs(trampoline_xen_phys_start)
> +
> +        /* Setup stack. %ss was initialized earlier. */
> +        lea     1024+sym_esi(cpu0_stack),%esp

Not sure if this is the bad code or what but after this patch in the
series the stack is at 0xAD000 which is in the middle of VGA memory so
the stack is getting screwy (hence my email last week). And the stack is
bad in trampoline_setup, before trampoline_setup the stack seems fine.

This is from my hacked up version of iPXE...

Type / Addr / Number of Pages / Flags

Conventional: 0x000059000 :      69 : f
Reserved:     0x00009e000 :       2 : f
Conventional: 0x000100000 :   65280 : f

As you can see from 0xA0000 to 0x100000 isn't mentioned but everything I
can find on EFI says if the range isn't mentioned you shouldn't use it.


>  
>          /* 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
> -        mov     %eax,sym_phys(multiboot_ptr)
> +        mov     %eax,sym_fs(multiboot_ptr)
>  
>          /*
>           * Do not zero BSS on EFI platform here.
>           * It was initialized earlier.
>           */
> -        cmpb    $0,sym_phys(efi_platform)
> +        cmpb    $0,sym_fs(efi_platform)
>          jnz     1f
>  
>          /* Initialize BSS (no nasty surprises!). */
>          mov     $sym_phys(__bss_start),%edi
>          mov     $sym_phys(__bss_end),%ecx
> +        push    %fs
> +        pop     %es
>          sub     %edi,%ecx
>          xor     %eax,%eax
>          shr     $2,%ecx
>          rep stosl
> +        push    %ds
> +        pop     %es
>  
>  1:
>          /* Interrogate CPU extended features via CPUID. */
> @@ -470,8 +528,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_fs(cpuid_ext_features)
> +        mov     %edx,sym_fs(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
>  
>          /* Check for availability of long mode. */
>          bt      $cpufeat_bit(X86_FEATURE_LM),%edx
> @@ -479,15 +537,52 @@ 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_fs(boot_tsc_stamp)
> +        mov     %edx,sym_fs(boot_tsc_stamp)+4
> +
> +        /*
> +         * Update frame addresses in page tables excluding l2_identmap
> +         * without its first entry which points to l1_identmap.
> +         */
> +        mov     $((__page_tables_end-__page_tables_start)/8),%ecx
> +        mov     $(((l2_identmap-__page_tables_start)/8)+1),%edx
> +1:      cmp     $((l2_identmap+l2_identmap_sizeof-__page_tables_start)/8),%ecx
> +        cmove   %edx,%ecx
> +        testl   $_PAGE_PRESENT,sym_fs(__page_tables_start)-8(,%ecx,8)
> +        jz      2f
> +        add     %esi,sym_fs(__page_tables_start)-8(,%ecx,8)
> +2:      loop    1b
> +
> +        /* Initialize L2 boot-map/direct map page table entries (16MB). */
> +        lea     sym_esi(start),%ebx
> +        lea     (1<<L2_PAGETABLE_SHIFT)*7+(PAGE_HYPERVISOR|_PAGE_PSE)(%ebx),%eax
> +        shr     $(L2_PAGETABLE_SHIFT-3),%ebx
> +        mov     $8,%ecx
> +1:      mov     %eax,sym_fs(l2_bootmap)-8(%ebx,%ecx,8)
> +        mov     %eax,sym_fs(l2_identmap)-8(%ebx,%ecx,8)
> +        sub     $(1<<L2_PAGETABLE_SHIFT),%eax
> +        loop    1b
> +
> +        /* Initialize L3 boot-map page directory entry. */
> +        lea     __PAGE_HYPERVISOR+(L2_PAGETABLE_ENTRIES*8)*3+sym_esi(l2_bootmap),%eax
> +        mov     $4,%ecx
> +1:      mov     %eax,sym_fs(l3_bootmap)-8(,%ecx,8)
> +        sub     $(L2_PAGETABLE_ENTRIES*8),%eax
> +        loop    1b
> +
> +        /*
> +         * During boot, hook 4kB mappings of first 2MB of memory into L2.
> +         * This avoids mixing cachability for the legacy VGA region.
> +         */
> +        lea     __PAGE_HYPERVISOR+sym_esi(l1_identmap),%edi
> +        mov     %edi,sym_fs(l2_bootmap)
>  
>          /* Apply relocations to bootstrap trampoline. */
> -        mov     sym_phys(trampoline_phys),%edx
> +        mov     sym_fs(trampoline_phys),%edx
>          mov     $sym_phys(__trampoline_rel_start),%edi
>  1:
> -        mov     (%edi),%eax
> -        add     %edx,(%edi,%eax)
> +        mov     %fs:(%edi),%eax
> +        add     %edx,%fs:(%edi,%eax)
>          add     $4,%edi
>          cmp     $sym_phys(__trampoline_rel_stop),%edi
>          jb      1b
> @@ -496,28 +591,29 @@ trampoline_setup:
>          shr     $4,%edx
>          mov     $sym_phys(__trampoline_seg_start),%edi
>  1:
> -        mov     (%edi),%eax
> -        mov     %dx,(%edi,%eax)
> +        mov     %fs:(%edi),%eax
> +        mov     %dx,%fs:(%edi,%eax)
>          add     $4,%edi
>          cmp     $sym_phys(__trampoline_seg_stop),%edi
>          jb      1b
>  
>          /* Do not parse command line on EFI platform here. */
> -        cmpb    $0,sym_phys(efi_platform)
> +        cmpb    $0,sym_fs(efi_platform)
>          jnz     1f
>  
>          /* Bail if there is no command line to parse. */
> -        mov     sym_phys(multiboot_ptr),%ebx
> +        mov     sym_fs(multiboot_ptr),%ebx
>          testl   $MBI_CMDLINE,MB_flags(%ebx)
>          jz      1f
>  
> -        pushl   $sym_phys(early_boot_opts)
> +        lea     sym_esi(early_boot_opts),%eax
> +        push    %eax
>          pushl   MB_cmdline(%ebx)
>          call    cmdline_parse_early
>  
>  1:
>          /* Switch to low-memory stack.  */
> -        mov     sym_phys(trampoline_phys),%edi
> +        mov     sym_fs(trampoline_phys),%edi
>          lea     0x10000(%edi),%esp
>          lea     trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
>          pushl   $BOOT_CS32
> @@ -526,7 +622,7 @@ trampoline_setup:
>          /* Copy bootstrap trampoline to low memory, below 1MB. */
>          mov     $sym_phys(trampoline_start),%esi
>          mov     $((trampoline_end - trampoline_start) / 4),%ecx
> -        rep movsl
> +        rep movsl %fs:(%esi),%es:(%edi)
>  
>          /* Jump into the relocated trampoline. */
>          lret
> diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
> index 2715d17..64f8efd 100644
> --- a/xen/arch/x86/boot/trampoline.S
> +++ b/xen/arch/x86/boot/trampoline.S
> @@ -54,6 +54,11 @@ trampoline_gdt:
>          /* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
>          .long   0x0000ffff
>          .long   0x00009200
> +        /*
> +         * 0x0030: ring 0 Xen data, 16 MiB size, base
> +         * address is computed during runtime.
> +         */
> +        .quad   0x00c0920000000fff
>  
>          .pushsection .trampoline_rel, "a"
>          .long   trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
> diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
> index 7890374..7392004 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
> @@ -102,6 +101,13 @@ l1_identmap:
>          .size l1_identmap, . - l1_identmap
>  
>  /*
> + * __page_tables_start does not cover l1_identmap because it (l1_identmap)
> + * contains 1-1 mappings. This means that frame addresses of these mappings
> + * are static and should not be updated during runtime.
> + */
> +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.
>   */
> @@ -186,21 +192,14 @@ GLOBAL(idle_pg_table)
>  
>  GLOBAL(__page_tables_end)
>  
> -/* Init pagetables.  Enough page directories to map into the bottom 1GB. */
> +/* Init pagetables. Enough page directories to map into 4GB. */
>          .section .init.data, "a", @progbits
>          .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 5d0830e..561a139 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -330,9 +330,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;
> @@ -716,6 +713,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      printk("Command line: %s\n", cmdline);
>  
> +    printk("Xen image load base address: %#lx\n", xen_phys_start);
> +
>      printk("Video information:\n");
>  
>      /* Print VGA display mode information. */
> @@ -973,7 +972,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                      /* 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);
> @@ -983,7 +982,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                          /* 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);
> @@ -1006,7 +1005,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>              {
>                  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() )
> @@ -1060,6 +1060,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                  : "memory" );
>  
>              bootstrap_map(NULL);
> +
> +            printk("New Xen image base address: %#lx\n", xen_phys_start);
>          }
>  
>          /* Is the region suitable for relocating the multiboot modules? */
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index 2a22659..5d7a8e5 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -179,5 +179,8 @@ void __dummy__(void)
>      OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
>      BLANK();
>  
> +    DEFINE(l2_identmap_sizeof, sizeof(l2_identmap));
> +    BLANK();
> +
>      OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
>  }
> diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
> index af7d3e8..a54fdd1 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_fixmap[L1_PAGETABLE_ENTRIES];
> 


-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms...
  2017-01-10  1:24     ` Doug Goldstein
@ 2017-01-10  8:21       ` Jan Beulich
  0 siblings, 0 replies; 64+ messages in thread
From: Jan Beulich @ 2017-01-10  8:21 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: Juergen Gross, sstabellini, andrew.cooper3, Daniel Kiper,
	pgnet.dev, ning.sun, julien.grall, xen-devel, qiaowei.ren,
	gang.wei, fu.wei

>>> On 10.01.17 at 02:24, <cardoe@cardoe.com> wrote:
> On 12/7/16 7:18 AM, Jan Beulich wrote:
>>>>> On 05.12.16 at 23:25, <daniel.kiper@oracle.com> wrote:
>>> ..nor EFI platforms with runtime services enabled.
>> 
>> Btw, was the title meant to read "... neither on non-EFI platforms ..."?
> 
> Could we reduce the amount of negatives?
> 
> "disallow EFI reboot method on EFI platforms without runtime services"

Well, you're a little late to the party - the patch did go in a month ago.

Jan


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

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

* Re: [PATCH v11 01/13] x86: add multiboot2 protocol support
  2017-01-10  1:21   ` Doug Goldstein
@ 2017-01-10  8:38     ` Jan Beulich
  2017-01-10 15:19       ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2017-01-10  8:38 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: Juergen Gross, sstabellini, andrew.cooper3, Daniel Kiper,
	pgnet.dev, ning.sun, julien.grall, xen-devel, qiaowei.ren,
	gang.wei, fu.wei

>>> On 10.01.17 at 02:21, <cardoe@cardoe.com> wrote:
> On 12/5/16 4:25 PM, Daniel Kiper wrote:
>> +/* 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
> 
> Nitpicky but it would be nice if these lined up.

Well, the question is what tab width you expect them to line up
with - with tab == 8 spaces they do line up for me.

Also - please trim your quotes in replies.

Jan


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

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

* Re: [PATCH v11 01/13] x86: add multiboot2 protocol support
  2017-01-10  8:38     ` Jan Beulich
@ 2017-01-10 15:19       ` Doug Goldstein
  0 siblings, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10 15:19 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Juergen Gross, sstabellini, andrew.cooper3, Daniel Kiper,
	pgnet.dev, ning.sun, julien.grall, xen-devel, qiaowei.ren,
	gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 1147 bytes --]

On 1/10/17 2:38 AM, Jan Beulich wrote:
>>>> On 10.01.17 at 02:21, <cardoe@cardoe.com> wrote:
>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
>>> +/* 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
>>
>> Nitpicky but it would be nice if these lined up.
> 
> Well, the question is what tab width you expect them to line up
> with - with tab == 8 spaces they do line up for me.
> 
> Also - please trim your quotes in replies.
> 
> Jan
> 

Well given that this is a new file and CODING_STYLE says spaces over
tabs and to treat indent level as 4 spaces. That was what my assumption was.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-10  1:37   ` Doug Goldstein
@ 2017-01-10 20:51     ` Doug Goldstein
  2017-01-11 19:47       ` Daniel Kiper
  2017-01-11 19:08     ` Daniel Kiper
  1 sibling, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10 20:51 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 5551 bytes --]

On 1/9/17 7:37 PM, Doug Goldstein wrote:
> On 12/5/16 4:25 PM, Daniel Kiper wrote:

>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
>> index 62c010e..dc857d8 100644
>> --- a/xen/arch/x86/efi/efi-boot.h
>> +++ b/xen/arch/x86/efi/efi-boot.h
>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>  {
>>      struct e820entry *e;
>>      unsigned int i;
>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
> 
> Just wondering where the constant came from? And if there should be a
> little bit of information about it. To me its just weird to shift 64.

Its the size of the stack used in the assembly code.

> 
>>  
>>      /* Populate E820 table and check trampoline area availability. */
>>      e = e820map - 1;
>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>              /* fall through */
>>          case EfiConventionalMemory:
>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
>> +                 len >= cfg.size + extra_mem &&
>> +                 desc->PhysicalStart + len > cfg.addr )
>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
> 
> So this is where the current series blows up and fails on real hardware.

Honestly this was my misunderstanding and this shouldn't ever be used to
get memory for the trampoline. This also has the bug in it that it needs
to be:

ASSERT(cfg.size > 0);
cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;

> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
> only initialized in the straight EFI case. The result is that cfg.addr
> is set to the section immediately following this. Took a bit to
> trackdown because I checked for memory overlaps with where Xen was
> loaded and where it was relocated to but forgot to check for overlaps
> with the trampoline code. This is the address where the trampoline jumps
> are copied.
> 
> Personally I'd like to see an ASSERT added or the code swizzled around
> in such a way that its not possible to get into a bad state. But this is
> probably another patch series.
> 
>>              /* fall through */
>>          case EfiLoaderCode:
>> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>>  
>>  static void __init efi_arch_pre_exit_boot(void)
>>  {
>> -    if ( !trampoline_phys )
>> -    {
>> -        if ( !cfg.addr )
>> -            blexit(L"No memory for trampoline");
>> +    if ( trampoline_phys )
>> +        return;
>> +
>> +    if ( !cfg.addr )
>> +        blexit(L"No memory for trampoline");
>> +
>> +    if ( efi_enabled(EFI_LOADER) )
>>          relocate_trampoline(cfg.addr);

Why is this call even here anymore? Its called in
efi_arch_memory_setup() already. If it was unable to allocate memory
under the 1mb region its just going to trample over ANY conventional
memory region that might be in use.


>> -    }
>>  }
>>  
>>  static void __init noreturn efi_arch_post_exit_boot(void)
>> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
>> +    __set_bit(EFI_RS, &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();
>> +
>> +    efi_tables();
>> +    setup_efi_pci();
>> +    efi_variables();
> 
> This is probably where you missed the call to "efi_arch_memory_setup();"
> that gave me hell above.

Well it turns out that calling "efi_arch_memory_setup()" isn't correct
because it also messes with the page tables AND also does the trampoline
relocation. Which after this call finishes then it does the trampoline
relocations in assembly. The code currently makes the assumption it can
use any conventional memory range below 1mb (and unfortunately does the
math incorrectly and instead uses the region following the conventional
memory region). You need to use AllocatePages() otherwise you are
trampling memory that might have been allocated by the bootloader or any
multiboot modules (e.g. tboot) prior to Xen.

I'm just going to write a patch to fix the issues that I've found thus
far. I believe at this point there is something wrong with the page
tables because setting cr0 for the non-0 CPU in
trampoline_protmode_entry causes the machine to reboot.

I've also found where we have the possibility to call
relocate_trampoline() twice in the EFI case. Its protected by a check to
trampoline_phys but I'm not sure why we even have the code there to be
able to do so.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* [PATCH 2/??] memory allocation fix
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (13 preceding siblings ...)
  2016-12-16 15:59 ` [PATCH v11 00/13] x86: multiboot2 protocol support Doug Goldstein
@ 2017-01-10 23:12 ` Doug Goldstein
  2017-01-11 20:46 ` [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
  2017-01-12 17:46 ` Doug Goldstein
  16 siblings, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-10 23:12 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, Doug Goldstein, pgnet.dev,
	ning.sun, julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

Signed-off-by: Doug Goldstein <cardoe@cardoe.com>

---
Daniel,

Feel free to fold this in where it needs to go or break this up into
a patch (or patches) part of your series. This is what it took for me to
get it to boot on one of my Intel NUCs and to get into the dom0 kernel
booting on my other machines. There's still an issue with the page tables
somewhere I believe because that's where its dying on the other machines.
Writing to cr3 or cr0. QEMU is likely an issue with OVMF or what they're doing.
0x7fb27408 is smack in the middle of ACPI NVS.

(XEN) [    5.506811]    [<000000007fb27408>] 000000007fb27408
(XEN) [    5.509252]    [<ffff82d080235c7b>] vsnprintf+0x7eb/0xb70
(XEN) [    5.511779]    [<ffff82d080277fda>] i387.c#_vcpu_save_fpu+0x8a/0x180
(XEN) [    5.514548]    [<ffff82d080202374>] efi_runtime_call+0xa24/0xac0
(XEN) [    5.517233]    [<ffff82d08020220e>] efi_runtime_call+0x8be/0xac0
(XEN) [    5.519853]    [<ffff82d08025dc41>] avc_has_perm+0x51/0x70
(XEN) [    5.521985]    [<ffff82d080298a1f>] do_platform_op+0x73f/0x16e0
(XEN) [    5.524604]    [<ffff82d080298a1f>] do_platform_op+0x73f/0x16e0
(XEN) [    5.527172]    [<ffff82d08028cb21>] do_mmu_update+0x221/0x12b0
(XEN) [    5.531455]    [<ffff82d0802982e0>] do_platform_op+0/0x16e0
(XEN) [    5.533421]    [<ffff82d080277dc6>] pv_hypercall+0xf6/0x1c0
(XEN) [    5.537808]    [<ffff82d080230c00>] timer.c#timer_softirq_action+0xc0/0x250
(XEN) [    5.543847]    [<ffff82d080230c72>] timer.c#timer_softirq_action+0x132/0x250
(XEN) [    5.546743]    [<ffff82d080326c6e>] entry.o#test_all_events+0/0x2a

This happens right after dom0 spits out:
[    0.368037] PTP clock support registered

As an aside given all the Intel guys CC'd, what's a communication channel I
can use to report issues with the NUC's EFI implementation that's not canned
responses from level 1 tech support?
---
 xen/arch/x86/efi/efi-boot.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index dc857d8..878f683 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -172,7 +172,7 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
             if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
                  len >= cfg.size + extra_mem &&
                  desc->PhysicalStart + len > cfg.addr )
-                cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
+                cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem)) & PAGE_MASK;
             /* fall through */
         case EfiLoaderCode:
         case EfiLoaderData:
@@ -686,6 +686,14 @@ paddr_t __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTa
     setup_efi_pci();
     efi_variables();
 
+    cfg.addr = 0x100000;
+    cfg.size = (trampoline_end - trampoline_start) + (64 << 10);
+    if ( efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
+                PFN_UP(cfg.size), &cfg.addr) != EFI_SUCCESS ) {
+        cfg.addr = 0;
+        PrintStr(L"Trampoline space cannot be allocated; will try fallback.\r\n");
+    }
+
     if ( gop )
         efi_set_gop_mode(gop, gop_mode);
 
-- 
2.10.2


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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-10  1:37   ` Doug Goldstein
  2017-01-10 20:51     ` Doug Goldstein
@ 2017-01-11 19:08     ` Daniel Kiper
  2017-01-11 19:50       ` Doug Goldstein
  2017-01-11 20:31       ` Doug Goldstein
  1 sibling, 2 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-11 19:08 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Mon, Jan 09, 2017 at 07:37:59PM -0600, Doug Goldstein wrote:
> On 12/5/16 4:25 PM, Daniel Kiper wrote:

[...]

> > diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> > index 62c010e..dc857d8 100644
> > --- a/xen/arch/x86/efi/efi-boot.h
> > +++ b/xen/arch/x86/efi/efi-boot.h
> > @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >  {
> >      struct e820entry *e;
> >      unsigned int i;
> > +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
> > +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
>
> Just wondering where the constant came from? And if there should be a
> little bit of information about it. To me its just weird to shift 64.

64 << 10 == 64 KiB which is the size of trampoline region reserved in
xen/arch/x86/boot/head.S. Though I think that we should reserve real
size needed for trampoline code. IIRC, it was discussed here earlier
but there is no go for it in this patch series.

> >      /* Populate E820 table and check trampoline area availability. */
> >      e = e820map - 1;
> > @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >              /* fall through */
> >          case EfiConventionalMemory:
> >              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> > -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> > +                 len >= cfg.size + extra_mem &&
> > +                 desc->PhysicalStart + len > cfg.addr )
> >                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
>
> So this is where the current series blows up and fails on real hardware.
> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
> only initialized in the straight EFI case. The result is that cfg.addr
> is set to the section immediately following this. Took a bit to
> trackdown because I checked for memory overlaps with where Xen was
> loaded and where it was relocated to but forgot to check for overlaps
> with the trampoline code. This is the address where the trampoline jumps
> are copied.
>
> Personally I'd like to see an ASSERT added or the code swizzled around
> in such a way that its not possible to get into a bad state. But this is
> probably another patch series.

Nice catch! Thanks a lot. I think that we should initialize cfg.size = 64 << 10
in efi_multiboot2(). It looks like real fix. extra_mem stuff is bogus.

[...]

> > +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_BOOT, &efi_flags);
> > +    __set_bit(EFI_RS, &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();
> > +
> > +    efi_tables();
> > +    setup_efi_pci();
> > +    efi_variables();
>
> This is probably where you missed the call to "efi_arch_memory_setup();"
> that gave me hell above.

This does not work in MB2 case.

[...]

> > diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> > index 0a93e61..70ed836 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;
> >
>
> So as an aside, IMHO this is where the series should end and the next
> set of patches should be a follow on.

Hmmm... Why? If you do not apply rest of patches then MB2 does not
work on all EFI platforms.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-10 20:51     ` Doug Goldstein
@ 2017-01-11 19:47       ` Daniel Kiper
  2017-01-11 20:20         ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-11 19:47 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
> On 1/9/17 7:37 PM, Doug Goldstein wrote:
> > On 12/5/16 4:25 PM, Daniel Kiper wrote:
>
> >> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> >> index 62c010e..dc857d8 100644
> >> --- a/xen/arch/x86/efi/efi-boot.h
> >> +++ b/xen/arch/x86/efi/efi-boot.h
> >> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>  {
> >>      struct e820entry *e;
> >>      unsigned int i;
> >> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
> >> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
> >
> > Just wondering where the constant came from? And if there should be a
> > little bit of information about it. To me its just weird to shift 64.
>
> Its the size of the stack used in the assembly code.

No, it is trampoline region size.

> >>      /* Populate E820 table and check trampoline area availability. */
> >>      e = e820map - 1;
> >> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>              /* fall through */
> >>          case EfiConventionalMemory:
> >>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> >> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> >> +                 len >= cfg.size + extra_mem &&
> >> +                 desc->PhysicalStart + len > cfg.addr )
> >>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
> >
> > So this is where the current series blows up and fails on real hardware.
>
> Honestly this was my misunderstanding and this shouldn't ever be used to
> get memory for the trampoline. This also has the bug in it that it needs
> to be:
>
> ASSERT(cfg.size > 0);
> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;

As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
in one way or another. Hmmm... It looks OK. I will double check it because
I do not looked at this code long time and maybe I am missing something.

> > No where in the EFI + MB2 code path is cfg.size ever initialized. Its
> > only initialized in the straight EFI case. The result is that cfg.addr
> > is set to the section immediately following this. Took a bit to
> > trackdown because I checked for memory overlaps with where Xen was
> > loaded and where it was relocated to but forgot to check for overlaps
> > with the trampoline code. This is the address where the trampoline jumps
> > are copied.
> >
> > Personally I'd like to see an ASSERT added or the code swizzled around
> > in such a way that its not possible to get into a bad state. But this is
> > probably another patch series.
> >
> >>              /* fall through */
> >>          case EfiLoaderCode:
> >> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
> >>
> >>  static void __init efi_arch_pre_exit_boot(void)
> >>  {
> >> -    if ( !trampoline_phys )
> >> -    {
> >> -        if ( !cfg.addr )
> >> -            blexit(L"No memory for trampoline");
> >> +    if ( trampoline_phys )
> >> +        return;
> >> +
> >> +    if ( !cfg.addr )
> >> +        blexit(L"No memory for trampoline");
> >> +
> >> +    if ( efi_enabled(EFI_LOADER) )
> >>          relocate_trampoline(cfg.addr);
>
> Why is this call even here anymore? Its called in
> efi_arch_memory_setup() already. If it was unable to allocate memory
> under the 1mb region its just going to trample over ANY conventional
> memory region that might be in use.

Trampoline is relocated in xen/arch/x86/boot/head.S.

> >> -    }
> >>  }
> >>
> >>  static void __init noreturn efi_arch_post_exit_boot(void)
> >> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
> >> +    __set_bit(EFI_RS, &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();
> >> +
> >> +    efi_tables();
> >> +    setup_efi_pci();
> >> +    efi_variables();
> >
> > This is probably where you missed the call to "efi_arch_memory_setup();"
> > that gave me hell above.
>
> Well it turns out that calling "efi_arch_memory_setup()" isn't correct
> because it also messes with the page tables AND also does the trampoline

Yep.

> relocation. Which after this call finishes then it does the trampoline
> relocations in assembly. The code currently makes the assumption it can

I am not sure what do you mean here.

> use any conventional memory range below 1mb (and unfortunately does the
> math incorrectly and instead uses the region following the conventional

Which code? Which math?

> memory region). You need to use AllocatePages() otherwise you are
> trampling memory that might have been allocated by the bootloader or any

Bootloader code/data should be dead here.

> multiboot modules (e.g. tboot) prior to Xen.

How come?

> I'm just going to write a patch to fix the issues that I've found thus
> far. I believe at this point there is something wrong with the page
> tables because setting cr0 for the non-0 CPU in
> trampoline_protmode_entry causes the machine to reboot.

I have a feeling that problem lays somewhere else. Probably far before
trampoline_protmode_entry.

> I've also found where we have the possibility to call
> relocate_trampoline() twice in the EFI case. Its protected by a check to
> trampoline_phys but I'm not sure why we even have the code there to be
> able to do so.

Consider case when boot services use memory below 1 MiB.

Thank you for testing my patch series.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 19:08     ` Daniel Kiper
@ 2017-01-11 19:50       ` Doug Goldstein
  2017-01-11 20:36         ` Daniel Kiper
  2017-01-11 20:31       ` Doug Goldstein
  1 sibling, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-11 19:50 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 3939 bytes --]

On 1/11/17 1:08 PM, Daniel Kiper wrote:
> On Mon, Jan 09, 2017 at 07:37:59PM -0600, Doug Goldstein wrote:
>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> 
> [...]
> 
>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
>>> index 62c010e..dc857d8 100644
>>> --- a/xen/arch/x86/efi/efi-boot.h
>>> +++ b/xen/arch/x86/efi/efi-boot.h
>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>  {
>>>      struct e820entry *e;
>>>      unsigned int i;
>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
>>
>> Just wondering where the constant came from? And if there should be a
>> little bit of information about it. To me its just weird to shift 64.
> 
> 64 << 10 == 64 KiB which is the size of trampoline region reserved in
> xen/arch/x86/boot/head.S. Though I think that we should reserve real
> size needed for trampoline code. IIRC, it was discussed here earlier
> but there is no go for it in this patch series.

See my comments below but that's not entirely correct. But yes I would
avoid doing those changes in this series.

> 
>>>      /* Populate E820 table and check trampoline area availability. */
>>>      e = e820map - 1;
>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>              /* fall through */
>>>          case EfiConventionalMemory:
>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
>>> +                 len >= cfg.size + extra_mem &&
>>> +                 desc->PhysicalStart + len > cfg.addr )
>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
>>
>> So this is where the current series blows up and fails on real hardware.
>> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
>> only initialized in the straight EFI case. The result is that cfg.addr
>> is set to the section immediately following this. Took a bit to
>> trackdown because I checked for memory overlaps with where Xen was
>> loaded and where it was relocated to but forgot to check for overlaps
>> with the trampoline code. This is the address where the trampoline jumps
>> are copied.
>>
>> Personally I'd like to see an ASSERT added or the code swizzled around
>> in such a way that its not possible to get into a bad state. But this is
>> probably another patch series.
> 
> Nice catch! Thanks a lot. I think that we should initialize cfg.size = 64 << 10
> in efi_multiboot2(). It looks like real fix. extra_mem stuff is bogus.
> 

Except in head.S you start the stack 64kb after the end of the
trampoline size. So cfg.size = (64 << 10); won't work. It needs to be
the size of the trampoline + 64k.


>>> +    efi_tables();
>>> +    setup_efi_pci();
>>> +    efi_variables();
>>
>> This is probably where you missed the call to "efi_arch_memory_setup();"
>> that gave me hell above.
> 
> This does not work in MB2 case.

You're looking at the oldest email. I've have further follow ups that
point that out and I've included a patch to fix the issues.

>>
>> So as an aside, IMHO this is where the series should end and the next
>> set of patches should be a follow on.
> 
> Hmmm... Why? If you do not apply rest of patches then MB2 does not
> work on all EFI platforms.
> 
> Daniel
> 

Q: How do you eat an elephant?
A: One bite at a time.

The point is we have 0 MB2 support presently. We can add it in
incremental hunks. Otherwise we get a patch series that's been floating
around for around 3 years and missed at least 2 releases where it should
have gotten in. We've only got several weeks before the 4.9 window
closes as well.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 11/13] x86: make Xen early boot code relocatable
  2017-01-10  2:05   ` Doug Goldstein
@ 2017-01-11 20:05     ` Daniel Kiper
  2017-01-11 20:23       ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-11 20:05 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Mon, Jan 09, 2017 at 08:05:01PM -0600, Doug Goldstein wrote:
> On 12/5/16 4:25 PM, Daniel Kiper wrote:

[...]

> >          /* Save trampoline address for later use. */
> >          shl     $4, %ecx
> > -        mov     %ecx,sym_phys(trampoline_phys)
> > +        mov     %ecx,sym_fs(trampoline_phys)
> > +
> > +        /* Save Xen image load base address for later use. */
> > +        mov     %esi,sym_fs(xen_phys_start)
> > +        mov     %esi,sym_fs(trampoline_xen_phys_start)
> > +
> > +        /* Setup stack. %ss was initialized earlier. */
> > +        lea     1024+sym_esi(cpu0_stack),%esp
>
> Not sure if this is the bad code or what but after this patch in the
> series the stack is at 0xAD000 which is in the middle of VGA memory so
> the stack is getting screwy (hence my email last week). And the stack is
> bad in trampoline_setup, before trampoline_setup the stack seems fine.
>
> This is from my hacked up version of iPXE...
>
> Type / Addr / Number of Pages / Flags
>
> Conventional: 0x000059000 :      69 : f
> Reserved:     0x00009e000 :       2 : f
> Conventional: 0x000100000 :   65280 : f
>
> As you can see from 0xA0000 to 0x100000 isn't mentioned but everything I
> can find on EFI says if the range isn't mentioned you shouldn't use it.

Could you provide full EFI memory map from this machine?

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 19:47       ` Daniel Kiper
@ 2017-01-11 20:20         ` Doug Goldstein
  2017-01-12 10:22           ` Jan Beulich
  2017-01-12 12:50           ` Daniel Kiper
  0 siblings, 2 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-11 20:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 7727 bytes --]

On 1/11/17 1:47 PM, Daniel Kiper wrote:
> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
>>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
>>
>>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
>>>> index 62c010e..dc857d8 100644
>>>> --- a/xen/arch/x86/efi/efi-boot.h
>>>> +++ b/xen/arch/x86/efi/efi-boot.h
>>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>  {
>>>>      struct e820entry *e;
>>>>      unsigned int i;
>>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
>>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
>>>
>>> Just wondering where the constant came from? And if there should be a
>>> little bit of information about it. To me its just weird to shift 64.
>>
>> Its the size of the stack used in the assembly code.
> 
> No, it is trampoline region size.

trampoline + stack in head.S We take the address where we're going to
copy the trampoline and set the stack to 0x10000 past it.


> 
>>>>      /* Populate E820 table and check trampoline area availability. */
>>>>      e = e820map - 1;
>>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>              /* fall through */
>>>>          case EfiConventionalMemory:
>>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
>>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
>>>> +                 len >= cfg.size + extra_mem &&
>>>> +                 desc->PhysicalStart + len > cfg.addr )
>>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
>>>
>>> So this is where the current series blows up and fails on real hardware.
>>
>> Honestly this was my misunderstanding and this shouldn't ever be used to
>> get memory for the trampoline. This also has the bug in it that it needs
>> to be:
>>
>> ASSERT(cfg.size > 0);
>> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;
> 
> As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
> in one way or another. Hmmm... It looks OK. I will double check it because
> I do not looked at this code long time and maybe I am missing something.

cfg.size needs to be the size of the trampolines + stack.


>>> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
>>> only initialized in the straight EFI case. The result is that cfg.addr
>>> is set to the section immediately following this. Took a bit to
>>> trackdown because I checked for memory overlaps with where Xen was
>>> loaded and where it was relocated to but forgot to check for overlaps
>>> with the trampoline code. This is the address where the trampoline jumps
>>> are copied.
>>>
>>> Personally I'd like to see an ASSERT added or the code swizzled around
>>> in such a way that its not possible to get into a bad state. But this is
>>> probably another patch series.
>>>
>>>>              /* fall through */
>>>>          case EfiLoaderCode:
>>>> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>>>>
>>>>  static void __init efi_arch_pre_exit_boot(void)
>>>>  {
>>>> -    if ( !trampoline_phys )
>>>> -    {
>>>> -        if ( !cfg.addr )
>>>> -            blexit(L"No memory for trampoline");
>>>> +    if ( trampoline_phys )
>>>> +        return;
>>>> +
>>>> +    if ( !cfg.addr )
>>>> +        blexit(L"No memory for trampoline");
>>>> +
>>>> +    if ( efi_enabled(EFI_LOADER) )
>>>>          relocate_trampoline(cfg.addr);
>>
>> Why is this call even here anymore? Its called in
>> efi_arch_memory_setup() already. If it was unable to allocate memory
>> under the 1mb region its just going to trample over ANY conventional
>> memory region that might be in use.
> 
> Trampoline is relocated in xen/arch/x86/boot/head.S.

For the MB2/MB case. But for the straight EFI case its called in
efi_arch_memory_setup() and then you've added the wrapper of
efi_enabled(EFI_LOADER) which in theory would have it called again in
the straight EFI case if trampoline_phys isn't set and cfg.addr is set.


> 
>>>> -    }
>>>>  }
>>>>
>>>>  static void __init noreturn efi_arch_post_exit_boot(void)
>>>> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
>>>> +    __set_bit(EFI_RS, &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();
>>>> +
>>>> +    efi_tables();
>>>> +    setup_efi_pci();
>>>> +    efi_variables();
>>>
>>> This is probably where you missed the call to "efi_arch_memory_setup();"
>>> that gave me hell above.
>>
>> Well it turns out that calling "efi_arch_memory_setup()" isn't correct
>> because it also messes with the page tables AND also does the trampoline
> 
> Yep.
> 
>> relocation. Which after this call finishes then it does the trampoline
>> relocations in assembly. The code currently makes the assumption it can
> 
> I am not sure what do you mean here.
> 
>> use any conventional memory range below 1mb (and unfortunately does the
>> math incorrectly and instead uses the region following the conventional
> 
> Which code? Which math?

The code where cfg.size = 0 and the extra_mem was missing.

> 
>> memory region). You need to use AllocatePages() otherwise you are
>> trampling memory that might have been allocated by the bootloader or any
> 
> Bootloader code/data should be dead here.

Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
currently call ExitBootServices and a timer that iPXE has wired up has
some memory reserved down there and it was getting trampled. The real
answer is that we need to fix up stock Xen to be able to always call EBS.

> 
>> multiboot modules (e.g. tboot) prior to Xen.
> 
> How come?
> 
>> I'm just going to write a patch to fix the issues that I've found thus
>> far. I believe at this point there is something wrong with the page
>> tables because setting cr0 for the non-0 CPU in
>> trampoline_protmode_entry causes the machine to reboot.
> 
> I have a feeling that problem lays somewhere else. Probably far before
> trampoline_protmode_entry.
> 
>> I've also found where we have the possibility to call
>> relocate_trampoline() twice in the EFI case. Its protected by a check to
>> trampoline_phys but I'm not sure why we even have the code there to be
>> able to do so.
> 
> Consider case when boot services use memory below 1 MiB.
> 
> Thank you for testing my patch series.
> 
> Daniel
> 

So do we really need to go down below 1MiB? We're never going into
16-bit mode. Unless the other CPUs are starting up in 16-bit mode.

I'll keep whacking away at this until it lands on any piece of hardware
I've got.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 11/13] x86: make Xen early boot code relocatable
  2017-01-11 20:05     ` Daniel Kiper
@ 2017-01-11 20:23       ` Doug Goldstein
  0 siblings, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-11 20:23 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 3097 bytes --]

On 1/11/17 2:05 PM, Daniel Kiper wrote:
> On Mon, Jan 09, 2017 at 08:05:01PM -0600, Doug Goldstein wrote:
>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> 
> [...]
> 
>>>          /* Save trampoline address for later use. */
>>>          shl     $4, %ecx
>>> -        mov     %ecx,sym_phys(trampoline_phys)
>>> +        mov     %ecx,sym_fs(trampoline_phys)
>>> +
>>> +        /* Save Xen image load base address for later use. */
>>> +        mov     %esi,sym_fs(xen_phys_start)
>>> +        mov     %esi,sym_fs(trampoline_xen_phys_start)
>>> +
>>> +        /* Setup stack. %ss was initialized earlier. */
>>> +        lea     1024+sym_esi(cpu0_stack),%esp
>>
>> Not sure if this is the bad code or what but after this patch in the
>> series the stack is at 0xAD000 which is in the middle of VGA memory so
>> the stack is getting screwy (hence my email last week). And the stack is
>> bad in trampoline_setup, before trampoline_setup the stack seems fine.
>>
>> This is from my hacked up version of iPXE...
>>
>> Type / Addr / Number of Pages / Flags
>>
>> Conventional: 0x000059000 :      69 : f
>> Reserved:     0x00009e000 :       2 : f
>> Conventional: 0x000100000 :   65280 : f
>>
>> As you can see from 0xA0000 to 0x100000 isn't mentioned but everything I
>> can find on EFI says if the range isn't mentioned you shouldn't use it.
> 
> Could you provide full EFI memory map from this machine?
> 
> Daniel
> 

Its a NUC5i5MYHE with 16gb of RAM. Let me know if you need help
deciphering this. I'm going to convert this output into the same as
Linux's output when I get some time.

Name        : Start Addr : Pages : Flags
Conventional: 0x000000000 :      88 : f
Reserved:     0x000058000 :       1 : f
Conventional: 0x000059000 :      69 : f
Reserved:     0x00009e000 :       2 : f
Conventional: 0x000100000 :   65280 : f
BS Code:      0x010000000 :      11 : f
Conventional: 0x01000b000 :  547960 : f
BS Data:      0x095c83000 :      64 : f
Conventional: 0x095cc3000 :   30743 : f
Loader Code:  0x09d4da000 :     180 : f
BS Data:      0x09d58e000 :     484 : f
RS Data:      0x09d772000 :    1273 : 800000000000000f
BS Data:      0x09dc6b000 :       8 : f
Conventional: 0x09dc73000 :    2260 : f
BS Data:      0x09e547000 :   13272 : f
Conventional: 0x0a191f000 :     481 : f
BS Code:      0x0a1b00000 :    1925 : f
Reserved:     0x0a2285000 :     187 : f
ACPI Reclaim: 0x0a2340000 :      37 : f
ACPI NVS:     0x0a2365000 :    2352 : f
RS Data:      0x0a2c95000 :     781 : 800000000000000f
RS Code:      0x0a2fa2000 :      93 : 800000000000000f
BS Data:      0x0a2fff000 :       1 : f
Conventional: 0x100000000 : 3497984 : f
Reserved:     0x0a3800000 :   18432 : 0
MMAP IO:      0x0f8000000 :   16384 : 8000000000000001
MMAP IO:      0x0fec00000 :       1 : 8000000000000001
MMAP IO:      0x0fed00000 :       4 : 8000000000000001
MMAP IO:      0x0fed1c000 :       4 : 8000000000000001
MMAP IO:      0x0fee00000 :       1 : 8000000000000001
MMAP IO:      0x0ff000000 :    4096 : 8000000000000001

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 19:08     ` Daniel Kiper
  2017-01-11 19:50       ` Doug Goldstein
@ 2017-01-11 20:31       ` Doug Goldstein
  2017-01-12 12:18         ` Daniel Kiper
  1 sibling, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-11 20:31 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 2362 bytes --]

On 1/11/17 1:08 PM, Daniel Kiper wrote:
> On Mon, Jan 09, 2017 at 07:37:59PM -0600, Doug Goldstein wrote:
>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> 
> 
>>> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
>>> index 0a93e61..70ed836 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;
>>>
>>
>> So as an aside, IMHO this is where the series should end and the next
>> set of patches should be a follow on.
> 
> Hmmm... Why? If you do not apply rest of patches then MB2 does not
> work on all EFI platforms.
> 
> Daniel
> 

So I should have expanded more in my other email. I've got this series
pulled in on top of 4.8 along with different fixes as discussed on this
thread:

https://github.com/cardoe/xen/tree/48-and-daniel

This boots up on my NUC but reports the other CPUs as stuck and the
error is -5. This starts to come up on the Lenovo and it gets to near
where it starts the dom0 kernel and then blanks the screen and hard
hangs. This causes cr0 crashes on the other boards I've got access to.


I've also got the series only to this point with the fixes.

https://github.com/cardoe/xen/tree/48-and-daniel-sans-relocate

The later version boots up on my NUC with all CPUs. It still hangs on
the Lenovo. It works on the other boards. It also appears work under QEMU.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 19:50       ` Doug Goldstein
@ 2017-01-11 20:36         ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-11 20:36 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Jan 11, 2017 at 01:50:56PM -0600, Doug Goldstein wrote:
> On 1/11/17 1:08 PM, Daniel Kiper wrote:
> > On Mon, Jan 09, 2017 at 07:37:59PM -0600, Doug Goldstein wrote:
> >> On 12/5/16 4:25 PM, Daniel Kiper wrote:

[...]

> >>>      /* Populate E820 table and check trampoline area availability. */
> >>>      e = e820map - 1;
> >>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>>              /* fall through */
> >>>          case EfiConventionalMemory:
> >>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> >>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> >>> +                 len >= cfg.size + extra_mem &&
> >>> +                 desc->PhysicalStart + len > cfg.addr )
> >>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
> >>
> >> So this is where the current series blows up and fails on real hardware.
> >> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
> >> only initialized in the straight EFI case. The result is that cfg.addr
> >> is set to the section immediately following this. Took a bit to
> >> trackdown because I checked for memory overlaps with where Xen was
> >> loaded and where it was relocated to but forgot to check for overlaps
> >> with the trampoline code. This is the address where the trampoline jumps
> >> are copied.
> >>
> >> Personally I'd like to see an ASSERT added or the code swizzled around
> >> in such a way that its not possible to get into a bad state. But this is
> >> probably another patch series.
> >
> > Nice catch! Thanks a lot. I think that we should initialize cfg.size = 64 << 10
> > in efi_multiboot2(). It looks like real fix. extra_mem stuff is bogus.
>
> Except in head.S you start the stack 64kb after the end of the
> trampoline size. So cfg.size = (64 << 10); won't work. It needs to be
> the size of the trampoline + 64k.

I will double check it and drop you a line. Probably in 1-2 weeks.
Now I am tidying up my backlog after vacation.

> >>> +    efi_tables();
> >>> +    setup_efi_pci();
> >>> +    efi_variables();
> >>
> >> This is probably where you missed the call to "efi_arch_memory_setup();"
> >> that gave me hell above.
> >
> > This does not work in MB2 case.
>
> You're looking at the oldest email. I've have further follow ups that
> point that out and I've included a patch to fix the issues.

I have tried to reply to all your emails.

> >> So as an aside, IMHO this is where the series should end and the next
> >> set of patches should be a follow on.
> >
> > Hmmm... Why? If you do not apply rest of patches then MB2 does not
> > work on all EFI platforms.
> >
> > Daniel
> >
>
> Q: How do you eat an elephant?
> A: One bite at a time.
>
> The point is we have 0 MB2 support presently. We can add it in
> incremental hunks. Otherwise we get a patch series that's been floating

I think that nothing prevents maintainers to apply my patch series partially.
And many prerequisite patches went that way. However, I think that they should
not apply this patch without the rest (and more importantly patch series should
not end at this patch). If we do that we will provide MB2 functionality which
is broken and confuse users. However, if you think that it make sense please
convince maintainers to do that. Though I will not support such request.

> around for around 3 years and missed at least 2 releases where it should

Do not forget that it required a lot of changes in MB2 protocol, GRUB2 (changes
are in git repository and will come into next release), etc. And I have carried
almost all of that stuff myself. Please, believe me this is not easy task.

> have gotten in. We've only got several weeks before the 4.9 window
> closes as well.

Window closes at the end of the march. I am going to release new version
in 1-2 weeks after clearing my backlog. I hope that this patch series
will go into 4.9. At least I will do all my best to achieve that goal.

Daniel

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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (14 preceding siblings ...)
  2017-01-10 23:12 ` [PATCH 2/??] memory allocation fix Doug Goldstein
@ 2017-01-11 20:46 ` Daniel Kiper
  2017-01-13 15:45   ` Doug Goldstein
  2017-01-12 17:46 ` Doug Goldstein
  16 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-11 20:46 UTC (permalink / raw)
  To: xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, cardoe, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei

On Mon, Dec 05, 2016 at 11:25:05PM +0100, Daniel Kiper wrote:
> Hi,
>
> I am sending eleventh version of multiboot2 protocol support for
> legacy BIOS and EFI platforms. This patch series release contains
> fixes for all known issues.
>
> 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 is short list of changes since v10:
>   - changed patches: 06 (small change suggested by Jan).

Guys, I am going to release next version in 1-2 weeks. If you
have more comments for current one please post them ASAP.
I would like to have this patch series come into 4.9.

Thanks,

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 20:20         ` Doug Goldstein
@ 2017-01-12 10:22           ` Jan Beulich
  2017-01-12 12:50           ` Daniel Kiper
  1 sibling, 0 replies; 64+ messages in thread
From: Jan Beulich @ 2017-01-12 10:22 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: Juergen Gross, sstabellini, andrew.cooper3, Daniel Kiper,
	pgnet.dev, ning.sun, julien.grall, xen-devel, qiaowei.ren,
	gang.wei, fu.wei

>>> On 11.01.17 at 21:20, <cardoe@cardoe.com> wrote:
> So do we really need to go down below 1MiB? We're never going into
> 16-bit mode. Unless the other CPUs are starting up in 16-bit mode.

Well, AP startup works by providing an 8-bit page number value
for where the processor should start fetching instructions.

Jan


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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 20:31       ` Doug Goldstein
@ 2017-01-12 12:18         ` Daniel Kiper
  2017-01-12 15:44           ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 12:18 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Jan 11, 2017 at 02:31:35PM -0600, Doug Goldstein wrote:
> On 1/11/17 1:08 PM, Daniel Kiper wrote:
> > On Mon, Jan 09, 2017 at 07:37:59PM -0600, Doug Goldstein wrote:
> >> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> >>> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> >>> index 0a93e61..70ed836 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;
> >>>
> >>
> >> So as an aside, IMHO this is where the series should end and the next
> >> set of patches should be a follow on.
> >
> > Hmmm... Why? If you do not apply rest of patches then MB2 does not
> > work on all EFI platforms.
> >
> > Daniel
>
> So I should have expanded more in my other email. I've got this series
> pulled in on top of 4.8 along with different fixes as discussed on this
> thread:
>
> https://github.com/cardoe/xen/tree/48-and-daniel
>
> This boots up on my NUC but reports the other CPUs as stuck and the
> error is -5. This starts to come up on the Lenovo and it gets to near
> where it starts the dom0 kernel and then blanks the screen and hard
> hangs. This causes cr0 crashes on the other boards I've got access to.
>
> I've also got the series only to this point with the fixes.
>
> https://github.com/cardoe/xen/tree/48-and-daniel-sans-relocate
>
> The later version boots up on my NUC with all CPUs. It still hangs on
> the Lenovo. It works on the other boards. It also appears work under QEMU.

AIUI, you are trying to add full (legacy BIOS and EFI) MB2 support to iPXE. Great!.
Though I think that you should do this in steps. First of all you should have MB2
fully running on legacy BIOS platforms. It is much simpler. If it works move to EFI
platforms. OVMF is good choice for start but of course finally tests should be done
on real hardware. You can do tests on legacy BIOS with just patch #01. If everything
works then apply whole patch series to Xen and add MB2 reloc functionality. If it
works move to EFI platform tests. It is important that you do EFI platform tests with
whole patch series. This way you avoid issues related to overwriting BS/RS code/data.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-11 20:20         ` Doug Goldstein
  2017-01-12 10:22           ` Jan Beulich
@ 2017-01-12 12:50           ` Daniel Kiper
  2017-01-12 15:52             ` Doug Goldstein
  1 sibling, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 12:50 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
> On 1/11/17 1:47 PM, Daniel Kiper wrote:
> > On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
> >> On 1/9/17 7:37 PM, Doug Goldstein wrote:
> >>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> >>
> >>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> >>>> index 62c010e..dc857d8 100644
> >>>> --- a/xen/arch/x86/efi/efi-boot.h
> >>>> +++ b/xen/arch/x86/efi/efi-boot.h
> >>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>>>  {
> >>>>      struct e820entry *e;
> >>>>      unsigned int i;
> >>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
> >>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
> >>>
> >>> Just wondering where the constant came from? And if there should be a
> >>> little bit of information about it. To me its just weird to shift 64.
> >>
> >> Its the size of the stack used in the assembly code.
> >
> > No, it is trampoline region size.
>
> trampoline + stack in head.S We take the address where we're going to
> copy the trampoline and set the stack to 0x10000 past it.

I suppose that you think about this:

        /* Switch to low-memory stack.  */
        mov     sym_fs(trampoline_phys),%edi
        lea     0x10000(%edi),%esp

However, trampoline region size is (should be) 64 KiB. No way. Please
look below for more details.

> >>>>      /* Populate E820 table and check trampoline area availability. */
> >>>>      e = e820map - 1;
> >>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>>>              /* fall through */
> >>>>          case EfiConventionalMemory:
> >>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> >>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> >>>> +                 len >= cfg.size + extra_mem &&
> >>>> +                 desc->PhysicalStart + len > cfg.addr )
> >>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
> >>>
> >>> So this is where the current series blows up and fails on real hardware.
> >>
> >> Honestly this was my misunderstanding and this shouldn't ever be used to
> >> get memory for the trampoline. This also has the bug in it that it needs
> >> to be:
> >>
> >> ASSERT(cfg.size > 0);
> >> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;
> >
> > As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
> > in one way or another. Hmmm... It looks OK. I will double check it because
> > I do not looked at this code long time and maybe I am missing something.
>
> cfg.size needs to be the size of the trampolines + stack.

It looks that during some code rearrangement I moved one instruction too
much to trampoline_bios_setup. So, I can agree that right now cfg.size
should be properly initialized. Though it should be cfg.size = 64 << 10.
Then extra_mem should be dropped.

> >>> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
> >>> only initialized in the straight EFI case. The result is that cfg.addr
> >>> is set to the section immediately following this. Took a bit to
> >>> trackdown because I checked for memory overlaps with where Xen was
> >>> loaded and where it was relocated to but forgot to check for overlaps
> >>> with the trampoline code. This is the address where the trampoline jumps
> >>> are copied.
> >>>
> >>> Personally I'd like to see an ASSERT added or the code swizzled around
> >>> in such a way that its not possible to get into a bad state. But this is
> >>> probably another patch series.
> >>>
> >>>>              /* fall through */
> >>>>          case EfiLoaderCode:
> >>>> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
> >>>>
> >>>>  static void __init efi_arch_pre_exit_boot(void)
> >>>>  {
> >>>> -    if ( !trampoline_phys )
> >>>> -    {
> >>>> -        if ( !cfg.addr )
> >>>> -            blexit(L"No memory for trampoline");
> >>>> +    if ( trampoline_phys )
> >>>> +        return;
> >>>> +
> >>>> +    if ( !cfg.addr )
> >>>> +        blexit(L"No memory for trampoline");
> >>>> +
> >>>> +    if ( efi_enabled(EFI_LOADER) )
> >>>>          relocate_trampoline(cfg.addr);
> >>
> >> Why is this call even here anymore? Its called in
> >> efi_arch_memory_setup() already. If it was unable to allocate memory
> >> under the 1mb region its just going to trample over ANY conventional
> >> memory region that might be in use.
> >
> > Trampoline is relocated in xen/arch/x86/boot/head.S.
>
> For the MB2/MB case. But for the straight EFI case its called in
> efi_arch_memory_setup() and then you've added the wrapper of

That is true.

> efi_enabled(EFI_LOADER) which in theory would have it called again in
> the straight EFI case if trampoline_phys isn't set and cfg.addr is set.

Why "in theory"?

> >>>> -    }
> >>>>  }
> >>>>
> >>>>  static void __init noreturn efi_arch_post_exit_boot(void)
> >>>> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
> >>>> +    __set_bit(EFI_RS, &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();
> >>>> +
> >>>> +    efi_tables();
> >>>> +    setup_efi_pci();
> >>>> +    efi_variables();
> >>>
> >>> This is probably where you missed the call to "efi_arch_memory_setup();"
> >>> that gave me hell above.
> >>
> >> Well it turns out that calling "efi_arch_memory_setup()" isn't correct
> >> because it also messes with the page tables AND also does the trampoline
> >
> > Yep.
> >
> >> relocation. Which after this call finishes then it does the trampoline
> >> relocations in assembly. The code currently makes the assumption it can
> >
> > I am not sure what do you mean here.
> >
> >> use any conventional memory range below 1mb (and unfortunately does the
> >> math incorrectly and instead uses the region following the conventional
> >
> > Which code? Which math?
>
> The code where cfg.size = 0 and the extra_mem was missing.

This should be fixed as I stated above.

> >> memory region). You need to use AllocatePages() otherwise you are
> >> trampling memory that might have been allocated by the bootloader or any
> >
> > Bootloader code/data should be dead here.
>
> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
> currently call ExitBootServices and a timer that iPXE has wired up has

If you disable an important wheel in a machine you should not expect
that the machine will work. Sorry! No way!

> some memory reserved down there and it was getting trampled. The real

I still do not know why remnants of iPXE should run at this Xen boot stage.
It looks like an iPXE bug and IMO it should be fixed first.

> answer is that we need to fix up stock Xen to be able to always call EBS.

It looks that ExitBootServices() is always called. So, I do not think that
anything have to be fixed.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 12:18         ` Daniel Kiper
@ 2017-01-12 15:44           ` Doug Goldstein
  2017-01-12 19:30             ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 15:44 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 2783 bytes --]

On 1/12/17 6:18 AM, Daniel Kiper wrote:

>>>>
>>>> So as an aside, IMHO this is where the series should end and the next
>>>> set of patches should be a follow on.
>>>
>>> Hmmm... Why? If you do not apply rest of patches then MB2 does not
>>> work on all EFI platforms.
>>>
>>> Daniel
>>
>> So I should have expanded more in my other email. I've got this series
>> pulled in on top of 4.8 along with different fixes as discussed on this
>> thread:
>>
>> https://github.com/cardoe/xen/tree/48-and-daniel
>>
>> This boots up on my NUC but reports the other CPUs as stuck and the
>> error is -5. This starts to come up on the Lenovo and it gets to near
>> where it starts the dom0 kernel and then blanks the screen and hard
>> hangs. This causes cr0 crashes on the other boards I've got access to.
>>
>> I've also got the series only to this point with the fixes.
>>
>> https://github.com/cardoe/xen/tree/48-and-daniel-sans-relocate
>>
>> The later version boots up on my NUC with all CPUs. It still hangs on
>> the Lenovo. It works on the other boards. It also appears work under QEMU.
> 
> AIUI, you are trying to add full (legacy BIOS and EFI) MB2 support to iPXE. Great!.
> Though I think that you should do this in steps. First of all you should have MB2
> fully running on legacy BIOS platforms. It is much simpler. If it works move to EFI
> platforms. OVMF is good choice for start but of course finally tests should be done
> on real hardware. You can do tests on legacy BIOS with just patch #01. If everything
> works then apply whole patch series to Xen and add MB2 reloc functionality. If it
> works move to EFI platform tests. It is important that you do EFI platform tests with
> whole patch series. This way you avoid issues related to overwriting BS/RS code/data.
> 
> Daniel
> 

Daniel,

I appreciate your input. I do like the approach of splitting things up
into small incremental pieces, that's the way all this work should be
happening. You should also be aware that iPXE takes the approach of
least amount of functionality/code to make things work. So from their
view there's no reason for adding MB2 support for BIOS since it provides
no advantage over MB1 when booting from the BIOS. Now MB2 solves a
problem with booting over EFI vs MB1 so they'll be willing to take a
change there. I'll also disagree that BIOS is easier than EFI since with
EFI its just load the ELF into memory and set a few pointers in tags.
With BIOS it requires me to build up the memory map into a MB2 structure.

As far as it goes I've got iPXE booting MB2 EFI payloads just fine. The
issues I've explained here happen when I use Grub or iPXE to boot Xen so
its not implementation specific to my iPXE code.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 12:50           ` Daniel Kiper
@ 2017-01-12 15:52             ` Doug Goldstein
  2017-01-12 20:28               ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 15:52 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 8839 bytes --]

On 1/12/17 6:50 AM, Daniel Kiper wrote:
> On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
>> On 1/11/17 1:47 PM, Daniel Kiper wrote:
>>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
>>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
>>>>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
>>>>
>>>>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
>>>>>> index 62c010e..dc857d8 100644
>>>>>> --- a/xen/arch/x86/efi/efi-boot.h
>>>>>> +++ b/xen/arch/x86/efi/efi-boot.h
>>>>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>>>  {
>>>>>>      struct e820entry *e;
>>>>>>      unsigned int i;
>>>>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
>>>>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
>>>>>
>>>>> Just wondering where the constant came from? And if there should be a
>>>>> little bit of information about it. To me its just weird to shift 64.
>>>>
>>>> Its the size of the stack used in the assembly code.
>>>
>>> No, it is trampoline region size.
>>
>> trampoline + stack in head.S We take the address where we're going to
>> copy the trampoline and set the stack to 0x10000 past it.
> 
> I suppose that you think about this:
> 
>         /* Switch to low-memory stack.  */
>         mov     sym_fs(trampoline_phys),%edi
>         lea     0x10000(%edi),%esp
> 
> However, trampoline region size is (should be) 64 KiB. No way. Please
> look below for more details.

The trampoline + stack are 64kb together. The stack grows down and the
trampoline grows up. The stack starts at 64kb past the start of the
trampoline. %edi is the start of the trampoline.

> 
>>>>>>      /* Populate E820 table and check trampoline area availability. */
>>>>>>      e = e820map - 1;
>>>>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>>>              /* fall through */
>>>>>>          case EfiConventionalMemory:
>>>>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
>>>>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
>>>>>> +                 len >= cfg.size + extra_mem &&
>>>>>> +                 desc->PhysicalStart + len > cfg.addr )
>>>>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
>>>>>
>>>>> So this is where the current series blows up and fails on real hardware.
>>>>
>>>> Honestly this was my misunderstanding and this shouldn't ever be used to
>>>> get memory for the trampoline. This also has the bug in it that it needs
>>>> to be:
>>>>
>>>> ASSERT(cfg.size > 0);
>>>> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;
>>>
>>> As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
>>> in one way or another. Hmmm... It looks OK. I will double check it because
>>> I do not looked at this code long time and maybe I am missing something.
>>
>> cfg.size needs to be the size of the trampolines + stack.
> 
> It looks that during some code rearrangement I moved one instruction too
> much to trampoline_bios_setup. So, I can agree that right now cfg.size
> should be properly initialized. Though it should be cfg.size = 64 << 10.
> Then extra_mem should be dropped.

That's fine as long as its clear that 64kb is for the trampoline + the
stack.

> 
>>>>> No where in the EFI + MB2 code path is cfg.size ever initialized. Its
>>>>> only initialized in the straight EFI case. The result is that cfg.addr
>>>>> is set to the section immediately following this. Took a bit to
>>>>> trackdown because I checked for memory overlaps with where Xen was
>>>>> loaded and where it was relocated to but forgot to check for overlaps
>>>>> with the trampoline code. This is the address where the trampoline jumps
>>>>> are copied.
>>>>>
>>>>> Personally I'd like to see an ASSERT added or the code swizzled around
>>>>> in such a way that its not possible to get into a bad state. But this is
>>>>> probably another patch series.
>>>>>
>>>>>>              /* fall through */
>>>>>>          case EfiLoaderCode:
>>>>>> @@ -210,12 +213,14 @@ static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
>>>>>>
>>>>>>  static void __init efi_arch_pre_exit_boot(void)
>>>>>>  {
>>>>>> -    if ( !trampoline_phys )
>>>>>> -    {
>>>>>> -        if ( !cfg.addr )
>>>>>> -            blexit(L"No memory for trampoline");
>>>>>> +    if ( trampoline_phys )
>>>>>> +        return;
>>>>>> +
>>>>>> +    if ( !cfg.addr )
>>>>>> +        blexit(L"No memory for trampoline");
>>>>>> +
>>>>>> +    if ( efi_enabled(EFI_LOADER) )
>>>>>>          relocate_trampoline(cfg.addr);
>>>>
>>>> Why is this call even here anymore? Its called in
>>>> efi_arch_memory_setup() already. If it was unable to allocate memory
>>>> under the 1mb region its just going to trample over ANY conventional
>>>> memory region that might be in use.
>>>
>>> Trampoline is relocated in xen/arch/x86/boot/head.S.
>>
>> For the MB2/MB case. But for the straight EFI case its called in
>> efi_arch_memory_setup() and then you've added the wrapper of
> 
> That is true.
> 
>> efi_enabled(EFI_LOADER) which in theory would have it called again in
>> the straight EFI case if trampoline_phys isn't set and cfg.addr is set.
> 
> Why "in theory"?

ok drop the words "in theory" and the statement is fine.

> 
>>>>>> -    }
>>>>>>  }
>>>>>>
>>>>>>  static void __init noreturn efi_arch_post_exit_boot(void)
>>>>>> @@ -653,6 +658,43 @@ 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_BOOT, &efi_flags);
>>>>>> +    __set_bit(EFI_RS, &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();
>>>>>> +
>>>>>> +    efi_tables();
>>>>>> +    setup_efi_pci();
>>>>>> +    efi_variables();
>>>>>
>>>>> This is probably where you missed the call to "efi_arch_memory_setup();"
>>>>> that gave me hell above.
>>>>
>>>> Well it turns out that calling "efi_arch_memory_setup()" isn't correct
>>>> because it also messes with the page tables AND also does the trampoline
>>>
>>> Yep.
>>>
>>>> relocation. Which after this call finishes then it does the trampoline
>>>> relocations in assembly. The code currently makes the assumption it can
>>>
>>> I am not sure what do you mean here.
>>>
>>>> use any conventional memory range below 1mb (and unfortunately does the
>>>> math incorrectly and instead uses the region following the conventional
>>>
>>> Which code? Which math?
>>
>> The code where cfg.size = 0 and the extra_mem was missing.
> 
> This should be fixed as I stated above.
> 
>>>> memory region). You need to use AllocatePages() otherwise you are
>>>> trampling memory that might have been allocated by the bootloader or any
>>>
>>> Bootloader code/data should be dead here.
>>
>> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
>> currently call ExitBootServices and a timer that iPXE has wired up has
> 
> If you disable an important wheel in a machine you should not expect
> that the machine will work. Sorry! No way!

Speak to your co-workers Konrad and Boris. We've had long email threads
about how certain hardware does not work with the way Xen calls
ExitBootServices.

> 
>> some memory reserved down there and it was getting trampled. The real
> 
> I still do not know why remnants of iPXE should run at this Xen boot stage.
> It looks like an iPXE bug and IMO it should be fixed first.

Like I said above, its because on this machine I am unable to call Xen's
EBS.

> 
>> answer is that we need to fix up stock Xen to be able to always call EBS.
> 
> It looks that ExitBootServices() is always called. So, I do not think that
> anything have to be fixed.

It is commented out of this board using the patchset that Konrad
submitted to the ML years ago.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
                   ` (15 preceding siblings ...)
  2017-01-11 20:46 ` [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
@ 2017-01-12 17:46 ` Doug Goldstein
  2017-01-12 18:26   ` Daniel Kiper
  16 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 17:46 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 776 bytes --]

On 12/5/16 4:25 PM, Daniel Kiper wrote:
> Hi,
> 
> I am sending eleventh version of multiboot2 protocol support for
> legacy BIOS and EFI platforms. This patch series release contains
> fixes for all known issues.
> 
> 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:

So another issue I've found in the series is that xen/xen.gz is loadable
with MB2 but xen.efi is not but includes the MB2 header so I detect it
as a valid MB2 module. There's no entry point advertised in the xen.efi
case.

I think we'd probably just leave off the MB2 header for xen.efi and
leave that as a plain EFI loader case.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2017-01-12 17:46 ` Doug Goldstein
@ 2017-01-12 18:26   ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 18:26 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 11:46:04AM -0600, Doug Goldstein wrote:
> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> > Hi,
> >
> > I am sending eleventh version of multiboot2 protocol support for
> > legacy BIOS and EFI platforms. This patch series release contains
> > fixes for all known issues.
> >
> > 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:
>
> So another issue I've found in the series is that xen/xen.gz is loadable
> with MB2 but xen.efi is not but includes the MB2 header so I detect it
> as a valid MB2 module. There's no entry point advertised in the xen.efi
> case.
>
> I think we'd probably just leave off the MB2 header for xen.efi and
> leave that as a plain EFI loader case.

This is known issue. xen.efi contains MB1 and MB2 headers because it is
build from almost the same source/object files. I tried to fix this once
but this is not easy. I am going to do that when current patch series is
applied. After that xen.efi will be loadable by three boot protocols.
Additionally, there is a chance that this way we will drop dependency
on specific binutils version.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 15:44           ` Doug Goldstein
@ 2017-01-12 19:30             ` Daniel Kiper
  2017-01-12 19:46               ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 19:30 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 09:44:59AM -0600, Doug Goldstein wrote:
> On 1/12/17 6:18 AM, Daniel Kiper wrote:
> >>>> So as an aside, IMHO this is where the series should end and the next
> >>>> set of patches should be a follow on.
> >>>
> >>> Hmmm... Why? If you do not apply rest of patches then MB2 does not
> >>> work on all EFI platforms.
> >>>
> >>> Daniel
> >>
> >> So I should have expanded more in my other email. I've got this series
> >> pulled in on top of 4.8 along with different fixes as discussed on this
> >> thread:
> >>
> >> https://github.com/cardoe/xen/tree/48-and-daniel
> >>
> >> This boots up on my NUC but reports the other CPUs as stuck and the
> >> error is -5. This starts to come up on the Lenovo and it gets to near
> >> where it starts the dom0 kernel and then blanks the screen and hard
> >> hangs. This causes cr0 crashes on the other boards I've got access to.
> >>
> >> I've also got the series only to this point with the fixes.
> >>
> >> https://github.com/cardoe/xen/tree/48-and-daniel-sans-relocate
> >>
> >> The later version boots up on my NUC with all CPUs. It still hangs on
> >> the Lenovo. It works on the other boards. It also appears work under QEMU.
> >
> > AIUI, you are trying to add full (legacy BIOS and EFI) MB2 support to iPXE. Great!.
> > Though I think that you should do this in steps. First of all you should have MB2
> > fully running on legacy BIOS platforms. It is much simpler. If it works move to EFI
> > platforms. OVMF is good choice for start but of course finally tests should be done
> > on real hardware. You can do tests on legacy BIOS with just patch #01. If everything
> > works then apply whole patch series to Xen and add MB2 reloc functionality. If it
> > works move to EFI platform tests. It is important that you do EFI platform tests with
> > whole patch series. This way you avoid issues related to overwriting BS/RS code/data.
> >
> > Daniel
>
> Daniel,
>
> I appreciate your input. I do like the approach of splitting things up
> into small incremental pieces, that's the way all this work should be
> happening. You should also be aware that iPXE takes the approach of
> least amount of functionality/code to make things work. So from their

Nice and appreciated but look below...

> view there's no reason for adding MB2 support for BIOS since it provides
> no advantage over MB1 when booting from the BIOS. Now MB2 solves a

From your point of view maybe it does not. However, from user point of view it may.
If you have support for MB2 on legacy BIOS and EFI platforms then you can boot Xen
on both platforms without changing anything in boot config files. Otherwise you have
to prepare separate configuration for different platforms.

> problem with booting over EFI vs MB1 so they'll be willing to take a
> change there. I'll also disagree that BIOS is easier than EFI since with
> EFI its just load the ELF into memory and set a few pointers in tags.
> With BIOS it requires me to build up the memory map into a MB2 structure.

Xen uses only these tags on legacy BIOS platforms: MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
(well, nice to have but it can be also not provided), MULTIBOOT2_TAG_TYPE_MMAP (same
as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO), MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME
(same as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO) ,MULTIBOOT2_TAG_TYPE_CMDLINE,
MULTIBOOT2_TAG_TYPE_MODULE. I do not mention MULTIBOOT2_TAG_TYPE_END which
is obvious. So, if you are real hardcore minimalist then you have to provide
MULTIBOOT2_TAG_TYPE_CMDLINE and MULTIBOOT2_TAG_TYPE_MODULE. All of them
are provided also on EFI. So, I do not see any reason to not provide MB2
for legacy BIOS. And I do not think that it is very difficult to provide
all optional tags mentioned above.

> As far as it goes I've got iPXE booting MB2 EFI payloads just fine. The
> issues I've explained here happen when I use Grub or iPXE to boot Xen so
> its not implementation specific to my iPXE code.

It looks that we have found the reason and solution for this problem.
I will fix it.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 19:30             ` Daniel Kiper
@ 2017-01-12 19:46               ` Doug Goldstein
  2017-01-12 21:45                 ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 19:46 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 2897 bytes --]

On 1/12/17 1:30 PM, Daniel Kiper wrote:
> On Thu, Jan 12, 2017 at 09:44:59AM -0600, Doug Goldstein wrote:

> 
>> view there's no reason for adding MB2 support for BIOS since it provides
>> no advantage over MB1 when booting from the BIOS. Now MB2 solves a
> 
> From your point of view maybe it does not. However, from user point of view it may.
> If you have support for MB2 on legacy BIOS and EFI platforms then you can boot Xen
> on both platforms without changing anything in boot config files. Otherwise you have
> to prepare separate configuration for different platforms.

Neither Grub nor iPXE require different configs for MB1 vs MB2 so I'm
not seeing the validity of this logic.

> 
>> problem with booting over EFI vs MB1 so they'll be willing to take a
>> change there. I'll also disagree that BIOS is easier than EFI since with
>> EFI its just load the ELF into memory and set a few pointers in tags.
>> With BIOS it requires me to build up the memory map into a MB2 structure.
> 
> Xen uses only these tags on legacy BIOS platforms: MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> (well, nice to have but it can be also not provided), MULTIBOOT2_TAG_TYPE_MMAP (same
> as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO), MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME
> (same as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO) ,MULTIBOOT2_TAG_TYPE_CMDLINE,
> MULTIBOOT2_TAG_TYPE_MODULE. I do not mention MULTIBOOT2_TAG_TYPE_END which
> is obvious. So, if you are real hardcore minimalist then you have to provide
> MULTIBOOT2_TAG_TYPE_CMDLINE and MULTIBOOT2_TAG_TYPE_MODULE. All of them
> are provided also on EFI. So, I do not see any reason to not provide MB2
> for legacy BIOS. And I do not think that it is very difficult to provide
> all optional tags mentioned above.

I don't understand what you're attempting to convey here. You've listed
out a number of tags that I mentioned in my message that I don't have to
implement for EFI. You've basically reinforced my point that its easier
to implement this for EFI than BIOS. MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
and MULTIBOOT2_TAG_TYPE_MMAP are unused by Xen on EFI. It gets this info
from a call to GetMemoryMap(). You actually reminded me of another bug.
Calling ExitBootServices() on Grub and letting it pass the memory info
causes Xen to fail to load.

Andrew helped me troubleshoot this and he discovered the fix. You've got
code:

/* Store Xen image load base address in place accessible for 32-bit code. */
mov %r15d,%esi

But if any of the checks under the run_bs: label specifically:
- /* Are EFI boot services available? */
- /* Is EFI SystemTable address provided by boot loader? */
- /* Is EFI ImageHandle address provided by boot loader? */

Will not run the mov instruction and then fail to boot. Its only if any
of these are false will it attempt to use the tags mentioned above as well.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 15:52             ` Doug Goldstein
@ 2017-01-12 20:28               ` Daniel Kiper
  2017-01-12 22:23                 ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 20:28 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 09:52:15AM -0600, Doug Goldstein wrote:
> On 1/12/17 6:50 AM, Daniel Kiper wrote:
> > On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
> >> On 1/11/17 1:47 PM, Daniel Kiper wrote:
> >>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
> >>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
> >>>>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
> >>>>
> >>>>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
> >>>>>> index 62c010e..dc857d8 100644
> >>>>>> --- a/xen/arch/x86/efi/efi-boot.h
> >>>>>> +++ b/xen/arch/x86/efi/efi-boot.h
> >>>>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>>>>>  {
> >>>>>>      struct e820entry *e;
> >>>>>>      unsigned int i;
> >>>>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
> >>>>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
> >>>>>
> >>>>> Just wondering where the constant came from? And if there should be a
> >>>>> little bit of information about it. To me its just weird to shift 64.
> >>>>
> >>>> Its the size of the stack used in the assembly code.
> >>>
> >>> No, it is trampoline region size.
> >>
> >> trampoline + stack in head.S We take the address where we're going to
> >> copy the trampoline and set the stack to 0x10000 past it.
> >
> > I suppose that you think about this:
> >
> >         /* Switch to low-memory stack.  */
> >         mov     sym_fs(trampoline_phys),%edi
> >         lea     0x10000(%edi),%esp
> >
> > However, trampoline region size is (should be) 64 KiB. No way. Please
> > look below for more details.
>
> The trampoline + stack are 64kb together. The stack grows down and the
> trampoline grows up. The stack starts at 64kb past the start of the
> trampoline. %edi is the start of the trampoline.

Yep. I think that right now we are on the same boat.

> >>>>>>      /* Populate E820 table and check trampoline area availability. */
> >>>>>>      e = e820map - 1;
> >>>>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
> >>>>>>              /* fall through */
> >>>>>>          case EfiConventionalMemory:
> >>>>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
> >>>>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
> >>>>>> +                 len >= cfg.size + extra_mem &&
> >>>>>> +                 desc->PhysicalStart + len > cfg.addr )
> >>>>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
> >>>>>
> >>>>> So this is where the current series blows up and fails on real hardware.
> >>>>
> >>>> Honestly this was my misunderstanding and this shouldn't ever be used to
> >>>> get memory for the trampoline. This also has the bug in it that it needs
> >>>> to be:
> >>>>
> >>>> ASSERT(cfg.size > 0);
> >>>> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;
> >>>
> >>> As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
> >>> in one way or another. Hmmm... It looks OK. I will double check it because
> >>> I do not looked at this code long time and maybe I am missing something.
> >>
> >> cfg.size needs to be the size of the trampolines + stack.
> >
> > It looks that during some code rearrangement I moved one instruction too
> > much to trampoline_bios_setup. So, I can agree that right now cfg.size
> > should be properly initialized. Though it should be cfg.size = 64 << 10.
> > Then extra_mem should be dropped.
>
> That's fine as long as its clear that 64kb is for the trampoline + the
> stack.

OK, but there are two stacks. We talk about "low-memory stack". I will improve
the comment.

[...]

> >>>> memory region). You need to use AllocatePages() otherwise you are
> >>>> trampling memory that might have been allocated by the bootloader or any
> >>>
> >>> Bootloader code/data should be dead here.
> >>
> >> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
> >> currently call ExitBootServices and a timer that iPXE has wired up has
> >
> > If you disable an important wheel in a machine you should not expect
> > that the machine will work. Sorry! No way!
>
> Speak to your co-workers Konrad and Boris. We've had long email threads
> about how certain hardware does not work with the way Xen calls
> ExitBootServices.

Could you be more precise what is wrong? Or at least send links to
relevant threads.

> >> some memory reserved down there and it was getting trampled. The real
> >
> > I still do not know why remnants of iPXE should run at this Xen boot stage.
> > It looks like an iPXE bug and IMO it should be fixed first.
>
> Like I said above, its because on this machine I am unable to call Xen's
> EBS.

I do not understand how ExitBootServices() call is related to iPXE timer remnants
or so. Though if it is related somehow then I think that you should blame machine
and/or iPXE designer/developer not Xen developer.

> >> answer is that we need to fix up stock Xen to be able to always call EBS.
> >
> > It looks that ExitBootServices() is always called. So, I do not think that
> > anything have to be fixed.
>
> It is commented out of this board using the patchset that Konrad
> submitted to the ML years ago.

I do not know what patchset do you mean. Could you send it?

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 19:46               ` Doug Goldstein
@ 2017-01-12 21:45                 ` Daniel Kiper
  2017-01-12 22:20                   ` Doug Goldstein
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 21:45 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 01:46:41PM -0600, Doug Goldstein wrote:
> On 1/12/17 1:30 PM, Daniel Kiper wrote:
> > On Thu, Jan 12, 2017 at 09:44:59AM -0600, Doug Goldstein wrote:
>
> >
> >> view there's no reason for adding MB2 support for BIOS since it provides
> >> no advantage over MB1 when booting from the BIOS. Now MB2 solves a
> >
> > From your point of view maybe it does not. However, from user point of view it may.
> > If you have support for MB2 on legacy BIOS and EFI platforms then you can boot Xen
> > on both platforms without changing anything in boot config files. Otherwise you have
> > to prepare separate configuration for different platforms.
>
> Neither Grub nor iPXE require different configs for MB1 vs MB2 so I'm
> not seeing the validity of this logic.

Hmmm... This is interesting. I do not know iPXE, however, in GRUB you must
use multiboot/module for MB1 and multiboot2/module2 for MB2. I suppose that
you have to differentiate between both of them in iPXE somehow too. Hence,
there is pretty good chance that configs for MB1 and MB2 are different.

> >> problem with booting over EFI vs MB1 so they'll be willing to take a
> >> change there. I'll also disagree that BIOS is easier than EFI since with
> >> EFI its just load the ELF into memory and set a few pointers in tags.
> >> With BIOS it requires me to build up the memory map into a MB2 structure.
> >
> > Xen uses only these tags on legacy BIOS platforms: MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> > (well, nice to have but it can be also not provided), MULTIBOOT2_TAG_TYPE_MMAP (same
> > as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO), MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME
> > (same as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO) ,MULTIBOOT2_TAG_TYPE_CMDLINE,
> > MULTIBOOT2_TAG_TYPE_MODULE. I do not mention MULTIBOOT2_TAG_TYPE_END which
> > is obvious. So, if you are real hardcore minimalist then you have to provide
> > MULTIBOOT2_TAG_TYPE_CMDLINE and MULTIBOOT2_TAG_TYPE_MODULE. All of them
> > are provided also on EFI. So, I do not see any reason to not provide MB2
> > for legacy BIOS. And I do not think that it is very difficult to provide
> > all optional tags mentioned above.
>
> I don't understand what you're attempting to convey here. You've listed
> out a number of tags that I mentioned in my message that I don't have to
> implement for EFI. You've basically reinforced my point that its easier
> to implement this for EFI than BIOS. MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> and MULTIBOOT2_TAG_TYPE_MMAP are unused by Xen on EFI. It gets this info

I showed you that if you are real minimalist you can enable the same MB2 code
on legacy BIOS and EFI. I do not understand your objection against providing
MB2 in iPXE on legacy BIOS if you do not need extra code (maybe a few #ifdefs).
Though I am not going to convince you. It is your choice but I am still thinking
that it is wrong choice.

By the way, does iPXE check MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST in Xen header.
If it does (it should) and do not understand MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO and
MULTIBOOT2_TAG_TYPE_MMAP then it should fail.

> from a call to GetMemoryMap(). You actually reminded me of another bug.
> Calling ExitBootServices() on Grub and letting it pass the memory info
> causes Xen to fail to load.

How come... Which GRUB version do you use? Xen clearly says that it needs
boot services (look into MB2 header). So, GRUB is not allowed to call
ExitBootServices(). If it does then it is GRUB bug.

> Andrew helped me troubleshoot this and he discovered the fix. You've got
> code:
>
> /* Store Xen image load base address in place accessible for 32-bit code. */
> mov %r15d,%esi
>
> But if any of the checks under the run_bs: label specifically:
> - /* Are EFI boot services available? */
> - /* Is EFI SystemTable address provided by boot loader? */
> - /* Is EFI ImageHandle address provided by boot loader? */
>
> Will not run the mov instruction and then fail to boot. Its only if any
> of these are false will it attempt to use the tags mentioned above as well.

OK, this is a bug and I will fix it. However, this is not related to
ExitBootServices() call in GRUB2.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 21:45                 ` Daniel Kiper
@ 2017-01-12 22:20                   ` Doug Goldstein
  2017-01-12 23:44                     ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 22:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 6328 bytes --]

On 1/12/17 3:45 PM, Daniel Kiper wrote:
> On Thu, Jan 12, 2017 at 01:46:41PM -0600, Doug Goldstein wrote:
>> On 1/12/17 1:30 PM, Daniel Kiper wrote:
>>> On Thu, Jan 12, 2017 at 09:44:59AM -0600, Doug Goldstein wrote:
>>
>>>
>>>> view there's no reason for adding MB2 support for BIOS since it provides
>>>> no advantage over MB1 when booting from the BIOS. Now MB2 solves a
>>>
>>> From your point of view maybe it does not. However, from user point of view it may.
>>> If you have support for MB2 on legacy BIOS and EFI platforms then you can boot Xen
>>> on both platforms without changing anything in boot config files. Otherwise you have
>>> to prepare separate configuration for different platforms.
>>
>> Neither Grub nor iPXE require different configs for MB1 vs MB2 so I'm
>> not seeing the validity of this logic.
> 
> Hmmm... This is interesting. I do not know iPXE, however, in GRUB you must
> use multiboot/module for MB1 and multiboot2/module2 for MB2. I suppose that
> you have to differentiate between both of them in iPXE somehow too. Hence,
> there is pretty good chance that configs for MB1 and MB2 are different.

multiboot/multiboot2 and module/module2 are aliases of each other. They
work interchangeably. Its the same way in iPXE.


> 
>>>> problem with booting over EFI vs MB1 so they'll be willing to take a
>>>> change there. I'll also disagree that BIOS is easier than EFI since with
>>>> EFI its just load the ELF into memory and set a few pointers in tags.
>>>> With BIOS it requires me to build up the memory map into a MB2 structure.
>>>
>>> Xen uses only these tags on legacy BIOS platforms: MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
>>> (well, nice to have but it can be also not provided), MULTIBOOT2_TAG_TYPE_MMAP (same
>>> as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO), MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME
>>> (same as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO) ,MULTIBOOT2_TAG_TYPE_CMDLINE,
>>> MULTIBOOT2_TAG_TYPE_MODULE. I do not mention MULTIBOOT2_TAG_TYPE_END which
>>> is obvious. So, if you are real hardcore minimalist then you have to provide
>>> MULTIBOOT2_TAG_TYPE_CMDLINE and MULTIBOOT2_TAG_TYPE_MODULE. All of them
>>> are provided also on EFI. So, I do not see any reason to not provide MB2
>>> for legacy BIOS. And I do not think that it is very difficult to provide
>>> all optional tags mentioned above.
>>
>> I don't understand what you're attempting to convey here. You've listed
>> out a number of tags that I mentioned in my message that I don't have to
>> implement for EFI. You've basically reinforced my point that its easier
>> to implement this for EFI than BIOS. MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
>> and MULTIBOOT2_TAG_TYPE_MMAP are unused by Xen on EFI. It gets this info
> 
> I showed you that if you are real minimalist you can enable the same MB2 code
> on legacy BIOS and EFI. I do not understand your objection against providing
> MB2 in iPXE on legacy BIOS if you do not need extra code (maybe a few #ifdefs).
> Though I am not going to convince you. It is your choice but I am still thinking
> that it is wrong choice.

Its not my choice. Its the feedback I've received from upstream.

> 
> By the way, does iPXE check MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST in Xen header.
> If it does (it should) and do not understand MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO and
> MULTIBOOT2_TAG_TYPE_MMAP then it should fail.

It does but I know that Xen doesn't use that information if Boot
Services are available by code inspection. Which is what my comments are
related to.

> 
>> from a call to GetMemoryMap(). You actually reminded me of another bug.
>> Calling ExitBootServices() on Grub and letting it pass the memory info
>> causes Xen to fail to load.
> 
> How come... Which GRUB version do you use? Xen clearly says that it needs
> boot services (look into MB2 header). So, GRUB is not allowed to call
> ExitBootServices(). If it does then it is GRUB bug.

No. That's not how it works at all. To quote 3.1.12 of the Multiboot2
spec...

"This tag indicates that payload supports starting without terminating
boot services."

This tag is not required to be respected but instead means that the
payload supports using boot services. Additionally section 3.6.3 which
talks about passing MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO states...

"This tag may not be provided by some boot loaders on EFI platforms if
EFI boot services are enabled and available for the loaded image (EFI
boot services not terminated tag exists in Multiboot2 information
structure)."

And section 3.6.8 talks about passing MULTIBOOT2_TAG_TYPE_MMAP states...

"This tag may not be provided by some boot loaders on EFI platforms if
EFI boot services are enabled and available for the loaded image (EFI
boot services not terminated tag exists in Multiboot2 information
structure)."


So for my iPXE support if the payload (in this case Xen) reports that it
supports not having boot services exited then I don't exit it and I
don't provide MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO or
MULTIBOOT2_TAG_TYPE_MMAP. Considering the fact that if Xen has boot
services available it ignores these two tags it seems what I've done
complies with the spec and complies with the only known full
implementation of MB2. (fwiw, the only implementations I know about are
tboot and your Xen patches. I've written a small application which dumps
out the data that was received but that was purely for debugging).


> 
>> Andrew helped me troubleshoot this and he discovered the fix. You've got
>> code:
>>
>> /* Store Xen image load base address in place accessible for 32-bit code. */
>> mov %r15d,%esi
>>
>> But if any of the checks under the run_bs: label specifically:
>> - /* Are EFI boot services available? */
>> - /* Is EFI SystemTable address provided by boot loader? */
>> - /* Is EFI ImageHandle address provided by boot loader? */
>>
>> Will not run the mov instruction and then fail to boot. Its only if any
>> of these are false will it attempt to use the tags mentioned above as well.
> 
> OK, this is a bug and I will fix it. However, this is not related to
> ExitBootServices() call in GRUB2.

Well it is. Because if boot services are not available then to goes the
path of the bug.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 20:28               ` Daniel Kiper
@ 2017-01-12 22:23                 ` Doug Goldstein
  2017-01-13  0:04                   ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-12 22:23 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 5964 bytes --]

On 1/12/17 2:28 PM, Daniel Kiper wrote:
> On Thu, Jan 12, 2017 at 09:52:15AM -0600, Doug Goldstein wrote:
>> On 1/12/17 6:50 AM, Daniel Kiper wrote:
>>> On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
>>>> On 1/11/17 1:47 PM, Daniel Kiper wrote:
>>>>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
>>>>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
>>>>>>> On 12/5/16 4:25 PM, Daniel Kiper wrote:
>>>>>>
>>>>>>>> diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
>>>>>>>> index 62c010e..dc857d8 100644
>>>>>>>> --- a/xen/arch/x86/efi/efi-boot.h
>>>>>>>> +++ b/xen/arch/x86/efi/efi-boot.h
>>>>>>>> @@ -146,6 +146,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>>>>>  {
>>>>>>>>      struct e820entry *e;
>>>>>>>>      unsigned int i;
>>>>>>>> +    /* Check for extra mem for mbi data if Xen is loaded via multiboot2 protocol. */
>>>>>>>> +    UINTN extra_mem = efi_enabled(EFI_LOADER) ? 0 : (64 << 10);
>>>>>>>
>>>>>>> Just wondering where the constant came from? And if there should be a
>>>>>>> little bit of information about it. To me its just weird to shift 64.
>>>>>>
>>>>>> Its the size of the stack used in the assembly code.
>>>>>
>>>>> No, it is trampoline region size.
>>>>
>>>> trampoline + stack in head.S We take the address where we're going to
>>>> copy the trampoline and set the stack to 0x10000 past it.
>>>
>>> I suppose that you think about this:
>>>
>>>         /* Switch to low-memory stack.  */
>>>         mov     sym_fs(trampoline_phys),%edi
>>>         lea     0x10000(%edi),%esp
>>>
>>> However, trampoline region size is (should be) 64 KiB. No way. Please
>>> look below for more details.
>>
>> The trampoline + stack are 64kb together. The stack grows down and the
>> trampoline grows up. The stack starts at 64kb past the start of the
>> trampoline. %edi is the start of the trampoline.
> 
> Yep. I think that right now we are on the same boat.
> 
>>>>>>>>      /* Populate E820 table and check trampoline area availability. */
>>>>>>>>      e = e820map - 1;
>>>>>>>> @@ -168,7 +170,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
>>>>>>>>              /* fall through */
>>>>>>>>          case EfiConventionalMemory:
>>>>>>>>              if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 &&
>>>>>>>> -                 len >= cfg.size && desc->PhysicalStart + len > cfg.addr )
>>>>>>>> +                 len >= cfg.size + extra_mem &&
>>>>>>>> +                 desc->PhysicalStart + len > cfg.addr )
>>>>>>>>                  cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK;
>>>>>>>
>>>>>>> So this is where the current series blows up and fails on real hardware.
>>>>>>
>>>>>> Honestly this was my misunderstanding and this shouldn't ever be used to
>>>>>> get memory for the trampoline. This also has the bug in it that it needs
>>>>>> to be:
>>>>>>
>>>>>> ASSERT(cfg.size > 0);
>>>>>> cfg.addr = (desc->PhysicalStart + len - (cfg.size + extra_mem) & PAGE_MASK;
>>>>>
>>>>> As I said earlier. This extra_mem stuff is (maybe) wrong and should be fixed
>>>>> in one way or another. Hmmm... It looks OK. I will double check it because
>>>>> I do not looked at this code long time and maybe I am missing something.
>>>>
>>>> cfg.size needs to be the size of the trampolines + stack.
>>>
>>> It looks that during some code rearrangement I moved one instruction too
>>> much to trampoline_bios_setup. So, I can agree that right now cfg.size
>>> should be properly initialized. Though it should be cfg.size = 64 << 10.
>>> Then extra_mem should be dropped.
>>
>> That's fine as long as its clear that 64kb is for the trampoline + the
>> stack.
> 
> OK, but there are two stacks. We talk about "low-memory stack". I will improve
> the comment.
> 
> [...]
> 
>>>>>> memory region). You need to use AllocatePages() otherwise you are
>>>>>> trampling memory that might have been allocated by the bootloader or any
>>>>>
>>>>> Bootloader code/data should be dead here.
>>>>
>>>> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
>>>> currently call ExitBootServices and a timer that iPXE has wired up has
>>>
>>> If you disable an important wheel in a machine you should not expect
>>> that the machine will work. Sorry! No way!
>>
>> Speak to your co-workers Konrad and Boris. We've had long email threads
>> about how certain hardware does not work with the way Xen calls
>> ExitBootServices.
> 
> Could you be more precise what is wrong? Or at least send links to
> relevant threads.

There have been several on the ML over the past 2 years. A quick Google
search turns these up.

http://xen.markmail.org/message/f6lx2ab4o2fch35r
https://lists.xenproject.org/archives/html/xen-devel/2015-01/msg03164.html


> 
>>>> some memory reserved down there and it was getting trampled. The real
>>>
>>> I still do not know why remnants of iPXE should run at this Xen boot stage.
>>> It looks like an iPXE bug and IMO it should be fixed first.
>>
>> Like I said above, its because on this machine I am unable to call Xen's
>> EBS.
> 
> I do not understand how ExitBootServices() call is related to iPXE timer remnants
> or so. Though if it is related somehow then I think that you should blame machine
> and/or iPXE designer/developer not Xen developer.

iPXE registers a callback for when EBS is called to clean up a timer.

> 
>>>> answer is that we need to fix up stock Xen to be able to always call EBS.
>>>
>>> It looks that ExitBootServices() is always called. So, I do not think that
>>> anything have to be fixed.
>>
>> It is commented out of this board using the patchset that Konrad
>> submitted to the ML years ago.
> 
> I do not know what patchset do you mean. Could you send it?
> 

See the above link.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 22:20                   ` Doug Goldstein
@ 2017-01-12 23:44                     ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-12 23:44 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 04:20:00PM -0600, Doug Goldstein wrote:
> On 1/12/17 3:45 PM, Daniel Kiper wrote:
> > On Thu, Jan 12, 2017 at 01:46:41PM -0600, Doug Goldstein wrote:
> >> On 1/12/17 1:30 PM, Daniel Kiper wrote:
> >>> On Thu, Jan 12, 2017 at 09:44:59AM -0600, Doug Goldstein wrote:
> >>>> view there's no reason for adding MB2 support for BIOS since it provides
> >>>> no advantage over MB1 when booting from the BIOS. Now MB2 solves a
> >>>
> >>> From your point of view maybe it does not. However, from user point of view it may.
> >>> If you have support for MB2 on legacy BIOS and EFI platforms then you can boot Xen
> >>> on both platforms without changing anything in boot config files. Otherwise you have
> >>> to prepare separate configuration for different platforms.
> >>
> >> Neither Grub nor iPXE require different configs for MB1 vs MB2 so I'm
> >> not seeing the validity of this logic.
> >
> > Hmmm... This is interesting. I do not know iPXE, however, in GRUB you must
> > use multiboot/module for MB1 and multiboot2/module2 for MB2. I suppose that
> > you have to differentiate between both of them in iPXE somehow too. Hence,
> > there is pretty good chance that configs for MB1 and MB2 are different.
>
> multiboot/multiboot2 and module/module2 are aliases of each other. They
> work interchangeably. Its the same way in iPXE.

If you carefully look at GRUB2 code and how multiboot and multiboot2
modules are build you quickly realize that they are not aliases.
Though I do not how it works in iPXE.

> >>>> problem with booting over EFI vs MB1 so they'll be willing to take a
> >>>> change there. I'll also disagree that BIOS is easier than EFI since with
> >>>> EFI its just load the ELF into memory and set a few pointers in tags.
> >>>> With BIOS it requires me to build up the memory map into a MB2 structure.
> >>>
> >>> Xen uses only these tags on legacy BIOS platforms: MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> >>> (well, nice to have but it can be also not provided), MULTIBOOT2_TAG_TYPE_MMAP (same
> >>> as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO), MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME
> >>> (same as MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO) ,MULTIBOOT2_TAG_TYPE_CMDLINE,
> >>> MULTIBOOT2_TAG_TYPE_MODULE. I do not mention MULTIBOOT2_TAG_TYPE_END which
> >>> is obvious. So, if you are real hardcore minimalist then you have to provide
> >>> MULTIBOOT2_TAG_TYPE_CMDLINE and MULTIBOOT2_TAG_TYPE_MODULE. All of them
> >>> are provided also on EFI. So, I do not see any reason to not provide MB2
> >>> for legacy BIOS. And I do not think that it is very difficult to provide
> >>> all optional tags mentioned above.
> >>
> >> I don't understand what you're attempting to convey here. You've listed
> >> out a number of tags that I mentioned in my message that I don't have to
> >> implement for EFI. You've basically reinforced my point that its easier
> >> to implement this for EFI than BIOS. MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
> >> and MULTIBOOT2_TAG_TYPE_MMAP are unused by Xen on EFI. It gets this info
> >
> > I showed you that if you are real minimalist you can enable the same MB2 code
> > on legacy BIOS and EFI. I do not understand your objection against providing
> > MB2 in iPXE on legacy BIOS if you do not need extra code (maybe a few #ifdefs).
> > Though I am not going to convince you. It is your choice but I am still thinking
> > that it is wrong choice.
>
> Its not my choice. Its the feedback I've received from upstream.

OK, they are iPXE maintainers. Though it still does not change my
opinion about their decision.

> > By the way, does iPXE check MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST in Xen header.
> > If it does (it should) and do not understand MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO and
> > MULTIBOOT2_TAG_TYPE_MMAP then it should fail.
>
> It does but I know that Xen doesn't use that information if Boot
> Services are available by code inspection. Which is what my comments are
> related to.

I am not sure that you correctly understood what I mean. Please read
multiboot2 "Information request header tag" section for more details.
iPXE should obey this rule even if you do not provide MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO
and MULTIBOOT2_TAG_TYPE_MMAP. The same is relevant for other tags in
image header. To be precise: I mean that iPXE should complain if it
sees __REQUESTS__ for unknown tags.

> >> from a call to GetMemoryMap(). You actually reminded me of another bug.
> >> Calling ExitBootServices() on Grub and letting it pass the memory info
> >> causes Xen to fail to load.
> >
> > How come... Which GRUB version do you use? Xen clearly says that it needs
> > boot services (look into MB2 header). So, GRUB is not allowed to call
> > ExitBootServices(). If it does then it is GRUB bug.
>
> No. That's not how it works at all. To quote 3.1.12 of the Multiboot2
> spec...
>
> "This tag indicates that payload supports starting without terminating
> boot services."
>
> This tag is not required to be respected but instead means that the
> payload supports using boot services. Additionally section 3.6.3 which

Ahhh... Right, I forgot about that.

> talks about passing MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO states...
>
> "This tag may not be provided by some boot loaders on EFI platforms if
> EFI boot services are enabled and available for the loaded image (EFI
> boot services not terminated tag exists in Multiboot2 information
> structure)."
>
> And section 3.6.8 talks about passing MULTIBOOT2_TAG_TYPE_MMAP states...
>
> "This tag may not be provided by some boot loaders on EFI platforms if
> EFI boot services are enabled and available for the loaded image (EFI
> boot services not terminated tag exists in Multiboot2 information
> structure)."
>
> So for my iPXE support if the payload (in this case Xen) reports that it
> supports not having boot services exited then I don't exit it and I
> don't provide MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO or
> MULTIBOOT2_TAG_TYPE_MMAP. Considering the fact that if Xen has boot
> services available it ignores these two tags it seems what I've done
> complies with the spec and complies with the only known full
> implementation of MB2. (fwiw, the only implementations I know about are
> tboot and your Xen patches. I've written a small application which dumps
> out the data that was received but that was purely for debugging).

Yep, you can do that and I have never ever said that you have to provide both
above mentioned tags. Even on legacy BIOS platforms.

> >> Andrew helped me troubleshoot this and he discovered the fix. You've got
> >> code:
> >>
> >> /* Store Xen image load base address in place accessible for 32-bit code. */
> >> mov %r15d,%esi
> >>
> >> But if any of the checks under the run_bs: label specifically:
> >> - /* Are EFI boot services available? */
> >> - /* Is EFI SystemTable address provided by boot loader? */
> >> - /* Is EFI ImageHandle address provided by boot loader? */
> >>
> >> Will not run the mov instruction and then fail to boot. Its only if any
> >> of these are false will it attempt to use the tags mentioned above as well.
> >
> > OK, this is a bug and I will fix it. However, this is not related to
> > ExitBootServices() call in GRUB2.
>
> Well it is. Because if boot services are not available then to goes the
> path of the bug.

By chance you have triggered this bug by shutting down boot services in the
boot loader but it is also possible to do that in a bit different way
unrelated to the EFI stuff at all.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-12 22:23                 ` Doug Goldstein
@ 2017-01-13  0:04                   ` Daniel Kiper
  2017-01-13  0:35                     ` Doug Goldstein
  2017-01-13  0:37                     ` Doug Goldstein
  0 siblings, 2 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-13  0:04 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei

On Thu, Jan 12, 2017 at 04:23:59PM -0600, Doug Goldstein wrote:
> On 1/12/17 2:28 PM, Daniel Kiper wrote:
> > On Thu, Jan 12, 2017 at 09:52:15AM -0600, Doug Goldstein wrote:
> >> On 1/12/17 6:50 AM, Daniel Kiper wrote:
> >>> On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
> >>>> On 1/11/17 1:47 PM, Daniel Kiper wrote:
> >>>>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
> >>>>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:

[...]

> >>>>>> memory region). You need to use AllocatePages() otherwise you are
> >>>>>> trampling memory that might have been allocated by the bootloader or any
> >>>>>
> >>>>> Bootloader code/data should be dead here.
> >>>>
> >>>> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
> >>>> currently call ExitBootServices and a timer that iPXE has wired up has
> >>>
> >>> If you disable an important wheel in a machine you should not expect
> >>> that the machine will work. Sorry! No way!
> >>
> >> Speak to your co-workers Konrad and Boris. We've had long email threads
> >> about how certain hardware does not work with the way Xen calls
> >> ExitBootServices.
> >
> > Could you be more precise what is wrong? Or at least send links to
> > relevant threads.
>
> There have been several on the ML over the past 2 years. A quick Google
> search turns these up.
>
> http://xen.markmail.org/message/f6lx2ab4o2fch35r
> https://lists.xenproject.org/archives/html/xen-devel/2015-01/msg03164.html

This is more or less what I expected. However, IIRC, it was not related
to ExitBootServices() itself. The problem was that some runtime services
code lived in boot services code and data regions. So, I suppose that if
you map boot services code and data regions with runtime services code
and data everything should work. However, I have just realized that we
need an option to enable this functionality from GRUB2 command line.
Though you can do a test by setting map_bs to 1 at the beginning of
efi_multiboot2(). Do not forget to enable ExitBootServices() call in Xen.

> >>>> some memory reserved down there and it was getting trampled. The real
> >>>
> >>> I still do not know why remnants of iPXE should run at this Xen boot stage.
> >>> It looks like an iPXE bug and IMO it should be fixed first.
> >>
> >> Like I said above, its because on this machine I am unable to call Xen's
> >> EBS.
> >
> > I do not understand how ExitBootServices() call is related to iPXE timer remnants
> > or so. Though if it is related somehow then I think that you should blame machine
> > and/or iPXE designer/developer not Xen developer.
>
> iPXE registers a callback for when EBS is called to clean up a timer.

Could not you unregister this callback just before jump to the Xen image?
I do not think it is needed for Xen boot.

Daniel

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-13  0:04                   ` Daniel Kiper
@ 2017-01-13  0:35                     ` Doug Goldstein
  2017-01-13  0:37                     ` Doug Goldstein
  1 sibling, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-13  0:35 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 3140 bytes --]

On 1/12/17 6:04 PM, Daniel Kiper wrote:
> On Thu, Jan 12, 2017 at 04:23:59PM -0600, Doug Goldstein wrote:
>> On 1/12/17 2:28 PM, Daniel Kiper wrote:
>>> On Thu, Jan 12, 2017 at 09:52:15AM -0600, Doug Goldstein wrote:
>>>> On 1/12/17 6:50 AM, Daniel Kiper wrote:
>>>>> On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
>>>>>> On 1/11/17 1:47 PM, Daniel Kiper wrote:
>>>>>>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
>>>>>>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
> 
> [...]
> 
>>>>>>>> memory region). You need to use AllocatePages() otherwise you are
>>>>>>>> trampling memory that might have been allocated by the bootloader or any
>>>>>>>
>>>>>>> Bootloader code/data should be dead here.
>>>>>>
>>>>>> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
>>>>>> currently call ExitBootServices and a timer that iPXE has wired up has
>>>>>
>>>>> If you disable an important wheel in a machine you should not expect
>>>>> that the machine will work. Sorry! No way!
>>>>
>>>> Speak to your co-workers Konrad and Boris. We've had long email threads
>>>> about how certain hardware does not work with the way Xen calls
>>>> ExitBootServices.
>>>
>>> Could you be more precise what is wrong? Or at least send links to
>>> relevant threads.
>>
>> There have been several on the ML over the past 2 years. A quick Google
>> search turns these up.
>>
>> http://xen.markmail.org/message/f6lx2ab4o2fch35r
>> https://lists.xenproject.org/archives/html/xen-devel/2015-01/msg03164.html
> 
> This is more or less what I expected. However, IIRC, it was not related
> to ExitBootServices() itself. The problem was that some runtime services
> code lived in boot services code and data regions. So, I suppose that if
> you map boot services code and data regions with runtime services code
> and data everything should work. However, I have just realized that we
> need an option to enable this functionality from GRUB2 command line.
> Though you can do a test by setting map_bs to 1 at the beginning of
> efi_multiboot2(). Do not forget to enable ExitBootServices() call in Xen.
> 
>>>>>> some memory reserved down there and it was getting trampled. The real
>>>>>
>>>>> I still do not know why remnants of iPXE should run at this Xen boot stage.
>>>>> It looks like an iPXE bug and IMO it should be fixed first.
>>>>
>>>> Like I said above, its because on this machine I am unable to call Xen's
>>>> EBS.
>>>
>>> I do not understand how ExitBootServices() call is related to iPXE timer remnants
>>> or so. Though if it is related somehow then I think that you should blame machine
>>> and/or iPXE designer/developer not Xen developer.
>>
>> iPXE registers a callback for when EBS is called to clean up a timer.
> 
> Could not you unregister this callback just before jump to the Xen image?
> I do not think it is needed for Xen boot.

Yep. Already done and merged. But my point is we should prefer to use
AllocatePages() and only fall back to trampling any conventional memory
region if the call didn't work.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms
  2017-01-13  0:04                   ` Daniel Kiper
  2017-01-13  0:35                     ` Doug Goldstein
@ 2017-01-13  0:37                     ` Doug Goldstein
  1 sibling, 0 replies; 64+ messages in thread
From: Doug Goldstein @ 2017-01-13  0:37 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, xen-devel, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 2443 bytes --]

On 1/12/17 6:04 PM, Daniel Kiper wrote:
> On Thu, Jan 12, 2017 at 04:23:59PM -0600, Doug Goldstein wrote:
>> On 1/12/17 2:28 PM, Daniel Kiper wrote:
>>> On Thu, Jan 12, 2017 at 09:52:15AM -0600, Doug Goldstein wrote:
>>>> On 1/12/17 6:50 AM, Daniel Kiper wrote:
>>>>> On Wed, Jan 11, 2017 at 02:20:15PM -0600, Doug Goldstein wrote:
>>>>>> On 1/11/17 1:47 PM, Daniel Kiper wrote:
>>>>>>> On Tue, Jan 10, 2017 at 02:51:27PM -0600, Doug Goldstein wrote:
>>>>>>>> On 1/9/17 7:37 PM, Doug Goldstein wrote:
> 
> [...]
> 
>>>>>>>> memory region). You need to use AllocatePages() otherwise you are
>>>>>>>> trampling memory that might have been allocated by the bootloader or any
>>>>>>>
>>>>>>> Bootloader code/data should be dead here.
>>>>>>
>>>>>> Correct. Unfortunately on my Lenovo laptop and my Intel NUCs I can't
>>>>>> currently call ExitBootServices and a timer that iPXE has wired up has
>>>>>
>>>>> If you disable an important wheel in a machine you should not expect
>>>>> that the machine will work. Sorry! No way!
>>>>
>>>> Speak to your co-workers Konrad and Boris. We've had long email threads
>>>> about how certain hardware does not work with the way Xen calls
>>>> ExitBootServices.
>>>
>>> Could you be more precise what is wrong? Or at least send links to
>>> relevant threads.
>>
>> There have been several on the ML over the past 2 years. A quick Google
>> search turns these up.
>>
>> http://xen.markmail.org/message/f6lx2ab4o2fch35r
>> https://lists.xenproject.org/archives/html/xen-devel/2015-01/msg03164.html
> 
> This is more or less what I expected. However, IIRC, it was not related
> to ExitBootServices() itself. The problem was that some runtime services
> code lived in boot services code and data regions. So, I suppose that if
> you map boot services code and data regions with runtime services code
> and data everything should work. However, I have just realized that we
> need an option to enable this functionality from GRUB2 command line.
> Though you can do a test by setting map_bs to 1 at the beginning of
> efi_multiboot2(). Do not forget to enable ExitBootServices() call in Xen.

On Intel NUCs, Super Micro boards and others, you are unable to call
ExitBootServices() without having called SetVirtualAddressMap(). If you
follow through both threads you'll see there's more than just map_bs.
Konrad also proposed adding /noexitbs

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2017-01-11 20:46 ` [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
@ 2017-01-13 15:45   ` Doug Goldstein
  2017-01-13 16:18     ` Daniel Kiper
  0 siblings, 1 reply; 64+ messages in thread
From: Doug Goldstein @ 2017-01-13 15:45 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: jgross, sstabellini, andrew.cooper3, pgnet.dev, ning.sun,
	julien.grall, jbeulich, qiaowei.ren, gang.wei, fu.wei


[-- Attachment #1.1.1: Type: text/plain, Size: 1559 bytes --]

On 1/11/17 2:46 PM, Daniel Kiper wrote:
> On Mon, Dec 05, 2016 at 11:25:05PM +0100, Daniel Kiper wrote:
>> Hi,
>>
>> I am sending eleventh version of multiboot2 protocol support for
>> legacy BIOS and EFI platforms. This patch series release contains
>> fixes for all known issues.
>>
>> 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 is short list of changes since v10:
>>   - changed patches: 06 (small change suggested by Jan).
> 
> Guys, I am going to release next version in 1-2 weeks. If you
> have more comments for current one please post them ASAP.
> I would like to have this patch series come into 4.9.
> 
> Thanks,
> 
> Daniel
> 

Daniel,

I have a more immediate deadline from my $EMPLOYER. I plan on posting
the series that I am using for my requirements. In my situation I need
to boot EFI and the machine I'm booting requires multiple initrds that
the dom0 kernel glues together. Hence my need for this series. It
includes all the changes we've discussed in this thread. Hopefully it
will help you out to post v12.

-- 
Doug Goldstein


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 959 bytes --]

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

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

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

* Re: [PATCH v11 00/13] x86: multiboot2 protocol support
  2017-01-13 15:45   ` Doug Goldstein
@ 2017-01-13 16:18     ` Daniel Kiper
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Kiper @ 2017-01-13 16:18 UTC (permalink / raw)
  To: Doug Goldstein
  Cc: jgross, sstabellini, konrad.wilk, andrew.cooper3, pgnet.dev,
	ning.sun, julien.grall, jbeulich, xen-devel, qiaowei.ren,
	gang.wei, fu.wei

On Fri, Jan 13, 2017 at 09:45:13AM -0600, Doug Goldstein wrote:
> On 1/11/17 2:46 PM, Daniel Kiper wrote:
> > On Mon, Dec 05, 2016 at 11:25:05PM +0100, Daniel Kiper wrote:
> >> Hi,
> >>
> >> I am sending eleventh version of multiboot2 protocol support for
> >> legacy BIOS and EFI platforms. This patch series release contains
> >> fixes for all known issues.
> >>
> >> 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 is short list of changes since v10:
> >>   - changed patches: 06 (small change suggested by Jan).
> >
> > Guys, I am going to release next version in 1-2 weeks. If you
> > have more comments for current one please post them ASAP.
> > I would like to have this patch series come into 4.9.
> >
> > Thanks,
> >
> > Daniel
> >
>
> Daniel,
>
> I have a more immediate deadline from my $EMPLOYER. I plan on posting
> the series that I am using for my requirements. In my situation I need
> to boot EFI and the machine I'm booting requires multiple initrds that
> the dom0 kernel glues together. Hence my need for this series. It
> includes all the changes we've discussed in this thread. Hopefully it
> will help you out to post v12.

If it helps you somehow please do. It will be nice if you CC me, mark
somehow patches changed in comparison to v11 and describe what is fixed.
Then I will incorporate all needed changes into v12.

Daniel

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

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

end of thread, other threads:[~2017-01-13 16:18 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-05 22:25 [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 01/13] x86: add " Daniel Kiper
2017-01-10  1:21   ` Doug Goldstein
2017-01-10  8:38     ` Jan Beulich
2017-01-10 15:19       ` Doug Goldstein
2016-12-05 22:25 ` [PATCH v11 02/13] efi: create efi_enabled() Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 03/13] x86: allow EFI reboot method neither on EFI platforms Daniel Kiper
2016-12-07 13:18   ` Jan Beulich
2016-12-07 17:25     ` Daniel Kiper
2017-01-10  1:24     ` Doug Goldstein
2017-01-10  8:21       ` Jan Beulich
2016-12-05 22:25 ` [PATCH v11 04/13] x86: properly calculate xen ELF end of image address Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 05/13] efi: build xen.gz with EFI code Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 06/13] efi: create new early memory allocator Daniel Kiper
2016-12-06  8:27   ` Jan Beulich
2016-12-09 18:03   ` Julien Grall
2016-12-12 14:27     ` Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 07/13] x86: add multiboot2 protocol support for EFI platforms Daniel Kiper
2016-12-16 13:38   ` Andrew Cooper
2016-12-16 13:50     ` Jan Beulich
2017-01-10  1:37   ` Doug Goldstein
2017-01-10 20:51     ` Doug Goldstein
2017-01-11 19:47       ` Daniel Kiper
2017-01-11 20:20         ` Doug Goldstein
2017-01-12 10:22           ` Jan Beulich
2017-01-12 12:50           ` Daniel Kiper
2017-01-12 15:52             ` Doug Goldstein
2017-01-12 20:28               ` Daniel Kiper
2017-01-12 22:23                 ` Doug Goldstein
2017-01-13  0:04                   ` Daniel Kiper
2017-01-13  0:35                     ` Doug Goldstein
2017-01-13  0:37                     ` Doug Goldstein
2017-01-11 19:08     ` Daniel Kiper
2017-01-11 19:50       ` Doug Goldstein
2017-01-11 20:36         ` Daniel Kiper
2017-01-11 20:31       ` Doug Goldstein
2017-01-12 12:18         ` Daniel Kiper
2017-01-12 15:44           ` Doug Goldstein
2017-01-12 19:30             ` Daniel Kiper
2017-01-12 19:46               ` Doug Goldstein
2017-01-12 21:45                 ` Daniel Kiper
2017-01-12 22:20                   ` Doug Goldstein
2017-01-12 23:44                     ` Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 08/13] x86/boot: implement early command line parser in C Daniel Kiper
2016-12-07 13:43   ` Jan Beulich
2016-12-07 17:27     ` Daniel Kiper
2016-12-08 23:08       ` Daniel Kiper
2016-12-09  8:19         ` Jan Beulich
2016-12-09 13:32           ` Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 09/13] x86: change default load address from 1 MiB to 2 MiB Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 10/13] x86/setup: use XEN_IMG_OFFSET instead of Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 11/13] x86: make Xen early boot code relocatable Daniel Kiper
2017-01-10  2:05   ` Doug Goldstein
2017-01-11 20:05     ` Daniel Kiper
2017-01-11 20:23       ` Doug Goldstein
2016-12-05 22:25 ` [PATCH v11 12/13] x86/boot: rename sym_phys() to sym_offs() Daniel Kiper
2016-12-05 22:25 ` [PATCH v11 13/13] x86: add multiboot2 protocol support for relocatable images Daniel Kiper
2016-12-16 15:59 ` [PATCH v11 00/13] x86: multiboot2 protocol support Doug Goldstein
2017-01-10 23:12 ` [PATCH 2/??] memory allocation fix Doug Goldstein
2017-01-11 20:46 ` [PATCH v11 00/13] x86: multiboot2 protocol support Daniel Kiper
2017-01-13 15:45   ` Doug Goldstein
2017-01-13 16:18     ` Daniel Kiper
2017-01-12 17:46 ` Doug Goldstein
2017-01-12 18:26   ` Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.