From patchwork Tue Jun 28 14:03:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9203321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D6EAF6074E for ; Tue, 28 Jun 2016 14:06:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C4179285F9 for ; Tue, 28 Jun 2016 14:06:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B61FE28607; Tue, 28 Jun 2016 14:06:14 +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=-4.2 required=2.0 tests=BAYES_00, 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 AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E001F285F9 for ; Tue, 28 Jun 2016 14:06:12 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bHtcT-0006Sr-ON; Tue, 28 Jun 2016 14:04:05 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bHtcR-0006Sh-UM for xen-devel@lists.xenproject.org; Tue, 28 Jun 2016 14:04:04 +0000 Received: from [85.158.143.35] by server-3.bemta-6.messagelabs.com id C7/AF-22092-3D382775; Tue, 28 Jun 2016 14:04:03 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCIsWRWlGSWpSXmKPExsXS6fjDS/dSc1G 4QdMzOYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNePW8QnMBTN8KtYueMnWwPjMrouRk0NIIE/i xt59rCA2r4CdxKeeH8wgtoSAocS++avYQGwWAVWJtd8esYDYbALqEm3PtgPVc3CICBhInDuaB BJmFkiSaP/axg5iCwu4SWxc1wRWwisgKPF3hzBEiZ3E9Ffz2Ccwcs1CyMxCkoGwtSQe/rrFAm FrSyxb+JoZpJxZQFpi+T8OiLCDRPOOV+yoSkBsb4nH148xLWDkWMWoXpxaVJZapGusl1SUmZ5 RkpuYmaNraGCml5taXJyYnpqTmFSsl5yfu4kRGHoMQLCDseOf0yFGSQ4mJVHeBQxF4UJ8Sfkp lRmJxRnxRaU5qcWHGGU4OJQkeEObgHKCRanpqRVpmTnAKIBJS3DwKInw3mwESvMWFyTmFmemQ 6ROMSpKifN6g/QJgCQySvPg2mCRd4lRVkqYlxHoECGegtSi3MwSVPlXjOIcjErCvNIgU3gy80 rgpr8CWswEtJi1Oh9kcUkiQkqqgdEi7Pj3pYo/Eo2C2u0i8i5r7wrca/+1KEp+xb+Srfkrs7Z t5rp0priGic87NWe3qkniVOGL785bqz/29z3y2H/SiYaLs1Nrb6nM3G0uJXRFX8Z8u+GKGDFu y5e7Tfbv2e68Vmj3oUTxJ49n7YzRPOd8ID7GsCfcReSlaTjP0So9hvhtkXd0E5RYijMSDbWYi 4oTAeuhLuy3AgAA X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-15.tower-21.messagelabs.com!1467122640!21231704!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 2138 invoked from network); 28 Jun 2016 14:04:02 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-15.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 28 Jun 2016 14:04:02 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Tue, 28 Jun 2016 08:03:59 -0600 Message-Id: <57729FED02000078000F975B@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Tue, 28 Jun 2016 08:03:57 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH] x86/EFI + Live Patch: avoid symbol address truncation X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP ld associates __init_end, placed outside of any section by the linker script, with the following section, resulting in a huge (wrapped, as it would be negative) section relative offset. COFF symbol tables store section relative addresses, and hence the above leads to assembler truncation warnings when all symbols get included in the symbol table (for Live Patching code). To overcome this, move __init_end past both ALIGN() directives. The consuming code (init_done()) is fine with such an adjustment (the distinction really would only be relevant for the loop claring the pages, and I think it's acceptable to clear a few more on - for now - EFI). This effectively results in the (__init_begin,__init_end) and (__2M_init_start,__2M_init_end) pairs to become identical, with their different names only serving documentation purposes now. Note that moving __init_end and __2M_init_end into .init is not a good idea, as that would significantly grow xen.efi binary size. While inspecting symbol table and ld behavior I also noticed that __2M_text_start gets put at address zero in the EFI case, which hasn't caused problems solely because we don't actually reference that symbol. Correct the setting of the initial address, and comment out said symbol for the time being, as with the initial address correction it would in turn cause an assembler truncation warning similar to the one mentioned above. While checking init_done() for correctness with the above changes I noticed that code can easily be folded there, at once correcting the logged amount of memory which has got freed for the 2M-alignment case (i.e. EFI right now). Signed-off-by: Jan Beulich x86/EFI + Live Patch: avoid symbol address truncation ld associates __init_end, placed outside of any section by the linker script, with the following section, resulting in a huge (wrapped, as it would be negative) section relative offset. COFF symbol tables store section relative addresses, and hence the above leads to assembler truncation warnings when all symbols get included in the symbol table (for Live Patching code). To overcome this, move __init_end past both ALIGN() directives. The consuming code (init_done()) is fine with such an adjustment (the distinction really would only be relevant for the loop claring the pages, and I think it's acceptable to clear a few more on - for now - EFI). This effectively results in the (__init_begin,__init_end) and (__2M_init_start,__2M_init_end) pairs to become identical, with their different names only serving documentation purposes now. Note that moving __init_end and __2M_init_end into .init is not a good idea, as that would significantly grow xen.efi binary size. While inspecting symbol table and ld behavior I also noticed that __2M_text_start gets put at address zero in the EFI case, which hasn't caused problems solely because we don't actually reference that symbol. Correct the setting of the initial address, and comment out said symbol for the time being, as with the initial address correction it would in turn cause an assembler truncation warning similar to the one mentioned above. While checking init_done() for correctness with the above changes I noticed that code can easily be folded there, at once correcting the logged amount of memory which has got freed for the 2M-alignment case (i.e. EFI right now). Signed-off-by: Jan Beulich --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -515,6 +515,7 @@ static inline bool_t using_2M_mapping(vo static void noinline init_done(void) { void *va; + unsigned long start, end; system_state = SYS_STATE_active; @@ -530,18 +531,18 @@ static void noinline init_done(void) /* Destroy Xen's mappings, and reuse the pages. */ if ( using_2M_mapping() ) { - destroy_xen_mappings((unsigned long)&__2M_init_start, - (unsigned long)&__2M_init_end); - init_xenheap_pages(__pa(__2M_init_start), __pa(__2M_init_end)); + start = (unsigned long)&__2M_init_start, + end = (unsigned long)&__2M_init_end; } else { - destroy_xen_mappings((unsigned long)&__init_begin, - (unsigned long)&__init_end); - init_xenheap_pages(__pa(__init_begin), __pa(__init_end)); + start = (unsigned long)&__init_begin; + end = (unsigned long)&__init_end; } - printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); + destroy_xen_mappings(start, end); + init_xenheap_pages(__pa(start), __pa(end)); + printk("Freed %ldkB init memory\n", (end - start) >> 10); startup_cpu_idle_loop(); } --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -40,9 +40,20 @@ SECTIONS #if !defined(EFI) . = __XEN_VIRT_START; __image_base__ = .; +#else + . = __image_base__; #endif +#if 0 +/* + * We don't really use this symbol anywhere, and the way it would get defined + * here would result in it having a negative (wrapped to huge positive) + * offset relative to the .text section. That, in turn, causes an assembler + * truncation warning when including all symbols in the symbol table for Live + * Patching code. + */ __2M_text_start = .; /* Start of 2M superpages, mapped RX. */ +#endif . = __XEN_VIRT_START + MB(1); _start = .; @@ -194,14 +205,13 @@ SECTIONS *(.ctors) __ctors_end = .; } :text - . = ALIGN(PAGE_SIZE); - __init_end = .; #ifdef EFI . = ALIGN(MB(2)); #else . = ALIGN(PAGE_SIZE); #endif + __init_end = .; __2M_init_end = .; __2M_rwdata_start = .; /* Start of 2M superpages, mapped RW. */ @@ -296,7 +306,6 @@ ASSERT(__image_base__ > XEN_VIRT_START | ASSERT(kexec_reloc_size - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large") #endif -ASSERT(IS_ALIGNED(__2M_text_start, MB(2)), "__2M_text_start misaligned") #ifdef EFI ASSERT(IS_ALIGNED(__2M_text_end, MB(2)), "__2M_text_end misaligned") ASSERT(IS_ALIGNED(__2M_rodata_start, MB(2)), "__2M_rodata_start misaligned") --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -515,6 +515,7 @@ static inline bool_t using_2M_mapping(vo static void noinline init_done(void) { void *va; + unsigned long start, end; system_state = SYS_STATE_active; @@ -530,18 +531,18 @@ static void noinline init_done(void) /* Destroy Xen's mappings, and reuse the pages. */ if ( using_2M_mapping() ) { - destroy_xen_mappings((unsigned long)&__2M_init_start, - (unsigned long)&__2M_init_end); - init_xenheap_pages(__pa(__2M_init_start), __pa(__2M_init_end)); + start = (unsigned long)&__2M_init_start, + end = (unsigned long)&__2M_init_end; } else { - destroy_xen_mappings((unsigned long)&__init_begin, - (unsigned long)&__init_end); - init_xenheap_pages(__pa(__init_begin), __pa(__init_end)); + start = (unsigned long)&__init_begin; + end = (unsigned long)&__init_end; } - printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); + destroy_xen_mappings(start, end); + init_xenheap_pages(__pa(start), __pa(end)); + printk("Freed %ldkB init memory\n", (end - start) >> 10); startup_cpu_idle_loop(); } --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -40,9 +40,20 @@ SECTIONS #if !defined(EFI) . = __XEN_VIRT_START; __image_base__ = .; +#else + . = __image_base__; #endif +#if 0 +/* + * We don't really use this symbol anywhere, and the way it would get defined + * here would result in it having a negative (wrapped to huge positive) + * offset relative to the .text section. That, in turn, causes an assembler + * truncation warning when including all symbols in the symbol table for Live + * Patching code. + */ __2M_text_start = .; /* Start of 2M superpages, mapped RX. */ +#endif . = __XEN_VIRT_START + MB(1); _start = .; @@ -194,14 +205,13 @@ SECTIONS *(.ctors) __ctors_end = .; } :text - . = ALIGN(PAGE_SIZE); - __init_end = .; #ifdef EFI . = ALIGN(MB(2)); #else . = ALIGN(PAGE_SIZE); #endif + __init_end = .; __2M_init_end = .; __2M_rwdata_start = .; /* Start of 2M superpages, mapped RW. */ @@ -296,7 +306,6 @@ ASSERT(__image_base__ > XEN_VIRT_START | ASSERT(kexec_reloc_size - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large") #endif -ASSERT(IS_ALIGNED(__2M_text_start, MB(2)), "__2M_text_start misaligned") #ifdef EFI ASSERT(IS_ALIGNED(__2M_text_end, MB(2)), "__2M_text_end misaligned") ASSERT(IS_ALIGNED(__2M_rodata_start, MB(2)), "__2M_rodata_start misaligned")