From d4df6d4e7a66b7a9bd57f5dc7d80d6b55dc12dbb Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:01 +0200 Subject: [MIPS] setup.c: get ride of CPHYSADDR() and use new __pa() implementation instead introduced by the previous patch. Indeed this macro can be used now even by the 64 bit kernels with CONFIG_BUILD_ELF64=n config. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 8f6e89697ccf..715451a9d5d6 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -204,12 +204,12 @@ static void __init finalize_initrd(void) printk(KERN_INFO "Initrd not found or empty"); goto disable; } - if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { + if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("Initrd extends beyond end of memory"); goto disable; } - reserve_bootmem(CPHYSADDR(initrd_start), size); + reserve_bootmem(__pa(initrd_start), size); initrd_below_start_ok = 1; printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", @@ -260,7 +260,7 @@ static void __init bootmem_init(void) * of usable memory. */ reserved_end = init_initrd(); - reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); + reserved_end = PFN_UP(__pa(max(reserved_end, (unsigned long)&_end))); /* * Find the highest page frame number we have available. -- cgit v1.2.2 From f5bffe3a9bcd6e5319b5fd3a8109625f8638425a Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:03 +0200 Subject: [MIPS] setup.c: use __pa_symbol() where needed It should fix the broken code in resource_init() too. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 715451a9d5d6..b52cc9763763 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -260,7 +260,7 @@ static void __init bootmem_init(void) * of usable memory. */ reserved_end = init_initrd(); - reserved_end = PFN_UP(__pa(max(reserved_end, (unsigned long)&_end))); + reserved_end = PFN_UP(max(__pa(reserved_end), __pa_symbol(&_end))); /* * Find the highest page frame number we have available. @@ -432,10 +432,10 @@ static void __init resource_init(void) if (UNCAC_BASE != IO_BASE) return; - code_resource.start = virt_to_phys(&_text); - code_resource.end = virt_to_phys(&_etext) - 1; - data_resource.start = virt_to_phys(&_etext); - data_resource.end = virt_to_phys(&_edata) - 1; + code_resource.start = __pa_symbol(&_text); + code_resource.end = __pa_symbol(&_etext) - 1; + data_resource.start = __pa_symbol(&_etext); + data_resource.end = __pa_symbol(&_edata) - 1; /* * Request address space for all standard RAM. -- cgit v1.2.2 From a7837b76b6de932c31d0b7c71176ca8d1213a3ce Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:04 +0200 Subject: [MIPS] setup.c: clean up initrd related code Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 75 +++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 27 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index b52cc9763763..89440a0d8528 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -145,13 +145,12 @@ static int __init rd_start_early(char *p) unsigned long start = memparse(p, &p); #ifdef CONFIG_64BIT - /* HACK: Guess if the sign extension was forgotten */ - if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000UL; + /* Guess if the sign extension was forgotten by bootloader */ + if (start < XKPHYS) + start = (int)start; #endif initrd_start = start; initrd_end += start; - return 0; } early_param("rd_start", rd_start_early); @@ -159,41 +158,64 @@ early_param("rd_start", rd_start_early); static int __init rd_size_early(char *p) { initrd_end += memparse(p, &p); - return 0; } early_param("rd_size", rd_size_early); +/* it returns the next free pfn after initrd */ static unsigned long __init init_initrd(void) { - unsigned long tmp, end, size; + unsigned long end; u32 *initrd_header; - ROOT_DEV = Root_RAM0; - /* * Board specific code or command line parser should have * already set up initrd_start and initrd_end. In these cases * perfom sanity checks and use them if all looks good. */ - size = initrd_end - initrd_start; - if (initrd_end == 0 || size == 0) { - initrd_start = 0; - initrd_end = 0; - } else - return initrd_end; - - end = (unsigned long)&_end; - tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; - if (tmp < end) - tmp += PAGE_SIZE; - - initrd_header = (u32 *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; + if (initrd_start && initrd_end > initrd_start) + goto sanitize; + + /* + * See if initrd has been added to the kernel image by + * arch/mips/boot/addinitrd.c. In that case a header is + * prepended to initrd and is made up by 8 bytes. The fisrt + * word is a magic number and the second one is the size of + * initrd. Initrd start must be page aligned in any cases. + */ + initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; + if (initrd_header[0] != 0x494E5244) + goto disable; + initrd_start = (unsigned long)(initrd_header + 2); + initrd_end = initrd_start + initrd_header[1]; + +sanitize: + if (initrd_start & ~PAGE_MASK) { + printk(KERN_ERR "initrd start must be page aligned\n"); + goto disable; } - return initrd_end; + if (initrd_start < PAGE_OFFSET) { + printk(KERN_ERR "initrd start < PAGE_OFFSET\n"); + goto disable; + } + + /* + * Sanitize initrd addresses. For example firmware + * can't guess if they need to pass them through + * 64-bits values if the kernel has been built in pure + * 32-bit. We need also to switch from KSEG0 to XKPHYS + * addresses now, so the code can now safely use __pa(). + */ + end = __pa(initrd_end); + initrd_end = (unsigned long)__va(end); + initrd_start = (unsigned long)__va(__pa(initrd_start)); + + ROOT_DEV = Root_RAM0; + return PFN_UP(end); +disable: + initrd_start = 0; + initrd_end = 0; + return 0; } static void __init finalize_initrd(void) @@ -259,8 +281,7 @@ static void __init bootmem_init(void) * not selected. Once that done we can determine the low bound * of usable memory. */ - reserved_end = init_initrd(); - reserved_end = PFN_UP(max(__pa(reserved_end), __pa_symbol(&_end))); + reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); /* * Find the highest page frame number we have available. -- cgit v1.2.2 From 656be92f9ae194ed62bc81310a4589a7cd765f13 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 26 Oct 2006 00:08:31 +0900 Subject: [MIPS] Load modules to CKSEG0 if CONFIG_BUILD_ELF64=n This is a patch to load 64-bit modules to CKSEG0 so that can be compiled with -msym32 option. This makes each module ~10% smaller. * introduce MODULE_START and MODULE_END * custom module_alloc() * PGD for modules * change XTLB refill handler synthesizer * enable -msym32 for modules again (revert ca78b1a5c6a6e70e052d3ea253828e49b5d07c8a) New XTLB refill handler looks like this: 80000080 dmfc0 k0,C0_BADVADDR 80000084 bltz k0,800000e4 # goto l_module_alloc 80000088 lui k1,0x8046 # %high(pgd_current) 8000008c ld k1,24600(k1) # %low(pgd_current) 80000090 dsrl k0,k0,0x1b # l_vmalloc_done: 80000094 andi k0,k0,0x1ff8 80000098 daddu k1,k1,k0 8000009c dmfc0 k0,C0_BADVADDR 800000a0 ld k1,0(k1) 800000a4 dsrl k0,k0,0x12 800000a8 andi k0,k0,0xff8 800000ac daddu k1,k1,k0 800000b0 dmfc0 k0,C0_XCONTEXT 800000b4 ld k1,0(k1) 800000b8 andi k0,k0,0xff0 800000bc daddu k1,k1,k0 800000c0 ld k0,0(k1) 800000c4 ld k1,8(k1) 800000c8 dsrl k0,k0,0x6 800000cc mtc0 k0,C0_ENTRYLO0 800000d0 dsrl k1,k1,0x6 800000d4 mtc0 k1,C0_ENTRYL01 800000d8 nop 800000dc tlbwr 800000e0 eret 800000e4 dsll k1,k0,0x2 # l_module_alloc: 800000e8 bgez k1,80000008 # goto l_vmalloc 800000ec lui k1,0xc000 800000f0 dsubu k0,k0,k1 800000f4 lui k1,0x8046 # %high(module_pg_dir) 800000f8 beq zero,zero,80000000 800000fc nop 80000000 beq zero,zero,80000090 # goto l_vmalloc_done 80000004 daddiu k1,k1,0x4000 80000008 dsll32 k1,k1,0x0 # l_vmalloc: 8000000c dsubu k0,k0,k1 80000010 beq zero,zero,80000090 # goto l_vmalloc_done 80000014 lui k1,0x8046 # %high(swapper_pg_dir) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/head.S | 3 +++ arch/mips/kernel/module.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index ddc1b71c9378..a2e095adaa3f 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -250,6 +250,9 @@ NESTED(smp_bootstrap, 16, sp) */ page swapper_pg_dir, _PGD_ORDER #ifdef CONFIG_64BIT +#if defined(CONFIG_MODULES) && !defined(CONFIG_BUILD_ELF64) + page module_pg_dir, _PGD_ORDER +#endif page invalid_pmd_table, _PMD_ORDER #endif page invalid_pte_table, _PTE_ORDER diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index d7bf0215bc1d..cb0801437b66 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -29,6 +29,7 @@ #include #include #include +#include /* MODULE_START */ struct mips_hi16 { struct mips_hi16 *next; @@ -43,9 +44,23 @@ static DEFINE_SPINLOCK(dbe_lock); void *module_alloc(unsigned long size) { +#ifdef MODULE_START + struct vm_struct *area; + + size = PAGE_ALIGN(size); + if (!size) + return NULL; + + area = __get_vm_area(size, VM_ALLOC, MODULE_START, MODULE_END); + if (!area) + return NULL; + + return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); +#else if (size == 0) return NULL; return vmalloc(size); +#endif } /* Free memory returned from module_alloc */ -- cgit v1.2.2 From 5b10496b6e6577f65b032a5c4c97d0d3a841273c Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 11 Sep 2006 17:50:29 +0900 Subject: [MIPS] Fast path for rdhwr emulation for TLS Add special short path for emulationg RDHWR which is used to support TLS. Add an extra prologue for cpu_has_vtag_icache case. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/genex.S | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/traps.c | 15 +++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 5baca16993d0..aacd4a005c5f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -19,6 +19,7 @@ #include #include #include +#include #define PANIC_PIC(msg) \ .set push; \ @@ -378,6 +379,68 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER dsp dsp sti silent /* #26 */ BUILD_HANDLER reserved reserved sti verbose /* others */ + .align 5 + LEAF(handle_ri_rdhwr_vivt) +#ifdef CONFIG_MIPS_MT_SMTC + PANIC_PIC("handle_ri_rdhwr_vivt called") +#else + .set push + .set noat + .set noreorder + /* check if TLB contains a entry for EPC */ + MFC0 k1, CP0_ENTRYHI + andi k1, 0xff /* ASID_MASK */ + MFC0 k0, CP0_EPC + PTR_SRL k0, PAGE_SHIFT + 1 + PTR_SLL k0, PAGE_SHIFT + 1 + or k1, k0 + MTC0 k1, CP0_ENTRYHI + mtc0_tlbw_hazard + tlbp + tlb_probe_hazard + mfc0 k1, CP0_INDEX + .set pop + bltz k1, handle_ri /* slow path */ + /* fall thru */ +#endif + END(handle_ri_rdhwr_vivt) + + LEAF(handle_ri_rdhwr) + .set push + .set noat + .set noreorder + /* 0x7c03e83b: rdhwr v1,$29 */ + MFC0 k1, CP0_EPC + lui k0, 0x7c03 + lw k1, (k1) + ori k0, 0xe83b + .set reorder + bne k0, k1, handle_ri /* if not ours */ + /* The insn is rdhwr. No need to check CAUSE.BD here. */ + get_saved_sp /* k1 := current_thread_info */ + .set noreorder + MFC0 k0, CP0_EPC +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + ori k1, _THREAD_MASK + xori k1, _THREAD_MASK + LONG_L v1, TI_TP_VALUE(k1) + LONG_ADDIU k0, 4 + jr k0 + rfe +#else + LONG_ADDIU k0, 4 /* stall on $k0 */ + MTC0 k0, CP0_EPC + /* I hope three instructions between MTC0 and ERET are enough... */ + ori k1, _THREAD_MASK + xori k1, _THREAD_MASK + LONG_L v1, TI_TP_VALUE(k1) + .set mips3 + eret + .set mips0 +#endif + .set pop + END(handle_ri_rdhwr) + #ifdef CONFIG_64BIT /* A temporary overflow handler used by check_daddi(). */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9fda1b8be3a7..6eccfb49ae68 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -54,6 +54,8 @@ extern asmlinkage void handle_dbe(void); extern asmlinkage void handle_sys(void); extern asmlinkage void handle_bp(void); extern asmlinkage void handle_ri(void); +extern asmlinkage void handle_ri_rdhwr_vivt(void); +extern asmlinkage void handle_ri_rdhwr(void); extern asmlinkage void handle_cpu(void); extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); @@ -1423,6 +1425,15 @@ void __init set_uncached_handler (unsigned long offset, void *addr, unsigned lon memcpy((void *)(uncached_ebase + offset), addr, size); } +static int __initdata rdhwr_noopt; +static int __init set_rdhwr_noopt(char *str) +{ + rdhwr_noopt = 1; + return 1; +} + +__setup("rdhwr_noopt", set_rdhwr_noopt); + void __init trap_init(void) { extern char except_vec3_generic, except_vec3_r4000; @@ -1502,7 +1513,9 @@ void __init trap_init(void) set_except_vector(8, handle_sys); set_except_vector(9, handle_bp); - set_except_vector(10, handle_ri); + set_except_vector(10, rdhwr_noopt ? handle_ri : + (cpu_has_vtag_icache ? + handle_ri_rdhwr_vivt : handle_ri_rdhwr)); set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); -- cgit v1.2.2 From c237923009da464881d89f4bc27c3b5b1a93d61b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:44 +0000 Subject: [MIPS] Don't print presence of WAIT instruction on bootup. Not useful and quite a big of noise on bootup of large systems. Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 8485af340ee1..442839e9578c 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -110,9 +110,8 @@ static inline void check_wait(void) { struct cpuinfo_mips *c = ¤t_cpu_data; - printk("Checking for 'wait' instruction... "); if (nowait) { - printk (" disabled.\n"); + printk("Wait instruction disabled.\n"); return; } @@ -120,11 +119,9 @@ static inline void check_wait(void) case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; - printk(" available.\n"); break; case CPU_TX3927: cpu_wait = r39xx_wait; - printk(" available.\n"); break; case CPU_R4200: /* case CPU_R4300: */ @@ -146,33 +143,23 @@ static inline void check_wait(void) case CPU_74K: case CPU_PR4450: cpu_wait = r4k_wait; - printk(" available.\n"); break; case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; - printk(" available.\n"); break; case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: case CPU_AU1200: - if (allow_au1k_wait) { + if (allow_au1k_wait) cpu_wait = au1k_wait; - printk(" available.\n"); - } else - printk(" unavailable.\n"); break; case CPU_RM9000: - if ((c->processor_id & 0x00ff) >= 0x40) { + if ((c->processor_id & 0x00ff) >= 0x40) cpu_wait = r4k_wait; - printk(" available.\n"); - } else { - printk(" unavailable.\n"); - } break; default: - printk(" unavailable.\n"); break; } } -- cgit v1.2.2 From 583bb86fbb9e85287f020fe4eb5352a0ec3c66a3 Mon Sep 17 00:00:00 2001 From: Nicolas Schichan Date: Wed, 18 Oct 2006 15:14:55 +0200 Subject: [MIPS] Add support for kexec A tiny userland application loading the kernel and invoking kexec_load for mips is available here: http://chac.le-poulpe.net/~nico/kexec/kexec-2006-10-18.tar.gz Signed-off-by: Ralf Baechle --- arch/mips/kernel/Makefile | 2 + arch/mips/kernel/machine_kexec.c | 85 ++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/relocate_kernel.S | 80 +++++++++++++++++++++++++++++++++++ arch/mips/kernel/scall32-o32.S | 2 +- arch/mips/kernel/scall64-64.S | 2 +- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 7 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 arch/mips/kernel/machine_kexec.c create mode 100644 arch/mips/kernel/relocate_kernel.S (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 6bfbbed0897e..f35b739d0a12 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -67,6 +67,8 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o obj-$(CONFIG_I8253) += i8253.o +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o + CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c new file mode 100644 index 000000000000..e0ad754c7edd --- /dev/null +++ b/arch/mips/kernel/machine_kexec.c @@ -0,0 +1,85 @@ +/* + * machine_kexec.c for kexec + * Created by on Thu Oct 12 15:15:06 2006 + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include + +#include +#include + +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; + +extern unsigned long kexec_start_address; +extern unsigned long kexec_indirection_page; + +int +machine_kexec_prepare(struct kimage *kimage) +{ + return 0; +} + +void +machine_kexec_cleanup(struct kimage *kimage) +{ +} + +void +machine_shutdown(void) +{ +} + +void +machine_crash_shutdown(struct pt_regs *regs) +{ +} + +void +machine_kexec(struct kimage *image) +{ + unsigned long reboot_code_buffer; + unsigned long entry; + unsigned long *ptr; + + reboot_code_buffer = + (unsigned long)page_address(image->control_code_page); + + kexec_start_address = image->start; + kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK); + + memcpy((void*)reboot_code_buffer, relocate_new_kernel, + relocate_new_kernel_size); + + /* + * The generic kexec code builds a page list with physical + * addresses. they are directly accessible through KSEG0 (or + * CKSEG0 or XPHYS if on 64bit system), hence the + * pys_to_virt() call. + */ + for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE); + ptr = (entry & IND_INDIRECTION) ? + phys_to_virt(entry & PAGE_MASK) : ptr + 1) { + if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION || + *ptr & IND_DESTINATION) + *ptr = phys_to_virt(*ptr); + } + + /* + * we do not want to be bothered. + */ + local_irq_disable(); + + flush_icache_range(reboot_code_buffer, + reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); + + printk("Will call new kernel at %08x\n", image->start); + printk("Bye ...\n"); + flush_cache_all(); + ((void (*)(void))reboot_code_buffer)(); +} diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S new file mode 100644 index 000000000000..a3f0d00c1334 --- /dev/null +++ b/arch/mips/kernel/relocate_kernel.S @@ -0,0 +1,80 @@ +/* + * relocate_kernel.S for kexec + * Created by on Thu Oct 12 17:49:57 2006 + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + .globl relocate_new_kernel +relocate_new_kernel: + + PTR_L s0, kexec_indirection_page + PTR_L s1, kexec_start_address + +process_entry: + PTR_L s2, (s0) + PTR_ADD s0, s0, SZREG + + /* destination page */ + and s3, s2, 0x1 + beq s3, zero, 1f + and s4, s2, ~0x1 /* store destination addr in s4 */ + move a0, s4 + b process_entry + +1: + /* indirection page, update s0 */ + and s3, s2, 0x2 + beq s3, zero, 1f + and s0, s2, ~0x2 + b process_entry + +1: + /* done page */ + and s3, s2, 0x4 + beq s3, zero, 1f + b done +1: + /* source page */ + and s3, s2, 0x8 + beq s3, zero, process_entry + and s2, s2, ~0x8 + li s6, (1 << PAGE_SHIFT) / SZREG + +copy_word: + /* copy page word by word */ + REG_L s5, (s2) + REG_S s5, (s4) + INT_ADD s4, s4, SZREG + INT_ADD s2, s2, SZREG + INT_SUB s6, s6, 1 + beq s6, zero, process_entry + b copy_word + b process_entry + +done: + /* jump to kexec_start_address */ + j s1 + + .globl kexec_start_address +kexec_start_address: + .long 0x0 + + .globl kexec_indirection_page +kexec_indirection_page: + .long 0x0 + +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .long relocate_new_kernel_end - relocate_new_kernel diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index a95f37de080e..7c0b3936ba44 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -653,7 +653,7 @@ einval: li v0, -EINVAL sys sys_move_pages 6 sys sys_set_robust_list 2 sys sys_get_robust_list 3 /* 4310 */ - sys sys_ni_syscall 0 + sys sys_kexec_load 4 sys sys_getcpu 3 sys sys_epoll_pwait 6 .endm diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 8fb0f60f657b..e569b846e9a3 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -468,6 +468,6 @@ sys_call_table: PTR sys_move_pages PTR sys_set_robust_list PTR sys_get_robust_list - PTR sys_ni_syscall /* 5270 */ + PTR sys_kexec_load /* 5270 */ PTR sys_getcpu PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 0da5ca2040ff..5b18f265d75b 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -394,6 +394,6 @@ EXPORT(sysn32_call_table) PTR sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list - PTR sys_ni_syscall + PTR compat_sys_kexec_load PTR sys_getcpu PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b9d00cae8b5f..e91379c1be1d 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -516,7 +516,7 @@ sys_call_table: PTR compat_sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ - PTR sys_ni_syscall + PTR compat_sys_kexec_load PTR sys_getcpu PTR sys_epoll_pwait .size sys_call_table,.-sys_call_table -- cgit v1.2.2 From c87b6ebaea034c0e0ce86127870cf1511a307b64 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 28 Oct 2006 01:14:37 +0900 Subject: [MIPS] mips hpt cleanup: get rid of mips_hpt_init Currently nobody outside time.c require mips_hpt_init(). Remove it and call c0_hpt_timer_init() directly if R4k counter was used for timer interrupt. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index e535f86efa2f..111d1baa3b22 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -88,12 +88,6 @@ static unsigned int null_hpt_read(void) return 0; } -static void __init null_hpt_init(void) -{ - /* nothing */ -} - - /* * Timer ack for an R4k-compatible timer of a known frequency. */ @@ -133,7 +127,6 @@ static void __init c0_hpt_timer_init(void) int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); -void (*mips_hpt_init)(void) __initdata = null_hpt_init; unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ @@ -383,16 +376,20 @@ void __init time_init(void) if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ - mips_hpt_init = c0_hpt_timer_init; mips_timer_ack = c0_timer_ack; + /* Calculate cache parameters. */ + cycles_per_jiffy = + (mips_hpt_frequency + HZ / 2) / HZ; + /* + * This sets up the high precision + * timer for the first interrupt. + */ + c0_hpt_timer_init(); } } if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); - /* Calculate cache parameters. */ - cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; - /* Report the high precision timer rate for a reference. */ printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, @@ -403,9 +400,6 @@ void __init time_init(void) /* No timer interrupt ack (e.g. i8254). */ mips_timer_ack = null_timer_ack; - /* This sets up the high precision timer for the first interrupt. */ - mips_hpt_init(); - /* * Call board specific timer interrupt setup. * -- cgit v1.2.2 From 1603b5aca4f15b34848fb5594d0c7b6333b99144 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 2 Nov 2006 02:08:36 +0900 Subject: [MIPS] IRQ cleanups This is a big irq cleanup patch. * Use set_irq_chip() to register irq_chip. * Initialize .mask, .unmask, .mask_ack field. Functions for these method are already exist in most case. * Do not initialize .startup, .shutdown, .enable, .disable fields if default routines provided by irq_chip_set_defaults() were suitable. * Remove redundant irq_desc initializations. * Remove unnecessary local_irq_save/local_irq_restore, spin_lock. With this cleanup, it would be easy to switch to slightly lightwait irq flow handlers (handle_level_irq(), etc.) instead of __do_IRQ(). Though whole this patch is quite large, changes in each irq_chip are not quite simple. Please review and test on your platform. Thanks. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 21 ++---------- arch/mips/kernel/irq-msc01.c | 45 +++++------------------- arch/mips/kernel/irq-mv6434x.c | 53 ++++------------------------- arch/mips/kernel/irq-rm7000.c | 53 ++++------------------------- arch/mips/kernel/irq-rm9000.c | 45 ++++++------------------ arch/mips/kernel/irq.c | 13 ------- arch/mips/kernel/irq_cpu.c | 77 +++++++----------------------------------- 7 files changed, 47 insertions(+), 260 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 48e3418c217b..2526c0ca4d81 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -40,21 +40,10 @@ static void end_8259A_irq (unsigned int irq) enable_8259A_irq(irq); } -#define shutdown_8259A_irq disable_8259A_irq - void mask_and_ack_8259A(unsigned int); -static unsigned int startup_8259A_irq(unsigned int irq) -{ - enable_8259A_irq(irq); - - return 0; /* never anything pending */ -} - static struct irq_chip i8259A_irq_type = { .typename = "XT-PIC", - .startup = startup_8259A_irq, - .shutdown = shutdown_8259A_irq, .enable = enable_8259A_irq, .disable = disable_8259A_irq, .ack = mask_and_ack_8259A, @@ -120,7 +109,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &i8259A_irq_type; + set_irq_chip(irq, &i8259A_irq_type); enable_irq(irq); } @@ -323,12 +312,8 @@ void __init init_i8259_irqs (void) init_8259A(0); - for (i = 0; i < 16; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &i8259A_irq_type; - } + for (i = 0; i < 16; i++) + set_irq_chip(i, &i8259A_irq_type); setup_irq(2, &irq2); } diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 650a80ca3741..e1880b27381b 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -44,31 +44,6 @@ static inline void unmask_msc_irq(unsigned int irq) MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32)); } -/* - * Enables the IRQ on SOC-it - */ -static void enable_msc_irq(unsigned int irq) -{ - unmask_msc_irq(irq); -} - -/* - * Initialize the IRQ on SOC-it - */ -static unsigned int startup_msc_irq(unsigned int irq) -{ - unmask_msc_irq(irq); - return 0; -} - -/* - * Disables the IRQ on SOC-it - */ -static void disable_msc_irq(unsigned int irq) -{ - mask_msc_irq(irq); -} - /* * Masks and ACKs an IRQ */ @@ -136,25 +111,21 @@ msc_bind_eic_interrupt (unsigned int irq, unsigned int set) (irq<im_type) { case MSC01_IRQ_EDGE: - irq_desc[base+n].chip = &msc_edgeirq_type; + set_irq_chip(base+n, &msc_edgeirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_desc[base+n].chip = &msc_levelirq_type; + set_irq_chip(base+n, &msc_levelirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 37d106202b83..5012b9df1b5a 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -66,39 +66,6 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } -/* - * Enables the IRQ on Marvell Chip - */ -static void enable_mv64340_irq(unsigned int irq) -{ - unmask_mv64340_irq(irq); -} - -/* - * Initialize the IRQ on Marvell Chip - */ -static unsigned int startup_mv64340_irq(unsigned int irq) -{ - unmask_mv64340_irq(irq); - return 0; -} - -/* - * Disables the IRQ on Marvell Chip - */ -static void disable_mv64340_irq(unsigned int irq) -{ - mask_mv64340_irq(irq); -} - -/* - * Masks and ACKs an IRQ - */ -static void mask_and_ack_mv64340_irq(unsigned int irq) -{ - mask_mv64340_irq(irq); -} - /* * End IRQ processing */ @@ -133,15 +100,12 @@ void ll_mv64340_irq(void) do_IRQ(ls1bit32(irq_src_high) + irq_base + 32); } -#define shutdown_mv64340_irq disable_mv64340_irq - struct irq_chip mv64340_irq_type = { .typename = "MV-64340", - .startup = startup_mv64340_irq, - .shutdown = shutdown_mv64340_irq, - .enable = enable_mv64340_irq, - .disable = disable_mv64340_irq, - .ack = mask_and_ack_mv64340_irq, + .ack = mask_mv64340_irq, + .mask = mask_mv64340_irq, + .mask_ack = mask_mv64340_irq, + .unmask = unmask_mv64340_irq, .end = end_mv64340_irq, }; @@ -149,13 +113,8 @@ void __init mv64340_irq_init(unsigned int base) { int i; - /* Reset irq handlers pointers to NULL */ - for (i = base; i < base + 64; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 2; - irq_desc[i].chip = &mv64340_irq_type; - } + for (i = base; i < base + 64; i++) + set_irq_chip(i, &mv64340_irq_type); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 6b54c7109e2e..6a297e3b8899 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -29,42 +29,6 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } -static inline void rm7k_cpu_irq_enable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - unmask_rm7k_irq(irq); - local_irq_restore(flags); -} - -static void rm7k_cpu_irq_disable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - mask_rm7k_irq(irq); - local_irq_restore(flags); -} - -static unsigned int rm7k_cpu_irq_startup(unsigned int irq) -{ - rm7k_cpu_irq_enable(irq); - - return 0; -} - -#define rm7k_cpu_irq_shutdown rm7k_cpu_irq_disable - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for rm7k_cpu_irq_end. - */ -static void rm7k_cpu_irq_ack(unsigned int irq) -{ - mask_rm7k_irq(irq); -} - static void rm7k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -73,11 +37,10 @@ static void rm7k_cpu_irq_end(unsigned int irq) static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", - .startup = rm7k_cpu_irq_startup, - .shutdown = rm7k_cpu_irq_shutdown, - .enable = rm7k_cpu_irq_enable, - .disable = rm7k_cpu_irq_disable, - .ack = rm7k_cpu_irq_ack, + .ack = mask_rm7k_irq, + .mask = mask_rm7k_irq, + .mask_ack = mask_rm7k_irq, + .unmask = unmask_rm7k_irq, .end = rm7k_cpu_irq_end, }; @@ -87,12 +50,8 @@ void __init rm7k_cpu_irq_init(int base) clear_c0_intcontrol(0x00000f00); /* Mask all */ - for (i = base; i < base + 4; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &rm7k_irq_controller; - } + for (i = base; i < base + 4; i++) + set_irq_chip(i, &rm7k_irq_controller); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 62f011ba97a2..977538445cf3 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -48,15 +48,6 @@ static void rm9k_cpu_irq_disable(unsigned int irq) local_irq_restore(flags); } -static unsigned int rm9k_cpu_irq_startup(unsigned int irq) -{ - rm9k_cpu_irq_enable(irq); - - return 0; -} - -#define rm9k_cpu_irq_shutdown rm9k_cpu_irq_disable - /* * Performance counter interrupts are global on all processors. */ @@ -89,16 +80,6 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for rm9k_cpu_irq_end. - */ -static void rm9k_cpu_irq_ack(unsigned int irq) -{ - mask_rm9k_irq(irq); -} - static void rm9k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -107,11 +88,10 @@ static void rm9k_cpu_irq_end(unsigned int irq) static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", - .startup = rm9k_cpu_irq_startup, - .shutdown = rm9k_cpu_irq_shutdown, - .enable = rm9k_cpu_irq_enable, - .disable = rm9k_cpu_irq_disable, - .ack = rm9k_cpu_irq_ack, + .ack = mask_rm9k_irq, + .mask = mask_rm9k_irq, + .mask_ack = mask_rm9k_irq, + .unmask = unmask_rm9k_irq, .end = rm9k_cpu_irq_end, }; @@ -119,9 +99,10 @@ static struct irq_chip rm9k_perfcounter_irq = { .typename = "RM9000", .startup = rm9k_perfcounter_irq_startup, .shutdown = rm9k_perfcounter_irq_shutdown, - .enable = rm9k_cpu_irq_enable, - .disable = rm9k_cpu_irq_disable, - .ack = rm9k_cpu_irq_ack, + .ack = mask_rm9k_irq, + .mask = mask_rm9k_irq, + .mask_ack = mask_rm9k_irq, + .unmask = unmask_rm9k_irq, .end = rm9k_cpu_irq_end, }; @@ -135,15 +116,11 @@ void __init rm9k_cpu_irq_init(int base) clear_c0_intcontrol(0x0000f000); /* Mask all */ - for (i = base; i < base + 4; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &rm9k_irq_controller; - } + for (i = base; i < base + 4; i++) + set_irq_chip(i, &rm9k_irq_controller); rm9000_perfcount_irq = base + 1; - irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; + set_irq_chip(rm9000_perfcount_irq, &rm9k_perfcounter_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 9b0e49d63d7b..e997c9454f47 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -172,19 +172,6 @@ __setup("nokgdb", nokgdb); void __init init_IRQ(void) { - int i; - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &no_irq_chip; - spin_lock_init(&irq_desc[i].lock); -#ifdef CONFIG_MIPS_MT_SMTC - irq_hwmask[i] = 0; -#endif /* CONFIG_MIPS_MT_SMTC */ - } - arch_init_irq(); #ifdef CONFIG_KGDB diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 9bb21c7f2149..3b7cfa407e87 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -50,44 +50,6 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } -static inline void mips_cpu_irq_enable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - unmask_mips_irq(irq); - back_to_back_c0_hazard(); - local_irq_restore(flags); -} - -static void mips_cpu_irq_disable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - mask_mips_irq(irq); - back_to_back_c0_hazard(); - local_irq_restore(flags); -} - -static unsigned int mips_cpu_irq_startup(unsigned int irq) -{ - mips_cpu_irq_enable(irq); - - return 0; -} - -#define mips_cpu_irq_shutdown mips_cpu_irq_disable - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for mips_cpu_irq_end. - */ -static void mips_cpu_irq_ack(unsigned int irq) -{ - mask_mips_irq(irq); -} - static void mips_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -96,11 +58,10 @@ static void mips_cpu_irq_end(unsigned int irq) static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", - .startup = mips_cpu_irq_startup, - .shutdown = mips_cpu_irq_shutdown, - .enable = mips_cpu_irq_enable, - .disable = mips_cpu_irq_disable, - .ack = mips_cpu_irq_ack, + .ack = mask_mips_irq, + .mask = mask_mips_irq, + .mask_ack = mask_mips_irq, + .unmask = unmask_mips_irq, .end = mips_cpu_irq_end, }; @@ -110,8 +71,6 @@ static struct irq_chip mips_cpu_irq_controller = { #define unmask_mips_mt_irq unmask_mips_irq #define mask_mips_mt_irq mask_mips_irq -#define mips_mt_cpu_irq_enable mips_cpu_irq_enable -#define mips_mt_cpu_irq_disable mips_cpu_irq_disable static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) { @@ -119,13 +78,11 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); evpe(vpflags); - mips_mt_cpu_irq_enable(irq); + unmask_mips_mt_irq(irq); return 0; } -#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable - /* * While we ack the interrupt interrupts are disabled and thus we don't need * to deal with concurrency issues. Same for mips_cpu_irq_end. @@ -143,10 +100,10 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, - .shutdown = mips_mt_cpu_irq_shutdown, - .enable = mips_mt_cpu_irq_enable, - .disable = mips_mt_cpu_irq_disable, .ack = mips_mt_cpu_irq_ack, + .mask = mask_mips_mt_irq, + .mask_ack = mips_mt_cpu_irq_ack, + .unmask = unmask_mips_mt_irq, .end = mips_mt_cpu_irq_end, }; @@ -163,19 +120,11 @@ void __init mips_cpu_irq_init(int irq_base) * leave them uninitialized for other processors. */ if (cpu_has_mipsmt) - for (i = irq_base; i < irq_base + 2; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_mt_cpu_irq_controller; - } - - for (i = irq_base + 2; i < irq_base + 8; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_cpu_irq_controller; - } + for (i = irq_base; i < irq_base + 2; i++) + set_irq_chip(i, &mips_mt_cpu_irq_controller); + + for (i = irq_base + 2; i < irq_base + 8; i++) + set_irq_chip(i, &mips_cpu_irq_controller); mips_cpu_irq_base = irq_base; } -- cgit v1.2.2 From 1417836e81c0ab8f5a0bfeafa90d3eaa41b2a067 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 14 Nov 2006 01:13:18 +0900 Subject: [MIPS] use generic_handle_irq, handle_level_irq, handle_percpu_irq Further incorporation of generic irq framework. Replacing __do_IRQ() by proper flow handler would make the irq handling path a bit simpler and faster. * use generic_handle_irq() instead of __do_IRQ(). * use handle_level_irq for obvious level-type irq chips. * use handle_percpu_irq for irqs marked as IRQ_PER_CPU. * setup .eoi routine for irq chips possibly used with handle_percpu_irq. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq-msc01.c | 2 ++ arch/mips/kernel/irq-mv6434x.c | 3 ++- arch/mips/kernel/irq-rm7000.c | 3 ++- arch/mips/kernel/irq-rm9000.c | 6 ++++-- arch/mips/kernel/irq_cpu.c | 5 ++++- arch/mips/kernel/smp-mt.c | 2 ++ arch/mips/kernel/smtc.c | 1 + 7 files changed, 17 insertions(+), 5 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index e1880b27381b..bcaad6696082 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -117,6 +117,7 @@ struct irq_chip msc_levelirq_type = { .mask = mask_msc_irq, .mask_ack = level_mask_and_ack_msc_irq, .unmask = unmask_msc_irq, + .eoi = unmask_msc_irq, .end = end_msc_irq, }; @@ -126,6 +127,7 @@ struct irq_chip msc_edgeirq_type = { .mask = mask_msc_irq, .mask_ack = edge_mask_and_ack_msc_irq, .unmask = unmask_msc_irq, + .eoi = unmask_msc_irq, .end = end_msc_irq, }; diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 5012b9df1b5a..6cfb31cafde2 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -114,7 +114,8 @@ void __init mv64340_irq_init(unsigned int base) int i; for (i = base; i < base + 64; i++) - set_irq_chip(i, &mv64340_irq_type); + set_irq_chip_and_handler(i, &mv64340_irq_type, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 6a297e3b8899..ddcc2a5f8a06 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -51,7 +51,8 @@ void __init rm7k_cpu_irq_init(int base) clear_c0_intcontrol(0x00000f00); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip(i, &rm7k_irq_controller); + set_irq_chip_and_handler(i, &rm7k_irq_controller, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 977538445cf3..ba6440c88abd 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -117,10 +117,12 @@ void __init rm9k_cpu_irq_init(int base) clear_c0_intcontrol(0x0000f000); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip(i, &rm9k_irq_controller); + set_irq_chip_and_handler(i, &rm9k_irq_controller, + handle_level_irq); rm9000_perfcount_irq = base + 1; - set_irq_chip(rm9000_perfcount_irq, &rm9k_perfcounter_irq); + set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 3b7cfa407e87..be5ac23d3812 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -62,6 +62,7 @@ static struct irq_chip mips_cpu_irq_controller = { .mask = mask_mips_irq, .mask_ack = mask_mips_irq, .unmask = unmask_mips_irq, + .eoi = unmask_mips_irq, .end = mips_cpu_irq_end, }; @@ -104,6 +105,7 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .mask = mask_mips_mt_irq, .mask_ack = mips_mt_cpu_irq_ack, .unmask = unmask_mips_mt_irq, + .eoi = unmask_mips_mt_irq, .end = mips_mt_cpu_irq_end, }; @@ -124,7 +126,8 @@ void __init mips_cpu_irq_init(int irq_base) set_irq_chip(i, &mips_mt_cpu_irq_controller); for (i = irq_base + 2; i < irq_base + 8; i++) - set_irq_chip(i, &mips_cpu_irq_controller); + set_irq_chip_and_handler(i, &mips_cpu_irq_controller, + handle_level_irq); mips_cpu_irq_base = irq_base; } diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 2ac19a6cbf68..1ee689c0e0c9 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -278,7 +278,9 @@ void __init plat_prepare_cpus(unsigned int max_cpus) /* need to mark IPI's as IRQ_PER_CPU */ irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } /* diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 3b78caf112f5..802febed7df5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1009,6 +1009,7 @@ void setup_cross_vpe_interrupts(void) setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_irq, handle_percpu_irq); } /* -- cgit v1.2.2 From dd6bfd627c4f4df771b9b73e4df75c6c0c177b09 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Tue, 7 Nov 2006 09:56:24 +0100 Subject: [MIPS] Fix double inclusions Signed-off-by: Nicolas Kaiser Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal_n32.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 477c5334ec1b..a67c18555ed3 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -17,7 +17,6 @@ */ #include #include -#include #include #include #include -- cgit v1.2.2 From e56798824456bd907cefe840ca127df0518942e3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:47 +0000 Subject: [MIPS] Work around bogus gcc warnings. Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6eccfb49ae68..0ae19e1fa867 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -399,19 +399,6 @@ asmlinkage void do_be(struct pt_regs *regs) force_sig(SIGBUS, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned int __user *epc; - - epc = (unsigned int __user *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(*opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - /* * ll/sc emulation */ @@ -546,8 +533,8 @@ static inline int simulate_llsc(struct pt_regs *regs) { unsigned int opcode; - if (unlikely(get_insn_opcode(regs, &opcode))) - return -EFAULT; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; if ((opcode & OPCODE) == LL) { simulate_ll(regs, opcode); @@ -559,6 +546,10 @@ static inline int simulate_llsc(struct pt_regs *regs) } return -EFAULT; /* Strange things going on ... */ + +out_sigsegv: + force_sig(SIGSEGV, current); + return -EFAULT; } /* @@ -571,8 +562,8 @@ static inline int simulate_rdhwr(struct pt_regs *regs) struct thread_info *ti = task_thread_info(current); unsigned int opcode; - if (unlikely(get_insn_opcode(regs, &opcode))) - return -EFAULT; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; if (unlikely(compute_return_epc(regs))) return -EFAULT; @@ -591,6 +582,10 @@ static inline int simulate_rdhwr(struct pt_regs *regs) /* Not ours. */ return -EFAULT; + +out_sigsegv: + force_sig(SIGSEGV, current); + return -EFAULT; } asmlinkage void do_ov(struct pt_regs *regs) @@ -676,8 +671,8 @@ asmlinkage void do_bp(struct pt_regs *regs) die_if_kernel("Break instruction in kernel code", regs); - if (get_insn_opcode(regs, &opcode)) - return; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break @@ -710,6 +705,9 @@ asmlinkage void do_bp(struct pt_regs *regs) default: force_sig(SIGTRAP, current); } + +out_sigsegv: + force_sig(SIGSEGV, current); } asmlinkage void do_tr(struct pt_regs *regs) @@ -719,8 +717,8 @@ asmlinkage void do_tr(struct pt_regs *regs) die_if_kernel("Trap instruction in kernel code", regs); - if (get_insn_opcode(regs, &opcode)) - return; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) @@ -747,6 +745,9 @@ asmlinkage void do_tr(struct pt_regs *regs) default: force_sig(SIGTRAP, current); } + +out_sigsegv: + force_sig(SIGSEGV, current); } asmlinkage void do_ri(struct pt_regs *regs) -- cgit v1.2.2 From 187933f23679c413706030aefad9e85e79164c44 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 25 Oct 2006 23:57:04 +0900 Subject: [MIPS] do_IRQ cleanup Now we have both function and macro version of do_IRQ() and the former is used only by DEC and non-preemptive kernel. This patch makes everyone use the macro version and removes the function version. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index e997c9454f47..b339798b3172 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -88,25 +88,6 @@ atomic_t irq_err_count; unsigned long irq_hwmask[NR_IRQS]; #endif /* CONFIG_MIPS_MT_SMTC */ -#undef do_IRQ - -/* - * do_IRQ handles all normal device IRQ's (the special - * SMP cross-CPU interrupts have their own specific - * handlers). - */ -asmlinkage unsigned int do_IRQ(unsigned int irq) -{ - irq_enter(); - - __DO_IRQ_SMTC_HOOK(); - __do_IRQ(irq); - - irq_exit(); - - return 1; -} - /* * Generic, controller-independent functions: */ -- cgit v1.2.2 From 005985609ff72df3257fde6b29aa9d71342c2a6b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 12 Nov 2006 00:10:28 +0900 Subject: [MIPS] mips HPT cleanup: make clocksource_mips public Make clocksource_mips public and get rid of mips_hpt_read, mips_hpt_mask. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 111d1baa3b22..11aab6d6bfe5 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,7 +11,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -83,7 +82,7 @@ static void null_timer_ack(void) { /* nothing */ } /* * Null high precision timer functions for systems lacking one. */ -static unsigned int null_hpt_read(void) +static cycle_t null_hpt_read(void) { return 0; } @@ -112,7 +111,7 @@ static void c0_timer_ack(void) /* * High precision timer functions for a R4k-compatible timer. */ -static unsigned int c0_hpt_read(void) +static cycle_t c0_hpt_read(void) { return read_c0_count(); } @@ -126,8 +125,6 @@ static void __init c0_hpt_timer_init(void) int (*mips_timer_state)(void); void (*mips_timer_ack)(void); -unsigned int (*mips_hpt_read)(void); -unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -269,8 +266,7 @@ static struct irqaction timer_irqaction = { static unsigned int __init calibrate_hpt(void) { - u64 frequency; - u32 hpt_start, hpt_end, hpt_count, hz; + cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; const int loops = HZ / 10; int log_2_loops = 0; @@ -296,28 +292,23 @@ static unsigned int __init calibrate_hpt(void) * during the calculated number of periods between timer * interrupts. */ - hpt_start = mips_hpt_read(); + hpt_start = clocksource_mips.read(); do { while (mips_timer_state()); while (!mips_timer_state()); } while (--i); - hpt_end = mips_hpt_read(); + hpt_end = clocksource_mips.read(); - hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; + hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask; hz = HZ; - frequency = (u64)hpt_count * (u64)hz; + frequency = hpt_count * hz; return frequency >> log_2_loops; } -static cycle_t read_mips_hpt(void) -{ - return (cycle_t)mips_hpt_read(); -} - -static struct clocksource clocksource_mips = { +struct clocksource clocksource_mips = { .name = "MIPS", - .read = read_mips_hpt, + .mask = 0xffffffff, .is_continuous = 1, }; @@ -326,7 +317,7 @@ static void __init init_mips_clocksource(void) u64 temp; u32 shift; - if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) + if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) return; /* Calclate a somewhat reasonable rating value */ @@ -340,7 +331,6 @@ static void __init init_mips_clocksource(void) } clocksource_mips.shift = shift; clocksource_mips.mult = (u32)temp; - clocksource_mips.mask = mips_hpt_mask; clocksource_register(&clocksource_mips); } @@ -360,19 +350,19 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !mips_hpt_read) + if (!cpu_has_counter && !clocksource_mips.read) /* No high precision timer -- sorry. */ - mips_hpt_read = null_hpt_read; + clocksource_mips.read = null_hpt_read; else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ - if (!mips_hpt_read) + if (!clocksource_mips.read) /* No external high precision timer -- use R4k. */ - mips_hpt_read = c0_hpt_read; + clocksource_mips.read = c0_hpt_read; } else { /* We know counter frequency. Or we can get it. */ - if (!mips_hpt_read) { + if (!clocksource_mips.read) { /* No external high precision timer -- use R4k. */ - mips_hpt_read = c0_hpt_read; + clocksource_mips.read = c0_hpt_read; if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ -- cgit v1.2.2 From 63dc68a8cf60cb110b147dab1704d990808b39e2 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 16 Oct 2006 01:38:50 +0100 Subject: [MIPS] Use conditional traps for BUG_ON on MIPS II and better. This shaves of around 4kB and a few cycles for the average kernel that has CONFIG_BUG enabled. Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 0ae19e1fa867..2a932cada244 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -669,8 +669,6 @@ asmlinkage void do_bp(struct pt_regs *regs) unsigned int opcode, bcode; siginfo_t info; - die_if_kernel("Break instruction in kernel code", regs); - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; @@ -693,6 +691,7 @@ asmlinkage void do_bp(struct pt_regs *regs) switch (bcode) { case BRK_OVERFLOW << 10: case BRK_DIVZERO << 10: + die_if_kernel("Break instruction in kernel code", regs); if (bcode == (BRK_DIVZERO << 10)) info.si_code = FPE_INTDIV; else @@ -702,7 +701,11 @@ asmlinkage void do_bp(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; + case BRK_BUG: + die("Kernel bug detected", regs); + break; default: + die_if_kernel("Break instruction in kernel code", regs); force_sig(SIGTRAP, current); } @@ -715,8 +718,6 @@ asmlinkage void do_tr(struct pt_regs *regs) unsigned int opcode, tcode = 0; siginfo_t info; - die_if_kernel("Trap instruction in kernel code", regs); - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; @@ -733,6 +734,7 @@ asmlinkage void do_tr(struct pt_regs *regs) switch (tcode) { case BRK_OVERFLOW: case BRK_DIVZERO: + die_if_kernel("Trap instruction in kernel code", regs); if (tcode == BRK_DIVZERO) info.si_code = FPE_INTDIV; else @@ -742,7 +744,11 @@ asmlinkage void do_tr(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; + case BRK_BUG: + die("Kernel bug detected", regs); + break; default: + die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } -- cgit v1.2.2 From aa414dff4f7bef29457592414551becdca72dd6b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:51 +0000 Subject: [MIPS] Remove duplicate ISA DMA code for 0 DMA channel case. Signed-off-by: Ralf Baechle --- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/dma-no-isa.c | 28 ---------------------------- 2 files changed, 29 deletions(-) delete mode 100644 arch/mips/kernel/dma-no-isa.c (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index f35b739d0a12..bbbb8d7cb89b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o -obj-$(CONFIG_NO_ISA) += dma-no-isa.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o diff --git a/arch/mips/kernel/dma-no-isa.c b/arch/mips/kernel/dma-no-isa.c deleted file mode 100644 index 6df8b07741e3..000000000000 --- a/arch/mips/kernel/dma-no-isa.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2004 by Ralf Baechle - * - * Dummy ISA DMA functions for systems that don't have ISA but share drivers - * with ISA such as legacy free PCI. - */ -#include -#include -#include - -DEFINE_SPINLOCK(dma_spin_lock); - -int request_dma(unsigned int dmanr, const char * device_id) -{ - return -EINVAL; -} - -void free_dma(unsigned int dmanr) -{ -} - -EXPORT_SYMBOL(dma_spin_lock); -EXPORT_SYMBOL(request_dma); -EXPORT_SYMBOL(free_dma); -- cgit v1.2.2 From 05e4396651ca1cac51d8da9ff4992741c9dc1e39 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 7 Nov 2006 18:02:44 +0900 Subject: [MIPS] Use SYSVIPC_COMPAT to fix various problems on N32 N32 SysV IPC system calls should use 32-bit compatible code. arch/mips/kernel/linux32.c have similar compatible code for O32, but ipc/compat.c seems more complete. We can use it for both N32 and O32. This patch should fix these problems (and other possible problems): http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=1149188824.6986.6.camel%40diimka-laptop http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=44C6B829.8050508%40caviumnetworks.com Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 578 ++--------------------------------------- arch/mips/kernel/scall64-n32.S | 14 +- 2 files changed, 30 insertions(+), 562 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 7a3ebbeba1f3..b061c9aa6302 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -382,531 +382,6 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, return ret; } -struct msgbuf32 { s32 mtype; char mtext[1]; }; - -struct ipc_perm32 -{ - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; -}; - -struct ipc64_perm32 { - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; - unsigned short __pad1; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct semid_ds32 { - struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ - compat_time_t sem_otime; /* last semop time */ - compat_time_t sem_ctime; /* last change time */ - u32 sem_base; /* ptr to first semaphore in array */ - u32 sem_pending; /* pending operations to be processed */ - u32 sem_pending_last; /* last pending operation */ - u32 undo; /* undo requests on this array */ - unsigned short sem_nsems; /* no. of semaphores in array */ -}; - -struct semid64_ds32 { - struct ipc64_perm32 sem_perm; - compat_time_t sem_otime; - compat_time_t sem_ctime; - unsigned int sem_nsems; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct msqid_ds32 -{ - struct ipc_perm32 msg_perm; - u32 msg_first; - u32 msg_last; - compat_time_t msg_stime; - compat_time_t msg_rtime; - compat_time_t msg_ctime; - u32 wwait; - u32 rwait; - unsigned short msg_cbytes; - unsigned short msg_qnum; - unsigned short msg_qbytes; - compat_ipc_pid_t msg_lspid; - compat_ipc_pid_t msg_lrpid; -}; - -struct msqid64_ds32 { - struct ipc64_perm32 msg_perm; - compat_time_t msg_stime; - unsigned int __unused1; - compat_time_t msg_rtime; - unsigned int __unused2; - compat_time_t msg_ctime; - unsigned int __unused3; - unsigned int msg_cbytes; - unsigned int msg_qnum; - unsigned int msg_qbytes; - compat_pid_t msg_lspid; - compat_pid_t msg_lrpid; - unsigned int __unused4; - unsigned int __unused5; -}; - -struct shmid_ds32 { - struct ipc_perm32 shm_perm; - int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_ipc_pid_t shm_cpid; - compat_ipc_pid_t shm_lpid; - unsigned short shm_nattch; -}; - -struct shmid64_ds32 { - struct ipc64_perm32 shm_perm; - compat_size_t shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_pid_t shm_cpid; - compat_pid_t shm_lpid; - unsigned int shm_nattch; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct ipc_kludge32 { - u32 msgp; - s32 msgtyp; -}; - -static int -do_sys32_semctl(int first, int second, int third, void __user *uptr) -{ - union semun fourth; - u32 pad; - int err, err2; - struct semid64_ds s; - mm_segment_t old_fs; - - if (!uptr) - return -EINVAL; - err = -EFAULT; - if (get_user (pad, (u32 __user *)uptr)) - return err; - if ((third & ~IPC_64) == SETVAL) - fourth.val = (int)pad; - else - fourth.__pad = (void __user *)A(pad); - switch (third & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case IPC_SET: - case SEM_INFO: - case GETVAL: - case GETPID: - case GETNCNT: - case GETZCNT: - case GETALL: - case SETVAL: - case SETALL: - err = sys_semctl (first, second, third, fourth); - break; - - case IPC_STAT: - case SEM_STAT: - fourth.__pad = (struct semid64_ds __user *)&s; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_semctl(first, second, third | IPC_64, fourth); - set_fs(old_fs); - - if (third & IPC_64) { - struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp64->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); - } else { - struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp32->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); - } - if (err2) - err = -EFAULT; - break; - - default: - err = - EINVAL; - break; - } - - return err; -} - -static int -do_sys32_msgsnd (int first, int second, int third, void __user *uptr) -{ - struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (second < 0) - return -EINVAL; - p = kmalloc (second + sizeof (struct msgbuf) - + 4, GFP_USER); - if (!p) - return -ENOMEM; - err = get_user (p->mtype, &up->mtype); - if (err) - goto out; - err |= __copy_from_user (p->mtext, &up->mtext, second); - if (err) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third); - set_fs (old_fs); -out: - kfree (p); - - return err; -} - -static int -do_sys32_msgrcv (int first, int second, int msgtyp, int third, - int version, void __user *uptr) -{ - struct msgbuf32 __user *up; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (!version) { - struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr; - struct ipc_kludge32 ipck; - - err = -EINVAL; - if (!uptr) - goto out; - err = -EFAULT; - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) - goto out; - uptr = (void __user *)AA(ipck.msgp); - msgtyp = ipck.msgtyp; - } - - if (second < 0) - return -EINVAL; - err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); - if (!p) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third); - set_fs (old_fs); - if (err < 0) - goto free_then_out; - up = (struct msgbuf32 __user *)uptr; - if (put_user (p->mtype, &up->mtype) || - __copy_to_user (&up->mtext, p->mtext, err)) - err = -EFAULT; -free_then_out: - kfree (p); -out: - return err; -} - -static int -do_sys32_msgctl (int first, int second, void __user *uptr) -{ - int err = -EINVAL, err2; - struct msqid64_ds m; - struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr; - struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr; - mm_segment_t old_fs; - - switch (second & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case MSG_INFO: - err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr); - break; - - case IPC_SET: - if (second & IPC_64) { - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); - } else { - if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - break; - - case IPC_STAT: - case MSG_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up64->msg_stime); - err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); - if (err2) - err = -EFAULT; - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up32->msg_stime); - err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); - if (err2) - err = -EFAULT; - } - break; - } - - return err; -} - -static int -do_sys32_shmat (int first, int second, int third, int version, void __user *uptr) -{ - unsigned long raddr; - u32 __user *uaddr = (u32 __user *)A((u32)third); - int err = -EINVAL; - - if (version == 1) - return err; - err = do_shmat (first, uptr, second, &raddr); - if (err) - return err; - err = put_user (raddr, uaddr); - return err; -} - -struct shm_info32 { - int used_ids; - u32 shm_tot, shm_rss, shm_swp; - u32 swap_attempts, swap_successes; -}; - -static int -do_sys32_shmctl (int first, int second, void __user *uptr) -{ - struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr; - struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr; - struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr; - int err = -EFAULT, err2; - struct shmid64_ds s64; - mm_segment_t old_fs; - struct shm_info si; - struct shmid_ds s; - - switch (second & ~IPC_64) { - case IPC_INFO: - second = IPC_INFO; /* So that we don't have to translate it */ - case IPC_RMID: - case SHM_LOCK: - case SHM_UNLOCK: - err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr); - break; - case IPC_SET: - if (second & IPC_64) { - err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); - } else { - err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s); - set_fs(old_fs); - break; - - case IPC_STAT: - case SHM_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second | IPC_64, (void __user *) &s64); - set_fs(old_fs); - if (err < 0) - break; - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up64->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up32->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); - } - if (err2) - err = -EFAULT; - break; - - case SHM_INFO: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second, (void __user *)&si); - set_fs(old_fs); - if (err < 0) - break; - err2 = put_user(si.used_ids, &uip->used_ids); - err2 |= __put_user(si.shm_tot, &uip->shm_tot); - err2 |= __put_user(si.shm_rss, &uip->shm_rss); - err2 |= __put_user(si.shm_swp, &uip->shm_swp); - err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); - err2 |= __put_user (si.swap_successes, &uip->swap_successes); - if (err2) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - - return err; -} - -static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, - const struct compat_timespec __user *timeout32) -{ - struct compat_timespec t32; - struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64)); - - if (copy_from_user(&t32, timeout32, sizeof(t32))) - return -EFAULT; - - if (put_user(t32.tv_sec, &t64->tv_sec) || - put_user(t32.tv_nsec, &t64->tv_nsec)) - return -EFAULT; - - return sys_semtimedop(semid, tsems, nsems, t64); -} - asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -918,48 +393,43 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - NULL); + err = sys_semtimedop(first, compat_ptr(ptr), second, NULL); break; case SEMTIMEDOP: - err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - (const struct compat_timespec __user *)AA(fifth)); + err = compat_sys_semtimedop(first, compat_ptr(ptr), second, + compat_ptr(fifth)); break; case SEMGET: - err = sys_semget (first, second, third); + err = sys_semget(first, second, third); break; case SEMCTL: - err = do_sys32_semctl (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_semctl(first, second, third, compat_ptr(ptr)); break; - case MSGSND: - err = do_sys32_msgsnd (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); break; case MSGRCV: - err = do_sys32_msgrcv (first, second, fifth, third, - version, (void __user *)AA(ptr)); + err = compat_sys_msgrcv(first, second, fifth, third, + version, compat_ptr(ptr)); break; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t) first, second); break; case MSGCTL: - err = do_sys32_msgctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_msgctl(first, second, compat_ptr(ptr)); break; - case SHMAT: - err = do_sys32_shmat (first, second, third, - version, (void __user *)AA(ptr)); + err = compat_sys_shmat(first, second, third, version, + compat_ptr(ptr)); break; case SHMDT: - err = sys_shmdt ((char __user *)A(ptr)); + err = sys_shmdt(compat_ptr(ptr)); break; case SHMGET: - err = sys_shmget (first, (unsigned)second, third); + err = sys_shmget(first, (unsigned)second, third); break; case SHMCTL: - err = do_sys32_shmctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: err = -EINVAL; @@ -969,18 +439,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) return err; } -asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, - int shmflg, int32_t __user *addr) +#ifdef CONFIG_MIPS32_N32 +asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg) { - unsigned long raddr; - int err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - return err; - - return put_user(raddr, addr); + /* compat_sys_semctl expects a pointer to union semun */ + u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); + if (put_user(ptr_to_compat(arg.__pad), uptr)) + return -EFAULT; + return compat_sys_semctl(semid, semnum, cmd, uptr); } +#endif struct sysctl_args32 { diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 5b18f265d75b..34567d81f940 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -149,8 +149,8 @@ EXPORT(sysn32_call_table) PTR sys_mincore PTR sys_madvise PTR sys_shmget - PTR sys32_shmat - PTR sys_shmctl /* 6030 */ + PTR sys_shmat + PTR compat_sys_shmctl /* 6030 */ PTR sys_dup PTR sys_dup2 PTR sys_pause @@ -184,12 +184,12 @@ EXPORT(sysn32_call_table) PTR sys32_newuname PTR sys_semget PTR sys_semop - PTR sys_semctl + PTR sysn32_semctl PTR sys_shmdt /* 6065 */ PTR sys_msgget - PTR sys_msgsnd - PTR sys_msgrcv - PTR sys_msgctl + PTR compat_sys_msgsnd + PTR compat_sys_msgrcv + PTR compat_sys_msgctl PTR compat_sys_fcntl /* 6070 */ PTR sys_flock PTR sys_fsync @@ -335,7 +335,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_fcntl64 PTR sys_set_tid_address PTR sys_restart_syscall - PTR sys_semtimedop /* 6215 */ + PTR compat_sys_semtimedop /* 6215 */ PTR sys_fadvise64_64 PTR compat_sys_statfs64 PTR compat_sys_fstatfs64 -- cgit v1.2.2 From 0004a9dfeaa709a7f853487aba19932c9b1a87c8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 03:45:07 +0000 Subject: [MIPS] Cleanup memory barriers for weakly ordered systems. Also the R4000 / R4600 LL/SC instructions imply a sync so no explicit sync needed. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 49db516789e0..f2a8701e414d 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -172,7 +172,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, spin_lock(&smp_call_lock); call_data = &data; - mb(); + smp_mb(); /* Send a message to all other CPUs and wait for them to respond */ for_each_online_cpu(i) @@ -204,7 +204,7 @@ void smp_call_function_interrupt(void) * Notify initiating CPU that I've grabbed the data and am * about to execute the function. */ - mb(); + smp_mb(); atomic_inc(&call_data->started); /* @@ -215,7 +215,7 @@ void smp_call_function_interrupt(void) irq_exit(); if (wait) { - mb(); + smp_mb(); atomic_inc(&call_data->finished); } } -- cgit v1.2.2 From 6d5aefb8eaa38e44b5b8cf60c812aceafc02d924 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 5 Dec 2006 19:36:26 +0000 Subject: WorkQueue: Fix up arch-specific work items where possible Fix up arch-specific work items where possible to use the new work_struct and delayed_work structs. Three places that enqueue bits of their stack and then return have been marked with #error as this is not permitted. Signed-Off-By: David Howells --- arch/mips/kernel/kspd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index f06a144c7881..2c82412b9efe 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -319,7 +319,7 @@ static void sp_cleanup(void) static int channel_open = 0; /* the work handler */ -static void sp_work(void *data) +static void sp_work(struct work_struct *unused) { if (!channel_open) { if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { @@ -354,7 +354,7 @@ static void startwork(int vpe) return; } - INIT_WORK(&work, sp_work, NULL); + INIT_WORK(&work, sp_work); queue_work(workqueue, &work); } else queue_work(workqueue, &work); -- cgit v1.2.2 From 1ccd1c1c35a6cb21da32479931d4fa6d47320095 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 6 Dec 2006 01:20:57 +0900 Subject: [MIPS] genirq: use name instead of typename The "typename" field was obsoleted by the "name" field. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index b339798b3172..2fe4c868a801 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -117,7 +117,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].chip->name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) -- cgit v1.2.2 From e77c232cfc6e1250b2916a7c69225d6634d05a49 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 1 Dec 2006 18:22:27 +0100 Subject: [MIPS] Compile __do_IRQ() when really needed __do_IRQ() is needed only by irq handlers that can't use default handlers defined in kernel/irq/chip.c. For others platforms there's no need to compile this function since it won't be used. For those platforms this patch defines GENERIC_HARDIRQS_NO__DO_IRQ symbol which is used exactly for this purpose. Futhermore for platforms which do not use __do_IRQ(), end() method which is part of the 'irq_chip' structure is not used. This patch simply removes this method in this case. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq-mv6434x.c | 10 ---------- arch/mips/kernel/irq-rm7000.c | 7 ------- arch/mips/kernel/irq-rm9000.c | 8 -------- arch/mips/kernel/irq_cpu.c | 10 ---------- 4 files changed, 35 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 6cfb31cafde2..efbd219845b5 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -66,15 +66,6 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } -/* - * End IRQ processing - */ -static void end_mv64340_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_mv64340_irq(irq); -} - /* * Interrupt handler for interrupts coming from the Marvell chip. * It could be built in ethernet ports etc... @@ -106,7 +97,6 @@ struct irq_chip mv64340_irq_type = { .mask = mask_mv64340_irq, .mask_ack = mask_mv64340_irq, .unmask = unmask_mv64340_irq, - .end = end_mv64340_irq, }; void __init mv64340_irq_init(unsigned int base) diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index ddcc2a5f8a06..123324ba8c14 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -29,19 +29,12 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } -static void rm7k_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_rm7k_irq(irq); -} - static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", .ack = mask_rm7k_irq, .mask = mask_rm7k_irq, .mask_ack = mask_rm7k_irq, .unmask = unmask_rm7k_irq, - .end = rm7k_cpu_irq_end, }; void __init rm7k_cpu_irq_init(int base) diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index ba6440c88abd..0e6f4c5349d2 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -80,19 +80,12 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } -static void rm9k_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_rm9k_irq(irq); -} - static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", .ack = mask_rm9k_irq, .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, - .end = rm9k_cpu_irq_end, }; static struct irq_chip rm9k_perfcounter_irq = { @@ -103,7 +96,6 @@ static struct irq_chip rm9k_perfcounter_irq = { .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, - .end = rm9k_cpu_irq_end, }; unsigned int rm9000_perfcount_irq; diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index be5ac23d3812..fcc86b96ccf6 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -50,12 +50,6 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } -static void mips_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_mips_irq(irq); -} - static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", .ack = mask_mips_irq, @@ -63,7 +57,6 @@ static struct irq_chip mips_cpu_irq_controller = { .mask_ack = mask_mips_irq, .unmask = unmask_mips_irq, .eoi = unmask_mips_irq, - .end = mips_cpu_irq_end, }; /* @@ -96,8 +89,6 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) mask_mips_mt_irq(irq); } -#define mips_mt_cpu_irq_end mips_cpu_irq_end - static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, @@ -106,7 +97,6 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .mask_ack = mips_mt_cpu_irq_ack, .unmask = unmask_mips_mt_irq, .eoi = unmask_mips_mt_irq, - .end = mips_mt_cpu_irq_end, }; void __init mips_cpu_irq_init(int irq_base) -- cgit v1.2.2 From 2cafe978462bc4016392aa330bf501a674679a86 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 7 Dec 2006 02:04:17 +0900 Subject: [MIPS] Import updates from i386's i8259.c Import many updates from i386's i8259.c, especially genirq transitions. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 162 +++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 76 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 2526c0ca4d81..b59a676c6d0e 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -19,9 +19,6 @@ #include #include -void enable_8259A_irq(unsigned int irq); -void disable_8259A_irq(unsigned int irq); - /* * This is the 'legacy' 8259A Programmable Interrupt Controller, * present in the majority of PC/AT boxes. @@ -31,23 +28,16 @@ void disable_8259A_irq(unsigned int irq); * moves to arch independent land */ +static int i8259A_auto_eoi; DEFINE_SPINLOCK(i8259A_lock); - -static void end_8259A_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && - irq_desc[irq].action) - enable_8259A_irq(irq); -} - +/* some platforms call this... */ void mask_and_ack_8259A(unsigned int); -static struct irq_chip i8259A_irq_type = { - .typename = "XT-PIC", - .enable = enable_8259A_irq, - .disable = disable_8259A_irq, - .ack = mask_and_ack_8259A, - .end = end_8259A_irq, +static struct irq_chip i8259A_chip = { + .name = "XT-PIC", + .mask = disable_8259A_irq, + .unmask = enable_8259A_irq, + .mask_ack = mask_and_ack_8259A, }; /* @@ -59,8 +49,8 @@ static struct irq_chip i8259A_irq_type = { */ static unsigned int cached_irq_mask = 0xffff; -#define cached_21 (cached_irq_mask) -#define cached_A1 (cached_irq_mask >> 8) +#define cached_master_mask (cached_irq_mask) +#define cached_slave_mask (cached_irq_mask >> 8) void disable_8259A_irq(unsigned int irq) { @@ -70,9 +60,9 @@ void disable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask |= mask; if (irq & 8) - outb(cached_A1,0xA1); + outb(cached_slave_mask, PIC_SLAVE_IMR); else - outb(cached_21,0x21); + outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -84,9 +74,9 @@ void enable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask &= mask; if (irq & 8) - outb(cached_A1,0xA1); + outb(cached_slave_mask, PIC_SLAVE_IMR); else - outb(cached_21,0x21); + outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -98,9 +88,9 @@ int i8259A_irq_pending(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); if (irq < 8) - ret = inb(0x20) & mask; + ret = inb(PIC_MASTER_CMD) & mask; else - ret = inb(0xA0) & (mask >> 8); + ret = inb(PIC_SLAVE_CMD) & (mask >> 8); spin_unlock_irqrestore(&i8259A_lock, flags); return ret; @@ -109,7 +99,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - set_irq_chip(irq, &i8259A_irq_type); + set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); enable_irq(irq); } @@ -125,14 +115,14 @@ static inline int i8259A_irq_real(unsigned int irq) int irqmask = 1 << irq; if (irq < 8) { - outb(0x0B,0x20); /* ISR register */ - value = inb(0x20) & irqmask; - outb(0x0A,0x20); /* back to the IRR register */ + outb(0x0B,PIC_MASTER_CMD); /* ISR register */ + value = inb(PIC_MASTER_CMD) & irqmask; + outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */ return value; } - outb(0x0B,0xA0); /* ISR register */ - value = inb(0xA0) & (irqmask >> 8); - outb(0x0A,0xA0); /* back to the IRR register */ + outb(0x0B,PIC_SLAVE_CMD); /* ISR register */ + value = inb(PIC_SLAVE_CMD) & (irqmask >> 8); + outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */ return value; } @@ -149,17 +139,19 @@ void mask_and_ack_8259A(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); /* - * Lightweight spurious IRQ detection. We do not want to overdo - * spurious IRQ handling - it's usually a sign of hardware problems, so - * we only do the checks we can do without slowing down good hardware - * nnecesserily. + * Lightweight spurious IRQ detection. We do not want + * to overdo spurious IRQ handling - it's usually a sign + * of hardware problems, so we only do the checks we can + * do without slowing down good hardware unnecessarily. * - * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting - * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A. - * Thus we can check spurious 8259A IRQs without doing the quite slow - * i8259A_irq_real() call for every IRQ. This does not cover 100% of - * spurious interrupts, but should be enough to warn the user that - * there is something bad going on ... + * Note that IRQ7 and IRQ15 (the two spurious IRQs + * usually resulting from the 8259A-1|2 PICs) occur + * even if the IRQ is masked in the 8259A. Thus we + * can check spurious 8259A IRQs without doing the + * quite slow i8259A_irq_real() call for every IRQ. + * This does not cover 100% of spurious interrupts, + * but should be enough to warn the user that there + * is something bad going on ... */ if (cached_irq_mask & irqmask) goto spurious_8259A_irq; @@ -167,14 +159,14 @@ void mask_and_ack_8259A(unsigned int irq) handle_real_irq: if (irq & 8) { - inb(0xA1); /* DUMMY - (do we need this?) */ - outb(cached_A1,0xA1); - outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ - outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ + inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ + outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ } else { - inb(0x21); /* DUMMY - (do we need this?) */ - outb(cached_21,0x21); - outb(0x60+irq,0x20); /* 'Specific EOI' to master */ + inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ + outb(cached_master_mask, PIC_MASTER_IMR); + outb(0x60+irq,PIC_MASTER_CMD); /* 'Specific EOI to master */ } #ifdef CONFIG_MIPS_MT_SMTC if (irq_hwmask[irq] & ST0_IM) @@ -195,7 +187,7 @@ spurious_8259A_irq: goto handle_real_irq; { - static int spurious_irq_mask = 0; + static int spurious_irq_mask; /* * At this point we can be sure the IRQ is spurious, * lets ACK and report it. [once per IRQ] @@ -216,13 +208,25 @@ spurious_8259A_irq: static int i8259A_resume(struct sys_device *dev) { - init_8259A(0); + init_8259A(i8259A_auto_eoi); + return 0; +} + +static int i8259A_shutdown(struct sys_device *dev) +{ + /* Put the i8259A into a quiescent state that + * the kernel initialization code can get it + * out of. + */ + outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ return 0; } static struct sysdev_class i8259_sysdev_class = { set_kset_name("i8259"), .resume = i8259A_resume, + .shutdown = i8259A_shutdown, }; static struct sys_device device_i8259A = { @@ -244,41 +248,41 @@ void __init init_8259A(int auto_eoi) { unsigned long flags; + i8259A_auto_eoi = auto_eoi; + spin_lock_irqsave(&i8259A_lock, flags); - outb(0xff, 0x21); /* mask all of 8259A-1 */ - outb(0xff, 0xA1); /* mask all of 8259A-2 */ + outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ /* * outb_p - this has to work on a wide range of PC hardware. */ - outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ - outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */ - outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ - if (auto_eoi) - outb_p(0x03, 0x21); /* master does Auto EOI */ - else - outb_p(0x01, 0x21); /* master expects normal EOI */ - - outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ - outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */ - outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ - outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode - is to be investigated) */ - + outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ + outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */ + outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ + if (auto_eoi) /* master does Auto EOI */ + outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); + else /* master expects normal EOI */ + outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); + + outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ + outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */ + outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */ + outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ if (auto_eoi) /* - * in AEOI mode we just have to mask the interrupt + * In AEOI mode we just have to mask the interrupt * when acking. */ - i8259A_irq_type.ack = disable_8259A_irq; + i8259A_chip.mask_ack = disable_8259A_irq; else - i8259A_irq_type.ack = mask_and_ack_8259A; + i8259A_chip.mask_ack = mask_and_ack_8259A; udelay(100); /* wait for 8259A to initialize */ - outb(cached_21, 0x21); /* restore master IRQ mask */ - outb(cached_A1, 0xA1); /* restore slave IRQ mask */ + outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ + outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -291,11 +295,17 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY + .name = "pic1", + .start = PIC_MASTER_CMD, + .end = PIC_MASTER_IMR, + .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY + .name = "pic2", + .start = PIC_SLAVE_CMD, + .end = PIC_SLAVE_IMR, + .flags = IORESOURCE_BUSY }; /* @@ -313,7 +323,7 @@ void __init init_i8259_irqs (void) init_8259A(0); for (i = 0; i < 16; i++) - set_irq_chip(i, &i8259A_irq_type); + set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); - setup_irq(2, &irq2); + setup_irq(PIC_CASCADE_IR, &irq2); } -- cgit v1.2.2 From 386d9a7edd9f3492c99124b0a659e9ed7abb30f9 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Dec 2006 20:37:53 -0800 Subject: [PATCH] elf: Always define elf_addr_t in linux/elf.h Define elf_addr_t in linux/elf.h. The size of the type is determined using ELF_CLASS. This allows us to remove the defines that today are spread all over .c and .h files. Signed-off-by: Magnus Damm Cc: Daniel Jacobowitz Cc: Roland McGrath Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/binfmt_elfn32.c | 1 - arch/mips/kernel/binfmt_elfo32.c | 1 - arch/mips/kernel/irixelf.c | 4 ---- 3 files changed, 6 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 4a9f1ecefaf2..9b34238d41c0 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -90,7 +90,6 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; -#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elfn32_binfmt diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index e31813779895..993f7ec70f35 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -92,7 +92,6 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; -#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elf32_binfmt diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index ab12c8f01518..a82fae221ce4 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -52,10 +52,6 @@ static struct linux_binfmt irix_format = { irix_core_dump, PAGE_SIZE }; -#ifndef elf_addr_t -#define elf_addr_t unsigned long -#endif - #ifdef DEBUG /* Debugging routines. */ static char *get_elf_p_type(Elf32_Word p_type) -- cgit v1.2.2 From 584236ac7cdddeec0fdff25d2e475471ef91d028 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Dec 2006 20:37:56 -0800 Subject: [PATCH] elf: include terminating zero in n_namesz The ELF32 spec says we should plus we include the zero on other platforms. Signed-off-by: Magnus Damm Cc: Daniel Jacobowitz Cc: Roland McGrath Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/irixelf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index a82fae221ce4..1bbefbf43373 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1009,7 +1009,7 @@ static int notesize(struct memelfnote *en) int sz; sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name), 4); + sz += roundup(strlen(en->name) + 1, 4); sz += roundup(en->datasz, 4); return sz; @@ -1028,7 +1028,7 @@ static int writenote(struct memelfnote *men, struct file *file) { struct elf_note en; - en.n_namesz = strlen(men->name); + en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; -- cgit v1.2.2 From 1b04fe9a8ef10774174897b15d753b9de85fe9e9 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:20 -0800 Subject: [PATCH] struct path: convert mips Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/rtlx.c | 6 +++--- arch/mips/kernel/sysirix.c | 10 +++++----- arch/mips/kernel/vpe.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 8c8c8324f775..5a99e3e0c96d 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -415,7 +415,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) int minor; unsigned int mask = 0; - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); poll_wait(file, &channel_wqs[minor].rt_queue, wait); poll_wait(file, &channel_wqs[minor].lx_queue, wait); @@ -437,7 +437,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) static ssize_t file_read(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { - int minor = iminor(file->f_dentry->d_inode); + int minor = iminor(file->f_path.dentry->d_inode); /* data available? */ if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { @@ -454,7 +454,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer, struct rtlx_channel *rt; DECLARE_WAITQUEUE(wait, current); - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); rt = &rtlx->channel[minor]; /* any space left... */ diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 93c74fefff76..6c2406a93f2b 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; @@ -1041,7 +1041,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, unsigned long old_pos; long max_size = offset + len; - if (max_size > file->f_dentry->d_inode->i_size) { + if (max_size > file->f_path.dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; @@ -1526,7 +1526,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs) unsigned long old_pos; long max_size = off2 + len; - if (max_size > file->f_dentry->d_inode->i_size) { + if (max_size > file->f_path.dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 51ddd2166898..666bef484dcb 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -1179,7 +1179,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, size_t ret = count; struct vpe *v; - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); if ((v = get_vpe(minor)) == NULL) return -ENODEV; -- cgit v1.2.2 From 937949d9edbf4049bd41af6c9f92c26280584564 Mon Sep 17 00:00:00 2001 From: Cedric Le Goater Date: Fri, 8 Dec 2006 02:37:54 -0800 Subject: [PATCH] add process_session() helper routine Replace occurences of task->signal->session by a new process_session() helper routine. It will be useful for pid namespaces to abstract the session pid number. Signed-off-by: Cedric Le Goater Cc: Kirill Korotaev Cc: Eric W. Biederman Cc: Herbert Poetzl Cc: Sukadev Bhattiprolu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/irixelf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 1bbefbf43373..37cad5de515c 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1145,7 +1145,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current); - psinfo.pr_sid = prstatus.pr_sid = current->signal->session; + psinfo.pr_sid = prstatus.pr_sid = process_session(current); if (current->pid == current->tgid) { /* * This is the record for the group leader. Add in the -- cgit v1.2.2 From c25c79d80e02db1bd993426f979c5f1b42a0f132 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 8 Dec 2006 12:55:42 +0000 Subject: [MIPS] Qemu now has an ELF loader. So nuke kludge for flat binaries. Signed-off-by: Ralf Baechle --- arch/mips/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index a2e095adaa3f..9a7811d13db2 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -138,7 +138,7 @@ EXPORT(stext) # used for profiling EXPORT(_stext) -#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM) +#ifdef CONFIG_MIPS_SIM /* * Give us a fighting chance of running if execution beings at the * kernel load address. This is needed because this platform does -- cgit v1.2.2 From bbea9f69668a3d0cf9feba15a724cd02896f8675 Mon Sep 17 00:00:00 2001 From: Vadim Lobanov Date: Sun, 10 Dec 2006 02:21:12 -0800 Subject: [PATCH] fdtable: Make fdarray and fdsets equal in size Currently, each fdtable supports three dynamically-sized arrays of data: the fdarray and two fdsets. The code allows the number of fds supported by the fdarray (fdtable->max_fds) to differ from the number of fds supported by each of the fdsets (fdtable->max_fdset). In practice, it is wasteful for these two sizes to differ: whenever we hit a limit on the smaller-capacity structure, we will reallocate the entire fdtable and all the dynamic arrays within it, so any delta in the memory used by the larger-capacity structure will never be touched at all. Rather than hogging this excess, we shouldn't even allocate it in the first place, and keep the capacities of the fdarray and the fdsets equal. This patch removes fdtable->max_fdset. As an added bonus, most of the supporting code becomes simpler. Signed-off-by: Vadim Lobanov Cc: Christoph Hellwig Cc: Al Viro Cc: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/kspd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 2c82412b9efe..5929f883e46b 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -301,7 +301,7 @@ static void sp_cleanup(void) for (;;) { unsigned long set; i = j * __NFDBITS; - if (i >= fdt->max_fdset || i >= fdt->max_fds) + if (i >= fdt->max_fds) break; set = fdt->open_fds->fds_bits[j++]; while (set) { -- cgit v1.2.2 From 86384d544157db23879064cde36061cdcafc6794 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 14:57:28 +0000 Subject: [MIPS] Discard .exit.text at linktime. This fixes fairly unobvious breakage of various drivers. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vmlinux.lds.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 79f0317d84ac..2f4508f55fca 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -109,9 +109,6 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT - /* .exit.text is discarded at runtime, not link time, to deal with - references from .rodata */ - .exit.text : { *(.exit.text) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -139,6 +136,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { + *(.exit.text) *(.exit.data) *(.exitcall.exit) -- cgit v1.2.2 From f8bf35a9145b0831d7d110402662d9cff2d90bd9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 15:09:38 +0000 Subject: [MIPS] Export pm_power_off This is required for ipmi_poweroff.c to work as a module. Signed-off-by: Ralf Baechle --- arch/mips/kernel/reset.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 621037db2290..060563a712b6 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c @@ -23,6 +23,8 @@ void (*_machine_restart)(char *command); void (*_machine_halt)(void); void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + void machine_restart(char *command) { if (_machine_restart) -- cgit v1.2.2 From 2efac77e82a36bf616d474f2eb721d95543cfae9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 11 Dec 2006 11:54:52 +0000 Subject: [MIPS] Discard .exit.text and .exit.data at runtime. While the recent cset 86384d544157db23879064cde36061cdcafc6794 did improve things it didn't resolve all the problems. So bite the bullet and discard .exit.text and .exit.data at runtime. Which of course sucks because it bloats binaries with code that will never ever be used but it's the only thing that will work reliable as demonstrated by the function sd_major() in drivers/scsi/sd.c. Gcc may compile sd_major() using a jump table which it will put into .rodata. If it also inlines sd_major's function body into exit_sd() which gcc > 3.4.x does. If CONFIG_BLK_DEV_SD has been set to y we would like ld to discard exit_sd's code at link time. However sd_major happens to contain a switch statement which gcc will compile using a jump table in .rodata on the architectures I checked. So, when ld later discards .exit.text only the jump table in .rodata with its stale references to the discard .exit.text will be left which any no antique ld will honor with a link error. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vmlinux.lds.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2f4508f55fca..cecff24cc972 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -109,6 +109,10 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT + /* .exit.text is discarded at runtime, not link time, to deal with + references from .rodata */ + .exit.text : { *(.exit.text) } + .exit.data : { *(.exit.data) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -136,8 +140,6 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) - *(.exit.data) *(.exitcall.exit) /* ABI crap starts here */ -- cgit v1.2.2 From 5cbded585d129d0226cb48ac4202b253c781be26 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Wed, 13 Dec 2006 00:35:56 -0800 Subject: [PATCH] getting rid of all casts of k[cmz]alloc() calls Run this: #!/bin/sh for f in $(grep -Erl "\([^\)]*\) *k[cmz]alloc" *) ; do echo "De-casting $f..." perl -pi -e "s/ ?= ?\([^\)]*\) *(k[cmz]alloc) *\(/ = \1\(/" $f done And then go through and reinstate those cases where code is casting pointers to non-pointers. And then drop a few hunks which conflicted with outstanding work. Cc: Russell King , Ian Molton Cc: Mikael Starvik Cc: Yoshinori Sato Cc: Roman Zippel Cc: Geert Uytterhoeven Cc: Ralf Baechle Cc: Paul Mackerras Cc: Kyle McMartin Cc: Benjamin Herrenschmidt Cc: Martin Schwidefsky Cc: "David S. Miller" Cc: Jeff Dike Cc: Greg KH Cc: Jens Axboe Cc: Paul Fulghum Cc: Alan Cox Cc: Karsten Keil Cc: Mauro Carvalho Chehab Cc: Jeff Garzik Cc: James Bottomley Cc: Ian Kent Cc: Steven French Cc: David Woodhouse Cc: Neil Brown Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/apm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/apm.c b/arch/mips/kernel/apm.c index 528e731049c1..ba16d07588cb 100644 --- a/arch/mips/kernel/apm.c +++ b/arch/mips/kernel/apm.c @@ -356,7 +356,7 @@ static int apm_open(struct inode * inode, struct file * filp) { struct apm_user *as; - as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL); + as = kzalloc(sizeof(*as), GFP_KERNEL); if (as) { /* * XXX - this is a tiny bit broken, when we consider BSD -- cgit v1.2.2 From f860c90bd6ce22c6a0a352cc16acc74fba3d628e Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 13 Dec 2006 01:22:06 +0900 Subject: [MIPS] csum_partial and copy in parallel Implement optimized asm version of csum_partial_copy_nocheck, csum_partial_copy_from_user and csum_and_copy_to_user which can do calculate and copy in parallel, based on memcpy.S. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/mips_ksyms.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index f44a01357ada..2ef857c3ee53 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -46,5 +46,7 @@ EXPORT_SYMBOL(__strnlen_user_nocheck_asm); EXPORT_SYMBOL(__strnlen_user_asm); EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(csum_partial_copy_nocheck); +EXPORT_SYMBOL(__csum_partial_copy_user); EXPORT_SYMBOL(invalid_pte_table); -- cgit v1.2.2 From 2dbda7dceca81adfe57c8884be5c66e70822d89a Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Thu, 28 Dec 2006 17:14:05 +0300 Subject: [MIPS] PNX8550: Fix system timer support the patch inlined below restores proper time accounting for PNX8550-based boards. It also gets rid of #ifdef in the generic code which becomes unnecessary then. It's functionally identical to the previous patch with the same name but it has minor comments from Atsushi and Sergei taken into account. Signed-off-by: Vitaly Wool Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 11aab6d6bfe5..8aa544f73a5e 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -94,10 +94,8 @@ static void c0_timer_ack(void) { unsigned int count; -#ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */ /* Ack this timer interrupt and set the next one. */ expirelo += cycles_per_jiffy; -#endif write_c0_compare(expirelo); /* Check to see if we have missed any timer interrupts. */ -- cgit v1.2.2 From e16d8df0be26c8e82c4a1188af8143f2d466b12a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 10 Jan 2007 18:53:33 +0900 Subject: [MIPS] Fix N32 SysV IPC routines Add wrappers for N32 msg{snd,rcv}. compat_sys_msg{snd,rcv} can not not be used as system call entries as is. This fix is based on Kaz Kylheku's patch. Also change a type of last argument of sysn32_semctl to match its true size. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 16 ++++++++++++++-- arch/mips/kernel/scall64-n32.S | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index b061c9aa6302..de3fae260ff8 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -440,14 +440,26 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) } #ifdef CONFIG_MIPS32_N32 -asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg) +asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg) { /* compat_sys_semctl expects a pointer to union semun */ u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); - if (put_user(ptr_to_compat(arg.__pad), uptr)) + if (put_user(arg, uptr)) return -EFAULT; return compat_sys_semctl(semid, semnum, cmd, uptr); } + +asmlinkage long sysn32_msgsnd(int msqid, u32 msgp, unsigned msgsz, int msgflg) +{ + return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp)); +} + +asmlinkage long sysn32_msgrcv(int msqid, u32 msgp, size_t msgsz, int msgtyp, + int msgflg) +{ + return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64, + compat_ptr(msgp)); +} #endif struct sysctl_args32 diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 34567d81f940..a7bff2a54723 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -187,8 +187,8 @@ EXPORT(sysn32_call_table) PTR sysn32_semctl PTR sys_shmdt /* 6065 */ PTR sys_msgget - PTR compat_sys_msgsnd - PTR compat_sys_msgrcv + PTR sysn32_msgsnd + PTR sysn32_msgrcv PTR compat_sys_msgctl PTR compat_sys_fcntl /* 6070 */ PTR sys_flock -- cgit v1.2.2 From b282b6f8a8d1cf3e132ce3769d7d1cac81d9dd2d Mon Sep 17 00:00:00 2001 From: Gautham R Shenoy Date: Wed, 10 Jan 2007 23:15:34 -0800 Subject: [PATCH] Change cpu_up and co from __devinit to __cpuinit Compiling the kernel with CONFIG_HOTPLUG = y and CONFIG_HOTPLUG_CPU = n with CONFIG_RELOCATABLE = y generates the following modpost warnings WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between '_cpu_up' (at offset 0xc0141b7d) and 'cpu_up' WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between '_cpu_up' (at offset 0xc0141b9c) and 'cpu_up' WARNING: vmlinux - Section mismatch: reference to .init.text:__cpu_up from .text between '_cpu_up' (at offset 0xc0141bd8) and 'cpu_up' WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between '_cpu_up' (at offset 0xc0141c05) and 'cpu_up' WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between '_cpu_up' (at offset 0xc0141c26) and 'cpu_up' WARNING: vmlinux - Section mismatch: reference to .init.data: from .text between '_cpu_up' (at offset 0xc0141c37) and 'cpu_up' This is because cpu_up, _cpu_up and __cpu_up (in some architectures) are defined as __devinit AND __cpu_up calls some __cpuinit functions. Since __cpuinit would map to __init with this kind of a configuration, we get a .text refering .init.data warning. This patch solves the problem by converting all of __cpu_up, _cpu_up and cpu_up from __devinit to __cpuinit. The approach is justified since the callers of cpu_up are either dependent on CONFIG_HOTPLUG_CPU or are of __init type. Thus when CONFIG_HOTPLUG_CPU=y, all these cpu up functions would land up in .text section, and when CONFIG_HOTPLUG_CPU=n, all these functions would land up in .init section. Tested on a i386 SMP machine running linux-2.6.20-rc3-mm1. Signed-off-by: Gautham R Shenoy Cc: Vivek Goyal Cc: Mikael Starvik Cc: Ralf Baechle Cc: Kyle McMartin Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index f2a8701e414d..0555fc554f65 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -271,7 +271,7 @@ void __devinit smp_prepare_boot_cpu(void) * and keep control until "cpu_online(cpu)" is set. Note: cpu is * physical, not logical. */ -int __devinit __cpu_up(unsigned int cpu) +int __cpuinit __cpu_up(unsigned int cpu) { struct task_struct *idle; -- cgit v1.2.2