diff options
Diffstat (limited to 'debian/patches/bugfix/m68k/611-module_fixup.diff')
-rw-r--r-- | debian/patches/bugfix/m68k/611-module_fixup.diff | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/debian/patches/bugfix/m68k/611-module_fixup.diff b/debian/patches/bugfix/m68k/611-module_fixup.diff new file mode 100644 index 000000000000..94aa02f4698c --- /dev/null +++ b/debian/patches/bugfix/m68k/611-module_fixup.diff @@ -0,0 +1,214 @@ +Subject: [PATCH] m68k: runtime patching infrastructure + +From: Roman Zippel <zippel@linux-m68k.org> + +Add the basic infrastructure to allow runtime patching of kernel and +modules to optimize a few functions with parameters, which are only +calculated once during bootup and are otherwise constant. +Use this for the conversion between virtual and physical addresses. + +Signed-off-by: Roman Zippel <zippel@linux-m68k.org> +Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> +--- + arch/m68k/Makefile | 1 + + arch/m68k/kernel/module.c | 24 +++++++++++++++++++++++- + arch/m68k/kernel/module.lds | 7 +++++++ + arch/m68k/kernel/vmlinux-std.lds | 5 +++++ + arch/m68k/kernel/vmlinux-sun3.lds | 5 +++++ + arch/m68k/mm/motorola.c | 3 +++ + include/asm-m68k/module.h | 33 ++++++++++++++++++++++++++++++++- + include/asm-m68k/page.h | 29 ++++++++++++++++++++++++++--- + 8 files changed, 102 insertions(+), 5 deletions(-) + +--- linux-m68k-2.6.21.orig/arch/m68k/Makefile ++++ linux-m68k-2.6.21/arch/m68k/Makefile +@@ -19,6 +19,7 @@ COMPILE_ARCH = $(shell uname -m) + # override top level makefile + AS += -m68020 + LDFLAGS := -m m68kelf ++LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds + ifneq ($(COMPILE_ARCH),$(ARCH)) + # prefix for cross-compiling binaries + CROSS_COMPILE = m68k-linux-gnu- +--- linux-m68k-2.6.21.orig/arch/m68k/kernel/module.c ++++ linux-m68k-2.6.21/arch/m68k/kernel/module.c +@@ -1,3 +1,9 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive ++ * for more details. ++ */ ++ + #include <linux/moduleloader.h> + #include <linux/elf.h> + #include <linux/vmalloc.h> +@@ -116,10 +122,26 @@ int apply_relocate_add(Elf32_Shdr *sechd + return 0; + } + ++void module_fixup(struct module *mod, struct m68k_fixup_info *start, ++ struct m68k_fixup_info *end) ++{ ++ struct m68k_fixup_info *fixup; ++ ++ for (fixup = start; fixup < end; fixup++) { ++ switch (fixup->type) { ++ case m68k_fixup_memoffset: ++ *(u32 *)fixup->addr = m68k_memoffset; ++ break; ++ } ++ } ++} ++ + int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, +- struct module *me) ++ struct module *mod) + { ++ module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); ++ + return 0; + } + +--- /dev/null ++++ linux-m68k-2.6.21/arch/m68k/kernel/module.lds +@@ -0,0 +1,7 @@ ++SECTIONS { ++ .m68k_fixup : { ++ __start_fixup = .; ++ *(.m68k_fixup) ++ __stop_fixup = .; ++ } ++} +--- linux-m68k-2.6.21.orig/arch/m68k/kernel/vmlinux-std.lds ++++ linux-m68k-2.6.21/arch/m68k/kernel/vmlinux-std.lds +@@ -60,6 +60,11 @@ SECTIONS + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; ++ .m68k_fixup : { ++ __start_fixup = .; ++ *(.m68k_fixup) ++ __stop_fixup = .; ++ } + SECURITY_INIT + #ifdef CONFIG_BLK_DEV_INITRD + . = ALIGN(8192); +--- linux-m68k-2.6.21.orig/arch/m68k/kernel/vmlinux-sun3.lds ++++ linux-m68k-2.6.21/arch/m68k/kernel/vmlinux-sun3.lds +@@ -54,6 +54,11 @@ __init_begin = .; + __con_initcall_start = .; + .con_initcall.init : { *(.con_initcall.init) } + __con_initcall_end = .; ++ .m68k_fixup : { ++ __start_fixup = .; ++ *(.m68k_fixup) ++ __stop_fixup = .; ++ } + SECURITY_INIT + #ifdef CONFIG_BLK_DEV_INITRD + . = ALIGN(8192); +--- linux-m68k-2.6.21.orig/arch/m68k/mm/motorola.c ++++ linux-m68k-2.6.21/arch/m68k/mm/motorola.c +@@ -222,6 +222,9 @@ void __init paging_init(void) + pgprot_val(protection_map[i]) |= _PAGE_CACHE040; + } + ++ module_fixup(NULL, __start_fixup, __stop_fixup); ++ flush_icache(); ++ + /* + * Map the physical memory available into the kernel virtual + * address space. It may allocate some memory for page +--- linux-m68k-2.6.21.orig/include/asm-m68k/module.h ++++ linux-m68k-2.6.21/include/asm-m68k/module.h +@@ -1,7 +1,38 @@ + #ifndef _ASM_M68K_MODULE_H + #define _ASM_M68K_MODULE_H +-struct mod_arch_specific { }; ++ ++struct mod_arch_specific { ++ struct m68k_fixup_info *fixup_start, *fixup_end; ++}; ++ ++#define MODULE_ARCH_INIT { \ ++ .fixup_start = __start_fixup, \ ++ .fixup_end = __stop_fixup, \ ++} ++ + #define Elf_Shdr Elf32_Shdr + #define Elf_Sym Elf32_Sym + #define Elf_Ehdr Elf32_Ehdr ++ ++ ++enum m68k_fixup_type { ++ m68k_fixup_memoffset, ++}; ++ ++struct m68k_fixup_info { ++ enum m68k_fixup_type type; ++ void *addr; ++}; ++ ++#define m68k_fixup(type, addr) \ ++ " .section \".m68k_fixup\",\"aw\"\n" \ ++ " .long " #type "," #addr "\n" \ ++ " .previous\n" ++ ++extern struct m68k_fixup_info __start_fixup[], __stop_fixup[]; ++ ++struct module; ++extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, ++ struct m68k_fixup_info *end); ++ + #endif /* _ASM_M68K_MODULE_H */ +--- linux-m68k-2.6.21.orig/include/asm-m68k/page.h ++++ linux-m68k-2.6.21/include/asm-m68k/page.h +@@ -27,6 +27,8 @@ + + #ifndef __ASSEMBLY__ + ++#include <asm/module.h> ++ + #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) + #define free_user_page(page, addr) free_page(addr) + +@@ -114,14 +116,35 @@ typedef struct { unsigned long pgprot; } + + #ifndef __ASSEMBLY__ + ++extern unsigned long m68k_memoffset; ++ + #ifndef CONFIG_SUN3 + + #define WANT_PAGE_VIRTUAL + #ifdef CONFIG_SINGLE_MEMORY_CHUNK +-extern unsigned long m68k_memoffset; + +-#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) +-#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) ++static inline unsigned long ___pa(void *vaddr) ++{ ++ unsigned long paddr; ++ asm ( ++ "1: addl #0,%0\n" ++ m68k_fixup(%c2, 1b+2) ++ : "=r" (paddr) ++ : "0" (vaddr), "i" (m68k_fixup_memoffset)); ++ return paddr; ++} ++#define __pa(vaddr) ___pa((void *)(vaddr)) ++static inline void *__va(unsigned long paddr) ++{ ++ void *vaddr; ++ asm ( ++ "1: subl #0,%0\n" ++ m68k_fixup(%c2, 1b+2) ++ : "=r" (vaddr) ++ : "0" (paddr), "i" (m68k_fixup_memoffset)); ++ return vaddr; ++} ++ + #else + #define __pa(vaddr) virt_to_phys((void *)(vaddr)) + #define __va(paddr) phys_to_virt((unsigned long)(paddr)) |