From: Prarit Bhargava <prarit@redhat.com> Subject: [RHEL5.1 PATCH] BZ 226824 226874: Fix boot_params and .pci_fixup warnings Date: Thu, 1 Feb 2007 18:01:08 -0500 Bugzilla: 226824 226874 Message-Id: <20070201230108.27497.74928.sendpatchset@prarit.boston.redhat.com> Changelog: [x86] Fix boot_params and .pci_fixup warnings Backport of http://marc.theaimsgroup.com/?l=linux-kernel&m=116650542300200&w=2 This resolves BZ 226824. This also required a backport of upstream secref_whitelist which resolves BZ 226874. Tested successfully by me. P. --- linux-2.6.18.i386.orig/arch/i386/kernel/head.S 2007-02-01 17:32:53.000000000 -0500 +++ linux-2.6.18.i386/arch/i386/kernel/head.S 2007-02-01 17:33:10.000000000 -0500 @@ -53,6 +53,7 @@ * any particular GDT layout, because we load our own as soon as we * can. */ +.section .text.head ENTRY(startup_32) /* @@ -135,16 +136,25 @@ page_pde_offset = (__PAGE_OFFSET >> 20); jb 10b movl %edi,(init_pg_tables_end - __PAGE_OFFSET) -#ifdef CONFIG_SMP xorl %ebx,%ebx /* This is the boot CPU (BSP) */ jmp 3f - /* * Non-boot CPU entry point; entered from trampoline.S * We can't lgdt here, because lgdt itself uses a data segment, but * we know the trampoline has already loaded the boot_gdt_table GDT * for us. + * + * If cpu hotplug is not supported then this code can go in init section + * which will be freed later */ + +#ifdef CONFIG_HOTPLUG_CPU +.section .text +#else +.section .init.text +#endif + +#ifdef CONFIG_SMP ENTRY(startup_32_smp) cld movl $(__BOOT_DS),%eax @@ -202,8 +212,8 @@ ENTRY(startup_32_smp) xorl %ebx,%ebx incl %ebx -3: #endif /* CONFIG_SMP */ +3: /* * Enable paging @@ -405,6 +415,7 @@ ignore_int: #endif iret +.section .text /* * Real beginning of normal "text" segment */ --- linux-2.6.18.i386.orig/arch/i386/kernel/vmlinux.lds.S 2007-02-01 16:08:21.000000000 -0500 +++ linux-2.6.18.i386/arch/i386/kernel/vmlinux.lds.S 2007-02-01 16:35:53.000000000 -0500 @@ -30,9 +30,14 @@ SECTIONS . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; #endif phys_startup_32 = startup_32 - LOAD_OFFSET; + + .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) { + _text = .; /* Text and read-only data */ + *(.text.head) + } :text = 0x9090 + /* read-only */ .text : AT(ADDR(.text) - LOAD_OFFSET) { - _text = .; /* Text and read-only data */ *(.text) SCHED_TEXT LOCK_TEXT --- linux-2.6.18.i386.orig/scripts/mod/modpost.c 2007-02-01 16:08:21.000000000 -0500 +++ linux-2.6.18.i386/scripts/mod/modpost.c 2007-02-01 17:18:11.000000000 -0500 @@ -580,9 +580,19 @@ static int strrcmp(const char *s, const * tosec = .init.text | .exit.text | .init.data * fromsec = .data * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one - **/ -static int secref_whitelist(const char *tosec, const char *fromsec, - const char *atsym) + * + * Pattern 3: + * Some symbols belong to init section but still it is ok to reference + * these from non-init sections as these symbols don't have any memory + * allocated for them and symbol address and value are same. So even + * if init section is freed, its ok to reference those symbols. + * For ex. symbols marking the init section boundaries. + * This pattern is identified by + * refsymname = __init_begin, _sinittext, _einittext + **/ +static int secref_whitelist(const char *modname, const char *tosec, + const char *fromsec, const char *atsym, + const char *refsymname) { int f1 = 1, f2 = 1; const char **s; @@ -593,6 +603,14 @@ static int secref_whitelist(const char * "_ops", "_probe", "_probe_one", + "_console", + NULL + }; + + const char *pat3refsym[] = { + "__init_begin", + "_sinittext", + "_einittext", NULL }; @@ -618,8 +636,29 @@ static int secref_whitelist(const char * for (s = pat2sym; *s; s++) if (strrcmp(atsym, *s) == 0) f1 = 1; + if (f1 && f2) + return 1; - return f1 && f2; + /* Whitelist all references from .pci_fixup section if vmlinux + * Whitelist all refereces from .text.head to .init.data if vmlinux + * Whitelist all refereces from .text.head to .init.text if vmlinux + */ + if (is_vmlinux(modname)) { + if ((strcmp(fromsec, ".pci_fixup") == 0) && + (strcmp(tosec, ".init.text") == 0)) + return 1; + + if ((strcmp(fromsec, ".text.head") == 0) && + ((strcmp(tosec, ".init.data") == 0) || + (strcmp(tosec, ".init.text") == 0))) + return 1; + + /* Check for pattern 3 */ + for (s = pat3refsym; *s; s++) + if (strcmp(refsymname, *s) == 0) + return 1; + } + return 0; } /** @@ -726,7 +765,8 @@ static void warn_sec_mismatch(const char /* check whitelist - we may ignore it */ if (before && - secref_whitelist(secname, fromsec, elf->strtab + before->st_name)) + secref_whitelist(modname, secname, fromsec, + elf->strtab + before->st_name, refsymname)) return; if (before && after) {