[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 19/62] x86/entry: Early PVH boot code
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- v2: 1. Fix comment. 2. Use cmpb $0. 3. Address comments on pvh-boot.c. 4. Haven't changed the pritnk modifiers to accommodate future changes. 5. Missing a prerequisite patch to relocate pvh_info to make __va work reliably. [BLOCKER]. --- xen/arch/x86/Makefile | 1 + xen/arch/x86/boot/head.S | 40 +++++++++++- xen/arch/x86/boot/x86_64.S | 2 +- xen/arch/x86/guest/Makefile | 1 + xen/arch/x86/guest/pvh-boot.c | 119 +++++++++++++++++++++++++++++++++++ xen/arch/x86/setup.c | 18 +++++- xen/include/asm-x86/guest.h | 34 ++++++++++ xen/include/asm-x86/guest/pvh-boot.h | 57 +++++++++++++++++ 8 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 xen/arch/x86/guest/Makefile create mode 100644 xen/arch/x86/guest/pvh-boot.c create mode 100644 xen/include/asm-x86/guest.h create mode 100644 xen/include/asm-x86/guest/pvh-boot.h diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 01d1178530..ac91e13606 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -1,6 +1,7 @@ subdir-y += acpi subdir-y += cpu subdir-y += genapic +subdir-$(CONFIG_XEN_GUEST) += guest subdir-$(CONFIG_HVM) += hvm subdir-y += mm subdir-$(CONFIG_XENOPROF) += oprofile diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 472255a4b7..4fe5a776b1 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -379,7 +379,39 @@ cs32_switch: ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long sym_offs(__pvh_start)) __pvh_start: - ud2a + cld + cli + + /* + * We need one push/pop to determine load address. Use the same + * absolute stack address as the native path, for lack of a better + * alternative. + */ + mov $0x1000, %esp + + /* Calculate the load base address. */ + call 1f +1: pop %esi + sub $sym_offs(1b), %esi + + /* Set up stack. */ + lea STACK_SIZE + sym_esi(cpu0_stack), %esp + + mov %ebx, sym_esi(pvh_start_info_pa) + + /* Prepare gdt and 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 + + /* Skip bootloader setup and bios setup, go straight to trampoline */ + movb $1, sym_esi(pvh_boot) + movb $1, sym_esi(skip_realmode) + jmp trampoline_setup #endif /* CONFIG_PVH_GUEST */ @@ -543,12 +575,18 @@ trampoline_setup: /* Get bottom-most low-memory stack address. */ add $TRAMPOLINE_SPACE,%ecx +#ifdef CONFIG_PVH_GUEST + cmpb $0, sym_fs(pvh_boot) + jne 1f +#endif + /* Save the Multiboot info struct (after relocation) for later use. */ push %ecx /* Bottom-most low-memory stack address. */ push %ebx /* Multiboot information address. */ push %eax /* Multiboot magic. */ call reloc mov %eax,sym_fs(multiboot_ptr) +1: /* * Now trampoline_phys points to the following structure (lowest address diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 925fd4bb0a..cf47e019f5 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -31,7 +31,7 @@ ENTRY(__high_start) test %ebx,%ebx jnz start_secondary - /* Pass off the Multiboot info structure to C land. */ + /* Pass off the Multiboot info structure to C land (if applicable). */ mov multiboot_ptr(%rip),%edi call __start_xen BUG /* __start_xen() shouldn't return. */ diff --git a/xen/arch/x86/guest/Makefile b/xen/arch/x86/guest/Makefile new file mode 100644 index 0000000000..a5f1625ab1 --- /dev/null +++ b/xen/arch/x86/guest/Makefile @@ -0,0 +1 @@ +obj-bin-$(CONFIG_PVH_GUEST) += pvh-boot.init.o diff --git a/xen/arch/x86/guest/pvh-boot.c b/xen/arch/x86/guest/pvh-boot.c new file mode 100644 index 0000000000..186e332657 --- /dev/null +++ b/xen/arch/x86/guest/pvh-boot.c @@ -0,0 +1,119 @@ +/****************************************************************************** + * arch/x86/guest/pvh-boot.c + * + * PVH boot time support + * + * 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/>. + * + * Copyright (c) 2017 Citrix Systems Ltd. + */ +#include <xen/init.h> +#include <xen/lib.h> +#include <xen/mm.h> + +#include <asm/guest.h> + +#include <public/arch-x86/hvm/start_info.h> + +/* Initialised in head.S, before .bss is zeroed. */ +bool __initdata pvh_boot; +uint32_t __initdata pvh_start_info_pa; + +static multiboot_info_t __initdata pvh_mbi; +static module_t __initdata pvh_mbi_mods[8]; +static const char *__initdata pvh_loader = "PVH Directboot"; + +static void __init convert_pvh_info(void) +{ + const struct hvm_start_info *pvh_info = __va(pvh_start_info_pa); + const struct hvm_modlist_entry *entry; + module_t *mod; + unsigned int i; + + ASSERT(pvh_info->magic == XEN_HVM_START_MAGIC_VALUE); + + /* + * Turn hvm_start_info into mbi. Luckily all modules are placed under 4GB + * boundary on x86. + */ + pvh_mbi.flags = MBI_CMDLINE | MBI_MODULES | MBI_LOADERNAME; + + BUG_ON(pvh_info->cmdline_paddr >> 32); + pvh_mbi.cmdline = pvh_info->cmdline_paddr; + pvh_mbi.boot_loader_name = __pa(pvh_loader); + + BUG_ON(pvh_info->nr_modules >= ARRAY_SIZE(pvh_mbi_mods)); + pvh_mbi.mods_count = pvh_info->nr_modules; + pvh_mbi.mods_addr = __pa(pvh_mbi_mods); + + mod = pvh_mbi_mods; + entry = __va(pvh_info->modlist_paddr); + for ( i = 0; i < pvh_info->nr_modules; i++ ) + { + BUG_ON(entry[i].paddr >> 32); + BUG_ON(entry[i].cmdline_paddr >> 32); + + mod[i].mod_start = entry[i].paddr; + mod[i].mod_end = entry[i].paddr + entry[i].size; + mod[i].string = entry[i].cmdline_paddr; + } +} + +multiboot_info_t *__init pvh_init(void) +{ + convert_pvh_info(); + + return &pvh_mbi; +} + +void __init pvh_print_info(void) +{ + const struct hvm_start_info *pvh_info = __va(pvh_start_info_pa); + const struct hvm_modlist_entry *entry; + unsigned int i; + + ASSERT(pvh_info->magic == XEN_HVM_START_MAGIC_VALUE); + + printk("PVH start info: (pa %08x)\n", pvh_start_info_pa); + printk(" version: %u\n", pvh_info->version); + printk(" flags: %#"PRIx32"\n", pvh_info->flags); + printk(" nr_modules: %u\n", pvh_info->nr_modules); + printk(" modlist_pa: %016"PRIx64"\n", pvh_info->modlist_paddr); + printk(" cmdline_pa: %016"PRIx64"\n", pvh_info->cmdline_paddr); + if ( pvh_info->cmdline_paddr ) + printk(" cmdline: '%s'\n", (char *)__va(pvh_info->cmdline_paddr)); + printk(" rsdp_pa: %016"PRIx64"\n", pvh_info->rsdp_paddr); + + entry = __va(pvh_info->modlist_paddr); + for ( i = 0; i < pvh_info->nr_modules; i++ ) + { + printk(" mod[%u].pa: %016"PRIx64"\n", i, entry[i].paddr); + printk(" mod[%u].size: %016"PRIu64"\n", i, entry[i].size); + printk(" mod[%u].cmdline_pa: %016"PRIx64"\n", + i, entry[i].cmdline_paddr); + if ( entry[i].cmdline_paddr ) + printk(" mod[%1u].cmdline: '%s'\n", i, + (char *)__va(entry[i].cmdline_paddr)); + } +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 65170fe54c..f507d22a2d 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -51,6 +51,7 @@ #include <asm/alternative.h> #include <asm/mc146818rtc.h> #include <asm/cpuid.h> +#include <asm/guest.h> /* opt_nosmp: If true, secondary processors are ignored. */ static bool __initdata opt_nosmp; @@ -649,8 +650,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) char *memmap_type = NULL; char *cmdline, *kextra, *loader; unsigned int initrdidx, domcr_flags = DOMCRF_s3_integrity; - multiboot_info_t *mbi = __va(mbi_p); - module_t *mod = (module_t *)__va(mbi->mods_addr); + multiboot_info_t *mbi; + module_t *mod; unsigned long nr_pages, raw_max_page, modules_headroom, *module_map; int i, j, e820_warn = 0, bytes = 0; bool acpi_boot_table_init_done = false, relocated = false; @@ -680,6 +681,16 @@ void __init noreturn __start_xen(unsigned long mbi_p) /* Full exception support from here on in. */ + if ( pvh_boot ) + { + ASSERT(mbi_p == 0); + mbi = pvh_init(); + } + else + mbi = __va(mbi_p); + + mod = __va(mbi->mods_addr); + loader = (mbi->flags & MBI_LOADERNAME) ? (char *)__va(mbi->boot_loader_name) : "unknown"; @@ -719,6 +730,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) ehci_dbgp_init(); console_init_preirq(); + if ( pvh_boot ) + pvh_print_info(); + printk("Bootloader: %s\n", loader); printk("Command line: %s\n", cmdline); diff --git a/xen/include/asm-x86/guest.h b/xen/include/asm-x86/guest.h new file mode 100644 index 0000000000..630c092c25 --- /dev/null +++ b/xen/include/asm-x86/guest.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * asm-x86/guest.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms and conditions of the GNU General Public + * License, version 2, as published by the Free Software Foundation. + * + * 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/>. + * + * Copyright (c) 2017 Citrix Systems Ltd. + */ + +#ifndef __X86_GUEST_H__ +#define __X86_GUEST_H__ + +#include <asm/guest/pvh-boot.h> + +#endif /* __X86_GUEST_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-x86/guest/pvh-boot.h b/xen/include/asm-x86/guest/pvh-boot.h new file mode 100644 index 0000000000..1b429f9401 --- /dev/null +++ b/xen/include/asm-x86/guest/pvh-boot.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * asm-x86/guest/pvh-boot.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms and conditions of the GNU General Public + * License, version 2, as published by the Free Software Foundation. + * + * 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/>. + * + * Copyright (c) 2017 Citrix Systems Ltd. + */ + +#ifndef __X86_PVH_BOOT_H__ +#define __X86_PVH_BOOT_H__ + +#include <xen/multiboot.h> + +#ifdef CONFIG_PVH_GUEST + +extern bool pvh_boot; + +multiboot_info_t *pvh_init(void); +void pvh_print_info(void); + +#else + +#define pvh_boot 0 + +static inline multiboot_info_t *pvh_init(void) +{ + ASSERT_UNREACHABLE(); + return NULL; +} + +static inline void pvh_print_info(void) +{ + ASSERT_UNREACHABLE(); +} + +#endif /* CONFIG_PVH_GUEST */ +#endif /* __X86_PVH_BOOT_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |