Discussion:
[PATCH v5 06/20] xen: rearrange xen/init.c to prepare it for Xen PVH mode
Juergen Gross
2018-11-21 14:28:41 UTC
Permalink
Rearrange grub-core/kern/xen/init.c to prepare adding PVH mode support
to it. This includes putting some code under #ifdef GRUB_MACHINE_XEN
as it will not be used when running as PVH.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
grub-core/kern/xen/init.c | 60 +++++++++++++++++++++++++++--------------------
1 file changed, 34 insertions(+), 26 deletions(-)

diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
index 29f5bc23d..10007b411 100644
--- a/grub-core/kern/xen/init.c
+++ b/grub-core/kern/xen/init.c
@@ -41,9 +41,11 @@ grub_size_t grub_xen_n_allocated_shared_pages;
static grub_xen_mfn_t
grub_xen_ptr2mfn (void *ptr)
{
+#ifdef GRUB_MACHINE_XEN
grub_xen_mfn_t *mfn_list =
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE];
+#endif
}

void *
@@ -104,18 +106,6 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
{
}

-static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
- __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
-
-#ifdef __x86_64__
-#define NUMBER_OF_LEVELS 4
-#else
-#define NUMBER_OF_LEVELS 3
-#endif
-
-#define LOG_POINTERS_PER_PAGE 9
-#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
-
void
grub_xen_store_send (const void *buf_, grub_size_t len)
{
@@ -337,6 +327,19 @@ grub_xen_setup_gnttab (void)
grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
}

+#ifdef GRUB_MACHINE_XEN
+static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
+ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+#ifdef __x86_64__
+#define NUMBER_OF_LEVELS 4
+#else
+#define NUMBER_OF_LEVELS 3
+#endif
+
+#define LOG_POINTERS_PER_PAGE 9
+#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
+
#define MAX_N_UNUSABLE_PAGES 4

static int
@@ -529,13 +532,30 @@ map_all_pages (void)
grub_mm_init_region ((void *) heap_start, heap_end - heap_start);
}

+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+ grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
+ grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
+ if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
+ return GRUB_ERR_NONE;
+
+ hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
+ GRUB_MEMORY_RESERVED, hook_data);
+
+ return GRUB_ERR_NONE;
+}
+#endif
+
extern char _end[];

void
grub_machine_init (void)
{
+#ifdef GRUB_MACHINE_XEN
#ifdef __i386__
grub_xen_vm_assist (VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3);
+#endif
#endif

grub_modbase = ALIGN_UP ((grub_addr_t) _end
@@ -544,7 +564,9 @@ grub_machine_init (void)

grub_xen_setup_gnttab ();

+#ifdef GRUB_MACHINE_XEN
map_all_pages ();
+#endif

grub_console_init ();

@@ -571,17 +593,3 @@ grub_machine_fini (int flags __attribute__ ((unused)))
grub_xendisk_fini ();
grub_boot_fini ();
}
-
-grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
-{
- grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
- grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
- if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
- return GRUB_ERR_NONE;
-
- hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
- GRUB_MEMORY_RESERVED, hook_data);
-
- return GRUB_ERR_NONE;
-}
--
2.16.4
Juergen Gross
2018-11-21 14:28:42 UTC
Permalink
grub_xen_ptr2mfn() returns the machine frame number for a given pointer
value. For Xen-PVH guests this is just the PFN. Add the PVH specific
variant.

Signed-off-by: Juergen Gross <***@suse.com>
---
V5: new patch (Daniel Kiper)
---
grub-core/kern/xen/init.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
index 10007b411..a23dad633 100644
--- a/grub-core/kern/xen/init.c
+++ b/grub-core/kern/xen/init.c
@@ -45,6 +45,8 @@ grub_xen_ptr2mfn (void *ptr)
grub_xen_mfn_t *mfn_list =
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE];
+#else
+ return (grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE;
#endif
}
--
2.16.4
Daniel Kiper
2018-11-27 20:02:44 UTC
Permalink
Post by Juergen Gross
grub_xen_ptr2mfn() returns the machine frame number for a given pointer
value. For Xen-PVH guests this is just the PFN. Add the PVH specific
variant.
Reviewed-by: Daniel Kiper <***@oracle.com>

Daniel
Juergen Gross
2018-11-21 14:28:38 UTC
Permalink
Initialize the grant tab in a dedicated function. This will enable
using it for PVH guests, too.

Call the new function from grub_machine_init() as this will later
be common between Xen PV and Xen PVH mode.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V2: update commit message (Daniel Kiper)
---
grub-core/kern/xen/init.c | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
index 0559c033c..29f5bc23d 100644
--- a/grub-core/kern/xen/init.c
+++ b/grub-core/kern/xen/init.c
@@ -318,6 +318,25 @@ grub_xenstore_dir (const char *dir,

unsigned long gntframe = 0;

+static void
+grub_xen_setup_gnttab (void)
+{
+ struct gnttab_set_version gnttab_setver;
+ struct gnttab_setup_table gnttab_setup;
+
+ grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
+
+ gnttab_setver.version = 1;
+ grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1);
+
+ grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup));
+ gnttab_setup.dom = DOMID_SELF;
+ gnttab_setup.nr_frames = 1;
+ gnttab_setup.frame_list.p = &gntframe;
+
+ grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
+}
+
#define MAX_N_UNUSABLE_PAGES 4

static int
@@ -357,26 +376,12 @@ map_all_pages (void)
(grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
grub_uint64_t *pg = (grub_uint64_t *) window;
grub_uint64_t oldpgstart, oldpgend;
- struct gnttab_setup_table gnttab_setup;
- struct gnttab_set_version gnttab_setver;
grub_size_t n_unusable_pages = 0;
struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES];

if (total_pages > MAX_TOTAL_PAGES - 4)
total_pages = MAX_TOTAL_PAGES - 4;

- grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
-
- gnttab_setver.version = 1;
- grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1);
-
- grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup));
- gnttab_setup.dom = DOMID_SELF;
- gnttab_setup.nr_frames = 1;
- gnttab_setup.frame_list.p = &gntframe;
-
- grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
-
for (j = 0; j < total_pages - n_unusable_pages; j++)
while (!grub_xen_is_page_usable (mfn_list[j]))
{
@@ -537,6 +542,8 @@ grub_machine_init (void)
+ GRUB_KERNEL_MACHINE_MOD_GAP,
GRUB_KERNEL_MACHINE_MOD_ALIGN);

+ grub_xen_setup_gnttab ();
+
map_all_pages ();

grub_console_init ();
--
2.16.4
Juergen Gross
2018-11-21 14:28:37 UTC
Permalink
Xen PVH guests will have the RSDP at an arbitrary address. Support that
by passing the RSDP address via the boot parameters to Linux.

Signed-off-by: Juergen Gross <***@suse.com>
---
V2: add oring 0x8000 to version field
V3: move including machine/kernel.h to patch 8 (Daniel Kiper)
V5: move acpi_rsdp_addr to struct linux_kernel_params (Peter Anvin)
---
grub-core/loader/i386/linux.c | 4 ++++
include/grub/i386/linux.h | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index c408b10d8..375ee80dc 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -508,6 +508,10 @@ grub_linux_boot (void)
}
}

+#ifdef GRUB_KERNEL_USE_RSDP_ADDR
+ linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr);
+#endif
+
mmap_size = find_mmap_size ();
/* Make sure that each size is aligned to a page boundary. */
cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096);
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index 60c7c3b5e..a96059311 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -210,8 +210,9 @@ struct linux_kernel_params
grub_uint32_t ist_command; /* 64 */
grub_uint32_t ist_event; /* 68 */
grub_uint32_t ist_perf_level; /* 6c */
+ grub_uint64_t acpi_rsdp_addr; /* 70 */

- grub_uint8_t padding5[0x80 - 0x70];
+ grub_uint8_t padding5[0x80 - 0x78];

grub_uint8_t hd0_drive_info[0x10]; /* 80 */
grub_uint8_t hd1_drive_info[0x10]; /* 90 */
--
2.16.4
Daniel Kiper
2018-11-27 19:52:27 UTC
Permalink
Post by Juergen Gross
Xen PVH guests will have the RSDP at an arbitrary address. Support that
by passing the RSDP address via the boot parameters to Linux.
Reviewed-by: Daniel Kiper <***@oracle.com>

Daniel
Juergen Gross
2018-11-21 14:28:45 UTC
Permalink
Add the code for the Xen PVH mode boot entry.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V3: clear %fs and %gs, too (Daniel Kiper)
use GRUB_MEMORY_MACHINE_PROT_STACK_SIZE for stack size (Daniel Kiper)
V5: reorder clearing segment regs (Daniel Kiper)
---
grub-core/kern/i386/xen/startup_pvh.S | 52 +++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)

diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S
index 69b8fdcca..363c31858 100644
--- a/grub-core/kern/i386/xen/startup_pvh.S
+++ b/grub-core/kern/i386/xen/startup_pvh.S
@@ -19,11 +19,63 @@

#include <config.h>
#include <grub/symbol.h>
+#include <grub/machine/memory.h>

.file "startup_pvh.S"
.text
+ .globl start, _start
+ .code32

+start:
+_start:
+ cld
+ lgdt gdtdesc
+ ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
+1:
+ movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax
+ mov %eax, %ds
+ mov %eax, %es
+ mov %eax, %fs
+ mov %eax, %gs
+ mov %eax, %ss
+ leal LOCAL(stack_end), %esp
+
+ /* Save address of start info structure. */
+ mov %ebx, pvh_start_info
+ call EXT_C(grub_main)
+ /* Doesn't return. */
+
+ .p2align 3
+gdt:
+ .word 0, 0
+ .byte 0, 0, 0, 0
+
+ /* -- code segment --
+ * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
+ * type = 32bit code execute/read, DPL = 0
+ */
+ .word 0xFFFF, 0
+ .byte 0, 0x9A, 0xCF, 0
+
+ /* -- data segment --
+ * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
+ * type = 32 bit data read/write, DPL = 0
+ */
+ .word 0xFFFF, 0
+ .byte 0, 0x92, 0xCF, 0
+
+ .p2align 3
+/* this is the GDT descriptor */
+gdtdesc:
+ .word 0x17 /* limit */
+ .long gdt /* addr */
+
+ .p2align 2
/* Saved pointer to start info structure. */
.globl pvh_start_info
pvh_start_info:
.long 0
+
+ .bss
+ .space GRUB_MEMORY_MACHINE_PROT_STACK_SIZE
+LOCAL(stack_end):
--
2.16.4
Juergen Gross
2018-11-21 14:28:39 UTC
Permalink
Some common code needs to be special cased for Xen PVH mode. This hits
mostly Xen PV mode specific areas.

Split include/grub/i386/pc/int_types.h off from
include/grub/i386/pc/int.h to support including this file later from
xen_pvh code without the grub_bios_interrupt definition.

Move definition of struct grub_e820_mmap_entry from
grub-core/mmap/i386/pc/mmap.c to include/grub/i386/memory.h in order
to make it usable from xen_pvh code.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V3: GRUB_MACHINE_XENPVH -> GRUB_MACHINE_XEN_PVH (Daniel Kiper)
split include/grub/i386/pc/int.h (Daniel Kiper)
move struct grub_e820_mmap_entry definition to header file
V5: minor style adjustments (Daniel Kiper)
---
grub-core/kern/i386/tsc.c | 2 +-
grub-core/mmap/i386/pc/mmap.c | 8 ------
include/grub/i386/memory.h | 7 +++++
include/grub/i386/pc/int.h | 36 +-----------------------
include/grub/i386/pc/int_types.h | 59 +++++++++++++++++++++++++++++++++++++++
include/grub/i386/tsc.h | 2 +-
include/grub/i386/xen/hypercall.h | 5 +++-
include/grub/kernel.h | 4 ++-
8 files changed, 76 insertions(+), 47 deletions(-)
create mode 100644 include/grub/i386/pc/int_types.h

diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
index f266eb131..9293b161d 100644
--- a/grub-core/kern/i386/tsc.c
+++ b/grub-core/kern/i386/tsc.c
@@ -65,7 +65,7 @@ grub_tsc_init (void)

tsc_boot_time = grub_get_tsc ();

-#ifdef GRUB_MACHINE_XEN
+#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XEN_PVH)
(void) (grub_tsc_calibrate_from_xen () || calibrate_tsc_hardcode());
#elif defined (GRUB_MACHINE_EFI)
(void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () || grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode());
diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c
index 609994516..6ab4f6730 100644
--- a/grub-core/mmap/i386/pc/mmap.c
+++ b/grub-core/mmap/i386/pc/mmap.c
@@ -42,14 +42,6 @@ extern grub_uint16_t grub_machine_mmaphook_kblow;
extern grub_uint16_t grub_machine_mmaphook_kbin16mb;
extern grub_uint16_t grub_machine_mmaphook_64kbin4gb;

-struct grub_e820_mmap_entry
-{
- grub_uint64_t addr;
- grub_uint64_t len;
- grub_uint32_t type;
-} GRUB_PACKED;
-
-
/* Helper for preboot. */
static int fill_hook (grub_uint64_t addr, grub_uint64_t size,
grub_memory_type_t type, void *data)
diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h
index 8bb6e1cbb..5cb607fb4 100644
--- a/include/grub/i386/memory.h
+++ b/include/grub/i386/memory.h
@@ -44,6 +44,13 @@

#include <grub/types.h>

+struct grub_e820_mmap_entry
+{
+ grub_uint64_t addr;
+ grub_uint64_t len;
+ grub_uint32_t type;
+} GRUB_PACKED;
+
grub_uint64_t grub_mmap_get_upper (void);
grub_uint64_t grub_mmap_get_lower (void);
grub_uint64_t grub_mmap_get_post64 (void);
diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h
index 16a53e4fe..a60104001 100644
--- a/include/grub/i386/pc/int.h
+++ b/include/grub/i386/pc/int.h
@@ -20,45 +20,11 @@
#define GRUB_INTERRUPT_MACHINE_HEADER 1

#include <grub/symbol.h>
-#include <grub/types.h>
-
-struct grub_bios_int_registers
-{
- grub_uint32_t eax;
- grub_uint16_t es;
- grub_uint16_t ds;
- grub_uint16_t flags;
- grub_uint16_t dummy;
- grub_uint32_t ebx;
- grub_uint32_t ecx;
- grub_uint32_t edi;
- grub_uint32_t esi;
- grub_uint32_t edx;
-};
-
-#define GRUB_CPU_INT_FLAGS_CARRY 0x1
-#define GRUB_CPU_INT_FLAGS_PARITY 0x4
-#define GRUB_CPU_INT_FLAGS_ADJUST 0x10
-#define GRUB_CPU_INT_FLAGS_ZERO 0x40
-#define GRUB_CPU_INT_FLAGS_SIGN 0x80
-#define GRUB_CPU_INT_FLAGS_TRAP 0x100
-#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200
-#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400
-#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800
-#ifdef GRUB_MACHINE_PCBIOS
-#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT
-#else
-#define GRUB_CPU_INT_FLAGS_DEFAULT 0
-#endif
+#include <grub/i386/pc/int_types.h>

void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno,
struct grub_bios_int_registers *regs)
__attribute__ ((regparm(3)));
-struct grub_i386_idt
-{
- grub_uint16_t limit;
- grub_uint32_t base;
-} GRUB_PACKED;

#ifdef GRUB_MACHINE_PCBIOS
extern struct grub_i386_idt *EXPORT_VAR(grub_realidt);
diff --git a/include/grub/i386/pc/int_types.h b/include/grub/i386/pc/int_types.h
new file mode 100644
index 000000000..2c5a69b63
--- /dev/null
+++ b/include/grub/i386/pc/int_types.h
@@ -0,0 +1,59 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_INTERRUPT_TYPES_MACHINE_HEADER
+#define GRUB_INTERRUPT_TYPES_MACHINE_HEADER 1
+
+#include <grub/types.h>
+
+#define GRUB_CPU_INT_FLAGS_CARRY 0x1
+#define GRUB_CPU_INT_FLAGS_PARITY 0x4
+#define GRUB_CPU_INT_FLAGS_ADJUST 0x10
+#define GRUB_CPU_INT_FLAGS_ZERO 0x40
+#define GRUB_CPU_INT_FLAGS_SIGN 0x80
+#define GRUB_CPU_INT_FLAGS_TRAP 0x100
+#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200
+#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400
+#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800
+#ifdef GRUB_MACHINE_PCBIOS
+#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT
+#else
+#define GRUB_CPU_INT_FLAGS_DEFAULT 0
+#endif
+
+struct grub_bios_int_registers
+{
+ grub_uint32_t eax;
+ grub_uint16_t es;
+ grub_uint16_t ds;
+ grub_uint16_t flags;
+ grub_uint16_t dummy;
+ grub_uint32_t ebx;
+ grub_uint32_t ecx;
+ grub_uint32_t edi;
+ grub_uint32_t esi;
+ grub_uint32_t edx;
+};
+
+struct grub_i386_idt
+{
+ grub_uint16_t limit;
+ grub_uint32_t base;
+} GRUB_PACKED;
+
+#endif
diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h
index a0aa2c573..324174ded 100644
--- a/include/grub/i386/tsc.h
+++ b/include/grub/i386/tsc.h
@@ -54,7 +54,7 @@ grub_get_tsc (void)
static __inline int
grub_cpu_is_tsc_supported (void)
{
-#ifndef GRUB_MACHINE_XEN
+#if !defined(GRUB_MACHINE_XEN) && !defined(GRUB_MACHINE_XEN_PVH)
grub_uint32_t a,b,c,d;
if (! grub_cpu_is_cpuid_supported ())
return 0;
diff --git a/include/grub/i386/xen/hypercall.h b/include/grub/i386/xen/hypercall.h
index 198ee94af..4e4c12a49 100644
--- a/include/grub/i386/xen/hypercall.h
+++ b/include/grub/i386/xen/hypercall.h
@@ -26,7 +26,10 @@ EXPORT_FUNC (grub_xen_hypercall) (grub_uint32_t callno, grub_uint32_t a0,
grub_uint32_t a1, grub_uint32_t a2,
grub_uint32_t a3, grub_uint32_t a4,
grub_uint32_t a5)
-__attribute__ ((regparm (3), cdecl));
+#ifdef GRUB_MACHINE_XEN
+ __attribute__ ((regparm (3), cdecl))
+#endif
+ ;

static inline int
grub_xen_sched_op (int cmd, void *arg)
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index ecd88ca72..133a37c8d 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -79,7 +79,9 @@ struct grub_module_info64
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \
|| defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \
|| defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \
- || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN)
+ || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \
+ || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \
+ || defined(GRUB_MACHINE_XEN_PVH)
/* FIXME: stack is between 2 heap regions. Move it. */
#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1
#endif
--
2.16.4
Juergen Gross
2018-11-21 14:28:44 UTC
Permalink
Add the hooks to current code needed for Xen PVH. They will be filled
with code later when the related functionality is being added.

loader/i386/linux.c needs to include machine/kernel.h now as it needs
to get GRUB_KERNEL_USE_RSDP_ADDR from there.

Signed-off-by: Juergen Gross <***@suse.com>
---
V3: xenpvh->xen_pvh (Daniel Kiper)
adjust copyright date (Roger Pau Monné)
V5: update commit message (Daniel Kiper)
move including xen/hvm/start_info.h to the sources really needing
it (Daniel Kiper)
---
grub-core/kern/i386/xen/pvh.c | 37 +++++++++++++++++++++++++++++++++++
grub-core/kern/i386/xen/startup_pvh.S | 29 +++++++++++++++++++++++++++
grub-core/kern/xen/init.c | 4 ++++
grub-core/loader/i386/linux.c | 1 +
include/grub/i386/xen_pvh/kernel.h | 30 ++++++++++++++++++++++++++++
include/grub/xen.h | 5 +++++
6 files changed, 106 insertions(+)
create mode 100644 grub-core/kern/i386/xen/pvh.c
create mode 100644 grub-core/kern/i386/xen/startup_pvh.S
create mode 100644 include/grub/i386/xen_pvh/kernel.h

diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
new file mode 100644
index 000000000..4f629b15e
--- /dev/null
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -0,0 +1,37 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/xen.h>
+#include <xen/hvm/start_info.h>
+#include <grub/machine/kernel.h>
+
+grub_uint64_t grub_rsdp_addr;
+
+void
+grub_xen_setup_pvh (void)
+{
+}
+
+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+}
diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S
new file mode 100644
index 000000000..69b8fdcca
--- /dev/null
+++ b/grub-core/kern/i386/xen/startup_pvh.S
@@ -0,0 +1,29 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+
+ .file "startup_pvh.S"
+ .text
+
+/* Saved pointer to start info structure. */
+ .globl pvh_start_info
+pvh_start_info:
+ .long 0
diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
index a23dad633..782ca7295 100644
--- a/grub-core/kern/xen/init.c
+++ b/grub-core/kern/xen/init.c
@@ -564,6 +564,10 @@ grub_machine_init (void)
+ GRUB_KERNEL_MACHINE_MOD_GAP,
GRUB_KERNEL_MACHINE_MOD_ALIGN);

+#ifdef GRUB_MACHINE_XEN_PVH
+ grub_xen_setup_pvh ();
+#endif
+
grub_xen_setup_gnttab ();

#ifdef GRUB_MACHINE_XEN
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 375ee80dc..b6015913b 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -35,6 +35,7 @@
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
+#include <grub/machine/kernel.h>

GRUB_MOD_LICENSE ("GPLv3+");

diff --git a/include/grub/i386/xen_pvh/kernel.h b/include/grub/i386/xen_pvh/kernel.h
new file mode 100644
index 000000000..2b7b8a129
--- /dev/null
+++ b/include/grub/i386/xen_pvh/kernel.h
@@ -0,0 +1,30 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER 1
+
+#ifndef ASM_FILE
+
+#define GRUB_KERNEL_USE_RSDP_ADDR 1
+
+extern grub_uint64_t EXPORT_VAR(grub_rsdp_addr);
+
+#endif /* ! ASM_FILE */
+
+#endif /* GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/xen.h b/include/grub/xen.h
index c31cc10c7..91cb7cf81 100644
--- a/include/grub/xen.h
+++ b/include/grub/xen.h
@@ -95,6 +95,11 @@ typedef grub_uint64_t grub_xen_mfn_t;
typedef grub_uint32_t grub_xen_mfn_t;
#endif
typedef unsigned int grub_xen_evtchn_t;
+
+#ifdef GRUB_MACHINE_XEN_PVH
+extern struct hvm_start_info *pvh_start_info;
+void grub_xen_setup_pvh (void);
+#endif
#endif

#endif
--
2.16.4
Daniel Kiper
2018-11-27 20:10:43 UTC
Permalink
Post by Juergen Gross
Add the hooks to current code needed for Xen PVH. They will be filled
with code later when the related functionality is being added.
loader/i386/linux.c needs to include machine/kernel.h now as it needs
to get GRUB_KERNEL_USE_RSDP_ADDR from there.
Reviewed-by: Daniel Kiper <***@oracle.com>

Daniel
Juergen Gross
2018-11-21 14:28:40 UTC
Permalink
With Xen PVH mode adding a new machine type the machine related headers
need to be present for the build to succeed. Most of the headers just
need to include the related common i386 headers. Add those to the tree.

Note that xen_pvh/int.h needs to include pc/int_types.h instead of
pc/int.h in order to avoid the definition of grub_bios_interrupt().

xen_pvh/memory.h needs to include coreboot/memory.h (like some other
<machine>/memory.h do as well) as this contains just the needed stubs.

Signed-off-by: Juergen Gross <***@suse.com>
---
V3: updated commit message (Daniel Kiper)
xenpvh->xen_pvh (Daniel Kiper)
V5: updated commit message (Daniel Kiper)
---
include/grub/i386/xen_pvh/boot.h | 1 +
include/grub/i386/xen_pvh/console.h | 1 +
include/grub/i386/xen_pvh/int.h | 1 +
include/grub/i386/xen_pvh/memory.h | 1 +
include/grub/i386/xen_pvh/time.h | 1 +
5 files changed, 5 insertions(+)
create mode 100644 include/grub/i386/xen_pvh/boot.h
create mode 100644 include/grub/i386/xen_pvh/console.h
create mode 100644 include/grub/i386/xen_pvh/int.h
create mode 100644 include/grub/i386/xen_pvh/memory.h
create mode 100644 include/grub/i386/xen_pvh/time.h

diff --git a/include/grub/i386/xen_pvh/boot.h b/include/grub/i386/xen_pvh/boot.h
new file mode 100644
index 000000000..6cd23aa83
--- /dev/null
+++ b/include/grub/i386/xen_pvh/boot.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/boot.h>
diff --git a/include/grub/i386/xen_pvh/console.h b/include/grub/i386/xen_pvh/console.h
new file mode 100644
index 000000000..305a46d8e
--- /dev/null
+++ b/include/grub/i386/xen_pvh/console.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/console.h>
diff --git a/include/grub/i386/xen_pvh/int.h b/include/grub/i386/xen_pvh/int.h
new file mode 100644
index 000000000..0f1f9ee62
--- /dev/null
+++ b/include/grub/i386/xen_pvh/int.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/int_types.h>
diff --git a/include/grub/i386/xen_pvh/memory.h b/include/grub/i386/xen_pvh/memory.h
new file mode 100644
index 000000000..8dd6f7c8c
--- /dev/null
+++ b/include/grub/i386/xen_pvh/memory.h
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/memory.h>
diff --git a/include/grub/i386/xen_pvh/time.h b/include/grub/i386/xen_pvh/time.h
new file mode 100644
index 000000000..2298ee8f4
--- /dev/null
+++ b/include/grub/i386/xen_pvh/time.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/time.h>
--
2.16.4
Daniel Kiper
2018-11-27 19:59:28 UTC
Permalink
Post by Juergen Gross
With Xen PVH mode adding a new machine type the machine related headers
need to be present for the build to succeed. Most of the headers just
need to include the related common i386 headers. Add those to the tree.
Note that xen_pvh/int.h needs to include pc/int_types.h instead of
pc/int.h in order to avoid the definition of grub_bios_interrupt().
xen_pvh/memory.h needs to include coreboot/memory.h (like some other
<machine>/memory.h do as well) as this contains just the needed stubs.
Reviewed-by: Daniel Kiper <***@oracle.com>

Daniel
Juergen Gross
2018-11-21 14:28:51 UTC
Permalink
From: Hans van Kranenburg <***@knorrie.org>

This solves the build failing with "Error: no symbol table and no
.moddeps section"

Also see:
- 6371e9c10433578bb236a8284ddb9ce9e201eb59
- https://savannah.gnu.org/bugs/?49012

Signed-off-by: Hans van Kranenburg <***@knorrie.org>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V2: new patch
Signed-off-by: Juergen Gross <***@suse.com>
---
util/grub-module-verifier.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index 03ba1ab43..979999cb9 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -129,6 +129,7 @@ struct platform_whitelist {

static struct platform_whitelist whitelists[] = {
{"i386", "xen", (const char *[]) {"all_video", 0}},
+ {"i386", "xen_pvh", (const char *[]) {"all_video", 0}},
{"x86_64", "xen", (const char *[]) {"all_video", 0}},
{"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
--
2.16.4
Juergen Gross
2018-11-21 14:28:47 UTC
Permalink
Retrieve the memory map from the hypervisor and normalize it to contain
no overlapping entries and to be sorted by address.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V3: use grub_e820_mmap_entry instead of own struct (Daniel Kiper)
---
grub-core/kern/i386/xen/pvh.c | 94 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)

diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
index 478cef0d1..bb90874b3 100644
--- a/grub-core/kern/i386/xen/pvh.c
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -24,7 +24,12 @@
#include <grub/i386/io.h>
#include <grub/xen.h>
#include <xen/hvm/start_info.h>
+#include <grub/i386/linux.h>
#include <grub/machine/kernel.h>
+#include <grub/machine/memory.h>
+#include <xen/memory.h>
+
+#define XEN_MEMORY_MAP_SIZE 128

grub_uint64_t grub_rsdp_addr;

@@ -32,6 +37,8 @@ static char hypercall_page[GRUB_XEN_PAGE_SIZE]
__attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));

static grub_uint32_t xen_cpuid_base;
+static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE];
+static unsigned int nr_map_entries;

static void
grub_xen_cons_msg (const char *msg)
@@ -103,11 +110,98 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
return __res;
}

+static void
+grub_xen_sort_mmap (void)
+{
+ grub_uint64_t from, to;
+ unsigned int i;
+ struct grub_e820_mmap_entry tmp;
+
+ /* Align map entries to page boundaries. */
+ for (i = 0; i < nr_map_entries; i++)
+ {
+ from = map[i].addr;
+ to = from + map[i].len;
+ if (map[i].type == GRUB_MEMORY_AVAILABLE)
+ {
+ from = ALIGN_UP (from, GRUB_XEN_PAGE_SIZE);
+ to = ALIGN_DOWN (to, GRUB_XEN_PAGE_SIZE);
+ }
+ else
+ {
+ from = ALIGN_DOWN (from, GRUB_XEN_PAGE_SIZE);
+ to = ALIGN_UP (to, GRUB_XEN_PAGE_SIZE);
+ }
+ map[i].addr = from;
+ map[i].len = to - from;
+ }
+
+ again:
+ /* Sort entries by start address. */
+ for (i = 1; i < nr_map_entries; i++)
+ {
+ if (map[i].addr >= map[i - 1].addr)
+ continue;
+ tmp = map[i];
+ map[i] = map[i - 1];
+ map[i - 1] = tmp;
+ i = 0;
+ }
+
+ /* Detect overlapping areas. */
+ for (i = 1; i < nr_map_entries; i++)
+ {
+ if (map[i].addr >= map[i - 1].addr + map[i - 1].len)
+ continue;
+ tmp = map[i - 1];
+ map[i - 1].len = map[i].addr - map[i - 1].addr;
+ if (map[i].addr + map[i].len >= tmp.addr + tmp.len)
+ continue;
+ if (nr_map_entries < ARRAY_SIZE (map))
+ {
+ map[nr_map_entries].addr = map[i].addr + map[i].len;
+ map[nr_map_entries].len = tmp.addr + tmp.len - map[nr_map_entries].addr;
+ map[nr_map_entries].type = tmp.type;
+ nr_map_entries++;
+ goto again;
+ }
+ }
+
+ /* Merge adjacent entries. */
+ for (i = 1; i < nr_map_entries; i++)
+ {
+ if (map[i].type == map[i - 1].type &&
+ map[i].addr == map[i - 1].addr + map[i - 1].len)
+ {
+ map[i - 1].len += map[i].len;
+ map[i] = map[nr_map_entries - 1];
+ nr_map_entries--;
+ goto again;
+ }
+ }
+}
+
+static void
+grub_xen_get_mmap (void)
+{
+ struct xen_memory_map memmap;
+
+ memmap.nr_entries = ARRAY_SIZE (map);
+ set_xen_guest_handle (memmap.buffer, map);
+ if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_memory_map,
+ (grub_uint32_t) (&memmap), 0, 0, 0, 0))
+ grub_xen_panic ("Could not get memory map from Xen!\n");
+ nr_map_entries = memmap.nr_entries;
+
+ grub_xen_sort_mmap ();
+}
+
void
grub_xen_setup_pvh (void)
{
grub_xen_cpuid_base ();
grub_xen_setup_hypercall_page ();
+ grub_xen_get_mmap ();
}

grub_err_t
--
2.16.4
Juergen Gross
2018-11-21 14:28:43 UTC
Permalink
include/grub/offsets.h needs some defines for Xen PVH mode.

Add them. While at it line up the values in the surrounding lines to
start at the same column.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V3: XENPVH->XEN_PVH (Daniel Kiper)
---
include/grub/offsets.h | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/include/grub/offsets.h b/include/grub/offsets.h
index 330e4c707..871e1cd4c 100644
--- a/include/grub/offsets.h
+++ b/include/grub/offsets.h
@@ -36,9 +36,10 @@
#define GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE (0x9000-0x8200)

/* The segment where the kernel is loaded. */
-#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800
+#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800

-#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000
+#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000
+#define GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR 0x100000

/* The upper memory area (starting at 640 kiB). */
#define GRUB_MEMORY_I386_PC_UPPER 0xa0000
@@ -101,15 +102,17 @@
#define GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN

#define GRUB_KERNEL_X86_64_XEN_MOD_ALIGN 0x8
-#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8
+#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8
+#define GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN 0x8

/* Non-zero value is only needed for PowerMacs. */
-#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0
-#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0
-#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
-#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
-#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
-#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0
+#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0
+#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0
+#define GRUB_KERNEL_I386_XEN_PVH_MOD_GAP 0x0
+#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
+#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
+#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
+#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0

#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000
#define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3
--
2.16.4
Juergen Gross
2018-11-21 14:28:48 UTC
Permalink
Initialize the needed Xen specific data. This is:

- the Xen start of day page containing the console and Xenstore ring
page PFN and event channel
- the grant table
- the shared info page

Write back the possibly modified memory map to the hypervisor in case
the guest is reading it from there again.

Set the RSDP address for the guest from the start_info page passed
as boot parameter.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V4: write back memory map to Xen (Roger Pau Monné)
V5: add comment (Daniel Kiper)
---
grub-core/kern/i386/xen/pvh.c | 120 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)

diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
index bb90874b3..6de84eb8e 100644
--- a/grub-core/kern/i386/xen/pvh.c
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -27,6 +27,7 @@
#include <grub/i386/linux.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
+#include <xen/hvm/params.h>
#include <xen/memory.h>

#define XEN_MEMORY_MAP_SIZE 128
@@ -37,6 +38,7 @@ static char hypercall_page[GRUB_XEN_PAGE_SIZE]
__attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));

static grub_uint32_t xen_cpuid_base;
+static struct start_info grub_xen_start_page;
static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE];
static unsigned int nr_map_entries;

@@ -110,6 +112,36 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
return __res;
}

+static grub_uint32_t
+grub_xen_get_param (int idx)
+{
+ struct xen_hvm_param xhv;
+ int r;
+
+ xhv.domid = DOMID_SELF;
+ xhv.index = idx;
+ r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param,
+ (grub_uint32_t) (&xhv), 0, 0, 0, 0);
+ if (r < 0)
+ grub_xen_panic ("Could not get parameter from Xen!\n");
+ return xhv.value;
+}
+
+static void *
+grub_xen_add_physmap (unsigned int space, void *addr)
+{
+ struct xen_add_to_physmap xatp;
+
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = space;
+ xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE;
+ if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap,
+ (grub_uint32_t) (&xatp), 0, 0, 0, 0))
+ grub_xen_panic ("Memory_op hypercall failed!\n");
+ return addr;
+}
+
static void
grub_xen_sort_mmap (void)
{
@@ -196,12 +228,100 @@ grub_xen_get_mmap (void)
grub_xen_sort_mmap ();
}

+static void
+grub_xen_set_mmap (void)
+{
+ struct xen_foreign_memory_map memmap;
+
+ memmap.domid = DOMID_SELF;
+ memmap.map.nr_entries = nr_map_entries;
+ set_xen_guest_handle (memmap.map.buffer, map);
+ grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_set_memory_map,
+ (grub_uint32_t) (&memmap), 0, 0, 0, 0);
+}
+
+static grub_uint64_t
+grub_xen_find_page (grub_uint64_t start)
+{
+ unsigned int i, j;
+ grub_uint64_t last = start;
+
+ /* Try to find a e820 map hole below 4G. */
+ /* Relies on page-aligned entries (addr and len) and input (start). */
+ for (i = 0; i < nr_map_entries; i++)
+ {
+ if (last > map[i].addr + map[i].len)
+ continue;
+ if (last < map[i].addr)
+ return last;
+ if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32))
+ break;
+ last = map[i].addr + map[i].len;
+ }
+ if (i == nr_map_entries)
+ return last;
+
+ /* No hole found, use the highest RAM page below 4G and reserve it. */
+ if (nr_map_entries == ARRAY_SIZE (map))
+ grub_xen_panic ("Memory map size limit reached!\n");
+ for (i = 0, j = 0; i < nr_map_entries; i++)
+ {
+ if (map[i].type != GRUB_MEMORY_AVAILABLE)
+ continue;
+ if (map[i].addr >> 32)
+ break;
+ j = i;
+ if ((map[i].addr + map[i].len) >> 32)
+ break;
+ }
+ if (map[j].type != GRUB_MEMORY_AVAILABLE)
+ grub_xen_panic ("No free memory page found!\n");
+ if ((map[j].addr + map[j].len) >> 32)
+ last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE;
+ else
+ last = map[j].addr + map[j].len - GRUB_XEN_PAGE_SIZE;
+ map[nr_map_entries].addr = last;
+ map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE;
+ map[nr_map_entries].type = GRUB_MEMORY_RESERVED;
+ nr_map_entries++;
+ grub_xen_sort_mmap ();
+
+ return last;
+}
+
void
grub_xen_setup_pvh (void)
{
+ grub_addr_t par;
+
grub_xen_cpuid_base ();
grub_xen_setup_hypercall_page ();
grub_xen_get_mmap ();
+
+ /* Setup Xen data. */
+ grub_xen_start_page_addr = &grub_xen_start_page;
+
+ par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN);
+ grub_xen_start_page_addr->console.domU.mfn = par;
+ grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
+ par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN);
+ grub_xen_start_page_addr->console.domU.evtchn = par;
+
+ par = grub_xen_get_param (HVM_PARAM_STORE_PFN);
+ grub_xen_start_page_addr->store_mfn = par;
+ grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
+ par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN);
+ grub_xen_start_page_addr->store_evtchn = par;
+
+ par = grub_xen_find_page (0);
+ grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table,
+ (void *) par);
+ par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE);
+ grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info,
+ (void *) par);
+ grub_xen_set_mmap ();
+
+ grub_rsdp_addr = pvh_start_info->rsdp_paddr;
}

grub_err_t
--
2.16.4
Roger Pau Monné
2018-11-23 15:04:20 UTC
Permalink
Post by Juergen Gross
- the Xen start of day page containing the console and Xenstore ring
page PFN and event channel
- the grant table
- the shared info page
Write back the possibly modified memory map to the hypervisor in case
the guest is reading it from there again.
Set the RSDP address for the guest from the start_info page passed
as boot parameter.
LGTM:

Reviewed-by: Roger Pau Monné <***@citrix.com>
Daniel Kiper
2018-11-27 21:10:19 UTC
Permalink
Post by Juergen Gross
- the Xen start of day page containing the console and Xenstore ring
page PFN and event channel
- the grant table
- the shared info page
Write back the possibly modified memory map to the hypervisor in case
the guest is reading it from there again.
Set the RSDP address for the guest from the start_info page passed
as boot parameter.
One nitpick below...
Post by Juergen Gross
---
V4: write back memory map to Xen (Roger Pau Monné)
V5: add comment (Daniel Kiper)
---
grub-core/kern/i386/xen/pvh.c | 120 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
index bb90874b3..6de84eb8e 100644
--- a/grub-core/kern/i386/xen/pvh.c
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -27,6 +27,7 @@
#include <grub/i386/linux.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
+#include <xen/hvm/params.h>
#include <xen/memory.h>
#define XEN_MEMORY_MAP_SIZE 128
@@ -37,6 +38,7 @@ static char hypercall_page[GRUB_XEN_PAGE_SIZE]
__attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
static grub_uint32_t xen_cpuid_base;
+static struct start_info grub_xen_start_page;
static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE];
static unsigned int nr_map_entries;
@@ -110,6 +112,36 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
return __res;
}
+static grub_uint32_t
+grub_xen_get_param (int idx)
+{
+ struct xen_hvm_param xhv;
+ int r;
+
+ xhv.domid = DOMID_SELF;
+ xhv.index = idx;
+ r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param,
+ (grub_uint32_t) (&xhv), 0, 0, 0, 0);
+ if (r < 0)
+ grub_xen_panic ("Could not get parameter from Xen!\n");
+ return xhv.value;
+}
+
+static void *
+grub_xen_add_physmap (unsigned int space, void *addr)
+{
+ struct xen_add_to_physmap xatp;
+
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = space;
+ xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE;
+ if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap,
+ (grub_uint32_t) (&xatp), 0, 0, 0, 0))
+ grub_xen_panic ("Memory_op hypercall failed!\n");
+ return addr;
+}
+
static void
grub_xen_sort_mmap (void)
{
@@ -196,12 +228,100 @@ grub_xen_get_mmap (void)
grub_xen_sort_mmap ();
}
+static void
+grub_xen_set_mmap (void)
+{
+ struct xen_foreign_memory_map memmap;
+
+ memmap.domid = DOMID_SELF;
+ memmap.map.nr_entries = nr_map_entries;
+ set_xen_guest_handle (memmap.map.buffer, map);
+ grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_set_memory_map,
+ (grub_uint32_t) (&memmap), 0, 0, 0, 0);
+}
+
+static grub_uint64_t
+grub_xen_find_page (grub_uint64_t start)
+{
+ unsigned int i, j;
+ grub_uint64_t last = start;
+
+ /* Try to find a e820 map hole below 4G. */
+ /* Relies on page-aligned entries (addr and len) and input (start). */
I would like to see above two comments as one as below.

/*
* Try to find a e820 map hole below 4G.
* Relies on page-aligned entries (addr and len) and input (start).
*/

You can retain my RB if you change that.

Daniel
Juergen Gross
2018-11-21 14:28:36 UTC
Permalink
This post might be inappropriate. Click to display it.
Daniel Kiper
2018-11-28 11:31:27 UTC
Permalink
Post by Juergen Gross
In order to support grub2 in Xen PVH environment some additional Xen
headers are needed as grub2 will be started in PVH mode requiring to
use several HVM hypercalls and structures.
Add the needed headers from Xen 4.10 being the first Xen version with
full (not only experimental) PVH guest support.
When I apply this patch I get this:

Applying: xen: add some xen headers
.git/rebase-apply/patch:723: trailing whitespace.
*
.git/rebase-apply/patch:725: trailing whitespace.
*
.git/rebase-apply/patch:764: trailing whitespace.
* Maximum # bits addressable by the user of the allocated region (e.g., I/O
.git/rebase-apply/patch:765: trailing whitespace.
* devices often have a 32-bit limitation even in 64-bit systems). If zero
.git/rebase-apply/patch:766: trailing whitespace.
* then the user has no addressing restriction. This field is not used by
warning: squelched 7 whitespace errors
warning: 12 lines add whitespace errors.

Could you fix this?

Daniel
Juergen Gross
2018-11-28 11:46:02 UTC
Permalink
Post by Daniel Kiper
Post by Juergen Gross
In order to support grub2 in Xen PVH environment some additional Xen
headers are needed as grub2 will be started in PVH mode requiring to
use several HVM hypercalls and structures.
Add the needed headers from Xen 4.10 being the first Xen version with
full (not only experimental) PVH guest support.
Applying: xen: add some xen headers
.git/rebase-apply/patch:723: trailing whitespace.
*
.git/rebase-apply/patch:725: trailing whitespace.
*
.git/rebase-apply/patch:764: trailing whitespace.
* Maximum # bits addressable by the user of the allocated region (e.g., I/O
.git/rebase-apply/patch:765: trailing whitespace.
* devices often have a 32-bit limitation even in 64-bit systems). If zero
.git/rebase-apply/patch:766: trailing whitespace.
* then the user has no addressing restriction. This field is not used by
warning: squelched 7 whitespace errors
warning: 12 lines add whitespace errors.
Could you fix this?
Yes.


Juergen
Juergen Gross
2018-11-21 14:28:52 UTC
Permalink
In order to avoid using plain integers for the ELF notes use the
available Xen include instead.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V5: new patch (Daniel Kiper)
---
util/grub-mkimagexx.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index a483c674c..784ed1a52 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -48,6 +48,8 @@
#include <grub/util/install.h>
#include <grub/util/mkimage.h>

+#include <xen/elfnote.h>
+
#pragma GCC diagnostic ignored "-Wcast-align"

#define GRUB_MKIMAGEXX
@@ -341,7 +343,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME));
- note_ptr->n_type = grub_host_to_target32 (6);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
@@ -352,7 +354,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic"));
- note_ptr->n_type = grub_host_to_target32 (8);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
@@ -363,7 +365,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0"));
- note_ptr->n_type = grub_host_to_target32 (5);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
@@ -374,7 +376,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
- note_ptr->n_type = grub_host_to_target32 (1);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
@@ -385,7 +387,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
- note_ptr->n_type = grub_host_to_target32 (3);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
@@ -398,7 +400,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
note_ptr = (Elf_Nhdr *) ptr;
note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal"));
- note_ptr->n_type = grub_host_to_target32 (9);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE);
ptr += sizeof (Elf_Nhdr);
memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
--
2.16.4
Juergen Gross
2018-11-21 14:28:53 UTC
Permalink
Support mkimage for xen_pvh.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V2: some style adjustments (Daniel Kiper)
use defines for elf-notes (Daniel Kiper)
V5: move elf-note define usage into new patch (Daniel Kiper)

I didn't replace the 4096 by a PAGE_SIZE macro as requested by Daniel,
as there isn't such a macro easily available for util/mkimage.c and
I didn't introduce its usage.
---
include/grub/util/mkimage.h | 3 ++-
util/grub-mkimage32.c | 4 +++-
util/grub-mkimage64.c | 4 +++-
util/grub-mkimagexx.c | 44 ++++++++++++++++++++++++++++++++++++++++----
util/mkimage.c | 23 ++++++++++++++++++++++-
5 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
index b3a5ca132..ba9f568f6 100644
--- a/include/grub/util/mkimage.h
+++ b/include/grub/util/mkimage.h
@@ -71,7 +71,8 @@ struct grub_install_image_target_desc
IMAGE_I386_IEEE1275,
IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
- IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
+ IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO,
+ IMAGE_XEN_PVH
} id;
enum
{
diff --git a/util/grub-mkimage32.c b/util/grub-mkimage32.c
index 1f2ccccd2..026a2dd59 100644
--- a/util/grub-mkimage32.c
+++ b/util/grub-mkimage32.c
@@ -17,7 +17,9 @@
# define ELF_R_SYM(val) ELF32_R_SYM(val)
# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
-#define XEN_NOTE_SIZE 132
+
+#define XEN_NOTE_SIZE 132
+#define XEN_PVH_NOTE_SIZE 20

#ifndef GRUB_MKIMAGEXX
#include "grub-mkimagexx.c"
diff --git a/util/grub-mkimage64.c b/util/grub-mkimage64.c
index 4ff72a625..170defb40 100644
--- a/util/grub-mkimage64.c
+++ b/util/grub-mkimage64.c
@@ -17,7 +17,9 @@
# define ELF_R_SYM(val) ELF64_R_SYM(val)
# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
-#define XEN_NOTE_SIZE 120
+
+#define XEN_NOTE_SIZE 120
+#define XEN_PVH_NOTE_SIZE 24

#ifndef GRUB_MKIMAGEXX
#include "grub-mkimagexx.c"
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index 784ed1a52..e94a721b4 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -229,12 +229,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phnum++;
footer_size += sizeof (struct grub_ieee1275_note);
}
- if (image_target->id == IMAGE_XEN)
+ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
{
phnum++;
shnum++;
string_size += sizeof (".xen");
- footer_size += XEN_NOTE_SIZE;
+ footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE;
}
header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr)
+ shnum * sizeof (*shdr) + string_size, layout->align);
@@ -421,6 +421,39 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
}

+ if (image_target->id == IMAGE_XEN_PVH)
+ {
+ char *note_start = (elf_img + program_size + header_size);
+ Elf_Nhdr *note_ptr;
+ char *ptr = (char *) note_start;
+
+ grub_util_info ("adding XEN NOTE segment");
+
+ /* Phys32 Entry. */
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+ memset (ptr, 0, image_target->voidp_sizeof);
+ *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR;
+ ptr += image_target->voidp_sizeof;
+
+ assert (XEN_PVH_NOTE_SIZE == (ptr - note_start));
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ }
+
if (note)
{
int note_size = sizeof (struct grub_ieee1275_note);
@@ -496,7 +529,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
shdr->sh_entsize = grub_host_to_target32 (0);
shdr++;

- if (image_target->id == IMAGE_XEN)
+ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
{
memcpy (ptr, ".xen", sizeof (".xen"));
shdr->sh_name = grub_host_to_target32 (ptr - str_start);
@@ -504,7 +537,10 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size);
shdr->sh_offset = grub_host_to_target_addr (program_size + header_size);
- shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
+ if (image_target->id == IMAGE_XEN)
+ shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
+ else
+ shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
shdr->sh_link = grub_host_to_target32 (0);
shdr->sh_info = grub_host_to_target32 (0);
shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
diff --git a/util/mkimage.c b/util/mkimage.c
index b2f43fea6..353bb1098 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -132,6 +132,24 @@ static const struct grub_install_image_target_desc image_targets[] =
.link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
.default_compression = GRUB_COMPRESSION_LZMA
},
+ {
+ .dirname = "i386-xen_pvh",
+ .names = { "i386-xen_pvh", NULL },
+ .voidp_sizeof = 4,
+ .bigendian = 0,
+ .id = IMAGE_XEN_PVH,
+ .flags = PLATFORM_FLAGS_NONE,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+ .elf_target = EM_386,
+ .section_align = 1,
+ .vaddr_offset = 0,
+ .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR,
+ .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN,
+ .link_align = 4
+ },
{
.dirname = "i386-pc",
.names = { "i386-pc-pxe", NULL },
@@ -860,7 +878,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
else
kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size,
&layout, image_target);
- if (image_target->id == IMAGE_XEN && layout.align < 4096)
+ if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) &&
+ layout.align < 4096)
layout.align = 4096;

if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
@@ -1103,6 +1122,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
case IMAGE_MIPS_ARC:
case IMAGE_QEMU_MIPS_FLASH:
case IMAGE_XEN:
+ case IMAGE_XEN_PVH:
break;
case IMAGE_SPARC64_AOUT:
case IMAGE_SPARC64_RAW:
@@ -1679,6 +1699,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
case IMAGE_LOONGSON_ELF:
case IMAGE_PPC:
case IMAGE_XEN:
+ case IMAGE_XEN_PVH:
case IMAGE_COREBOOT:
case IMAGE_I386_IEEE1275:
{
--
2.16.4
Juergen Gross
2018-11-21 14:28:55 UTC
Permalink
Support platform i386/xen_pvh in configure.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
configure.ac | 3 +++
1 file changed, 3 insertions(+)

diff --git a/configure.ac b/configure.ac
index 5e63c4af3..81a19afd5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -151,6 +151,7 @@ case "$target_cpu"-"$platform" in
i386-efi) ;;
x86_64-efi) ;;
i386-xen) ;;
+ i386-xen_pvh) ;;
x86_64-xen) ;;
i386-pc) ;;
i386-multiboot) ;;
@@ -219,6 +220,7 @@ case "$platform" in
multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
+ xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;;
ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
@@ -1897,6 +1899,7 @@ AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform =
AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen])
+AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh])
AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen])
AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
--
2.16.4
Juergen Gross
2018-11-21 14:28:54 UTC
Permalink
Add xen_pvh support to grub-install.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
include/grub/util/install.h | 1 +
util/grub-install-common.c | 1 +
util/grub-install.c | 7 +++++++
3 files changed, 9 insertions(+)

diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 0dba8b67f..af2bf65d7 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -100,6 +100,7 @@ enum grub_install_plat
GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
GRUB_INSTALL_PLATFORM_I386_XEN,
GRUB_INSTALL_PLATFORM_X86_64_XEN,
+ GRUB_INSTALL_PLATFORM_I386_XEN_PVH,
GRUB_INSTALL_PLATFORM_ARM64_EFI,
GRUB_INSTALL_PLATFORM_ARM_COREBOOT,
GRUB_INSTALL_PLATFORM_MAX
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 0a2e24a79..1b1cb43b4 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -716,6 +716,7 @@ static struct
[GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" },
[GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" },
[GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" },
+ [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" },
[GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" },
[GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" },
[GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" },
diff --git a/util/grub-install.c b/util/grub-install.c
index 4375c1619..743296f36 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -496,6 +496,7 @@ have_bootdev (enum grub_install_plat pl)

case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
return 0;

/* pacify warning. */
@@ -913,6 +914,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
break;

case GRUB_INSTALL_PLATFORM_I386_QEMU:
@@ -960,6 +962,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
free (install_device);
install_device = NULL;
break;
@@ -1477,6 +1480,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
break;
/* pacify warning. */
@@ -1568,6 +1572,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
core_name = "core.elf";
snprintf (mkimage_target, sizeof (mkimage_target),
"%s-%s",
@@ -1660,6 +1665,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
break;
/* pacify warning. */
case GRUB_INSTALL_PLATFORM_MAX:
@@ -1926,6 +1932,7 @@ main (int argc, char *argv[])
case GRUB_INSTALL_PLATFORM_I386_QEMU:
case GRUB_INSTALL_PLATFORM_I386_XEN:
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
+ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
grub_util_warn ("%s",
_("WARNING: no platform-specific install was performed"));
break;
--
2.16.4
Juergen Gross
2018-11-21 14:28:49 UTC
Permalink
Add all usable memory regions to grub memory management and add the
needed mmap iterate code, which will be used by grub core (e.g.
grub-core/lib/relocator.c or grub-core/mmap/mmap.c).

As we are running in 32-bit mode don't add memory above 4GB.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V5: 0x100000000ULL -> 1ULL << 32 (Roger Pau Monné)
---
grub-core/kern/i386/xen/pvh.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)

diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
index 6de84eb8e..1bd503c4a 100644
--- a/grub-core/kern/i386/xen/pvh.c
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -240,6 +240,30 @@ grub_xen_set_mmap (void)
(grub_uint32_t) (&memmap), 0, 0, 0, 0);
}

+static void
+grub_xen_mm_init_regions (void)
+{
+ grub_uint64_t modend, from, to;
+ unsigned int i;
+
+ modend = grub_modules_get_end ();
+
+ for (i = 0; i < nr_map_entries; i++)
+ {
+ if (map[i].type != GRUB_MEMORY_AVAILABLE)
+ continue;
+ from = map[i].addr;
+ to = from + map[i].len;
+ if (from < modend)
+ from = modend;
+ if (from >= to || from >= (1ULL << 32))
+ continue;
+ if (to > (1ULL << 32))
+ to = 1ULL << 32;
+ grub_mm_init_region ((void *) (grub_addr_t) from, to - from);
+ }
+}
+
static grub_uint64_t
grub_xen_find_page (grub_uint64_t start)
{
@@ -321,10 +345,21 @@ grub_xen_setup_pvh (void)
(void *) par);
grub_xen_set_mmap ();

+ grub_xen_mm_init_regions ();
+
grub_rsdp_addr = pvh_start_info->rsdp_paddr;
}

grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
{
+ unsigned int i;
+
+ for (i = 0; i < nr_map_entries; i++)
+ {
+ if (map[i].len && hook (map[i].addr, map[i].len, map[i].type, hook_data))
+ break;
+ }
+
+ return GRUB_ERR_NONE;
}
--
2.16.4
Juergen Gross
2018-11-21 14:28:46 UTC
Permalink
This post might be inappropriate. Click to display it.
Roger Pau Monné
2018-11-23 15:14:07 UTC
Permalink
Post by Juergen Gross
Add the needed code to setup the hypercall page for calling into the
Xen hypervisor.
Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
include/xen/arch-x86/xen.h
Reviewed-by: Roger Pau Monné <***@citrix.com>
Daniel Kiper
2018-11-27 20:31:10 UTC
Permalink
Post by Juergen Gross
Add the needed code to setup the hypercall page for calling into the
Xen hypervisor.
Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
include/xen/arch-x86/xen.h
---
V3: grub_xen_early_halt->grub_xen_panic (Roger Pau Monné)
issue panic message (Roger Pau Monné)
rewrite grub_xen_hypercall to avoid register variables (Daniel Kiper)
V5: Use XEN_HVM_DEBUGCONS_IOPORT from Xen unstable (Roger Pau Monné)
Issue "System halted!" in panic (Daniel Kiper)
Clear interrupts and loop for halting (Roger Pau Monné, Daniel Kiper)
Use only one dummy variable for hypercall asm statement
---
grub-core/kern/i386/xen/pvh.c | 79 +++++++++++++++++++++++++++++++++++++++++++
include/xen/arch-x86/xen.h | 7 ++++
2 files changed, 86 insertions(+)
diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
index 4f629b15e..478cef0d1 100644
--- a/grub-core/kern/i386/xen/pvh.c
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -20,15 +20,94 @@
#include <grub/misc.h>
#include <grub/memory.h>
#include <grub/mm.h>
+#include <grub/i386/cpuid.h>
+#include <grub/i386/io.h>
#include <grub/xen.h>
#include <xen/hvm/start_info.h>
#include <grub/machine/kernel.h>
grub_uint64_t grub_rsdp_addr;
+static char hypercall_page[GRUB_XEN_PAGE_SIZE]
+ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+static grub_uint32_t xen_cpuid_base;
+
+static void
+grub_xen_cons_msg (const char *msg)
+{
+ const char *c;
+
+ for (c = msg; *c; c++)
+ grub_outb (*c, XEN_HVM_DEBUGCONS_IOPORT);
+}
+
+static void
+grub_xen_panic (const char *msg)
+{
+ grub_xen_cons_msg (msg);
+ grub_xen_cons_msg ("System halted!\n");
+
+ asm volatile ("cli");
+
+ while (1)
+ {
+ asm volatile ("hlt");
+ }
+}
+
+static void
+grub_xen_cpuid_base (void)
+{
+ grub_uint32_t base, eax, signature[3];
+
+ for (base = 0x40000000; base < 0x40010000; base += 0x100)
+ {
+ grub_cpuid (base, eax, signature[0], signature[1], signature[2]);
+ if (!grub_memcmp ("XenVMMXenVMM", signature, 12) && (eax - base) >= 2)
+ {
+ xen_cpuid_base = base;
+ return;
+ }
+ }
+
+ grub_xen_panic ("Found no Xen signature!\n");
+}
+
+static void
+grub_xen_setup_hypercall_page (void)
+{
+ grub_uint32_t msr, pfn, eax, ebx, ecx, edx;
+
+ grub_cpuid (xen_cpuid_base + 2, eax, ebx, ecx, edx);
Could not you use a constant instead of plain 2 here? Is there anything
like that in Xen headers? If not please add a comment what grub_cpuid ()
and wrmsr do. One line is sufficient.
Post by Juergen Gross
+ msr = ebx;
+ pfn = (grub_uint32_t) (&hypercall_page);
Is it PFN? Really? I do not think so.
Post by Juergen Gross
+
+ asm volatile ("wrmsr" : : "c" (msr), "a" (pfn), "d" (0) : "memory");
+}
+
+int
+grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+ grub_uint32_t a1, grub_uint32_t a2,
+ grub_uint32_t a3, grub_uint32_t a4,
+ grub_uint32_t a5 __attribute__ ((unused)))
+{
+ grub_uint32_t __res, dummy;
+
+ asm volatile ("call *%[callno]"
+ : "=a" (__res), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+ "=S" (dummy), "=D" (dummy)
+ : "1" (a0), "2" (a1), "3" (a2), "4" (a3), "5" (a4),
+ [callno] "a" (&hypercall_page[callno * 32])
+ : "memory");
Have you tried "+b", "+c", ... instead of "=b", "=c", ...?

Daniel
Daniel Kiper
2018-11-28 11:28:08 UTC
Permalink
Post by Daniel Kiper
Post by Juergen Gross
Add the needed code to setup the hypercall page for calling into the
Xen hypervisor.
Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
include/xen/arch-x86/xen.h
[...]
Post by Daniel Kiper
Post by Juergen Gross
+int
+grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+ grub_uint32_t a1, grub_uint32_t a2,
+ grub_uint32_t a3, grub_uint32_t a4,
+ grub_uint32_t a5 __attribute__ ((unused)))
+{
+ grub_uint32_t __res, dummy;
+
+ asm volatile ("call *%[callno]"
+ : "=a" (__res), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+ "=S" (dummy), "=D" (dummy)
+ : "1" (a0), "2" (a1), "3" (a2), "4" (a3), "5" (a4),
+ [callno] "a" (&hypercall_page[callno * 32])
+ : "memory");
Have you tried "+b", "+c", ... instead of "=b", "=c", ...?
I have done some experiments. Your code:

grub_uint32_t __res, dummy;

asm volatile ("call *%[callno]"
: "=a" (__res), "=b" (dummy), "=c" (dummy), "=d" (dummy),
"=S" (dummy), "=D" (dummy)
: "1" (a0), "2" (a1), "3" (a2), "4" (a3), "5" (a4),
[callno] "a" (&hypercall_page[callno * 32])
: "memory");

... generates this assembly:

0000048e <grub_xen_hypercall>:
48e: 55 push %ebp
48f: 89 e5 mov %esp,%ebp
491: 57 push %edi
492: 56 push %esi
493: 53 push %ebx
494: c1 e0 05 shl $0x5,%eax
497: 05 00 10 00 00 add $0x1000,%eax
49c: 89 d3 mov %edx,%ebx
49e: 8b 55 08 mov 0x8(%ebp),%edx
4a1: 8b 75 0c mov 0xc(%ebp),%esi
4a4: 8b 7d 10 mov 0x10(%ebp),%edi
4a7: ff d0 call *%eax
4a9: 5b pop %ebx
4aa: 5e pop %esi
4ab: 5f pop %edi
4ac: 5d pop %ebp
4ad: c2 10 00 ret $0x10

Mine code:

grub_uint32_t __res;

asm volatile ("call *%[callno]"
: "=a" (__res), "+b" (a0), "+c" (a1), "+d" (a2), "+S" (a3), "+D" (a4)
: [callno] "rm" (&hypercall_page[callno * 32])
: "memory");

... generates this assembly:

0000048e <grub_xen_hypercall>:
48e: 55 push %ebp
48f: 89 e5 mov %esp,%ebp
491: 57 push %edi
492: 56 push %esi
493: 53 push %ebx
494: c1 e0 05 shl $0x5,%eax
497: 05 00 10 00 00 add $0x1000,%eax
49c: 89 d3 mov %edx,%ebx
49e: 8b 55 08 mov 0x8(%ebp),%edx
4a1: 8b 75 0c mov 0xc(%ebp),%esi
4a4: 8b 7d 10 mov 0x10(%ebp),%edi
4a7: ff d0 call *%eax
4a9: 5b pop %ebx
4aa: 5e pop %esi
4ab: 5f pop %edi
4ac: 5d pop %ebp
4ad: c2 10 00 ret $0x10

So, both are equal but mine seems a bit simpler.

And I think that you can drop "__" from __res variable.

Daniel
Juergen Gross
2018-11-28 11:44:08 UTC
Permalink
Post by Juergen Gross
Post by Daniel Kiper
Post by Juergen Gross
Add the needed code to setup the hypercall page for calling into the
Xen hypervisor.
Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
include/xen/arch-x86/xen.h
[...]
Post by Daniel Kiper
Post by Juergen Gross
+int
+grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+ grub_uint32_t a1, grub_uint32_t a2,
+ grub_uint32_t a3, grub_uint32_t a4,
+ grub_uint32_t a5 __attribute__ ((unused)))
+{
+ grub_uint32_t __res, dummy;
+
+ asm volatile ("call *%[callno]"
+ : "=a" (__res), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+ "=S" (dummy), "=D" (dummy)
+ : "1" (a0), "2" (a1), "3" (a2), "4" (a3), "5" (a4),
+ [callno] "a" (&hypercall_page[callno * 32])
+ : "memory");
Have you tried "+b", "+c", ... instead of "=b", "=c", ...?
grub_uint32_t __res, dummy;
asm volatile ("call *%[callno]"
: "=a" (__res), "=b" (dummy), "=c" (dummy), "=d" (dummy),
"=S" (dummy), "=D" (dummy)
: "1" (a0), "2" (a1), "3" (a2), "4" (a3), "5" (a4),
[callno] "a" (&hypercall_page[callno * 32])
: "memory");
48e: 55 push %ebp
48f: 89 e5 mov %esp,%ebp
491: 57 push %edi
492: 56 push %esi
493: 53 push %ebx
494: c1 e0 05 shl $0x5,%eax
497: 05 00 10 00 00 add $0x1000,%eax
49c: 89 d3 mov %edx,%ebx
49e: 8b 55 08 mov 0x8(%ebp),%edx
4a1: 8b 75 0c mov 0xc(%ebp),%esi
4a4: 8b 7d 10 mov 0x10(%ebp),%edi
4a7: ff d0 call *%eax
4a9: 5b pop %ebx
4aa: 5e pop %esi
4ab: 5f pop %edi
4ac: 5d pop %ebp
4ad: c2 10 00 ret $0x10
grub_uint32_t __res;
asm volatile ("call *%[callno]"
: "=a" (__res), "+b" (a0), "+c" (a1), "+d" (a2), "+S" (a3), "+D" (a4)
: [callno] "rm" (&hypercall_page[callno * 32])
: "memory");
48e: 55 push %ebp
48f: 89 e5 mov %esp,%ebp
491: 57 push %edi
492: 56 push %esi
493: 53 push %ebx
494: c1 e0 05 shl $0x5,%eax
497: 05 00 10 00 00 add $0x1000,%eax
49c: 89 d3 mov %edx,%ebx
49e: 8b 55 08 mov 0x8(%ebp),%edx
4a1: 8b 75 0c mov 0xc(%ebp),%esi
4a4: 8b 7d 10 mov 0x10(%ebp),%edi
4a7: ff d0 call *%eax
4a9: 5b pop %ebx
4aa: 5e pop %esi
4ab: 5f pop %edi
4ac: 5d pop %ebp
4ad: c2 10 00 ret $0x10
So, both are equal but mine seems a bit simpler.
And I think that you can drop "__" from __res variable.
Okay.


Juergen
Juergen Gross
2018-11-21 14:28:50 UTC
Permalink
Add the modifications to the build system needed to build a xen_pvh
grub.

Signed-off-by: Juergen Gross <***@suse.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
V3: sorted some filenames (Daniel Kiper)
V4: add bus/pci.c to xen_pvh
---
gentpl.py | 4 ++--
grub-core/Makefile.am | 12 ++++++++++++
grub-core/Makefile.core.def | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/gentpl.py b/gentpl.py
index da67965a4..e8439484a 100644
--- a/gentpl.py
+++ b/gentpl.py
@@ -28,7 +28,7 @@ import re

GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
- "i386_xen", "x86_64_xen",
+ "i386_xen", "x86_64_xen", "i386_xen_pvh",
"mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
@@ -71,7 +71,7 @@ GROUPS["videomodules"] = GRUB_PLATFORMS[:];
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)

# Similar for terminfo
-GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
+GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)

diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index f4ff62b76..02cb5e33d 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -101,6 +101,18 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif

+if COND_i386_xen_pvh
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
+endif
+
if COND_i386_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 6e2cc8444..db3231f77 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -79,6 +79,8 @@ kernel = {
i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
+ i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)';
+ i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000';

mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
@@ -100,6 +102,7 @@ kernel = {
x86_64_efi_startup = kern/x86_64/efi/startup.S;
i386_xen_startup = kern/i386/xen/startup.S;
x86_64_xen_startup = kern/x86_64/xen/startup.S;
+ i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S;
i386_qemu_startup = kern/i386/qemu/startup.S;
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
i386_coreboot_startup = kern/i386/coreboot/startup.S;
@@ -177,6 +180,7 @@ kernel = {

i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
+ i386_xen_pvh = kern/i386/dl.c;

i386_coreboot = kern/i386/coreboot/init.c;
i386_multiboot = kern/i386/coreboot/init.c;
@@ -222,6 +226,14 @@ kernel = {
xen = disk/xen/xendisk.c;
xen = commands/boot.c;

+ i386_xen_pvh = commands/boot.c;
+ i386_xen_pvh = disk/xen/xendisk.c;
+ i386_xen_pvh = kern/i386/tsc.c;
+ i386_xen_pvh = kern/i386/xen/tsc.c;
+ i386_xen_pvh = kern/i386/xen/pvh.c;
+ i386_xen_pvh = kern/xen/init.c;
+ i386_xen_pvh = term/xen/console.c;
+
ia64_efi = kern/ia64/efi/startup.S;
ia64_efi = kern/ia64/efi/init.c;
ia64_efi = kern/ia64/dl.c;
@@ -801,6 +813,7 @@ module = {
name = cpuid;
common = commands/i386/cpuid.c;
enable = x86;
+ enable = i386_xen_pvh;
enable = i386_xen;
enable = x86_64_xen;
};
@@ -860,6 +873,7 @@ module = {
i386_coreboot = lib/i386/halt.c;
i386_qemu = lib/i386/halt.c;
xen = lib/xen/halt.c;
+ i386_xen_pvh = lib/xen/halt.c;
efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c;
emu = lib/emu/halt.c;
@@ -877,6 +891,7 @@ module = {
mips_loongson = lib/mips/loongson/reboot.c;
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
xen = lib/xen/reboot.c;
+ i386_xen_pvh = lib/xen/reboot.c;
uboot = lib/uboot/reboot.c;
arm_coreboot = lib/dummy/reboot.c;
common = commands/reboot.c;
@@ -1556,12 +1571,18 @@ module = {
x86 = lib/i386/relocator16.S;
x86 = lib/i386/relocator32.S;
x86 = lib/i386/relocator64.S;
+ i386_xen_pvh = lib/i386/relocator16.S;
+ i386_xen_pvh = lib/i386/relocator32.S;
+ i386_xen_pvh = lib/i386/relocator64.S;
i386 = lib/i386/relocator_asm.S;
+ i386_xen_pvh = lib/i386/relocator_asm.S;
x86_64 = lib/x86_64/relocator_asm.S;
i386_xen = lib/i386/relocator_asm.S;
x86_64_xen = lib/x86_64/relocator_asm.S;
x86 = lib/i386/relocator.c;
x86 = lib/i386/relocator_common_c.c;
+ i386_xen_pvh = lib/i386/relocator.c;
+ i386_xen_pvh = lib/i386/relocator_common_c.c;
ieee1275 = lib/ieee1275/relocator.c;
efi = lib/efi/relocator.c;
mips = lib/mips/relocator_asm.S;
@@ -1580,6 +1601,7 @@ module = {
enable = mips;
enable = powerpc;
enable = x86;
+ enable = i386_xen_pvh;
enable = xen;
};

@@ -1594,6 +1616,7 @@ module = {
sparc64_ieee1275 = lib/ieee1275/cmos.c;
powerpc_ieee1275 = lib/ieee1275/cmos.c;
xen = lib/xen/datetime.c;
+ i386_xen_pvh = lib/xen/datetime.c;

mips_arc = lib/arc/datetime.c;
enable = noemu;
@@ -1677,6 +1700,7 @@ module = {
common = loader/multiboot.c;
common = loader/multiboot_mbi2.c;
enable = x86;
+ enable = i386_xen_pvh;
enable = mips;
};

@@ -1684,8 +1708,10 @@ module = {
name = multiboot;
common = loader/multiboot.c;
x86 = loader/i386/multiboot_mbi.c;
+ i386_xen_pvh = loader/i386/multiboot_mbi.c;
extra_dist = loader/multiboot_elfxx.c;
enable = x86;
+ enable = i386_xen_pvh;
};

module = {
@@ -1697,8 +1723,10 @@ module = {
module = {
name = linux;
x86 = loader/i386/linux.c;
+ i386_xen_pvh = loader/i386/linux.c;
xen = loader/i386/xen.c;
i386_pc = lib/i386/pc/vesa_modes_table.c;
+ i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
@@ -1786,6 +1814,8 @@ module = {
common = mmap/mmap.c;
x86 = mmap/i386/uppermem.c;
x86 = mmap/i386/mmap.c;
+ i386_xen_pvh = mmap/i386/uppermem.c;
+ i386_xen_pvh = mmap/i386/mmap.c;

i386_pc = mmap/i386/pc/mmap.c;
i386_pc = mmap/i386/pc/mmap_helper.S;
@@ -1795,6 +1825,7 @@ module = {
mips = mmap/mips/uppermem.c;

enable = x86;
+ enable = i386_xen_pvh;
enable = ia64_efi;
enable = arm_efi;
enable = arm64_efi;
@@ -2034,6 +2065,7 @@ module = {
name = legacy_password_test;
common = tests/legacy_password_test.c;
enable = i386_pc;
+ enable = i386_xen_pvh;
enable = i386_efi;
enable = x86_64_efi;
enable = emu;
@@ -2232,6 +2264,7 @@ module = {
xen = lib/i386/pc/vesa_modes_table.c;

enable = i386_pc;
+ enable = i386_xen_pvh;
enable = i386_efi;
enable = x86_64_efi;
enable = emu;
@@ -2275,10 +2308,12 @@ module = {
module = {
name = backtrace;
x86 = lib/i386/backtrace.c;
+ i386_xen_pvh = lib/i386/backtrace.c;
i386_xen = lib/i386/backtrace.c;
x86_64_xen = lib/i386/backtrace.c;
common = lib/backtrace.c;
enable = x86;
+ enable = i386_xen_pvh;
enable = i386_xen;
enable = x86_64_xen;
};
--
2.16.4
Daniel Kiper
2018-11-27 21:17:48 UTC
Permalink
Post by Juergen Gross
Add the modifications to the build system needed to build a xen_pvh
grub.
---
V3: sorted some filenames (Daniel Kiper)
V4: add bus/pci.c to xen_pvh
V5 drops bus/pci.c from xen_pvh. Is it intentional or mistake?

Daniel
Juergen Gross
2018-11-28 11:52:28 UTC
Permalink
Post by Daniel Kiper
Post by Juergen Gross
Add the modifications to the build system needed to build a xen_pvh
grub.
---
V3: sorted some filenames (Daniel Kiper)
V4: add bus/pci.c to xen_pvh
V5 drops bus/pci.c from xen_pvh. Is it intentional or mistake?
As the patch needing this has been dropped again this was
intentional.


Juergen

Loading...