From patchwork Wed May 1 19:39:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Woodhouse X-Patchwork-Id: 10925527 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49FBF14B6 for ; Wed, 1 May 2019 19:41:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 39AF228ED4 for ; Wed, 1 May 2019 19:41:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E0C328ED1; Wed, 1 May 2019 19:41:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E763828E59 for ; Wed, 1 May 2019 19:41:14 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hLv4l-0005L7-AF; Wed, 01 May 2019 19:39:31 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hLv4j-0005KV-B5 for xen-devel@lists.xenproject.org; Wed, 01 May 2019 19:39:29 +0000 X-Inumbo-ID: d49d2a06-6c48-11e9-843c-bc764e045a96 Received: from bombadil.infradead.org (unknown [2607:7c80:54:e::133]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id d49d2a06-6c48-11e9-843c-bc764e045a96; Wed, 01 May 2019 19:39:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Sender:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=5jt+5npRe6p81P8RyMxxmUSB4Zxhx3mhFjyte/083J8=; b=Zw4DTdHNasn5RJwKxQQd42i/T Xox28Ylk0vkDpFc2dDqMbRK0pk4aKJXPura81zRff61jjzlUd64pOyYOxoxbScYOcNAayi8YDd0JW 2J+7DXOGNt8+VwEQ+nIClZ4FJwJdZHeQlOZVp99oWBCS6/TcwNbmi1QEob51pCilLQ4Jv9fHYKCJB Bah0+2h/4aNzrYBI1px7eIQDIwGEa+mmwe9OQbMcgVvz/45meeJrsN5Ge4ilW5bbn+M0U7O1/kRbw xnjIdTPgM06X6YnAGoTpA5LDCTq3KynbOcqA1usT7+ESJlhAzor6KOY44sW9b/iuUlk2ucRe7bCBj sj+ClfZKw==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1hLv4g-0007rn-N8 for xen-devel@lists.xenproject.org; Wed, 01 May 2019 19:39:27 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.92 #3 (Red Hat Linux)) id 1hLv4f-0032Ts-Bg for xen-devel@lists.xenproject.org; Wed, 01 May 2019 20:39:25 +0100 From: David Woodhouse To: xen-devel@lists.xenproject.org Date: Wed, 1 May 2019 20:39:24 +0100 Message-Id: <15986052e40bcef5d80f2367ada726d482b12c45.1556739209.git.dwmw2@infradead.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: References: In-Reply-To: References: X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Subject: [Xen-devel] [RFC PATCH v2 6/7] x86/boot: Copy 16-bit boot variables back up to Xen image X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: David Woodhouse Ditch the bootsym() access from C code for the variables populated by 16-bit boot code. As well as being cleaner this also paves the way for not having the 16-bit boot code in low memory for no-real-mode or EFI loader boots at all. Signed-off-by: David Woodhouse --- xen/arch/x86/boot/edd.S | 2 ++ xen/arch/x86/boot/head.S | 16 +++++++++++++++ xen/arch/x86/boot/mem.S | 2 ++ xen/arch/x86/boot/trampoline.S | 33 ++++++++++++++++++++++++++++--- xen/arch/x86/boot/video.S | 30 +++++++++++++++------------- xen/arch/x86/platform_hypercall.c | 18 ++++++++--------- xen/arch/x86/setup.c | 23 +++++++++++---------- xen/arch/x86/xen.lds.S | 8 +++++++- xen/include/asm-x86/edd.h | 1 - 9 files changed, 93 insertions(+), 40 deletions(-) diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S index 434bbbd960..138d04c964 100644 --- a/xen/arch/x86/boot/edd.S +++ b/xen/arch/x86/boot/edd.S @@ -163,6 +163,7 @@ edd_done: .Ledd_mbr_sig_skip: ret + .pushsection .data.boot16, "aw", @progbits GLOBAL(boot_edd_info_nr) .byte 0 GLOBAL(boot_mbr_signature_nr) @@ -171,3 +172,4 @@ GLOBAL(boot_mbr_signature) .fill EDD_MBR_SIG_MAX*8,1,0 GLOBAL(boot_edd_info) .fill EDD_INFO_MAX * (EDDEXTSIZE + EDDPARMSIZE), 1, 0 + .popsection diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 82342769c7..7d6c8d3292 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -732,6 +732,17 @@ trampoline_setup: cmp $sym_offs(__bootsym_seg_stop),%edi jb 1b + /* Relocations for the boot data section. */ + mov sym_fs(trampoline_phys),%edx + add $(boot_trampoline_end - boot_trampoline_start),%edx + mov $sym_offs(__bootdatasym_rel_start),%edi +1: + mov %fs:(%edi),%eax + add %edx,%fs:(%edi,%eax) + add $4,%edi + cmp $sym_offs(__bootdatasym_rel_stop),%edi + jb 1b + /* Do not parse command line on EFI platform here. */ cmpb $0,sym_fs(efi_platform) jnz 1f @@ -769,6 +780,11 @@ trampoline_setup: mov $((boot_trampoline_end - boot_trampoline_start) / 4),%ecx rep movsl %fs:(%esi),%es:(%edi) + /* Copy boot data template to low memory. */ + mov $sym_offs(bootdata_start),%esi + mov $((bootdata_end - bootdata_start + 3) / 4),%ecx + rep movsl %fs:(%esi),%es:(%edi) + /* Jump into the relocated trampoline. */ lret diff --git a/xen/arch/x86/boot/mem.S b/xen/arch/x86/boot/mem.S index aa39608442..86f0fa9af7 100644 --- a/xen/arch/x86/boot/mem.S +++ b/xen/arch/x86/boot/mem.S @@ -67,6 +67,7 @@ get_memory_map: ret .align 4 + .pushsection .data.boot16, "aw", @progbits GLOBAL(bios_e820map) .fill E820_BIOS_MAX*20,1,0 GLOBAL(bios_e820nr) @@ -75,3 +76,4 @@ GLOBAL(lowmem_kb) .long 0 GLOBAL(highmem_kb) .long 0 + .popsection diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index 0f4a740fcb..fdfee2edb1 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -47,11 +47,15 @@ .long 111b - (off) - .; \ .popsection -#define bootdatasym(s) ((s)-boot_trampoline_start) + .pushsection .data.boot16, "aw", @progbits +GLOBAL(bootdata_start) + .popsection + +#define bootdatasym(s) ((s)-bootdata_start+(boot_trampoline_end-boot_trampoline_start)) #define bootdatasym_rel(sym, off, opnd...) \ bootdatasym(sym),##opnd; \ 111:; \ - .pushsection .bootdatasym_rel, "a";\ + .pushsection .bootsym_rel, "a";\ .long 111b - (off) - .; \ .popsection @@ -100,7 +104,7 @@ GLOBAL(trampoline_cpu_started) .word 0 idt_48: .word 0, 0, 0 # base = limit = 0 .word 0 -gdt_48: .word 6*8-1 +gdt_48: .word 7*8-1 .long tramp32sym_rel(trampoline_gdt,4) /* Start of tramp32sym section which can be used in place during boot */ @@ -312,6 +316,23 @@ trampoline_boot_cpu_entry: mov %eax,%gs mov %eax,%ss + /* + * Copy locally-gathered data back up into the Xen physical image + */ + mov $BOOT_FS,%eax + mov %eax,%es + + mov $sym_offs(bootdata_end),%ecx + mov $sym_offs(bootdata_start),%edi + sub %edi,%ecx + mov $bootdatasym_rel(bootdata_start,4,%esi) + rep movsb %ds:(%esi),%es:(%edi) + + /* + * %es still points to BOOT_FS but trampoline_protmode_entry + * reloads it anyway. + */ + /* EBX == 0 indicates we are the BP (Boot Processor). */ xor %ebx,%ebx @@ -339,8 +360,10 @@ vesa_size: .word 0,0,0 /* width x depth x height */ #endif + .pushsection .data.boot16, "aw", @progbits GLOBAL(kbd_shift_flags) .byte 0 + .popsection rm_idt: .word 256*4-1, 0, 0 @@ -349,3 +372,7 @@ rm_idt: .word 256*4-1, 0, 0 #ifdef CONFIG_VIDEO #include "video.S" #endif + + .pushsection .data.boot16, "aw", @progbits +GLOBAL(bootdata_end) + .popsection diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S index 5087c6a4d5..4608464b77 100644 --- a/xen/arch/x86/boot/video.S +++ b/xen/arch/x86/boot/video.S @@ -15,10 +15,10 @@ #include "video.h" -/* Scratch space layout: boot_trampoline_end to boot_trampoline_end+0x1000. */ -#define modelist bootsym(boot_trampoline_end) /* 2kB (256 entries) */ -#define vesa_glob_info (modelist + 0x800) /* 1kB */ -#define vesa_mode_info (vesa_glob_info + 0x400) /* 1kB */ +/* Scratch space layout: bootdata_end to bootdata_end+0x1000. */ +#define modelist(t) bootdatasym_rel(bootdata_end,2,t) /* 2KiB (256 entries) */ +#define vesa_glob_info(t) bootdatasym_rel((bootdata_end+0x800),2,t) /* 1KiB */ +#define vesa_mode_info(t) bootdatasym_rel((bootdata_end+0xc00),2,t) /* 1KiB */ /* Retrieve Extended Display Identification Data. */ #define CONFIG_FIRMWARE_EDID @@ -113,7 +113,7 @@ mopar2: movb %al, _param(PARAM_VIDEO_LINES) # Fetching of VESA frame buffer parameters mopar_gr: - leaw vesa_mode_info, %di + leaw vesa_mode_info(%di) movb $0x23, _param(PARAM_HAVE_VGA) movw 16(%di), %ax movw %ax, _param(PARAM_LFB_LINELENGTH) @@ -134,7 +134,7 @@ mopar_gr: movw %ax, _param(PARAM_VESA_ATTRIB) # get video mem size - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) xorl %eax, %eax movw 18(%di), %ax movl %eax, _param(PARAM_LFB_SIZE) @@ -226,7 +226,7 @@ an1: call prtstr leaw bootsym(listhdr), %si # Table header call prtstr movb $0x30, %dl # DL holds mode number - leaw modelist, %si + leaw modelist(%si) lm1: cmpw $ASK_VGA, (%si) # End? jz lm2 @@ -435,13 +435,13 @@ setmenu: jmp mode_set check_vesa: - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax int $0x10 cmpw $0x004f, %ax jnz setbad - leaw vesa_mode_info, %di + leaw vesa_mode_info(%di) subb $VIDEO_FIRST_VESA>>8, %bh movw %bx, %cx # Get mode information structure movw $0x4f01, %ax @@ -509,7 +509,7 @@ inidx: outb %al, %dx # Read from indexed VGA register setvesabysize: call mode_table - leaw modelist,%si + leaw modelist(%si) 1: add $8,%si cmpw $ASK_VGA,-8(%si) # End? je _setbad @@ -669,7 +669,7 @@ mode_table: orw %di, %di jnz mtab1 - leaw modelist, %di # Store standard modes: + leaw modelist(%di) # Store standard modes: movw $VIDEO_80x25,(%di) # The 80x25 mode (ALL) movw $0x50,2(%di) movw $0x19,4(%di) @@ -684,7 +684,7 @@ mode_table: movw $ASK_VGA, (%di) # End marker movw %di, bootsym(mt_end) -mtab1: leaw modelist, %si # SI=mode list, DI=list end +mtab1: leaw modelist(%si) # SI=mode list, DI=list end ret0: ret # Modes usable on all standard VGAs @@ -700,7 +700,7 @@ vga_modes_end: # Detect VESA modes. vesa_modes: movw %di, %bp # BP=original mode table end - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax # VESA Get card info call int $0x10 movw %di, %si @@ -897,7 +897,7 @@ store_edid: cmpb $1, bootsym(opt_edid) # EDID disabled on cmdline (edid=no)? je .Lno_edid - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax int $0x10 cmpw $0x004f, %ax @@ -990,6 +990,7 @@ name_bann: .asciz "Video adapter: " force_size: .word 0 # Use this size instead of the one in BIOS vars + .pushsection .data.boot16, "aw", @progbits GLOBAL(boot_vid_info) .byte 0, 0 /* orig_x, orig_y */ .byte 3 /* text mode 3 */ @@ -1001,3 +1002,4 @@ GLOBAL(boot_edid_info) .fill 128,1,0x13 GLOBAL(boot_edid_caps) .word 0x1313 + .popsection diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index ea18c3215a..5c8953ae19 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -333,10 +333,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) u16 length; ret = -ESRCH; - if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) ) + if ( op->u.firmware_info.index >= boot_edd_info_nr ) break; - info = bootsym(boot_edd_info) + op->u.firmware_info.index; + info = boot_edd_info + op->u.firmware_info.index; /* Transfer the EDD info block. */ ret = -EFAULT; @@ -372,10 +372,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) const struct mbr_signature *sig; ret = -ESRCH; - if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) ) + if ( op->u.firmware_info.index >= boot_mbr_signature_nr ) break; - sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index; + sig = boot_mbr_signature + op->u.firmware_info.index; op->u.firmware_info.u.disk_mbr_signature.device = sig->device; op->u.firmware_info.u.disk_mbr_signature.mbr_signature = @@ -391,13 +391,13 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) #ifdef CONFIG_VIDEO if ( op->u.firmware_info.index != 0 ) break; - if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 ) + if ( *(u32 *)boot_edid_info == 0x13131313 ) break; op->u.firmware_info.u.vbeddc_info.capabilities = - bootsym(boot_edid_caps); + boot_edid_caps; op->u.firmware_info.u.vbeddc_info.edid_transfer_time = - bootsym(boot_edid_caps) >> 8; + boot_edid_caps >> 8; ret = 0; if ( __copy_field_to_guest(u_xenpf_op, op, u.firmware_info. @@ -405,7 +405,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) __copy_field_to_guest(u_xenpf_op, op, u.firmware_info. u.vbeddc_info.edid_transfer_time) || copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid, - bootsym(boot_edid_info), 128) ) + boot_edid_info, 128) ) ret = -EFAULT; #endif break; @@ -422,7 +422,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) if ( op->u.firmware_info.index != 0 ) break; - op->u.firmware_info.u.kbd_shift_flags = bootsym(kbd_shift_flags); + op->u.firmware_info.u.kbd_shift_flags = kbd_shift_flags; ret = 0; if ( __copy_field_to_guest(u_xenpf_op, op, diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index b714e3c237..4dd4c4161c 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -507,7 +507,7 @@ extern struct boot_video_info boot_vid_info; static void __init parse_video_info(void) { #ifdef CONFIG_VIDEO - struct boot_video_info *bvi = &bootsym(boot_vid_info); + struct boot_video_info *bvi = &boot_vid_info; /* vga_console_info is filled directly on EFI platform. */ if ( efi_enabled(EFI_BOOT) ) @@ -666,12 +666,11 @@ static char * __init cmdline_cook(char *p, const char *loader_name) static int copy_bios_e820(struct e820entry *map, unsigned int limit) { - unsigned int n = bootsym(bios_e820nr); + unsigned int n = bios_e820nr; if (n > limit) n = limit; - if (n) - memcpy(map, bootsym(bios_e820map), sizeof(*map) * n); + memcpy(map, bios_e820map, sizeof(*map) * n); return n; } @@ -802,15 +801,15 @@ void __init noreturn __start_xen(unsigned long mbi_p) } /* Print VBE/DDC EDID information. */ - if ( bootsym(boot_edid_caps) != 0x1313 ) + if ( boot_edid_caps != 0x1313 ) { - u16 caps = bootsym(boot_edid_caps); + u16 caps = boot_edid_caps; printk(" VBE/DDC methods:%s%s%s; ", (caps & 1) ? " V1" : "", (caps & 2) ? " V2" : "", !(caps & 3) ? " none" : ""); printk("EDID transfer time: %d seconds\n", caps >> 8); - if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 ) + if ( *(u32 *)boot_edid_info == 0x13131313 ) { printk(" EDID info not retrieved because "); if ( !(caps & 3) ) @@ -825,9 +824,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) printk("Disc information:\n"); printk(" Found %d MBR signatures\n", - bootsym(boot_mbr_signature_nr)); + boot_mbr_signature_nr); printk(" Found %d EDD information structures\n", - bootsym(boot_edd_info_nr)); + boot_edd_info_nr); /* Check that we have at least one Multiboot module. */ if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) @@ -899,14 +898,14 @@ void __init noreturn __start_xen(unsigned long mbi_p) bytes += map->size + 4; } } - else if ( bootsym(lowmem_kb) ) + else if ( lowmem_kb ) { memmap_type = "Xen-e801"; e820_raw.map[0].addr = 0; - e820_raw.map[0].size = bootsym(lowmem_kb) << 10; + e820_raw.map[0].size = lowmem_kb << 10; e820_raw.map[0].type = E820_RAM; e820_raw.map[1].addr = 0x100000; - e820_raw.map[1].size = bootsym(highmem_kb) << 10; + e820_raw.map[1].size = highmem_kb << 10; e820_raw.map[1].type = E820_RAM; e820_raw.nr_map = 2; } diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 5f36b88b92..436781cefa 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -228,11 +228,13 @@ SECTIONS __trampoline32_rel_stop = .; __bootsym_rel_start = .; *(.bootsym_rel) - *(.bootdatasym_rel) __bootsym_rel_stop = .; __bootsym_seg_start = .; *(.bootsym_seg) __bootsym_seg_stop = .; + __bootdatasym_rel_start = .; + *(.bootdatasym_rel) + __bootdatasym_rel_stop = .; /* * struct alt_inst entries. From the header (alternative.h): * "Alternative instructions for different CPU types or capabilities" @@ -275,6 +277,10 @@ SECTIONS DECL_SECTION(.data) { *(.data.page_aligned) *(.data) + . = ALIGN(16); + __bootdata_start = .; + *(.data.boot16) + __bootdata_end = .; *(.data.rel) *(.data.rel.*) CONSTRUCTORS diff --git a/xen/include/asm-x86/edd.h b/xen/include/asm-x86/edd.h index afaa23732a..a4d6b4d90e 100644 --- a/xen/include/asm-x86/edd.h +++ b/xen/include/asm-x86/edd.h @@ -143,7 +143,6 @@ struct __packed mbr_signature { u32 signature; }; -/* These all reside in the boot trampoline. Access via bootsym(). */ extern struct mbr_signature boot_mbr_signature[]; extern u8 boot_mbr_signature_nr; extern struct edd_info boot_edd_info[];