From 9848e49a9a9aab075d79c5d2856abb879495f97f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 16 Jan 2014 03:38:58 +0400 Subject: xtensa: fix warning '"CONFIG_OF" is not defined' The warning only shows up when building MMUv3 configuration with OF support disabled. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/io.h | 2 +- arch/xtensa/include/asm/vectors.h | 2 +- arch/xtensa/mm/mmu.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 2a042d430c25..74944207167e 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -25,7 +25,7 @@ #ifdef CONFIG_MMU -#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) extern unsigned long xtensa_kio_paddr; static inline unsigned long xtensa_get_kio_paddr(void) diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h index 5791b45d5a5d..f74ddfbb92ef 100644 --- a/arch/xtensa/include/asm/vectors.h +++ b/arch/xtensa/include/asm/vectors.h @@ -25,7 +25,7 @@ #define XCHAL_KIO_DEFAULT_PADDR 0xf0000000 #define XCHAL_KIO_SIZE 0x10000000 -#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) #define XCHAL_KIO_PADDR xtensa_get_kio_paddr() #else #define XCHAL_KIO_PADDR XCHAL_KIO_DEFAULT_PADDR diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 36ec171698b8..861203e958da 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -39,7 +39,7 @@ void init_mmu(void) set_itlbcfg_register(0); set_dtlbcfg_register(0); #endif -#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF) /* * Update the IO area mapping in case xtensa_kio_paddr has changed */ -- cgit v1.2.3-55-g7522 From 45ec8860be2f681b2e3e521a3fb4554ec29fbaac Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 19 Jan 2014 20:00:48 +0400 Subject: xtensa: export ccount_freq Now that ccount_freq is used in udelay and ndelay it needs to be exported in order to be available to modules. Signed-off-by: Max Filippov --- arch/xtensa/kernel/time.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 08b769d3b3a1..2a1823de69cc 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -30,6 +30,7 @@ #include unsigned long ccount_freq; /* ccount Hz */ +EXPORT_SYMBOL(ccount_freq); static cycle_t ccount_read(struct clocksource *cs) { -- cgit v1.2.3-55-g7522 From e2fd1374c705abe4661df3fb6fadb3879c7c1846 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 22 Jan 2014 08:04:43 +0400 Subject: xtensa: introduce spill_registers_kernel macro Most in-kernel users want registers spilled on the kernel stack and don't require PS.EXCM to be set. That means that they don't need fixup routine and could reuse regular window overflow mechanism for that, which makes spill routine very simple. Cc: stable@vger.kernel.org Suggested-by: Chris Zankel Signed-off-by: Max Filippov --- arch/xtensa/include/asm/traps.h | 44 +++++++++++++++++++----------- arch/xtensa/kernel/entry.S | 60 ++++++++++++++++++++++++++++++++--------- 2 files changed, 76 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h index 8c194f6af45e..677bfcf4ee5d 100644 --- a/arch/xtensa/include/asm/traps.h +++ b/arch/xtensa/include/asm/traps.h @@ -23,25 +23,37 @@ void secondary_trap_init(void); static inline void spill_registers(void) { - +#if XCHAL_NUM_AREGS > 16 __asm__ __volatile__ ( - "movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t" - "mov a12, a0\n\t" - "rsr a13, sar\n\t" - "xsr a14, ps\n\t" - "movi a0, _spill_registers\n\t" - "rsync\n\t" - "callx0 a0\n\t" - "mov a0, a12\n\t" - "wsr a13, sar\n\t" - "wsr a14, ps\n\t" - : : -#if defined(CONFIG_FRAME_POINTER) - : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15", + " call12 1f\n" + " _j 2f\n" + " retw\n" + " .align 4\n" + "1:\n" + " _entry a1, 48\n" + " addi a12, a0, 3\n" +#if XCHAL_NUM_AREGS > 32 + " .rept (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n" + " _entry a1, 48\n" + " mov a12, a0\n" + " .endr\n" +#endif + " _entry a1, 48\n" +#if XCHAL_NUM_AREGS % 12 == 0 + " mov a8, a8\n" +#elif XCHAL_NUM_AREGS % 12 == 4 + " mov a12, a12\n" +#elif XCHAL_NUM_AREGS % 12 == 8 + " mov a4, a4\n" +#endif + " retw\n" + "2:\n" + : : : "a12", "a13", "memory"); #else - : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", + __asm__ __volatile__ ( + " mov a12, a12\n" + : : : "memory"); #endif - "memory"); } #endif /* _XTENSA_TRAPS_H */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 21dbe6bdb8ed..0489918e40d2 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1794,6 +1794,43 @@ ENTRY(system_call) ENDPROC(system_call) +/* + * Spill live registers on the kernel stack macro. + * + * Entry condition: ps.woe is set, ps.excm is cleared + * Exit condition: windowstart has single bit set + * May clobber: a12, a13 + */ + .macro spill_registers_kernel + +#if XCHAL_NUM_AREGS > 16 + call12 1f + _j 2f + retw + .align 4 +1: + _entry a1, 48 + addi a12, a0, 3 +#if XCHAL_NUM_AREGS > 32 + .rept (XCHAL_NUM_AREGS - 32) / 12 + _entry a1, 48 + mov a12, a0 + .endr +#endif + _entry a1, 48 +#if XCHAL_NUM_AREGS % 12 == 0 + mov a8, a8 +#elif XCHAL_NUM_AREGS % 12 == 4 + mov a12, a12 +#elif XCHAL_NUM_AREGS % 12 == 8 + mov a4, a4 +#endif + retw +2: +#else + mov a12, a12 +#endif + .endm /* * Task switch. @@ -1806,21 +1843,20 @@ ENTRY(_switch_to) entry a1, 16 - mov a12, a2 # preserve 'prev' (a2) - mov a13, a3 # and 'next' (a3) + mov a10, a2 # preserve 'prev' (a2) + mov a11, a3 # and 'next' (a3) l32i a4, a2, TASK_THREAD_INFO l32i a5, a3, TASK_THREAD_INFO - save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER + save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER - s32i a0, a12, THREAD_RA # save return address - s32i a1, a12, THREAD_SP # save stack pointer + s32i a0, a10, THREAD_RA # save return address + s32i a1, a10, THREAD_SP # save stack pointer /* Disable ints while we manipulate the stack pointer. */ - movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL - xsr a14, ps + rsil a14, LOCKLEVEL rsr a3, excsave1 rsync s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ @@ -1835,7 +1871,7 @@ ENTRY(_switch_to) /* Flush register file. */ - call0 _spill_registers # destroys a3, a4, and SAR + spill_registers_kernel /* Set kernel stack (and leave critical section) * Note: It's save to set it here. The stack will not be overwritten @@ -1851,13 +1887,13 @@ ENTRY(_switch_to) /* restore context of the task 'next' */ - l32i a0, a13, THREAD_RA # restore return address - l32i a1, a13, THREAD_SP # restore stack pointer + l32i a0, a11, THREAD_RA # restore return address + l32i a1, a11, THREAD_SP # restore stack pointer - load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER + load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER wsr a14, ps - mov a2, a12 # return 'prev' + mov a2, a10 # return 'prev' rsync retw -- cgit v1.2.3-55-g7522 From 3251f1e27a5a17f0efd436cfd1e7b9896cfab0a0 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 30 Oct 2013 16:18:25 +0400 Subject: xtensa: save current register frame in fast_syscall_spill_registers_fixup We need it saved because it contains a3 where we track which register windows we still need to spill, and fixup handler may call C exception handlers. Also fix comments. Cc: stable@vger.kernel.org Signed-off-by: Max Filippov --- arch/xtensa/kernel/entry.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 0489918e40d2..b61e25146a2f 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1117,6 +1117,13 @@ ENDPROC(fast_syscall_spill_registers) * We basically restore WINDOWBASE and WINDOWSTART to the condition when * we entered the spill routine and jump to the user exception handler. * + * Note that we only need to restore the bits in windowstart that have not + * been spilled yet by the _spill_register routine. Luckily, a3 contains a + * rotated windowstart with only those bits set for frames that haven't been + * spilled yet. Because a3 is rotated such that bit 0 represents the register + * frame for the current windowbase - 1, we need to rotate a3 left by the + * value of the current windowbase + 1 and move it to windowstart. + * * a0: value of depc, original value in depc * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE * a3: exctable, original value in excsave1 @@ -1131,10 +1138,15 @@ ENTRY(fast_syscall_spill_registers_fixup) /* We need to make sure the current registers (a0-a3) are preserved. * To do this, we simply set the bit for the current window frame * in WS, so that the exception handlers save them to the task stack. + * + * Note: we use a3 to set the windowbase, so we take a special care + * of it, saving it in the original _spill_registers frame across + * the exception handler call. */ xsr a3, excsave1 # get spill-mask slli a3, a3, 1 # shift left by one + addi a3, a3, 1 # set the bit for the current window frame slli a2, a3, 32-WSBITS src a2, a3, a2 # a2 = xxwww1yyxxxwww1yy...... -- cgit v1.2.3-55-g7522 From 6b5a1f74e50170e64104135490dc32b657483594 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 28 Jan 2014 22:09:51 -0800 Subject: xtensa: fix fast_syscall_spill_registers The original implementation could clobber registers under certain conditions. The Xtensa processor architecture uses windowed registers and the original implementation was using a4 as a temporary register, which under certain conditions could be register a0 of the oldest window frame, and didn't always restore the content correctly. By moving the _spill_registers routine inside the fast system call, it frees up one more register (the return address is not required anymore) for the spill routine. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/entry.S | 383 ++++++++++++++++++++------------------------- 1 file changed, 174 insertions(+), 209 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index b61e25146a2f..ef7f4990722b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1081,34 +1081,202 @@ ENTRY(fast_syscall_spill_registers) rsr a0, sar s32i a3, a2, PT_AREG3 - s32i a4, a2, PT_AREG4 - s32i a0, a2, PT_AREG5 # store SAR to PT_AREG5 + s32i a0, a2, PT_SAR - /* The spill routine might clobber a7, a11, and a15. */ + /* The spill routine might clobber a4, a7, a8, a11, a12, and a15. */ + s32i a4, a2, PT_AREG4 s32i a7, a2, PT_AREG7 + s32i a8, a2, PT_AREG8 s32i a11, a2, PT_AREG11 + s32i a12, a2, PT_AREG12 s32i a15, a2, PT_AREG15 - call0 _spill_registers # destroys a3, a4, and SAR + /* + * Rotate ws so that the current windowbase is at bit 0. + * Assume ws = xxxwww1yy (www1 current window frame). + * Rotate ws right so that a4 = yyxxxwww1. + */ + + rsr a0, windowbase + rsr a3, windowstart # a3 = xxxwww1yy + ssr a0 # holds WB + slli a0, a3, WSBITS + or a3, a3, a0 # a3 = xxxwww1yyxxxwww1yy + srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 + + /* We are done if there are no more than the current register frame. */ + + extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww + movi a0, (1 << (WSBITS-1)) + _beqz a3, .Lnospill # only one active frame? jump + + /* We want 1 at the top, so that we return to the current windowbase */ + + or a3, a3, a0 # 1yyxxxwww + + /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ + + wsr a3, windowstart # save shifted windowstart + neg a0, a3 + and a3, a0, a3 # first bit set from right: 000010000 + + ffs_ws a0, a3 # a0: shifts to skip empty frames + movi a3, WSBITS + sub a0, a3, a0 # WSBITS-a0:number of 0-bits from right + ssr a0 # save in SAR for later. + + rsr a3, windowbase + add a3, a3, a0 + wsr a3, windowbase + rsync + + rsr a3, windowstart + srl a3, a3 # shift windowstart + + /* WB is now just one frame below the oldest frame in the register + window. WS is shifted so the oldest frame is in bit 0, thus, WB + and WS differ by one 4-register frame. */ + + /* Save frames. Depending what call was used (call4, call8, call12), + * we have to save 4,8. or 12 registers. + */ + + +.Lloop: _bbsi.l a3, 1, .Lc4 + _bbci.l a3, 2, .Lc12 + +.Lc8: s32e a4, a13, -16 + l32e a4, a5, -12 + s32e a8, a4, -32 + s32e a5, a13, -12 + s32e a6, a13, -8 + s32e a7, a13, -4 + s32e a9, a4, -28 + s32e a10, a4, -24 + s32e a11, a4, -20 + srli a11, a3, 2 # shift windowbase by 2 + rotw 2 + _bnei a3, 1, .Lloop + j .Lexit + +.Lc4: s32e a4, a9, -16 + s32e a5, a9, -12 + s32e a6, a9, -8 + s32e a7, a9, -4 + + srli a7, a3, 1 + rotw 1 + _bnei a3, 1, .Lloop + j .Lexit + +.Lc12: _bbci.l a3, 3, .Linvalid_mask # bit 2 shouldn't be zero! + + /* 12-register frame (call12) */ + + l32e a0, a5, -12 + s32e a8, a0, -48 + mov a8, a0 + + s32e a9, a8, -44 + s32e a10, a8, -40 + s32e a11, a8, -36 + s32e a12, a8, -32 + s32e a13, a8, -28 + s32e a14, a8, -24 + s32e a15, a8, -20 + srli a15, a3, 3 + + /* The stack pointer for a4..a7 is out of reach, so we rotate the + * window, grab the stackpointer, and rotate back. + * Alternatively, we could also use the following approach, but that + * makes the fixup routine much more complicated: + * rotw 1 + * s32e a0, a13, -16 + * ... + * rotw 2 + */ + + rotw 1 + mov a4, a13 + rotw -1 + + s32e a4, a8, -16 + s32e a5, a8, -12 + s32e a6, a8, -8 + s32e a7, a8, -4 + + rotw 3 + + _beqi a3, 1, .Lexit + j .Lloop + +.Lexit: + + /* Done. Do the final rotation and set WS */ + + rotw 1 + rsr a3, windowbase + ssl a3 + movi a3, 1 + sll a3, a3 + wsr a3, windowstart +.Lnospill: /* Advance PC, restore registers and SAR, and return from exception. */ - l32i a3, a2, PT_AREG5 - l32i a4, a2, PT_AREG4 + l32i a3, a2, PT_SAR l32i a0, a2, PT_AREG0 wsr a3, sar l32i a3, a2, PT_AREG3 /* Restore clobbered registers. */ + l32i a4, a2, PT_AREG4 l32i a7, a2, PT_AREG7 + l32i a8, a2, PT_AREG8 l32i a11, a2, PT_AREG11 + l32i a12, a2, PT_AREG12 l32i a15, a2, PT_AREG15 movi a2, 0 rfe +.Linvalid_mask: + + /* We get here because of an unrecoverable error in the window + * registers, so set up a dummy frame and kill the user application. + * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. + */ + + movi a0, 1 + movi a1, 0 + + wsr a0, windowstart + wsr a1, windowbase + rsync + + movi a0, 0 + + rsr a3, excsave1 + l32i a1, a3, EXC_TABLE_KSTK + + movi a4, (1 << PS_WOE_BIT) | LOCKLEVEL + wsr a4, ps + rsync + + movi a6, SIGSEGV + movi a4, do_exit + callx4 a4 + + /* shouldn't return, so panic */ + + wsr a0, excsave1 + movi a0, unrecoverable_exception + callx0 a0 # should not return +1: j 1b + + ENDPROC(fast_syscall_spill_registers) /* Fixup handler. @@ -1232,209 +1400,6 @@ ENTRY(fast_syscall_spill_registers_fixup_return) ENDPROC(fast_syscall_spill_registers_fixup_return) -/* - * spill all registers. - * - * This is not a real function. The following conditions must be met: - * - * - must be called with call0. - * - uses a3, a4 and SAR. - * - the last 'valid' register of each frame are clobbered. - * - the caller must have registered a fixup handler - * (or be inside a critical section) - * - PS_EXCM must be set (PS_WOE cleared?) - */ - -ENTRY(_spill_registers) - - /* - * Rotate ws so that the current windowbase is at bit 0. - * Assume ws = xxxwww1yy (www1 current window frame). - * Rotate ws right so that a4 = yyxxxwww1. - */ - - rsr a4, windowbase - rsr a3, windowstart # a3 = xxxwww1yy - ssr a4 # holds WB - slli a4, a3, WSBITS - or a3, a3, a4 # a3 = xxxwww1yyxxxwww1yy - srl a3, a3 # a3 = 00xxxwww1yyxxxwww1 - - /* We are done if there are no more than the current register frame. */ - - extui a3, a3, 1, WSBITS-1 # a3 = 0yyxxxwww - movi a4, (1 << (WSBITS-1)) - _beqz a3, .Lnospill # only one active frame? jump - - /* We want 1 at the top, so that we return to the current windowbase */ - - or a3, a3, a4 # 1yyxxxwww - - /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */ - - wsr a3, windowstart # save shifted windowstart - neg a4, a3 - and a3, a4, a3 # first bit set from right: 000010000 - - ffs_ws a4, a3 # a4: shifts to skip empty frames - movi a3, WSBITS - sub a4, a3, a4 # WSBITS-a4:number of 0-bits from right - ssr a4 # save in SAR for later. - - rsr a3, windowbase - add a3, a3, a4 - wsr a3, windowbase - rsync - - rsr a3, windowstart - srl a3, a3 # shift windowstart - - /* WB is now just one frame below the oldest frame in the register - window. WS is shifted so the oldest frame is in bit 0, thus, WB - and WS differ by one 4-register frame. */ - - /* Save frames. Depending what call was used (call4, call8, call12), - * we have to save 4,8. or 12 registers. - */ - - _bbsi.l a3, 1, .Lc4 - _bbsi.l a3, 2, .Lc8 - - /* Special case: we have a call12-frame starting at a4. */ - - _bbci.l a3, 3, .Lc12 # bit 3 shouldn't be zero! (Jump to Lc12 first) - - s32e a4, a1, -16 # a1 is valid with an empty spill area - l32e a4, a5, -12 - s32e a8, a4, -48 - mov a8, a4 - l32e a4, a1, -16 - j .Lc12c - -.Lnospill: - ret - -.Lloop: _bbsi.l a3, 1, .Lc4 - _bbci.l a3, 2, .Lc12 - -.Lc8: s32e a4, a13, -16 - l32e a4, a5, -12 - s32e a8, a4, -32 - s32e a5, a13, -12 - s32e a6, a13, -8 - s32e a7, a13, -4 - s32e a9, a4, -28 - s32e a10, a4, -24 - s32e a11, a4, -20 - - srli a11, a3, 2 # shift windowbase by 2 - rotw 2 - _bnei a3, 1, .Lloop - -.Lexit: /* Done. Do the final rotation, set WS, and return. */ - - rotw 1 - rsr a3, windowbase - ssl a3 - movi a3, 1 - sll a3, a3 - wsr a3, windowstart - ret - -.Lc4: s32e a4, a9, -16 - s32e a5, a9, -12 - s32e a6, a9, -8 - s32e a7, a9, -4 - - srli a7, a3, 1 - rotw 1 - _bnei a3, 1, .Lloop - j .Lexit - -.Lc12: _bbci.l a3, 3, .Linvalid_mask # bit 2 shouldn't be zero! - - /* 12-register frame (call12) */ - - l32e a2, a5, -12 - s32e a8, a2, -48 - mov a8, a2 - -.Lc12c: s32e a9, a8, -44 - s32e a10, a8, -40 - s32e a11, a8, -36 - s32e a12, a8, -32 - s32e a13, a8, -28 - s32e a14, a8, -24 - s32e a15, a8, -20 - srli a15, a3, 3 - - /* The stack pointer for a4..a7 is out of reach, so we rotate the - * window, grab the stackpointer, and rotate back. - * Alternatively, we could also use the following approach, but that - * makes the fixup routine much more complicated: - * rotw 1 - * s32e a0, a13, -16 - * ... - * rotw 2 - */ - - rotw 1 - mov a5, a13 - rotw -1 - - s32e a4, a9, -16 - s32e a5, a9, -12 - s32e a6, a9, -8 - s32e a7, a9, -4 - - rotw 3 - - _beqi a3, 1, .Lexit - j .Lloop - -.Linvalid_mask: - - /* We get here because of an unrecoverable error in the window - * registers. If we are in user space, we kill the application, - * however, this condition is unrecoverable in kernel space. - */ - - rsr a0, ps - _bbci.l a0, PS_UM_BIT, 1f - - /* User space: Setup a dummy frame and kill application. - * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. - */ - - movi a0, 1 - movi a1, 0 - - wsr a0, windowstart - wsr a1, windowbase - rsync - - movi a0, 0 - - rsr a3, excsave1 - l32i a1, a3, EXC_TABLE_KSTK - - movi a4, (1 << PS_WOE_BIT) | LOCKLEVEL - wsr a4, ps - rsync - - movi a6, SIGSEGV - movi a4, do_exit - callx4 a4 - -1: /* Kernel space: PANIC! */ - - wsr a0, excsave1 - movi a0, unrecoverable_exception - callx0 a0 # should not return -1: j 1b - -ENDPROC(_spill_registers) - #ifdef CONFIG_MMU /* * We should never get here. Bail out! -- cgit v1.2.3-55-g7522 From c0e50d41126e4786d9cf1105bdf783e55c99f915 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 28 Jan 2014 22:09:51 -0800 Subject: xtensa: fix fast_syscall_spill_registers The original implementation could clobber registers under certain conditions. The Xtensa processor architecture uses windowed registers and the original implementation was using a4 as a temporary register, which under certain conditions could be register a0 of the oldest window frame, and didn't always restore the content correctly. By moving the _spill_registers routine inside the fast system call, it frees up one more register (the return address is not required anymore) for the spill routine. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/vectors.S | 2 +- arch/xtensa/kernel/xtensa_ksyms.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index cb8fd44caabc..f9e1ec346e35 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -235,7 +235,7 @@ ENTRY(_DoubleExceptionVector) /* Check for overflow/underflow exception, jump if overflow. */ - _bbci.l a0, 6, _DoubleExceptionVector_WindowOverflow + bbci.l a0, 6, _DoubleExceptionVector_WindowOverflow /* * Restart window underflow exception. diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 74a60c7e085e..80b33ed51f31 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -122,9 +122,7 @@ EXPORT_SYMBOL(insw); EXPORT_SYMBOL(insl); extern long common_exception_return; -extern long _spill_registers; EXPORT_SYMBOL(common_exception_return); -EXPORT_SYMBOL(_spill_registers); #ifdef CONFIG_FUNCTION_TRACER EXPORT_SYMBOL(_mcount); -- cgit v1.2.3-55-g7522 From b399fe355b30d0102e7690c99e6f764ddfd32ec3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 5 Feb 2014 01:55:11 +0100 Subject: x86: Disable generation of traditional x87 instructions We recently had the case where wrongly used floating-constant 'E' caused the generation of traditional x87 instructions in kernel code and wreaking all kinds of havoc. Disable the generation of those too. This will save people a lot of time when trying to debug such issues by erroring out of the build instead of let them manifest themselves in very spectacular and happy-crappy ways at runtime. We're using -mno-fp-ret-in-387 in addition to -mno-80387 (which is == -msoft-float) because, as the gcc manpage says: On machines where a function returns floating-point results in the 80387 register stack, some floating-point opcodes may be emitted even if -msoft-float is used. so we want to turn off *all* non-integer instructions involving any architectural FPU state, unless it is absolutely necessary (and those cases need special handling anyway). Cc: Jiri Kosina Cc: Michael Matz Cc: Michal Hocko Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1391561711-3023-1-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/Makefile b/arch/x86/Makefile index eeda43abed6e..a414b1471ffc 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -82,8 +82,8 @@ else KBUILD_AFLAGS += -m64 KBUILD_CFLAGS += -m64 - # Don't autogenerate MMX or SSE instructions - KBUILD_CFLAGS += -mno-mmx -mno-sse + # Don't autogenerate traditional x87, MMX or SSE instructions + KBUILD_CFLAGS += -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 # Use -mpreferred-stack-boundary=3 if supported. KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) -- cgit v1.2.3-55-g7522 From 2f41898704d3cff796ea0adaea272808707d758e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sat, 1 Feb 2014 16:46:16 +0100 Subject: ARM: sun7i: dt: Fix interrupt trigger types The Allwinner A20 uses the ARM GIC as its internal interrupts controller. The GIC can work on several interrupt triggers, and the A20 was actually setting it up to use a rising edge as a trigger, while it was actually a level high trigger, leading to some interrupts that would be completely ignored if the edge was missed. Fix this for the remaining DT nodes that slipped through. Signed-off-by: Maxime Ripard Cc: stable@vger.kernel.org --- arch/arm/boot/dts/sun7i-a20.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 119f066f0d98..2374f5aa92e8 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -454,7 +454,7 @@ rtc: rtc@01c20d00 { compatible = "allwinner,sun7i-a20-rtc"; reg = <0x01c20d00 0x20>; - interrupts = <0 24 1>; + interrupts = <0 24 4>; }; sid: eeprom@01c23800 { @@ -596,10 +596,10 @@ hstimer@01c60000 { compatible = "allwinner,sun7i-a20-hstimer"; reg = <0x01c60000 0x1000>; - interrupts = <0 81 1>, - <0 82 1>, - <0 83 1>, - <0 84 1>; + interrupts = <0 81 4>, + <0 82 4>, + <0 83 4>, + <0 84 4>; clocks = <&ahb_gates 28>; }; -- cgit v1.2.3-55-g7522 From 40dd8f3b900cac1d925605a9d3199368c4af0a40 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Sun, 2 Feb 2014 14:52:40 +0100 Subject: ARM: sunxi: dt: Change the touchscreen compatibles Switch the device tree touchscreen compatibles to have a common pattern accross all Allwinner SoCs. Since the touchscreen driver has not been merged yet, it has no side effect. Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10.dtsi | 2 +- arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +- arch/arm/boot/dts/sun5i-a13.dtsi | 2 +- arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 040bb0eba152..e3ff64cbd279 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -426,7 +426,7 @@ }; rtp: rtp@01c25000 { - compatible = "allwinner,sun4i-ts"; + compatible = "allwinner,sun4i-a10-ts"; reg = <0x01c25000 0x100>; interrupts = <29>; }; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index ea16054857a4..8e57a2872f32 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -383,7 +383,7 @@ }; rtp: rtp@01c25000 { - compatible = "allwinner,sun4i-ts"; + compatible = "allwinner,sun4i-a10-ts"; reg = <0x01c25000 0x100>; interrupts = <29>; }; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index 320335abfccd..c463fd730c91 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -346,7 +346,7 @@ }; rtp: rtp@01c25000 { - compatible = "allwinner,sun4i-ts"; + compatible = "allwinner,sun4i-a10-ts"; reg = <0x01c25000 0x100>; interrupts = <29>; }; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 2374f5aa92e8..b79a626e0f76 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -463,7 +463,7 @@ }; rtp: rtp@01c25000 { - compatible = "allwinner,sun4i-ts"; + compatible = "allwinner,sun4i-a10-ts"; reg = <0x01c25000 0x100>; interrupts = <0 29 4>; }; -- cgit v1.2.3-55-g7522 From e90c78535283dd0ded3bf2e484890d14dba2d527 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 3 Feb 2014 18:02:09 +0100 Subject: x86/nmi: Push duration printk() to irq context Calling printk() from NMI context is bad (TM), so move it to IRQ context. In doing so we slightly change (probably wreck) the debugfs nmi_longest_ns thingy, in that it doesn't update to reflect the longest, nor does writing to it reset the count. Signed-off-by: Peter Zijlstra Cc: Don Zickus Cc: Dave Hansen Link: http://lkml.kernel.org/n/tip-rdw0au56a5ymis1u8p48c12d@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/nmi.h | 3 +++ arch/x86/kernel/nmi.c | 37 ++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index 86f9301903c8..5f2fc4441b11 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_NMI_H #define _ASM_X86_NMI_H +#include #include #include #include @@ -38,6 +39,8 @@ typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *); struct nmiaction { struct list_head list; nmi_handler_t handler; + u64 max_duration; + struct irq_work irq_work; unsigned long flags; const char *name; }; diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 6fcb49ce50a1..b4872b999a71 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -87,6 +87,7 @@ __setup("unknown_nmi_panic", setup_unknown_nmi_panic); #define nmi_to_desc(type) (&nmi_desc[type]) static u64 nmi_longest_ns = 1 * NSEC_PER_MSEC; + static int __init nmi_warning_debugfs(void) { debugfs_create_u64("nmi_longest_ns", 0644, @@ -95,6 +96,20 @@ static int __init nmi_warning_debugfs(void) } fs_initcall(nmi_warning_debugfs); +static void nmi_max_handler(struct irq_work *w) +{ + struct nmiaction *a = container_of(w, struct nmiaction, irq_work); + int remainder_ns, decimal_msecs; + u64 whole_msecs = ACCESS_ONCE(a->max_duration); + + remainder_ns = do_div(whole_msecs, (1000 * 1000)); + decimal_msecs = remainder_ns / 1000; + + printk_ratelimited(KERN_INFO + "INFO: NMI handler (%ps) took too long to run: %lld.%03d msecs\n", + a->handler, whole_msecs, decimal_msecs); +} + static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b) { struct nmi_desc *desc = nmi_to_desc(type); @@ -110,26 +125,20 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2 * to handle those situations. */ list_for_each_entry_rcu(a, &desc->head, list) { - u64 before, delta, whole_msecs; - int remainder_ns, decimal_msecs, thishandled; + int thishandled; + u64 delta; - before = sched_clock(); + delta = sched_clock(); thishandled = a->handler(type, regs); handled += thishandled; - delta = sched_clock() - before; + delta = sched_clock() - delta; trace_nmi_handler(a->handler, (int)delta, thishandled); - if (delta < nmi_longest_ns) + if (delta < nmi_longest_ns || delta < a->max_duration) continue; - nmi_longest_ns = delta; - whole_msecs = delta; - remainder_ns = do_div(whole_msecs, (1000 * 1000)); - decimal_msecs = remainder_ns / 1000; - printk_ratelimited(KERN_INFO - "INFO: NMI handler (%ps) took too long to run: " - "%lld.%03d msecs\n", a->handler, whole_msecs, - decimal_msecs); + a->max_duration = delta; + irq_work_queue(&a->irq_work); } rcu_read_unlock(); @@ -146,6 +155,8 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) if (!action->handler) return -EINVAL; + init_irq_work(&action->irq_work, nmi_max_handler); + spin_lock_irqsave(&desc->lock, flags); /* -- cgit v1.2.3-55-g7522 From 13beacee817d27a40ffc6f065ea0042685611dd5 Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Wed, 29 Jan 2014 14:37:50 -0500 Subject: perf/x86/p4: Fix counter corruption when using lots of perf groups On a P4 box stressing perf with: ./perf record -o perf.data ./perf stat -v ./perf bench all it was noticed that a slew of unknown NMIs would pop out rather quickly. Painfully debugging this ancient platform, led me to notice cross cpu counter corruption. The P4 machine is special in that it has 18 counters, half are used for cpu0 and the other half is for cpu1 (or all 18 if hyperthreading is disabled). But the splitting of the counters has to be actively managed by the software. In this particular bug, one of the cpu0 specific counters was being used by cpu1 and caused all sorts of random unknown nmis. I am not entirely sure on the corruption path, but what happens is: o perf schedules a group with p4_pmu_schedule_events() o inside p4_pmu_schedule_events(), it notices an hwc pointer is being reused but for a different cpu, so it 'swaps' the config bits and returns the updated 'assign' array with a _new_ index. o perf schedules another group with p4_pmu_schedule_events() o inside p4_pmu_schedule_events(), it notices an hwc pointer is being reused (the same one as above) but for the _same_ cpu [BUG!!], so it updates the 'assign' array to use the _old_ (wrong cpu) index because the _new_ index is in an earlier part of the 'assign' array (and hasn't been committed yet). o perf commits the transaction using the wrong index and corrupts the other cpu The [BUG!!] is because the 'hwc->config' is updated but not the 'hwc->idx'. So the check for 'p4_should_swap_ts()' is correct the first time around but incorrect the second time around (because hwc->config was updated in between). I think the spirit of perf was to not modify anything until all the transactions had a chance to 'test' if they would succeed, and if so, commit atomically. However, P4 breaks this spirit by touching the hwc->config element. So my fix is to continue the un-perf like breakage, by assigning hwc->idx to -1 on swap to tell follow up group scheduling to find a new index. Of course if the transaction fails rolling this back will be difficult, but that is not different than how the current code works. :-) And I wasn't sure how much effort to cleanup the code I should do for a platform that is almost 10 years old by now. Hence the lazy fix. Signed-off-by: Don Zickus Acked-by: Cyrill Gorcunov Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1391024270-19469-1-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 3486e6660357..f44c34d7313b 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -1257,7 +1257,24 @@ again: pass++; goto again; } - + /* + * Perf does test runs to see if a whole group can be assigned + * together succesfully. There can be multiple rounds of this. + * Unfortunately, p4_pmu_swap_config_ts touches the hwc->config + * bits, such that the next round of group assignments will + * cause the above p4_should_swap_ts to pass instead of fail. + * This leads to counters exclusive to thread0 being used by + * thread1. + * + * Solve this with a cheap hack, reset the idx back to -1 to + * force a new lookup (p4_next_cntr) to get the right counter + * for the right thread. + * + * This probably doesn't comply with the general spirit of how + * perf wants to work, but P4 is special. :-( + */ + if (p4_should_swap_ts(hwc->config, cpu)) + hwc->idx = -1; p4_pmu_swap_config_ts(hwc, cpu); if (assign) assign[i] = cntr_idx; -- cgit v1.2.3-55-g7522 From 90ed5b0fa5eb96e1cbb34aebf6a9ed96ee1587ec Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Sun, 9 Feb 2014 13:20:18 +0100 Subject: perf/x86/p4: Block PMIs on init to prevent a stream of unkown NMIs A bunch of unknown NMIs have popped up on a Pentium4 recently when booting into a kdump kernel. This was exposed because the watchdog timer went from 60 seconds down to 10 seconds (increasing the ability to reproduce this problem). What is happening is on boot up of the second kernel (the kdump one), the previous nmi_watchdogs were enabled on thread 0 and thread 1. The second kernel only initializes one cpu but the perf counter on thread 1 still counts. Normally in a kdump scenario, the other cpus are blocking in an NMI loop, but more importantly their local apics have the performance counters disabled (iow LVTPC is masked). So any counters that fire are masked and never get through to the second kernel. However, on a P4 the local apic is shared by both threads and thread1's PMI (despite being configured to only interrupt thread1) will generate an NMI on thread0. Because thread0 knows nothing about this NMI, it is seen as an unknown NMI. This would be fine because it is a kdump kernel, strange things happen what is the big deal about a single unknown NMI. Unfortunately, the P4 comes with another quirk: clearing the overflow bit to prevent a stream of NMIs. This is the problem. The kdump kernel can not execute because of the endless NMIs that happen. To solve this, I instrumented the p4 perf init code, to walk all the counters and zero them out (just like a normal reset would). Now when the counters go off, they do not generate anything and no unknown NMIs are seen. I tested this on a P4 we have in our lab. After two or three crashes, I could normally reproduce the problem. Now after 10 crashes, everything continues to boot correctly. Signed-off-by: Don Zickus Cc: Dave Young Cc: Vivek Goyal Cc: Cyrill Gorcunov Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140120154115.GZ25953@redhat.com [ Fixed a stylistic detail. ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_p4.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index f44c34d7313b..5d466b7d8609 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -1339,6 +1339,7 @@ static __initconst const struct x86_pmu p4_pmu = { __init int p4_pmu_init(void) { unsigned int low, high; + int i, reg; /* If we get stripped -- indexing fails */ BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC); @@ -1357,5 +1358,19 @@ __init int p4_pmu_init(void) x86_pmu = p4_pmu; + /* + * Even though the counters are configured to interrupt a particular + * logical processor when an overflow happens, testing has shown that + * on kdump kernels (which uses a single cpu), thread1's counter + * continues to run and will report an NMI on thread0. Due to the + * overflow bug, this leads to a stream of unknown NMIs. + * + * Solve this by zero'ing out the registers to mimic a reset. + */ + for (i = 0; i < x86_pmu.num_counters; i++) { + reg = x86_pmu_config_addr(i); + wrmsrl_safe(reg, 0ULL); + } + return 0; } -- cgit v1.2.3-55-g7522 From d3c63ae1e2e35e4250390c079dc3fb7291347f5c Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 4 Feb 2014 23:54:58 -0800 Subject: x86/apic: Only use default_wait_for_init_deassert() es7000_wait_for_init_deassert() is functionally equivalent to default_wait_for_init_deassert(), so remove the duplicate code and use only a single function. Signed-off-by: David Rientjes Reviewed-by: Thomas Gleixner Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1402042353030.7839@chino.kir.corp.google.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 1 - arch/x86/kernel/apic/es7000_32.c | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 1d2091a226bc..2ef701381e2a 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -521,7 +521,6 @@ static inline void default_wait_for_init_deassert(atomic_t *deassert) { while (!atomic_read(deassert)) cpu_relax(); - return; } extern void generic_bigsmp_probe(void); diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index c55224731b2d..d03d57e0a806 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -394,12 +394,6 @@ static void es7000_enable_apic_mode(void) WARN(1, "Command failed, status = %x\n", mip_status); } -static void es7000_wait_for_init_deassert(atomic_t *deassert) -{ - while (!atomic_read(deassert)) - cpu_relax(); -} - static unsigned int es7000_get_apic_id(unsigned long x) { return (x >> 24) & 0xFF; @@ -722,7 +716,7 @@ static struct apic __refdata apic_es7000 = { .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, - .wait_for_init_deassert = es7000_wait_for_init_deassert, + .wait_for_init_deassert = default_wait_for_init_deassert, /* Nothing to do for most platforms, since cleared by the INIT cycle: */ .smp_callin_clear_local_apic = NULL, -- cgit v1.2.3-55-g7522 From 465822cfc8cb850ba76046965cc7b6fd1f8c3d73 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 4 Feb 2014 23:55:01 -0800 Subject: x86/apic: Switch wait_for_init_deassert() to a bool flag Now that there is only a single wait_for_init_deassert() function, just convert the member of struct apic to a bool to determine whether we need to wait for init_deassert to become non-zero. There are no more callers of default_wait_for_init_deassert(), so fold it into the caller. Signed-off-by: David Rientjes Reviewed-by: Thomas Gleixner Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1402042354010.7839@chino.kir.corp.google.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 8 +------- arch/x86/kernel/apic/apic_flat_64.c | 4 ++-- arch/x86/kernel/apic/apic_noop.c | 3 +-- arch/x86/kernel/apic/apic_numachip.c | 2 +- arch/x86/kernel/apic/bigsmp_32.c | 3 +-- arch/x86/kernel/apic/es7000_32.c | 6 ++---- arch/x86/kernel/apic/numaq_32.c | 3 +-- arch/x86/kernel/apic/probe_32.c | 3 +-- arch/x86/kernel/apic/summit_32.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 2 +- arch/x86/kernel/smpboot.c | 5 +++-- 13 files changed, 17 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 2ef701381e2a..c1d3074b8514 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -351,7 +351,7 @@ struct apic { int trampoline_phys_low; int trampoline_phys_high; - void (*wait_for_init_deassert)(atomic_t *deassert); + bool wait_for_init_deassert; void (*smp_callin_clear_local_apic)(void); void (*inquire_remote_apic)(int apicid); @@ -517,12 +517,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu); extern int default_check_phys_apicid_present(int phys_apicid); #endif -static inline void default_wait_for_init_deassert(atomic_t *deassert) -{ - while (!atomic_read(deassert)) - cpu_relax(); -} - extern void generic_bigsmp_probe(void); diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 2c621a6b901a..7c1b29479513 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -198,7 +198,7 @@ static struct apic apic_flat = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, @@ -314,7 +314,7 @@ static struct apic apic_physflat = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 191ce75c0e54..8c7c98249c20 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -172,8 +172,7 @@ struct apic apic_noop = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 3e67f9e3d7ef..a5b45df8bc88 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -248,7 +248,7 @@ static const struct apic apic_numachip __refconst = { .wakeup_secondary_cpu = numachip_wakeup_secondary, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = NULL, /* REMRD not supported */ diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index d50e3640d5ae..e4840aa7a255 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -199,8 +199,7 @@ static struct apic apic_bigsmp = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = default_wait_for_init_deassert, - + .wait_for_init_deassert = true, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index d03d57e0a806..6f8f8b348a39 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -652,8 +652,7 @@ static struct apic __refdata apic_es7000_cluster = { .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, - .wait_for_init_deassert = NULL, - + .wait_for_init_deassert = false, /* Nothing to do for most platforms, since cleared by the INIT cycle: */ .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, @@ -716,8 +715,7 @@ static struct apic __refdata apic_es7000 = { .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, - .wait_for_init_deassert = default_wait_for_init_deassert, - + .wait_for_init_deassert = true, /* Nothing to do for most platforms, since cleared by the INIT cycle: */ .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 1e42e8f305ee..030ea1c04f72 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -505,8 +505,7 @@ static struct apic __refdata apic_numaq = { .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, /* We don't do anything here because we use NMI's to boot instead */ - .wait_for_init_deassert = NULL, - + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index eb35ef9ee63f..cceb352c968c 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -119,8 +119,7 @@ static struct apic apic_default = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = default_wait_for_init_deassert, - + .wait_for_init_deassert = true, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 00146f9b0254..b656128611cd 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -532,8 +532,7 @@ static struct apic apic_summit = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = default_wait_for_init_deassert, - + .wait_for_init_deassert = true, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = default_inquire_remote_apic, diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index cac85ee6913f..e66766bf1641 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -279,7 +279,7 @@ static struct apic apic_x2apic_cluster = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index de231e328cae..6d600ebf6c12 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -133,7 +133,7 @@ static struct apic apic_x2apic_phys = { .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d263b1307de1..7834389ba5be 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -396,7 +396,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .wakeup_secondary_cpu = uv_wakeup_secondary, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, + .wait_for_init_deassert = false, .smp_callin_clear_local_apic = NULL, .inquire_remote_apic = NULL, diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a32da804252e..c77acc69ecf6 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -122,8 +122,9 @@ static void smp_callin(void) * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. */ cpuid = smp_processor_id(); - if (apic->wait_for_init_deassert && cpuid != 0) - apic->wait_for_init_deassert(&init_deasserted); + if (apic->wait_for_init_deassert && cpuid) + while (!atomic_read(&init_deasserted)) + cpu_relax(); /* * (This works even if the APIC is not enabled.) -- cgit v1.2.3-55-g7522 From 6d4989835e5418fdfda764fce7294246f80cf464 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 4 Feb 2014 23:55:04 -0800 Subject: x86/apic: Remove unused function prototypes Some function prototypes declared in asm/apic.h are never defined, so remove them. Signed-off-by: David Rientjes Reviewed-by: Thomas Gleixner Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1402042354210.7839@chino.kir.corp.google.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index c1d3074b8514..b4c561dbe3ba 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -93,9 +93,6 @@ static inline int is_vsmp_box(void) return 0; } #endif -extern void xapic_wait_icr_idle(void); -extern u32 safe_xapic_wait_icr_idle(void); -extern void xapic_icr_write(u32, u32); extern int setup_profiling_timer(unsigned int); static inline void native_apic_mem_write(u32 reg, u32 v) @@ -184,7 +181,6 @@ extern int x2apic_phys; extern int x2apic_preenabled; extern void check_x2apic(void); extern void enable_x2apic(void); -extern void x2apic_icr_write(u32 low, u32 id); static inline int x2apic_enabled(void) { u64 msr; -- cgit v1.2.3-55-g7522 From dc9788f40a769d967de3eb5a7aee8c1a70094d32 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 4 Feb 2014 23:55:06 -0800 Subject: x86/apic: Always define nox2apic and define it as initdata The "nox2apic" variable can be defined as __initdata since it is only used for bootstrap. It can now unconditionally be defined since it will later be freed. At the same time, it is also better off as a bool. Signed-off-by: David Rientjes Reviewed-by: Thomas Gleixner Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1402042354380.7839@chino.kir.corp.google.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 1 - arch/x86/kernel/apic/apic.c | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index b4c561dbe3ba..19b0ebafcd3e 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -217,7 +217,6 @@ static inline void x2apic_force_phys(void) { } -#define nox2apic 0 #define x2apic_preenabled 0 #define x2apic_supported() 0 #endif diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 7f26c9a70a9e..f824d697db19 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -133,6 +133,10 @@ static inline void imcr_apic_to_pic(void) * +1=force-enable */ static int force_enable_local_apic __initdata; + +/* Control whether x2APIC mode is enabled or not */ +static bool nox2apic __initdata; + /* * APIC command line parameters */ @@ -162,8 +166,7 @@ int x2apic_mode; /* x2apic enabled before OS handover */ int x2apic_preenabled; static int x2apic_disabled; -static int nox2apic; -static __init int setup_nox2apic(char *str) +static int __init setup_nox2apic(char *str) { if (x2apic_enabled()) { int apicid = native_apic_msr_read(APIC_ID); @@ -178,7 +181,7 @@ static __init int setup_nox2apic(char *str) } else setup_clear_cpu_cap(X86_FEATURE_X2APIC); - nox2apic = 1; + nox2apic = true; return 0; } -- cgit v1.2.3-55-g7522 From ba6a328f7dfc95b20df5e0eb33c698187e997190 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 26 Jan 2014 13:01:42 -0800 Subject: x86/mm: Avoid duplicated pxm_to_node() calls In slit init code, too many pxm_to_node() function calls are done. We can store from_node/to_node instead of keep calling pxm_to_node(). - Before this patch: pxm_to_node() is called n*(1+n*3) times. - After this patch: pxm_to_node() is called n*(1+n) times. for 8 sockets, it will be 72 instead of 200. for 32 sockets, it will be 1056 instead of 3104. Signed-off-by: Yinghai Lu Cc: Toshi Kani Cc: David Rientjes Link: http://lkml.kernel.org/r/1390770102-4007-1-git-send-email-yinghai@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/mm/srat.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 1953e9c9391a..66338a60aa6e 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c @@ -52,12 +52,18 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) int i, j; for (i = 0; i < slit->locality_count; i++) { - if (pxm_to_node(i) == NUMA_NO_NODE) + const int from_node = pxm_to_node(i); + + if (from_node == NUMA_NO_NODE) continue; + for (j = 0; j < slit->locality_count; j++) { - if (pxm_to_node(j) == NUMA_NO_NODE) + const int to_node = pxm_to_node(j); + + if (to_node == NUMA_NO_NODE) continue; - numa_set_distance(pxm_to_node(i), pxm_to_node(j), + + numa_set_distance(from_node, to_node, slit->entry[slit->locality_count * i + j]); } } -- cgit v1.2.3-55-g7522 From b119fa61d440fe0f5af504299ad506637585a8ca Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Tue, 21 Jan 2014 15:36:16 -0800 Subject: locking/mcs: Order the header files in Kbuild of each architecture in alphabetical order We perform a clean up of the Kbuid files in each architecture. We order the files in each Kbuild in alphabetical order by running the below script. for i in arch/*/include/asm/Kbuild do cat $i | gawk '/^generic-y/ { i = 3; do { for (; i <= NF; i++) { if ($i == "\\") { getline; i = 1; continue; } if ($i != "") hdr[$i] = $i; } break; } while (1); next; } // { print $0; } END { n = asort(hdr); for (i = 1; i <= n; i++) print "generic-y += " hdr[i]; }' > ${i}.sorted; mv ${i}.sorted $i; done Signed-off-by: Tim Chen Cc: Arnd Bergmann Cc: Matthew R Wilcox Cc: AswinChandramouleeswaran Cc: Dave Hansen Cc: "Paul E.McKenney" Cc: Scott J Norton Cc: Will Deacon Cc: "Figo.zhang" Cc: Linus Torvalds Cc: Rik van Riel Cc: Waiman Long Cc: Peter Hurley Cc: Andrea Arcangeli Cc: Tim Chen Cc: Alex Shi Cc: Raghavendra K T Cc: Andi Kleen Cc: George Spelvin Cc: MichelLespinasse Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Davidlohr Bueso Cc: Andrew Morton Signed-off-by: Peter Zijlstra [ Fixed build bug. ] Signed-off-by: Ingo Molnar --- arch/alpha/include/asm/Kbuild | 6 +++--- arch/arc/include/asm/Kbuild | 6 +++--- arch/arm/include/asm/Kbuild | 4 ++-- arch/arm64/include/asm/Kbuild | 6 +++--- arch/avr32/include/asm/Kbuild | 40 +++++++++++++++++++------------------- arch/blackfin/include/asm/Kbuild | 6 +++--- arch/c6x/include/asm/Kbuild | 4 ++-- arch/cris/include/asm/Kbuild | 2 +- arch/frv/include/asm/Kbuild | 4 ++-- arch/hexagon/include/asm/Kbuild | 6 +++--- arch/ia64/include/asm/Kbuild | 4 ++-- arch/m32r/include/asm/Kbuild | 4 ++-- arch/m68k/include/asm/Kbuild | 6 +++--- arch/metag/include/asm/Kbuild | 4 ++-- arch/microblaze/include/asm/Kbuild | 4 ++-- arch/mips/include/asm/Kbuild | 4 ++-- arch/mn10300/include/asm/Kbuild | 2 +- arch/openrisc/include/asm/Kbuild | 10 +++++----- arch/parisc/include/asm/Kbuild | 31 +++++++++++++++++++++++------ arch/powerpc/include/asm/Kbuild | 4 ++-- arch/s390/include/asm/Kbuild | 4 ++-- arch/score/include/asm/Kbuild | 4 ++-- arch/sh/include/asm/Kbuild | 8 ++++---- arch/sparc/include/asm/Kbuild | 10 +++++----- arch/tile/include/asm/Kbuild | 4 ++-- arch/um/include/asm/Kbuild | 33 ++++++++++++++++++++++++------- arch/unicore32/include/asm/Kbuild | 4 ++-- arch/xtensa/include/asm/Kbuild | 4 ++-- 28 files changed, 133 insertions(+), 95 deletions(-) (limited to 'arch') diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index a73a8e208a4a..55a2b0395d48 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -1,7 +1,7 @@ -generic-y += clkdev.h +generic-y += clkdev.h generic-y += exec.h -generic-y += trace_clock.h -generic-y += preempt.h generic-y += hash.h +generic-y += preempt.h +generic-y += trace_clock.h diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 0d3362991c31..54ceb91c7ce0 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -1,15 +1,15 @@ generic-y += auxvec.h generic-y += barrier.h -generic-y += bugs.h generic-y += bitsperlong.h +generic-y += bugs.h generic-y += clkdev.h generic-y += cputime.h generic-y += device.h generic-y += div64.h generic-y += emergency-restart.h generic-y += errno.h -generic-y += fcntl.h generic-y += fb.h +generic-y += fcntl.h generic-y += ftrace.h generic-y += hardirq.h generic-y += hash.h @@ -30,6 +30,7 @@ generic-y += pci.h generic-y += percpu.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sembuf.h @@ -48,4 +49,3 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 3278afe2c3ab..3b2092049b51 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += current.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += hash.h generic-y += ioctl.h generic-y += ipcbuf.h generic-y += irq_regs.h @@ -17,6 +18,7 @@ generic-y += msgbuf.h generic-y += param.h generic-y += parport.h generic-y += poll.h +generic-y += preempt.h generic-y += resource.h generic-y += sections.h generic-y += segment.h @@ -33,5 +35,3 @@ generic-y += termios.h generic-y += timex.h generic-y += trace_clock.h generic-y += unaligned.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 71c53ecfcc3a..54038befa0a4 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -12,6 +12,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += ftrace.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -28,6 +29,7 @@ generic-y += mutex.h generic-y += pci.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -38,8 +40,8 @@ generic-y += shmbuf.h generic-y += sizes.h generic-y += socket.h generic-y += sockios.h -generic-y += switch_to.h generic-y += swab.h +generic-y += switch_to.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h @@ -49,5 +51,3 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index cfb9fe1b8df9..064ca3c058ff 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -1,21 +1,21 @@ -generic-y += clkdev.h -generic-y += cputime.h -generic-y += delay.h -generic-y += device.h -generic-y += div64.h -generic-y += emergency-restart.h -generic-y += exec.h -generic-y += futex.h -generic-y += preempt.h -generic-y += irq_regs.h -generic-y += param.h -generic-y += local.h -generic-y += local64.h -generic-y += percpu.h -generic-y += scatterlist.h -generic-y += sections.h -generic-y += topology.h -generic-y += trace_clock.h -generic-y += xor.h -generic-y += hash.h +generic-y += clkdev.h +generic-y += cputime.h +generic-y += delay.h +generic-y += device.h +generic-y += div64.h +generic-y += emergency-restart.h +generic-y += exec.h +generic-y += futex.h +generic-y += hash.h +generic-y += irq_regs.h +generic-y += local.h +generic-y += local64.h +generic-y += param.h +generic-y += percpu.h +generic-y += preempt.h +generic-y += scatterlist.h +generic-y += sections.h +generic-y += topology.h +generic-y += trace_clock.h +generic-y += xor.h diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 359d36fdc247..ca30a3dc47e7 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -10,6 +10,7 @@ generic-y += emergency-restart.h generic-y += errno.h generic-y += fb.h generic-y += futex.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ipcbuf.h @@ -17,14 +18,15 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += kmap_types.h generic-y += kvm_para.h -generic-y += local64.h generic-y += local.h +generic-y += local64.h generic-y += mman.h generic-y += msgbuf.h generic-y += mutex.h generic-y += param.h generic-y += percpu.h generic-y += pgalloc.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sembuf.h @@ -44,5 +46,3 @@ generic-y += ucontext.h generic-y += unaligned.h generic-y += user.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index d73bb85ccdd3..dea0671524a1 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild @@ -15,6 +15,7 @@ generic-y += exec.h generic-y += fb.h generic-y += fcntl.h generic-y += futex.h +generic-y += hash.h generic-y += hw_irq.h generic-y += io.h generic-y += ioctl.h @@ -34,6 +35,7 @@ generic-y += percpu.h generic-y += pgalloc.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += segment.h @@ -56,5 +58,3 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index f3fd8768f095..7f8d1b174a34 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -10,7 +10,7 @@ generic-y += hash.h generic-y += kvm_para.h generic-y += linkage.h generic-y += module.h +generic-y += preempt.h generic-y += trace_clock.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index bc42f14c9c2e..93428d035cfb 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -1,6 +1,6 @@ generic-y += clkdev.h generic-y += exec.h -generic-y += trace_clock.h -generic-y += preempt.h generic-y += hash.h +generic-y += preempt.h +generic-y += trace_clock.h diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 38ca45d3df1e..9f0eda48643a 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -25,14 +25,15 @@ generic-y += ipcbuf.h generic-y += irq_regs.h generic-y += kdebug.h generic-y += kmap_types.h -generic-y += local64.h generic-y += local.h +generic-y += local64.h generic-y += mman.h generic-y += msgbuf.h generic-y += pci.h generic-y += percpu.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += rwsem.h generic-y += scatterlist.h @@ -45,8 +46,8 @@ generic-y += siginfo.h generic-y += sizes.h generic-y += socket.h generic-y += sockios.h -generic-y += statfs.h generic-y += stat.h +generic-y += statfs.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h @@ -55,4 +56,3 @@ generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h generic-y += xor.h -generic-y += preempt.h diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 283a83154b5e..81ebef7f1a87 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -1,8 +1,8 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += hash.h generic-y += kvm_para.h -generic-y += trace_clock.h generic-y += preempt.h +generic-y += trace_clock.h generic-y += vtime.h -generic-y += hash.h diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index 932435ac4e5c..87042215b543 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -1,7 +1,7 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += hash.h generic-y += module.h -generic-y += trace_clock.h generic-y += preempt.h -generic-y += hash.h +generic-y += trace_clock.h diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 7cc8c364924d..f44ac8f9536a 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -6,6 +6,7 @@ generic-y += device.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ipcbuf.h @@ -13,11 +14,12 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += kmap_types.h generic-y += kvm_para.h -generic-y += local64.h generic-y += local.h +generic-y += local64.h generic-y += mman.h generic-y += mutex.h generic-y += percpu.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -31,5 +33,3 @@ generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild index b716d807c2ec..ac22144e92a3 100644 --- a/arch/metag/include/asm/Kbuild +++ b/arch/metag/include/asm/Kbuild @@ -13,6 +13,7 @@ generic-y += fb.h generic-y += fcntl.h generic-y += futex.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -30,6 +31,7 @@ generic-y += pci.h generic-y += percpu.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += scatterlist.h generic-y += sections.h generic-y += sembuf.h @@ -52,5 +54,3 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 2b98bc73642a..4b5f12259d81 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,6 +3,6 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += exec.h generic-y += hash.h -generic-y += trace_clock.h -generic-y += syscalls.h generic-y += preempt.h +generic-y += syscalls.h +generic-y += trace_clock.h diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 2d7f65052c1f..82ee17a68ae0 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -2,16 +2,16 @@ generic-y += cputime.h generic-y += current.h generic-y += emergency-restart.h +generic-y += hash.h generic-y += local64.h generic-y += mutex.h generic-y += parport.h generic-y += percpu.h +generic-y += preempt.h generic-y += scatterlist.h generic-y += sections.h generic-y += segment.h generic-y += serial.h generic-y += trace_clock.h -generic-y += preempt.h generic-y += ucontext.h generic-y += xor.h -generic-y += hash.h diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index 992e989ab785..da3b2f50c07e 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -3,5 +3,5 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += exec.h generic-y += hash.h -generic-y += trace_clock.h generic-y += preempt.h +generic-y += trace_clock.h diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index 2e40f1ca8667..f62a67a15055 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild @@ -10,8 +10,8 @@ generic-y += bugs.h generic-y += cacheflush.h generic-y += checksum.h generic-y += clkdev.h -generic-y += cmpxchg.h generic-y += cmpxchg-local.h +generic-y += cmpxchg.h generic-y += cputime.h generic-y += current.h generic-y += device.h @@ -25,6 +25,7 @@ generic-y += fcntl.h generic-y += ftrace.h generic-y += futex.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -41,6 +42,7 @@ generic-y += pci.h generic-y += percpu.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -53,11 +55,11 @@ generic-y += siginfo.h generic-y += signal.h generic-y += socket.h generic-y += sockios.h -generic-y += statfs.h generic-y += stat.h +generic-y += statfs.h generic-y += string.h -generic-y += switch_to.h generic-y += swab.h +generic-y += switch_to.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h @@ -68,5 +70,3 @@ generic-y += user.h generic-y += vga.h generic-y += word-at-a-time.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 752c981bc3c7..958b79aac24f 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -1,9 +1,28 @@ +generic-y += auxvec.h generic-y += barrier.h -generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ - segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ - div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ - poll.h xor.h clkdev.h exec.h -generic-y += trace_clock.h -generic-y += preempt.h +generic-y += clkdev.h +generic-y += cputime.h +generic-y += device.h +generic-y += div64.h +generic-y += emergency-restart.h +generic-y += exec.h generic-y += hash.h +generic-y += hw_irq.h +generic-y += irq_regs.h +generic-y += kdebug.h +generic-y += kvm_para.h +generic-y += local.h +generic-y += local64.h +generic-y += mutex.h +generic-y += param.h +generic-y += percpu.h +generic-y += poll.h +generic-y += preempt.h +generic-y += segment.h +generic-y += topology.h +generic-y += trace_clock.h +generic-y += user.h +generic-y += vga.h +generic-y += word-at-a-time.h +generic-y += xor.h diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 6c0a955a1b06..b618c416d3d9 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -1,7 +1,7 @@ generic-y += clkdev.h +generic-y += hash.h +generic-y += preempt.h generic-y += rwsem.h generic-y += trace_clock.h -generic-y += preempt.h generic-y += vtime.h -generic-y += hash.h diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 8386a4a1f19a..482f492f0834 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -1,6 +1,6 @@ generic-y += clkdev.h -generic-y += trace_clock.h -generic-y += preempt.h generic-y += hash.h +generic-y += preempt.h +generic-y += trace_clock.h diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index 146b9d5e89f8..e92319fb146d 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -1,10 +1,10 @@ header-y += + generic-y += barrier.h generic-y += clkdev.h generic-y += hash.h +generic-y += preempt.h generic-y += trace_clock.h generic-y += xor.h -generic-y += preempt.h - diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 0cd7198a4524..85c214e456f9 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -8,18 +8,20 @@ generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h generic-y += fcntl.h +generic-y += hash.h generic-y += ioctl.h generic-y += ipcbuf.h generic-y += irq_regs.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mman.h +generic-y += msgbuf.h generic-y += param.h generic-y += parport.h generic-y += percpu.h generic-y += poll.h -generic-y += mman.h -generic-y += msgbuf.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sembuf.h @@ -34,5 +36,3 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += ucontext.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 4b60a0c325ec..82150287bfa4 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -6,15 +6,15 @@ generic-y += cputime.h generic-y += div64.h generic-y += emergency-restart.h generic-y += exec.h -generic-y += linkage.h -generic-y += local64.h -generic-y += mutex.h +generic-y += hash.h generic-y += irq_regs.h +generic-y += linkage.h generic-y += local.h +generic-y += local64.h generic-y += module.h +generic-y += mutex.h +generic-y += preempt.h generic-y += serial.h generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 3793c75e45d9..e0b1ed967737 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -11,6 +11,7 @@ generic-y += errno.h generic-y += exec.h generic-y += fb.h generic-y += fcntl.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -24,6 +25,7 @@ generic-y += param.h generic-y += parport.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sembuf.h @@ -38,5 +40,3 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += types.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 88a330dcdede..215e05d8d4b8 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -1,8 +1,27 @@ -generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h -generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h -generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h -generic-y += switch_to.h clkdev.h -generic-y += trace_clock.h -generic-y += preempt.h -generic-y += hash.h generic-y += barrier.h +generic-y += bug.h +generic-y += clkdev.h +generic-y += cputime.h +generic-y += current.h +generic-y += delay.h +generic-y += device.h +generic-y += emergency-restart.h +generic-y += exec.h +generic-y += ftrace.h +generic-y += futex.h +generic-y += hardirq.h +generic-y += hash.h +generic-y += hw_irq.h +generic-y += io.h +generic-y += irq_regs.h +generic-y += kdebug.h +generic-y += mutex.h +generic-y += param.h +generic-y += pci.h +generic-y += percpu.h +generic-y += preempt.h +generic-y += sections.h +generic-y += switch_to.h +generic-y += topology.h +generic-y += trace_clock.h +generic-y += xor.h diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index 3ef4f9d9bf5d..ad2c737a9cab 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -16,6 +16,7 @@ generic-y += fcntl.h generic-y += ftrace.h generic-y += futex.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h @@ -32,6 +33,7 @@ generic-y += parport.h generic-y += percpu.h generic-y += poll.h generic-y += posix_types.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -60,5 +62,3 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 0a337e4a8370..223280d8e611 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -9,6 +9,7 @@ generic-y += errno.h generic-y += exec.h generic-y += fcntl.h generic-y += hardirq.h +generic-y += hash.h generic-y += ioctl.h generic-y += irq_regs.h generic-y += kdebug.h @@ -18,6 +19,7 @@ generic-y += linkage.h generic-y += local.h generic-y += local64.h generic-y += percpu.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -27,5 +29,3 @@ generic-y += termios.h generic-y += topology.h generic-y += trace_clock.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h -- cgit v1.2.3-55-g7522 From ddf1d169c0a489d498c1799a7043904a43b0c159 Mon Sep 17 00:00:00 2001 From: Tim Chen Date: Tue, 21 Jan 2014 15:36:22 -0800 Subject: locking/mcs: Allow architecture specific asm files to be used for contended case This patch allows each architecture to add its specific assembly optimized arch_mcs_spin_lock_contended and arch_mcs_spinlock_uncontended for MCS lock and unlock functions. Signed-off-by: Tim Chen Cc: Scott J Norton Cc: Raghavendra K T Cc: AswinChandramouleeswaran Cc: George Spelvin Cc: Rik vanRiel Cc: Andrea Arcangeli Cc: MichelLespinasse Cc: Peter Hurley Cc: Andi Kleen Cc: Alex Shi Cc: Dave Hansen Cc: Tim Chen Cc: Arnd Bergmann Cc: "Figo.zhang" Cc: "Paul E.McKenney" Cc: "H. Peter Anvin" Cc: Davidlohr Bueso Cc: Waiman Long Cc: Ingo Molnar Cc: Will Deacon Cc: Andrew Morton Cc: Linus Torvalds Cc: Matthew R Wilcox Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1390347382.3138.67.camel@schen9-DESK Signed-off-by: Ingo Molnar --- arch/alpha/include/asm/Kbuild | 1 + arch/arc/include/asm/Kbuild | 1 + arch/arm/include/asm/Kbuild | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/avr32/include/asm/Kbuild | 1 + arch/blackfin/include/asm/Kbuild | 1 + arch/c6x/include/asm/Kbuild | 1 + arch/cris/include/asm/Kbuild | 1 + arch/frv/include/asm/Kbuild | 1 + arch/hexagon/include/asm/Kbuild | 1 + arch/ia64/include/asm/Kbuild | 1 + arch/m32r/include/asm/Kbuild | 1 + arch/m68k/include/asm/Kbuild | 1 + arch/metag/include/asm/Kbuild | 1 + arch/microblaze/include/asm/Kbuild | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mn10300/include/asm/Kbuild | 1 + arch/openrisc/include/asm/Kbuild | 1 + arch/parisc/include/asm/Kbuild | 1 + arch/powerpc/include/asm/Kbuild | 1 + arch/s390/include/asm/Kbuild | 1 + arch/score/include/asm/Kbuild | 1 + arch/sh/include/asm/Kbuild | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/tile/include/asm/Kbuild | 1 + arch/um/include/asm/Kbuild | 1 + arch/unicore32/include/asm/Kbuild | 1 + arch/x86/include/asm/Kbuild | 1 + arch/xtensa/include/asm/Kbuild | 1 + include/asm-generic/mcs_spinlock.h | 13 +++++++++++++ include/linux/mcs_spinlock.h | 2 ++ 31 files changed, 44 insertions(+) create mode 100644 include/asm-generic/mcs_spinlock.h (limited to 'arch') diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index 55a2b0395d48..7736f426ff3b 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -3,5 +3,6 @@ generic-y += clkdev.h generic-y += exec.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 54ceb91c7ce0..e76fd79f32b0 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -22,6 +22,7 @@ generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h generic-y += param.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 3b2092049b51..23e728ecf8ab 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -14,6 +14,7 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += msgbuf.h generic-y += param.h generic-y += parport.h diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 54038befa0a4..3bdfdda70567 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -23,6 +23,7 @@ generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h generic-y += mutex.h diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 064ca3c058ff..8b398ff96974 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -11,6 +11,7 @@ generic-y += hash.h generic-y += irq_regs.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += param.h generic-y += percpu.h generic-y += preempt.h diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index ca30a3dc47e7..0d93b9a79ca9 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -20,6 +20,7 @@ generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h generic-y += mutex.h diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index dea0671524a1..8dbdce8421b0 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild @@ -25,6 +25,7 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += kmap_types.h generic-y += local.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += mmu.h generic-y += mmu_context.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 7f8d1b174a34..056027f38351 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -9,6 +9,7 @@ generic-y += exec.h generic-y += hash.h generic-y += kvm_para.h generic-y += linkage.h +generic-y += mcs_spinlock.h generic-y += module.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index 93428d035cfb..babb9338ebf8 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -2,5 +2,6 @@ generic-y += clkdev.h generic-y += exec.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 9f0eda48643a..eadcc118f950 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -27,6 +27,7 @@ generic-y += kdebug.h generic-y += kmap_types.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h generic-y += pci.h diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 81ebef7f1a87..0da4aa2602ae 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -3,6 +3,7 @@ generic-y += clkdev.h generic-y += exec.h generic-y += hash.h generic-y += kvm_para.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h generic-y += vtime.h diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index 87042215b543..5825a35b2c56 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -2,6 +2,7 @@ generic-y += clkdev.h generic-y += exec.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += module.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index f44ac8f9536a..86b4c178cc75 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -16,6 +16,7 @@ generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += mutex.h generic-y += percpu.h diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild index ac22144e92a3..c29ead89a317 100644 --- a/arch/metag/include/asm/Kbuild +++ b/arch/metag/include/asm/Kbuild @@ -24,6 +24,7 @@ generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += msgbuf.h generic-y += mutex.h generic-y += param.h diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 4b5f12259d81..1f590ab8f323 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,6 +3,7 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += exec.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += syscalls.h generic-y += trace_clock.h diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 82ee17a68ae0..05439187891d 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -4,6 +4,7 @@ generic-y += current.h generic-y += emergency-restart.h generic-y += hash.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mutex.h generic-y += parport.h generic-y += percpu.h diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index da3b2f50c07e..cbc6b9bf45da 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -3,5 +3,6 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += exec.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index f62a67a15055..480af0d9c2f5 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild @@ -35,6 +35,7 @@ generic-y += kdebug.h generic-y += kmap_types.h generic-y += kvm_para.h generic-y += local.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += module.h generic-y += msgbuf.h diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 958b79aac24f..ecf25e6678ad 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -14,6 +14,7 @@ generic-y += kdebug.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mutex.h generic-y += param.h generic-y += percpu.h diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index b618c416d3d9..3fb1bc432f4f 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += clkdev.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += rwsem.h generic-y += trace_clock.h diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 482f492f0834..57892a8a9055 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -2,5 +2,6 @@ generic-y += clkdev.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index e92319fb146d..4630cf217b5b 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -5,6 +5,7 @@ header-y += generic-y += barrier.h generic-y += clkdev.h generic-y += hash.h +generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += trace_clock.h generic-y += xor.h diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 85c214e456f9..c19e47dacb31 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -15,6 +15,7 @@ generic-y += irq_regs.h generic-y += kvm_para.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += msgbuf.h generic-y += param.h diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 82150287bfa4..a45821818003 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -11,6 +11,7 @@ generic-y += irq_regs.h generic-y += linkage.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += module.h generic-y += mutex.h generic-y += preempt.h diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index e0b1ed967737..0aa5675e7025 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -19,6 +19,7 @@ generic-y += ipcbuf.h generic-y += irq_regs.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += msgbuf.h generic-y += mutex.h generic-y += param.h diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 215e05d8d4b8..a5e4b6068213 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -15,6 +15,7 @@ generic-y += hw_irq.h generic-y += io.h generic-y += irq_regs.h generic-y += kdebug.h +generic-y += mcs_spinlock.h generic-y += mutex.h generic-y += param.h generic-y += pci.h diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index ad2c737a9cab..1e5fb872a4aa 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -25,6 +25,7 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += kmap_types.h generic-y += local.h +generic-y += mcs_spinlock.h generic-y += mman.h generic-y += module.h generic-y += msgbuf.h diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 7f669853317a..a8fee078b92f 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -5,3 +5,4 @@ genhdr-y += unistd_64.h genhdr-y += unistd_x32.h generic-y += clkdev.h +generic-y += mcs_spinlock.h diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 223280d8e611..c3d20ba6eb86 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -18,6 +18,7 @@ generic-y += kvm_para.h generic-y += linkage.h generic-y += local.h generic-y += local64.h +generic-y += mcs_spinlock.h generic-y += percpu.h generic-y += preempt.h generic-y += resource.h diff --git a/include/asm-generic/mcs_spinlock.h b/include/asm-generic/mcs_spinlock.h new file mode 100644 index 000000000000..10cd4ffc6ba2 --- /dev/null +++ b/include/asm-generic/mcs_spinlock.h @@ -0,0 +1,13 @@ +#ifndef __ASM_MCS_SPINLOCK_H +#define __ASM_MCS_SPINLOCK_H + +/* + * Architectures can define their own: + * + * arch_mcs_spin_lock_contended(l) + * arch_mcs_spin_unlock_contended(l) + * + * See kernel/locking/mcs_spinlock.c. + */ + +#endif /* __ASM_MCS_SPINLOCK_H */ diff --git a/include/linux/mcs_spinlock.h b/include/linux/mcs_spinlock.h index e9a4d74c63dc..f2a5c6360083 100644 --- a/include/linux/mcs_spinlock.h +++ b/include/linux/mcs_spinlock.h @@ -12,6 +12,8 @@ #ifndef __LINUX_MCS_SPINLOCK_H #define __LINUX_MCS_SPINLOCK_H +#include + struct mcs_spinlock { struct mcs_spinlock *next; int locked; /* 1 if lock acquired */ -- cgit v1.2.3-55-g7522 From a18b31dd537f51331b9cd357987a5e807bf3e8d1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 3 Feb 2014 10:35:35 +0100 Subject: m68k: Sort arch/m68k/include/asm/Kbuild Signed-off-by: Geert Uytterhoeven Acked-by: Greg Ungerer --- arch/m68k/include/asm/Kbuild | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 7cc8c364924d..df4d46fc321b 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -1,4 +1,3 @@ - generic-y += bitsperlong.h generic-y += clkdev.h generic-y += cputime.h @@ -6,6 +5,7 @@ generic-y += device.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ipcbuf.h @@ -18,6 +18,7 @@ generic-y += local.h generic-y += mman.h generic-y += mutex.h generic-y += percpu.h +generic-y += preempt.h generic-y += resource.h generic-y += scatterlist.h generic-y += sections.h @@ -31,5 +32,3 @@ generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h -generic-y += preempt.h -generic-y += hash.h -- cgit v1.2.3-55-g7522 From 3067bab1cb6e45063c602a731b9341651c4f2ddb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 3 Feb 2014 10:38:39 +0100 Subject: m68k: Switch to asm-generic/barrier.h The generic nop() implementation is fine for m68k. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Ungerer --- arch/m68k/include/asm/Kbuild | 1 + arch/m68k/include/asm/barrier.h | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 arch/m68k/include/asm/barrier.h (limited to 'arch') diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index df4d46fc321b..6fb9e813a910 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -1,3 +1,4 @@ +generic-y += barrier.h generic-y += bitsperlong.h generic-y += clkdev.h generic-y += cputime.h diff --git a/arch/m68k/include/asm/barrier.h b/arch/m68k/include/asm/barrier.h deleted file mode 100644 index 15c5f77c1614..000000000000 --- a/arch/m68k/include/asm/barrier.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _M68K_BARRIER_H -#define _M68K_BARRIER_H - -#define nop() do { asm volatile ("nop"); barrier(); } while (0) - -#include - -#endif /* _M68K_BARRIER_H */ -- cgit v1.2.3-55-g7522 From 7247f55381d54645a1eb47588de51bb26fa7cb7a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 3 Feb 2014 15:07:13 +0100 Subject: m68k: Wire up sched_setattr and sched_getattr Signed-off-by: Geert Uytterhoeven Acked-by: Greg Ungerer --- arch/m68k/include/asm/unistd.h | 2 +- arch/m68k/include/uapi/asm/unistd.h | 2 ++ arch/m68k/kernel/syscalltable.S | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 014f288fc813..9d38b73989eb 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 349 +#define NR_syscalls 351 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 625f321001dc..b932dd470041 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -354,5 +354,7 @@ #define __NR_process_vm_writev 346 #define __NR_kcmp 347 #define __NR_finit_module 348 +#define __NR_sched_setattr 349 +#define __NR_sched_getattr 350 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 3f04ea0ab802..b6223dc41d82 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -369,4 +369,6 @@ ENTRY(sys_call_table) .long sys_process_vm_writev .long sys_kcmp .long sys_finit_module + .long sys_sched_setattr + .long sys_sched_getattr /* 350 */ -- cgit v1.2.3-55-g7522 From 565bbdcd3b91523b4142587c00206302e091a23e Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Mon, 10 Feb 2014 14:07:35 -0500 Subject: ARM: keystone: dts: fix clkvcp3 control register address The address for control regs in clkvcp3 node is not correct and should be 0x023500a8 instead of 0x0235000a8. This lead to few unexpected behaviors while clocks were turned of in absence of clk_ignore_unused Mike Turquette Signed-off-by: Ivan Khoronzhuk Signed-off-by: Santosh Shilimkar --- arch/arm/boot/dts/keystone-clocks.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi index 2363593e1050..ef58d1c24313 100644 --- a/arch/arm/boot/dts/keystone-clocks.dtsi +++ b/arch/arm/boot/dts/keystone-clocks.dtsi @@ -612,7 +612,7 @@ clocks { compatible = "ti,keystone,psc-clock"; clocks = <&chipclk13>; clock-output-names = "vcp-3"; - reg = <0x0235000a8 0xb00>, <0x02350060 0x400>; + reg = <0x023500a8 0xb00>, <0x02350060 0x400>; reg-names = "control", "domain"; domain-id = <24>; }; -- cgit v1.2.3-55-g7522 From ad68cc7a777948b77f15a3dc3510918ff87ed0c0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jan 2014 12:45:09 -0500 Subject: sched/idle, ARM: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. Signed-off-by: Nicolas Pitre Acked-by: Daniel Lezcano Cc: Preeti U Murthy Cc: Paul Mundt Cc: "Rafael J. Wysocki" Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: Russell King Cc: linaro-kernel@lists.linaro.org Cc: Benjamin Herrenschmidt Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-y2nbw5j3ma5siy5584919z5i@git.kernel.org Signed-off-by: Ingo Molnar --- arch/arm/kernel/process.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 92f7b15dd221..adabeababeb0 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -133,7 +132,11 @@ EXPORT_SYMBOL_GPL(arm_pm_restart); void (*arm_pm_idle)(void); -static void default_idle(void) +/* + * Called from the core idle loop. + */ + +void arch_cpu_idle(void) { if (arm_pm_idle) arm_pm_idle(); @@ -167,15 +170,6 @@ void arch_cpu_idle_dead(void) } #endif -/* - * Called from the core idle loop. - */ -void arch_cpu_idle(void) -{ - if (cpuidle_idle_call()) - default_idle(); -} - /* * Called by kexec, immediately prior to machine_kexec(). * -- cgit v1.2.3-55-g7522 From d8c6ad3184ca6516a5cf457af1afaa293d8f09c0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jan 2014 12:45:10 -0500 Subject: sched/idle, PPC: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. However a few things need checking: - Invocation of cpuidle_idle_call() in pseries_lpar_idle() happened through arch_cpu_idle() and was therefore always preceded by a call to ppc64_runlatch_off(). To preserve this property now that cpuidle_idle_call() is invoked directly from core code, a call to ppc64_runlatch_off() has been added to idle_loop_prolog() in platforms/pseries/processor_idle.c. - Similarly, cpuidle_idle_call() was followed by ppc64_runlatch_off() so a call to the later has been added to idle_loop_epilog(). - And since arch_cpu_idle() always made sure to re-enable IRQs if they were not enabled, this is now done in idle_loop_epilog() as well. The above was made in order to keep the execution flow close to the original. I don't know if that was strictly necessary. Someone well aquainted with the platform details might find some room for possible optimizations. Signed-off-by: Nicolas Pitre Reviewed-by: Preeti U Murthy Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: Russell King Cc: linaro-kernel@lists.linaro.org Cc: Benjamin Herrenschmidt Cc: Paul Mundt Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-47o4m03citrfg9y1vxic5asb@git.kernel.org Signed-off-by: Ingo Molnar --- arch/powerpc/platforms/pseries/setup.c | 34 ++++++++++++++-------------------- drivers/cpuidle/cpuidle-pseries.c | 5 +++++ 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8e639d7cbda7..c737d554571a 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -356,29 +355,24 @@ early_initcall(alloc_dispatch_log_kmem_cache); static void pseries_lpar_idle(void) { - /* This would call on the cpuidle framework, and the back-end pseries - * driver to go to idle states + /* + * Default handler to go into low thread priority and possibly + * low power mode by cedeing processor to hypervisor */ - if (cpuidle_idle_call()) { - /* On error, execute default handler - * to go into low thread priority and possibly - * low power mode by cedeing processor to hypervisor - */ - /* Indicate to hypervisor that we are idle. */ - get_lppaca()->idle = 1; + /* Indicate to hypervisor that we are idle. */ + get_lppaca()->idle = 1; - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - */ - cede_processor(); + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + */ + cede_processor(); - get_lppaca()->idle = 0; - } + get_lppaca()->idle = 0; } /* diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index 7ab564aa0b1c..d4864892951b 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -29,6 +29,7 @@ static struct cpuidle_state *cpuidle_state_table; static inline void idle_loop_prolog(unsigned long *in_purr) { + ppc64_runlatch_off(); *in_purr = mfspr(SPRN_PURR); /* * Indicate to the HV that we are idle. Now would be @@ -45,6 +46,10 @@ static inline void idle_loop_epilog(unsigned long in_purr) wait_cycles += mfspr(SPRN_PURR) - in_purr; get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles); get_lppaca()->idle = 0; + + if (irqs_disabled()) + local_irq_enable(); + ppc64_runlatch_on(); } static int snooze_loop(struct cpuidle_device *dev, -- cgit v1.2.3-55-g7522 From f0c5cdb5cf89e56bdef9d71da89d4966dea6ef71 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jan 2014 12:45:11 -0500 Subject: sched/idle, SH: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. Signed-off-by: Nicolas Pitre Acked-by: Daniel Lezcano Cc: Preeti U Murthy Cc: Paul Mundt Cc: "Rafael J. Wysocki" Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: Russell King Cc: linaro-kernel@lists.linaro.org Cc: Benjamin Herrenschmidt Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-v2c3oswyd80xk2vh7fwmu6r8@git.kernel.org Signed-off-by: Ingo Molnar --- arch/sh/kernel/idle.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 2ea4483fd722..be616ee0cf87 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,7 @@ void arch_cpu_idle_dead(void) void arch_cpu_idle(void) { - if (cpuidle_idle_call()) - sh_idle(); + sh_idle(); } void __init select_idle_routine(void) -- cgit v1.2.3-55-g7522 From 16f8b05abe33575b5fc0833cab1286bd6227f255 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jan 2014 12:45:12 -0500 Subject: sched/idle, x86: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. Signed-off-by: Nicolas Pitre Acked-by: Daniel Lezcano Cc: Preeti U Murthy Cc: Paul Mundt Cc: "Rafael J. Wysocki" Cc: linux-arm-kernel@lists.infradead.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org Cc: linux-pm@vger.kernel.org Cc: Russell King Cc: linaro-kernel@lists.linaro.org Cc: Benjamin Herrenschmidt Cc: Linus Torvalds Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-3ioazimg4j5iq6kdefks04i8@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/process.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 3fb8d95ab8b5..4505e2a950d8 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -298,10 +298,7 @@ void arch_cpu_idle_dead(void) */ void arch_cpu_idle(void) { - if (cpuidle_idle_call()) - x86_idle(); - else - local_irq_enable(); + x86_idle(); } /* -- cgit v1.2.3-55-g7522 From 74b8af7837fa55c020e2ad1b34a6b10dfe25a9b1 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 11 Feb 2014 14:05:17 +0800 Subject: powerpc/spufs: Remove MAX_USER_PRIO define Current ppc64_defconfig fails with: arch/powerpc/platforms/cell/spufs/sched.c:86:0: error: "MAX_USER_PRIO" redefined [-Werror] cc1: all warnings being treated as errors Commit 6b6350f155af ("sched: Expose some macros related to priority") introduced a generic MAX_USER_PRIO macro to sched/prio.h, which is causing the conflit. Use that one instead of our own. Reported-by: Fengguang Wu Reported-by: Stephen Rothwell Signed-off-by: Jeremy Kerr Cc: Dongsheng Yang Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/1392098717.689604.970589769393.1.gpush@pablo Signed-off-by: Ingo Molnar --- arch/powerpc/platforms/cell/spufs/sched.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 49318385d4fa..4a0a64fe25df 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -83,7 +83,6 @@ static struct timer_list spuloadavg_timer; #define MIN_SPU_TIMESLICE max(5 * HZ / (1000 * SPUSCHED_TICK), 1) #define DEF_SPU_TIMESLICE (100 * HZ / (1000 * SPUSCHED_TICK)) -#define MAX_USER_PRIO (MAX_PRIO - MAX_RT_PRIO) #define SCALE_PRIO(x, prio) \ max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_SPU_TIMESLICE) -- cgit v1.2.3-55-g7522 From 40747ffa5aa8d5b99ca46c696234b9194b59e0ac Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 8 Feb 2014 08:51:59 +0100 Subject: asmlinkage: Make jiffies visible Jiffies is referenced by the linker script, so it has to be visible. Handled both the generic and the x86 version. Signed-off-by: Andi Kleen Link: http://lkml.kernel.org/r/1391845930-28580-3-git-send-email-ak@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/time.c | 2 +- kernel/timer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index 24d3c91e9812..6ec91c00d84d 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -23,7 +23,7 @@ #include #ifdef CONFIG_X86_64 -DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES; +__visible DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES; #endif unsigned long profile_pc(struct pt_regs *regs) diff --git a/kernel/timer.c b/kernel/timer.c index accfd241b9e5..d78de047599b 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -52,7 +52,7 @@ #define CREATE_TRACE_POINTS #include -u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; +__visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; EXPORT_SYMBOL(jiffies_64); -- cgit v1.2.3-55-g7522 From a9143296dd612dceb0765229ccfb13fd642e2840 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 8 Feb 2014 08:52:07 +0100 Subject: asmlinkage, x86: Fix 32bit memcpy for LTO These functions can be called implicitely from gcc, and thus need to be visible. Signed-off-by: Andi Kleen Link: http://lkml.kernel.org/r/1391845930-28580-11-git-send-email-ak@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/lib/memcpy_32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c index e78761d6b7f8..a404b4b75533 100644 --- a/arch/x86/lib/memcpy_32.c +++ b/arch/x86/lib/memcpy_32.c @@ -4,7 +4,7 @@ #undef memcpy #undef memset -void *memcpy(void *to, const void *from, size_t n) +__visible void *memcpy(void *to, const void *from, size_t n) { #ifdef CONFIG_X86_USE_3DNOW return __memcpy3d(to, from, n); @@ -14,13 +14,13 @@ void *memcpy(void *to, const void *from, size_t n) } EXPORT_SYMBOL(memcpy); -void *memset(void *s, int c, size_t count) +__visible void *memset(void *s, int c, size_t count) { return __memset(s, c, count); } EXPORT_SYMBOL(memset); -void *memmove(void *dest, const void *src, size_t n) +__visible void *memmove(void *dest, const void *src, size_t n) { int d0,d1,d2,d3,d4,d5; char *ret = dest; -- cgit v1.2.3-55-g7522 From 634676c203f130c8efa138296c2efba219821346 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 8 Feb 2014 08:52:10 +0100 Subject: initconst, x86: Fix initconst mistake in ts5500 code const data must be initconst. Signed-off-by: Andi Kleen Link: http://lkml.kernel.org/r/1391845930-28580-14-git-send-email-ak@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/platform/ts5500/ts5500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/platform/ts5500/ts5500.c b/arch/x86/platform/ts5500/ts5500.c index 39febb214e8c..9471b9456f25 100644 --- a/arch/x86/platform/ts5500/ts5500.c +++ b/arch/x86/platform/ts5500/ts5500.c @@ -88,7 +88,7 @@ struct ts5500_sbc { static const struct { const char * const string; const ssize_t offset; -} ts5500_signatures[] __initdata = { +} ts5500_signatures[] __initconst = { { "TS-5x00 AMD Elan", 0xb14 }, }; -- cgit v1.2.3-55-g7522 From 67424d5a22124fa2d115faa8f32d12506989628f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 8 Feb 2014 09:01:05 +0100 Subject: x86, lto: Disable LTO for the x86 VDSO The VDSO does not play well with LTO, so just disable LTO for it. Also pass a 32bit linker flag for the 32bit version. [ hpa: change braces to parens to match kernel Makefile style ] Signed-off-by: Andi Kleen Link: http://lkml.kernel.org/r/1391846481-31491-1-git-send-email-ak@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/vdso/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index fd14be1d1472..9206ac7961a5 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -2,6 +2,8 @@ # Building vDSO images for x86. # +KBUILD_CFLAGS += $(DISABLE_LTO) + VDSO64-$(CONFIG_X86_64) := y VDSOX32-$(CONFIG_X86_X32_ABI) := y VDSO32-$(CONFIG_X86_32) := y @@ -35,7 +37,8 @@ export CPPFLAGS_vdso.lds += -P -C VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ -Wl,--no-undefined \ - -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 + -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \ + $(DISABLE_LTO) $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so @@ -127,7 +130,7 @@ vdso32.so-$(VDSO32-y) += sysenter vdso32-images = $(vdso32.so-y:%=vdso32-%.so) CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) -VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1 +VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1 # This makes sure the $(obj) subdirectory exists even though vdso32/ # is not a kbuild sub-make subdirectory. @@ -181,7 +184,8 @@ quiet_cmd_vdso = VDSO $@ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' -VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) +VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \ + $(LTO_CFLAGS) GCOV_PROFILE := n # -- cgit v1.2.3-55-g7522 From e306dfd06fcb44d21c80acb8e5a88d55f3d1cf63 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 14 Feb 2014 19:35:15 +0000 Subject: ARM64: unwind: Fix PC calculation The frame PC value in the unwind code used to just take the saved LR value and use that. That's incorrect as a stack trace, since it shows the return path stack, not the call path stack. In particular, it shows faulty information in case the bl is done as the very last instruction of one label, since the return point will be in the next label. That can easily be seen with tail calls to panic(), which is marked __noreturn and thus doesn't have anything useful after it. Easiest here is to just correct the unwind code and do a -4, to get the actual call site for the backtrace instead of the return site. Signed-off-by: Olof Johansson Cc: stable@vger.kernel.org Signed-off-by: Catalin Marinas --- arch/arm64/kernel/stacktrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index c3b6c63ea5fb..38f0558f0c0a 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -48,7 +48,11 @@ int unwind_frame(struct stackframe *frame) frame->sp = fp + 0x10; frame->fp = *(unsigned long *)(fp); - frame->pc = *(unsigned long *)(fp + 8); + /* + * -4 here because we care about the PC at time of bl, + * not where the return will go. + */ + frame->pc = *(unsigned long *)(fp + 8) - 4; return 0; } -- cgit v1.2.3-55-g7522 From cd91b2fecfa66967e6ad732a9af860eb96c31ba4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 14 Feb 2014 20:19:03 +0100 Subject: ARM: 7963/1: mm: report both sections from PMD On 2-level page table systems, the PMD has 2 section entries. Report these, otherwise ARM_PTDUMP will miss reporting permission changes on odd section boundaries. Signed-off-by: Kees Cook Acked-by: Catalin Marinas Tested-by: Steve Capper Signed-off-by: Russell King --- arch/arm/mm/dump.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index 2b3a56414271..ef69152f9b52 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -264,6 +264,9 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) note_page(st, addr, 3, pmd_val(*pmd)); else walk_pte(st, pmd, addr); + + if (SECTION_SIZE < PMD_SIZE && pmd_large(pmd[1])) + note_page(st, addr + SECTION_SIZE, 3, pmd_val(pmd[1])); } } -- cgit v1.2.3-55-g7522 From 18ba7b9d5fd6eb2c2c510dfcfc6e8fee56c42571 Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Sun, 16 Feb 2014 18:15:44 -0500 Subject: ARM: OMAP5: PRM: Fix reboot handling Use the correct register offset for issuing the reset command in OMAP5. Since dev_inst is set dynamically OMAP4 should not be affected by this change. Signed-off-by: Vaibhav Bedia Tested-by: Lokesh Vutla Acked-by: Rajendra Nayak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/prminst44xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index 6334b96b4097..280f3c58abe5 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -183,11 +183,11 @@ void omap4_prminst_global_warm_sw_reset(void) OMAP4_PRM_RSTCTRL_OFFSET); v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, - OMAP4430_PRM_DEVICE_INST, + dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, - OMAP4430_PRM_DEVICE_INST, + dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); } -- cgit v1.2.3-55-g7522 From c317d0f241fa0bbb098aa35f3d4b3067be2b5f3d Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 10 Jan 2014 17:43:08 -0600 Subject: ARM: DRA7: hwmod data: correct the sysc data for spinlock The spinlock module's SYSCONFIG register on DRA7xx does not support smart wakeup, and also does not have the CLKACTIVITY field. The sysc data for spinlock module has been appropriately fixed up to reflect the same. Cc: Ambresh K Signed-off-by: Suman Anna Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 18f333c440db..810c205d668b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -1365,11 +1365,10 @@ static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | - SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, }; -- cgit v1.2.3-55-g7522 From 01142519ffc0734436f26b01aeed37a915dece05 Mon Sep 17 00:00:00 2001 From: Illia Smyrnov Date: Wed, 5 Feb 2014 17:06:09 +0200 Subject: ARM: OMAP4: hwmod: Fix SOFTRESET logic for OMAP4 Commit 313a76e (ARM: OMAP2+: hwmod: Fix SOFTRESET logic) introduced softreset bit cleaning right after set one. It is caused L3 error for OMAP4 ISS because ISS register write occurs when ISS reset process is in progress. Avoid this situation by cleaning softreset bit later, when reset process is successfully finished. Signed-off-by: Illia Smyrnov Reviewed-by: Grygorii Strashko Acked-by: Roger Quadros Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 42d81885c700..1f33f5db10d5 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1946,30 +1946,32 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (ret) goto dis_opt_clks; - _write_sysconfig(v, oh); - ret = _clear_softreset(oh, &v); - if (ret) - goto dis_opt_clks; - _write_sysconfig(v, oh); if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); c = _wait_softreset_complete(oh); - if (c == MAX_MODULE_SOFTRESET_WAIT) + if (c == MAX_MODULE_SOFTRESET_WAIT) { pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); - else + ret = -ETIMEDOUT; + goto dis_opt_clks; + } else { pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c); + } + + ret = _clear_softreset(oh, &v); + if (ret) + goto dis_opt_clks; + + _write_sysconfig(v, oh); /* * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from * _wait_target_ready() or _reset() */ - ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; - dis_opt_clks: if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) _disable_optional_clocks(oh); -- cgit v1.2.3-55-g7522 From 994c41ee0ac875797b4dfef509ac7753e2649b4d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 30 Jan 2014 13:17:20 +0200 Subject: ARM: OMAP2+: clock: fix clkoutx2 with CLK_SET_RATE_PARENT If CLK_SET_RATE_PARENT is set for a clkoutx2 clock, calling clk_set_rate() on the clock "skips" the x2 multiplier as there are no set_rate and round_rate functions defined for the clkoutx2. This results in getting double the requested clock rates, breaking the display on omap3430 based devices. This got broken when d0f58bd3bba3877fb1af4664c4e33273d36f00e4 and related patches were merged for v3.14, as omapdss driver now relies more on the clk-framework and CLK_SET_RATE_PARENT. This patch implements set_rate and round_rate for clkoutx2. Tested on OMAP3430, OMAP3630, OMAP4460. Signed-off-by: Tomi Valkeinen Acked-by: Tero Kristo Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cclock3xxx_data.c | 2 + arch/arm/mach-omap2/dpll3xxx.c | 92 +++++++++++++++++++++++++++++------ include/linux/clk/ti.h | 4 ++ 3 files changed, 83 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index 3b05aea56d1f..11ed9152e665 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -433,7 +433,9 @@ static const struct clk_ops dpll4_m5x2_ck_ops = { .enable = &omap2_dflt_clk_enable, .disable = &omap2_dflt_clk_disable, .is_enabled = &omap2_dflt_clk_is_enabled, + .set_rate = &omap3_clkoutx2_set_rate, .recalc_rate = &omap3_clkoutx2_recalc, + .round_rate = &omap3_clkoutx2_round_rate, }; static const struct clk_ops dpll4_m5x2_ck_3630_ops = { diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index 3185ced807c9..3c418ea54bbe 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -623,6 +623,32 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk) /* Clock control for DPLL outputs */ +/* Find the parent DPLL for the given clkoutx2 clock */ +static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw) +{ + struct clk_hw_omap *pclk = NULL; + struct clk *parent; + + /* Walk up the parents of clk, looking for a DPLL */ + do { + do { + parent = __clk_get_parent(hw->clk); + hw = __clk_get_hw(parent); + } while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC)); + if (!hw) + break; + pclk = to_clk_hw_omap(hw); + } while (pclk && !pclk->dpll_data); + + /* clk does not have a DPLL as a parent? error in the clock data */ + if (!pclk) { + WARN_ON(1); + return NULL; + } + + return pclk; +} + /** * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * @clk: DPLL output struct clk @@ -637,27 +663,14 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long rate; u32 v; struct clk_hw_omap *pclk = NULL; - struct clk *parent; if (!parent_rate) return 0; - /* Walk up the parents of clk, looking for a DPLL */ - do { - do { - parent = __clk_get_parent(hw->clk); - hw = __clk_get_hw(parent); - } while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC)); - if (!hw) - break; - pclk = to_clk_hw_omap(hw); - } while (pclk && !pclk->dpll_data); + pclk = omap3_find_clkoutx2_dpll(hw); - /* clk does not have a DPLL as a parent? error in the clock data */ - if (!pclk) { - WARN_ON(1); + if (!pclk) return 0; - } dd = pclk->dpll_data; @@ -672,6 +685,55 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, return rate; } +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + const struct dpll_data *dd; + u32 v; + struct clk_hw_omap *pclk = NULL; + + if (!*prate) + return 0; + + pclk = omap3_find_clkoutx2_dpll(hw); + + if (!pclk) + return 0; + + dd = pclk->dpll_data; + + /* TYPE J does not have a clkoutx2 */ + if (dd->flags & DPLL_J_TYPE) { + *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate); + return *prate; + } + + WARN_ON(!dd->enable_mask); + + v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask; + v >>= __ffs(dd->enable_mask); + + /* If in bypass, the rate is fixed to the bypass rate*/ + if (v != OMAP3XXX_EN_DPLL_LOCKED) + return *prate; + + if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) { + unsigned long best_parent; + + best_parent = (rate / 2); + *prate = __clk_round_rate(__clk_get_parent(hw->clk), + best_parent); + } + + return *prate * 2; +} + /* OMAP3/4 non-CORE DPLL clkops */ const struct clk_hw_omap_ops clkhwops_omap3_dpll = { .allow_idle = omap3_dpll_allow_idle, diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 092b64168d7f..4a21a872dbbd 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -245,6 +245,10 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, void omap2_init_clk_clkdm(struct clk_hw *clk); unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, unsigned long parent_rate); +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate); +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate); int omap2_clkops_enable_clkdm(struct clk_hw *hw); void omap2_clkops_disable_clkdm(struct clk_hw *hw); int omap2_clk_disable_autoidle_all(void); -- cgit v1.2.3-55-g7522 From 8e5780fdeef7dc490b3f0b3a62704593721fa4f3 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Thu, 20 Feb 2014 13:24:50 -0800 Subject: x86, AVX-512: AVX-512 Feature Detection AVX-512 is an extention of AVX2. Its spec can be found at: http://download-software.intel.com/sites/default/files/managed/71/2e/319433-017.pdf This patch detects AVX-512 features by CPUID. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1392931491-33237-1-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin Cc: # hw enabling --- arch/x86/include/asm/cpufeature.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index e099f9502ace..5f1296872aed 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -217,9 +217,13 @@ #define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */ #define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */ #define X86_FEATURE_MPX (9*32+14) /* Memory Protection Extension */ +#define X86_FEATURE_AVX512F (9*32+16) /* AVX-512 Foundation */ #define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */ #define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ #define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */ +#define X86_FEATURE_AVX512PF (9*32+26) /* AVX-512 Prefetch */ +#define X86_FEATURE_AVX512ER (9*32+27) /* AVX-512 Exponential and Reciprocal */ +#define X86_FEATURE_AVX512CD (9*32+28) /* AVX-512 Conflict Detection */ /* * BUG word(s) -- cgit v1.2.3-55-g7522 From c2bc11f10a39527cd1bb252097b5525664560956 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Thu, 20 Feb 2014 13:24:51 -0800 Subject: x86, AVX-512: Enable AVX-512 States Context Switch This patch enables Opmask, ZMM_Hi256, and Hi16_ZMM AVX-512 states for xstate context switch. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1392931491-33237-2-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin Cc: # hw enabling --- arch/x86/include/asm/xsave.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 554738963b28..6c1d7411eb00 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -6,11 +6,14 @@ #define XSTATE_CPUID 0x0000000d -#define XSTATE_FP 0x1 -#define XSTATE_SSE 0x2 -#define XSTATE_YMM 0x4 -#define XSTATE_BNDREGS 0x8 -#define XSTATE_BNDCSR 0x10 +#define XSTATE_FP 0x1 +#define XSTATE_SSE 0x2 +#define XSTATE_YMM 0x4 +#define XSTATE_BNDREGS 0x8 +#define XSTATE_BNDCSR 0x10 +#define XSTATE_OPMASK 0x20 +#define XSTATE_ZMM_Hi256 0x40 +#define XSTATE_Hi16_ZMM 0x80 #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) @@ -23,7 +26,8 @@ #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) /* Supported features which support lazy state saving */ -#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) +#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ + | XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) /* Supported features which require eager state saving */ #define XSTATE_EAGER (XSTATE_BNDREGS | XSTATE_BNDCSR) -- cgit v1.2.3-55-g7522 From 896dc5064083063981954f142e43548765199792 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Mon, 20 Jan 2014 10:31:54 +0800 Subject: x86, acpi: Fix bug in associating hot-added CPUs with corresponding NUMA node Current ACPI cpu hotplug driver fails to associate hot-added CPUs with corresponding NUMA node when doing socket online. The code path to associate CPU with NUMA node is as below: acpi_processor_add() ->acpi_processor_get_info() ->acpi_processor_hotadd_init() ->acpi_map_lsapic() ->_acpi_map_lsapic() ->acpi_map_cpu2node() cpu_subsys_online() ->try_online_node() ->node_set_online() When doing socket online, a new NUMA node is introduced in addition to hot-added CPU and memory device. And the new NUMA node is marked as online when onlining hot-added CPUs through sysfs interface /sys/devices/system/cpu/cpuxx/online. On the other hand, acpi_map_cpu2node() will only build the CPU to node map if corresponding NUMA node is already online, so it always fails to associate hot-added CPUs with corresponding NUMA node because the NUMA node is still in offline state. For the fix, we could safely remove the "node_online(node)" check in function acpi_map_cpu2node() because it's only called for hot-added CPUs by acpi_processor_hotadd_init(). Signed-off-by: Jiang Liu Link: http://lkml.kernel.org/r/1390185115-26850-1-git-send-email-jiang.liu@linux.intel.com Acked-by: Rafael J. Wysocki Signed-off-by: H. Peter Anvin --- arch/x86/kernel/acpi/boot.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 1dac94265b59..9f46f2b1cfc2 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -613,10 +613,10 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) int nid; nid = acpi_get_node(handle); - if (nid == -1 || !node_online(nid)) - return; - set_apicid_to_node(physid, nid); - numa_set_node(cpu, nid); + if (nid != -1) { + set_apicid_to_node(physid, nid); + numa_set_node(cpu, nid); + } #endif } -- cgit v1.2.3-55-g7522 From 423edb6fce67133d4524513954af943a75bb6ef5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Feb 2014 13:15:28 +0100 Subject: s390/compat: fix sys_sched_getattr compat wrapper Fix stupid typo. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_wrapper.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 59c8efce1b99..0248949a756d 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1421,5 +1421,5 @@ ENTRY(sys_sched_setattr_wrapper) ENTRY(sys_sched_getattr_wrapper) lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # const char __user * - llgfr %r3,%r3 # unsigned int + llgfr %r4,%r4 # unsigned int jg sys_sched_getattr -- cgit v1.2.3-55-g7522 From 5ec6d4918a45952e99b1b36c93372d79d6927c57 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 18 Feb 2014 19:47:17 +0100 Subject: s390/pci/dma: use correct segment boundary size The boundary size for iommu_area_alloc() is currently set to a constant value. This is wrong, we shouldn't use a constant value but rather the return value of dma_get_seg_boundary(), since a device driver can override the default. Reviewed-by: Sebastian Ott Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/pci/pci_dma.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 60c11a629d96..f91c03119804 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -206,11 +206,13 @@ static void dma_cleanup_tables(struct zpci_dev *zdev) zdev->dma_table = NULL; } -static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, unsigned long start, - int size) +static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, + unsigned long start, int size) { - unsigned long boundary_size = 0x1000000; + unsigned long boundary_size; + boundary_size = ALIGN(dma_get_seg_boundary(&zdev->pdev->dev) + 1, + PAGE_SIZE) >> PAGE_SHIFT; return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, start, size, 0, boundary_size, 0); } -- cgit v1.2.3-55-g7522 From 2253e8d79237c69086ded391e6767afe16972527 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 27 Jan 2014 13:26:10 +0100 Subject: s390/cio: fix driver callback initialization for ccw consoles ccw consoles are in use before they can be properly registered with the driver core. For devices which are in use by a device driver we rely on the ccw_device's pointer to the driver callbacks to be valid. For ccw consoles this pointer is NULL until they are registered later during boot and we dereferenced this pointer. This worked by chance on 64 bit builds (cdev->drv was NULL but the optional callback cdev->drv->path_event was also NULL by coincidence) and was unnoticed until we received reports about boot failures on 31 bit systems. Fix it by initializing the driver pointer for ccw consoles. Cc: # 3.10+ Reported-by: Mike Frysinger Reported-by: Heiko Carstens Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ccwdev.h | 2 +- drivers/s390/char/con3215.c | 2 +- drivers/s390/char/con3270.c | 6 +----- drivers/s390/char/raw3270.c | 10 +++++++++- drivers/s390/char/raw3270.h | 2 +- drivers/s390/cio/device.c | 3 ++- 6 files changed, 15 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index f201af8be580..31b5ca8f8c3d 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -219,7 +219,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define to_ccwdev(n) container_of(n, struct ccw_device, dev) #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) -extern struct ccw_device *ccw_device_probe_console(void); +extern struct ccw_device *ccw_device_probe_console(struct ccw_driver *); extern void ccw_device_wait_idle(struct ccw_device *); extern int ccw_device_force_console(struct ccw_device *); diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index eb5d22795c47..bb86494e2b7b 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -922,7 +922,7 @@ static int __init con3215_init(void) raw3215_freelist = req; } - cdev = ccw_device_probe_console(); + cdev = ccw_device_probe_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 699fd3e363df..bb6b0df50b33 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -576,7 +576,6 @@ static struct console con3270 = { static int __init con3270_init(void) { - struct ccw_device *cdev; struct raw3270 *rp; void *cbuf; int i; @@ -591,10 +590,7 @@ con3270_init(void) cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } - cdev = ccw_device_probe_console(); - if (IS_ERR(cdev)) - return -ENODEV; - rp = raw3270_setup_console(cdev); + rp = raw3270_setup_console(); if (IS_ERR(rp)) return PTR_ERR(rp); diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 2cdec21e8924..de2c0483949f 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -776,16 +776,24 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) } #ifdef CONFIG_TN3270_CONSOLE +/* Tentative definition - see below for actual definition. */ +static struct ccw_driver raw3270_ccw_driver; + /* * Setup 3270 device configured as console. */ -struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) +struct raw3270 __init *raw3270_setup_console(void) { + struct ccw_device *cdev; unsigned long flags; struct raw3270 *rp; char *ascebc; int rc; + cdev = ccw_device_probe_console(&raw3270_ccw_driver); + if (IS_ERR(cdev)) + return ERR_CAST(cdev); + rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); ascebc = kzalloc(256, GFP_KERNEL); rc = raw3270_setup_device(cdev, rp, ascebc); diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h index 7b73ff8c1bd7..359276a88396 100644 --- a/drivers/s390/char/raw3270.h +++ b/drivers/s390/char/raw3270.h @@ -190,7 +190,7 @@ raw3270_put_view(struct raw3270_view *view) wake_up(&raw3270_wait_queue); } -struct raw3270 *raw3270_setup_console(struct ccw_device *cdev); +struct raw3270 *raw3270_setup_console(void); void raw3270_wait_cons_dev(struct raw3270 *); /* Notifier for device addition/removal */ diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e9d783563cbb..4283dd3cdd49 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1609,7 +1609,7 @@ out_unlock: return rc; } -struct ccw_device *ccw_device_probe_console(void) +struct ccw_device *ccw_device_probe_console(struct ccw_driver *drv) { struct io_subchannel_private *io_priv; struct ccw_device *cdev; @@ -1631,6 +1631,7 @@ struct ccw_device *ccw_device_probe_console(void) kfree(io_priv); return cdev; } + cdev->drv = drv; set_io_private(sch, io_priv); ret = ccw_device_console_enable(cdev, sch); if (ret) { -- cgit v1.2.3-55-g7522 From 1e5320960510d6d6f2cbdc7ed33df9791283b7ea Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 27 Jan 2014 13:28:10 +0100 Subject: s390/cio: reorder initialization of ccw consoles Drivers for ccw consoles use ccw_device_probe_console to receive an initialized ccw device which is already enabled for interrupts. After that the device driver does the initialization of its private data. This can race with unsolicited interrupts which can happen once the device is enabled for interrupts. Split ccw_device_probe_console into ccw_device_create_console and ccw_device_enable_console and reorder the initialization of the ccw console drivers. While at it mark these functions as __init. Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ccwdev.h | 4 +++- drivers/s390/char/con3215.c | 8 +++++++- drivers/s390/char/raw3270.c | 9 ++++++++- drivers/s390/cio/device.c | 29 +++++++++++++++++------------ 4 files changed, 35 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index 31b5ca8f8c3d..a9c2c0686177 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -219,7 +219,9 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define to_ccwdev(n) container_of(n, struct ccw_device, dev) #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) -extern struct ccw_device *ccw_device_probe_console(struct ccw_driver *); +extern struct ccw_device *ccw_device_create_console(struct ccw_driver *); +extern void ccw_device_destroy_console(struct ccw_device *); +extern int ccw_device_enable_console(struct ccw_device *); extern void ccw_device_wait_idle(struct ccw_device *); extern int ccw_device_force_console(struct ccw_device *); diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index bb86494e2b7b..5af7f0bd6125 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -922,7 +922,7 @@ static int __init con3215_init(void) raw3215_freelist = req; } - cdev = ccw_device_probe_console(&raw3215_ccw_driver); + cdev = ccw_device_create_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; @@ -932,6 +932,12 @@ static int __init con3215_init(void) cdev->handler = raw3215_irq; raw->flags |= RAW3215_FIXED; + if (ccw_device_enable_console(cdev)) { + ccw_device_destroy_console(cdev); + raw3215_free_info(raw); + raw3215[0] = NULL; + return -ENODEV; + } /* Request the console irq */ if (raw3215_startup(raw) != 0) { diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index de2c0483949f..041c65bc7bb1 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -790,7 +790,7 @@ struct raw3270 __init *raw3270_setup_console(void) char *ascebc; int rc; - cdev = ccw_device_probe_console(&raw3270_ccw_driver); + cdev = ccw_device_create_console(&raw3270_ccw_driver); if (IS_ERR(cdev)) return ERR_CAST(cdev); @@ -800,6 +800,13 @@ struct raw3270 __init *raw3270_setup_console(void) if (rc) return ERR_PTR(rc); set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags); + + rc = ccw_device_enable_console(cdev); + if (rc) { + ccw_device_destroy_console(cdev); + return ERR_PTR(rc); + } + spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); do { __raw3270_reset_device(rp); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 4283dd3cdd49..da431992fd8e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1572,11 +1572,14 @@ out: } #ifdef CONFIG_CCW_CONSOLE -static int ccw_device_console_enable(struct ccw_device *cdev, - struct subchannel *sch) +int __init ccw_device_enable_console(struct ccw_device *cdev) { + struct subchannel *sch = to_subchannel(cdev->dev.parent); int rc; + if (!cdev->drv || !cdev->handler) + return -EINVAL; + io_subchannel_init_fields(sch); rc = cio_commit_config(sch); if (rc) @@ -1609,12 +1612,11 @@ out_unlock: return rc; } -struct ccw_device *ccw_device_probe_console(struct ccw_driver *drv) +struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) { struct io_subchannel_private *io_priv; struct ccw_device *cdev; struct subchannel *sch; - int ret; sch = cio_probe_console(); if (IS_ERR(sch)) @@ -1633,17 +1635,20 @@ struct ccw_device *ccw_device_probe_console(struct ccw_driver *drv) } cdev->drv = drv; set_io_private(sch, io_priv); - ret = ccw_device_console_enable(cdev, sch); - if (ret) { - set_io_private(sch, NULL); - put_device(&sch->dev); - put_device(&cdev->dev); - kfree(io_priv); - return ERR_PTR(ret); - } return cdev; } +void __init ccw_device_destroy_console(struct ccw_device *cdev) +{ + struct subchannel *sch = to_subchannel(cdev->dev.parent); + struct io_subchannel_private *io_priv = to_io_private(sch); + + set_io_private(sch, NULL); + put_device(&sch->dev); + put_device(&cdev->dev); + kfree(io_priv); +} + /** * ccw_device_wait_idle() - busy wait for device to become idle * @cdev: ccw device -- cgit v1.2.3-55-g7522 From cfa785e623577cdad2aa721acb23bd3a95eced9a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 22 Jan 2014 14:49:30 +0100 Subject: s390/uaccess: normalize order of parameters of indirect uaccess function calls For some unknown reason the indirect uaccess functions on s390 implement a different parameter order than what is usual. e.g.: unsigned long copy_to_user(void *to, const void *from, unsigned long n); vs. size_t (*copy_to_user)(size_t n, void __user * to, const void *from); Let's get rid of this confusing parameter reordering. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/uaccess.h | 54 ++++++++++++++++++++--------------------- arch/s390/lib/uaccess_mvcos.c | 20 +++++++-------- arch/s390/lib/uaccess_pt.c | 34 +++++++++++++------------- 3 files changed, 54 insertions(+), 54 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 79330af9a5f8..73199636ba98 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -93,12 +93,12 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x) #define ARCH_HAS_SEARCH_EXTABLE struct uaccess_ops { - size_t (*copy_from_user)(size_t, const void __user *, void *); - size_t (*copy_to_user)(size_t, void __user *, const void *); - size_t (*copy_in_user)(size_t, void __user *, const void __user *); - size_t (*clear_user)(size_t, void __user *); - size_t (*strnlen_user)(size_t, const char __user *); - size_t (*strncpy_from_user)(size_t, const char __user *, char *); + size_t (*copy_from_user)(void *, const void __user *, size_t); + size_t (*copy_to_user)(void __user *, const void *, size_t); + size_t (*copy_in_user)(void __user *, const void __user *, size_t); + size_t (*clear_user)(void __user *, size_t); + size_t (*strnlen_user)(const char __user *, size_t); + size_t (*strncpy_from_user)(char *, const char __user *, size_t); int (*futex_atomic_op)(int op, u32 __user *, int oparg, int *old); int (*futex_atomic_cmpxchg)(u32 *, u32 __user *, u32 old, u32 new); }; @@ -109,15 +109,15 @@ extern struct uaccess_ops uaccess_pt; extern int __handle_fault(unsigned long, unsigned long, int); -static inline int __put_user_fn(size_t size, void __user *ptr, void *x) +static inline int __put_user_fn(void *x, void __user *ptr, size_t size) { - size = uaccess.copy_to_user(size, ptr, x); + size = uaccess.copy_to_user(ptr, x, size); return size ? -EFAULT : size; } -static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) +static inline int __get_user_fn(void *x, const void __user *ptr, size_t size) { - size = uaccess.copy_from_user(size, ptr, x); + size = uaccess.copy_from_user(x, ptr, size); return size ? -EFAULT : size; } @@ -135,8 +135,8 @@ static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) case 2: \ case 4: \ case 8: \ - __pu_err = __put_user_fn(sizeof (*(ptr)), \ - ptr, &__x); \ + __pu_err = __put_user_fn(&__x, ptr, \ + sizeof(*(ptr))); \ break; \ default: \ __put_user_bad(); \ @@ -161,29 +161,29 @@ extern int __put_user_bad(void) __attribute__((noreturn)); switch (sizeof(*(ptr))) { \ case 1: { \ unsigned char __x; \ - __gu_err = __get_user_fn(sizeof (*(ptr)), \ - ptr, &__x); \ + __gu_err = __get_user_fn(&__x, ptr, \ + sizeof(*(ptr))); \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 2: { \ unsigned short __x; \ - __gu_err = __get_user_fn(sizeof (*(ptr)), \ - ptr, &__x); \ + __gu_err = __get_user_fn(&__x, ptr, \ + sizeof(*(ptr))); \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 4: { \ unsigned int __x; \ - __gu_err = __get_user_fn(sizeof (*(ptr)), \ - ptr, &__x); \ + __gu_err = __get_user_fn(&__x, ptr, \ + sizeof(*(ptr))); \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ case 8: { \ unsigned long long __x; \ - __gu_err = __get_user_fn(sizeof (*(ptr)), \ - ptr, &__x); \ + __gu_err = __get_user_fn(&__x, ptr, \ + sizeof(*(ptr))); \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \ break; \ }; \ @@ -222,7 +222,7 @@ extern int __get_user_bad(void) __attribute__((noreturn)); static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) { - return uaccess.copy_to_user(n, to, from); + return uaccess.copy_to_user(to, from, n); } #define __copy_to_user_inatomic __copy_to_user @@ -268,7 +268,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n) { - return uaccess.copy_from_user(n, from, to); + return uaccess.copy_from_user(to, from, n); } extern void copy_from_user_overflow(void) @@ -309,7 +309,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n) static inline unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n) { - return uaccess.copy_in_user(n, to, from); + return uaccess.copy_in_user(to, from, n); } static inline unsigned long __must_check @@ -326,14 +326,14 @@ static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) { might_fault(); - return uaccess.strncpy_from_user(count, src, dst); + return uaccess.strncpy_from_user(dst, src, count); } static inline unsigned long strnlen_user(const char __user * src, unsigned long n) { might_fault(); - return uaccess.strnlen_user(n, src); + return uaccess.strnlen_user(src, n); } /** @@ -359,14 +359,14 @@ strnlen_user(const char __user * src, unsigned long n) static inline unsigned long __must_check __clear_user(void __user *to, unsigned long n) { - return uaccess.clear_user(n, to); + return uaccess.clear_user(to, n); } static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) { might_fault(); - return uaccess.clear_user(n, to); + return uaccess.clear_user(to, n); } extern int copy_to_user_real(void __user *dest, void *src, size_t count); diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 4b7993bf69b9..95123f57aaf8 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -26,7 +26,7 @@ #define SLR "slgr" #endif -static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) +static size_t copy_from_user_mvcos(void *x, const void __user *ptr, size_t size) { register unsigned long reg0 asm("0") = 0x81UL; unsigned long tmp1, tmp2; @@ -65,7 +65,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) return size; } -static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) +static size_t copy_to_user_mvcos(void __user *ptr, const void *x, size_t size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -94,8 +94,8 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) return size; } -static size_t copy_in_user_mvcos(size_t size, void __user *to, - const void __user *from) +static size_t copy_in_user_mvcos(void __user *to, const void __user *from, + size_t size) { register unsigned long reg0 asm("0") = 0x810081UL; unsigned long tmp1, tmp2; @@ -117,7 +117,7 @@ static size_t copy_in_user_mvcos(size_t size, void __user *to, return size; } -static size_t clear_user_mvcos(size_t size, void __user *to) +static size_t clear_user_mvcos(void __user *to, size_t size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -145,7 +145,7 @@ static size_t clear_user_mvcos(size_t size, void __user *to) return size; } -static size_t strnlen_user_mvcos(size_t count, const char __user *src) +static size_t strnlen_user_mvcos(const char __user *src, size_t count) { size_t done, len, offset, len_str; char buf[256]; @@ -155,7 +155,7 @@ static size_t strnlen_user_mvcos(size_t count, const char __user *src) offset = (size_t)src & ~PAGE_MASK; len = min(256UL, PAGE_SIZE - offset); len = min(count - done, len); - if (copy_from_user_mvcos(len, src, buf)) + if (copy_from_user_mvcos(buf, src, len)) return 0; len_str = strnlen(buf, len); done += len_str; @@ -164,8 +164,8 @@ static size_t strnlen_user_mvcos(size_t count, const char __user *src) return done + 1; } -static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, - char *dst) +static size_t strncpy_from_user_mvcos(char *dst, const char __user *src, + size_t count) { size_t done, len, offset, len_str; @@ -175,7 +175,7 @@ static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, do { offset = (size_t)src & ~PAGE_MASK; len = min(count - done, PAGE_SIZE - offset); - if (copy_from_user_mvcos(len, src, dst)) + if (copy_from_user_mvcos(dst, src, len)) return -EFAULT; len_str = strnlen(dst, len); done += len_str; diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 61ebcc9ccb34..2fa696b39b56 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -22,7 +22,7 @@ #define SLR "slgr" #endif -static size_t strnlen_kernel(size_t count, const char __user *src) +static size_t strnlen_kernel(const char __user *src, size_t count) { register unsigned long reg0 asm("0") = 0UL; unsigned long tmp1, tmp2; @@ -42,8 +42,8 @@ static size_t strnlen_kernel(size_t count, const char __user *src) return count; } -static size_t copy_in_kernel(size_t count, void __user *to, - const void __user *from) +static size_t copy_in_kernel(void __user *to, const void __user *from, + size_t count) { unsigned long tmp1; @@ -211,26 +211,26 @@ fault: return 0; } -static size_t copy_from_user_pt(size_t n, const void __user *from, void *to) +static size_t copy_from_user_pt(void *to, const void __user *from, size_t n) { size_t rc; if (segment_eq(get_fs(), KERNEL_DS)) - return copy_in_kernel(n, (void __user *) to, from); + return copy_in_kernel((void __user *) to, from, n); rc = __user_copy_pt((unsigned long) from, to, n, 0); if (unlikely(rc)) memset(to + n - rc, 0, rc); return rc; } -static size_t copy_to_user_pt(size_t n, void __user *to, const void *from) +static size_t copy_to_user_pt(void __user *to, const void *from, size_t n) { if (segment_eq(get_fs(), KERNEL_DS)) - return copy_in_kernel(n, to, (void __user *) from); + return copy_in_kernel(to, (void __user *) from, n); return __user_copy_pt((unsigned long) to, (void *) from, n, 1); } -static size_t clear_user_pt(size_t n, void __user *to) +static size_t clear_user_pt(void __user *to, size_t n) { void *zpage = (void *) empty_zero_page; long done, size, ret; @@ -242,7 +242,7 @@ static size_t clear_user_pt(size_t n, void __user *to) else size = n - done; if (segment_eq(get_fs(), KERNEL_DS)) - ret = copy_in_kernel(n, to, (void __user *) zpage); + ret = copy_in_kernel(to, (void __user *) zpage, n); else ret = __user_copy_pt((unsigned long) to, zpage, size, 1); done += size; @@ -253,7 +253,7 @@ static size_t clear_user_pt(size_t n, void __user *to) return 0; } -static size_t strnlen_user_pt(size_t count, const char __user *src) +static size_t strnlen_user_pt(const char __user *src, size_t count) { unsigned long uaddr = (unsigned long) src; struct mm_struct *mm = current->mm; @@ -263,7 +263,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src) if (unlikely(!count)) return 0; if (segment_eq(get_fs(), KERNEL_DS)) - return strnlen_kernel(count, src); + return strnlen_kernel(src, count); if (!mm) return 0; done = 0; @@ -289,8 +289,8 @@ fault: goto retry; } -static size_t strncpy_from_user_pt(size_t count, const char __user *src, - char *dst) +static size_t strncpy_from_user_pt(char *dst, const char __user *src, + size_t count) { size_t done, len, offset, len_str; @@ -301,7 +301,7 @@ static size_t strncpy_from_user_pt(size_t count, const char __user *src, offset = (size_t)src & ~PAGE_MASK; len = min(count - done, PAGE_SIZE - offset); if (segment_eq(get_fs(), KERNEL_DS)) { - if (copy_in_kernel(len, (void __user *) dst, src)) + if (copy_in_kernel((void __user *) dst, src, len)) return -EFAULT; } else { if (__user_copy_pt((unsigned long) src, dst, len, 0)) @@ -315,8 +315,8 @@ static size_t strncpy_from_user_pt(size_t count, const char __user *src, return done; } -static size_t copy_in_user_pt(size_t n, void __user *to, - const void __user *from) +static size_t copy_in_user_pt(void __user *to, const void __user *from, + size_t n) { struct mm_struct *mm = current->mm; unsigned long offset_max, uaddr, done, size, error_code; @@ -326,7 +326,7 @@ static size_t copy_in_user_pt(size_t n, void __user *to, int write_user; if (segment_eq(get_fs(), KERNEL_DS)) - return copy_in_kernel(n, to, from); + return copy_in_kernel(to, from, n); if (!mm) return n; done = 0; -- cgit v1.2.3-55-g7522 From 4f41c2b4567dbfb7ff93e5c552b869e2865bcd9d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 23 Jan 2014 11:18:36 +0100 Subject: s390/uaccess: get rid of indirect function calls There are only two uaccess variants on s390 left: the version that is used if the mvcos instruction is available, and the page table walk variant. So there is no need for expensive indirect function calls. By default the mvcos variant will be called. If the mvcos instruction is not available it will call the page table walk variant. For minimal performance impact the "if (mvcos_is_available)" is implemented with a jump label, which will be a six byte nop on machines with mvcos. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/futex.h | 13 ++-- arch/s390/include/asm/uaccess.h | 148 +++++++++++++++++----------------------- arch/s390/kernel/setup.c | 9 --- arch/s390/lib/Makefile | 3 +- arch/s390/lib/uaccess.h | 8 ++- arch/s390/lib/uaccess_mvcos.c | 89 ++++++++++++++++++------ arch/s390/lib/uaccess_pt.c | 31 +++------ 7 files changed, 152 insertions(+), 149 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index 51bcaa0fdeef..fda46bd38c99 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -5,7 +5,10 @@ #include #include -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval); +int __futex_atomic_op_inuser(int op, u32 __user *uaddr, int oparg, int *old); + +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) { int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; @@ -17,7 +20,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) oparg = 1 << oparg; pagefault_disable(); - ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval); + ret = __futex_atomic_op_inuser(op, uaddr, oparg, &oldval); pagefault_enable(); if (!ret) { @@ -34,10 +37,4 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) return ret; } -static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, - u32 oldval, u32 newval) -{ - return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval); -} - #endif /* _ASM_S390_FUTEX_H */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 73199636ba98..49885a518e5e 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -92,33 +92,58 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x) #define ARCH_HAS_SORT_EXTABLE #define ARCH_HAS_SEARCH_EXTABLE -struct uaccess_ops { - size_t (*copy_from_user)(void *, const void __user *, size_t); - size_t (*copy_to_user)(void __user *, const void *, size_t); - size_t (*copy_in_user)(void __user *, const void __user *, size_t); - size_t (*clear_user)(void __user *, size_t); - size_t (*strnlen_user)(const char __user *, size_t); - size_t (*strncpy_from_user)(char *, const char __user *, size_t); - int (*futex_atomic_op)(int op, u32 __user *, int oparg, int *old); - int (*futex_atomic_cmpxchg)(u32 *, u32 __user *, u32 old, u32 new); -}; +int __handle_fault(unsigned long, unsigned long, int); -extern struct uaccess_ops uaccess; -extern struct uaccess_ops uaccess_mvcos; -extern struct uaccess_ops uaccess_pt; +/** + * __copy_from_user: - Copy a block of data from user space, with less checking. + * @to: Destination address, in kernel space. + * @from: Source address, in user space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from user space to kernel space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + * + * If some data could not be copied, this function will pad the copied + * data to the requested size using zero bytes. + */ +size_t __must_check __copy_from_user(void *to, const void __user *from, + size_t n); + +/** + * __copy_to_user: - Copy a block of data into user space, with less checking. + * @to: Destination address, in user space. + * @from: Source address, in kernel space. + * @n: Number of bytes to copy. + * + * Context: User context only. This function may sleep. + * + * Copy data from kernel space to user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be copied. + * On success, this will be zero. + */ +unsigned long __must_check __copy_to_user(void __user *to, const void *from, + unsigned long n); -extern int __handle_fault(unsigned long, unsigned long, int); +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user static inline int __put_user_fn(void *x, void __user *ptr, size_t size) { - size = uaccess.copy_to_user(ptr, x, size); - return size ? -EFAULT : size; + size = __copy_to_user(ptr, x, size); + return size ? -EFAULT : 0; } static inline int __get_user_fn(void *x, const void __user *ptr, size_t size) { - size = uaccess.copy_from_user(x, ptr, size); - return size ? -EFAULT : size; + size = __copy_from_user(x, ptr, size); + return size ? -EFAULT : 0; } /* @@ -152,7 +177,7 @@ static inline int __get_user_fn(void *x, const void __user *ptr, size_t size) }) -extern int __put_user_bad(void) __attribute__((noreturn)); +int __put_user_bad(void) __attribute__((noreturn)); #define __get_user(x, ptr) \ ({ \ @@ -200,34 +225,11 @@ extern int __put_user_bad(void) __attribute__((noreturn)); __get_user(x, ptr); \ }) -extern int __get_user_bad(void) __attribute__((noreturn)); +int __get_user_bad(void) __attribute__((noreturn)); #define __put_user_unaligned __put_user #define __get_user_unaligned __get_user -/** - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) -{ - return uaccess.copy_to_user(to, from, n); -} - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - /** * copy_to_user: - Copy a block of data into user space. * @to: Destination address, in user space. @@ -248,30 +250,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n) return __copy_to_user(to, from, n); } -/** - * __copy_from_user: - Copy a block of data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -static inline unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n) -{ - return uaccess.copy_from_user(to, from, n); -} - -extern void copy_from_user_overflow(void) +void copy_from_user_overflow(void) #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS __compiletime_warning("copy_from_user() buffer size is not provably correct") #endif @@ -306,11 +285,8 @@ copy_from_user(void *to, const void __user *from, unsigned long n) return __copy_from_user(to, from, n); } -static inline unsigned long __must_check -__copy_in_user(void __user *to, const void __user *from, unsigned long n) -{ - return uaccess.copy_in_user(to, from, n); -} +unsigned long __must_check +__copy_in_user(void __user *to, const void __user *from, unsigned long n); static inline unsigned long __must_check copy_in_user(void __user *to, const void __user *from, unsigned long n) @@ -322,18 +298,22 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n) /* * Copy a null terminated string from userspace. */ + +long __strncpy_from_user(char *dst, const char __user *src, long count); + static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) { might_fault(); - return uaccess.strncpy_from_user(dst, src, count); + return __strncpy_from_user(dst, src, count); } -static inline unsigned long -strnlen_user(const char __user * src, unsigned long n) +size_t __must_check __strnlen_user(const char __user *src, size_t count); + +static inline size_t strnlen_user(const char __user *src, size_t n) { might_fault(); - return uaccess.strnlen_user(src, n); + return __strnlen_user(src, n); } /** @@ -355,21 +335,15 @@ strnlen_user(const char __user * src, unsigned long n) /* * Zero Userspace */ +size_t __must_check __clear_user(void __user *to, size_t size); -static inline unsigned long __must_check -__clear_user(void __user *to, unsigned long n) -{ - return uaccess.clear_user(to, n); -} - -static inline unsigned long __must_check -clear_user(void __user *to, unsigned long n) +static inline size_t __must_check clear_user(void __user *to, size_t n) { might_fault(); - return uaccess.clear_user(to, n); + return __clear_user(to, n); } -extern int copy_to_user_real(void __user *dest, void *src, size_t count); -extern int copy_from_user_real(void *dest, void __user *src, size_t count); +int copy_to_user_real(void __user *dest, void *src, size_t count); +int copy_from_user_real(void *dest, void __user *src, size_t count); #endif /* __S390_UACCESS_H */ diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 09e2f468f48b..91ea00955db7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -47,7 +47,6 @@ #include #include -#include #include #include #include @@ -64,12 +63,6 @@ #include #include "entry.h" -/* - * User copy operations. - */ -struct uaccess_ops uaccess; -EXPORT_SYMBOL(uaccess); - /* * Machine setup.. */ @@ -1009,8 +1002,6 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos : uaccess_pt; - parse_early_param(); detect_memory_layout(memory_chunk, memory_end); os_info_init(); diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index b068729e50ac..e3fffe1dff51 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -2,8 +2,7 @@ # Makefile for s390-specific library files.. # -lib-y += delay.o string.o uaccess_pt.o find.o +lib-y += delay.o string.o uaccess_pt.o uaccess_mvcos.o find.o obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o obj-$(CONFIG_64BIT) += mem64.o -lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/arch/s390/lib/uaccess.h b/arch/s390/lib/uaccess.h index b1a22173d027..e5b9c924b733 100644 --- a/arch/s390/lib/uaccess.h +++ b/arch/s390/lib/uaccess.h @@ -6,7 +6,11 @@ #ifndef __ARCH_S390_LIB_UACCESS_H #define __ARCH_S390_LIB_UACCESS_H -extern int futex_atomic_op_pt(int, u32 __user *, int, int *); -extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32); +size_t copy_from_user_pt(void *to, const void __user *from, size_t n); +size_t copy_to_user_pt(void __user *to, const void *from, size_t n); +size_t copy_in_user_pt(void __user *to, const void __user *from, size_t n); +size_t clear_user_pt(void __user *to, size_t n); +size_t strnlen_user_pt(const char __user *src, size_t count); +size_t strncpy_from_user_pt(char *dst, const char __user *src, size_t count); #endif /* __ARCH_S390_LIB_UACCESS_H */ diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 95123f57aaf8..66f35e15db2d 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -6,7 +6,9 @@ * Gerald Schaefer (gerald.schaefer@de.ibm.com) */ +#include #include +#include #include #include #include @@ -26,7 +28,10 @@ #define SLR "slgr" #endif -static size_t copy_from_user_mvcos(void *x, const void __user *ptr, size_t size) +static struct static_key have_mvcos = STATIC_KEY_INIT_TRUE; + +static inline size_t copy_from_user_mvcos(void *x, const void __user *ptr, + size_t size) { register unsigned long reg0 asm("0") = 0x81UL; unsigned long tmp1, tmp2; @@ -65,7 +70,16 @@ static size_t copy_from_user_mvcos(void *x, const void __user *ptr, size_t size) return size; } -static size_t copy_to_user_mvcos(void __user *ptr, const void *x, size_t size) +size_t __copy_from_user(void *to, const void __user *from, size_t n) +{ + if (static_key_true(&have_mvcos)) + return copy_from_user_mvcos(to, from, n); + return copy_from_user_pt(to, from, n); +} +EXPORT_SYMBOL(__copy_from_user); + +static inline size_t copy_to_user_mvcos(void __user *ptr, const void *x, + size_t size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -94,8 +108,16 @@ static size_t copy_to_user_mvcos(void __user *ptr, const void *x, size_t size) return size; } -static size_t copy_in_user_mvcos(void __user *to, const void __user *from, - size_t size) +size_t __copy_to_user(void __user *to, const void *from, size_t n) +{ + if (static_key_true(&have_mvcos)) + return copy_to_user_mvcos(to, from, n); + return copy_to_user_pt(to, from, n); +} +EXPORT_SYMBOL(__copy_to_user); + +static inline size_t copy_in_user_mvcos(void __user *to, const void __user *from, + size_t size) { register unsigned long reg0 asm("0") = 0x810081UL; unsigned long tmp1, tmp2; @@ -117,7 +139,15 @@ static size_t copy_in_user_mvcos(void __user *to, const void __user *from, return size; } -static size_t clear_user_mvcos(void __user *to, size_t size) +size_t __copy_in_user(void __user *to, const void __user *from, size_t n) +{ + if (static_key_true(&have_mvcos)) + return copy_in_user_mvcos(to, from, n); + return copy_in_user_pt(to, from, n); +} +EXPORT_SYMBOL(__copy_in_user); + +static inline size_t clear_user_mvcos(void __user *to, size_t size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -145,7 +175,15 @@ static size_t clear_user_mvcos(void __user *to, size_t size) return size; } -static size_t strnlen_user_mvcos(const char __user *src, size_t count) +size_t __clear_user(void __user *to, size_t size) +{ + if (static_key_true(&have_mvcos)) + return clear_user_mvcos(to, size); + return clear_user_pt(to, size); +} +EXPORT_SYMBOL(__clear_user); + +static inline size_t strnlen_user_mvcos(const char __user *src, size_t count) { size_t done, len, offset, len_str; char buf[256]; @@ -164,10 +202,18 @@ static size_t strnlen_user_mvcos(const char __user *src, size_t count) return done + 1; } -static size_t strncpy_from_user_mvcos(char *dst, const char __user *src, - size_t count) +size_t __strnlen_user(const char __user *src, size_t count) { - size_t done, len, offset, len_str; + if (static_key_true(&have_mvcos)) + return strnlen_user_mvcos(src, count); + return strnlen_user_pt(src, count); +} +EXPORT_SYMBOL(__strnlen_user); + +static inline size_t strncpy_from_user_mvcos(char *dst, const char __user *src, + size_t count) +{ + unsigned long done, len, offset, len_str; if (unlikely(!count)) return 0; @@ -185,13 +231,18 @@ static size_t strncpy_from_user_mvcos(char *dst, const char __user *src, return done; } -struct uaccess_ops uaccess_mvcos = { - .copy_from_user = copy_from_user_mvcos, - .copy_to_user = copy_to_user_mvcos, - .copy_in_user = copy_in_user_mvcos, - .clear_user = clear_user_mvcos, - .strnlen_user = strnlen_user_mvcos, - .strncpy_from_user = strncpy_from_user_mvcos, - .futex_atomic_op = futex_atomic_op_pt, - .futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt, -}; +long __strncpy_from_user(char *dst, const char __user *src, long count) +{ + if (static_key_true(&have_mvcos)) + return strncpy_from_user_mvcos(dst, src, count); + return strncpy_from_user_pt(dst, src, count); +} +EXPORT_SYMBOL(__strncpy_from_user); + +static int __init uaccess_init(void) +{ + if (!MACHINE_HAS_MVCOS) + static_key_slow_dec(&have_mvcos); + return 0; +} +early_initcall(uaccess_init); diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 2fa696b39b56..b49c3a440a24 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -211,7 +211,7 @@ fault: return 0; } -static size_t copy_from_user_pt(void *to, const void __user *from, size_t n) +size_t copy_from_user_pt(void *to, const void __user *from, size_t n) { size_t rc; @@ -223,14 +223,14 @@ static size_t copy_from_user_pt(void *to, const void __user *from, size_t n) return rc; } -static size_t copy_to_user_pt(void __user *to, const void *from, size_t n) +size_t copy_to_user_pt(void __user *to, const void *from, size_t n) { if (segment_eq(get_fs(), KERNEL_DS)) return copy_in_kernel(to, (void __user *) from, n); return __user_copy_pt((unsigned long) to, (void *) from, n, 1); } -static size_t clear_user_pt(void __user *to, size_t n) +size_t clear_user_pt(void __user *to, size_t n) { void *zpage = (void *) empty_zero_page; long done, size, ret; @@ -253,7 +253,7 @@ static size_t clear_user_pt(void __user *to, size_t n) return 0; } -static size_t strnlen_user_pt(const char __user *src, size_t count) +size_t strnlen_user_pt(const char __user *src, size_t count) { unsigned long uaddr = (unsigned long) src; struct mm_struct *mm = current->mm; @@ -289,8 +289,7 @@ fault: goto retry; } -static size_t strncpy_from_user_pt(char *dst, const char __user *src, - size_t count) +size_t strncpy_from_user_pt(char *dst, const char __user *src, size_t count) { size_t done, len, offset, len_str; @@ -315,8 +314,7 @@ static size_t strncpy_from_user_pt(char *dst, const char __user *src, return done; } -static size_t copy_in_user_pt(void __user *to, const void __user *from, - size_t n) +size_t copy_in_user_pt(void __user *to, const void __user *from, size_t n) { struct mm_struct *mm = current->mm; unsigned long offset_max, uaddr, done, size, error_code; @@ -411,7 +409,7 @@ static int __futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old) return ret; } -int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old) +int __futex_atomic_op_inuser(int op, u32 __user *uaddr, int oparg, int *old) { int ret; @@ -449,8 +447,8 @@ static int __futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, return ret; } -int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, - u32 oldval, u32 newval) +int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) { int ret; @@ -471,14 +469,3 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, put_page(virt_to_page(uaddr)); return ret; } - -struct uaccess_ops uaccess_pt = { - .copy_from_user = copy_from_user_pt, - .copy_to_user = copy_to_user_pt, - .copy_in_user = copy_in_user_pt, - .clear_user = clear_user_pt, - .strnlen_user = strnlen_user_pt, - .strncpy_from_user = strncpy_from_user_pt, - .futex_atomic_op = futex_atomic_op_pt, - .futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt, -}; -- cgit v1.2.3-55-g7522 From 211deca6bf413560b562d69748ebc4df5d80d65e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 24 Jan 2014 12:51:27 +0100 Subject: s390/uaccess: consistent types The types 'size_t' and 'unsigned long' have been used randomly for the uaccess functions. This looks rather confusing. So let's change all functions to use unsigned long instead and get rid of size_t in order to have a consistent interface. The only exception is strncpy_from_user() which uses 'long' since it may return a signed value (-EFAULT). Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/uaccess.h | 20 ++++++++++---------- arch/s390/lib/uaccess.h | 12 ++++++------ arch/s390/lib/uaccess_mvcos.c | 39 ++++++++++++++++++++------------------- arch/s390/lib/uaccess_pt.c | 38 +++++++++++++++++++------------------- arch/s390/mm/maccess.c | 4 ++-- 5 files changed, 57 insertions(+), 56 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 49885a518e5e..2710b41eed22 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -111,8 +111,8 @@ int __handle_fault(unsigned long, unsigned long, int); * If some data could not be copied, this function will pad the copied * data to the requested size using zero bytes. */ -size_t __must_check __copy_from_user(void *to, const void __user *from, - size_t n); +unsigned long __must_check __copy_from_user(void *to, const void __user *from, + unsigned long n); /** * __copy_to_user: - Copy a block of data into user space, with less checking. @@ -134,13 +134,13 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user -static inline int __put_user_fn(void *x, void __user *ptr, size_t size) +static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) { size = __copy_to_user(ptr, x, size); return size ? -EFAULT : 0; } -static inline int __get_user_fn(void *x, const void __user *ptr, size_t size) +static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size) { size = __copy_from_user(x, ptr, size); return size ? -EFAULT : 0; @@ -308,9 +308,9 @@ strncpy_from_user(char *dst, const char __user *src, long count) return __strncpy_from_user(dst, src, count); } -size_t __must_check __strnlen_user(const char __user *src, size_t count); +unsigned long __must_check __strnlen_user(const char __user *src, unsigned long count); -static inline size_t strnlen_user(const char __user *src, size_t n) +static inline unsigned long strnlen_user(const char __user *src, unsigned long n) { might_fault(); return __strnlen_user(src, n); @@ -335,15 +335,15 @@ static inline size_t strnlen_user(const char __user *src, size_t n) /* * Zero Userspace */ -size_t __must_check __clear_user(void __user *to, size_t size); +unsigned long __must_check __clear_user(void __user *to, unsigned long size); -static inline size_t __must_check clear_user(void __user *to, size_t n) +static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) { might_fault(); return __clear_user(to, n); } -int copy_to_user_real(void __user *dest, void *src, size_t count); -int copy_from_user_real(void *dest, void __user *src, size_t count); +int copy_to_user_real(void __user *dest, void *src, unsigned long count); +int copy_from_user_real(void *dest, void __user *src, unsigned long count); #endif /* __S390_UACCESS_H */ diff --git a/arch/s390/lib/uaccess.h b/arch/s390/lib/uaccess.h index e5b9c924b733..c7e0e81f4b4e 100644 --- a/arch/s390/lib/uaccess.h +++ b/arch/s390/lib/uaccess.h @@ -6,11 +6,11 @@ #ifndef __ARCH_S390_LIB_UACCESS_H #define __ARCH_S390_LIB_UACCESS_H -size_t copy_from_user_pt(void *to, const void __user *from, size_t n); -size_t copy_to_user_pt(void __user *to, const void *from, size_t n); -size_t copy_in_user_pt(void __user *to, const void __user *from, size_t n); -size_t clear_user_pt(void __user *to, size_t n); -size_t strnlen_user_pt(const char __user *src, size_t count); -size_t strncpy_from_user_pt(char *dst, const char __user *src, size_t count); +unsigned long copy_from_user_pt(void *to, const void __user *from, unsigned long n); +unsigned long copy_to_user_pt(void __user *to, const void *from, unsigned long n); +unsigned long copy_in_user_pt(void __user *to, const void __user *from, unsigned long n); +unsigned long clear_user_pt(void __user *to, unsigned long n); +unsigned long strnlen_user_pt(const char __user *src, unsigned long count); +long strncpy_from_user_pt(char *dst, const char __user *src, long count); #endif /* __ARCH_S390_LIB_UACCESS_H */ diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 66f35e15db2d..8c01f3aaf95c 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -30,8 +30,8 @@ static struct static_key have_mvcos = STATIC_KEY_INIT_TRUE; -static inline size_t copy_from_user_mvcos(void *x, const void __user *ptr, - size_t size) +static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr, + unsigned long size) { register unsigned long reg0 asm("0") = 0x81UL; unsigned long tmp1, tmp2; @@ -70,7 +70,7 @@ static inline size_t copy_from_user_mvcos(void *x, const void __user *ptr, return size; } -size_t __copy_from_user(void *to, const void __user *from, size_t n) +unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { if (static_key_true(&have_mvcos)) return copy_from_user_mvcos(to, from, n); @@ -78,8 +78,8 @@ size_t __copy_from_user(void *to, const void __user *from, size_t n) } EXPORT_SYMBOL(__copy_from_user); -static inline size_t copy_to_user_mvcos(void __user *ptr, const void *x, - size_t size) +static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x, + unsigned long size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -108,7 +108,7 @@ static inline size_t copy_to_user_mvcos(void __user *ptr, const void *x, return size; } -size_t __copy_to_user(void __user *to, const void *from, size_t n) +unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) { if (static_key_true(&have_mvcos)) return copy_to_user_mvcos(to, from, n); @@ -116,8 +116,8 @@ size_t __copy_to_user(void __user *to, const void *from, size_t n) } EXPORT_SYMBOL(__copy_to_user); -static inline size_t copy_in_user_mvcos(void __user *to, const void __user *from, - size_t size) +static inline unsigned long copy_in_user_mvcos(void __user *to, const void __user *from, + unsigned long size) { register unsigned long reg0 asm("0") = 0x810081UL; unsigned long tmp1, tmp2; @@ -139,7 +139,7 @@ static inline size_t copy_in_user_mvcos(void __user *to, const void __user *from return size; } -size_t __copy_in_user(void __user *to, const void __user *from, size_t n) +unsigned long __copy_in_user(void __user *to, const void __user *from, unsigned long n) { if (static_key_true(&have_mvcos)) return copy_in_user_mvcos(to, from, n); @@ -147,7 +147,7 @@ size_t __copy_in_user(void __user *to, const void __user *from, size_t n) } EXPORT_SYMBOL(__copy_in_user); -static inline size_t clear_user_mvcos(void __user *to, size_t size) +static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size) { register unsigned long reg0 asm("0") = 0x810000UL; unsigned long tmp1, tmp2; @@ -175,7 +175,7 @@ static inline size_t clear_user_mvcos(void __user *to, size_t size) return size; } -size_t __clear_user(void __user *to, size_t size) +unsigned long __clear_user(void __user *to, unsigned long size) { if (static_key_true(&have_mvcos)) return clear_user_mvcos(to, size); @@ -183,14 +183,15 @@ size_t __clear_user(void __user *to, size_t size) } EXPORT_SYMBOL(__clear_user); -static inline size_t strnlen_user_mvcos(const char __user *src, size_t count) +static inline unsigned long strnlen_user_mvcos(const char __user *src, + unsigned long count) { - size_t done, len, offset, len_str; + unsigned long done, len, offset, len_str; char buf[256]; done = 0; do { - offset = (size_t)src & ~PAGE_MASK; + offset = (unsigned long)src & ~PAGE_MASK; len = min(256UL, PAGE_SIZE - offset); len = min(count - done, len); if (copy_from_user_mvcos(buf, src, len)) @@ -202,7 +203,7 @@ static inline size_t strnlen_user_mvcos(const char __user *src, size_t count) return done + 1; } -size_t __strnlen_user(const char __user *src, size_t count) +unsigned long __strnlen_user(const char __user *src, unsigned long count) { if (static_key_true(&have_mvcos)) return strnlen_user_mvcos(src, count); @@ -210,16 +211,16 @@ size_t __strnlen_user(const char __user *src, size_t count) } EXPORT_SYMBOL(__strnlen_user); -static inline size_t strncpy_from_user_mvcos(char *dst, const char __user *src, - size_t count) +static inline long strncpy_from_user_mvcos(char *dst, const char __user *src, + long count) { unsigned long done, len, offset, len_str; - if (unlikely(!count)) + if (unlikely(count <= 0)) return 0; done = 0; do { - offset = (size_t)src & ~PAGE_MASK; + offset = (unsigned long)src & ~PAGE_MASK; len = min(count - done, PAGE_SIZE - offset); if (copy_from_user_mvcos(dst, src, len)) return -EFAULT; diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index b49c3a440a24..8d39760bae68 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -22,7 +22,7 @@ #define SLR "slgr" #endif -static size_t strnlen_kernel(const char __user *src, size_t count) +static unsigned long strnlen_kernel(const char __user *src, unsigned long count) { register unsigned long reg0 asm("0") = 0UL; unsigned long tmp1, tmp2; @@ -42,8 +42,8 @@ static size_t strnlen_kernel(const char __user *src, size_t count) return count; } -static size_t copy_in_kernel(void __user *to, const void __user *from, - size_t count) +static unsigned long copy_in_kernel(void __user *to, const void __user *from, + unsigned long count) { unsigned long tmp1; @@ -146,8 +146,8 @@ static unsigned long follow_table(struct mm_struct *mm, #endif /* CONFIG_64BIT */ -static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, - size_t n, int write_user) +static inline unsigned long __user_copy_pt(unsigned long uaddr, void *kptr, + unsigned long n, int write_user) { struct mm_struct *mm = current->mm; unsigned long offset, done, size, kaddr; @@ -189,8 +189,7 @@ fault: * Do DAT for user address by page table walk, return kernel address. * This function needs to be called with current->mm->page_table_lock held. */ -static __always_inline unsigned long __dat_user_addr(unsigned long uaddr, - int write) +static inline unsigned long __dat_user_addr(unsigned long uaddr, int write) { struct mm_struct *mm = current->mm; unsigned long kaddr; @@ -211,9 +210,9 @@ fault: return 0; } -size_t copy_from_user_pt(void *to, const void __user *from, size_t n) +unsigned long copy_from_user_pt(void *to, const void __user *from, unsigned long n) { - size_t rc; + unsigned long rc; if (segment_eq(get_fs(), KERNEL_DS)) return copy_in_kernel((void __user *) to, from, n); @@ -223,17 +222,17 @@ size_t copy_from_user_pt(void *to, const void __user *from, size_t n) return rc; } -size_t copy_to_user_pt(void __user *to, const void *from, size_t n) +unsigned long copy_to_user_pt(void __user *to, const void *from, unsigned long n) { if (segment_eq(get_fs(), KERNEL_DS)) return copy_in_kernel(to, (void __user *) from, n); return __user_copy_pt((unsigned long) to, (void *) from, n, 1); } -size_t clear_user_pt(void __user *to, size_t n) +unsigned long clear_user_pt(void __user *to, unsigned long n) { void *zpage = (void *) empty_zero_page; - long done, size, ret; + unsigned long done, size, ret; done = 0; do { @@ -253,12 +252,12 @@ size_t clear_user_pt(void __user *to, size_t n) return 0; } -size_t strnlen_user_pt(const char __user *src, size_t count) +unsigned long strnlen_user_pt(const char __user *src, unsigned long count) { unsigned long uaddr = (unsigned long) src; struct mm_struct *mm = current->mm; unsigned long offset, done, len, kaddr; - size_t len_str; + unsigned long len_str; if (unlikely(!count)) return 0; @@ -289,15 +288,15 @@ fault: goto retry; } -size_t strncpy_from_user_pt(char *dst, const char __user *src, size_t count) +long strncpy_from_user_pt(char *dst, const char __user *src, long count) { - size_t done, len, offset, len_str; + unsigned long done, len, offset, len_str; - if (unlikely(!count)) + if (unlikely(count <= 0)) return 0; done = 0; do { - offset = (size_t)src & ~PAGE_MASK; + offset = (unsigned long)src & ~PAGE_MASK; len = min(count - done, PAGE_SIZE - offset); if (segment_eq(get_fs(), KERNEL_DS)) { if (copy_in_kernel((void __user *) dst, src, len)) @@ -314,7 +313,8 @@ size_t strncpy_from_user_pt(char *dst, const char __user *src, size_t count) return done; } -size_t copy_in_user_pt(void __user *to, const void __user *from, size_t n) +unsigned long copy_in_user_pt(void __user *to, const void __user *from, + unsigned long n) { struct mm_struct *mm = current->mm; unsigned long offset_max, uaddr, done, size, error_code; diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index d1e0e0c7a7e2..efe8ad045c7b 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -128,7 +128,7 @@ void memcpy_absolute(void *dest, void *src, size_t count) /* * Copy memory from kernel (real) to user (virtual) */ -int copy_to_user_real(void __user *dest, void *src, size_t count) +int copy_to_user_real(void __user *dest, void *src, unsigned long count) { int offs = 0, size, rc; char *buf; @@ -154,7 +154,7 @@ out: /* * Copy memory from user (virtual) to kernel (real) */ -int copy_from_user_real(void *dest, void __user *src, size_t count) +int copy_from_user_real(void *dest, void __user *src, unsigned long count) { int offs = 0, size, rc; char *buf; -- cgit v1.2.3-55-g7522 From ca04ddbf537d30b25f6e240b70f19be35fac4313 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 24 Jan 2014 13:03:42 +0100 Subject: s390/setup: get rid of MACHINE_HAS_MVCOS machine flag MACHINE_HAS_MVCOS is used exactly once when the machine is brought up. There is no need to cache the flag in the machine_flags. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/setup.h | 3 --- arch/s390/kernel/early.c | 2 -- arch/s390/lib/uaccess_mvcos.c | 3 ++- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 94cfbe442f12..406f3a1e63ef 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -59,7 +59,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, #define MACHINE_FLAG_DIAG44 (1UL << 4) #define MACHINE_FLAG_IDTE (1UL << 5) #define MACHINE_FLAG_DIAG9C (1UL << 6) -#define MACHINE_FLAG_MVCOS (1UL << 7) #define MACHINE_FLAG_KVM (1UL << 8) #define MACHINE_FLAG_ESOP (1UL << 9) #define MACHINE_FLAG_EDAT1 (1UL << 10) @@ -85,7 +84,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, #define MACHINE_HAS_IDTE (0) #define MACHINE_HAS_DIAG44 (1) #define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG) -#define MACHINE_HAS_MVCOS (0) #define MACHINE_HAS_EDAT1 (0) #define MACHINE_HAS_EDAT2 (0) #define MACHINE_HAS_LPP (0) @@ -98,7 +96,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr, #define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE) #define MACHINE_HAS_DIAG44 (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44) #define MACHINE_HAS_MVPG (1) -#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) #define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1) #define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2) #define MACHINE_HAS_LPP (S390_lowcore.machine_flags & MACHINE_FLAG_LPP) diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index fca20b5fe79e..6b594439cca5 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -380,8 +380,6 @@ static __init void detect_machine_facilities(void) S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2; if (test_facility(3)) S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; - if (test_facility(27)) - S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; if (test_facility(40)) S390_lowcore.machine_flags |= MACHINE_FLAG_LPP; if (test_facility(50) && test_facility(73)) diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 8c01f3aaf95c..e2685ff2ec4b 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include "uaccess.h" @@ -242,7 +243,7 @@ EXPORT_SYMBOL(__strncpy_from_user); static int __init uaccess_init(void) { - if (!MACHINE_HAS_MVCOS) + if (IS_ENABLED(CONFIG_32BIT) || !test_facility(27)) static_key_slow_dec(&have_mvcos); return 0; } -- cgit v1.2.3-55-g7522 From 7385d0a550813c912094c5df22aeeb463712300e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 27 Jan 2014 10:09:11 +0100 Subject: s390/uaccess: remove dead kernel parameter 'user_mode=' Remove another leftover from the time when we supported running user space in either home or primary address space. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 91ea00955db7..f70f2489fa5f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -287,14 +287,6 @@ static int __init parse_vmalloc(char *arg) } early_param("vmalloc", parse_vmalloc); -static int __init early_parse_user_mode(char *p) -{ - if (!p || strcmp(p, "primary") == 0) - return 0; - return 1; -} -early_param("user_mode", early_parse_user_mode); - void *restart_stack __attribute__((__section__(".data"))); static void __init setup_lowcore(void) -- cgit v1.2.3-55-g7522 From 56f15e518cfdc732bd4e4da90e0c9cf2fc4e7c1b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 27 Jan 2014 10:25:39 +0100 Subject: s390/uaccess: introduce 'uaccesspt' kernel parameter The uaccesspt kernel parameter allows to enforce using the uaccess page table walk variant. This is mainly for debugging purposes, so this mode can also be enabled on machines which support the mvcos instruction. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_mvcos.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index e2685ff2ec4b..ae97b8df11aa 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -241,9 +241,22 @@ long __strncpy_from_user(char *dst, const char __user *src, long count) } EXPORT_SYMBOL(__strncpy_from_user); +/* + * The uaccess page tabe walk variant can be enforced with the "uaccesspt" + * kernel parameter. This is mainly for debugging purposes. + */ +static int force_uaccess_pt __initdata; + +static int __init parse_uaccess_pt(char *__unused) +{ + force_uaccess_pt = 1; + return 0; +} +early_param("uaccesspt", parse_uaccess_pt); + static int __init uaccess_init(void) { - if (IS_ENABLED(CONFIG_32BIT) || !test_facility(27)) + if (IS_ENABLED(CONFIG_32BIT) || force_uaccess_pt || !test_facility(27)) static_key_slow_dec(&have_mvcos); return 0; } -- cgit v1.2.3-55-g7522 From 53e857f30867918b3618d8e18902e63291946ef4 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 10 Sep 2012 13:00:09 +0200 Subject: s390/mm,tlb: race of lazy TLB flush vs. recreation of TLB entries Git commit 050eef364ad70059 "[S390] fix tlb flushing vs. concurrent /proc accesses" introduced the attach counter to avoid using the mm_users value to decide between IPTE for every PTE and lazy TLB flushing with IDTE. That fixed the problem with mm_users but it introduced another subtle race, fortunately one that is very hard to hit. The background is the requirement of the architecture that a valid PTE may not be changed while it can be used concurrently by another cpu. The decision between IPTE and lazy TLB flushing needs to be done while the PTE is still valid. Now if the virtual cpu is temporarily stopped after the decision to use lazy TLB flushing but before the invalid bit of the PTE has been set, another cpu can attach the mm, find that flush_mm is set, do the IDTE, return to userspace, and recreate a TLB that uses the PTE in question. When the first, stopped cpu continues it will change the PTE while it is attached on another cpu. The first cpu will do another IDTE shortly after the modification of the PTE which makes the race window quite short. To fix this race the CPU that wants to attach the address space of a user space thread needs to wait for the end of the PTE modification. The number of concurrent TLB flushers for an mm is tracked in the upper 16 bits of the attach_count and finish_arch_post_lock_switch is used to wait for the end of the flush operation if required. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/mmu_context.h | 39 ++++++++++++++++++++---- arch/s390/include/asm/pgtable.h | 60 +++++++++++++++++++++++-------------- arch/s390/include/asm/thread_info.h | 2 ++ arch/s390/kernel/entry.S | 9 ++++-- arch/s390/kernel/entry64.S | 9 ++++-- 5 files changed, 85 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 5d1f950704dc..38149b63dc44 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -48,13 +48,42 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { - cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); - update_mm(next, tsk); + int cpu = smp_processor_id(); + + if (prev == next) + return; + if (atomic_inc_return(&next->context.attach_count) >> 16) { + /* Delay update_mm until all TLB flushes are done. */ + set_tsk_thread_flag(tsk, TIF_TLB_WAIT); + } else { + cpumask_set_cpu(cpu, mm_cpumask(next)); + update_mm(next, tsk); + if (next->context.flush_mm) + /* Flush pending TLBs */ + __tlb_flush_mm(next); + } atomic_dec(&prev->context.attach_count); WARN_ON(atomic_read(&prev->context.attach_count) < 0); - atomic_inc(&next->context.attach_count); - /* Check for TLBs not flushed yet */ - __tlb_flush_mm_lazy(next); +} + +#define finish_arch_post_lock_switch finish_arch_post_lock_switch +static inline void finish_arch_post_lock_switch(void) +{ + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; + + if (!test_tsk_thread_flag(tsk, TIF_TLB_WAIT)) + return; + preempt_disable(); + clear_tsk_thread_flag(tsk, TIF_TLB_WAIT); + while (atomic_read(&mm->context.attach_count) >> 16) + cpu_relax(); + + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + update_mm(mm, tsk); + if (mm->context.flush_mm) + __tlb_flush_mm(mm); + preempt_enable(); } #define enter_lazy_tlb(mm,tsk) do { } while (0) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 2204400d0bd5..fc4bb82a0739 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1034,30 +1034,41 @@ static inline int ptep_test_and_clear_user_young(struct mm_struct *mm, static inline void __ptep_ipte(unsigned long address, pte_t *ptep) { - if (!(pte_val(*ptep) & _PAGE_INVALID)) { + unsigned long pto = (unsigned long) ptep; + #ifndef CONFIG_64BIT - /* pto must point to the start of the segment table */ - pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); -#else - /* ipte in zarch mode can do the math */ - pte_t *pto = ptep; + /* pto in ESA mode must point to the start of the segment table */ + pto &= 0x7ffffc00; #endif - asm volatile( - " ipte %2,%3" - : "=m" (*ptep) : "m" (*ptep), - "a" (pto), "a" (address)); - } + /* Invalidation + global TLB flush for the pte */ + asm volatile( + " ipte %2,%3" + : "=m" (*ptep) : "m" (*ptep), "a" (pto), "a" (address)); +} + +static inline void ptep_flush_direct(struct mm_struct *mm, + unsigned long address, pte_t *ptep) +{ + if (pte_val(*ptep) & _PAGE_INVALID) + return; + __ptep_ipte(address, ptep); } static inline void ptep_flush_lazy(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - int active = (mm == current->active_mm) ? 1 : 0; + int active, count; - if (atomic_read(&mm->context.attach_count) > active) - __ptep_ipte(address, ptep); - else + if (pte_val(*ptep) & _PAGE_INVALID) + return; + active = (mm == current->active_mm) ? 1 : 0; + count = atomic_add_return(0x10000, &mm->context.attach_count); + if ((count & 0xffff) <= active) { + pte_val(*ptep) |= _PAGE_INVALID; mm->context.flush_mm = 1; + } else + __ptep_ipte(address, ptep); + atomic_sub(0x10000, &mm->context.attach_count); } #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG @@ -1074,7 +1085,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, } pte = *ptep; - __ptep_ipte(addr, ptep); + ptep_flush_direct(vma->vm_mm, addr, ptep); young = pte_young(pte); pte = pte_mkold(pte); @@ -1145,7 +1156,6 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, pte = *ptep; ptep_flush_lazy(mm, address, ptep); - pte_val(*ptep) |= _PAGE_INVALID; if (mm_has_pgste(mm)) { pgste = pgste_update_all(&pte, pgste); @@ -1182,7 +1192,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, } pte = *ptep; - __ptep_ipte(address, ptep); + ptep_flush_direct(vma->vm_mm, address, ptep); pte_val(*ptep) = _PAGE_INVALID; if (mm_has_pgste(vma->vm_mm)) { @@ -1263,7 +1273,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma, pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste); } - __ptep_ipte(address, ptep); + ptep_flush_direct(vma->vm_mm, address, ptep); if (mm_has_pgste(vma->vm_mm)) { pgste_set_pte(ptep, entry); @@ -1447,12 +1457,16 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) static inline void pmdp_flush_lazy(struct mm_struct *mm, unsigned long address, pmd_t *pmdp) { - int active = (mm == current->active_mm) ? 1 : 0; + int active, count; - if ((atomic_read(&mm->context.attach_count) & 0xffff) > active) - __pmd_idte(address, pmdp); - else + active = (mm == current->active_mm) ? 1 : 0; + count = atomic_add_return(0x10000, &mm->context.attach_count); + if ((count & 0xffff) <= active) { + pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID; mm->context.flush_mm = 1; + } else + __pmd_idte(address, pmdp); + atomic_sub(0x10000, &mm->context.attach_count); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 10e0fcd3633d..d2e53d667a92 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -81,6 +81,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_TLB_WAIT 4 /* wait for TLB flush completion */ #define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */ #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ @@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NOTIFY_RESUME (1< Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/kvm_host.h | 5 ++- arch/s390/include/asm/pgtable.h | 26 ++++++++++++++ arch/s390/kvm/kvm-s390.c | 25 +++++++++++++ arch/s390/kvm/kvm-s390.h | 2 ++ arch/s390/kvm/priv.c | 41 +++++++++++++++++++++ arch/s390/mm/pgtable.c | 77 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index eef3dd3fd9a9..9bf95bb30f1a 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -106,7 +106,9 @@ struct kvm_s390_sie_block { __u64 gbea; /* 0x0180 */ __u8 reserved188[24]; /* 0x0188 */ __u32 fac; /* 0x01a0 */ - __u8 reserved1a4[68]; /* 0x01a4 */ + __u8 reserved1a4[20]; /* 0x01a4 */ + __u64 cbrlo; /* 0x01b8 */ + __u8 reserved1c0[40]; /* 0x01c0 */ __u64 itdba; /* 0x01e8 */ __u8 reserved1f0[16]; /* 0x01f0 */ } __attribute__((packed)); @@ -155,6 +157,7 @@ struct kvm_vcpu_stat { u32 instruction_stsi; u32 instruction_stfl; u32 instruction_tprot; + u32 instruction_essa; u32 instruction_sigp_sense; u32 instruction_sigp_sense_running; u32 instruction_sigp_external_call; diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index fc4bb82a0739..a7dd672c97f8 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -229,6 +229,7 @@ extern unsigned long MODULES_END; #define _PAGE_READ 0x010 /* SW pte read bit */ #define _PAGE_WRITE 0x020 /* SW pte write bit */ #define _PAGE_SPECIAL 0x040 /* SW associated with special page */ +#define _PAGE_UNUSED 0x080 /* SW bit for pgste usage state */ #define __HAVE_ARCH_PTE_SPECIAL /* Set of bits not changed in pte_modify */ @@ -394,6 +395,12 @@ extern unsigned long MODULES_END; #endif /* CONFIG_64BIT */ +/* Guest Page State used for virtualization */ +#define _PGSTE_GPS_ZERO 0x0000000080000000UL +#define _PGSTE_GPS_USAGE_MASK 0x0000000003000000UL +#define _PGSTE_GPS_USAGE_STABLE 0x0000000000000000UL +#define _PGSTE_GPS_USAGE_UNUSED 0x0000000001000000UL + /* * A user page table pointer has the space-switch-event bit, the * private-space-control bit and the storage-alteration-event-control @@ -617,6 +624,14 @@ static inline int pte_none(pte_t pte) return pte_val(pte) == _PAGE_INVALID; } +static inline int pte_swap(pte_t pte) +{ + /* Bit pattern: (pte & 0x603) == 0x402 */ + return (pte_val(pte) & (_PAGE_INVALID | _PAGE_PROTECT | + _PAGE_TYPE | _PAGE_PRESENT)) + == (_PAGE_INVALID | _PAGE_TYPE); +} + static inline int pte_file(pte_t pte) { /* Bit pattern: (pte & 0x601) == 0x600 */ @@ -821,6 +836,7 @@ unsigned long gmap_translate(unsigned long address, struct gmap *); unsigned long __gmap_fault(unsigned long address, struct gmap *); unsigned long gmap_fault(unsigned long address, struct gmap *); void gmap_discard(unsigned long from, unsigned long to, struct gmap *); +void __gmap_zap(unsigned long address, struct gmap *); void gmap_register_ipte_notifier(struct gmap_notifier *); void gmap_unregister_ipte_notifier(struct gmap_notifier *); @@ -852,6 +868,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, if (mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); + pgste_val(pgste) &= ~_PGSTE_GPS_ZERO; pgste_set_key(ptep, pgste, entry); pgste_set_pte(ptep, entry); pgste_set_unlock(ptep, pgste); @@ -881,6 +898,12 @@ static inline int pte_young(pte_t pte) return (pte_val(pte) & _PAGE_YOUNG) != 0; } +#define __HAVE_ARCH_PTE_UNUSED +static inline int pte_unused(pte_t pte) +{ + return pte_val(pte) & _PAGE_UNUSED; +} + /* * pgd/pmd/pte modification functions */ @@ -1196,6 +1219,9 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, pte_val(*ptep) = _PAGE_INVALID; if (mm_has_pgste(vma->vm_mm)) { + if ((pgste_val(pgste) & _PGSTE_GPS_USAGE_MASK) == + _PGSTE_GPS_USAGE_UNUSED) + pte_val(pte) |= _PAGE_UNUSED; pgste = pgste_update_all(&pte, pgste); pgste_set_unlock(ptep, pgste); } diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index e0676f390d57..10b5db3c9bc4 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -68,6 +68,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "instruction_storage_key", VCPU_STAT(instruction_storage_key) }, { "instruction_stsch", VCPU_STAT(instruction_stsch) }, { "instruction_chsc", VCPU_STAT(instruction_chsc) }, + { "instruction_essa", VCPU_STAT(instruction_essa) }, { "instruction_stsi", VCPU_STAT(instruction_stsi) }, { "instruction_stfl", VCPU_STAT(instruction_stfl) }, { "instruction_tprot", VCPU_STAT(instruction_tprot) }, @@ -283,7 +284,11 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) if (kvm_is_ucontrol(vcpu->kvm)) gmap_free(vcpu->arch.gmap); + if (vcpu->arch.sie_block->cbrlo) + __free_page(__pfn_to_page( + vcpu->arch.sie_block->cbrlo >> PAGE_SHIFT)); free_page((unsigned long)(vcpu->arch.sie_block)); + kvm_vcpu_uninit(vcpu); kmem_cache_free(kvm_vcpu_cache, vcpu); } @@ -390,6 +395,8 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { + struct page *cbrl; + atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM | CPUSTAT_STOPPED | @@ -401,6 +408,14 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->ecb2 = 8; vcpu->arch.sie_block->eca = 0xC1002001U; vcpu->arch.sie_block->fac = (int) (long) vfacilities; + if (kvm_enabled_cmma()) { + cbrl = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (cbrl) { + vcpu->arch.sie_block->ecb2 |= 0x80; + vcpu->arch.sie_block->ecb2 &= ~0x08; + vcpu->arch.sie_block->cbrlo = page_to_phys(cbrl); + } + } hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, (unsigned long) vcpu); @@ -761,6 +776,16 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) return rc; } +bool kvm_enabled_cmma(void) +{ + if (!MACHINE_IS_LPAR) + return false; + /* only enable for z10 and later */ + if (!MACHINE_HAS_EDAT1) + return false; + return true; +} + static int __vcpu_run(struct kvm_vcpu *vcpu) { int rc, exit_reason; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index f9559b0bd620..564514f410f4 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -156,6 +156,8 @@ void s390_vcpu_block(struct kvm_vcpu *vcpu); void s390_vcpu_unblock(struct kvm_vcpu *vcpu); void exit_sie(struct kvm_vcpu *vcpu); void exit_sie_sync(struct kvm_vcpu *vcpu); +/* are we going to support cmma? */ +bool kvm_enabled_cmma(void); /* implemented in diag.c */ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 75beea632a10..aacb6b129914 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -636,8 +636,49 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) return 0; } +static int handle_essa(struct kvm_vcpu *vcpu) +{ + /* entries expected to be 1FF */ + int entries = (vcpu->arch.sie_block->cbrlo & ~PAGE_MASK) >> 3; + unsigned long *cbrlo, cbrle; + struct gmap *gmap; + int i; + + VCPU_EVENT(vcpu, 5, "cmma release %d pages", entries); + gmap = vcpu->arch.gmap; + vcpu->stat.instruction_essa++; + if (!kvm_enabled_cmma() || !vcpu->arch.sie_block->cbrlo) + return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); + + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); + + if (((vcpu->arch.sie_block->ipb & 0xf0000000) >> 28) > 6) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + + /* Rewind PSW to repeat the ESSA instruction */ + vcpu->arch.sie_block->gpsw.addr = + __rewind_psw(vcpu->arch.sie_block->gpsw, 4); + vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */ + cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo); + down_read(&gmap->mm->mmap_sem); + for (i = 0; i < entries; ++i) { + cbrle = cbrlo[i]; + if (unlikely(cbrle & ~PAGE_MASK || cbrle < 2 * PAGE_SIZE)) + /* invalid entry */ + break; + /* try to free backing */ + __gmap_zap(cbrle, gmap); + } + up_read(&gmap->mm->mmap_sem); + if (i < entries) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + return 0; +} + static const intercept_handler_t b9_handlers[256] = { [0x8d] = handle_epsw, + [0xab] = handle_essa, [0xaf] = handle_pfmf, }; diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 3584ed9b20a1..9e2b4705dea2 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -594,6 +595,82 @@ unsigned long gmap_fault(unsigned long address, struct gmap *gmap) } EXPORT_SYMBOL_GPL(gmap_fault); +static void gmap_zap_swap_entry(swp_entry_t entry, struct mm_struct *mm) +{ + if (!non_swap_entry(entry)) + dec_mm_counter(mm, MM_SWAPENTS); + else if (is_migration_entry(entry)) { + struct page *page = migration_entry_to_page(entry); + + if (PageAnon(page)) + dec_mm_counter(mm, MM_ANONPAGES); + else + dec_mm_counter(mm, MM_FILEPAGES); + } + free_swap_and_cache(entry); +} + +/** + * The mm->mmap_sem lock must be held + */ +static void gmap_zap_unused(struct mm_struct *mm, unsigned long address) +{ + unsigned long ptev, pgstev; + spinlock_t *ptl; + pgste_t pgste; + pte_t *ptep, pte; + + ptep = get_locked_pte(mm, address, &ptl); + if (unlikely(!ptep)) + return; + pte = *ptep; + if (!pte_swap(pte)) + goto out_pte; + /* Zap unused and logically-zero pages */ + pgste = pgste_get_lock(ptep); + pgstev = pgste_val(pgste); + ptev = pte_val(pte); + if (((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED) || + ((pgstev & _PGSTE_GPS_ZERO) && (ptev & _PAGE_INVALID))) { + gmap_zap_swap_entry(pte_to_swp_entry(pte), mm); + pte_clear(mm, address, ptep); + } + pgste_set_unlock(ptep, pgste); +out_pte: + pte_unmap_unlock(*ptep, ptl); +} + +/* + * this function is assumed to be called with mmap_sem held + */ +void __gmap_zap(unsigned long address, struct gmap *gmap) +{ + unsigned long *table, *segment_ptr; + unsigned long segment, pgstev, ptev; + struct gmap_pgtable *mp; + struct page *page; + + segment_ptr = gmap_table_walk(address, gmap); + if (IS_ERR(segment_ptr)) + return; + segment = *segment_ptr; + if (segment & _SEGMENT_ENTRY_INVALID) + return; + page = pfn_to_page(segment >> PAGE_SHIFT); + mp = (struct gmap_pgtable *) page->index; + address = mp->vmaddr | (address & ~PMD_MASK); + /* Page table is present */ + table = (unsigned long *)(segment & _SEGMENT_ENTRY_ORIGIN); + table = table + ((address >> 12) & 0xff); + pgstev = table[PTRS_PER_PTE]; + ptev = table[0]; + /* quick check, checked again with locks held */ + if (((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED) || + ((pgstev & _PGSTE_GPS_ZERO) && (ptev & _PAGE_INVALID))) + gmap_zap_unused(gmap->mm, address); +} +EXPORT_SYMBOL_GPL(__gmap_zap); + void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) { -- cgit v1.2.3-55-g7522 From deedabb2b4a68a63351a949b1abcf73fc97eb406 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 21 May 2013 17:29:52 +0200 Subject: s390/kvm: set guest page states to stable on re-ipl The guest page state needs to be reset to stable for all pages on initial program load via diagnose 0x308. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgalloc.h | 1 + arch/s390/kvm/diag.c | 3 ++ arch/s390/mm/pgtable.c | 72 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) (limited to 'arch') diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index e1408ddb94f8..14d43c77d6cf 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -22,6 +22,7 @@ unsigned long *page_table_alloc(struct mm_struct *, unsigned long); void page_table_free(struct mm_struct *, unsigned long *); void page_table_free_rcu(struct mmu_gather *, unsigned long *); +void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long); int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, unsigned long key, bool nq); diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 8216c0e0b2e2..6f9cfa500372 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "kvm-s390.h" #include "trace.h" @@ -86,9 +87,11 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) switch (subcode) { case 3: vcpu->run->s390_reset_flags = KVM_S390_RESET_CLEAR; + page_table_reset_pgste(current->mm, 0, TASK_SIZE); break; case 4: vcpu->run->s390_reset_flags = 0; + page_table_reset_pgste(current->mm, 0, TASK_SIZE); break; default: return -EOPNOTSUPP; diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 9e2b4705dea2..9c26b7aa96d9 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -879,6 +879,78 @@ static inline void page_table_free_pgste(unsigned long *table) __free_page(page); } +static inline unsigned long page_table_reset_pte(struct mm_struct *mm, + pmd_t *pmd, unsigned long addr, unsigned long end) +{ + pte_t *start_pte, *pte; + spinlock_t *ptl; + pgste_t pgste; + + start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl); + pte = start_pte; + do { + pgste = pgste_get_lock(pte); + pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; + pgste_set_unlock(pte, pgste); + } while (pte++, addr += PAGE_SIZE, addr != end); + pte_unmap_unlock(start_pte, ptl); + + return addr; +} + +static inline unsigned long page_table_reset_pmd(struct mm_struct *mm, + pud_t *pud, unsigned long addr, unsigned long end) +{ + unsigned long next; + pmd_t *pmd; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none_or_clear_bad(pmd)) + continue; + next = page_table_reset_pte(mm, pmd, addr, next); + } while (pmd++, addr = next, addr != end); + + return addr; +} + +static inline unsigned long page_table_reset_pud(struct mm_struct *mm, + pgd_t *pgd, unsigned long addr, unsigned long end) +{ + unsigned long next; + pud_t *pud; + + pud = pud_offset(pgd, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none_or_clear_bad(pud)) + continue; + next = page_table_reset_pmd(mm, pud, addr, next); + } while (pud++, addr = next, addr != end); + + return addr; +} + +void page_table_reset_pgste(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + unsigned long addr, next; + pgd_t *pgd; + + addr = start; + down_read(&mm->mmap_sem); + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end); + if (pgd_none_or_clear_bad(pgd)) + continue; + next = page_table_reset_pud(mm, pgd, addr, next); + } while (pgd++, addr = next, addr != end); + up_read(&mm->mmap_sem); +} +EXPORT_SYMBOL(page_table_reset_pgste); + int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, unsigned long key, bool nq) { -- cgit v1.2.3-55-g7522 From db85eaeb52637eb91a7bbc70f6684f5563b983e9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 12 Feb 2014 12:43:40 +0100 Subject: s390/bitops: fix comment Fix some numbers in the comments describing the layout of the bit maps. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/bitops.h | 8 ++++---- arch/s390/lib/find.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 6e6ad0680829..ec5ef891db6b 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -13,9 +13,9 @@ * * The bitop functions are defined to work on unsigned longs, so for an * s390x system the bits end up numbered: - * |63..............0|127............64|191...........128|255...........196| + * |63..............0|127............64|191...........128|255...........192| * and on s390: - * |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| + * |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224| * * There are a few little-endian macros used mostly for filesystem * bitmaps, these work on similar bit arrays layouts, but @@ -30,7 +30,7 @@ * on an s390x system the bits are numbered: * |0..............63|64............127|128...........191|192...........255| * and on s390: - * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| + * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255| * * The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit * number field needs to be reversed compared to the LSB0 encoded bit @@ -304,7 +304,7 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr) * On an s390x system the bits are numbered: * |0..............63|64............127|128...........191|192...........255| * and on s390: - * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| + * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255| */ unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size); unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size, diff --git a/arch/s390/lib/find.c b/arch/s390/lib/find.c index 620d34d6487e..922003c1b90d 100644 --- a/arch/s390/lib/find.c +++ b/arch/s390/lib/find.c @@ -4,7 +4,7 @@ * On s390x the bits are numbered: * |0..............63|64............127|128...........191|192...........255| * and on s390: - * |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| + * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255| * * The reason for this bit numbering is the fact that the hardware sets bits * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap -- cgit v1.2.3-55-g7522 From ec66ad66a0de87866be347b5ecc83bd46427f53b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 12 Feb 2014 14:16:18 +0100 Subject: s390/mm: enable split page table lock for PMD level Add the pgtable_pmd_page_ctor/pgtable_pmd_page_dtor calls to the pmd allocation and free functions and enable ARCH_ENABLE_SPLIT_PMD_PTLOCK for 64 bit. Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 4 ++++ arch/s390/include/asm/pgalloc.h | 17 ++++++++++++++--- arch/s390/mm/pgtable.c | 4 ++-- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 65a07750f4f9..86db5a8e6586 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -415,6 +415,10 @@ config ARCH_ENABLE_MEMORY_HOTPLUG config ARCH_ENABLE_MEMORY_HOTREMOVE def_bool y +config ARCH_ENABLE_SPLIT_PMD_PTLOCK + def_bool y + depends on 64BIT + config FORCE_MAX_ZONEORDER int default "9" diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index 14d43c77d6cf..884017cbfa9f 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -92,11 +92,22 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) { unsigned long *table = crst_table_alloc(mm); - if (table) - crst_table_init(table, _SEGMENT_ENTRY_EMPTY); + + if (!table) + return NULL; + crst_table_init(table, _SEGMENT_ENTRY_EMPTY); + if (!pgtable_pmd_page_ctor(virt_to_page(table))) { + crst_table_free(mm, table); + return NULL; + } return (pmd_t *) table; } -#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd) + +static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) +{ + pgtable_pmd_page_dtor(virt_to_page(pmd)); + crst_table_free(mm, (unsigned long *) pmd); +} static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) { diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 9c26b7aa96d9..f8b58a7a3048 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -1397,7 +1397,7 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, { struct list_head *lh = (struct list_head *) pgtable; - assert_spin_locked(&mm->page_table_lock); + assert_spin_locked(pmd_lockptr(mm, pmdp)); /* FIFO */ if (!pmd_huge_pte(mm, pmdp)) @@ -1413,7 +1413,7 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) pgtable_t pgtable; pte_t *ptep; - assert_spin_locked(&mm->page_table_lock); + assert_spin_locked(pmd_lockptr(mm, pmdp)); /* FIFO */ pgtable = pmd_huge_pte(mm, pmdp); -- cgit v1.2.3-55-g7522 From fe7c30a420761654777d3cc15412fc7626407e93 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 13 Feb 2014 13:02:32 +0100 Subject: s390/airq: add support for irq ranges Add airq_iv_alloc and airq_iv_free to allocate and free consecutive ranges of irqs from the interrupt vector. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/airq.h | 14 ++++++++-- drivers/s390/cio/airq.c | 66 +++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/airq.h b/arch/s390/include/asm/airq.h index 4bbb5957ed1b..bd93ff6661b8 100644 --- a/arch/s390/include/asm/airq.h +++ b/arch/s390/include/asm/airq.h @@ -44,11 +44,21 @@ struct airq_iv { struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); void airq_iv_release(struct airq_iv *iv); -unsigned long airq_iv_alloc_bit(struct airq_iv *iv); -void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit); +unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num); +void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num); unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, unsigned long end); +static inline unsigned long airq_iv_alloc_bit(struct airq_iv *iv) +{ + return airq_iv_alloc(iv, 1); +} + +static inline void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit) +{ + airq_iv_free(iv, bit, 1); +} + static inline unsigned long airq_iv_end(struct airq_iv *iv) { return iv->end; diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index f055df0b167f..445564c790f6 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c @@ -186,55 +186,71 @@ void airq_iv_release(struct airq_iv *iv) EXPORT_SYMBOL(airq_iv_release); /** - * airq_iv_alloc_bit - allocate an irq bit from an interrupt vector + * airq_iv_alloc - allocate irq bits from an interrupt vector * @iv: pointer to an interrupt vector structure + * @num: number of consecutive irq bits to allocate * - * Returns the bit number of the allocated irq, or -1UL if no bit - * is available or the AIRQ_IV_ALLOC flag has not been specified + * Returns the bit number of the first irq in the allocated block of irqs, + * or -1UL if no bit is available or the AIRQ_IV_ALLOC flag has not been + * specified */ -unsigned long airq_iv_alloc_bit(struct airq_iv *iv) +unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num) { - unsigned long bit; + unsigned long bit, i; - if (!iv->avail) + if (!iv->avail || num == 0) return -1UL; spin_lock(&iv->lock); bit = find_first_bit_inv(iv->avail, iv->bits); - if (bit < iv->bits) { - clear_bit_inv(bit, iv->avail); - if (bit >= iv->end) - iv->end = bit + 1; - } else + while (bit + num <= iv->bits) { + for (i = 1; i < num; i++) + if (!test_bit_inv(bit + i, iv->avail)) + break; + if (i >= num) { + /* Found a suitable block of irqs */ + for (i = 0; i < num; i++) + clear_bit_inv(bit + i, iv->avail); + if (bit + num >= iv->end) + iv->end = bit + num + 1; + break; + } + bit = find_next_bit_inv(iv->avail, iv->bits, bit + i + 1); + } + if (bit + num > iv->bits) bit = -1UL; spin_unlock(&iv->lock); return bit; } -EXPORT_SYMBOL(airq_iv_alloc_bit); +EXPORT_SYMBOL(airq_iv_alloc); /** - * airq_iv_free_bit - free an irq bit of an interrupt vector + * airq_iv_free - free irq bits of an interrupt vector * @iv: pointer to interrupt vector structure - * @bit: number of the irq bit to free + * @bit: number of the first irq bit to free + * @num: number of consecutive irq bits to free */ -void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit) +void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num) { - if (!iv->avail) + unsigned long i; + + if (!iv->avail || num == 0) return; spin_lock(&iv->lock); - /* Clear (possibly left over) interrupt bit */ - clear_bit_inv(bit, iv->vector); - /* Make the bit position available again */ - set_bit_inv(bit, iv->avail); - if (bit == iv->end - 1) { + for (i = 0; i < num; i++) { + /* Clear (possibly left over) interrupt bit */ + clear_bit_inv(bit + i, iv->vector); + /* Make the bit positions available again */ + set_bit_inv(bit + i, iv->avail); + } + if (bit + num >= iv->end) { /* Find new end of bit-field */ - while (--iv->end > 0) - if (!test_bit_inv(iv->end - 1, iv->avail)) - break; + while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail)) + iv->end--; } spin_unlock(&iv->lock); } -EXPORT_SYMBOL(airq_iv_free_bit); +EXPORT_SYMBOL(airq_iv_free); /** * airq_iv_scan - scan interrupt vector for non-zero bits -- cgit v1.2.3-55-g7522 From f7e1e65d29636d050cdde0770b9544572959a67d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 17 Feb 2014 11:16:10 +0100 Subject: s390: improve debug feature usage The maximum usable buffer size of the s390 debug feature (when using the sprintf_view) is 11 * sizeof(long) (1 pointer for the format string + 10 arguments). When a larger buffer size is specified the additional memory is unused and wasted per debug entry. So reducing the buffer size to its maximum (or to the actual buffer size used) will make more precious debug feature space usable. For pci_msg, chsc_msg, and cio_crw we use the additional usable dbf space to reduce the number of allocated pages. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/pci/pci_debug.c | 2 +- drivers/s390/cio/chsc_sch.c | 3 +-- drivers/s390/cio/cio.c | 4 ++-- drivers/s390/net/qeth_core_main.c | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c index 75c69b402e05..c5c66840ac00 100644 --- a/arch/s390/pci/pci_debug.c +++ b/arch/s390/pci/pci_debug.c @@ -139,7 +139,7 @@ void zpci_debug_exit_device(struct zpci_dev *zdev) int __init zpci_debug_init(void) { /* event trace buffer */ - pci_debug_msg_id = debug_register("pci_msg", 16, 1, 16 * sizeof(long)); + pci_debug_msg_id = debug_register("pci_msg", 8, 1, 8 * sizeof(long)); if (!pci_debug_msg_id) return -EINVAL; debug_register_view(pci_debug_msg_id, &debug_sprintf_view); diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 7b29d0be0ca3..1d3661af7bd8 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -173,8 +173,7 @@ static struct css_driver chsc_subchannel_driver = { static int __init chsc_init_dbfs(void) { - chsc_debug_msg_id = debug_register("chsc_msg", 16, 1, - 16 * sizeof(long)); + chsc_debug_msg_id = debug_register("chsc_msg", 8, 1, 4 * sizeof(long)); if (!chsc_debug_msg_id) goto out; debug_register_view(chsc_debug_msg_id, &debug_sprintf_view); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 8ee88c4ebd83..97c48b38d67d 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -54,7 +54,7 @@ debug_info_t *cio_debug_crw_id; */ static int __init cio_debug_init(void) { - cio_debug_msg_id = debug_register("cio_msg", 16, 1, 16 * sizeof(long)); + cio_debug_msg_id = debug_register("cio_msg", 16, 1, 11 * sizeof(long)); if (!cio_debug_msg_id) goto out_unregister; debug_register_view(cio_debug_msg_id, &debug_sprintf_view); @@ -64,7 +64,7 @@ static int __init cio_debug_init(void) goto out_unregister; debug_register_view(cio_debug_trace_id, &debug_hex_ascii_view); debug_set_level(cio_debug_trace_id, 2); - cio_debug_crw_id = debug_register("cio_crw", 16, 1, 16 * sizeof(long)); + cio_debug_crw_id = debug_register("cio_crw", 8, 1, 8 * sizeof(long)); if (!cio_debug_crw_id) goto out_unregister; debug_register_view(cio_debug_crw_id, &debug_sprintf_view); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c3a83df07894..bd5d4ab4bcf7 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -33,8 +33,8 @@ struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = { /* N P A M L V H */ [QETH_DBF_SETUP] = {"qeth_setup", 8, 1, 8, 5, &debug_hex_ascii_view, NULL}, - [QETH_DBF_MSG] = {"qeth_msg", - 8, 1, 128, 3, &debug_sprintf_view, NULL}, + [QETH_DBF_MSG] = {"qeth_msg", 8, 1, 11 * sizeof(long), 3, + &debug_sprintf_view, NULL}, [QETH_DBF_CTRL] = {"qeth_control", 8, 1, QETH_DBF_CTRL_LEN, 5, &debug_hex_ascii_view, NULL}, }; -- cgit v1.2.3-55-g7522 From b3634575930857724d5c3987a2739b0637999b4e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 18 Feb 2014 17:02:54 +0100 Subject: ARM: 7980/1: kernel: improve error message when LPAE config doesn't match CPU Currently, when the kernel is configured with LPAE support, but the CPU doesn't support it, the error message is fairly cryptic: Error: unrecognized/unsupported processor variant (0x561f5811). This messages is normally shown when there is an issue when comparing the processor ID (CP15 0, c0, c0) with the values/masks described in proc-v7.S. However, the same message is displayed when LPAE support is enabled in the kernel configuration, but not available in the CPU, after looking at ID_MMFR0 (CP15 0, c0, c1, 4). Having the same error message is highly misleading. This commit improves this by showing a different error message when this situation occurs: Error: Kernel with LPAE support, but CPU does not support LPAE. Signed-off-by: Thomas Petazzoni Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 12 ++++++++++++ arch/arm/kernel/head.S | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 47cd974e57ea..c96ecacb2021 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -177,6 +177,18 @@ __lookup_processor_type_data: .long __proc_info_end .size __lookup_processor_type_data, . - __lookup_processor_type_data +__error_lpae: +#ifdef CONFIG_DEBUG_LL + adr r0, str_lpae + bl printascii + b __error +str_lpae: .asciz "\nError: Kernel with LPAE support, but CPU does not support LPAE.\n" +#else + b __error +#endif + .align +ENDPROC(__error_lpae) + __error_p: #ifdef CONFIG_DEBUG_LL adr r0, str_p1 diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 914616e0bdcd..f5f381d91556 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -102,7 +102,7 @@ ENTRY(stext) and r3, r3, #0xf @ extract VMSA support cmp r3, #5 @ long-descriptor translation table format? THUMB( it lo ) @ force fixup-able long branch encoding - blo __error_p @ only classic page table format + blo __error_lpae @ only classic page table format #endif #ifndef CONFIG_XIP_KERNEL -- cgit v1.2.3-55-g7522 From e9d6dca51823b94e1ca28cb5e9180701d4375d61 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 31 Jan 2014 05:38:21 +0400 Subject: xtensa: don't pass high memory to bootmem allocator This fixes panic when booting on machine with more than 128M memory passed from the bootloader. Signed-off-by: Max Filippov --- arch/xtensa/mm/init.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 479d7537a32a..aff108df92d3 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -90,7 +90,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) /* - * Initialize the bootmem system and give it all the memory we have available. + * Initialize the bootmem system and give it all low memory we have available. */ void __init bootmem_init(void) @@ -142,9 +142,14 @@ void __init bootmem_init(void) /* Add all remaining memory pieces into the bootmem map */ - for (i=0; i> PAGE_SHIFT < max_low_pfn) { + unsigned long end = min(max_low_pfn << PAGE_SHIFT, + sysmem.bank[i].end); + free_bootmem(sysmem.bank[i].start, + end - sysmem.bank[i].start); + } + } } -- cgit v1.2.3-55-g7522 From 8e9356c6146d0bb81a6ffb02eae522e57ff29662 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 7 Feb 2014 11:09:52 +0400 Subject: xtensa: fsf: drop nonexistent GPIO32 support The toolchain for xtensa FSF core never supported GPIO32, drop it on the linux side too. Reported-by: Fengguang Wu Signed-off-by: Max Filippov Acked-by: Baruch Siach --- arch/xtensa/Kconfig | 1 - arch/xtensa/variants/fsf/include/variant/tie.h | 9 ++------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index ba56e11cbf77..1cfb3d50602e 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -80,7 +80,6 @@ choice config XTENSA_VARIANT_FSF bool "fsf - default (not generic) configuration" select MMU - select HAVE_XTENSA_GPIO32 config XTENSA_VARIANT_DC232B bool "dc232b - Diamond 232L Standard Core Rev.B (LE)" diff --git a/arch/xtensa/variants/fsf/include/variant/tie.h b/arch/xtensa/variants/fsf/include/variant/tie.h index bf4020116df5..244cdea4dee5 100644 --- a/arch/xtensa/variants/fsf/include/variant/tie.h +++ b/arch/xtensa/variants/fsf/include/variant/tie.h @@ -18,13 +18,6 @@ #define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ #define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ -/* Basic parameters of each coprocessor: */ -#define XCHAL_CP7_NAME "XTIOP" -#define XCHAL_CP7_IDENT XTIOP -#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ -#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ -#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ - /* Filler info for unassigned coprocessors, to simplify arrays etc: */ #define XCHAL_NCP_SA_SIZE 0 #define XCHAL_NCP_SA_ALIGN 1 @@ -42,6 +35,8 @@ #define XCHAL_CP5_SA_ALIGN 1 #define XCHAL_CP6_SA_SIZE 0 #define XCHAL_CP6_SA_ALIGN 1 +#define XCHAL_CP7_SA_SIZE 0 +#define XCHAL_CP7_SA_ALIGN 1 /* Save area for non-coprocessor optional and custom (TIE) state: */ #define XCHAL_NCP_SA_SIZE 0 -- cgit v1.2.3-55-g7522 From 4e3b4df839b550aec463945b10141c65c69f5135 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 9 Feb 2014 15:45:06 +0100 Subject: xtensa: no need to select USE_GENERIC_SMP_HELPERS Commit f615136c06a7 ("xtensa: add SMP support") added "select USE_GENERIC_SMP_HELPERS". But the Kconfig symbol USE_GENERIC_SMP_HELPERS was already removed in v3.13, so that select is a nop. Drop it. Signed-off-by: Paul Bolle Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 1cfb3d50602e..44f1152efa2f 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -134,7 +134,6 @@ config HAVE_SMP config SMP bool "Enable Symmetric multi-processing support" depends on HAVE_SMP - select USE_GENERIC_SMP_HELPERS select GENERIC_SMP_IDLE_THREAD help Enabled SMP Software; allows more than one CPU/CORE -- cgit v1.2.3-55-g7522 From bda8932d234aeaee870ac666e776a5ba03bb13a4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 29 Jan 2014 06:20:46 +0400 Subject: xtensa: support common clock framework Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 1 + arch/xtensa/kernel/setup.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 44f1152efa2f..c87ae7c6e5f9 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -20,6 +20,7 @@ config XTENSA select HAVE_FUNCTION_TRACER select HAVE_IRQ_TIME_ACCOUNTING select HAVE_PERF_EVENTS + select COMMON_CLK help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 7d12af1317f1..84fe931bb60e 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -276,6 +277,7 @@ void __init early_init_devtree(void *params) static int __init xtensa_device_probe(void) { + of_clk_init(NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); return 0; } -- cgit v1.2.3-55-g7522 From cdc9af7ccfc26d35ff8a29dded2cc2c096c0fc1e Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 29 Jan 2014 07:42:46 +0400 Subject: xtensa: xtfpga: use common clock framework With this change the board needs to set up single clock object, users of this clock will get correct frequency automatically. Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/xtfpga.dtsi | 11 ++++++++--- arch/xtensa/platforms/xtfpga/setup.c | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index 46b4f5eab421..d5ccbbb7eec1 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -35,6 +35,13 @@ interrupt-controller; }; + clocks { + osc: main-oscillator { + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + }; + serial0: serial@fd050020 { device_type = "serial"; compatible = "ns16550a"; @@ -42,9 +49,7 @@ reg = <0xfd050020 0x20>; reg-shift = <2>; interrupts = <0 1>; /* external irq 0 */ - /* Filled in by platform_setup from FPGA register - * clock-frequency = <100000000>; - */ + clocks = <&osc>; }; enet0: ethoc@fd030000 { diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 800227862fe8..03729132ae44 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -135,11 +135,11 @@ static void __init update_local_mac(struct device_node *node) static int __init machine_setup(void) { - struct device_node *serial; + struct device_node *clock; struct device_node *eth = NULL; - for_each_compatible_node(serial, NULL, "ns16550a") - update_clock_frequency(serial); + for_each_node_by_name(clock, "main-oscillator") + update_clock_frequency(clock); if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) update_local_mac(eth); -- cgit v1.2.3-55-g7522 From 2bc2fde63858322a942864bf6cb2d54f5aa33186 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 29 Jan 2014 07:53:44 +0400 Subject: xtensa: xtfpga: set ethoc clock frequency Connect xtfpga board ethernet MAC to the clock in the DTS. Set up MAC base frequency in the platform data in case of build w/o CONFIG_OF. Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/xtfpga.dtsi | 1 + arch/xtensa/platforms/xtfpga/setup.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index d5ccbbb7eec1..e7370b11348e 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -57,5 +57,6 @@ reg = <0xfd030000 0x4000 0xfd800000 0x4000>; interrupts = <1 1>; /* external irq 1 */ local-mac-address = [00 50 c2 13 6f 00]; + clocks = <&osc>; }; }; diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 03729132ae44..57fd08b36f51 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -290,6 +290,7 @@ static int __init xtavnet_init(void) * knows whether they set it correctly on the DIP switches. */ pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); + ethoc_pdata.eth_clkfreq = *(long *)XTFPGA_CLKFRQ_VADDR; return 0; } -- cgit v1.2.3-55-g7522 From f63b6d7555cd4064554b39da4d44c4cbbc9d6a4a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 18 Feb 2014 16:00:05 +0400 Subject: xtensa: wire up sched_setattr and sched_getattr syscalls Signed-off-by: Max Filippov --- arch/xtensa/include/uapi/asm/unistd.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 51940fec6990..b9395529f02d 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -734,7 +734,12 @@ __SYSCALL(332, sys_finit_module, 3) #define __NR_accept4 333 __SYSCALL(333, sys_accept4, 4) -#define __NR_syscall_count 334 +#define __NR_sched_setattr 334 +__SYSCALL(334, sys_sched_setattr, 2) +#define __NR_sched_getattr 335 +__SYSCALL(335, sys_sched_getattr, 3) + +#define __NR_syscall_count 336 /* * sysxtensa syscall handler -- cgit v1.2.3-55-g7522 From 411cf180fa00521f9bfb1d022e3ebf059a2d299f Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:07 +0100 Subject: perf/x86/uncore: fix initialization of cpumask On certain processors, the uncore PMU boxes may only be msr-bsed or PCI-based. But in both cases, the cpumask, suggesting on which CPUs to monitor to get full coverage of the particular PMU, must be created. However with the current code base, the cpumask was only created on processor which had at least one MSR-based uncore PMU. This patch removes that restriction and ensures the cpumask is created even when there is no msr-based PMU. For instance, on SNB client where only a PCI-based memory controller PMU is supported. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-2-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 61 ++++++++++++++++----------- 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 29c248799ced..fe4255b9be55 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -3764,7 +3764,7 @@ static void __init uncore_cpu_setup(void *dummy) static int __init uncore_cpu_init(void) { - int ret, cpu, max_cores; + int ret, max_cores; max_cores = boot_cpu_data.x86_max_cores; switch (boot_cpu_data.x86_model) { @@ -3808,29 +3808,6 @@ static int __init uncore_cpu_init(void) if (ret) return ret; - get_online_cpus(); - - for_each_online_cpu(cpu) { - int i, phys_id = topology_physical_package_id(cpu); - - for_each_cpu(i, &uncore_cpu_mask) { - if (phys_id == topology_physical_package_id(i)) { - phys_id = -1; - break; - } - } - if (phys_id < 0) - continue; - - uncore_cpu_prepare(cpu, phys_id); - uncore_event_init_cpu(cpu); - } - on_each_cpu(uncore_cpu_setup, NULL, 1); - - register_cpu_notifier(&uncore_cpu_nb); - - put_online_cpus(); - return 0; } @@ -3859,6 +3836,41 @@ static int __init uncore_pmus_register(void) return 0; } +static void uncore_cpumask_init(void) +{ + int cpu; + + /* + * ony invoke once from msr or pci init code + */ + if (!cpumask_empty(&uncore_cpu_mask)) + return; + + get_online_cpus(); + + for_each_online_cpu(cpu) { + int i, phys_id = topology_physical_package_id(cpu); + + for_each_cpu(i, &uncore_cpu_mask) { + if (phys_id == topology_physical_package_id(i)) { + phys_id = -1; + break; + } + } + if (phys_id < 0) + continue; + + uncore_cpu_prepare(cpu, phys_id); + uncore_event_init_cpu(cpu); + } + on_each_cpu(uncore_cpu_setup, NULL, 1); + + register_cpu_notifier(&uncore_cpu_nb); + + put_online_cpus(); +} + + static int __init intel_uncore_init(void) { int ret; @@ -3877,6 +3889,7 @@ static int __init intel_uncore_init(void) uncore_pci_exit(); goto fail; } + uncore_cpumask_init(); uncore_pmus_register(); return 0; -- cgit v1.2.3-55-g7522 From d64b25b6a08d95e973160689320504faed62be4a Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:08 +0100 Subject: perf/x86/uncore: add ability to customize pmu callbacks This patch enables custom struct pmu callbacks per uncore PMU types. This feature may be used to simplify counter setup for certain uncore PMUs which have free running counters for instance. It becomes possible to bypass the event scheduling phase of the configuration. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-3-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 25 +++++++++++++++---------- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 1 + 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index fe4255b9be55..e6f32b36c9be 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -3271,16 +3271,21 @@ static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) { int ret; - pmu->pmu = (struct pmu) { - .attr_groups = pmu->type->attr_groups, - .task_ctx_nr = perf_invalid_context, - .event_init = uncore_pmu_event_init, - .add = uncore_pmu_event_add, - .del = uncore_pmu_event_del, - .start = uncore_pmu_event_start, - .stop = uncore_pmu_event_stop, - .read = uncore_pmu_event_read, - }; + if (!pmu->type->pmu) { + pmu->pmu = (struct pmu) { + .attr_groups = pmu->type->attr_groups, + .task_ctx_nr = perf_invalid_context, + .event_init = uncore_pmu_event_init, + .add = uncore_pmu_event_add, + .del = uncore_pmu_event_del, + .start = uncore_pmu_event_start, + .stop = uncore_pmu_event_stop, + .read = uncore_pmu_event_read, + }; + } else { + pmu->pmu = *pmu->type->pmu; + pmu->pmu.attr_groups = pmu->type->attr_groups; + } if (pmu->type->num_boxes == 1) { if (strlen(pmu->type->name) > 0) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index a80ab71a883d..77dc9a575fd9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -440,6 +440,7 @@ struct intel_uncore_type { struct intel_uncore_ops *ops; struct uncore_event_desc *event_descs; const struct attribute_group *attr_groups[4]; + struct pmu *pmu; /* for custom pmu ops */ }; #define pmu_group attr_groups[0] -- cgit v1.2.3-55-g7522 From 79859cce5a551c3bcd8d36a6287f9d83568ccedb Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:10 +0100 Subject: perf/x86/uncore: make hrtimer timeout configurable per box This patch makes the hrtimer timeout configurable per PMU box. Not all counters have necessarily the same width and rate, thus the default timeout of 60s may need to be adjusted. This patch adds box->hrtimer_duration. It is set to default when the box is allocated. It can be overriden when the box is initialized. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-5-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 7 +++++-- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index e6f32b36c9be..ea823b8fd592 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -2798,14 +2798,14 @@ static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) local_irq_restore(flags); - hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL)); + hrtimer_forward_now(hrtimer, ns_to_ktime(box->hrtimer_duration)); return HRTIMER_RESTART; } static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) { __hrtimer_start_range_ns(&box->hrtimer, - ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0, + ns_to_ktime(box->hrtimer_duration), 0, HRTIMER_MODE_REL_PINNED, 0); } @@ -2839,6 +2839,9 @@ static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, box->cpu = -1; box->phys_id = -1; + /* set default hrtimer timeout */ + box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL; + return box; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 77dc9a575fd9..7efd298f6c6b 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -489,6 +489,7 @@ struct intel_uncore_box { u64 tags[UNCORE_PMC_IDX_MAX]; struct pci_dev *pci_dev; struct intel_uncore_pmu *pmu; + u64 hrtimer_duration; /* hrtimer timeout for this box */ struct hrtimer hrtimer; struct list_head list; struct intel_uncore_extra_reg shared_regs[0]; -- cgit v1.2.3-55-g7522 From 001e413f7e7a4a68dc1c3231f72b5be173939c8f Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:11 +0100 Subject: perf/x86/uncore: move uncore_event_to_box() and uncore_pmu_to_box() Move a couple of functions around to avoid forward declarations when we add code later on. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-6-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 72 +++++++++++++-------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index ea823b8fd592..acbbdde5751c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -66,6 +66,42 @@ DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); +static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) +{ + return container_of(event->pmu, struct intel_uncore_pmu, pmu); +} + +static struct intel_uncore_box * +uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) +{ + struct intel_uncore_box *box; + + box = *per_cpu_ptr(pmu->box, cpu); + if (box) + return box; + + raw_spin_lock(&uncore_box_lock); + list_for_each_entry(box, &pmu->box_list, list) { + if (box->phys_id == topology_physical_package_id(cpu)) { + atomic_inc(&box->refcnt); + *per_cpu_ptr(pmu->box, cpu) = box; + break; + } + } + raw_spin_unlock(&uncore_box_lock); + + return *per_cpu_ptr(pmu->box, cpu); +} + +static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) +{ + /* + * perf core schedules event on the basis of cpu, uncore events are + * collected by one of the cpus inside a physical package. + */ + return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id()); +} + static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) { u64 count; @@ -2845,42 +2881,6 @@ static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, return box; } -static struct intel_uncore_box * -uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) -{ - struct intel_uncore_box *box; - - box = *per_cpu_ptr(pmu->box, cpu); - if (box) - return box; - - raw_spin_lock(&uncore_box_lock); - list_for_each_entry(box, &pmu->box_list, list) { - if (box->phys_id == topology_physical_package_id(cpu)) { - atomic_inc(&box->refcnt); - *per_cpu_ptr(pmu->box, cpu) = box; - break; - } - } - raw_spin_unlock(&uncore_box_lock); - - return *per_cpu_ptr(pmu->box, cpu); -} - -static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) -{ - return container_of(event->pmu, struct intel_uncore_pmu, pmu); -} - -static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) -{ - /* - * perf core schedules event on the basis of cpu, uncore events are - * collected by one of the cpus inside a physical package. - */ - return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id()); -} - static int uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp) { -- cgit v1.2.3-55-g7522 From b9e1ab6d4c0582cad97699285a6b3cf992251b00 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:12 +0100 Subject: perf/x86/uncore: add SNB/IVB/HSW client uncore memory controller support This patch adds a new uncore PMU for Intel SNB/IVB/HSW client CPUs. It adds the Integrated Memory Controller (IMC) PMU. This new PMU provides a set of events to measure memory bandwidth utilization. The IMC on those processor is PCI-space based. This patch exposes a new uncore PMU on those processor: uncore_imc Two new events are defined: - name: data_reads - code: 0x1 - unit: 64 bytes - number of full cacheline read requests to the IMC - name: data_writes - code: 0x2 - unit: 64 bytes - number of full cacheline write requests to the IMC Documentation available at: http://software.intel.com/en-us/articles/monitoring-integrated-memory-controller-requests-in-the-2nd-3rd-and-4th-generation-intel Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-7-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 365 ++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_uncore.h | 1 + 2 files changed, 366 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index acbbdde5751c..66ce5e50cb44 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -66,6 +66,11 @@ DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); +static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box); +static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box); +static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event); +static void uncore_pmu_event_read(struct perf_event *event); + static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct intel_uncore_pmu, pmu); @@ -1667,6 +1672,344 @@ static struct intel_uncore_type *snb_msr_uncores[] = { &snb_uncore_cbox, NULL, }; + +enum { + SNB_PCI_UNCORE_IMC, +}; + +static struct uncore_event_desc snb_uncore_imc_events[] = { + INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"), + INTEL_UNCORE_EVENT_DESC(data_reads.scale, "64"), + INTEL_UNCORE_EVENT_DESC(data_reads.unit, "bytes"), + + INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"), + INTEL_UNCORE_EVENT_DESC(data_writes.scale, "64"), + INTEL_UNCORE_EVENT_DESC(data_writes.unit, "bytes"), + + { /* end: all zeroes */ }, +}; + +#define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff +#define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48 + +/* page size multiple covering all config regs */ +#define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000 + +#define SNB_UNCORE_PCI_IMC_DATA_READS 0x1 +#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050 +#define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2 +#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054 +#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE + +static struct attribute *snb_uncore_imc_formats_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group snb_uncore_imc_format_group = { + .name = "format", + .attrs = snb_uncore_imc_formats_attr, +}; + +static void snb_uncore_imc_init_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + u32 addr_lo, addr_hi; + resource_size_t addr; + + pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET, &addr_lo); + addr = addr_lo; + +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET+4, &addr_hi); + addr = ((resource_size_t)addr_hi << 32) | addr_lo; +#endif + + addr &= ~(PAGE_SIZE - 1); + + box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); +} + +static void snb_uncore_imc_enable_box(struct intel_uncore_box *box) +{} + +static void snb_uncore_imc_disable_box(struct intel_uncore_box *box) +{} + +static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{} + +static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{} + +static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + return (u64)*(unsigned int *)(box->io_addr + hwc->event_base); +} + +/* + * custom event_init() function because we define our own fixed, free + * running counters, so we do not want to conflict with generic uncore + * logic. Also simplifies processing + */ +static int snb_uncore_imc_event_init(struct perf_event *event) +{ + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + struct hw_perf_event *hwc = &event->hw; + u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK; + int idx, base; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + pmu = uncore_event_to_pmu(event); + /* no device found for this pmu */ + if (pmu->func_id < 0) + return -ENOENT; + + /* Sampling not supported yet */ + if (hwc->sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest || + event->attr.sample_period) /* no sampling */ + return -EINVAL; + + /* + * Place all uncore events for a particular physical package + * onto a single cpu + */ + if (event->cpu < 0) + return -EINVAL; + + /* check only supported bits are set */ + if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK) + return -EINVAL; + + box = uncore_pmu_to_box(pmu, event->cpu); + if (!box || box->cpu < 0) + return -EINVAL; + + event->cpu = box->cpu; + + event->hw.idx = -1; + event->hw.last_tag = ~0ULL; + event->hw.extra_reg.idx = EXTRA_REG_NONE; + event->hw.branch_reg.idx = EXTRA_REG_NONE; + /* + * check event is known (whitelist, determines counter) + */ + switch (cfg) { + case SNB_UNCORE_PCI_IMC_DATA_READS: + base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE; + idx = UNCORE_PMC_IDX_FIXED; + break; + case SNB_UNCORE_PCI_IMC_DATA_WRITES: + base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE; + idx = UNCORE_PMC_IDX_FIXED + 1; + break; + default: + return -EINVAL; + } + + /* must be done before validate_group */ + event->hw.event_base = base; + event->hw.config = cfg; + event->hw.idx = idx; + + /* no group validation needed, we have free running counters */ + + return 0; +} + +static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + return 0; +} + +static void snb_uncore_imc_event_start(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + u64 count; + + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + + event->hw.state = 0; + box->n_active++; + + list_add_tail(&event->active_entry, &box->active_list); + + count = snb_uncore_imc_read_counter(box, event); + local64_set(&event->hw.prev_count, count); + + if (box->n_active == 1) + uncore_pmu_start_hrtimer(box); +} + +static void snb_uncore_imc_event_stop(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + + if (!(hwc->state & PERF_HES_STOPPED)) { + box->n_active--; + + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + + list_del(&event->active_entry); + + if (box->n_active == 0) + uncore_pmu_cancel_hrtimer(box); + } + + if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { + /* + * Drain the remaining delta count out of a event + * that we are disabling: + */ + uncore_perf_event_update(box, event); + hwc->state |= PERF_HES_UPTODATE; + } +} + +static int snb_uncore_imc_event_add(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + + if (!box) + return -ENODEV; + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + if (!(flags & PERF_EF_START)) + hwc->state |= PERF_HES_ARCH; + + snb_uncore_imc_event_start(event, 0); + + box->n_events++; + + return 0; +} + +static void snb_uncore_imc_event_del(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + int i; + + snb_uncore_imc_event_stop(event, PERF_EF_UPDATE); + + for (i = 0; i < box->n_events; i++) { + if (event == box->event_list[i]) { + --box->n_events; + break; + } + } +} + +static int snb_pci2phy_map_init(int devid) +{ + struct pci_dev *dev = NULL; + int bus; + + dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev); + if (!dev) + return -ENOTTY; + + bus = dev->bus->number; + + pcibus_to_physid[bus] = 0; + + pci_dev_put(dev); + + return 0; +} + +static struct pmu snb_uncore_imc_pmu = { + .task_ctx_nr = perf_invalid_context, + .event_init = snb_uncore_imc_event_init, + .add = snb_uncore_imc_event_add, + .del = snb_uncore_imc_event_del, + .start = snb_uncore_imc_event_start, + .stop = snb_uncore_imc_event_stop, + .read = uncore_pmu_event_read, +}; + +static struct intel_uncore_ops snb_uncore_imc_ops = { + .init_box = snb_uncore_imc_init_box, + .enable_box = snb_uncore_imc_enable_box, + .disable_box = snb_uncore_imc_disable_box, + .disable_event = snb_uncore_imc_disable_event, + .enable_event = snb_uncore_imc_enable_event, + .hw_config = snb_uncore_imc_hw_config, + .read_counter = snb_uncore_imc_read_counter, +}; + +static struct intel_uncore_type snb_uncore_imc = { + .name = "imc", + .num_counters = 2, + .num_boxes = 1, + .fixed_ctr_bits = 32, + .fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE, + .event_descs = snb_uncore_imc_events, + .format_group = &snb_uncore_imc_format_group, + .perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE, + .event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK, + .ops = &snb_uncore_imc_ops, + .pmu = &snb_uncore_imc_pmu, +}; + +static struct intel_uncore_type *snb_pci_uncores[] = { + [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc, + NULL, +}; + +static DEFINE_PCI_DEVICE_TABLE(snb_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, +}; + +static DEFINE_PCI_DEVICE_TABLE(ivb_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, +}; + +static DEFINE_PCI_DEVICE_TABLE(hsw_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, +}; + +static struct pci_driver snb_uncore_pci_driver = { + .name = "snb_uncore", + .id_table = snb_uncore_pci_ids, +}; + +static struct pci_driver ivb_uncore_pci_driver = { + .name = "ivb_uncore", + .id_table = ivb_uncore_pci_ids, +}; + +static struct pci_driver hsw_uncore_pci_driver = { + .name = "hsw_uncore", + .id_table = hsw_uncore_pci_ids, +}; + /* end of Sandy Bridge uncore support */ /* Nehalem uncore support */ @@ -3501,6 +3844,28 @@ static int __init uncore_pci_init(void) pci_uncores = ivt_pci_uncores; uncore_pci_driver = &ivt_uncore_pci_driver; break; + case 42: /* Sandy Bridge */ + ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_SNB_IMC); + if (ret) + return ret; + pci_uncores = snb_pci_uncores; + uncore_pci_driver = &snb_uncore_pci_driver; + break; + case 58: /* Ivy Bridge */ + ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_IVB_IMC); + if (ret) + return ret; + pci_uncores = snb_pci_uncores; + uncore_pci_driver = &ivb_uncore_pci_driver; + break; + case 60: /* Haswell */ + case 69: /* Haswell Celeron */ + ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_HSW_IMC); + if (ret) + return ret; + pci_uncores = snb_pci_uncores; + uncore_pci_driver = &hsw_uncore_pci_driver; + break; default: return 0; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 7efd298f6c6b..fbf45a0ebf92 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -492,6 +492,7 @@ struct intel_uncore_box { u64 hrtimer_duration; /* hrtimer timeout for this box */ struct hrtimer hrtimer; struct list_head list; + void *io_addr; struct intel_uncore_extra_reg shared_regs[0]; }; -- cgit v1.2.3-55-g7522 From ced2efb099f4f24ea7030c22b064e5ddd65cd764 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:13 +0100 Subject: perf/x86/uncore: add hrtimer to SNB uncore IMC PMU This patch is needed because that PMU uses 32-bit free running counters with no interrupt capabilities. On SNB/IVB/HSW, we used 20GB/s theoretical peak to calculate the hrtimer timeout necessary to avoid missing an overflow. That delay is set to 5s to be on the cautious side. The SNB IMC uses free running counters, which are handled via pseudo fixed counters. The SNB IMC PMU implementation supports an arbitrary number of events, because the counters are read-only. Therefore it is not possible to track active counters. Instead we put active events on a linked list which is then used by the hrtimer handler to update the SW counts. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-8-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 12 ++++++++++++ arch/x86/kernel/cpu/perf_event_intel_uncore.h | 2 ++ 2 files changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 66ce5e50cb44..7760aeeefeac 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1728,6 +1728,7 @@ static void snb_uncore_imc_init_box(struct intel_uncore_box *box) addr &= ~(PAGE_SIZE - 1); box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); + box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL; } static void snb_uncore_imc_enable_box(struct intel_uncore_box *box) @@ -3160,6 +3161,7 @@ again: static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) { struct intel_uncore_box *box; + struct perf_event *event; unsigned long flags; int bit; @@ -3172,6 +3174,14 @@ static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) */ local_irq_save(flags); + /* + * handle boxes with an active event list as opposed to active + * counters + */ + list_for_each_entry(event, &box->active_list, active_entry) { + uncore_perf_event_update(box, event); + } + for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX) uncore_perf_event_update(box, box->events[bit]); @@ -3221,6 +3231,8 @@ static struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, /* set default hrtimer timeout */ box->hrtimer_duration = UNCORE_PMU_HRTIMER_INTERVAL; + INIT_LIST_HEAD(&box->active_list); + return box; } diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index fbf45a0ebf92..90236f0c94a9 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -6,6 +6,7 @@ #define UNCORE_PMU_NAME_LEN 32 #define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC) +#define UNCORE_SNB_IMC_HRTIMER_INTERVAL (5ULL * NSEC_PER_SEC) #define UNCORE_FIXED_EVENT 0xff #define UNCORE_PMC_IDX_MAX_GENERIC 8 @@ -492,6 +493,7 @@ struct intel_uncore_box { u64 hrtimer_duration; /* hrtimer timeout for this box */ struct hrtimer hrtimer; struct list_head list; + struct list_head active_list; void *io_addr; struct intel_uncore_extra_reg shared_regs[0]; }; -- cgit v1.2.3-55-g7522 From e9d9768824a18212712ae3afbebd5bfef05176f4 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 11 Feb 2014 16:20:14 +0100 Subject: perf/x86/uncore: use MiB unit for events for SNB/IVB/HSW IMC This patch makes perf use Mebibytes to display the counts of uncore_imc/data_reads/ and uncore_imc/data_writes. 1MiB = 1024*1024 bytes. Cc: mingo@elte.hu Cc: acme@redhat.com Cc: ak@linux.intel.com Cc: zheng.z.yan@intel.com Cc: peterz@infradead.org Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1392132015-14521-9-git-send-email-eranian@google.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 7760aeeefeac..de5c56899ae3 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1679,12 +1679,12 @@ enum { static struct uncore_event_desc snb_uncore_imc_events[] = { INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"), - INTEL_UNCORE_EVENT_DESC(data_reads.scale, "64"), - INTEL_UNCORE_EVENT_DESC(data_reads.unit, "bytes"), + INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"), INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"), - INTEL_UNCORE_EVENT_DESC(data_writes.scale, "64"), - INTEL_UNCORE_EVENT_DESC(data_writes.unit, "bytes"), + INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"), { /* end: all zeroes */ }, }; -- cgit v1.2.3-55-g7522 From deff82e688a278eb4b822fd616c05fc62907bb71 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 17 Feb 2014 22:30:58 +0100 Subject: ARM: OMAP2+: Add support for thumb mode on DT booted N900 Without enabling the workaround for ARM errata 430973 thumb compiled userland crashes randomly on the Nokia N900. Signed-off-by: Sebastian Reichel Reviewed-by: Pavel Machek Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 3d5b24dcd9a4..0cc710d0da90 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -22,6 +22,8 @@ #include "common-board-devices.h" #include "dss-common.h" #include "control.h" +#include "omap-secure.h" +#include "soc.h" struct pdata_init { const char *compatible; @@ -169,6 +171,22 @@ static void __init am3517_evm_legacy_init(void) omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ } + +static void __init nokia_n900_legacy_init(void) +{ + hsmmc2_internal_input_clk(); + + if (omap_type() == OMAP2_DEVICE_TYPE_SEC) { + if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) { + pr_info("RX-51: Enabling ARM errata 430973 workaround\n"); + /* set IBE to 1 */ + rx51_secure_update_aux_cr(BIT(6), 0); + } else { + pr_warning("RX-51: Not enabling ARM errata 430973 workaround\n"); + pr_warning("Thumb binaries may crash randomly without this workaround\n"); + } + } +} #endif /* CONFIG_ARCH_OMAP3 */ #ifdef CONFIG_ARCH_OMAP4 @@ -259,7 +277,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { static struct pdata_init pdata_quirks[] __initdata = { #ifdef CONFIG_ARCH_OMAP3 { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_legacy_init, }, - { "nokia,omap3-n900", hsmmc2_internal_input_clk, }, + { "nokia,omap3-n900", nokia_n900_legacy_init, }, { "nokia,omap3-n9", hsmmc2_internal_input_clk, }, { "nokia,omap3-n950", hsmmc2_internal_input_clk, }, { "isee,omap3-igep0020", omap3_igep0020_legacy_init, }, -- cgit v1.2.3-55-g7522 From 865da01cd98d67518befe854a71e432d894db279 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Mon, 17 Feb 2014 13:22:55 +0530 Subject: ARM: OMAP: Kill warning in CPUIDLE code with !CONFIG_SMP for non SMP build, NR_CPUS is 1 and hence the code complains with below warnings. arch/arm/mach-omap2/cpuidle44xx.c:207:8: warning: array subscript is above array bounds [-Warray-bounds] arch/arm/mach-omap2/cpuidle44xx.c:212:11: warning: array subscript is above array bounds [-Warray-bounds] Kill it by making array size fixed. Acked-by: Nishanth Menon Signed-off-by: Santosh Shilimkar Signed-off-by: Mugunthan V N Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cpuidle44xx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 4c158c838d40..01fc710c8181 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -23,6 +23,8 @@ #include "prm.h" #include "clockdomain.h" +#define MAX_CPUS 2 + /* Machine specific information */ struct idle_statedata { u32 cpu_state; @@ -48,11 +50,11 @@ static struct idle_statedata omap4_idle_data[] = { }, }; -static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS]; -static struct clockdomain *cpu_clkdm[NR_CPUS]; +static struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS]; +static struct clockdomain *cpu_clkdm[MAX_CPUS]; static atomic_t abort_barrier; -static bool cpu_done[NR_CPUS]; +static bool cpu_done[MAX_CPUS]; static struct idle_statedata *state_ptr = &omap4_idle_data[0]; /* Private functions */ -- cgit v1.2.3-55-g7522 From 591ac0cb01ec8d0ff131a318f9b9abf6ecab6225 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 17 Feb 2014 10:59:29 -0500 Subject: cpuidle/powernv: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. We need to add the runlatch function calls to the idle routines which was earlier taken care of by the arch specific idle routine. Signed-off-by: Nicolas Pitre Signed-off-by: Preeti U Murthy Reviewed-by: Deepthi Dharwar Signed-off-by: Peter Zijlstra Cc: Paul Burton Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: linux-pm@vger.kernel.org Cc: linaro-kernel@lists.linaro.org Link: http://lkml.kernel.org/n/tip-nr4mtbkkzf2oomaj85m24o7c@git.kernel.org Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/powerpc/platforms/powernv/setup.c | 13 +------------ drivers/cpuidle/cpuidle-powernv.c | 5 +++++ 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 110f4fbd319f..81a7a0a79be7 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -225,16 +224,6 @@ static int __init pnv_probe(void) return 1; } -void powernv_idle(void) -{ - /* Hook to cpuidle framework if available, else - * call on default platform idle code - */ - if (cpuidle_idle_call()) { - power7_idle(); - } -} - define_machine(powernv) { .name = "PowerNV", .probe = pnv_probe, @@ -244,7 +233,7 @@ define_machine(powernv) { .show_cpuinfo = pnv_show_cpuinfo, .progress = pnv_progress, .machine_shutdown = pnv_shutdown, - .power_save = powernv_idle, + .power_save = power7_idle, .calibrate_decr = generic_calibrate_decr, .dma_set_mask = pnv_dma_set_mask, #ifdef CONFIG_KEXEC diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 78fd174c57e8..f48607cd2540 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -14,6 +14,7 @@ #include #include +#include struct cpuidle_driver powernv_idle_driver = { .name = "powernv_idle", @@ -30,12 +31,14 @@ static int snooze_loop(struct cpuidle_device *dev, local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); + ppc64_runlatch_off(); while (!need_resched()) { HMT_low(); HMT_very_low(); } HMT_medium(); + ppc64_runlatch_on(); clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb(); return index; @@ -45,7 +48,9 @@ static int nap_loop(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { + ppc64_runlatch_off(); power7_idle(); + ppc64_runlatch_on(); return index; } -- cgit v1.2.3-55-g7522 From 6990566b535908905b4eccda7cc9e09c2db52187 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 17 Feb 2014 10:59:30 -0500 Subject: cpuidle/arm64: Remove redundant cpuidle_idle_call() The core idle loop now takes care of it. Signed-off-by: Nicolas Pitre Acked-by: Catalin Marinas Signed-off-by: Peter Zijlstra Cc: Paul Burton Cc: Deepthi Dharwar Cc: Preeti U Murthy Cc: "Rafael J. Wysocki" Cc: Daniel Lezcano Cc: linux-pm@vger.kernel.org Cc: linaro-kernel@lists.linaro.org Link: http://lkml.kernel.org/n/tip-wk9vpc8dsn46s12pl602ljpo@git.kernel.org Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/arm64/kernel/process.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1c0a9be2ffa8..9cce0098f4cd 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -94,10 +93,8 @@ void arch_cpu_idle(void) * This should do all the clock switching and wait for interrupt * tricks */ - if (cpuidle_idle_call()) { - cpu_do_idle(); - local_irq_enable(); - } + cpu_do_idle(); + local_irq_enable(); } #ifdef CONFIG_HOTPLUG_CPU -- cgit v1.2.3-55-g7522 From 823002023da6d9124ed63bc622267c15ab2a7347 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 24 Feb 2014 16:18:55 +0100 Subject: s390/uaccess: remove copy_from_user_real() There is no user left, so remove it. It was also potentially broken, since the function didn't clear destination memory if copy_from_user() failed. Which would allow for information leaks. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/uaccess.h | 1 - arch/s390/mm/maccess.c | 26 -------------------------- 2 files changed, 27 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 2710b41eed22..4133b3f72fb0 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -344,6 +344,5 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo } int copy_to_user_real(void __user *dest, void *src, unsigned long count); -int copy_from_user_real(void *dest, void __user *src, unsigned long count); #endif /* __S390_UACCESS_H */ diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index efe8ad045c7b..2a2e35416d2f 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -151,32 +151,6 @@ out: return rc; } -/* - * Copy memory from user (virtual) to kernel (real) - */ -int copy_from_user_real(void *dest, void __user *src, unsigned long count) -{ - int offs = 0, size, rc; - char *buf; - - buf = (char *) __get_free_page(GFP_KERNEL); - if (!buf) - return -ENOMEM; - rc = -EFAULT; - while (offs < count) { - size = min(PAGE_SIZE, count - offs); - if (copy_from_user(buf, src + offs, size)) - goto out; - if (memcpy_real(dest + offs, buf, size)) - goto out; - offs += size; - } - rc = 0; -out: - free_page((unsigned long) buf); - return rc; -} - /* * Check if physical address is within prefix or zero page */ -- cgit v1.2.3-55-g7522 From d72d2bb5a6bc85af77a9f969687c74ea00cdcc99 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 24 Feb 2014 16:33:08 +0100 Subject: s390/checksum: remove memset() within csum_partial_copy_from_user() The memset() within csum_partial_copy_from_user() is rather pointless since copy_from_user() already cleared the rest of the destination buffer if an exception happened. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/checksum.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index 4f57a4f3909a..740364856355 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -44,22 +44,15 @@ csum_partial(const void *buff, int len, __wsum sum) * here even more important to align src and dst on a 32-bit (or even * better 64-bit) boundary * - * Copy from userspace and compute checksum. If we catch an exception - * then zero the rest of the buffer. + * Copy from userspace and compute checksum. */ static inline __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr) { - int missing; - - missing = copy_from_user(dst, src, len); - if (missing) { - memset(dst + len - missing, 0, missing); + if (unlikely(copy_from_user(dst, src, len))) *err_ptr = -EFAULT; - } - return csum_partial(dst, len, sum); } -- cgit v1.2.3-55-g7522 From a2530060c1157a7863abbe1fea3cfdd5da55bd48 Mon Sep 17 00:00:00 2001 From: Sherman Yin Date: Thu, 23 Jan 2014 12:44:47 -0800 Subject: Update dtsi with new pinctrl compatible string This commit updates bcm11351.dtsi with the new compatible string for the same driver. Signed-off-by: Sherman Yin Reviewed-by: Matt Porter Acked-by: Linus Walleij Signed-off-by: Christian Daudt --- arch/arm/boot/dts/bcm11351.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi index e491b82f8d67..792fde1b7f75 100644 --- a/arch/arm/boot/dts/bcm11351.dtsi +++ b/arch/arm/boot/dts/bcm11351.dtsi @@ -147,7 +147,7 @@ }; pinctrl@35004800 { - compatible = "brcm,capri-pinctrl"; + compatible = "brcm,bcm11351-pinctrl"; reg = <0x35004800 0x430>; }; -- cgit v1.2.3-55-g7522 From b6085a865762236bb84934161273cdac6dd11c2d Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Thu, 23 Jan 2014 09:31:20 -0800 Subject: x86, kaslr: export offset in VMCOREINFO ELF notes Include kASLR offset in VMCOREINFO ELF notes to assist in debugging. [ hpa: pushing this for v3.14 to avoid having a kernel version with kASLR where we can't debug output. ] Signed-off-by: Eugene Surovegin Link: http://lkml.kernel.org/r/20140123173120.GA25474@www.outflux.net Signed-off-by: Kees Cook Signed-off-by: H. Peter Anvin --- arch/x86/kernel/machine_kexec_64.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 4eabc160696f..679cef0791cd 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -279,5 +279,7 @@ void arch_crash_save_vmcoreinfo(void) VMCOREINFO_SYMBOL(node_data); VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); #endif + vmcoreinfo_append_str("KERNELOFFSET=%lx\n", + (unsigned long)&_text - __START_KERNEL); } -- cgit v1.2.3-55-g7522 From e290e8c59dbc2a15088d868170d799f763202fef Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 9 Feb 2014 13:56:44 -0800 Subject: x86, kaslr: add missed "static" declarations This silences build warnings about unexported variables and functions. Signed-off-by: Kees Cook Link: http://lkml.kernel.org/r/20140209215644.GA30339@www.outflux.net Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/aslr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index 90a21f430117..4dbf967da50d 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c @@ -111,7 +111,7 @@ struct mem_vector { }; #define MEM_AVOID_MAX 5 -struct mem_vector mem_avoid[MEM_AVOID_MAX]; +static struct mem_vector mem_avoid[MEM_AVOID_MAX]; static bool mem_contains(struct mem_vector *region, struct mem_vector *item) { @@ -180,7 +180,7 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, } /* Does this memory vector overlap a known avoided area? */ -bool mem_avoid_overlap(struct mem_vector *img) +static bool mem_avoid_overlap(struct mem_vector *img) { int i; @@ -192,8 +192,9 @@ bool mem_avoid_overlap(struct mem_vector *img) return false; } -unsigned long slots[CONFIG_RANDOMIZE_BASE_MAX_OFFSET / CONFIG_PHYSICAL_ALIGN]; -unsigned long slot_max = 0; +static unsigned long slots[CONFIG_RANDOMIZE_BASE_MAX_OFFSET / + CONFIG_PHYSICAL_ALIGN]; +static unsigned long slot_max; static void slots_append(unsigned long addr) { -- cgit v1.2.3-55-g7522 From e2b32e6785138d92d2a40e0d0473575c8c7310a2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 25 Feb 2014 16:59:17 -0800 Subject: x86, kaslr: randomize module base load address Randomize the load address of modules in the kernel to make kASLR effective for modules. Modules can only be loaded within a particular range of virtual address space. This patch adds 10 bits of entropy to the load address by adding 1-1024 * PAGE_SIZE to the beginning range where modules are loaded. The single base offset was chosen because randomizing each module load ends up wasting/fragmenting memory too much. Prior approaches to minimizing fragmentation while doing randomization tend to result in worse entropy than just doing a single base address offset. Example kASLR boot without this change, with a single module loaded: ---[ Modules ]--- 0xffffffffc0000000-0xffffffffc0001000 4K ro GLB x pte 0xffffffffc0001000-0xffffffffc0002000 4K ro GLB NX pte 0xffffffffc0002000-0xffffffffc0004000 8K RW GLB NX pte 0xffffffffc0004000-0xffffffffc0200000 2032K pte 0xffffffffc0200000-0xffffffffff000000 1006M pmd ---[ End Modules ]--- Example kASLR boot after this change, same module loaded: ---[ Modules ]--- 0xffffffffc0000000-0xffffffffc0200000 2M pmd 0xffffffffc0200000-0xffffffffc03bf000 1788K pte 0xffffffffc03bf000-0xffffffffc03c0000 4K ro GLB x pte 0xffffffffc03c0000-0xffffffffc03c1000 4K ro GLB NX pte 0xffffffffc03c1000-0xffffffffc03c3000 8K RW GLB NX pte 0xffffffffc03c3000-0xffffffffc0400000 244K pte 0xffffffffc0400000-0xffffffffff000000 1004M pmd ---[ End Modules ]--- Signed-off-by: Andy Honig Link: http://lkml.kernel.org/r/20140226005916.GA27083@www.outflux.net Signed-off-by: Kees Cook Signed-off-by: H. Peter Anvin --- Documentation/kernel-parameters.txt | 4 ++-- arch/x86/kernel/module.c | 43 ++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7116fda7077f..580a60cabd9b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2053,8 +2053,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. IOAPICs that may be present in the system. nokaslr [X86] - Disable kernel base offset ASLR (Address Space - Layout Randomization) if built into the kernel. + Disable kernel and module base offset ASLR (Address + Space Layout Randomization) if built into the kernel. noautogroup Disable scheduler automatic task group creation. diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 18be189368bb..49483137371f 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -43,13 +44,49 @@ do { \ } while (0) #endif +#ifdef CONFIG_RANDOMIZE_BASE +static unsigned long module_load_offset; +static int randomize_modules = 1; + +static int __init parse_nokaslr(char *p) +{ + randomize_modules = 0; + return 0; +} +early_param("nokaslr", parse_nokaslr); + +static unsigned long int get_module_load_offset(void) +{ + if (randomize_modules) { + mutex_lock(&module_mutex); + /* + * Calculate the module_load_offset the first time this + * code is called. Once calculated it stays the same until + * reboot. + */ + if (module_load_offset == 0) + module_load_offset = + (get_random_int() % 1024 + 1) * PAGE_SIZE; + mutex_unlock(&module_mutex); + } + return module_load_offset; +} +#else +static unsigned long int get_module_load_offset(void) +{ + return 0; +} +#endif + void *module_alloc(unsigned long size) { if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; - return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, - NUMA_NO_NODE, __builtin_return_address(0)); + return __vmalloc_node_range(size, 1, + MODULES_VADDR + get_module_load_offset(), + MODULES_END, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXEC, NUMA_NO_NODE, + __builtin_return_address(0)); } #ifdef CONFIG_X86_32 -- cgit v1.2.3-55-g7522 From c7db4ff5d2b459a579d348532a92fd5885520ce6 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Tue, 28 Jan 2014 11:20:17 +0000 Subject: arm64: Add macros to manage processor debug state Add macros to enable and disable to manage PSTATE.D for debugging. The macros local_dbg_save and local_dbg_restore are moved to irqflags.h file KGDB boot tests fail because of PSTATE.D is masked. unmask it for debugging support Signed-off-by: Vijaya Kumar K Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/debug-monitors.h | 17 ----------------- arch/arm64/include/asm/irqflags.h | 23 +++++++++++++++++++++++ arch/arm64/kernel/debug-monitors.c | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 62314791570c..ee9f28e245aa 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h @@ -43,23 +43,6 @@ enum debug_el { #ifndef __ASSEMBLY__ struct task_struct; -#define local_dbg_save(flags) \ - do { \ - typecheck(unsigned long, flags); \ - asm volatile( \ - "mrs %0, daif // local_dbg_save\n" \ - "msr daifset, #8" \ - : "=r" (flags) : : "memory"); \ - } while (0) - -#define local_dbg_restore(flags) \ - do { \ - typecheck(unsigned long, flags); \ - asm volatile( \ - "msr daif, %0 // local_dbg_restore\n" \ - : : "r" (flags) : "memory"); \ - } while (0) - #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */ #define DBG_HOOK_HANDLED 0 diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h index b2fcfbc51ecc..11cc941bd107 100644 --- a/arch/arm64/include/asm/irqflags.h +++ b/arch/arm64/include/asm/irqflags.h @@ -90,5 +90,28 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) return flags & PSR_I_BIT; } +/* + * save and restore debug state + */ +#define local_dbg_save(flags) \ + do { \ + typecheck(unsigned long, flags); \ + asm volatile( \ + "mrs %0, daif // local_dbg_save\n" \ + "msr daifset, #8" \ + : "=r" (flags) : : "memory"); \ + } while (0) + +#define local_dbg_restore(flags) \ + do { \ + typecheck(unsigned long, flags); \ + asm volatile( \ + "msr daif, %0 // local_dbg_restore\n" \ + : : "r" (flags) : "memory"); \ + } while (0) + +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory") +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory") + #endif #endif diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 636ba8b6240b..1a8127da625b 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -138,6 +138,7 @@ static void clear_os_lock(void *unused) { asm volatile("msr oslar_el1, %0" : : "r" (0)); isb(); + local_dbg_enable(); } static int os_lock_notify(struct notifier_block *self, -- cgit v1.2.3-55-g7522 From bcf5763b0d58d20e288ac52f96cbd7788e262cac Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Tue, 28 Jan 2014 16:50:18 +0530 Subject: arm64: KGDB: Add Basic KGDB support Add KGDB debug support for kernel debugging. With this patch, basic KGDB debugging is possible.GDB register layout is updated and GDB tool can establish connection with target and can set/clear breakpoints. Signed-off-by: Vijaya Kumar K Reviewed-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/debug-monitors.h | 47 ++++++ arch/arm64/include/asm/kgdb.h | 84 ++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/kgdb.c | 288 ++++++++++++++++++++++++++++++++ 4 files changed, 420 insertions(+) create mode 100644 arch/arm64/include/asm/kgdb.h create mode 100644 arch/arm64/kernel/kgdb.c (limited to 'arch') diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index ee9f28e245aa..6e9b5b36921c 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h @@ -26,6 +26,53 @@ #define DBG_ESR_EVT_HWWP 0x2 #define DBG_ESR_EVT_BRK 0x6 +/* + * Break point instruction encoding + */ +#define BREAK_INSTR_SIZE 4 + +/* + * ESR values expected for dynamic and compile time BRK instruction + */ +#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff)) + +/* + * #imm16 values used for BRK instruction generation + * Allowed values for kgbd are 0x400 - 0x7ff + * 0x400: for dynamic BRK instruction + * 0x401: for compile time BRK instruction + */ +#define KGDB_DYN_DGB_BRK_IMM 0x400 +#define KDBG_COMPILED_DBG_BRK_IMM 0x401 + +/* + * BRK instruction encoding + * The #imm16 value should be placed at bits[20:5] within BRK ins + */ +#define AARCH64_BREAK_MON 0xd4200000 + +/* + * Extract byte from BRK instruction + */ +#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \ + ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff) + +/* + * Extract byte from BRK #imm16 + */ +#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \ + (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff) + +#define KGDB_DYN_DGB_BRK_BYTE(x) \ + (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x)) + +#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0) +#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1) +#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2) +#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3) + +#define CACHE_FLUSH_IS_SAFE 1 + enum debug_el { DBG_ACTIVE_EL0 = 0, DBG_ACTIVE_EL1, diff --git a/arch/arm64/include/asm/kgdb.h b/arch/arm64/include/asm/kgdb.h new file mode 100644 index 000000000000..3c8aafc1082f --- /dev/null +++ b/arch/arm64/include/asm/kgdb.h @@ -0,0 +1,84 @@ +/* + * AArch64 KGDB support + * + * Based on arch/arm/include/kgdb.h + * + * Copyright (C) 2013 Cavium Inc. + * Author: Vijaya Kumar K + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ARM_KGDB_H +#define __ARM_KGDB_H + +#include +#include + +#ifndef __ASSEMBLY__ + +static inline void arch_kgdb_breakpoint(void) +{ + asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM)); +} + +extern void kgdb_handle_bus_error(void); +extern int kgdb_fault_expected; + +#endif /* !__ASSEMBLY__ */ + +/* + * gdb is expecting the following registers layout. + * + * General purpose regs: + * r0-r30: 64 bit + * sp,pc : 64 bit + * pstate : 64 bit + * Total: 34 + * FPU regs: + * f0-f31: 128 bit + * Total: 32 + * Extra regs + * fpsr & fpcr: 32 bit + * Total: 2 + * + */ + +#define _GP_REGS 34 +#define _FP_REGS 32 +#define _EXTRA_REGS 2 +/* + * general purpose registers size in bytes. + * pstate is only 4 bytes. subtract 4 bytes + */ +#define GP_REG_BYTES (_GP_REGS * 8) +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) + +/* + * Size of I/O buffer for gdb packet. + * considering to hold all register contents, size is set + */ + +#define BUFMAX 2048 + +/* + * Number of bytes required for gdb_regs buffer. + * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each + * GDB fails to connect for size beyond this with error + * "'g' packet reply is too long" + */ + +#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \ + (_EXTRA_REGS * 4)) + +#endif /* __ASM_KGDB_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 2d4554b13410..e52bcdc6f097 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o +arm64-obj-$(CONFIG_KGDB) += kgdb.o obj-y += $(arm64-obj-y) vdso/ obj-m += $(arm64-obj-m) diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c new file mode 100644 index 000000000000..4b7a5695175e --- /dev/null +++ b/arch/arm64/kernel/kgdb.c @@ -0,0 +1,288 @@ +/* + * AArch64 KGDB support + * + * Based on arch/arm/kernel/kgdb.c + * + * Copyright (C) 2013 Cavium Inc. + * Author: Vijaya Kumar K + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { + { "x0", 8, offsetof(struct pt_regs, regs[0])}, + { "x1", 8, offsetof(struct pt_regs, regs[1])}, + { "x2", 8, offsetof(struct pt_regs, regs[2])}, + { "x3", 8, offsetof(struct pt_regs, regs[3])}, + { "x4", 8, offsetof(struct pt_regs, regs[4])}, + { "x5", 8, offsetof(struct pt_regs, regs[5])}, + { "x6", 8, offsetof(struct pt_regs, regs[6])}, + { "x7", 8, offsetof(struct pt_regs, regs[7])}, + { "x8", 8, offsetof(struct pt_regs, regs[8])}, + { "x9", 8, offsetof(struct pt_regs, regs[9])}, + { "x10", 8, offsetof(struct pt_regs, regs[10])}, + { "x11", 8, offsetof(struct pt_regs, regs[11])}, + { "x12", 8, offsetof(struct pt_regs, regs[12])}, + { "x13", 8, offsetof(struct pt_regs, regs[13])}, + { "x14", 8, offsetof(struct pt_regs, regs[14])}, + { "x15", 8, offsetof(struct pt_regs, regs[15])}, + { "x16", 8, offsetof(struct pt_regs, regs[16])}, + { "x17", 8, offsetof(struct pt_regs, regs[17])}, + { "x18", 8, offsetof(struct pt_regs, regs[18])}, + { "x19", 8, offsetof(struct pt_regs, regs[19])}, + { "x20", 8, offsetof(struct pt_regs, regs[20])}, + { "x21", 8, offsetof(struct pt_regs, regs[21])}, + { "x22", 8, offsetof(struct pt_regs, regs[22])}, + { "x23", 8, offsetof(struct pt_regs, regs[23])}, + { "x24", 8, offsetof(struct pt_regs, regs[24])}, + { "x25", 8, offsetof(struct pt_regs, regs[25])}, + { "x26", 8, offsetof(struct pt_regs, regs[26])}, + { "x27", 8, offsetof(struct pt_regs, regs[27])}, + { "x28", 8, offsetof(struct pt_regs, regs[28])}, + { "x29", 8, offsetof(struct pt_regs, regs[29])}, + { "x30", 8, offsetof(struct pt_regs, regs[30])}, + { "sp", 8, offsetof(struct pt_regs, sp)}, + { "pc", 8, offsetof(struct pt_regs, pc)}, + { "pstate", 8, offsetof(struct pt_regs, pstate)}, + { "v0", 16, -1 }, + { "v1", 16, -1 }, + { "v2", 16, -1 }, + { "v3", 16, -1 }, + { "v4", 16, -1 }, + { "v5", 16, -1 }, + { "v6", 16, -1 }, + { "v7", 16, -1 }, + { "v8", 16, -1 }, + { "v9", 16, -1 }, + { "v10", 16, -1 }, + { "v11", 16, -1 }, + { "v12", 16, -1 }, + { "v13", 16, -1 }, + { "v14", 16, -1 }, + { "v15", 16, -1 }, + { "v16", 16, -1 }, + { "v17", 16, -1 }, + { "v18", 16, -1 }, + { "v19", 16, -1 }, + { "v20", 16, -1 }, + { "v21", 16, -1 }, + { "v22", 16, -1 }, + { "v23", 16, -1 }, + { "v24", 16, -1 }, + { "v25", 16, -1 }, + { "v26", 16, -1 }, + { "v27", 16, -1 }, + { "v28", 16, -1 }, + { "v29", 16, -1 }, + { "v30", 16, -1 }, + { "v31", 16, -1 }, + { "fpsr", 4, -1 }, + { "fpcr", 4, -1 }, +}; + +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) +{ + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return NULL; + + if (dbg_reg_def[regno].offset != -1) + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, + dbg_reg_def[regno].size); + else + memset(mem, 0, dbg_reg_def[regno].size); + return dbg_reg_def[regno].name; +} + +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) +{ + if (regno >= DBG_MAX_REG_NUM || regno < 0) + return -EINVAL; + + if (dbg_reg_def[regno].offset != -1) + memcpy((void *)regs + dbg_reg_def[regno].offset, mem, + dbg_reg_def[regno].size); + return 0; +} + +void +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) +{ + struct pt_regs *thread_regs; + + /* Initialize to zero */ + memset((char *)gdb_regs, 0, NUMREGBYTES); + thread_regs = task_pt_regs(task); + memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES); +} + +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) +{ + regs->pc = pc; +} + +static int compiled_break; + +int kgdb_arch_handle_exception(int exception_vector, int signo, + int err_code, char *remcom_in_buffer, + char *remcom_out_buffer, + struct pt_regs *linux_regs) +{ + unsigned long addr; + char *ptr; + int err; + + switch (remcom_in_buffer[0]) { + case 'D': + case 'k': + /* + * Packet D (Detach), k (kill). No special handling + * is required here. Handle same as c packet. + */ + case 'c': + /* + * Packet c (Continue) to continue executing. + * Set pc to required address. + * Try to read optional parameter and set pc. + * If this was a compiled breakpoint, we need to move + * to the next instruction else we will just breakpoint + * over and over again. + */ + ptr = &remcom_in_buffer[1]; + if (kgdb_hex2long(&ptr, &addr)) + kgdb_arch_set_pc(linux_regs, addr); + else if (compiled_break == 1) + kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4); + + compiled_break = 0; + err = 0; + break; + default: + err = -1; + } + return err; +} + +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr) +{ + kgdb_handle_exception(1, SIGTRAP, 0, regs); + return 0; +} + +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) +{ + compiled_break = 1; + kgdb_handle_exception(1, SIGTRAP, 0, regs); + + return 0; +} + +static struct break_hook kgdb_brkpt_hook = { + .esr_mask = 0xffffffff, + .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM), + .fn = kgdb_brk_fn +}; + +static struct break_hook kgdb_compiled_brkpt_hook = { + .esr_mask = 0xffffffff, + .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM), + .fn = kgdb_compiled_brk_fn +}; + +static void kgdb_call_nmi_hook(void *ignored) +{ + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); +} + +void kgdb_roundup_cpus(unsigned long flags) +{ + local_irq_enable(); + smp_call_function(kgdb_call_nmi_hook, NULL, 0); + local_irq_disable(); +} + +static int __kgdb_notify(struct die_args *args, unsigned long cmd) +{ + struct pt_regs *regs = args->regs; + + if (kgdb_handle_exception(1, args->signr, cmd, regs)) + return NOTIFY_DONE; + return NOTIFY_STOP; +} + +static int +kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) +{ + unsigned long flags; + int ret; + + local_irq_save(flags); + ret = __kgdb_notify(ptr, cmd); + local_irq_restore(flags); + + return ret; +} + +static struct notifier_block kgdb_notifier = { + .notifier_call = kgdb_notify, + /* + * Want to be lowest priority + */ + .priority = -INT_MAX, +}; + +/* + * kgdb_arch_init - Perform any architecture specific initalization. + * This function will handle the initalization of any architecture + * specific callbacks. + */ +int kgdb_arch_init(void) +{ + int ret = register_die_notifier(&kgdb_notifier); + + if (ret != 0) + return ret; + + register_break_hook(&kgdb_brkpt_hook); + register_break_hook(&kgdb_compiled_brkpt_hook); + return 0; +} + +/* + * kgdb_arch_exit - Perform any architecture specific uninitalization. + * This function will handle the uninitalization of any architecture + * specific callbacks, for dynamic registration and unregistration. + */ +void kgdb_arch_exit(void) +{ + unregister_break_hook(&kgdb_brkpt_hook); + unregister_break_hook(&kgdb_compiled_brkpt_hook); + unregister_die_notifier(&kgdb_notifier); +} + +/* + * ARM instructions are always in LE. + * Break instruction is encoded in LE format + */ +struct kgdb_arch arch_kgdb_ops = { + .gdb_bpt_instr = { + KGDB_DYN_BRK_INS_BYTE0, + KGDB_DYN_BRK_INS_BYTE1, + KGDB_DYN_BRK_INS_BYTE2, + KGDB_DYN_BRK_INS_BYTE3, + } +}; -- cgit v1.2.3-55-g7522 From 44679a4f142b69ae0c68ed815a48bbd164827281 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Tue, 28 Jan 2014 11:20:19 +0000 Subject: arm64: KGDB: Add step debugging support Add KGDB software step debugging support for EL1 debug in AArch64 mode. KGDB registers step debug handler with debug monitor. On receiving 'step' command from GDB tool, target enables software step debugging and step address is updated in ELR. Software Step debugging is disabled when 'continue' command is received Signed-off-by: Vijaya Kumar K Reviewed-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/kgdb.c | 64 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 4b7a5695175e..75c9cf1aafee 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) static int compiled_break; +static void kgdb_arch_update_addr(struct pt_regs *regs, + char *remcom_in_buffer) +{ + unsigned long addr; + char *ptr; + + ptr = &remcom_in_buffer[1]; + if (kgdb_hex2long(&ptr, &addr)) + kgdb_arch_set_pc(regs, addr); + else if (compiled_break == 1) + kgdb_arch_set_pc(regs, regs->pc + 4); + + compiled_break = 0; +} + int kgdb_arch_handle_exception(int exception_vector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, struct pt_regs *linux_regs) { - unsigned long addr; - char *ptr; int err; switch (remcom_in_buffer[0]) { @@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, * to the next instruction else we will just breakpoint * over and over again. */ - ptr = &remcom_in_buffer[1]; - if (kgdb_hex2long(&ptr, &addr)) - kgdb_arch_set_pc(linux_regs, addr); - else if (compiled_break == 1) - kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4); + kgdb_arch_update_addr(linux_regs, remcom_in_buffer); + atomic_set(&kgdb_cpu_doing_single_step, -1); + kgdb_single_step = 0; + + /* + * Received continue command, disable single step + */ + if (kernel_active_single_step()) + kernel_disable_single_step(); + + err = 0; + break; + case 's': + /* + * Update step address value with address passed + * with step packet. + * On debug exception return PC is copied to ELR + * So just update PC. + * If no step address is passed, resume from the address + * pointed by PC. Do not update PC + */ + kgdb_arch_update_addr(linux_regs, remcom_in_buffer); + atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id()); + kgdb_single_step = 1; - compiled_break = 0; + /* + * Enable single step handling + */ + if (!kernel_active_single_step()) + kernel_enable_single_step(linux_regs); err = 0; break; default: @@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr) return 0; } +static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr) +{ + kgdb_handle_exception(1, SIGTRAP, 0, regs); + return 0; +} + static struct break_hook kgdb_brkpt_hook = { .esr_mask = 0xffffffff, .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM), @@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = { .fn = kgdb_compiled_brk_fn }; +static struct step_hook kgdb_step_hook = { + .fn = kgdb_step_brk_fn +}; + static void kgdb_call_nmi_hook(void *ignored) { kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); @@ -259,6 +305,7 @@ int kgdb_arch_init(void) register_break_hook(&kgdb_brkpt_hook); register_break_hook(&kgdb_compiled_brkpt_hook); + register_step_hook(&kgdb_step_hook); return 0; } @@ -271,6 +318,7 @@ void kgdb_arch_exit(void) { unregister_break_hook(&kgdb_brkpt_hook); unregister_break_hook(&kgdb_compiled_brkpt_hook); + unregister_step_hook(&kgdb_step_hook); unregister_die_notifier(&kgdb_notifier); } -- cgit v1.2.3-55-g7522 From 58dcc204f18af2821f683b235bb376f9db2557f5 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Tue, 28 Jan 2014 16:50:21 +0530 Subject: misc: debug: remove compilation warnings typecast instruction_pointer macro to unsigned long to resolve following compiler warnings like warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'u64' [-Wformat] Signed-off-by: Vijaya Kumar K Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 0e7fa4963735..5233966fba3d 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -164,7 +164,7 @@ static inline int valid_user_regs(struct user_pt_regs *regs) return 0; } -#define instruction_pointer(regs) (regs)->pc +#define instruction_pointer(regs) ((unsigned long)(regs)->pc) #ifdef CONFIG_SMP extern unsigned long profile_pc(struct pt_regs *regs); -- cgit v1.2.3-55-g7522 From 9529247db9ecfc5a723e17093614e7437ab0d5bd Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Tue, 28 Jan 2014 11:20:22 +0000 Subject: arm64: KGDB: Add KGDB config Add HAVE_ARCH_KGDB for arm64 Kconfig Signed-off-by: Vijaya Kumar K Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 27bbcfc7202a..0cb33a2c592e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -26,6 +26,7 @@ config ARM64 select GENERIC_TIME_VSYSCALL select HARDIRQS_SW_RESEND select HAVE_ARCH_JUMP_LABEL + select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK select HAVE_DEBUG_BUGVERBOSE select HAVE_DEBUG_KMEMLEAK -- cgit v1.2.3-55-g7522 From d8ed442a009ecfe155b57d58f231db3d6084633d Mon Sep 17 00:00:00 2001 From: Vijaya Kumar K Date: Fri, 21 Feb 2014 05:13:49 +0000 Subject: arm64: enable processor debug state for secondary cpus processor debug state PSTATE.D is unmasked in smp call clear_os_lock for secondary cpus. So debug state is still masked in normal kernel context. With this patch, unmask debug state on secondary boot for the cpus in normal kernel context. Now kgdb tests passed with multicore. Signed-off-by: Vijaya Kumar K Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/debug-monitors.c | 7 +++---- arch/arm64/kernel/smp.c | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 1a8127da625b..13f87def8ea1 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -137,8 +137,6 @@ void disable_debug_monitors(enum debug_el el) static void clear_os_lock(void *unused) { asm volatile("msr oslar_el1, %0" : : "r" (0)); - isb(); - local_dbg_enable(); } static int os_lock_notify(struct notifier_block *self, @@ -157,8 +155,9 @@ static struct notifier_block os_lock_nb = { static int debug_monitors_init(void) { /* Clear the OS lock. */ - smp_call_function(clear_os_lock, NULL, 1); - clear_os_lock(NULL); + on_each_cpu(clear_os_lock, NULL, 1); + isb(); + local_dbg_enable(); /* Register hotplug handler. */ register_cpu_notifier(&os_lock_nb); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 7cfb92a4ab66..5070dc3b65d2 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -160,6 +160,7 @@ asmlinkage void secondary_start_kernel(void) set_cpu_online(cpu, true); complete(&cpu_running); + local_dbg_enable(); local_irq_enable(); local_async_enable(); -- cgit v1.2.3-55-g7522 From 22bd1c91fe13d59cff734b69b6757adcfbd8dee9 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 4 Feb 2014 16:37:59 +0000 Subject: arm64: Extend the PCI I/O space to 16MB The patch moves the PCI I/O space (currently at 64K) before the earlyprintk mapping and extends it to 16MB. Signed-off-by: Catalin Marinas --- Documentation/arm64/memory.txt | 16 ++++++++++------ arch/arm64/include/asm/io.h | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt index 5e054bfe4dde..85e24c4f215c 100644 --- a/Documentation/arm64/memory.txt +++ b/Documentation/arm64/memory.txt @@ -35,11 +35,13 @@ ffffffbc00000000 ffffffbdffffffff 8GB vmemmap ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] -ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device +ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space + +ffffffbffb000000 ffffffbffbbfffff 12MB [guard] -ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space +ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device -ffffffbffbe10000 ffffffbcffffffff ~2MB [guard] +ffffffbffbe00000 ffffffbffbffffff 2MB [guard] ffffffbffc000000 ffffffbfffffffff 64MB modules @@ -60,11 +62,13 @@ fffffdfc00000000 fffffdfdffffffff 8GB vmemmap fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap] -fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device +fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space + +fffffdfffb000000 fffffdfffbbfffff 12MB [guard] -fffffdfffbe00000 fffffdfffbe0ffff 64KB PCI I/O space +fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device -fffffdfffbe10000 fffffdfffbffffff ~2MB [guard] +fffffdfffbe00000 fffffdfffbffffff 2MB [guard] fffffdfffc000000 fffffdffffffffff 64MB modules diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 4cc813eddacb..7846a6bb0833 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -121,7 +121,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * I/O port access primitives. */ #define IO_SPACE_LIMIT 0xffff -#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) +#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) static inline u8 inb(unsigned long addr) { -- cgit v1.2.3-55-g7522 From 020c1427f3ad73c86fd566d86441e673adfe2ecb Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 11 Feb 2014 15:22:01 +0000 Subject: arm64: Convert asm/tlb.h to generic mmu_gather Over the past couple of years, the generic mmu_gather gained range tracking - 597e1c3580b7 (mm/mmu_gather: enable tlb flush range in generic mmu_gather), 2b047252d087 (Fix TLB gather virtual address range invalidation corner cases) - and tlb_fast_mode() has been removed - 29eb77825cc7 (arch, mm: Remove tlb_fast_mode()). The new mmu_gather structure is now suitable for arm64 and this patch converts the arch asm/tlb.h to the generic code. One functional difference is the shift_arg_pages() case where previously the code was flushing the full mm (no tlb_start_vma call) but now it flushes the range given to tlb_gather_mmu() (possibly slightly more efficient previously). Signed-off-by: Catalin Marinas Cc: Peter Zijlstra --- arch/arm64/include/asm/tlb.h | 136 +++++++------------------------------------ 1 file changed, 20 insertions(+), 116 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 717031a762c2..72cadf52ca80 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h @@ -19,115 +19,44 @@ #ifndef __ASM_TLB_H #define __ASM_TLB_H -#include -#include -#include -#include - -#define MMU_GATHER_BUNDLE 8 - -/* - * TLB handling. This allows us to remove pages from the page - * tables, and efficiently handle the TLB issues. - */ -struct mmu_gather { - struct mm_struct *mm; - unsigned int fullmm; - struct vm_area_struct *vma; - unsigned long start, end; - unsigned long range_start; - unsigned long range_end; - unsigned int nr; - unsigned int max; - struct page **pages; - struct page *local[MMU_GATHER_BUNDLE]; -}; +#include /* - * This is unnecessarily complex. There's three ways the TLB shootdown - * code is used: + * There's three ways the TLB shootdown code is used: * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region(). * tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called. - * tlb->vma will be non-NULL. * 2. Unmapping all vmas. See exit_mmap(). * tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called. - * tlb->vma will be non-NULL. Additionally, page tables will be freed. + * Page tables will be freed. * 3. Unmapping argument pages. See shift_arg_pages(). * tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called. - * tlb->vma will be NULL. */ static inline void tlb_flush(struct mmu_gather *tlb) { - if (tlb->fullmm || !tlb->vma) + if (tlb->fullmm) { flush_tlb_mm(tlb->mm); - else if (tlb->range_end > 0) { - flush_tlb_range(tlb->vma, tlb->range_start, tlb->range_end); - tlb->range_start = TASK_SIZE; - tlb->range_end = 0; + } else if (tlb->end > 0) { + struct vm_area_struct vma = { .vm_mm = tlb->mm, }; + flush_tlb_range(&vma, tlb->start, tlb->end); + tlb->start = TASK_SIZE; + tlb->end = 0; } } static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr) { if (!tlb->fullmm) { - if (addr < tlb->range_start) - tlb->range_start = addr; - if (addr + PAGE_SIZE > tlb->range_end) - tlb->range_end = addr + PAGE_SIZE; - } -} - -static inline void __tlb_alloc_page(struct mmu_gather *tlb) -{ - unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0); - - if (addr) { - tlb->pages = (void *)addr; - tlb->max = PAGE_SIZE / sizeof(struct page *); + tlb->start = min(tlb->start, addr); + tlb->end = max(tlb->end, addr + PAGE_SIZE); } } -static inline void tlb_flush_mmu(struct mmu_gather *tlb) -{ - tlb_flush(tlb); - free_pages_and_swap_cache(tlb->pages, tlb->nr); - tlb->nr = 0; - if (tlb->pages == tlb->local) - __tlb_alloc_page(tlb); -} - -static inline void -tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) -{ - tlb->mm = mm; - tlb->fullmm = !(start | (end+1)); - tlb->start = start; - tlb->end = end; - tlb->vma = NULL; - tlb->max = ARRAY_SIZE(tlb->local); - tlb->pages = tlb->local; - tlb->nr = 0; - __tlb_alloc_page(tlb); -} - -static inline void -tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) -{ - tlb_flush_mmu(tlb); - - /* keep the page table cache within bounds */ - check_pgt_cache(); - - if (tlb->pages != tlb->local) - free_pages((unsigned long)tlb->pages, 0); -} - /* * Memorize the range for the TLB flush. */ -static inline void -tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr) +static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, + unsigned long addr) { tlb_add_flush(tlb, addr); } @@ -137,38 +66,24 @@ tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr) * case where we're doing a full MM flush. When we're doing a munmap, * the vmas are adjusted to only cover the region to be torn down. */ -static inline void -tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +static inline void tlb_start_vma(struct mmu_gather *tlb, + struct vm_area_struct *vma) { if (!tlb->fullmm) { - tlb->vma = vma; - tlb->range_start = TASK_SIZE; - tlb->range_end = 0; + tlb->start = TASK_SIZE; + tlb->end = 0; } } -static inline void -tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +static inline void tlb_end_vma(struct mmu_gather *tlb, + struct vm_area_struct *vma) { if (!tlb->fullmm) tlb_flush(tlb); } -static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) -{ - tlb->pages[tlb->nr++] = page; - VM_BUG_ON(tlb->nr > tlb->max); - return tlb->max - tlb->nr; -} - -static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) -{ - if (!__tlb_remove_page(tlb, page)) - tlb_flush_mmu(tlb); -} - static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, - unsigned long addr) + unsigned long addr) { pgtable_page_dtor(pte); tlb_add_flush(tlb, addr); @@ -184,16 +99,5 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, } #endif -#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) -#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) -#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp) - -#define tlb_migrate_finish(mm) do { } while (0) - -static inline void -tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr) -{ - tlb_add_flush(tlb, addr); -} #endif -- cgit v1.2.3-55-g7522 From ea8c2e1124457f266f82effc3e6558552527943a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 17 Feb 2014 12:03:25 +0000 Subject: arm64: Extend the idmap to the whole kernel image This patch changes the idmap page table creation during boot to cover the whole kernel image, allowing functions like cpu_reset() to be safely called with the physical address. This patch also simplifies the create_block_map asm macro to no longer take an idmap argument and always use the phys/virt/end parameters. For the idmap case, phys == virt. Signed-off-by: Catalin Marinas --- arch/arm64/kernel/head.S | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 0b281fffda51..61035d6814cb 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -384,26 +384,18 @@ ENDPROC(__calc_phys_offset) * Preserves: tbl, flags * Corrupts: phys, start, end, pstate */ - .macro create_block_map, tbl, flags, phys, start, end, idmap=0 + .macro create_block_map, tbl, flags, phys, start, end lsr \phys, \phys, #BLOCK_SHIFT - .if \idmap - and \start, \phys, #PTRS_PER_PTE - 1 // table index - .else lsr \start, \start, #BLOCK_SHIFT and \start, \start, #PTRS_PER_PTE - 1 // table index - .endif orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry - .ifnc \start,\end lsr \end, \end, #BLOCK_SHIFT and \end, \end, #PTRS_PER_PTE - 1 // table end index - .endif 9999: str \phys, [\tbl, \start, lsl #3] // store the entry - .ifnc \start,\end add \start, \start, #1 // next entry add \phys, \phys, #BLOCK_SIZE // next block cmp \start, \end b.ls 9999b - .endif .endm /* @@ -435,9 +427,13 @@ __create_page_tables: * Create the identity mapping. */ add x0, x25, #PAGE_SIZE // section table address - adr x3, __turn_mmu_on // virtual/physical address + ldr x3, =KERNEL_START + add x3, x3, x28 // __pa(KERNEL_START) create_pgd_entry x25, x0, x3, x5, x6 - create_block_map x0, x7, x3, x5, x5, idmap=1 + ldr x6, =KERNEL_END + mov x5, x3 // __pa(KERNEL_START) + add x6, x6, x28 // __pa(KERNEL_END) + create_block_map x0, x7, x3, x5, x6 /* * Map the kernel image (starting with PHYS_OFFSET). @@ -445,7 +441,7 @@ __create_page_tables: add x0, x26, #PAGE_SIZE // section table address mov x5, #PAGE_OFFSET create_pgd_entry x26, x0, x5, x3, x6 - ldr x6, =KERNEL_END - 1 + ldr x6, =KERNEL_END mov x3, x24 // phys offset create_block_map x0, x7, x3, x5, x6 -- cgit v1.2.3-55-g7522 From 09024aa61e1bc994404683e2e5b363484a15dd12 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 17 Dec 2013 00:19:29 +0000 Subject: arm64: Fix the soft_restart routine Change the soft_restart() routine to call cpu_reset() at its identity mapped physical address. The cpu_reset() routine must be called at its identity mapped physical address so that when the MMU is turned off the instruction pointer will be at the correct location in physical memory. Signed-off-by: Geoff Levand for Huawei, Linaro Signed-off-by: Catalin Marinas --- arch/arm64/kernel/process.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1c0a9be2ffa8..fa6b5bba15f6 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -72,8 +72,17 @@ static void setup_restart(void) void soft_restart(unsigned long addr) { + typedef void (*phys_reset_t)(unsigned long); + phys_reset_t phys_reset; + setup_restart(); - cpu_reset(addr); + + /* Switch to the identity mapping */ + phys_reset = (phys_reset_t)virt_to_phys(cpu_reset); + phys_reset(addr); + + /* Should never get here */ + BUG(); } /* -- cgit v1.2.3-55-g7522 From bb10eb7b4d176f408d45fb492df28bed2981a1f3 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Thu, 6 Feb 2014 17:21:51 +0530 Subject: arm64: Change misleading function names in dma-mapping arm64_swiotlb_alloc/free_coherent name can be misleading somtimes with CMA support being enabled after this patch (c2104debc235b745265b64d610237a6833fd53) Change this name to be more generic: __dma_alloc/free_coherent Signed-off-by: Ritesh Harjani [catalin.marinas@arm.com: renamed arm64_swiotlb_dma_ops to coherent_swiotlb_dma_ops] Signed-off-by: Catalin Marinas --- arch/arm64/mm/dma-mapping.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index fbd76785c5db..985fc075c0f3 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -30,9 +30,9 @@ struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); -static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs) +static void *__dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) { if (dev == NULL) { WARN_ONCE(1, "Use an actual device structure for DMA allocation\n"); @@ -58,9 +58,9 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, } } -static void arm64_swiotlb_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static void __dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) { if (dev == NULL) { WARN_ONCE(1, "Use an actual device structure for DMA allocation\n"); @@ -78,9 +78,9 @@ static void arm64_swiotlb_free_coherent(struct device *dev, size_t size, } } -static struct dma_map_ops arm64_swiotlb_dma_ops = { - .alloc = arm64_swiotlb_alloc_coherent, - .free = arm64_swiotlb_free_coherent, +static struct dma_map_ops coherent_swiotlb_dma_ops = { + .alloc = __dma_alloc_coherent, + .free = __dma_free_coherent, .map_page = swiotlb_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = swiotlb_map_sg_attrs, @@ -95,7 +95,7 @@ static struct dma_map_ops arm64_swiotlb_dma_ops = { void __init arm64_swiotlb_init(void) { - dma_ops = &arm64_swiotlb_dma_ops; + dma_ops = &coherent_swiotlb_dma_ops; swiotlb_init(1); } -- cgit v1.2.3-55-g7522 From 16fb1a9bec6126162560f159df449e4781560807 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 11 Feb 2014 22:28:42 +0000 Subject: arm64: vdso: clean up vdso_pagelist initialization Remove some unnecessary bits that were apparently carried over from another architecture's implementation: - No need to get_page() the vdso text/data - these are part of the kernel image. - No need for ClearPageReserved on the vdso text. - No need to vmap the first text page to check the ELF header - this can be done through &vdso_start. Also some minor cleanup: - Use kcalloc for vdso_pagelist array allocation. - Don't print on allocation failure, slab/slub will do that for us. Signed-off-by: Nathan Lynch Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/vdso.c | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index a7149cae1615..50384fec56c4 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -106,49 +106,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) static int __init vdso_init(void) { - struct page *pg; - char *vbase; - int i, ret = 0; + int i; + + if (memcmp(&vdso_start, "\177ELF", 4)) { + pr_err("vDSO is not a valid ELF object!\n"); + return -EINVAL; + } vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n", vdso_pages + 1, vdso_pages, 1L, &vdso_start); /* Allocate the vDSO pagelist, plus a page for the data. */ - vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 1), + vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL); - if (vdso_pagelist == NULL) { - pr_err("Failed to allocate vDSO pagelist!\n"); + if (vdso_pagelist == NULL) return -ENOMEM; - } /* Grab the vDSO code pages. */ - for (i = 0; i < vdso_pages; i++) { - pg = virt_to_page(&vdso_start + i*PAGE_SIZE); - ClearPageReserved(pg); - get_page(pg); - vdso_pagelist[i] = pg; - } - - /* Sanity check the shared object header. */ - vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL); - if (vbase == NULL) { - pr_err("Failed to map vDSO pagelist!\n"); - return -ENOMEM; - } else if (memcmp(vbase, "\177ELF", 4)) { - pr_err("vDSO is not a valid ELF object!\n"); - ret = -EINVAL; - goto unmap; - } + for (i = 0; i < vdso_pages; i++) + vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE); /* Grab the vDSO data page. */ - pg = virt_to_page(vdso_data); - get_page(pg); - vdso_pagelist[i] = pg; + vdso_pagelist[i] = virt_to_page(vdso_data); -unmap: - vunmap(vbase); - return ret; + return 0; } arch_initcall(vdso_init); -- cgit v1.2.3-55-g7522 From 404381c5839d67aa0c275ad1da96ef3d3928ca2c Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 24 Feb 2014 13:59:32 -0300 Subject: KVM: MMU: drop read-only large sptes when creating lower level sptes Read-only large sptes can be created due to read-only faults as follows: - QEMU pagetable entry that maps guest memory is read-only due to COW. - Guest read faults such memory, COW is not broken, because it is a read-only fault. - Enable dirty logging, large spte not nuked because it is read-only. - Write-fault on such memory causes guest to loop endlessly (which must go down to level 1 because dirty logging is enabled). Fix by dropping large spte when necessary. Signed-off-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index e50425d0f5f7..9b531351a587 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2672,6 +2672,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, break; } + drop_large_spte(vcpu, iterator.sptep); if (!is_shadow_present_pte(*iterator.sptep)) { u64 base_addr = iterator.addr; -- cgit v1.2.3-55-g7522 From 26e61e8939b1fe8729572dabe9a9e97d930dd4f6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 21 Feb 2014 16:03:12 +0100 Subject: perf/x86: Fix event scheduling Vince "Super Tester" Weaver reported a new round of syscall fuzzing (Trinity) failures, with perf WARN_ON()s triggering. He also provided traces of the failures. This is I think the relevant bit: > pec_1076_warn-2804 [000] d... 147.926153: x86_pmu_disable: x86_pmu_disable > pec_1076_warn-2804 [000] d... 147.926153: x86_pmu_state: Events: { > pec_1076_warn-2804 [000] d... 147.926156: x86_pmu_state: 0: state: .R config: ffffffffffffffff ( (null)) > pec_1076_warn-2804 [000] d... 147.926158: x86_pmu_state: 33: state: AR config: 0 (ffff88011ac99800) > pec_1076_warn-2804 [000] d... 147.926159: x86_pmu_state: } > pec_1076_warn-2804 [000] d... 147.926160: x86_pmu_state: n_events: 1, n_added: 0, n_txn: 1 > pec_1076_warn-2804 [000] d... 147.926161: x86_pmu_state: Assignment: { > pec_1076_warn-2804 [000] d... 147.926162: x86_pmu_state: 0->33 tag: 1 config: 0 (ffff88011ac99800) > pec_1076_warn-2804 [000] d... 147.926163: x86_pmu_state: } > pec_1076_warn-2804 [000] d... 147.926166: collect_events: Adding event: 1 (ffff880119ec8800) So we add the insn:p event (fd[23]). At this point we should have: n_events = 2, n_added = 1, n_txn = 1 > pec_1076_warn-2804 [000] d... 147.926170: collect_events: Adding event: 0 (ffff8800c9e01800) > pec_1076_warn-2804 [000] d... 147.926172: collect_events: Adding event: 4 (ffff8800cbab2c00) We try and add the {BP,cycles,br_insn} group (fd[3], fd[4], fd[15]). These events are 0:cycles and 4:br_insn, the BP event isn't x86_pmu so that's not visible. group_sched_in() pmu->start_txn() /* nop - BP pmu */ event_sched_in() event->pmu->add() So here we should end up with: 0: n_events = 3, n_added = 2, n_txn = 2 4: n_events = 4, n_added = 3, n_txn = 3 But seeing the below state on x86_pmu_enable(), the must have failed, because the 0 and 4 events aren't there anymore. Looking at group_sched_in(), since the BP is the leader, its event_sched_in() must have succeeded, for otherwise we would not have seen the sibling adds. But since neither 0 or 4 are in the below state; their event_sched_in() must have failed; but I don't see why, the complete state: 0,0,1:p,4 fits perfectly fine on a core2. However, since we try and schedule 4 it means the 0 event must have succeeded! Therefore the 4 event must have failed, its failure will have put group_sched_in() into the fail path, which will call: event_sched_out() event->pmu->del() on 0 and the BP event. Now x86_pmu_del() will reduce n_events; but it will not reduce n_added; giving what we see below: n_event = 2, n_added = 2, n_txn = 2 > pec_1076_warn-2804 [000] d... 147.926177: x86_pmu_enable: x86_pmu_enable > pec_1076_warn-2804 [000] d... 147.926177: x86_pmu_state: Events: { > pec_1076_warn-2804 [000] d... 147.926179: x86_pmu_state: 0: state: .R config: ffffffffffffffff ( (null)) > pec_1076_warn-2804 [000] d... 147.926181: x86_pmu_state: 33: state: AR config: 0 (ffff88011ac99800) > pec_1076_warn-2804 [000] d... 147.926182: x86_pmu_state: } > pec_1076_warn-2804 [000] d... 147.926184: x86_pmu_state: n_events: 2, n_added: 2, n_txn: 2 > pec_1076_warn-2804 [000] d... 147.926184: x86_pmu_state: Assignment: { > pec_1076_warn-2804 [000] d... 147.926186: x86_pmu_state: 0->33 tag: 1 config: 0 (ffff88011ac99800) > pec_1076_warn-2804 [000] d... 147.926188: x86_pmu_state: 1->0 tag: 1 config: 1 (ffff880119ec8800) > pec_1076_warn-2804 [000] d... 147.926188: x86_pmu_state: } > pec_1076_warn-2804 [000] d... 147.926190: x86_pmu_enable: S0: hwc->idx: 33, hwc->last_cpu: 0, hwc->last_tag: 1 hwc->state: 0 So the problem is that x86_pmu_del(), when called from a group_sched_in() that fails (for whatever reason), and without x86_pmu TXN support (because the leader is !x86_pmu), will corrupt the n_added state. Reported-and-Tested-by: Vince Weaver Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Cc: Stephane Eranian Cc: Dave Jones Cc: Link: http://lkml.kernel.org/r/20140221150312.GF3104@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 895604f2e916..79f9f848bee4 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1192,6 +1192,9 @@ static void x86_pmu_del(struct perf_event *event, int flags) for (i = 0; i < cpuc->n_events; i++) { if (event == cpuc->event_list[i]) { + if (i >= cpuc->n_events - cpuc->n_added) + --cpuc->n_added; + if (x86_pmu.put_event_constraints) x86_pmu.put_event_constraints(cpuc, event); -- cgit v1.2.3-55-g7522 From c347a2f1793e285b0812343e715bb7e953dbdf68 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 24 Feb 2014 12:26:21 +0100 Subject: perf/x86: Add a few more comments Add a few comments on the ->add(), ->del() and ->*_txn() implementation. Requested-by: Vince Weaver Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-he3819318c245j7t5e1e22tr@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 47 ++++++++++++++++++++++++++++------------ arch/x86/kernel/cpu/perf_event.h | 8 ++++--- 2 files changed, 38 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 79f9f848bee4..ae407f7226c8 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -892,7 +892,6 @@ static void x86_pmu_enable(struct pmu *pmu) * hw_perf_group_sched_in() or x86_pmu_enable() * * step1: save events moving to new counters - * step2: reprogram moved events into new counters */ for (i = 0; i < n_running; i++) { event = cpuc->event_list[i]; @@ -918,6 +917,9 @@ static void x86_pmu_enable(struct pmu *pmu) x86_pmu_stop(event, PERF_EF_UPDATE); } + /* + * step2: reprogram moved events into new counters + */ for (i = 0; i < cpuc->n_events; i++) { event = cpuc->event_list[i]; hwc = &event->hw; @@ -1043,7 +1045,7 @@ static int x86_pmu_add(struct perf_event *event, int flags) /* * If group events scheduling transaction was started, * skip the schedulability test here, it will be performed - * at commit time (->commit_txn) as a whole + * at commit time (->commit_txn) as a whole. */ if (cpuc->group_flag & PERF_EVENT_TXN) goto done_collect; @@ -1058,6 +1060,10 @@ static int x86_pmu_add(struct perf_event *event, int flags) memcpy(cpuc->assign, assign, n*sizeof(int)); done_collect: + /* + * Commit the collect_events() state. See x86_pmu_del() and + * x86_pmu_*_txn(). + */ cpuc->n_events = n; cpuc->n_added += n - n0; cpuc->n_txn += n - n0; @@ -1183,28 +1189,38 @@ static void x86_pmu_del(struct perf_event *event, int flags) * If we're called during a txn, we don't need to do anything. * The events never got scheduled and ->cancel_txn will truncate * the event_list. + * + * XXX assumes any ->del() called during a TXN will only be on + * an event added during that same TXN. */ if (cpuc->group_flag & PERF_EVENT_TXN) return; + /* + * Not a TXN, therefore cleanup properly. + */ x86_pmu_stop(event, PERF_EF_UPDATE); for (i = 0; i < cpuc->n_events; i++) { - if (event == cpuc->event_list[i]) { + if (event == cpuc->event_list[i]) + break; + } - if (i >= cpuc->n_events - cpuc->n_added) - --cpuc->n_added; + if (WARN_ON_ONCE(i == cpuc->n_events)) /* called ->del() without ->add() ? */ + return; - if (x86_pmu.put_event_constraints) - x86_pmu.put_event_constraints(cpuc, event); + /* If we have a newly added event; make sure to decrease n_added. */ + if (i >= cpuc->n_events - cpuc->n_added) + --cpuc->n_added; - while (++i < cpuc->n_events) - cpuc->event_list[i-1] = cpuc->event_list[i]; + if (x86_pmu.put_event_constraints) + x86_pmu.put_event_constraints(cpuc, event); + + /* Delete the array entry. */ + while (++i < cpuc->n_events) + cpuc->event_list[i-1] = cpuc->event_list[i]; + --cpuc->n_events; - --cpuc->n_events; - break; - } - } perf_event_update_userpage(event); } @@ -1598,7 +1614,8 @@ static void x86_pmu_cancel_txn(struct pmu *pmu) { __this_cpu_and(cpu_hw_events.group_flag, ~PERF_EVENT_TXN); /* - * Truncate the collected events. + * Truncate collected array by the number of events added in this + * transaction. See x86_pmu_add() and x86_pmu_*_txn(). */ __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn)); __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn)); @@ -1609,6 +1626,8 @@ static void x86_pmu_cancel_txn(struct pmu *pmu) * Commit group events scheduling transaction * Perform the group schedulability test as a whole * Return 0 if success + * + * Does not cancel the transaction on failure; expects the caller to do this. */ static int x86_pmu_commit_txn(struct pmu *pmu) { diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 4972c244d0bc..3b2f9bdd974b 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -130,9 +130,11 @@ struct cpu_hw_events { unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; int enabled; - int n_events; - int n_added; - int n_txn; + int n_events; /* the # of events in the below arrays */ + int n_added; /* the # last events in the below arrays; + they've never been enabled yet */ + int n_txn; /* the # last events in the below arrays; + added in the current transaction */ int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */ u64 tags[X86_PMC_IDX_MAX]; struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */ -- cgit v1.2.3-55-g7522 From 19e7640d1f2302c20df2733e3e3df49acb17189e Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 27 Feb 2014 12:09:22 +0000 Subject: arm64: Replace ZONE_DMA32 with ZONE_DMA On arm64 we do not have two DMA zones, so it does not make sense to implement ZONE_DMA32. This patch changes ZONE_DMA32 with ZONE_DMA, the latter covering 32-bit dma address space to honour GFP_DMA allocations. Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 2 +- arch/arm64/mm/dma-mapping.c | 4 ++-- arch/arm64/mm/init.c | 31 ++++++++++++++++--------------- 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 0cb33a2c592e..33e8f845a540 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -86,7 +86,7 @@ config GENERIC_CSUM config GENERIC_CALIBRATE_DELAY def_bool y -config ZONE_DMA32 +config ZONE_DMA def_bool y config ARCH_DMA_ADDR_T_64BIT diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 985fc075c0f3..26b2512c1fcd 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -39,9 +39,9 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size, return NULL; } - if (IS_ENABLED(CONFIG_ZONE_DMA32) && + if (IS_ENABLED(CONFIG_ZONE_DMA) && dev->coherent_dma_mask <= DMA_BIT_MASK(32)) - flags |= GFP_DMA32; + flags |= GFP_DMA; if (IS_ENABLED(CONFIG_DMA_CMA)) { struct page *page; diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index d0b4c2efda90..a61a4d560d12 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -59,22 +60,22 @@ static int __init early_initrd(char *p) early_param("initrd", early_initrd); #endif -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT) - static void __init zone_sizes_init(unsigned long min, unsigned long max) { struct memblock_region *reg; unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; - unsigned long max_dma32 = min; + unsigned long max_dma = min; memset(zone_size, 0, sizeof(zone_size)); -#ifdef CONFIG_ZONE_DMA32 /* 4GB maximum for 32-bit only capable devices */ - max_dma32 = max(min, min(max, MAX_DMA32_PFN)); - zone_size[ZONE_DMA32] = max_dma32 - min; -#endif - zone_size[ZONE_NORMAL] = max - max_dma32; + if (IS_ENABLED(CONFIG_ZONE_DMA)) { + unsigned long max_dma_phys = + (unsigned long)dma_to_phys(NULL, DMA_BIT_MASK(32) + 1); + max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT)); + zone_size[ZONE_DMA] = max_dma - min; + } + zone_size[ZONE_NORMAL] = max - max_dma; memcpy(zhole_size, zone_size, sizeof(zhole_size)); @@ -84,15 +85,15 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) if (start >= max) continue; -#ifdef CONFIG_ZONE_DMA32 - if (start < max_dma32) { - unsigned long dma_end = min(end, max_dma32); - zhole_size[ZONE_DMA32] -= dma_end - start; + + if (IS_ENABLED(CONFIG_ZONE_DMA) && start < max_dma) { + unsigned long dma_end = min(end, max_dma); + zhole_size[ZONE_DMA] -= dma_end - start; } -#endif - if (end > max_dma32) { + + if (end > max_dma) { unsigned long normal_end = min(end, max); - unsigned long normal_start = max(start, max_dma32); + unsigned long normal_start = max(start, max_dma); zhole_size[ZONE_NORMAL] -= normal_end - normal_start; } } -- cgit v1.2.3-55-g7522 From 3690951fc6d42f3a0903987677d0e592c49dd8db Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 27 Feb 2014 12:24:57 +0000 Subject: arm64: Use swiotlb late initialisation Since arm64 does not support ISA, there is no need for early swiotlb initialisation. This patch switches the DMA mapping code to swiotlb_tlb_late_init_with_default_size(). A side effect of this is that GFP_DMA is used for the swiotlb buffer and devices with a 32-bit coherent mask are correctly supported. Signed-off-by: Catalin Marinas --- arch/arm64/mm/dma-mapping.c | 10 ++++++++-- arch/arm64/mm/init.c | 2 -- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 26b2512c1fcd..afa91a26a72b 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -93,11 +93,17 @@ static struct dma_map_ops coherent_swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, }; -void __init arm64_swiotlb_init(void) +extern int swiotlb_late_init_with_default_size(size_t default_size); + +static int __init swiotlb_late_init(void) { + size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); + dma_ops = &coherent_swiotlb_dma_ops; - swiotlb_init(1); + + return swiotlb_late_init_with_default_size(swiotlb_size); } +subsys_initcall(swiotlb_late_init); #define PREALLOC_DMA_DEBUG_ENTRIES 4096 diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index a61a4d560d12..88627c450a6c 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -262,8 +262,6 @@ static void __init free_unused_memmap(void) */ void __init mem_init(void) { - arm64_swiotlb_init(); - max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; #ifndef CONFIG_SPARSEMEM_VMEMMAP -- cgit v1.2.3-55-g7522 From 171699f7630c92d0a928f83e5fb3aeabe35398c0 Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Wed, 26 Feb 2014 12:06:49 -0700 Subject: x86: Add support for the clflushopt instruction Add support for the new clflushopt instruction. This instruction was announced in the document "Intel Architecture Instruction Set Extensions Programming Reference" with Ref # 319433-018. http://download-software.intel.com/sites/default/files/managed/50/1a/319433-018.pdf [ hpa: changed the feature flag to simply X86_FEATURE_CLFLUSHOPT - if that is what we want to report in /proc/cpuinfo anyway... ] Signed-off-by: Ross Zwisler Link: http://lkml.kernel.org/r/1393441612-19729-2-git-send-email-ross.zwisler@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/include/asm/special_insns.h | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 5f1296872aed..bc507d7640f8 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -221,6 +221,7 @@ #define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */ #define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ #define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */ +#define X86_FEATURE_CLFLUSHOPT (9*32+23) /* CLFLUSHOPT instruction */ #define X86_FEATURE_AVX512PF (9*32+26) /* AVX-512 Prefetch */ #define X86_FEATURE_AVX512ER (9*32+27) /* AVX-512 Exponential and Reciprocal */ #define X86_FEATURE_AVX512CD (9*32+28) /* AVX-512 Conflict Detection */ diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 645cad2c95ff..e820c080a4e9 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -191,6 +191,14 @@ static inline void clflush(volatile void *__p) asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p)); } +static inline void clflushopt(volatile void *__p) +{ + alternative_io(".byte " __stringify(NOP_DS_PREFIX) "; clflush %P0", + ".byte 0x66; clflush %P0", + X86_FEATURE_CLFLUSHOPT, + "+m" (*(volatile char __force *)__p)); +} + #define nop() asm volatile ("nop") -- cgit v1.2.3-55-g7522 From 8b80fd8b45458a7d0b726d454c51c5219e0fb2ee Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Wed, 26 Feb 2014 12:06:50 -0700 Subject: x86: Use clflushopt in clflush_cache_range If clflushopt is available on the system, use it instead of clflush in clflush_cache_range. Signed-off-by: Ross Zwisler Link: http://lkml.kernel.org/r/1393441612-19729-3-git-send-email-ross.zwisler@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/pageattr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index b3b19f46c016..b1c46723b19b 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -126,8 +126,8 @@ within(unsigned long addr, unsigned long start, unsigned long end) * @vaddr: virtual start address * @size: number of bytes to flush * - * clflush is an unordered instruction which needs fencing with mfence - * to avoid ordering issues. + * clflushopt is an unordered instruction which needs fencing with mfence or + * sfence to avoid ordering issues. */ void clflush_cache_range(void *vaddr, unsigned int size) { @@ -136,11 +136,11 @@ void clflush_cache_range(void *vaddr, unsigned int size) mb(); for (; vaddr < vend; vaddr += boot_cpu_data.x86_clflush_size) - clflush(vaddr); + clflushopt(vaddr); /* * Flush any possible final partial cacheline: */ - clflush(vend); + clflushopt(vend); mb(); } -- cgit v1.2.3-55-g7522 From 840d2830e6e56b8fdacc7ff12915dd91bf91566b Mon Sep 17 00:00:00 2001 From: H. Peter Anvin Date: Thu, 27 Feb 2014 08:31:30 -0800 Subject: x86, cpufeature: Rename X86_FEATURE_CLFLSH to X86_FEATURE_CLFLUSH We call this "clflush" in /proc/cpuinfo, and have cpu_has_clflush()... let's be consistent and just call it that. Cc: Gleb Natapov Cc: Paolo Bonzini Cc: Alan Cox Link: http://lkml.kernel.org/n/tip-mlytfzjkvuf739okyn40p8a5@git.kernel.org --- arch/x86/include/asm/cpufeature.h | 4 ++-- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/smpboot.c | 2 +- arch/x86/kvm/cpuid.c | 2 +- drivers/gpu/drm/gma500/mmu.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index bc507d7640f8..63211ef5046a 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -37,7 +37,7 @@ #define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ -#define X86_FEATURE_CLFLSH (0*32+19) /* "clflush" CLFLUSH instruction */ +#define X86_FEATURE_CLFLUSH (0*32+19) /* CLFLUSH instruction */ #define X86_FEATURE_DS (0*32+21) /* "dts" Debug Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ @@ -318,7 +318,7 @@ extern const char * const x86_power_flags[32]; #define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) #define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) #define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) -#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) +#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH) #define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) #define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES) #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8e28bf2fc3ef..2c6ac6f2b5b1 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1025,7 +1025,7 @@ __setup("show_msr=", setup_show_msr); static __init int setup_noclflush(char *arg) { - setup_clear_cpu_cap(X86_FEATURE_CLFLSH); + setup_clear_cpu_cap(X86_FEATURE_CLFLUSH); return 1; } __setup("noclflush", setup_noclflush); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a32da804252e..ffc78c3e9be1 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1379,7 +1379,7 @@ static inline void mwait_play_dead(void) if (!this_cpu_has(X86_FEATURE_MWAIT)) return; - if (!this_cpu_has(X86_FEATURE_CLFLSH)) + if (!this_cpu_has(X86_FEATURE_CLFLUSH)) return; if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF) return; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index c6976257eff5..e5503d8aec1d 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -263,7 +263,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(TSC) | F(MSR) | F(PAE) | F(MCE) | F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) | F(MTRR) | F(PGE) | F(MCA) | F(CMOV) | - F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLSH) | + F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLUSH) | 0 /* Reserved, DS, ACPI */ | F(MMX) | F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) | 0 /* HTT, TM, Reserved, PBE */; diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c index 49bac41beefb..c3e67ba94446 100644 --- a/drivers/gpu/drm/gma500/mmu.c +++ b/drivers/gpu/drm/gma500/mmu.c @@ -520,7 +520,7 @@ struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, driver->has_clflush = 0; - if (boot_cpu_has(X86_FEATURE_CLFLSH)) { + if (boot_cpu_has(X86_FEATURE_CLFLUSH)) { uint32_t tfms, misc, cap0, cap4, clflush_size; /* -- cgit v1.2.3-55-g7522 From da4aaa7d860c63a1bfd3c73cf8309afe2840c5b9 Mon Sep 17 00:00:00 2001 From: H. Peter Anvin Date: Thu, 27 Feb 2014 08:36:31 -0800 Subject: x86, cpufeature: If we disable CLFLUSH, we should disable CLFLUSHOPT If we explicitly disable the use of CLFLUSH, we should disable the use of CLFLUSHOPT as well. Cc: Ross Zwisler Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/n/tip-jtdv7btppr4jgzxm3sxx1e74@git.kernel.org --- arch/x86/kernel/cpu/common.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 2c6ac6f2b5b1..cca53d88762a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1026,6 +1026,7 @@ __setup("show_msr=", setup_show_msr); static __init int setup_noclflush(char *arg) { setup_clear_cpu_cap(X86_FEATURE_CLFLUSH); + setup_clear_cpu_cap(X86_FEATURE_CLFLUSHOPT); return 1; } __setup("noclflush", setup_noclflush); -- cgit v1.2.3-55-g7522 From 7363590d2c4691593fd280f94b3deaeb5e83dbbd Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 21 May 2013 17:35:19 +0100 Subject: arm64: Implement coherent DMA API based on swiotlb This patch adds support for DMA API cache maintenance on SoCs without hardware device cache coherency. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/cacheflush.h | 7 ++ arch/arm64/include/asm/dma-mapping.h | 7 ++ arch/arm64/mm/cache.S | 78 +++++++++++++++++ arch/arm64/mm/dma-mapping.c | 162 ++++++++++++++++++++++++++++++++++- 4 files changed, 253 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index 889324981aa4..4c60e64a801c 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -84,6 +84,13 @@ static inline void flush_cache_page(struct vm_area_struct *vma, { } +/* + * Cache maintenance functions used by the DMA API. No to be used directly. + */ +extern void __dma_map_area(const void *, size_t, int); +extern void __dma_unmap_area(const void *, size_t, int); +extern void __dma_flush_range(const void *, const void *); + /* * Copy user data from/to a page which is mapped into a different * processes address space. Really, we want to allow our "user diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h index fd0c0c0e447a..3a4572ec3273 100644 --- a/arch/arm64/include/asm/dma-mapping.h +++ b/arch/arm64/include/asm/dma-mapping.h @@ -30,6 +30,8 @@ #define DMA_ERROR_CODE (~(dma_addr_t)0) extern struct dma_map_ops *dma_ops; +extern struct dma_map_ops coherent_swiotlb_dma_ops; +extern struct dma_map_ops noncoherent_swiotlb_dma_ops; static inline struct dma_map_ops *__generic_dma_ops(struct device *dev) { @@ -47,6 +49,11 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) return __generic_dma_ops(dev); } +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) +{ + dev->archdata.dma_ops = ops; +} + #include static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 1ea9f26d1b70..97fcef535a8a 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S @@ -166,3 +166,81 @@ ENTRY(__flush_dcache_area) dsb sy ret ENDPROC(__flush_dcache_area) + +/* + * __dma_inv_range(start, end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +__dma_inv_range: + dcache_line_size x2, x3 + sub x3, x2, #1 + bic x0, x0, x3 + bic x1, x1, x3 +1: dc ivac, x0 // invalidate D / U line + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__dma_inv_range) + +/* + * __dma_clean_range(start, end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +__dma_clean_range: + dcache_line_size x2, x3 + sub x3, x2, #1 + bic x0, x0, x3 +1: dc cvac, x0 // clean D / U line + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__dma_clean_range) + +/* + * __dma_flush_range(start, end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +ENTRY(__dma_flush_range) + dcache_line_size x2, x3 + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 // clean & invalidate D / U line + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__dma_flush_range) + +/* + * __dma_map_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(__dma_map_area) + add x1, x1, x0 + cmp w2, #DMA_FROM_DEVICE + b.eq __dma_inv_range + b __dma_clean_range +ENDPROC(__dma_map_area) + +/* + * __dma_unmap_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(__dma_unmap_area) + add x1, x1, x0 + cmp w2, #DMA_TO_DEVICE + b.ne __dma_inv_range + ret +ENDPROC(__dma_unmap_area) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index afa91a26a72b..88fbc5e5bae7 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -78,7 +78,166 @@ static void __dma_free_coherent(struct device *dev, size_t size, } } -static struct dma_map_ops coherent_swiotlb_dma_ops = { +static void *__dma_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flags, + struct dma_attrs *attrs) +{ + struct page *page, **map; + void *ptr, *coherent_ptr; + int order, i; + + size = PAGE_ALIGN(size); + order = get_order(size); + + ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs); + if (!ptr) + goto no_mem; + map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA); + if (!map) + goto no_map; + + /* remove any dirty cache lines on the kernel alias */ + __dma_flush_range(ptr, ptr + size); + + /* create a coherent mapping */ + page = virt_to_page(ptr); + for (i = 0; i < (size >> PAGE_SHIFT); i++) + map[i] = page + i; + coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP, + pgprot_dmacoherent(pgprot_default)); + kfree(map); + if (!coherent_ptr) + goto no_map; + + return coherent_ptr; + +no_map: + __dma_free_coherent(dev, size, ptr, *dma_handle, attrs); +no_mem: + *dma_handle = ~0; + return NULL; +} + +static void __dma_free_noncoherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + struct dma_attrs *attrs) +{ + void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle)); + + vunmap(vaddr); + __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs); +} + +static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + dma_addr_t dev_addr; + + dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs); + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); + + return dev_addr; +} + + +static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); + swiotlb_unmap_page(dev, dev_addr, size, dir, attrs); +} + +static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl, + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *sg; + int i, ret; + + ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs); + for_each_sg(sgl, sg, ret, i) + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), + sg->length, dir); + + return ret; +} + +static void __swiotlb_unmap_sg_attrs(struct device *dev, + struct scatterlist *sgl, int nelems, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sgl, sg, nelems, i) + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), + sg->length, dir); + swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs); +} + +static void __swiotlb_sync_single_for_cpu(struct device *dev, + dma_addr_t dev_addr, size_t size, + enum dma_data_direction dir) +{ + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); + swiotlb_sync_single_for_cpu(dev, dev_addr, size, dir); +} + +static void __swiotlb_sync_single_for_device(struct device *dev, + dma_addr_t dev_addr, size_t size, + enum dma_data_direction dir) +{ + swiotlb_sync_single_for_device(dev, dev_addr, size, dir); + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir); +} + +static void __swiotlb_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sgl, int nelems, + enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sgl, sg, nelems, i) + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), + sg->length, dir); + swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir); +} + +static void __swiotlb_sync_sg_for_device(struct device *dev, + struct scatterlist *sgl, int nelems, + enum dma_data_direction dir) +{ + struct scatterlist *sg; + int i; + + swiotlb_sync_sg_for_device(dev, sgl, nelems, dir); + for_each_sg(sgl, sg, nelems, i) + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)), + sg->length, dir); +} + +struct dma_map_ops noncoherent_swiotlb_dma_ops = { + .alloc = __dma_alloc_noncoherent, + .free = __dma_free_noncoherent, + .map_page = __swiotlb_map_page, + .unmap_page = __swiotlb_unmap_page, + .map_sg = __swiotlb_map_sg_attrs, + .unmap_sg = __swiotlb_unmap_sg_attrs, + .sync_single_for_cpu = __swiotlb_sync_single_for_cpu, + .sync_single_for_device = __swiotlb_sync_single_for_device, + .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = __swiotlb_sync_sg_for_device, + .dma_supported = swiotlb_dma_supported, + .mapping_error = swiotlb_dma_mapping_error, +}; +EXPORT_SYMBOL(noncoherent_swiotlb_dma_ops); + +struct dma_map_ops coherent_swiotlb_dma_ops = { .alloc = __dma_alloc_coherent, .free = __dma_free_coherent, .map_page = swiotlb_map_page, @@ -92,6 +251,7 @@ static struct dma_map_ops coherent_swiotlb_dma_ops = { .dma_supported = swiotlb_dma_supported, .mapping_error = swiotlb_dma_mapping_error, }; +EXPORT_SYMBOL(coherent_swiotlb_dma_ops); extern int swiotlb_late_init_with_default_size(size_t default_size); -- cgit v1.2.3-55-g7522 From b20c9f29c5c25921c6ad18b50d4b61e6d181c3cc Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 26 Feb 2014 18:47:36 +0000 Subject: arm/arm64: KVM: detect CPU reset on CPU_PM_EXIT Commit 1fcf7ce0c602 (arm: kvm: implement CPU PM notifier) added support for CPU power-management, using a cpu_notifier to re-init KVM on a CPU that entered CPU idle. The code assumed that a CPU entering idle would actually be powered off, loosing its state entierely, and would then need to be reinitialized. It turns out that this is not always the case, and some HW performs CPU PM without actually killing the core. In this case, we try to reinitialize KVM while it is still live. It ends up badly, as reported by Andre Przywara (using a Calxeda Midway): [ 3.663897] Kernel panic - not syncing: unexpected prefetch abort in Hyp mode at: 0x685760 [ 3.663897] unexpected data abort in Hyp mode at: 0xc067d150 [ 3.663897] unexpected HVC/SVC trap in Hyp mode at: 0xc0901dd0 The trick here is to detect if we've been through a full re-init or not by looking at HVBAR (VBAR_EL2 on arm64). This involves implementing the backend for __hyp_get_vectors in the main KVM HYP code (rather small), and checking the return value against the default one when the CPU notifier is called on CPU_PM_EXIT. Reported-by: Andre Przywara Tested-by: Andre Przywara Cc: Lorenzo Pieralisi Cc: Rob Herring Acked-by: Christoffer Dall Signed-off-by: Marc Zyngier Signed-off-by: Paolo Bonzini --- arch/arm/kvm/arm.c | 3 ++- arch/arm/kvm/interrupts.S | 11 ++++++++++- arch/arm64/kvm/hyp.S | 27 +++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 1d8248ea5669..bd18bb8b2770 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -878,7 +878,8 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { - if (cmd == CPU_PM_EXIT) { + if (cmd == CPU_PM_EXIT && + __hyp_get_vectors() == hyp_default_vectors) { cpu_init_hyp_mode(NULL); return NOTIFY_OK; } diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index ddc15539bad2..0d68d4073068 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -220,6 +220,10 @@ after_vfp_restore: * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are * passed in r0 and r1. * + * A function pointer with a value of 0xffffffff has a special meaning, + * and is used to implement __hyp_get_vectors in the same way as in + * arch/arm/kernel/hyp_stub.S. + * * The calling convention follows the standard AAPCS: * r0 - r3: caller save * r12: caller save @@ -363,6 +367,11 @@ hyp_hvc: host_switch_to_hyp: pop {r0, r1, r2} + /* Check for __hyp_get_vectors */ + cmp r0, #-1 + mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR + beq 1f + push {lr} mrs lr, SPSR push {lr} @@ -378,7 +387,7 @@ THUMB( orr lr, #1) pop {lr} msr SPSR_csxf, lr pop {lr} - eret +1: eret guest_trap: load_vcpu @ Load VCPU pointer to r0 diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S index 3b47c36e10ff..2c56012cb2d2 100644 --- a/arch/arm64/kvm/hyp.S +++ b/arch/arm64/kvm/hyp.S @@ -694,6 +694,24 @@ __hyp_panic_str: .align 2 +/* + * u64 kvm_call_hyp(void *hypfn, ...); + * + * This is not really a variadic function in the classic C-way and care must + * be taken when calling this to ensure parameters are passed in registers + * only, since the stack will change between the caller and the callee. + * + * Call the function with the first argument containing a pointer to the + * function you wish to call in Hyp mode, and subsequent arguments will be + * passed as x0, x1, and x2 (a maximum of 3 arguments in addition to the + * function pointer can be passed). The function being called must be mapped + * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are + * passed in r0 and r1. + * + * A function pointer with a value of 0 has a special meaning, and is + * used to implement __hyp_get_vectors in the same way as in + * arch/arm64/kernel/hyp_stub.S. + */ ENTRY(kvm_call_hyp) hvc #0 ret @@ -737,7 +755,12 @@ el1_sync: // Guest trapped into EL2 pop x2, x3 pop x0, x1 - push lr, xzr + /* Check for __hyp_get_vectors */ + cbnz x0, 1f + mrs x0, vbar_el2 + b 2f + +1: push lr, xzr /* * Compute the function address in EL2, and shuffle the parameters. @@ -750,7 +773,7 @@ el1_sync: // Guest trapped into EL2 blr lr pop lr, xzr - eret +2: eret el1_trap: /* -- cgit v1.2.3-55-g7522 From a08d3b3b99efd509133946056531cdf8f3a0c09b Mon Sep 17 00:00:00 2001 From: Andrew Honig Date: Thu, 27 Feb 2014 19:35:14 +0100 Subject: kvm: x86: fix emulator buffer overflow (CVE-2014-0049) The problem occurs when the guest performs a pusha with the stack address pointing to an mmio address (or an invalid guest physical address) to start with, but then extending into an ordinary guest physical address. When doing repeated emulated pushes emulator_read_write sets mmio_needed to 1 on the first one. On a later push when the stack points to regular memory, mmio_nr_fragments is set to 0, but mmio_is_needed is not set to 0. As a result, KVM exits to userspace, and then returns to complete_emulated_mmio. In complete_emulated_mmio vcpu->mmio_cur_fragment is incremented. The termination condition of vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments is never achieved. The code bounces back and fourth to userspace incrementing mmio_cur_fragment past it's buffer. If the guest does nothing else it eventually leads to a a crash on a memcpy from invalid memory address. However if a guest code can cause the vm to be destroyed in another vcpu with excellent timing, then kvm_clear_async_pf_completion_queue can be used by the guest to control the data that's pointed to by the call to cancel_work_item, which can be used to gain execution. Fixes: f78146b0f9230765c6315b2e14f56112513389ad Signed-off-by: Andrew Honig Cc: stable@vger.kernel.org (3.5+) Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 39c28f09dfd5..2b8578432d5b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6186,7 +6186,7 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) frag->len -= len; } - if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { + if (vcpu->mmio_cur_fragment >= vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; /* FIXME: return into emulator if single-stepping. */ -- cgit v1.2.3-55-g7522 From 1b385cbdd74aa803e966e01e5fe49490d6044e30 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 Feb 2014 22:54:11 +0100 Subject: kvm, vmx: Really fix lazy FPU on nested guest Commit e504c9098ed6 (kvm, vmx: Fix lazy FPU on nested guest, 2013-11-13) highlighted a real problem, but the fix was subtly wrong. nested_read_cr0 is the CR0 as read by L2, but here we want to look at the CR0 value reflecting L1's setup. In other words, L2 might think that TS=0 (so nested_read_cr0 has the bit clear); but if L1 is actually running it with TS=1, we should inject the fault into L1. The effective value of CR0 in L2 is contained in vmcs12->guest_cr0, use it. Fixes: e504c9098ed6acd9e1079c5e10e4910724ad429f Reported-by: Kashyap Chamarty Reported-by: Stefan Bader Tested-by: Kashyap Chamarty Tested-by: Anthoine Bourgeois Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a06f101ef64b..392752834751 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6688,7 +6688,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) else if (is_page_fault(intr_info)) return enable_ept; else if (is_no_device(intr_info) && - !(nested_read_cr0(vmcs12) & X86_CR0_TS)) + !(vmcs12->guest_cr0 & X86_CR0_TS)) return 0; return vmcs12->exception_bitmap & (1u << (intr_info & INTR_INFO_VECTOR_MASK)); -- cgit v1.2.3-55-g7522 From 4b41636878ee32d4c45a49de7749abca9721bd6a Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 27 Feb 2014 15:35:48 -0800 Subject: ARM: OMAP3: Fix pinctrl interrupts for core2 After splitting padconf core into two parts to avoid exposing unaccessable registers, the new padconf core2 domain was left without a wake-up interrupt. Fix the issue by passing the shared wake-up interrupt in platform data like we do for padconf core and wkup domains already. Fixes: 3d49538364 (ARM: dts: Split omap3 pinmux core device) Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 0cc710d0da90..c33e07e2f0d4 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -257,6 +257,7 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { #endif #ifdef CONFIG_ARCH_OMAP3 OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002030, "48002030.pinmux", &pcs_pdata), + OF_DEV_AUXDATA("ti,omap3-padconf", 0x480025a0, "480025a0.pinmux", &pcs_pdata), OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), /* Only on am3517 */ OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), -- cgit v1.2.3-55-g7522 From 41dd03a94c7d408d2ef32530545097f7d1befe5c Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Thu, 20 Feb 2014 21:13:52 +1100 Subject: powerpc/le: Ensure that the 'stop-self' RTAS token is handled correctly Currently we're storing a host endian RTAS token in rtas_stop_self_args.token. We then pass that directly to rtas. This is fine on big endian however on little endian the token is not what we expect. This will typically result in hitting: panic("Alas, I survived.\n"); To fix this we always use the stop-self token in host order and always convert it to be32 before passing this to rtas. Signed-off-by: Tony Breeds Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 82789e79e539..0ea99e3d4815 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -35,12 +35,7 @@ #include "offline_states.h" /* This version can't take the spinlock, because it never returns */ -static struct rtas_args rtas_stop_self_args = { - .token = RTAS_UNKNOWN_SERVICE, - .nargs = 0, - .nret = 1, - .rets = &rtas_stop_self_args.args[0], -}; +static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE; static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) = CPU_STATE_OFFLINE; @@ -93,15 +88,20 @@ void set_default_offline_state(int cpu) static void rtas_stop_self(void) { - struct rtas_args *args = &rtas_stop_self_args; + struct rtas_args args = { + .token = cpu_to_be32(rtas_stop_self_token), + .nargs = 0, + .nret = 1, + .rets = &args.args[0], + }; local_irq_disable(); - BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); + BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); printk("cpu %u (hwid %u) Ready to die...\n", smp_processor_id(), hard_smp_processor_id()); - enter_rtas(__pa(args)); + enter_rtas(__pa(&args)); panic("Alas, I survived.\n"); } @@ -392,10 +392,10 @@ static int __init pseries_cpu_hotplug_init(void) } } - rtas_stop_self_args.token = rtas_token("stop-self"); + rtas_stop_self_token = rtas_token("stop-self"); qcss_tok = rtas_token("query-cpu-stopped-state"); - if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || + if (rtas_stop_self_token == RTAS_UNKNOWN_SERVICE || qcss_tok == RTAS_UNKNOWN_SERVICE) { printk(KERN_INFO "CPU Hotplug not supported by firmware " "- disabling.\n"); -- cgit v1.2.3-55-g7522 From f5295bd8ea8a65dc5eac608b151386314cb978f1 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Mon, 24 Feb 2014 17:30:55 +0100 Subject: powerpc/crashdump : Fix page frame number check in copy_oldmem_page In copy_oldmem_page, the current check using max_pfn and min_low_pfn to decide if the page is backed or not, is not valid when the memory layout is not continuous. This happens when running as a QEMU/KVM guest, where RTAS is mapped higher in the memory. In that case max_pfn points to the end of RTAS, and a hole between the end of the kdump kernel and RTAS is not backed by PTEs. As a consequence, the kdump kernel is crashing in copy_oldmem_page when accessing in a direct way the pages in that hole. This fix relies on the memblock's service memblock_is_region_memory to check if the read page is part or not of the directly accessible memory. Signed-off-by: Laurent Dufour Tested-by: Mahesh Salgaonkar CC: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash_dump.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 11c1d069d920..7a13f378ca2c 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -98,17 +98,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, unsigned long offset, int userbuf) { void *vaddr; + phys_addr_t paddr; if (!csize) return 0; csize = min_t(size_t, csize, PAGE_SIZE); + paddr = pfn << PAGE_SHIFT; - if ((min_low_pfn < pfn) && (pfn < max_pfn)) { - vaddr = __va(pfn << PAGE_SHIFT); + if (memblock_is_region_memory(paddr, csize)) { + vaddr = __va(paddr); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); } else { - vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); + vaddr = __ioremap(paddr, PAGE_SIZE, 0); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); iounmap(vaddr); } -- cgit v1.2.3-55-g7522 From a95fc58549e8f462e560868a16b1fa97b12d5db6 Mon Sep 17 00:00:00 2001 From: Liu Ping Fan Date: Wed, 26 Feb 2014 10:23:01 +0800 Subject: powerpc/ftrace: bugfix for test_24bit_addr The branch target should be the func addr, not the addr of func_descr_t. So using ppc_function_entry() to generate the right target addr. Signed-off-by: Liu Ping Fan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/ftrace.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 9b27b293a922..b0ded97ee4e1 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -74,6 +74,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) */ static int test_24bit_addr(unsigned long ip, unsigned long addr) { + addr = ppc_function_entry((void *)addr); /* use the create_branch to verify that this offset can be branched */ return create_branch((unsigned int *)ip, addr, 0); -- cgit v1.2.3-55-g7522 From 573ebfa6601fa58b439e7f15828762839ccd306a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 26 Feb 2014 17:07:38 +1100 Subject: powerpc: Increase stack redzone for 64-bit userspace to 512 bytes The new ELFv2 little-endian ABI increases the stack redzone -- the area below the stack pointer that can be used for storing data -- from 288 bytes to 512 bytes. This means that we need to allow more space on the user stack when delivering a signal to a 64-bit process. To make the code a bit clearer, we define new USER_REDZONE_SIZE and KERNEL_REDZONE_SIZE symbols in ptrace.h. For now, we leave the kernel redzone size at 288 bytes, since increasing it to 512 bytes would increase the size of interrupt stack frames correspondingly. Gcc currently only makes use of 288 bytes of redzone even when compiling for the new little-endian ABI, and the kernel cannot currently be compiled with the new ABI anyway. In the future, hopefully gcc will provide an option to control the amount of redzone used, and then we could reduce it even more. This also changes the code in arch_compat_alloc_user_space() to preserve the expanded redzone. It is not clear why this function would ever be used on a 64-bit process, though. Signed-off-by: Paul Mackerras CC: [v3.13] Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/compat.h | 5 +++-- arch/powerpc/include/asm/ptrace.h | 16 +++++++++++++++- arch/powerpc/kernel/signal_64.c | 4 ++-- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 84fdf6857c31..a613d2c82fd9 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -200,10 +200,11 @@ static inline void __user *arch_compat_alloc_user_space(long len) /* * We can't access below the stack pointer in the 32bit ABI and - * can access 288 bytes in the 64bit ABI + * can access 288 bytes in the 64bit big-endian ABI, + * or 512 bytes with the new ELFv2 little-endian ABI. */ if (!is_32bit_task()) - usp -= 288; + usp -= USER_REDZONE_SIZE; return (void __user *) (usp - len); } diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index becc08e6a65c..279b80f3bb29 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h @@ -28,11 +28,23 @@ #ifdef __powerpc64__ +/* + * Size of redzone that userspace is allowed to use below the stack + * pointer. This is 288 in the 64-bit big-endian ELF ABI, and 512 in + * the new ELFv2 little-endian ABI, so we allow the larger amount. + * + * For kernel code we allow a 288-byte redzone, in order to conserve + * kernel stack space; gcc currently only uses 288 bytes, and will + * hopefully allow explicit control of the redzone size in future. + */ +#define USER_REDZONE_SIZE 512 +#define KERNEL_REDZONE_SIZE 288 + #define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ #define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */ #define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265) #define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \ - STACK_FRAME_OVERHEAD + 288) + STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE) #define STACK_FRAME_MARKER 12 /* Size of dummy stack frame allocated when calling signal handler. */ @@ -41,6 +53,8 @@ #else /* __powerpc64__ */ +#define USER_REDZONE_SIZE 0 +#define KERNEL_REDZONE_SIZE 0 #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ #define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */ #define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index e35bf773df7a..8d253c29649b 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -65,8 +65,8 @@ struct rt_sigframe { struct siginfo __user *pinfo; void __user *puc; struct siginfo info; - /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ - char abigap[288]; + /* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */ + char abigap[USER_REDZONE_SIZE]; } __attribute__ ((aligned (16))); static const char fmt32[] = KERN_INFO \ -- cgit v1.2.3-55-g7522 From 947166043732b69878123bf31f51933ad0316080 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 25 Feb 2014 15:28:37 +0800 Subject: powerpc/powernv: Dump PHB diag-data immediately The PHB diag-data is important to help locating the root cause for EEH errors such as frozen PE or fenced PHB. However, the EEH core enables IO path by clearing part of HW registers before collecting this data causing it to be corrupted. This patch fixes this by dumping the PHB diag-data immediately when frozen/fenced state on PE or PHB is detected for the first time in eeh_ops::get_state() or next_error() backend. Signed-off-by: Gavin Shan CC: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/eeh-ioda.c | 96 ++++++++++++++----------------- 1 file changed, 43 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index f51474336460..253fefe3d1a0 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -114,6 +114,7 @@ DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get, ioda_eeh_inbB_dbgfs_set, "0x%llx\n"); #endif /* CONFIG_DEBUG_FS */ + /** * ioda_eeh_post_init - Chip dependent post initialization * @hose: PCI controller @@ -221,6 +222,22 @@ static int ioda_eeh_set_option(struct eeh_pe *pe, int option) return ret; } +static void ioda_eeh_phb_diag(struct pci_controller *hose) +{ + struct pnv_phb *phb = hose->private_data; + long rc; + + rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, + PNV_PCI_DIAG_BUF_SIZE); + if (rc != OPAL_SUCCESS) { + pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", + __func__, hose->global_number, rc); + return; + } + + pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); +} + /** * ioda_eeh_get_state - Retrieve the state of PE * @pe: EEH PE @@ -272,6 +289,9 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) result |= EEH_STATE_DMA_ACTIVE; result |= EEH_STATE_MMIO_ENABLED; result |= EEH_STATE_DMA_ENABLED; + } else if (!(pe->state & EEH_PE_ISOLATED)) { + eeh_pe_state_mark(pe, EEH_PE_ISOLATED); + ioda_eeh_phb_diag(hose); } return result; @@ -315,6 +335,15 @@ static int ioda_eeh_get_state(struct eeh_pe *pe) __func__, fstate, hose->global_number, pe_no); } + /* Dump PHB diag-data for frozen PE */ + if (result != EEH_STATE_NOT_SUPPORT && + (result & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) != + (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE) && + !(pe->state & EEH_PE_ISOLATED)) { + eeh_pe_state_mark(pe, EEH_PE_ISOLATED); + ioda_eeh_phb_diag(hose); + } + return result; } @@ -529,42 +558,6 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) return ret; } -/** - * ioda_eeh_get_log - Retrieve error log - * @pe: EEH PE - * @severity: Severity level of the log - * @drv_log: buffer to store the log - * @len: space of the log buffer - * - * The function is used to retrieve error log from P7IOC. - */ -static int ioda_eeh_get_log(struct eeh_pe *pe, int severity, - char *drv_log, unsigned long len) -{ - s64 ret; - unsigned long flags; - struct pci_controller *hose = pe->phb; - struct pnv_phb *phb = hose->private_data; - - spin_lock_irqsave(&phb->lock, flags); - - ret = opal_pci_get_phb_diag_data2(phb->opal_id, - phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); - if (ret) { - spin_unlock_irqrestore(&phb->lock, flags); - pr_warning("%s: Can't get log for PHB#%x-PE#%x (%lld)\n", - __func__, hose->global_number, pe->addr, ret); - return -EIO; - } - - /* The PHB diag-data is always indicative */ - pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); - - spin_unlock_irqrestore(&phb->lock, flags); - - return 0; -} - /** * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE * @pe: EEH PE @@ -646,22 +639,6 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose) } } -static void ioda_eeh_phb_diag(struct pci_controller *hose) -{ - struct pnv_phb *phb = hose->private_data; - long rc; - - rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, - PNV_PCI_DIAG_BUF_SIZE); - if (rc != OPAL_SUCCESS) { - pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", - __func__, hose->global_number, rc); - return; - } - - pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); -} - static int ioda_eeh_get_phb_pe(struct pci_controller *hose, struct eeh_pe **pe) { @@ -834,6 +811,20 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) __func__, err_type); } + /* + * EEH core will try recover from fenced PHB or + * frozen PE. In the time for frozen PE, EEH core + * enable IO path for that before collecting logs, + * but it ruins the site. So we have to dump the + * log in advance here. + */ + if ((ret == EEH_NEXT_ERR_FROZEN_PE || + ret == EEH_NEXT_ERR_FENCED_PHB) && + !((*pe)->state & EEH_PE_ISOLATED)) { + eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); + ioda_eeh_phb_diag(hose); + } + /* * If we have no errors on the specific PHB or only * informative error there, we continue poking it. @@ -852,7 +843,6 @@ struct pnv_eeh_ops ioda_eeh_ops = { .set_option = ioda_eeh_set_option, .get_state = ioda_eeh_get_state, .reset = ioda_eeh_reset, - .get_log = ioda_eeh_get_log, .configure_bridge = ioda_eeh_configure_bridge, .next_error = ioda_eeh_next_error }; -- cgit v1.2.3-55-g7522 From af87d2fe95444d107e0c0cf0ba7e20e6716a7bfd Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Tue, 25 Feb 2014 15:28:38 +0800 Subject: powerpc/powernv: Refactor PHB diag-data dump As Ben suggested, the patch prints PHB diag-data with multiple fields in one line and omits the line if the fields of that line are all zero. With the patch applied, the PHB3 diag-data dump looks like: PHB3 PHB#3 Diag-data (Version: 1) brdgCtl: 00000002 RootSts: 0000000f 00400000 b0830008 00100147 00002000 nFir: 0000000000000000 0030006e00000000 0000000000000000 PhbSts: 0000001c00000000 0000000000000000 Lem: 0000000000100000 42498e327f502eae 0000000000000000 InAErr: 8000000000000000 8000000000000000 0402030000000000 0000000000000000 PE[ 8] A/B: 8480002b00000000 8000000000000000 [ The current diag data is so big that it overflows the printk buffer pretty quickly in cases when we get a handful of errors at once which can happen. --BenH ] Signed-off-by: Gavin Shan CC: Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/pci.c | 220 ++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 95 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 95633d79ef5d..8518817dcdfd 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -134,57 +134,72 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n", hose->global_number, common->version); - pr_info(" brdgCtl: %08x\n", data->brdgCtl); - - pr_info(" portStatusReg: %08x\n", data->portStatusReg); - pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); - pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); - - pr_info(" deviceStatus: %08x\n", data->deviceStatus); - pr_info(" slotStatus: %08x\n", data->slotStatus); - pr_info(" linkStatus: %08x\n", data->linkStatus); - pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); - pr_info(" devSecStatus: %08x\n", data->devSecStatus); - - pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); - pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); - pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); - pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); - pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); - pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); - pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); - pr_info(" sourceId: %08x\n", data->sourceId); - pr_info(" errorClass: %016llx\n", data->errorClass); - pr_info(" correlator: %016llx\n", data->correlator); - pr_info(" p7iocPlssr: %016llx\n", data->p7iocPlssr); - pr_info(" p7iocCsr: %016llx\n", data->p7iocCsr); - pr_info(" lemFir: %016llx\n", data->lemFir); - pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); - pr_info(" lemWOF: %016llx\n", data->lemWOF); - pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); - pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); - pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); - pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); - pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); - pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); - pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); - pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); - pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); - pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); - pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); - pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); - pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); - pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); - pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); - pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); + if (data->brdgCtl) + pr_info(" brdgCtl: %08x\n", + data->brdgCtl); + if (data->portStatusReg || data->rootCmplxStatus || + data->busAgentStatus) + pr_info(" UtlSts: %08x %08x %08x\n", + data->portStatusReg, data->rootCmplxStatus, + data->busAgentStatus); + if (data->deviceStatus || data->slotStatus || + data->linkStatus || data->devCmdStatus || + data->devSecStatus) + pr_info(" RootSts: %08x %08x %08x %08x %08x\n", + data->deviceStatus, data->slotStatus, + data->linkStatus, data->devCmdStatus, + data->devSecStatus); + if (data->rootErrorStatus || data->uncorrErrorStatus || + data->corrErrorStatus) + pr_info(" RootErrSts: %08x %08x %08x\n", + data->rootErrorStatus, data->uncorrErrorStatus, + data->corrErrorStatus); + if (data->tlpHdr1 || data->tlpHdr2 || + data->tlpHdr3 || data->tlpHdr4) + pr_info(" RootErrLog: %08x %08x %08x %08x\n", + data->tlpHdr1, data->tlpHdr2, + data->tlpHdr3, data->tlpHdr4); + if (data->sourceId || data->errorClass || + data->correlator) + pr_info(" RootErrLog1: %08x %016llx %016llx\n", + data->sourceId, data->errorClass, + data->correlator); + if (data->p7iocPlssr || data->p7iocCsr) + pr_info(" PhbSts: %016llx %016llx\n", + data->p7iocPlssr, data->p7iocCsr); + if (data->lemFir || data->lemErrorMask || + data->lemWOF) + pr_info(" Lem: %016llx %016llx %016llx\n", + data->lemFir, data->lemErrorMask, + data->lemWOF); + if (data->phbErrorStatus || data->phbFirstErrorStatus || + data->phbErrorLog0 || data->phbErrorLog1) + pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", + data->phbErrorStatus, data->phbFirstErrorStatus, + data->phbErrorLog0, data->phbErrorLog1); + if (data->mmioErrorStatus || data->mmioFirstErrorStatus || + data->mmioErrorLog0 || data->mmioErrorLog1) + pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", + data->mmioErrorStatus, data->mmioFirstErrorStatus, + data->mmioErrorLog0, data->mmioErrorLog1); + if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || + data->dma0ErrorLog0 || data->dma0ErrorLog1) + pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", + data->dma0ErrorStatus, data->dma0FirstErrorStatus, + data->dma0ErrorLog0, data->dma0ErrorLog1); + if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || + data->dma1ErrorLog0 || data->dma1ErrorLog1) + pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", + data->dma1ErrorStatus, data->dma1FirstErrorStatus, + data->dma1ErrorLog0, data->dma1ErrorLog1); for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { if ((data->pestA[i] >> 63) == 0 && (data->pestB[i] >> 63) == 0) continue; - pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); - pr_info(" PESTB: %016llx\n", data->pestB[i]); + pr_info(" PE[%3d] A/B: %016llx %016llx\n", + i, data->pestA[i], data->pestB[i]); } } @@ -197,62 +212,77 @@ static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose, data = (struct OpalIoPhb3ErrorData*)common; pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n", hose->global_number, common->version); - - pr_info(" brdgCtl: %08x\n", data->brdgCtl); - - pr_info(" portStatusReg: %08x\n", data->portStatusReg); - pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); - pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); - - pr_info(" deviceStatus: %08x\n", data->deviceStatus); - pr_info(" slotStatus: %08x\n", data->slotStatus); - pr_info(" linkStatus: %08x\n", data->linkStatus); - pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); - pr_info(" devSecStatus: %08x\n", data->devSecStatus); - - pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); - pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); - pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); - pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); - pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); - pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); - pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); - pr_info(" sourceId: %08x\n", data->sourceId); - pr_info(" errorClass: %016llx\n", data->errorClass); - pr_info(" correlator: %016llx\n", data->correlator); - - pr_info(" nFir: %016llx\n", data->nFir); - pr_info(" nFirMask: %016llx\n", data->nFirMask); - pr_info(" nFirWOF: %016llx\n", data->nFirWOF); - pr_info(" PhbPlssr: %016llx\n", data->phbPlssr); - pr_info(" PhbCsr: %016llx\n", data->phbCsr); - pr_info(" lemFir: %016llx\n", data->lemFir); - pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); - pr_info(" lemWOF: %016llx\n", data->lemWOF); - pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); - pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); - pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); - pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); - pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); - pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); - pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); - pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); - pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); - pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); - pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); - pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); - pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); - pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); - pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); - pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); + if (data->brdgCtl) + pr_info(" brdgCtl: %08x\n", + data->brdgCtl); + if (data->portStatusReg || data->rootCmplxStatus || + data->busAgentStatus) + pr_info(" UtlSts: %08x %08x %08x\n", + data->portStatusReg, data->rootCmplxStatus, + data->busAgentStatus); + if (data->deviceStatus || data->slotStatus || + data->linkStatus || data->devCmdStatus || + data->devSecStatus) + pr_info(" RootSts: %08x %08x %08x %08x %08x\n", + data->deviceStatus, data->slotStatus, + data->linkStatus, data->devCmdStatus, + data->devSecStatus); + if (data->rootErrorStatus || data->uncorrErrorStatus || + data->corrErrorStatus) + pr_info(" RootErrSts: %08x %08x %08x\n", + data->rootErrorStatus, data->uncorrErrorStatus, + data->corrErrorStatus); + if (data->tlpHdr1 || data->tlpHdr2 || + data->tlpHdr3 || data->tlpHdr4) + pr_info(" RootErrLog: %08x %08x %08x %08x\n", + data->tlpHdr1, data->tlpHdr2, + data->tlpHdr3, data->tlpHdr4); + if (data->sourceId || data->errorClass || + data->correlator) + pr_info(" RootErrLog1: %08x %016llx %016llx\n", + data->sourceId, data->errorClass, + data->correlator); + if (data->nFir || data->nFirMask || + data->nFirWOF) + pr_info(" nFir: %016llx %016llx %016llx\n", + data->nFir, data->nFirMask, + data->nFirWOF); + if (data->phbPlssr || data->phbCsr) + pr_info(" PhbSts: %016llx %016llx\n", + data->phbPlssr, data->phbCsr); + if (data->lemFir || data->lemErrorMask || + data->lemWOF) + pr_info(" Lem: %016llx %016llx %016llx\n", + data->lemFir, data->lemErrorMask, + data->lemWOF); + if (data->phbErrorStatus || data->phbFirstErrorStatus || + data->phbErrorLog0 || data->phbErrorLog1) + pr_info(" PhbErr: %016llx %016llx %016llx %016llx\n", + data->phbErrorStatus, data->phbFirstErrorStatus, + data->phbErrorLog0, data->phbErrorLog1); + if (data->mmioErrorStatus || data->mmioFirstErrorStatus || + data->mmioErrorLog0 || data->mmioErrorLog1) + pr_info(" OutErr: %016llx %016llx %016llx %016llx\n", + data->mmioErrorStatus, data->mmioFirstErrorStatus, + data->mmioErrorLog0, data->mmioErrorLog1); + if (data->dma0ErrorStatus || data->dma0FirstErrorStatus || + data->dma0ErrorLog0 || data->dma0ErrorLog1) + pr_info(" InAErr: %016llx %016llx %016llx %016llx\n", + data->dma0ErrorStatus, data->dma0FirstErrorStatus, + data->dma0ErrorLog0, data->dma0ErrorLog1); + if (data->dma1ErrorStatus || data->dma1FirstErrorStatus || + data->dma1ErrorLog0 || data->dma1ErrorLog1) + pr_info(" InBErr: %016llx %016llx %016llx %016llx\n", + data->dma1ErrorStatus, data->dma1FirstErrorStatus, + data->dma1ErrorLog0, data->dma1ErrorLog1); for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { if ((data->pestA[i] >> 63) == 0 && (data->pestB[i] >> 63) == 0) continue; - pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); - pr_info(" PESTB: %016llx\n", data->pestB[i]); + pr_info(" PE[%3d] A/B: %016llx %016llx\n", + i, data->pestA[i], data->pestB[i]); } } -- cgit v1.2.3-55-g7522 From 2f3f38e4d3d03dd4125cc9a1f49ab3cc91d8d670 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 28 Feb 2014 16:20:29 +1100 Subject: powerpc/powernv: Fix opal_xscom_{read,write} prototype The OPAL firmware functions opal_xscom_read and opal_xscom_write take a 64-bit argument for the XSCOM (PCB) address in order to support the indirect mode on P8. Signed-off-by: Benjamin Herrenschmidt CC: [v3.13] --- arch/powerpc/include/asm/opal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 40157e2ca691..ed82142a3251 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -816,8 +816,8 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe, int64_t opal_pci_poll(uint64_t phb_id); int64_t opal_return_cpu(void); -int64_t opal_xscom_read(uint32_t gcid, uint32_t pcb_addr, __be64 *val); -int64_t opal_xscom_write(uint32_t gcid, uint32_t pcb_addr, uint64_t val); +int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); +int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, uint32_t addr, uint32_t data, uint32_t sz); -- cgit v1.2.3-55-g7522 From e0cf957614976896111e676e5134ac98ee227d3d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 28 Feb 2014 16:20:38 +1100 Subject: powerpc/powernv: Fix indirect XSCOM unmangling We need to unmangle the full address, not just the register number, and we also need to support the real indirect bit being set for in-kernel uses. Signed-off-by: Benjamin Herrenschmidt CC: [v3.13] --- arch/powerpc/platforms/powernv/opal-xscom.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 4fbf276ac99e..4cd2ea6c0dbe 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -71,11 +71,11 @@ static int opal_xscom_err_xlate(int64_t rc) } } -static u64 opal_scom_unmangle(u64 reg) +static u64 opal_scom_unmangle(u64 addr) { /* * XSCOM indirect addresses have the top bit set. Additionally - * the reset of the top 3 nibbles is always 0. + * the rest of the top 3 nibbles is always 0. * * Because the debugfs interface uses signed offsets and shifts * the address left by 3, we basically cannot use the top 4 bits @@ -86,10 +86,13 @@ static u64 opal_scom_unmangle(u64 reg) * conversion here. To leave room for further xscom address * expansion, we only clear out the top byte * + * For in-kernel use, we also support the real indirect bit, so + * we test for any of the top 5 bits + * */ - if (reg & (1ull << 59)) - reg = (reg & ~(0xffull << 56)) | (1ull << 63); - return reg; + if (addr & (0x1full << 59)) + addr = (addr & ~(0xffull << 56)) | (1ull << 63); + return addr; } static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) @@ -98,8 +101,8 @@ static int opal_scom_read(scom_map_t map, u64 reg, u64 *value) int64_t rc; __be64 v; - reg = opal_scom_unmangle(reg); - rc = opal_xscom_read(m->chip, m->addr + reg, (__be64 *)__pa(&v)); + reg = opal_scom_unmangle(m->addr + reg); + rc = opal_xscom_read(m->chip, reg, (__be64 *)__pa(&v)); *value = be64_to_cpu(v); return opal_xscom_err_xlate(rc); } @@ -109,8 +112,8 @@ static int opal_scom_write(scom_map_t map, u64 reg, u64 value) struct opal_scom_map *m = map; int64_t rc; - reg = opal_scom_unmangle(reg); - rc = opal_xscom_write(m->chip, m->addr + reg, value); + reg = opal_scom_unmangle(m->addr + reg); + rc = opal_xscom_write(m->chip, reg, value); return opal_xscom_err_xlate(rc); } -- cgit v1.2.3-55-g7522 From 288ac26cc2334e5e6ecad6416e9bf750691afd84 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 28 Feb 2014 09:57:47 +0000 Subject: arm64: remove redundant "psci:" prefixes Since 652af899799354049b273af897b798b8f03fdd88 "arm64: factor out spin-table boot method" psci prefix's been introduced. We have a common pr_fmt, so clean them up. Signed-off-by: Vladimir Murzin Acked-by: Mark Rutland Signed-off-by: Catalin Marinas --- arch/arm64/kernel/psci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 4f97db3d7363..83ebee880d19 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -251,7 +251,7 @@ static int cpu_psci_cpu_boot(unsigned int cpu) { int err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_entry)); if (err) - pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); + pr_err("failed to boot CPU%d (%d)\n", cpu, err); return err; } @@ -278,7 +278,7 @@ static void cpu_psci_cpu_die(unsigned int cpu) ret = psci_ops.cpu_off(state); - pr_crit("psci: unable to power off CPU%u (%d)\n", cpu, ret); + pr_crit("unable to power off CPU%u (%d)\n", cpu, ret); } #endif -- cgit v1.2.3-55-g7522 From 64b4f60f497058f1c6ba118a0260249ee5c091a6 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Fri, 28 Feb 2014 09:57:33 +0000 Subject: arm64: remove return value form psci_init() psci_init() is written to return err code if something goes wrong. However, the single user, setup_arch(), doesn't care about it. Moreover, every error path is supplied with a clear message which is enough for pleasant debugging. Signed-off-by: Vladimir Murzin Acked-by: Mark Rutland Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/psci.h | 2 +- arch/arm64/kernel/psci.c | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/psci.h b/arch/arm64/include/asm/psci.h index e5312ea0ec1a..d15ab8b46336 100644 --- a/arch/arm64/include/asm/psci.h +++ b/arch/arm64/include/asm/psci.h @@ -14,6 +14,6 @@ #ifndef __ASM_PSCI_H #define __ASM_PSCI_H -int psci_init(void); +void psci_init(void); #endif /* __ASM_PSCI_H */ diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index 83ebee880d19..ea4828a4aa96 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -176,22 +176,20 @@ static const struct of_device_id psci_of_match[] __initconst = { {}, }; -int __init psci_init(void) +void __init psci_init(void) { struct device_node *np; const char *method; u32 id; - int err = 0; np = of_find_matching_node(NULL, psci_of_match); if (!np) - return -ENODEV; + return; pr_info("probing function IDs from device-tree\n"); if (of_property_read_string(np, "method", &method)) { pr_warning("missing \"method\" property\n"); - err = -ENXIO; goto out_put_node; } @@ -201,7 +199,6 @@ int __init psci_init(void) invoke_psci_fn = __invoke_psci_fn_smc; } else { pr_warning("invalid \"method\" property: %s\n", method); - err = -EINVAL; goto out_put_node; } @@ -227,7 +224,7 @@ int __init psci_init(void) out_put_node: of_node_put(np); - return err; + return; } #ifdef CONFIG_SMP -- cgit v1.2.3-55-g7522 From addea9ef055bf5a10f9ec967b1e0443ceb44bd83 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 24 Feb 2014 02:27:57 +0000 Subject: cpufreq: enable ARM drivers on arm64 Enable cpufreq and power kconfig menus on arm64 along with arm cpufreq drivers. The power menu is needed for OPP support. At least on Calxeda systems, the same cpufreq driver is used for arm and arm64 based systems. Signed-off-by: Rob Herring Acked-by: Viresh Kumar Signed-off-by: Mark Brown Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 8 ++++++++ drivers/cpufreq/Kconfig | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 33e8f845a540..c2056ca04ae2 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -304,6 +304,14 @@ source "drivers/cpuidle/Kconfig" endmenu +menu "Power management options" + +source "kernel/power/Kconfig" + +source "drivers/cpufreq/Kconfig" + +endmenu + source "net/Kconfig" source "drivers/Kconfig" diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4b029c0944af..1fbe11f2a146 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -200,7 +200,7 @@ source "drivers/cpufreq/Kconfig.x86" endmenu menu "ARM CPU frequency scaling drivers" -depends on ARM +depends on ARM || ARM64 source "drivers/cpufreq/Kconfig.arm" endmenu -- cgit v1.2.3-55-g7522 From 84fe6826c28f69d8708bd575faed7f75e6b6f57f Mon Sep 17 00:00:00 2001 From: Steve Capper Date: Tue, 25 Feb 2014 11:38:53 +0000 Subject: arm64: mm: Add double logical invert to pte accessors Page table entries on ARM64 are 64 bits, and some pte functions such as pte_dirty return a bitwise-and of a flag with the pte value. If the flag to be tested resides in the upper 32 bits of the pte, then we run into the danger of the result being dropped if downcast. For example: gather_stats(page, md, pte_dirty(*pte), 1); where pte_dirty(*pte) is downcast to an int. This patch adds a double logical invert to all the pte_ accessors to ensure predictable downcasting. Signed-off-by: Steve Capper Cc: Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/pgtable.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index b524dcd17243..aa3917c8b623 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -136,11 +136,11 @@ extern struct page *empty_zero_page; /* * The following only work if pte_present(). Undefined behaviour otherwise. */ -#define pte_present(pte) (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) -#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY) -#define pte_young(pte) (pte_val(pte) & PTE_AF) -#define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) -#define pte_write(pte) (pte_val(pte) & PTE_WRITE) +#define pte_present(pte) (!!(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))) +#define pte_dirty(pte) (!!(pte_val(pte) & PTE_DIRTY)) +#define pte_young(pte) (!!(pte_val(pte) & PTE_AF)) +#define pte_special(pte) (!!(pte_val(pte) & PTE_SPECIAL)) +#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE)) #define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_valid_user(pte) \ -- cgit v1.2.3-55-g7522 From b57fc9e80692043e2a3a74e1d2c047eb700dcd0c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 28 Feb 2014 16:12:25 +0000 Subject: arm64: Fix !CONFIG_SMP kernel build Commit fb4a96029c8a (arm64: kernel: fix per-cpu offset restore on resume) uses per_cpu_offset() unconditionally during CPU wakeup, however, this is only defined for the SMP case. Signed-off-by: Catalin Marinas Reported-by: Dave P Martin --- arch/arm64/include/asm/percpu.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 13fb0b3efc5f..453a179469a3 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h @@ -16,6 +16,8 @@ #ifndef __ASM_PERCPU_H #define __ASM_PERCPU_H +#ifdef CONFIG_SMP + static inline void set_my_cpu_offset(unsigned long off) { asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); @@ -36,6 +38,12 @@ static inline unsigned long __my_cpu_offset(void) } #define __my_cpu_offset __my_cpu_offset() +#else /* !CONFIG_SMP */ + +#define set_my_cpu_offset(x) do { } while (0) + +#endif /* CONFIG_SMP */ + #include #endif /* __ASM_PERCPU_H */ -- cgit v1.2.3-55-g7522 From f3ffaaa8b727da6c442b5b8cb356c2196b6e2d59 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Fri, 28 Feb 2014 11:02:02 -0800 Subject: [IA64] sba_iommu: fix section mismatch To: linux-kernel@vger.kernel.org Fix the section mismatch warning by remove __init annotate for functions ioc_iova_init(), ioc_init() and acpi_sba_ioc_add() because they may be called at runtime. WARNING: vmlinux.o(.data+0x66ee0): Section mismatch in reference from the variable acpi_sba_ioc_handler to the function .init.text:acpi_sba_ioc_add() The variable acpi_sba_ioc_handler references the function __init acpi_sba_ioc_add() Signed-off-by: Jiang Liu Signed-off-by: Tony Luck --- arch/ia64/hp/common/sba_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 8e858b593e4f..30c43d39dede 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1596,7 +1596,7 @@ static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, * ***************************************************************/ -static void __init +static void ioc_iova_init(struct ioc *ioc) { int tcnfg; @@ -1807,7 +1807,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { SX2000_IOC_ID, "sx2000", NULL }, }; -static struct ioc * __init +static struct ioc * ioc_init(unsigned long hpa, void *handle) { struct ioc *ioc; @@ -2041,7 +2041,7 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) #define sba_map_ioc_to_node(ioc, handle) #endif -static int __init +static int acpi_sba_ioc_add(struct acpi_device *device, const struct acpi_device_id *not_used) { -- cgit v1.2.3-55-g7522 From d21114236d0e1232023cb8c84bd29e06810f6a2f Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Mon, 17 Feb 2014 13:59:30 +0800 Subject: Fix warning in make defconfig Now the ACPI container and ACPI PCI hotplug driver has been converted as built-in modules, so reflect these changes in IA64 defconfig file. Signed-off-by: Jiang Liu Signed-off-by: Tony Luck --- arch/ia64/configs/generic_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index efbd2929aeb7..6404acbb84b2 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -30,9 +30,9 @@ CONFIG_ACPI_BUTTON=m CONFIG_ACPI_FAN=m CONFIG_ACPI_DOCK=y CONFIG_ACPI_PROCESSOR=m -CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_CONTAINER=y CONFIG_HOTPLUG_PCI=y -CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -- cgit v1.2.3-55-g7522 From fb0cfecf67cc1cec4487efb6267317de432add2f Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 22 Feb 2014 10:59:36 -0300 Subject: ARM: dts: omap3-igep: fix boot fail due wrong compatible match This patch is based on commit: 016c12d2 ("ARM: OMAP3: Fix hardware detection for omap3630 when booted with device tree") and fixes a boot hang due the IGEP board being wrongly initialized as an OMAP3430 platform instead of an OMAP3630. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-igep0020.dts | 2 +- arch/arm/boot/dts/omap3-igep0030.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index 25a2b5f652fd..f2779ac75872 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -14,7 +14,7 @@ / { model = "IGEPv2 (TI OMAP AM/DM37x)"; - compatible = "isee,omap3-igep0020", "ti,omap3"; + compatible = "isee,omap3-igep0020", "ti,omap36xx", "ti,omap3"; leds { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts index 145c58cfc8ac..2793749eb1ba 100644 --- a/arch/arm/boot/dts/omap3-igep0030.dts +++ b/arch/arm/boot/dts/omap3-igep0030.dts @@ -13,7 +13,7 @@ / { model = "IGEP COM MODULE (TI OMAP AM/DM37x)"; - compatible = "isee,omap3-igep0030", "ti,omap3"; + compatible = "isee,omap3-igep0030", "ti,omap36xx", "ti,omap3"; leds { pinctrl-names = "default"; -- cgit v1.2.3-55-g7522 From 014325e933b43844f5d01fcef39bbc3301320e59 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 20 Feb 2014 14:37:20 -0700 Subject: ARM: tegra: add LED options back into tegra_defconfig The last time tegra_defconfig was rebuilt, various LEDs options were somehow selected by other options, and hence their entries in tegra_defconfig were removed by "make savedefconfig". However, for some reason this is no longer happening, so we need to add the entries back into tegra_defconfig so the they are enabled in .config. Fixes: db079b1811d1 ("ARM: tegra: rebuild tegra_defconfig to add DEBUG_FS)" Reported-by: Marc Dietrich Signed-off-by: Stephen Warren Signed-off-by: Arnd Bergmann --- arch/arm/configs/tegra_defconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 00fe9e9710fd..27d69b558c5d 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -204,7 +204,10 @@ CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -- cgit v1.2.3-55-g7522 From ae41a3030ce8901853b3cfd5e118a4b0288aa068 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Sat, 1 Mar 2014 14:58:48 +0100 Subject: ARM: dts: omap3-gta04: Add ti,omap36xx to compatible property to avoid problems with booting Without that change booting leads to crash with more warnings like below: [ 0.284454] omap_hwmod: uart4: cannot clk_get main_clk uart4_fck [ 0.284484] omap_hwmod: uart4: cannot _init_clocks [ 0.284484] ------------[ cut here ]------------ [ 0.284545] WARNING: CPU: 0 PID: 1 at arch/arm/mach-omap2/omap_hwmod.c:2543 _init+0x300/0x3e4() [ 0.284545] omap_hwmod: uart4: couldn't init clocks [ 0.284576] Modules linked in: [ 0.284606] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.13.0-next-20140124-00020-gd2aefec-dirty #26 [ 0.284637] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 0.284667] [] (show_stack) from [] (dump_stack+0x7c/0x94) [ 0.284729] [] (dump_stack) from [] (warn_slowpath_common+0x6c/0x90) [ 0.284729] [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [ 0.284759] [] (warn_slowpath_fmt) from [] (_init+0x300/0x3e4) [ 0.284790] [] (_init) from [] (__omap_hwmod_setup_all+0x40/0x8c) [ 0.284820] [] (__omap_hwmod_setup_all) from [] (do_one_initcall+0xe8/0x14c) [ 0.284851] [] (do_one_initcall) from [] (kernel_init_freeable+0x104/0x1c8) [ 0.284881] [] (kernel_init_freeable) from [] (kernel_init+0x8/0x118) [ 0.284912] [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) [ 0.285064] ---[ end trace 63de210ad43b627d ]--- Reference: https://lkml.org/lkml/2013/10/8/553 Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index c551e4af4d83..d3b253bbc885 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -13,7 +13,7 @@ / { model = "OMAP3 GTA04"; - compatible = "ti,omap3-gta04", "ti,omap3"; + compatible = "ti,omap3-gta04", "ti,omap36xx", "ti,omap3"; cpus { cpu@0 { -- cgit v1.2.3-55-g7522 From 03b8c7b623c80af264c4c8d6111e5c6289933666 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sun, 2 Mar 2014 13:09:47 +0100 Subject: futex: Allow architectures to skip futex_atomic_cmpxchg_inatomic() test If an architecture has futex_atomic_cmpxchg_inatomic() implemented and there is no runtime check necessary, allow to skip the test within futex_init(). This allows to get rid of some code which would always give the same result, and also allows the compiler to optimize a couple of if statements away. Signed-off-by: Heiko Carstens Cc: Finn Thain Cc: Geert Uytterhoeven Link: http://lkml.kernel.org/r/20140302120947.GA3641@osiris Signed-off-by: Thomas Gleixner --- arch/s390/Kconfig | 1 + include/linux/futex.h | 4 ++++ init/Kconfig | 7 +++++++ kernel/futex.c | 37 ++++++++++++++++++++++++------------- 4 files changed, 36 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 65a07750f4f9..bb74b21f007a 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -117,6 +117,7 @@ config S390 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 diff --git a/include/linux/futex.h b/include/linux/futex.h index b0d95cac826e..6435f46d6e13 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -55,7 +55,11 @@ union futex_key { #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); extern void exit_pi_state_list(struct task_struct *curr); +#ifdef CONFIG_HAVE_FUTEX_CMPXCHG +#define futex_cmpxchg_enabled 1 +#else extern int futex_cmpxchg_enabled; +#endif #else static inline void exit_robust_list(struct task_struct *curr) { diff --git a/init/Kconfig b/init/Kconfig index 009a797dd242..d56cb03c1b49 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1387,6 +1387,13 @@ config FUTEX support for "fast userspace mutexes". The resulting kernel may not run glibc-based applications correctly. +config HAVE_FUTEX_CMPXCHG + bool + help + Architectures should select this if futex_atomic_cmpxchg_inatomic() + is implemented and always working. This removes a couple of runtime + checks. + config EPOLL bool "Enable eventpoll support" if EXPERT default y diff --git a/kernel/futex.c b/kernel/futex.c index 44a1261cb9ff..5d17e3a83f8c 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -157,7 +157,9 @@ * enqueue. */ +#ifndef CONFIG_HAVE_FUTEX_CMPXCHG int __read_mostly futex_cmpxchg_enabled; +#endif /* * Futex flags used to encode options to functions and preserve them across @@ -2843,9 +2845,28 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); } -static int __init futex_init(void) +static void __init futex_detect_cmpxchg(void) { +#ifndef CONFIG_HAVE_FUTEX_CMPXCHG u32 curval; + + /* + * This will fail and we want it. Some arch implementations do + * runtime detection of the futex_atomic_cmpxchg_inatomic() + * functionality. We want to know that before we call in any + * of the complex code paths. Also we want to prevent + * registration of robust lists in that case. NULL is + * guaranteed to fault and we get -EFAULT on functional + * implementation, the non-functional ones will return + * -ENOSYS. + */ + if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) + futex_cmpxchg_enabled = 1; +#endif +} + +static int __init futex_init(void) +{ unsigned int futex_shift; unsigned long i; @@ -2861,18 +2882,8 @@ static int __init futex_init(void) &futex_shift, NULL, futex_hashsize, futex_hashsize); futex_hashsize = 1UL << futex_shift; - /* - * This will fail and we want it. Some arch implementations do - * runtime detection of the futex_atomic_cmpxchg_inatomic() - * functionality. We want to know that before we call in any - * of the complex code paths. Also we want to prevent - * registration of robust lists in that case. NULL is - * guaranteed to fault and we get -EFAULT on functional - * implementation, the non-functional ones will return - * -ENOSYS. - */ - if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) - futex_cmpxchg_enabled = 1; + + futex_detect_cmpxchg(); for (i = 0; i < futex_hashsize; i++) { plist_head_init(&futex_queues[i].chain); -- cgit v1.2.3-55-g7522 From 7693decce869a94821bed1fa6c237c7224096b5b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 3 Mar 2014 09:25:52 -0500 Subject: ARM: XEN depends on having a MMU arch/arm/xen/enlighten.c (and maybe others) use MMU-specific functions like pte_mkspecial which are only available on MMU builds. So let XEN depend on MMU. Suggested-by: Arnd Bergmann Signed-off-by: Uwe Kleine-König Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24307dc85d08..8b784656156d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1883,6 +1883,7 @@ config XEN depends on ARM && AEABI && OF depends on CPU_V7 && !CPU_V6 depends on !GENERIC_ATOMIC64 + depends on MMU select ARM_PSCI select SWIOTLB_XEN select ARCH_DMA_ADDR_T_64BIT -- cgit v1.2.3-55-g7522 From bff705950e2cdcf35641dee35eb14bad9ed49e8f Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 14 Aug 2013 09:54:54 +0100 Subject: arm64: remove unnecessary cache flush at boot Currently we flush the entire dcache at boot within __cpu_setup, but this is unnecessary as the booting protocol demands that the dcache is invalid and off upon entering the kernel. The presence of the cache flush only serves to hide bugs in bootloaders, and is not safe in the presence of SMP. In an SMP boot scenario the CPUs enter coherency outside of the kernel, and the primary CPU enables its caches before bringing up secondary CPUs. Therefore if any secondary CPU has an entry in its cache (in violation of the boot protocol), the primary CPU might snoop it even if the secondary CPU's cache is disabled. The boot-time cache flush only serves to hide a firmware bug, and slows down a cpu boot unnecessarily. This patch removes the unnecessary boot-time cache flush. Signed-off-by: Mark Rutland Acked-by: Will Deacon [catalin.marinas@arm.com: make __flush_dcache_all local only] Signed-off-by: Catalin Marinas --- arch/arm64/mm/cache.S | 2 +- arch/arm64/mm/proc.S | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 97fcef535a8a..c46f48b33c14 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S @@ -30,7 +30,7 @@ * * Corrupted registers: x0-x7, x9-x11 */ -ENTRY(__flush_dcache_all) +__flush_dcache_all: dsb sy // ensure ordering with previous memory accesses mrs x0, clidr_el1 // read clidr and x3, x0, #0x7000000 // extract loc from clidr diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 1333e6f9a8e5..e0ef63cd05dc 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -173,12 +173,6 @@ ENDPROC(cpu_do_switch_mm) * value of the SCTLR_EL1 register. */ ENTRY(__cpu_setup) - /* - * Preserve the link register across the function call. - */ - mov x28, lr - bl __flush_dcache_all - mov lr, x28 ic iallu // I+BTB cache invalidate tlbi vmalle1is // invalidate I + D TLBs dsb sy -- cgit v1.2.3-55-g7522 From 0473c9b5f05948df780bbc7b996dd7aefc4ec41d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Mar 2014 10:44:03 +0100 Subject: compat: let architectures define __ARCH_WANT_COMPAT_SYS_GETDENTS64 For architecture dependent compat syscalls in common code an architecture must define something like __ARCH_WANT_ if it wants to use the code. This however is not true for compat_sys_getdents64 for which architectures must define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 if they do not want the code. This leads to the situation where all architectures, except mips, get the compat code but only x86_64, arm64 and the generic syscall architectures actually use it. So invert the logic, so that architectures actively must do something to get the compat code. This way a couple of architectures get rid of otherwise dead code. Signed-off-by: Heiko Carstens --- arch/arm64/include/asm/unistd.h | 1 + arch/mips/include/asm/unistd.h | 1 - arch/x86/include/asm/unistd.h | 1 + fs/compat.c | 4 ++-- include/linux/compat.h | 2 ++ include/uapi/asm-generic/unistd.h | 1 + 6 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 82ce217e94cf..a4654c656a1e 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #ifdef CONFIG_COMPAT +#define __ARCH_WANT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 4d3b92886665..413d6c612bec 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -24,7 +24,6 @@ #ifndef __ASSEMBLY__ -#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index c2a48139c340..f4b5795d7e34 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h @@ -23,6 +23,7 @@ # include # include # define __ARCH_WANT_COMPAT_SYS_TIME +# define __ARCH_WANT_COMPAT_SYS_GETDENTS64 # endif diff --git a/fs/compat.c b/fs/compat.c index 6af20de2c1a3..0095a6978eef 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -981,7 +981,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd, return error; } -#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64 +#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64 struct compat_getdents_callback64 { struct dir_context ctx; @@ -1066,7 +1066,7 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, fdput(f); return error; } -#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ +#endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */ /* * Exactly like fs/open.c:sys_open(), except that it doesn't set the diff --git a/include/linux/compat.h b/include/linux/compat.h index 3f448c65511b..beded18f992d 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -502,9 +502,11 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, asmlinkage long compat_sys_getdents(unsigned int fd, struct compat_linux_dirent __user *dirent, unsigned int count); +#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64 asmlinkage long compat_sys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, unsigned int count); +#endif asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *, unsigned int nr_segs, unsigned int flags); asmlinkage long compat_sys_open(const char __user *filename, int flags, diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h index dde8041f40d2..6db66783d268 100644 --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h @@ -191,6 +191,7 @@ __SYSCALL(__NR_quotactl, sys_quotactl) /* fs/readdir.c */ #define __NR_getdents64 61 +#define __ARCH_WANT_COMPAT_SYS_GETDENTS64 __SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64) /* fs/read_write.c */ -- cgit v1.2.3-55-g7522 From c6c0f58f90cb8e159702ccc08772bc9221f1c35e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Feb 2014 14:08:39 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 1 Convert s390 specific system calls to to the new COMPAT_SYSCALL_DEFINE macro. This allows us to get rid of the assembly compat wrappers. Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 12 +++++++----- arch/s390/kernel/compat_linux.h | 10 +++++----- arch/s390/kernel/compat_wrapper.S | 27 --------------------------- arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 17 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index db02052bd137..9abf84e19d69 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -86,27 +86,29 @@ #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) -asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, + u16, user, u16, group) { return sys_chown(filename, low2highuid(user), low2highgid(group)); } -asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, + filename, u16, user, u16, group) { return sys_lchown(filename, low2highuid(user), low2highgid(group)); } -asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group) { return sys_fchown(fd, low2highuid(user), low2highgid(group)); } -asmlinkage long sys32_setregid16(u16 rgid, u16 egid) +COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid) { return sys_setregid(low2highgid(rgid), low2highgid(egid)); } -asmlinkage long sys32_setgid16(u16 gid) +COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid) { return sys_setgid((gid_t)gid); } diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 1bfda3eca379..161b6c40fa12 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -76,11 +76,11 @@ struct stat64_emu31; struct mmap_arg_struct_emu31; struct fadvise64_64_args; -long sys32_chown16(const char __user * filename, u16 user, u16 group); -long sys32_lchown16(const char __user * filename, u16 user, u16 group); -long sys32_fchown16(unsigned int fd, u16 user, u16 group); -long sys32_setregid16(u16 rgid, u16 egid); -long sys32_setgid16(u16 gid); +long compat_sys_s390_chown16(const char __user *filename, u16 user, u16 group); +long compat_sys_s390_lchown16(const char __user *filename, u16 user, u16 group); +long compat_sys_s390_fchown16(unsigned int fd, u16 user, u16 group); +long compat_sys_s390_setregid16(u16 rgid, u16 egid); +long compat_sys_s390_setgid16(u16 gid); long sys32_setreuid16(u16 ruid, u16 euid); long sys32_setuid16(u16 uid); long sys32_setresuid16(u16 ruid, u16 euid, u16 suid); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 0248949a756d..cc85c7227dc2 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -61,12 +61,6 @@ ENTRY(sys32_chmod_wrapper) llgfr %r3,%r3 # mode_t jg sys_chmod # branch to system call -ENTRY(sys32_lchown16_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t - jg sys32_lchown16 # branch to system call - #sys32_getpid_wrapper # void ENTRY(sys32_mount_wrapper) @@ -149,10 +143,6 @@ ENTRY(sys32_brk_wrapper) llgtr %r2,%r2 # unsigned long jg sys_brk # branch to system call -ENTRY(sys32_setgid16_wrapper) - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - jg sys32_setgid16 # branch to system call - #sys32_getgid16_wrapper # void ENTRY(sys32_signal_wrapper) @@ -219,11 +209,6 @@ ENTRY(sys32_setreuid16_wrapper) llgfr %r3,%r3 # __kernel_old_uid_emu31_t jg sys32_setreuid16 # branch to system call -ENTRY(sys32_setregid16_wrapper) - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t - jg sys32_setregid16 # branch to system call - ENTRY(sys_sigsuspend_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -325,12 +310,6 @@ ENTRY(sys32_fchmod_wrapper) llgfr %r3,%r3 # mode_t jg sys_fchmod # branch to system call -ENTRY(sys32_fchown16_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # compat_uid_t - llgfr %r4,%r4 # compat_uid_t - jg sys32_fchown16 # branch to system call - ENTRY(sys32_getpriority_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -632,12 +611,6 @@ ENTRY(sys32_pwrite64_wrapper) llgfr %r6,%r6 # u32 jg sys32_pwrite64 # branch to system call -ENTRY(sys32_chown16_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t - jg sys32_chown16 # branch to system call - ENTRY(sys32_getcwd_wrapper) llgtr %r2,%r2 # char * llgfr %r3,%r3 # unsigned long diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 143992152ec9..a2986306fbb5 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -24,7 +24,7 @@ SYSCALL(sys_chdir,sys_chdir,sys32_chdir_wrapper) SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper) SYSCALL(sys_chmod,sys_chmod,sys32_chmod_wrapper) /* 15 */ -SYSCALL(sys_lchown16,sys_ni_syscall,sys32_lchown16_wrapper) /* old lchown16 syscall*/ +SYSCALL(sys_lchown16,sys_ni_syscall,compat_sys_s390_lchown16) /* old lchown16 syscall*/ NI_SYSCALL /* old break syscall holder */ NI_SYSCALL /* old stat syscall holder */ SYSCALL(sys_lseek,sys_lseek,compat_sys_lseek) @@ -54,7 +54,7 @@ SYSCALL(sys_pipe,sys_pipe,sys32_pipe_wrapper) SYSCALL(sys_times,sys_times,compat_sys_times_wrapper) NI_SYSCALL /* old prof syscall */ SYSCALL(sys_brk,sys_brk,sys32_brk_wrapper) /* 45 */ -SYSCALL(sys_setgid16,sys_ni_syscall,sys32_setgid16_wrapper) /* old setgid16 syscall*/ +SYSCALL(sys_setgid16,sys_ni_syscall,compat_sys_s390_setgid16) /* old setgid16 syscall*/ SYSCALL(sys_getgid16,sys_ni_syscall,sys32_getgid16) /* old getgid16 syscall*/ SYSCALL(sys_signal,sys_signal,sys32_signal_wrapper) SYSCALL(sys_geteuid16,sys_ni_syscall,sys32_geteuid16) /* old geteuid16 syscall */ @@ -79,7 +79,7 @@ SYSCALL(sys_sigaction,sys_sigaction,compat_sys_sigaction) NI_SYSCALL /* old sgetmask syscall*/ NI_SYSCALL /* old ssetmask syscall*/ SYSCALL(sys_setreuid16,sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */ -SYSCALL(sys_setregid16,sys_ni_syscall,sys32_setregid16_wrapper) /* old setregid16 syscall */ +SYSCALL(sys_setregid16,sys_ni_syscall,compat_sys_s390_setregid16) /* old setregid16 syscall */ SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper) SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper) @@ -103,7 +103,7 @@ SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper) SYSCALL(sys_truncate,sys_truncate,compat_sys_truncate) SYSCALL(sys_ftruncate,sys_ftruncate,compat_sys_ftruncate) SYSCALL(sys_fchmod,sys_fchmod,sys32_fchmod_wrapper) -SYSCALL(sys_fchown16,sys_ni_syscall,sys32_fchown16_wrapper) /* 95 old fchown16 syscall*/ +SYSCALL(sys_fchown16,sys_ni_syscall,compat_sys_s390_fchown16) /* 95 old fchown16 syscall*/ SYSCALL(sys_getpriority,sys_getpriority,sys32_getpriority_wrapper) SYSCALL(sys_setpriority,sys_setpriority,sys32_setpriority_wrapper) NI_SYSCALL /* old profil syscall */ @@ -190,7 +190,7 @@ SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,compat_sys_rt_sigqueueinfo) SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend) SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper) /* 180 */ SYSCALL(sys_pwrite64,sys_pwrite64,sys32_pwrite64_wrapper) -SYSCALL(sys_chown16,sys_ni_syscall,sys32_chown16_wrapper) /* old chown16 syscall */ +SYSCALL(sys_chown16,sys_ni_syscall,compat_sys_s390_chown16) /* old chown16 syscall */ SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */ -- cgit v1.2.3-55-g7522 From 208096eee2fa44de0464e1f3c1f0c1ca1afe67ad Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Feb 2014 15:52:24 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 2 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 15 ++++++++------- arch/s390/kernel/compat_linux.h | 10 +++++----- arch/s390/kernel/compat_wrapper.S | 27 --------------------------- arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 18 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 9abf84e19d69..b47a8f1a2662 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -113,23 +113,24 @@ COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid) return sys_setgid((gid_t)gid); } -asmlinkage long sys32_setreuid16(u16 ruid, u16 euid) +COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid) { return sys_setreuid(low2highuid(ruid), low2highuid(euid)); } -asmlinkage long sys32_setuid16(u16 uid) +COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid) { return sys_setuid((uid_t)uid); } -asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) +COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid) { return sys_setresuid(low2highuid(ruid), low2highuid(euid), - low2highuid(suid)); + low2highuid(suid)); } -asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __user *suidp) +COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp, + u16 __user *, euidp, u16 __user *, suidp) { const struct cred *cred = current_cred(); int retval; @@ -146,10 +147,10 @@ asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __us return retval; } -asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) +COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid) { return sys_setresgid(low2highgid(rgid), low2highgid(egid), - low2highgid(sgid)); + low2highgid(sgid)); } asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __user *sgidp) diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 161b6c40fa12..2b8dfe66b9b9 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -81,11 +81,11 @@ long compat_sys_s390_lchown16(const char __user *filename, u16 user, u16 group); long compat_sys_s390_fchown16(unsigned int fd, u16 user, u16 group); long compat_sys_s390_setregid16(u16 rgid, u16 egid); long compat_sys_s390_setgid16(u16 gid); -long sys32_setreuid16(u16 ruid, u16 euid); -long sys32_setuid16(u16 uid); -long sys32_setresuid16(u16 ruid, u16 euid, u16 suid); -long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid); -long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid); +long compat_sys_s390_setreuid16(u16 ruid, u16 euid); +long compat_sys_s390_setuid16(u16 uid); +long compat_sys_s390_setresuid16(u16 ruid, u16 euid, u16 suid); +long compat_sys_s390_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid); +long compat_sys_s390_setresgid16(u16 rgid, u16 egid, u16 sgid); long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid); long sys32_setfsuid16(u16 uid); long sys32_setfsgid16(u16 gid); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index cc85c7227dc2..a073e7f9acfa 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -75,10 +75,6 @@ ENTRY(sys32_oldumount_wrapper) llgtr %r2,%r2 # char * jg sys_oldumount # branch to system call -ENTRY(sys32_setuid16_wrapper) - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - jg sys32_setuid16 # branch to system call - #sys32_getuid16_wrapper # void ENTRY(sys32_ptrace_wrapper) @@ -204,11 +200,6 @@ ENTRY(sys32_dup2_wrapper) #sys32_setsid_wrapper # void -ENTRY(sys32_setreuid16_wrapper) - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - jg sys32_setreuid16 # branch to system call - ENTRY(sys_sigsuspend_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -555,30 +546,12 @@ ENTRY(sys32_mremap_wrapper) llgfr %r6,%r6 # unsigned long jg sys_mremap # branch to system call -ENTRY(sys32_setresuid16_wrapper) - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t - jg sys32_setresuid16 # branch to system call - -ENTRY(sys32_getresuid16_wrapper) - llgtr %r2,%r2 # __kernel_old_uid_emu31_t * - llgtr %r3,%r3 # __kernel_old_uid_emu31_t * - llgtr %r4,%r4 # __kernel_old_uid_emu31_t * - jg sys32_getresuid16 # branch to system call - ENTRY(sys32_poll_wrapper) llgtr %r2,%r2 # struct pollfd * llgfr %r3,%r3 # unsigned int lgfr %r4,%r4 # int jg sys_poll # branch to system call -ENTRY(sys32_setresgid16_wrapper) - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t - jg sys32_setresgid16 # branch to system call - ENTRY(sys32_getresgid16_wrapper) llgtr %r2,%r2 # __kernel_old_gid_emu31_t * llgtr %r3,%r3 # __kernel_old_gid_emu31_t * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index a2986306fbb5..8c7c4a6f6722 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -31,7 +31,7 @@ SYSCALL(sys_lseek,sys_lseek,compat_sys_lseek) SYSCALL(sys_getpid,sys_getpid,sys_getpid) /* 20 */ SYSCALL(sys_mount,sys_mount,sys32_mount_wrapper) SYSCALL(sys_oldumount,sys_oldumount,sys32_oldumount_wrapper) -SYSCALL(sys_setuid16,sys_ni_syscall,sys32_setuid16_wrapper) /* old setuid16 syscall*/ +SYSCALL(sys_setuid16,sys_ni_syscall,compat_sys_s390_setuid16) /* old setuid16 syscall*/ SYSCALL(sys_getuid16,sys_ni_syscall,sys32_getuid16) /* old getuid16 syscall*/ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) @@ -78,7 +78,7 @@ SYSCALL(sys_setsid,sys_setsid,sys_setsid) SYSCALL(sys_sigaction,sys_sigaction,compat_sys_sigaction) NI_SYSCALL /* old sgetmask syscall*/ NI_SYSCALL /* old ssetmask syscall*/ -SYSCALL(sys_setreuid16,sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */ +SYSCALL(sys_setreuid16,sys_ni_syscall,compat_sys_s390_setreuid16) /* old setreuid16 syscall */ SYSCALL(sys_setregid16,sys_ni_syscall,compat_sys_s390_setregid16) /* old setregid16 syscall */ SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper) SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) @@ -172,13 +172,13 @@ SYSCALL(sys_sched_get_priority_min,sys_sched_get_priority_min,sys32_sched_get_pr SYSCALL(sys_sched_rr_get_interval,sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval) SYSCALL(sys_nanosleep,sys_nanosleep,compat_sys_nanosleep_wrapper) SYSCALL(sys_mremap,sys_mremap,sys32_mremap_wrapper) -SYSCALL(sys_setresuid16,sys_ni_syscall,sys32_setresuid16_wrapper) /* old setresuid16 syscall */ -SYSCALL(sys_getresuid16,sys_ni_syscall,sys32_getresuid16_wrapper) /* 165 old getresuid16 syscall */ +SYSCALL(sys_setresuid16,sys_ni_syscall,compat_sys_s390_setresuid16) /* old setresuid16 syscall */ +SYSCALL(sys_getresuid16,sys_ni_syscall,compat_sys_s390_getresuid16) /* 165 old getresuid16 syscall */ NI_SYSCALL /* for vm86 */ NI_SYSCALL /* old sys_query_module */ SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) NI_SYSCALL /* old nfsservctl */ -SYSCALL(sys_setresgid16,sys_ni_syscall,sys32_setresgid16_wrapper) /* 170 old setresgid16 syscall */ +SYSCALL(sys_setresgid16,sys_ni_syscall,compat_sys_s390_setresgid16) /* 170 old setresgid16 syscall */ SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,sys32_rt_sigreturn) -- cgit v1.2.3-55-g7522 From 4ca2ea58c8421784bdad43b05e9939549e4d34e9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 25 Feb 2014 16:17:41 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 3 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 11 ++++++----- arch/s390/kernel/compat_linux.h | 10 +++++----- arch/s390/kernel/compat_wrapper.S | 24 ------------------------ arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 16 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index b47a8f1a2662..65b5acbd375b 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -153,7 +153,8 @@ COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid) low2highgid(sgid)); } -asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __user *sgidp) +COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp, + u16 __user *, egidp, u16 __user *, sgidp) { const struct cred *cred = current_cred(); int retval; @@ -170,12 +171,12 @@ asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __us return retval; } -asmlinkage long sys32_setfsuid16(u16 uid) +COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid) { return sys_setfsuid((uid_t)uid); } -asmlinkage long sys32_setfsgid16(u16 gid) +COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid) { return sys_setfsgid((gid_t)gid); } @@ -218,7 +219,7 @@ static int groups16_from_user(struct group_info *group_info, u16 __user *groupli return 0; } -asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) +COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist) { const struct cred *cred = current_cred(); int i; @@ -243,7 +244,7 @@ out: return i; } -asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) +COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist) { struct group_info *group_info; int retval; diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 2b8dfe66b9b9..766867230d26 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -86,11 +86,11 @@ long compat_sys_s390_setuid16(u16 uid); long compat_sys_s390_setresuid16(u16 ruid, u16 euid, u16 suid); long compat_sys_s390_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid); long compat_sys_s390_setresgid16(u16 rgid, u16 egid, u16 sgid); -long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid); -long sys32_setfsuid16(u16 uid); -long sys32_setfsgid16(u16 gid); -long sys32_getgroups16(int gidsetsize, u16 __user *grouplist); -long sys32_setgroups16(int gidsetsize, u16 __user *grouplist); +long compat_sys_s390_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid); +long compat_sys_s390_setfsuid16(u16 uid); +long compat_sys_s390_setfsgid16(u16 gid); +long compat_sys_s390_getgroups16(int gidsetsize, u16 __user *grouplist); +long compat_sys_s390_setgroups16(int gidsetsize, u16 __user *grouplist); long sys32_getuid16(void); long sys32_geteuid16(void); long sys32_getgid16(void); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index a073e7f9acfa..6c55523acf29 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -244,16 +244,6 @@ ENTRY(compat_sys_settimeofday_wrapper) llgtr %r3,%r3 # struct timezone * jg compat_sys_settimeofday # branch to system call -ENTRY(sys32_getgroups16_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # __kernel_old_gid_emu31_t * - jg sys32_getgroups16 # branch to system call - -ENTRY(sys32_setgroups16_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # __kernel_old_gid_emu31_t * - jg sys32_setgroups16 # branch to system call - ENTRY(sys32_symlink_wrapper) llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * @@ -426,14 +416,6 @@ ENTRY(sys32_personality_wrapper) llgfr %r2,%r2 # unsigned int jg sys_s390_personality # branch to system call -ENTRY(sys32_setfsuid16_wrapper) - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - jg sys32_setfsuid16 # branch to system call - -ENTRY(sys32_setfsgid16_wrapper) - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - jg sys32_setfsgid16 # branch to system call - ENTRY(sys32_llseek_wrapper) llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long @@ -552,12 +534,6 @@ ENTRY(sys32_poll_wrapper) lgfr %r4,%r4 # int jg sys_poll # branch to system call -ENTRY(sys32_getresgid16_wrapper) - llgtr %r2,%r2 # __kernel_old_gid_emu31_t * - llgtr %r3,%r3 # __kernel_old_gid_emu31_t * - llgtr %r4,%r4 # __kernel_old_gid_emu31_t * - jg sys32_getresgid16 # branch to system call - ENTRY(sys32_prctl_wrapper) lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned long diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 8c7c4a6f6722..bdba42a35ec6 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -88,8 +88,8 @@ SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper) SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage) SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper) SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper) -SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper) /* 80 old getgroups16 syscall */ -SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */ +SYSCALL(sys_getgroups16,sys_ni_syscall,compat_sys_s390_getgroups16) /* 80 old getgroups16 syscall */ +SYSCALL(sys_setgroups16,sys_ni_syscall,compat_sys_s390_setgroups16) /* old setgroups16 syscall */ NI_SYSCALL /* old select syscall */ SYSCALL(sys_symlink,sys_symlink,sys32_symlink_wrapper) NI_SYSCALL /* old lstat syscall */ @@ -146,8 +146,8 @@ SYSCALL(sys_bdflush,sys_bdflush,sys32_bdflush_wrapper) SYSCALL(sys_sysfs,sys_sysfs,sys32_sysfs_wrapper) /* 135 */ SYSCALL(sys_personality,sys_s390_personality,sys32_personality_wrapper) NI_SYSCALL /* for afs_syscall */ -SYSCALL(sys_setfsuid16,sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */ -SYSCALL(sys_setfsgid16,sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */ +SYSCALL(sys_setfsuid16,sys_ni_syscall,compat_sys_s390_setfsuid16) /* old setfsuid16 syscall */ +SYSCALL(sys_setfsgid16,sys_ni_syscall,compat_sys_s390_setfsgid16) /* old setfsgid16 syscall */ SYSCALL(sys_llseek,sys_llseek,sys32_llseek_wrapper) /* 140 */ SYSCALL(sys_getdents,sys_getdents,sys32_getdents_wrapper) SYSCALL(sys_select,sys_select,compat_sys_select_wrapper) @@ -179,7 +179,7 @@ NI_SYSCALL /* old sys_query_module */ SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) NI_SYSCALL /* old nfsservctl */ SYSCALL(sys_setresgid16,sys_ni_syscall,compat_sys_s390_setresgid16) /* 170 old setresgid16 syscall */ -SYSCALL(sys_getresgid16,sys_ni_syscall,sys32_getresgid16_wrapper) /* old getresgid16 syscall */ +SYSCALL(sys_getresgid16,sys_ni_syscall,compat_sys_s390_getresgid16) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,sys32_rt_sigreturn) SYSCALL(sys_rt_sigaction,sys_rt_sigaction,compat_sys_rt_sigaction) -- cgit v1.2.3-55-g7522 From e723e0cc17f8d8573b19a809277d81cecdd6e92b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Feb 2014 10:58:09 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 4 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 15 ++++++--------- arch/s390/kernel/compat_linux.h | 11 +++++------ arch/s390/kernel/compat_wrapper.S | 14 -------------- arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 16 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 65b5acbd375b..79571343bc75 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -269,22 +269,22 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplis return retval; } -asmlinkage long sys32_getuid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getuid16) { return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); } -asmlinkage long sys32_geteuid16(void) +COMPAT_SYSCALL_DEFINE0(s390_geteuid16) { return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); } -asmlinkage long sys32_getgid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getgid16) { return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); } -asmlinkage long sys32_getegid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getegid16) { return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); } @@ -299,12 +299,9 @@ COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, } #endif -asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) +COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low) { - if ((int)high < 0) - return -EINVAL; - else - return sys_truncate(path, (high << 32) | low); + return sys_truncate(path, (unsigned long)high << 32 | low); } asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 766867230d26..3e03325d0e95 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -91,12 +91,11 @@ long compat_sys_s390_setfsuid16(u16 uid); long compat_sys_s390_setfsgid16(u16 gid); long compat_sys_s390_getgroups16(int gidsetsize, u16 __user *grouplist); long compat_sys_s390_setgroups16(int gidsetsize, u16 __user *grouplist); -long sys32_getuid16(void); -long sys32_geteuid16(void); -long sys32_getgid16(void); -long sys32_getegid16(void); -long sys32_truncate64(const char __user * path, unsigned long high, - unsigned long low); +long compat_sys_s390_getuid16(void); +long compat_sys_s390_geteuid16(void); +long compat_sys_s390_getgid16(void); +long compat_sys_s390_getegid16(void); +long compat_sys_s390_truncate64(const char __user *path, u32 high, u32 low); long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low); long sys32_init_module(void __user *umod, unsigned long len, const char __user *uargs); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 6c55523acf29..9128f7b87e80 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -75,8 +75,6 @@ ENTRY(sys32_oldumount_wrapper) llgtr %r2,%r2 # char * jg sys_oldumount # branch to system call -#sys32_getuid16_wrapper # void - ENTRY(sys32_ptrace_wrapper) lgfr %r2,%r2 # long lgfr %r3,%r3 # long @@ -139,17 +137,11 @@ ENTRY(sys32_brk_wrapper) llgtr %r2,%r2 # unsigned long jg sys_brk # branch to system call -#sys32_getgid16_wrapper # void - ENTRY(sys32_signal_wrapper) lgfr %r2,%r2 # int llgtr %r3,%r3 # __sighandler_t jg sys_signal -#sys32_geteuid16_wrapper # void - -#sys32_getegid16_wrapper # void - ENTRY(sys32_acct_wrapper) llgtr %r2,%r2 # char * jg sys_acct # branch to system call @@ -577,12 +569,6 @@ ENTRY(sys32_capset_wrapper) #sys32_vfork_wrapper # done in vfork_glue -ENTRY(sys32_truncate64_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - jg sys32_truncate64 # branch to system call - ENTRY(sys32_ftruncate64_wrapper) llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index bdba42a35ec6..fa17cefe40e2 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -32,7 +32,7 @@ SYSCALL(sys_getpid,sys_getpid,sys_getpid) /* 20 */ SYSCALL(sys_mount,sys_mount,sys32_mount_wrapper) SYSCALL(sys_oldumount,sys_oldumount,sys32_oldumount_wrapper) SYSCALL(sys_setuid16,sys_ni_syscall,compat_sys_s390_setuid16) /* old setuid16 syscall*/ -SYSCALL(sys_getuid16,sys_ni_syscall,sys32_getuid16) /* old getuid16 syscall*/ +SYSCALL(sys_getuid16,sys_ni_syscall,compat_sys_s390_getuid16) /* old getuid16 syscall*/ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper) @@ -55,10 +55,10 @@ SYSCALL(sys_times,sys_times,compat_sys_times_wrapper) NI_SYSCALL /* old prof syscall */ SYSCALL(sys_brk,sys_brk,sys32_brk_wrapper) /* 45 */ SYSCALL(sys_setgid16,sys_ni_syscall,compat_sys_s390_setgid16) /* old setgid16 syscall*/ -SYSCALL(sys_getgid16,sys_ni_syscall,sys32_getgid16) /* old getgid16 syscall*/ +SYSCALL(sys_getgid16,sys_ni_syscall,compat_sys_s390_getgid16) /* old getgid16 syscall*/ SYSCALL(sys_signal,sys_signal,sys32_signal_wrapper) -SYSCALL(sys_geteuid16,sys_ni_syscall,sys32_geteuid16) /* old geteuid16 syscall */ -SYSCALL(sys_getegid16,sys_ni_syscall,sys32_getegid16) /* 50 old getegid16 syscall */ +SYSCALL(sys_geteuid16,sys_ni_syscall,compat_sys_s390_geteuid16) /* old geteuid16 syscall */ +SYSCALL(sys_getegid16,sys_ni_syscall,compat_sys_s390_getegid16) /* 50 old getegid16 syscall */ SYSCALL(sys_acct,sys_acct,sys32_acct_wrapper) SYSCALL(sys_umount,sys_umount,sys32_umount_wrapper) NI_SYSCALL /* old lock syscall */ @@ -201,7 +201,7 @@ NI_SYSCALL /* streams2 */ SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit_wrapper) SYSCALL(sys_mmap2,sys_mmap2,sys32_mmap2_wrapper) -SYSCALL(sys_truncate64,sys_ni_syscall,sys32_truncate64_wrapper) +SYSCALL(sys_truncate64,sys_ni_syscall,compat_sys_s390_truncate64) SYSCALL(sys_ftruncate64,sys_ni_syscall,sys32_ftruncate64_wrapper) SYSCALL(sys_stat64,sys_ni_syscall,sys32_stat64_wrapper) /* 195 */ SYSCALL(sys_lstat64,sys_ni_syscall,sys32_lstat64_wrapper) -- cgit v1.2.3-55-g7522 From 52a0b536a3addcfe20325303b2dddc2538019476 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Feb 2014 12:51:40 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 5 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 25 +++++++++++-------------- arch/s390/kernel/compat_linux.h | 12 +++++------- arch/s390/kernel/compat_wrapper.S | 34 ---------------------------------- arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 21 insertions(+), 60 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 79571343bc75..08b20c2539da 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -304,33 +304,30 @@ COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u3 return sys_truncate(path, (unsigned long)high << 32 | low); } -asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) +COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low) { - if ((int)high < 0) - return -EINVAL; - else - return sys_ftruncate(fd, (high << 32) | low); + return sys_ftruncate(fd, (unsigned long)high << 32 | low); } -asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, - size_t count, u32 poshi, u32 poslo) +COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf, + compat_size_t, count, u32, high, u32, low) { if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); + return sys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low); } -asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf, - size_t count, u32 poshi, u32 poslo) +COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf, + compat_size_t, count, u32, high, u32, low) { if ((compat_ssize_t) count < 0) return -EINVAL; - return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); + return sys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low); } -asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count) +COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count) { - return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); + return sys_readahead(fd, (unsigned long)high << 32 | low, count); } struct stat64_emu31 { @@ -382,7 +379,7 @@ static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat) return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf) { struct kstat stat; int ret = vfs_stat(filename, &stat); diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 3e03325d0e95..df5f715ed6be 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -96,16 +96,14 @@ long compat_sys_s390_geteuid16(void); long compat_sys_s390_getgid16(void); long compat_sys_s390_getegid16(void); long compat_sys_s390_truncate64(const char __user *path, u32 high, u32 low); -long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low); +long compat_sys_s390_ftruncate64(unsigned int fd, u32 high, u32 low); long sys32_init_module(void __user *umod, unsigned long len, const char __user *uargs); long sys32_delete_module(const char __user *name_user, unsigned int flags); -long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, - u32 poshi, u32 poslo); -long sys32_pwrite64(unsigned int fd, const char __user *ubuf, - size_t count, u32 poshi, u32 poslo); -compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count); -long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf); +long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 high, u32 low); +long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low); +long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count); +long compat_sys_s390_stat64(const char __user *filename, struct stat64_emu31 __user *statbuf); long sys32_lstat64(const char __user * filename, struct stat64_emu31 __user * statbuf); long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 9128f7b87e80..399255de7d48 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -536,22 +536,6 @@ ENTRY(sys32_prctl_wrapper) #sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue -ENTRY(sys32_pread64_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - llgfr %r5,%r5 # u32 - llgfr %r6,%r6 # u32 - jg sys32_pread64 # branch to system call - -ENTRY(sys32_pwrite64_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # size_t - llgfr %r5,%r5 # u32 - llgfr %r6,%r6 # u32 - jg sys32_pwrite64 # branch to system call - ENTRY(sys32_getcwd_wrapper) llgtr %r2,%r2 # char * llgfr %r3,%r3 # unsigned long @@ -569,12 +553,6 @@ ENTRY(sys32_capset_wrapper) #sys32_vfork_wrapper # done in vfork_glue -ENTRY(sys32_ftruncate64_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - jg sys32_ftruncate64 # branch to system call - ENTRY(sys32_lchown_wrapper) llgtr %r2,%r2 # const char * llgfr %r3,%r3 # uid_t @@ -687,11 +665,6 @@ ENTRY(compat_sys_fcntl64_wrapper) llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl64 # branch to system call -ENTRY(sys32_stat64_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct stat64 * - jg sys32_stat64 # branch to system call - ENTRY(sys32_lstat64_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat64 * @@ -1201,13 +1174,6 @@ ENTRY(sys_epoll_create1_wrapper) lgfr %r2,%r2 # int jg sys_epoll_create1 # branch to system call -ENTRY(sys32_readahead_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # u32 - llgfr %r4,%r4 # u32 - lgfr %r5,%r5 # s32 - jg sys32_readahead # branch to system call - ENTRY(sys_tkill_wrapper) lgfr %r2,%r2 # pid_t lgfr %r3,%r3 # int diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index fa17cefe40e2..8b07ce3ffdf7 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -188,8 +188,8 @@ SYSCALL(sys_rt_sigpending,sys_rt_sigpending,compat_sys_rt_sigpending) SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_sys_rt_sigtimedwait) SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,compat_sys_rt_sigqueueinfo) SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend) -SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper) /* 180 */ -SYSCALL(sys_pwrite64,sys_pwrite64,sys32_pwrite64_wrapper) +SYSCALL(sys_pread64,sys_pread64,compat_sys_s390_pread64) /* 180 */ +SYSCALL(sys_pwrite64,sys_pwrite64,compat_sys_s390_pwrite64) SYSCALL(sys_chown16,sys_ni_syscall,compat_sys_s390_chown16) /* old chown16 syscall */ SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) @@ -202,8 +202,8 @@ SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit_wrapper) SYSCALL(sys_mmap2,sys_mmap2,sys32_mmap2_wrapper) SYSCALL(sys_truncate64,sys_ni_syscall,compat_sys_s390_truncate64) -SYSCALL(sys_ftruncate64,sys_ni_syscall,sys32_ftruncate64_wrapper) -SYSCALL(sys_stat64,sys_ni_syscall,sys32_stat64_wrapper) /* 195 */ +SYSCALL(sys_ftruncate64,sys_ni_syscall,compat_sys_s390_ftruncate64) +SYSCALL(sys_stat64,sys_ni_syscall,compat_sys_s390_stat64) /* 195 */ SYSCALL(sys_lstat64,sys_ni_syscall,sys32_lstat64_wrapper) SYSCALL(sys_fstat64,sys_ni_syscall,sys32_fstat64_wrapper) SYSCALL(sys_lchown,sys_lchown,sys32_lchown_wrapper) @@ -230,7 +230,7 @@ SYSCALL(sys_mincore,sys_mincore,sys32_mincore_wrapper) SYSCALL(sys_madvise,sys_madvise,sys32_madvise_wrapper) SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */ SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) -SYSCALL(sys_readahead,sys_readahead,sys32_readahead_wrapper) +SYSCALL(sys_readahead,sys_readahead,compat_sys_s390_readahead) SYSCALL(sys_sendfile64,sys_ni_syscall,compat_sys_sendfile64) SYSCALL(sys_setxattr,sys_setxattr,sys32_setxattr_wrapper) SYSCALL(sys_lsetxattr,sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */ -- cgit v1.2.3-55-g7522 From a0f8c6da8f3da63283e978ebece03e81d107b1d0 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Feb 2014 14:05:34 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 6 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 12 ++++++------ arch/s390/kernel/compat_linux.h | 12 +++++------- arch/s390/kernel/compat_wrapper.S | 25 ------------------------- arch/s390/kernel/syscalls.S | 10 +++++----- 4 files changed, 16 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 08b20c2539da..861427fc0329 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -388,7 +388,7 @@ COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64 return ret; } -asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_lstat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf) { struct kstat stat; int ret = vfs_lstat(filename, &stat); @@ -397,7 +397,7 @@ asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31 return ret; } -asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_fstat64, unsigned int, fd, struct stat64_emu31 __user *, statbuf) { struct kstat stat; int ret = vfs_fstat(fd, &stat); @@ -406,8 +406,8 @@ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * sta return ret; } -asmlinkage long sys32_fstatat64(unsigned int dfd, const char __user *filename, - struct stat64_emu31 __user* statbuf, int flag) +COMPAT_SYSCALL_DEFINE4(s390_fstatat64, unsigned int, dfd, const char __user *, filename, + struct stat64_emu31 __user *, statbuf, int, flag) { struct kstat stat; int error; @@ -433,7 +433,7 @@ struct mmap_arg_struct_emu31 { compat_ulong_t offset; }; -asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) +COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg) { struct mmap_arg_struct_emu31 a; @@ -445,7 +445,7 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) a.offset >> PAGE_SHIFT); } -asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) +COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg) { struct mmap_arg_struct_emu31 a; diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index df5f715ed6be..7e7afb91252c 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -104,13 +104,11 @@ long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t c long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low); long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count); long compat_sys_s390_stat64(const char __user *filename, struct stat64_emu31 __user *statbuf); -long sys32_lstat64(const char __user * filename, - struct stat64_emu31 __user * statbuf); -long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf); -long sys32_fstatat64(unsigned int dfd, const char __user *filename, - struct stat64_emu31 __user* statbuf, int flag); -unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg); -long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg); +long compat_sys_s390_lstat64(const char __user *filename, struct stat64_emu31 __user *statbuf); +long compat_sys_s390_fstat64(unsigned int fd, struct stat64_emu31 __user *statbuf); +long compat_sys_s390_fstatat64(unsigned int dfd, const char __user *filename, struct stat64_emu31 __user *statbuf, int flag); +long compat_sys_s390_old_mmap(struct mmap_arg_struct_emu31 __user *arg); +long compat_sys_s390_mmap2(struct mmap_arg_struct_emu31 __user *arg); long sys32_read(unsigned int fd, char __user * buf, size_t count); long sys32_write(unsigned int fd, const char __user * buf, size_t count); long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 399255de7d48..c8ac063398bb 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -222,10 +222,6 @@ ENTRY(compat_sys_getrlimit_wrapper) llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_getrlimit # branch to system call -ENTRY(sys32_mmap2_wrapper) - llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * - jg sys32_mmap2 # branch to system call - ENTRY(compat_sys_gettimeofday_wrapper) llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * @@ -269,10 +265,6 @@ ENTRY(old32_readdir_wrapper) llgfr %r4,%r4 # unsigned int jg compat_sys_old_readdir # branch to system call -ENTRY(old32_mmap_wrapper) - llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * - jg old32_mmap # branch to system call - ENTRY(sys32_munmap_wrapper) llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t @@ -665,20 +657,10 @@ ENTRY(compat_sys_fcntl64_wrapper) llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl64 # branch to system call -ENTRY(sys32_lstat64_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct stat64 * - jg sys32_lstat64 # branch to system call - ENTRY(sys32_stime_wrapper) llgtr %r2,%r2 # long * jg compat_sys_stime # branch to system call -ENTRY(sys32_fstat64_wrapper) - llgfr %r2,%r2 # unsigned long - llgtr %r3,%r3 # struct stat64 * - jg sys32_fstat64 # branch to system call - ENTRY(sys32_setxattr_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # char * @@ -1013,13 +995,6 @@ ENTRY(compat_sys_futimesat_wrapper) llgtr %r4,%r4 # struct timeval * jg compat_sys_futimesat -ENTRY(sys32_fstatat64_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # struct stat64 * - lgfr %r5,%r5 # int - jg sys32_fstatat64 - ENTRY(sys_unlinkat_wrapper) lgfr %r2,%r2 # int llgtr %r3,%r3 # const char * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 8b07ce3ffdf7..9d4e6b576173 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -98,7 +98,7 @@ SYSCALL(sys_uselib,sys_uselib,sys32_uselib_wrapper) SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper) SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper) SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ -SYSCALL(sys_old_mmap,sys_old_mmap,old32_mmap_wrapper) /* 90 */ +SYSCALL(sys_old_mmap,sys_old_mmap,compat_sys_s390_old_mmap) /* 90 */ SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper) SYSCALL(sys_truncate,sys_truncate,compat_sys_truncate) SYSCALL(sys_ftruncate,sys_ftruncate,compat_sys_ftruncate) @@ -200,12 +200,12 @@ NI_SYSCALL /* streams1 */ NI_SYSCALL /* streams2 */ SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit_wrapper) -SYSCALL(sys_mmap2,sys_mmap2,sys32_mmap2_wrapper) +SYSCALL(sys_mmap2,sys_mmap2,compat_sys_s390_mmap2) SYSCALL(sys_truncate64,sys_ni_syscall,compat_sys_s390_truncate64) SYSCALL(sys_ftruncate64,sys_ni_syscall,compat_sys_s390_ftruncate64) SYSCALL(sys_stat64,sys_ni_syscall,compat_sys_s390_stat64) /* 195 */ -SYSCALL(sys_lstat64,sys_ni_syscall,sys32_lstat64_wrapper) -SYSCALL(sys_fstat64,sys_ni_syscall,sys32_fstat64_wrapper) +SYSCALL(sys_lstat64,sys_ni_syscall,compat_sys_s390_lstat64) +SYSCALL(sys_fstat64,sys_ni_syscall,compat_sys_s390_fstat64) SYSCALL(sys_lchown,sys_lchown,sys32_lchown_wrapper) SYSCALL(sys_getuid,sys_getuid,sys_getuid) SYSCALL(sys_getgid,sys_getgid,sys_getgid) /* 200 */ @@ -301,7 +301,7 @@ SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper) SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper) /* 290 */ SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper) SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) -SYSCALL(sys_fstatat64,sys_newfstatat,sys32_fstatat64_wrapper) +SYSCALL(sys_fstatat64,sys_newfstatat,compat_sys_s390_fstatat64) SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper) SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper) /* 295 */ SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper) -- cgit v1.2.3-55-g7522 From 5383d2c8b3ee61a762043818d7c07bbc0049b031 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 26 Feb 2014 14:40:43 +0100 Subject: s390/compat: convert to COMPAT_SYSCALL_DEFINEx part 7 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 12 +++++------- arch/s390/kernel/compat_linux.h | 11 ++++------- arch/s390/kernel/compat_wrapper.S | 24 ------------------------ arch/s390/kernel/syscalls.S | 8 ++++---- 4 files changed, 13 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 861427fc0329..59097741f509 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -454,7 +454,7 @@ COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg) return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); } -asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) +COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count) { if ((compat_ssize_t) count < 0) return -EINVAL; @@ -462,7 +462,7 @@ asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) return sys_read(fd, buf, count); } -asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t count) +COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count) { if ((compat_ssize_t) count < 0) return -EINVAL; @@ -476,14 +476,13 @@ asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t cou * because the 31 bit values differ from the 64 bit values. */ -asmlinkage long -sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size_t, len, int, advise) { if (advise == 4) advise = POSIX_FADV_DONTNEED; else if (advise == 5) advise = POSIX_FADV_NOREUSE; - return sys_fadvise64(fd, offset, len, advise); + return sys_fadvise64(fd, (unsigned long)high << 32 | low, len, advise); } struct fadvise64_64_args { @@ -493,8 +492,7 @@ struct fadvise64_64_args { int advice; }; -asmlinkage long -sys32_fadvise64_64(struct fadvise64_64_args __user *args) +COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args) { struct fadvise64_64_args a; diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 7e7afb91252c..7d2ce4bb84a6 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -97,9 +97,6 @@ long compat_sys_s390_getgid16(void); long compat_sys_s390_getegid16(void); long compat_sys_s390_truncate64(const char __user *path, u32 high, u32 low); long compat_sys_s390_ftruncate64(unsigned int fd, u32 high, u32 low); -long sys32_init_module(void __user *umod, unsigned long len, - const char __user *uargs); -long sys32_delete_module(const char __user *name_user, unsigned int flags); long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 high, u32 low); long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low); long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count); @@ -109,8 +106,8 @@ long compat_sys_s390_fstat64(unsigned int fd, struct stat64_emu31 __user *statbu long compat_sys_s390_fstatat64(unsigned int dfd, const char __user *filename, struct stat64_emu31 __user *statbuf, int flag); long compat_sys_s390_old_mmap(struct mmap_arg_struct_emu31 __user *arg); long compat_sys_s390_mmap2(struct mmap_arg_struct_emu31 __user *arg); -long sys32_read(unsigned int fd, char __user * buf, size_t count); -long sys32_write(unsigned int fd, const char __user * buf, size_t count); -long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise); -long sys32_fadvise64_64(struct fadvise64_64_args __user *args); +long compat_sys_s390_read(unsigned int fd, char __user * buf, compat_size_t count); +long compat_sys_s390_write(unsigned int fd, const char __user * buf, compat_size_t count); +long compat_sys_s390_fadvise64(int fd, u32 high, u32 low, compat_size_t len, int advise); +long compat_sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); #endif /* _ASM_S390X_S390_H */ diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index c8ac063398bb..16ce71880cbd 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -12,18 +12,6 @@ ENTRY(sys32_exit_wrapper) lgfr %r2,%r2 # int jg sys_exit # branch to sys_exit -ENTRY(sys32_read_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - jg sys32_read # branch to sys_read - -ENTRY(sys32_write_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # size_t - jg sys32_write # branch to system call - ENTRY(sys32_close_wrapper) llgfr %r2,%r2 # unsigned int jg sys_close # branch to system call @@ -777,18 +765,6 @@ ENTRY(sys_epoll_wait_wrapper) lgfr %r5,%r5 # int jg sys_epoll_wait # branch to system call -ENTRY(sys32_fadvise64_wrapper) - lgfr %r2,%r2 # int - sllg %r3,%r3,32 # get high word of 64bit loff_t - or %r3,%r4 # get low word of 64bit loff_t - llgfr %r4,%r5 # size_t (unsigned long) - lgfr %r5,%r6 # int - jg sys32_fadvise64 - -ENTRY(sys32_fadvise64_64_wrapper) - llgtr %r2,%r2 # struct fadvise64_64_args * - jg sys32_fadvise64_64 - ENTRY(sys32_clock_settime_wrapper) lgfr %r2,%r2 # clockid_t (int) llgtr %r3,%r3 # struct compat_timespec * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 9d4e6b576173..5a83f6a52c0e 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -11,8 +11,8 @@ NI_SYSCALL /* 0 */ SYSCALL(sys_exit,sys_exit,sys32_exit_wrapper) SYSCALL(sys_fork,sys_fork,sys_fork) -SYSCALL(sys_read,sys_read,sys32_read_wrapper) -SYSCALL(sys_write,sys_write,sys32_write_wrapper) +SYSCALL(sys_read,sys_read,compat_sys_s390_read) +SYSCALL(sys_write,sys_write,compat_sys_s390_write) SYSCALL(sys_open,sys_open,compat_sys_open) /* 5 */ SYSCALL(sys_close,sys_close,sys32_close_wrapper) SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall) @@ -261,7 +261,7 @@ SYSCALL(sys_epoll_create,sys_epoll_create,sys_epoll_create_wrapper) SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper) /* 250 */ SYSCALL(sys_epoll_wait,sys_epoll_wait,sys_epoll_wait_wrapper) SYSCALL(sys_set_tid_address,sys_set_tid_address,sys32_set_tid_address_wrapper) -SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,sys32_fadvise64_wrapper) +SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,compat_sys_s390_fadvise64) SYSCALL(sys_timer_create,sys_timer_create,sys32_timer_create_wrapper) SYSCALL(sys_timer_settime,sys_timer_settime,sys32_timer_settime_wrapper) /* 255 */ SYSCALL(sys_timer_gettime,sys_timer_gettime,sys32_timer_gettime_wrapper) @@ -272,7 +272,7 @@ SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) NI_SYSCALL /* reserved for vserver */ -SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) +SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,compat_sys_s390_fadvise64_64) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) SYSCALL(sys_remap_file_pages,sys_remap_file_pages,sys32_remap_file_pages_wrapper) -- cgit v1.2.3-55-g7522 From b07edab23c7f93db0e7ab09bd7f5eddc421f6e8c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 09:52:01 +0100 Subject: s390/compat: convert system call wrappers to C part 01 Introduce a new compat_wrap.c file which contains the s390 specific compat system call wrappers. The s390 specific system call wrappers only perform sign, zero and pointer conversion of system call arguments before actually calling the non-compat system call. Therefore introduce COMPAT_SYSCALL_WRAPx macros which generate C code that is nearly identical to the assembly code. This has the advantage that the compile will generate correct code, and we avoid the frequent copy-paste errors seen in the compat_wrapper.S file. Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 1 + arch/s390/kernel/compat_wrap.c | 35 ++++++++++++++++++++++++ arch/s390/kernel/compat_wrapper.S | 56 --------------------------------------- arch/s390/kernel/syscalls.S | 24 ++++++++--------- 4 files changed, 48 insertions(+), 68 deletions(-) create mode 100644 arch/s390/kernel/compat_wrap.c (limited to 'arch') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 1b3ac09c11b6..725515f9c5db 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -50,6 +50,7 @@ compat-obj-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ compat_wrapper.o compat_exec_domain.o \ $(compat-obj-y) +obj-$(CONFIG_COMPAT) += compat_wrap.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_KPROBES) += kprobes.o diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c new file mode 100644 index 000000000000..5357190c814e --- /dev/null +++ b/arch/s390/kernel/compat_wrap.c @@ -0,0 +1,35 @@ +#include +#include + +#define COMPAT_SYSCALL_WRAP1(name, ...) \ + COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP2(name, ...) \ + COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP3(name, ...) \ + COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP4(name, ...) \ + COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP5(name, ...) \ + COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP6(name, ...) \ + COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) + +#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ + asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + { \ + return sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ + } + +COMPAT_SYSCALL_WRAP1(exit, int, error_code); +COMPAT_SYSCALL_WRAP1(close, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); +COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); +COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename); +COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev); +COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode); +COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name); +COMPAT_SYSCALL_WRAP1(alarm, unsigned int, seconds); +COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode); +COMPAT_SYSCALL_WRAP1(nice, int, increment); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 16ce71880cbd..09e65cd2e24e 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -8,47 +8,10 @@ #include -ENTRY(sys32_exit_wrapper) - lgfr %r2,%r2 # int - jg sys_exit # branch to sys_exit - -ENTRY(sys32_close_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_close # branch to system call - -ENTRY(sys32_creat_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - jg sys_creat # branch to system call - -ENTRY(sys32_link_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - jg sys_link # branch to system call - -ENTRY(sys32_unlink_wrapper) - llgtr %r2,%r2 # const char * - jg sys_unlink # branch to system call - -ENTRY(sys32_chdir_wrapper) - llgtr %r2,%r2 # const char * - jg sys_chdir # branch to system call - ENTRY(sys32_time_wrapper) llgtr %r2,%r2 # int * jg compat_sys_time # branch to system call -ENTRY(sys32_mknod_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - llgfr %r4,%r4 # dev - jg sys_mknod # branch to system call - -ENTRY(sys32_chmod_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # mode_t - jg sys_chmod # branch to system call - #sys32_getpid_wrapper # void ENTRY(sys32_mount_wrapper) @@ -59,10 +22,6 @@ ENTRY(sys32_mount_wrapper) llgtr %r6,%r6 # void * jg compat_sys_mount # branch to system call -ENTRY(sys32_oldumount_wrapper) - llgtr %r2,%r2 # char * - jg sys_oldumount # branch to system call - ENTRY(sys32_ptrace_wrapper) lgfr %r2,%r2 # long lgfr %r3,%r3 # long @@ -70,26 +29,11 @@ ENTRY(sys32_ptrace_wrapper) llgfr %r5,%r5 # long jg compat_sys_ptrace # branch to system call -ENTRY(sys32_alarm_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_alarm # branch to system call - ENTRY(compat_sys_utime_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_utimbuf * jg compat_sys_utime # branch to system call -ENTRY(sys32_access_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - jg sys_access # branch to system call - -ENTRY(sys32_nice_wrapper) - lgfr %r2,%r2 # int - jg sys_nice # branch to system call - -#sys32_sync_wrapper # void - ENTRY(sys32_kill_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 5a83f6a52c0e..ec1de1b3ecd2 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -9,40 +9,40 @@ #define NI_SYSCALL SYSCALL(sys_ni_syscall,sys_ni_syscall,sys_ni_syscall) NI_SYSCALL /* 0 */ -SYSCALL(sys_exit,sys_exit,sys32_exit_wrapper) +SYSCALL(sys_exit,sys_exit,compat_sys_exit) SYSCALL(sys_fork,sys_fork,sys_fork) SYSCALL(sys_read,sys_read,compat_sys_s390_read) SYSCALL(sys_write,sys_write,compat_sys_s390_write) SYSCALL(sys_open,sys_open,compat_sys_open) /* 5 */ -SYSCALL(sys_close,sys_close,sys32_close_wrapper) +SYSCALL(sys_close,sys_close,compat_sys_close) SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall) -SYSCALL(sys_creat,sys_creat,sys32_creat_wrapper) -SYSCALL(sys_link,sys_link,sys32_link_wrapper) -SYSCALL(sys_unlink,sys_unlink,sys32_unlink_wrapper) /* 10 */ +SYSCALL(sys_creat,sys_creat,compat_sys_creat) +SYSCALL(sys_link,sys_link,compat_sys_link) +SYSCALL(sys_unlink,sys_unlink,compat_sys_unlink) /* 10 */ SYSCALL(sys_execve,sys_execve,sys32_execve_wrapper) -SYSCALL(sys_chdir,sys_chdir,sys32_chdir_wrapper) +SYSCALL(sys_chdir,sys_chdir,compat_sys_chdir) SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ -SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper) -SYSCALL(sys_chmod,sys_chmod,sys32_chmod_wrapper) /* 15 */ +SYSCALL(sys_mknod,sys_mknod,compat_sys_mknod) +SYSCALL(sys_chmod,sys_chmod,compat_sys_chmod) /* 15 */ SYSCALL(sys_lchown16,sys_ni_syscall,compat_sys_s390_lchown16) /* old lchown16 syscall*/ NI_SYSCALL /* old break syscall holder */ NI_SYSCALL /* old stat syscall holder */ SYSCALL(sys_lseek,sys_lseek,compat_sys_lseek) SYSCALL(sys_getpid,sys_getpid,sys_getpid) /* 20 */ SYSCALL(sys_mount,sys_mount,sys32_mount_wrapper) -SYSCALL(sys_oldumount,sys_oldumount,sys32_oldumount_wrapper) +SYSCALL(sys_oldumount,sys_oldumount,compat_sys_oldumount) SYSCALL(sys_setuid16,sys_ni_syscall,compat_sys_s390_setuid16) /* old setuid16 syscall*/ SYSCALL(sys_getuid16,sys_ni_syscall,compat_sys_s390_getuid16) /* old getuid16 syscall*/ SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) -SYSCALL(sys_alarm,sys_alarm,sys32_alarm_wrapper) +SYSCALL(sys_alarm,sys_alarm,compat_sys_alarm) NI_SYSCALL /* old fstat syscall */ SYSCALL(sys_pause,sys_pause,sys_pause) SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */ NI_SYSCALL /* old stty syscall */ NI_SYSCALL /* old gtty syscall */ -SYSCALL(sys_access,sys_access,sys32_access_wrapper) -SYSCALL(sys_nice,sys_nice,sys32_nice_wrapper) +SYSCALL(sys_access,sys_access,compat_sys_access) +SYSCALL(sys_nice,sys_nice,compat_sys_nice) NI_SYSCALL /* 35 old ftime syscall */ SYSCALL(sys_sync,sys_sync,sys_sync) SYSCALL(sys_kill,sys_kill,sys32_kill_wrapper) -- cgit v1.2.3-55-g7522 From 473a06572fcd6b2e321d4b82c19ecafe383e8be9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 13:42:10 +0100 Subject: s390/compat: convert system call wrappers to C part 02 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++++ arch/s390/kernel/compat_wrapper.S | 45 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++++--------- 3 files changed, 20 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 5357190c814e..93f13f2350d4 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -33,3 +33,13 @@ COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name); COMPAT_SYSCALL_WRAP1(alarm, unsigned int, seconds); COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode); COMPAT_SYSCALL_WRAP1(nice, int, increment); +COMPAT_SYSCALL_WRAP2(kill, int, pid, int, sig); +COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname); +COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname); +COMPAT_SYSCALL_WRAP1(dup, unsigned int, fildes); +COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes); +COMPAT_SYSCALL_WRAP1(brk, compat_ulong_t, brk); +COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); +COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); +COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 09e65cd2e24e..e1b9d4ab0796 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -34,55 +34,10 @@ ENTRY(compat_sys_utime_wrapper) llgtr %r3,%r3 # struct compat_utimbuf * jg compat_sys_utime # branch to system call -ENTRY(sys32_kill_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_kill # branch to system call - -ENTRY(sys32_rename_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - jg sys_rename # branch to system call - -ENTRY(sys32_mkdir_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - jg sys_mkdir # branch to system call - -ENTRY(sys32_rmdir_wrapper) - llgtr %r2,%r2 # const char * - jg sys_rmdir # branch to system call - -ENTRY(sys32_dup_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_dup # branch to system call - -ENTRY(sys32_pipe_wrapper) - llgtr %r2,%r2 # u32 * - jg sys_pipe # branch to system call - ENTRY(compat_sys_times_wrapper) llgtr %r2,%r2 # struct compat_tms * jg compat_sys_times # branch to system call -ENTRY(sys32_brk_wrapper) - llgtr %r2,%r2 # unsigned long - jg sys_brk # branch to system call - -ENTRY(sys32_signal_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # __sighandler_t - jg sys_signal - -ENTRY(sys32_acct_wrapper) - llgtr %r2,%r2 # char * - jg sys_acct # branch to system call - -ENTRY(sys32_umount_wrapper) - llgtr %r2,%r2 # char * - lgfr %r3,%r3 # int - jg sys_umount # branch to system call - ENTRY(compat_sys_ioctl_wrapper) llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index ec1de1b3ecd2..da6bffd5c473 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -45,22 +45,22 @@ SYSCALL(sys_access,sys_access,compat_sys_access) SYSCALL(sys_nice,sys_nice,compat_sys_nice) NI_SYSCALL /* 35 old ftime syscall */ SYSCALL(sys_sync,sys_sync,sys_sync) -SYSCALL(sys_kill,sys_kill,sys32_kill_wrapper) -SYSCALL(sys_rename,sys_rename,sys32_rename_wrapper) -SYSCALL(sys_mkdir,sys_mkdir,sys32_mkdir_wrapper) -SYSCALL(sys_rmdir,sys_rmdir,sys32_rmdir_wrapper) /* 40 */ -SYSCALL(sys_dup,sys_dup,sys32_dup_wrapper) -SYSCALL(sys_pipe,sys_pipe,sys32_pipe_wrapper) +SYSCALL(sys_kill,sys_kill,compat_sys_kill) +SYSCALL(sys_rename,sys_rename,compat_sys_rename) +SYSCALL(sys_mkdir,sys_mkdir,compat_sys_mkdir) +SYSCALL(sys_rmdir,sys_rmdir,compat_sys_rmdir) /* 40 */ +SYSCALL(sys_dup,sys_dup,compat_sys_dup) +SYSCALL(sys_pipe,sys_pipe,compat_sys_pipe) SYSCALL(sys_times,sys_times,compat_sys_times_wrapper) NI_SYSCALL /* old prof syscall */ -SYSCALL(sys_brk,sys_brk,sys32_brk_wrapper) /* 45 */ +SYSCALL(sys_brk,sys_brk,compat_sys_brk) /* 45 */ SYSCALL(sys_setgid16,sys_ni_syscall,compat_sys_s390_setgid16) /* old setgid16 syscall*/ SYSCALL(sys_getgid16,sys_ni_syscall,compat_sys_s390_getgid16) /* old getgid16 syscall*/ -SYSCALL(sys_signal,sys_signal,sys32_signal_wrapper) +SYSCALL(sys_signal,sys_signal,compat_sys_signal) SYSCALL(sys_geteuid16,sys_ni_syscall,compat_sys_s390_geteuid16) /* old geteuid16 syscall */ SYSCALL(sys_getegid16,sys_ni_syscall,compat_sys_s390_getegid16) /* 50 old getegid16 syscall */ -SYSCALL(sys_acct,sys_acct,sys32_acct_wrapper) -SYSCALL(sys_umount,sys_umount,sys32_umount_wrapper) +SYSCALL(sys_acct,sys_acct,compat_sys_acct) +SYSCALL(sys_umount,sys_umount,compat_sys_umount) NI_SYSCALL /* old lock syscall */ SYSCALL(sys_ioctl,sys_ioctl,compat_sys_ioctl_wrapper) SYSCALL(sys_fcntl,sys_fcntl,compat_sys_fcntl_wrapper) /* 55 */ -- cgit v1.2.3-55-g7522 From be06fbf816020a846991ef7f5489ac0027320ea3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 14:04:43 +0100 Subject: s390/compat: convert system call wrappers to C part 03 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++ arch/s390/kernel/compat_wrapper.S | 55 --------------------------------------- arch/s390/kernel/syscalls.S | 20 +++++++------- 3 files changed, 20 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 93f13f2350d4..ac26ee715553 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -43,3 +43,13 @@ COMPAT_SYSCALL_WRAP1(brk, compat_ulong_t, brk); COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); +COMPAT_SYSCALL_WRAP2(setpgid, compat_pid_t, pid, compat_pid_t, pgid); +COMPAT_SYSCALL_WRAP1(umask, int, mask); +COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename); +COMPAT_SYSCALL_WRAP2(dup2, unsigned int, oldfd, unsigned int, newfd); +COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, compat_old_sigset_t, mask); +COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len); +COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new); +COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); +COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); +COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index e1b9d4ab0796..359751108b8b 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -50,50 +50,15 @@ ENTRY(compat_sys_fcntl_wrapper) llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl # branch to system call -ENTRY(sys32_setpgid_wrapper) - lgfr %r2,%r2 # pid_t - lgfr %r3,%r3 # pid_t - jg sys_setpgid # branch to system call - -ENTRY(sys32_umask_wrapper) - lgfr %r2,%r2 # int - jg sys_umask # branch to system call - -ENTRY(sys32_chroot_wrapper) - llgtr %r2,%r2 # char * - jg sys_chroot # branch to system call - ENTRY(sys32_ustat_wrapper) llgfr %r2,%r2 # dev_t llgtr %r3,%r3 # struct ustat * jg compat_sys_ustat -ENTRY(sys32_dup2_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - jg sys_dup2 # branch to system call - -#sys32_getppid_wrapper # void - -#sys32_getpgrp_wrapper # void - -#sys32_setsid_wrapper # void - -ENTRY(sys_sigsuspend_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - llgfr %r4,%r4 # old_sigset_t - jg sys_sigsuspend - ENTRY(compat_sys_sigpending_wrapper) llgtr %r2,%r2 # compat_old_sigset_t * jg compat_sys_sigpending # branch to system call -ENTRY(sys32_sethostname_wrapper) - llgtr %r2,%r2 # char * - lgfr %r3,%r3 # int - jg sys_sethostname # branch to system call - ENTRY(compat_sys_setrlimit_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * @@ -119,26 +84,6 @@ ENTRY(compat_sys_settimeofday_wrapper) llgtr %r3,%r3 # struct timezone * jg compat_sys_settimeofday # branch to system call -ENTRY(sys32_symlink_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - jg sys_symlink # branch to system call - -ENTRY(sys32_readlink_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # char * - lgfr %r4,%r4 # int - jg sys_readlink # branch to system call - -ENTRY(sys32_uselib_wrapper) - llgtr %r2,%r2 # const char * - jg sys_uselib # branch to system call - -ENTRY(sys32_swapon_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - jg sys_swapon # branch to system call - ENTRY(sys32_reboot_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index da6bffd5c473..5bc24d9167dc 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -65,13 +65,13 @@ NI_SYSCALL /* old lock syscall */ SYSCALL(sys_ioctl,sys_ioctl,compat_sys_ioctl_wrapper) SYSCALL(sys_fcntl,sys_fcntl,compat_sys_fcntl_wrapper) /* 55 */ NI_SYSCALL /* intel mpx syscall */ -SYSCALL(sys_setpgid,sys_setpgid,sys32_setpgid_wrapper) +SYSCALL(sys_setpgid,sys_setpgid,compat_sys_setpgid) NI_SYSCALL /* old ulimit syscall */ NI_SYSCALL /* old uname syscall */ -SYSCALL(sys_umask,sys_umask,sys32_umask_wrapper) /* 60 */ -SYSCALL(sys_chroot,sys_chroot,sys32_chroot_wrapper) +SYSCALL(sys_umask,sys_umask,compat_sys_umask) /* 60 */ +SYSCALL(sys_chroot,sys_chroot,compat_sys_chroot) SYSCALL(sys_ustat,sys_ustat,sys32_ustat_wrapper) -SYSCALL(sys_dup2,sys_dup2,sys32_dup2_wrapper) +SYSCALL(sys_dup2,sys_dup2,compat_sys_dup2) SYSCALL(sys_getppid,sys_getppid,sys_getppid) SYSCALL(sys_getpgrp,sys_getpgrp,sys_getpgrp) /* 65 */ SYSCALL(sys_setsid,sys_setsid,sys_setsid) @@ -80,9 +80,9 @@ NI_SYSCALL /* old sgetmask syscall*/ NI_SYSCALL /* old ssetmask syscall*/ SYSCALL(sys_setreuid16,sys_ni_syscall,compat_sys_s390_setreuid16) /* old setreuid16 syscall */ SYSCALL(sys_setregid16,sys_ni_syscall,compat_sys_s390_setregid16) /* old setregid16 syscall */ -SYSCALL(sys_sigsuspend,sys_sigsuspend,sys_sigsuspend_wrapper) +SYSCALL(sys_sigsuspend,sys_sigsuspend,compat_sys_sigsuspend) SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) -SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper) +SYSCALL(sys_sethostname,sys_sethostname,compat_sys_sethostname) SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */ SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper) SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage) @@ -91,11 +91,11 @@ SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper) SYSCALL(sys_getgroups16,sys_ni_syscall,compat_sys_s390_getgroups16) /* 80 old getgroups16 syscall */ SYSCALL(sys_setgroups16,sys_ni_syscall,compat_sys_s390_setgroups16) /* old setgroups16 syscall */ NI_SYSCALL /* old select syscall */ -SYSCALL(sys_symlink,sys_symlink,sys32_symlink_wrapper) +SYSCALL(sys_symlink,sys_symlink,compat_sys_symlink) NI_SYSCALL /* old lstat syscall */ -SYSCALL(sys_readlink,sys_readlink,sys32_readlink_wrapper) /* 85 */ -SYSCALL(sys_uselib,sys_uselib,sys32_uselib_wrapper) -SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper) +SYSCALL(sys_readlink,sys_readlink,compat_sys_readlink) /* 85 */ +SYSCALL(sys_uselib,sys_uselib,compat_sys_uselib) +SYSCALL(sys_swapon,sys_swapon,compat_sys_swapon) SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper) SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ SYSCALL(sys_old_mmap,sys_old_mmap,compat_sys_s390_old_mmap) /* 90 */ -- cgit v1.2.3-55-g7522 From c355ce182a2e3f88d6382a9720be61369c38c5c7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 14:20:53 +0100 Subject: s390/compat: convert system call wrappers to C part 04 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++ arch/s390/kernel/compat_wrapper.S | 57 --------------------------------------- arch/s390/kernel/syscalls.S | 20 +++++++------- 3 files changed, 20 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index ac26ee715553..f2b85401a998 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -53,3 +53,13 @@ COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); +COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg); +COMPAT_SYSCALL_WRAP2(munmap, compat_ulong_t, addr, compat_size_t, len); +COMPAT_SYSCALL_WRAP2(fchmod, unsigned int, fd, umode_t, mode); +COMPAT_SYSCALL_WRAP2(getpriority, int, which, int, who); +COMPAT_SYSCALL_WRAP3(setpriority, int, which, int, who, int, niceval); +COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len); +COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); +COMPAT_SYSCALL_WRAP1(fsync, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); +COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 359751108b8b..3ea908f563f6 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -84,40 +84,12 @@ ENTRY(compat_sys_settimeofday_wrapper) llgtr %r3,%r3 # struct timezone * jg compat_sys_settimeofday # branch to system call -ENTRY(sys32_reboot_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - llgfr %r4,%r4 # unsigned int - llgtr %r5,%r5 # void * - jg sys_reboot # branch to system call - ENTRY(old32_readdir_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg compat_sys_old_readdir # branch to system call -ENTRY(sys32_munmap_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - jg sys_munmap # branch to system call - -ENTRY(sys32_fchmod_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # mode_t - jg sys_fchmod # branch to system call - -ENTRY(sys32_getpriority_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_getpriority # branch to system call - -ENTRY(sys32_setpriority_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - lgfr %r4,%r4 # int - jg sys_setpriority # branch to system call - ENTRY(compat_sys_statfs_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_statfs * @@ -133,12 +105,6 @@ ENTRY(compat_sys_socketcall_wrapper) llgtr %r3,%r3 # u32 * jg compat_sys_socketcall # branch to system call -ENTRY(sys32_syslog_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # char * - lgfr %r4,%r4 # int - jg sys_syslog # branch to system call - ENTRY(compat_sys_newstat_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat_emu31 * @@ -154,33 +120,10 @@ ENTRY(compat_sys_newfstat_wrapper) llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newfstat # branch to system call -#sys32_vhangup_wrapper # void - -ENTRY(sys32_swapoff_wrapper) - llgtr %r2,%r2 # const char * - jg sys_swapoff # branch to system call - ENTRY(compat_sys_sysinfo_wrapper) llgtr %r2,%r2 # struct sysinfo_emu31 * jg compat_sys_sysinfo # branch to system call -ENTRY(sys32_fsync_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_fsync # branch to system call - -#sys32_sigreturn_wrapper # done in sigreturn_glue - -#sys32_clone_wrapper # done in clone_glue - -ENTRY(sys32_setdomainname_wrapper) - llgtr %r2,%r2 # char * - lgfr %r3,%r3 # int - jg sys_setdomainname # branch to system call - -ENTRY(sys32_newuname_wrapper) - llgtr %r2,%r2 # struct new_utsname * - jg sys_newuname # branch to system call - ENTRY(compat_sys_adjtimex_wrapper) llgtr %r2,%r2 # struct compat_timex * jg compat_sys_adjtimex # branch to system call diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 5bc24d9167dc..4cf5a52de2ba 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -96,22 +96,22 @@ NI_SYSCALL /* old lstat syscall */ SYSCALL(sys_readlink,sys_readlink,compat_sys_readlink) /* 85 */ SYSCALL(sys_uselib,sys_uselib,compat_sys_uselib) SYSCALL(sys_swapon,sys_swapon,compat_sys_swapon) -SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper) +SYSCALL(sys_reboot,sys_reboot,compat_sys_reboot) SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ SYSCALL(sys_old_mmap,sys_old_mmap,compat_sys_s390_old_mmap) /* 90 */ -SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper) +SYSCALL(sys_munmap,sys_munmap,compat_sys_munmap) SYSCALL(sys_truncate,sys_truncate,compat_sys_truncate) SYSCALL(sys_ftruncate,sys_ftruncate,compat_sys_ftruncate) -SYSCALL(sys_fchmod,sys_fchmod,sys32_fchmod_wrapper) +SYSCALL(sys_fchmod,sys_fchmod,compat_sys_fchmod) SYSCALL(sys_fchown16,sys_ni_syscall,compat_sys_s390_fchown16) /* 95 old fchown16 syscall*/ -SYSCALL(sys_getpriority,sys_getpriority,sys32_getpriority_wrapper) -SYSCALL(sys_setpriority,sys_setpriority,sys32_setpriority_wrapper) +SYSCALL(sys_getpriority,sys_getpriority,compat_sys_getpriority) +SYSCALL(sys_setpriority,sys_setpriority,compat_sys_setpriority) NI_SYSCALL /* old profil syscall */ SYSCALL(sys_statfs,sys_statfs,compat_sys_statfs_wrapper) SYSCALL(sys_fstatfs,sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */ NI_SYSCALL /* ioperm for i386 */ SYSCALL(sys_socketcall,sys_socketcall,compat_sys_socketcall_wrapper) -SYSCALL(sys_syslog,sys_syslog,sys32_syslog_wrapper) +SYSCALL(sys_syslog,sys_syslog,compat_sys_syslog) SYSCALL(sys_setitimer,sys_setitimer,compat_sys_setitimer) SYSCALL(sys_getitimer,sys_getitimer,compat_sys_getitimer) /* 105 */ SYSCALL(sys_newstat,sys_newstat,compat_sys_newstat_wrapper) @@ -123,14 +123,14 @@ SYSCALL(sys_vhangup,sys_vhangup,sys_vhangup) NI_SYSCALL /* old "idle" system call */ NI_SYSCALL /* vm86old for i386 */ SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4) -SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */ +SYSCALL(sys_swapoff,sys_swapoff,compat_sys_swapoff) /* 115 */ SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) SYSCALL(sys_s390_ipc,sys_s390_ipc,compat_sys_s390_ipc) -SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) +SYSCALL(sys_fsync,sys_fsync,compat_sys_fsync) SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */ -SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper) -SYSCALL(sys_newuname,sys_newuname,sys32_newuname_wrapper) +SYSCALL(sys_setdomainname,sys_setdomainname,compat_sys_setdomainname) +SYSCALL(sys_newuname,sys_newuname,compat_sys_newuname) NI_SYSCALL /* modify_ldt for i386 */ SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper) SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */ -- cgit v1.2.3-55-g7522 From 86d295e1cc59b42d0d2f9fb5f7ff9b1894f90e0c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 15:16:04 +0100 Subject: s390/compat: convert system call wrappers to C part 05 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 11 ++++++++ arch/s390/kernel/compat_wrapper.S | 55 --------------------------------------- arch/s390/kernel/entry.h | 2 ++ arch/s390/kernel/syscalls.S | 20 +++++++------- 4 files changed, 23 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index f2b85401a998..558a1d485aa9 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -1,5 +1,6 @@ #include #include +#include "entry.h" #define COMPAT_SYSCALL_WRAP1(name, ...) \ COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) @@ -63,3 +64,13 @@ COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); COMPAT_SYSCALL_WRAP1(fsync, unsigned int, fd); COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); +COMPAT_SYSCALL_WRAP3(mprotect, compat_ulong_t, start, compat_size_t, len, compat_ulong_t, prot); +COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, compat_ulong_t, len, const char __user *, uargs); +COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr); +COMPAT_SYSCALL_WRAP1(getpgid, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP1(fchdir, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(bdflush, int, func, compat_long_t, data); +COMPAT_SYSCALL_WRAP3(sysfs, int, option, compat_ulong_t, arg1, compat_ulong_t, arg2); +COMPAT_SYSCALL_WRAP1(s390_personality, unsigned int, personality); +COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, u32, high, u32, low, loff_t __user *, result, unsigned int, whence); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 3ea908f563f6..78b78991257b 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -128,61 +128,6 @@ ENTRY(compat_sys_adjtimex_wrapper) llgtr %r2,%r2 # struct compat_timex * jg compat_sys_adjtimex # branch to system call -ENTRY(sys32_mprotect_wrapper) - llgtr %r2,%r2 # unsigned long (actually pointer - llgfr %r3,%r3 # size_t - llgfr %r4,%r4 # unsigned long - jg sys_mprotect # branch to system call - -ENTRY(sys_init_module_wrapper) - llgtr %r2,%r2 # void * - llgfr %r3,%r3 # unsigned long - llgtr %r4,%r4 # char * - jg sys_init_module # branch to system call - -ENTRY(sys_delete_module_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # unsigned int - jg sys_delete_module # branch to system call - -ENTRY(sys32_quotactl_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # qid_t - llgtr %r5,%r5 # caddr_t - jg sys_quotactl # branch to system call - -ENTRY(sys32_getpgid_wrapper) - lgfr %r2,%r2 # pid_t - jg sys_getpgid # branch to system call - -ENTRY(sys32_fchdir_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_fchdir # branch to system call - -ENTRY(sys32_bdflush_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # long - jg sys_bdflush # branch to system call - -ENTRY(sys32_sysfs_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - jg sys_sysfs # branch to system call - -ENTRY(sys32_personality_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_s390_personality # branch to system call - -ENTRY(sys32_llseek_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - llgtr %r5,%r5 # loff_t * - llgfr %r6,%r6 # unsigned int - jg sys_llseek # branch to system call - ENTRY(sys32_getdents_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index cb533f78c09e..8c6c022aeb71 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -72,4 +72,6 @@ long sys_rt_sigreturn(void); long sys32_sigreturn(void); long sys32_rt_sigreturn(void); +long sys_s390_personality(unsigned int personality); + #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 4cf5a52de2ba..88c85e4300aa 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -133,22 +133,22 @@ SYSCALL(sys_setdomainname,sys_setdomainname,compat_sys_setdomainname) SYSCALL(sys_newuname,sys_newuname,compat_sys_newuname) NI_SYSCALL /* modify_ldt for i386 */ SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper) -SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */ +SYSCALL(sys_mprotect,sys_mprotect,compat_sys_mprotect) /* 125 */ SYSCALL(sys_sigprocmask,sys_sigprocmask,compat_sys_sigprocmask) NI_SYSCALL /* old "create module" */ -SYSCALL(sys_init_module,sys_init_module,sys_init_module_wrapper) -SYSCALL(sys_delete_module,sys_delete_module,sys_delete_module_wrapper) +SYSCALL(sys_init_module,sys_init_module,compat_sys_init_module) +SYSCALL(sys_delete_module,sys_delete_module,compat_sys_delete_module) NI_SYSCALL /* 130: old get_kernel_syms */ -SYSCALL(sys_quotactl,sys_quotactl,sys32_quotactl_wrapper) -SYSCALL(sys_getpgid,sys_getpgid,sys32_getpgid_wrapper) -SYSCALL(sys_fchdir,sys_fchdir,sys32_fchdir_wrapper) -SYSCALL(sys_bdflush,sys_bdflush,sys32_bdflush_wrapper) -SYSCALL(sys_sysfs,sys_sysfs,sys32_sysfs_wrapper) /* 135 */ -SYSCALL(sys_personality,sys_s390_personality,sys32_personality_wrapper) +SYSCALL(sys_quotactl,sys_quotactl,compat_sys_quotactl) +SYSCALL(sys_getpgid,sys_getpgid,compat_sys_getpgid) +SYSCALL(sys_fchdir,sys_fchdir,compat_sys_fchdir) +SYSCALL(sys_bdflush,sys_bdflush,compat_sys_bdflush) +SYSCALL(sys_sysfs,sys_sysfs,compat_sys_sysfs) /* 135 */ +SYSCALL(sys_personality,sys_s390_personality,compat_sys_s390_personality) NI_SYSCALL /* for afs_syscall */ SYSCALL(sys_setfsuid16,sys_ni_syscall,compat_sys_s390_setfsuid16) /* old setfsuid16 syscall */ SYSCALL(sys_setfsgid16,sys_ni_syscall,compat_sys_s390_setfsgid16) /* old setfsgid16 syscall */ -SYSCALL(sys_llseek,sys_llseek,sys32_llseek_wrapper) /* 140 */ +SYSCALL(sys_llseek,sys_llseek,compat_sys_llseek) /* 140 */ SYSCALL(sys_getdents,sys_getdents,sys32_getdents_wrapper) SYSCALL(sys_select,sys_select,compat_sys_select_wrapper) SYSCALL(sys_flock,sys_flock,sys32_flock_wrapper) -- cgit v1.2.3-55-g7522 From ce5cef7edecd21b993c6019dae01a7ff1b453379 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 15:33:06 +0100 Subject: s390/compat: convert system call wrappers to C part 06 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 ++++++++ arch/s390/kernel/compat_wrapper.S | 51 --------------------------------------- arch/s390/kernel/syscalls.S | 20 +++++++-------- 3 files changed, 20 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 558a1d485aa9..60813d5c743d 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -74,3 +74,13 @@ COMPAT_SYSCALL_WRAP2(bdflush, int, func, compat_long_t, data); COMPAT_SYSCALL_WRAP3(sysfs, int, option, compat_ulong_t, arg1, compat_ulong_t, arg2); COMPAT_SYSCALL_WRAP1(s390_personality, unsigned int, personality); COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, u32, high, u32, low, loff_t __user *, result, unsigned int, whence); +COMPAT_SYSCALL_WRAP2(flock, unsigned int, fd, unsigned int, cmd); +COMPAT_SYSCALL_WRAP3(msync, compat_ulong_t, start, compat_size_t, len, int, flags); +COMPAT_SYSCALL_WRAP1(getsid, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP1(fdatasync, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(mlock, compat_ulong_t, start, compat_size_t, len); +COMPAT_SYSCALL_WRAP2(munlock, compat_ulong_t, start, compat_size_t, len); +COMPAT_SYSCALL_WRAP1(mlockall, int, flags); +COMPAT_SYSCALL_WRAP2(sched_setparam, compat_pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP2(sched_getparam, compat_pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP3(sched_setscheduler, compat_pid_t, pid, int, policy, struct sched_param __user *, param); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 78b78991257b..707e37524d9f 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -142,17 +142,6 @@ ENTRY(compat_sys_select_wrapper) llgtr %r6,%r6 # struct compat_timeval * jg compat_sys_select # branch to system call -ENTRY(sys32_flock_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - jg sys_flock # branch to system call - -ENTRY(sys32_msync_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - lgfr %r4,%r4 # int - jg sys_msync # branch to system call - ENTRY(compat_sys_readv_wrapper) lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct compat_iovec * @@ -165,46 +154,6 @@ ENTRY(compat_sys_writev_wrapper) llgfr %r4,%r4 # unsigned long jg compat_sys_writev # branch to system call -ENTRY(sys32_getsid_wrapper) - lgfr %r2,%r2 # pid_t - jg sys_getsid # branch to system call - -ENTRY(sys32_fdatasync_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_fdatasync # branch to system call - -ENTRY(sys32_mlock_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - jg sys_mlock # branch to system call - -ENTRY(sys32_munlock_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - jg sys_munlock # branch to system call - -ENTRY(sys32_mlockall_wrapper) - lgfr %r2,%r2 # int - jg sys_mlockall # branch to system call - -#sys32_munlockall_wrapper # void - -ENTRY(sys32_sched_setparam_wrapper) - lgfr %r2,%r2 # pid_t - llgtr %r3,%r3 # struct sched_param * - jg sys_sched_setparam # branch to system call - -ENTRY(sys32_sched_getparam_wrapper) - lgfr %r2,%r2 # pid_t - llgtr %r3,%r3 # struct sched_param * - jg sys_sched_getparam # branch to system call - -ENTRY(sys32_sched_setscheduler_wrapper) - lgfr %r2,%r2 # pid_t - lgfr %r3,%r3 # int - llgtr %r4,%r4 # struct sched_param * - jg sys_sched_setscheduler # branch to system call - ENTRY(sys32_sched_getscheduler_wrapper) lgfr %r2,%r2 # pid_t jg sys_sched_getscheduler # branch to system call diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 88c85e4300aa..c667bb13a4d7 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -151,20 +151,20 @@ SYSCALL(sys_setfsgid16,sys_ni_syscall,compat_sys_s390_setfsgid16) /* old setfsgi SYSCALL(sys_llseek,sys_llseek,compat_sys_llseek) /* 140 */ SYSCALL(sys_getdents,sys_getdents,sys32_getdents_wrapper) SYSCALL(sys_select,sys_select,compat_sys_select_wrapper) -SYSCALL(sys_flock,sys_flock,sys32_flock_wrapper) -SYSCALL(sys_msync,sys_msync,sys32_msync_wrapper) +SYSCALL(sys_flock,sys_flock,compat_sys_flock) +SYSCALL(sys_msync,sys_msync,compat_sys_msync) SYSCALL(sys_readv,sys_readv,compat_sys_readv_wrapper) /* 145 */ SYSCALL(sys_writev,sys_writev,compat_sys_writev_wrapper) -SYSCALL(sys_getsid,sys_getsid,sys32_getsid_wrapper) -SYSCALL(sys_fdatasync,sys_fdatasync,sys32_fdatasync_wrapper) +SYSCALL(sys_getsid,sys_getsid,compat_sys_getsid) +SYSCALL(sys_fdatasync,sys_fdatasync,compat_sys_fdatasync) SYSCALL(sys_sysctl,sys_sysctl,compat_sys_sysctl) -SYSCALL(sys_mlock,sys_mlock,sys32_mlock_wrapper) /* 150 */ -SYSCALL(sys_munlock,sys_munlock,sys32_munlock_wrapper) -SYSCALL(sys_mlockall,sys_mlockall,sys32_mlockall_wrapper) +SYSCALL(sys_mlock,sys_mlock,compat_sys_mlock) /* 150 */ +SYSCALL(sys_munlock,sys_munlock,compat_sys_munlock) +SYSCALL(sys_mlockall,sys_mlockall,compat_sys_mlockall) SYSCALL(sys_munlockall,sys_munlockall,sys_munlockall) -SYSCALL(sys_sched_setparam,sys_sched_setparam,sys32_sched_setparam_wrapper) -SYSCALL(sys_sched_getparam,sys_sched_getparam,sys32_sched_getparam_wrapper) /* 155 */ -SYSCALL(sys_sched_setscheduler,sys_sched_setscheduler,sys32_sched_setscheduler_wrapper) +SYSCALL(sys_sched_setparam,sys_sched_setparam,compat_sys_sched_setparam) +SYSCALL(sys_sched_getparam,sys_sched_getparam,compat_sys_sched_getparam) /* 155 */ +SYSCALL(sys_sched_setscheduler,sys_sched_setscheduler,compat_sys_sched_setscheduler) SYSCALL(sys_sched_getscheduler,sys_sched_getscheduler,sys32_sched_getscheduler_wrapper) SYSCALL(sys_sched_yield,sys_sched_yield,sys_sched_yield) SYSCALL(sys_sched_get_priority_max,sys_sched_get_priority_max,sys32_sched_get_priority_max_wrapper) -- cgit v1.2.3-55-g7522 From 0ebe3eec1e38bb1253e7542b0e567f0478f7bf4f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 16:49:10 +0100 Subject: s390/compat: convert system call wrappers to C part 07 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 ++++++ arch/s390/kernel/compat_wrapper.S | 66 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++------ 3 files changed, 20 insertions(+), 76 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 60813d5c743d..2e132f998d63 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -84,3 +84,13 @@ COMPAT_SYSCALL_WRAP1(mlockall, int, flags); COMPAT_SYSCALL_WRAP2(sched_setparam, compat_pid_t, pid, struct sched_param __user *, param); COMPAT_SYSCALL_WRAP2(sched_getparam, compat_pid_t, pid, struct sched_param __user *, param); COMPAT_SYSCALL_WRAP3(sched_setscheduler, compat_pid_t, pid, int, policy, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP1(sched_getscheduler, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP1(sched_get_priority_max, int, policy); +COMPAT_SYSCALL_WRAP1(sched_get_priority_min, int, policy); +COMPAT_SYSCALL_WRAP5(mremap, u32, addr, u32, old_len, u32, new_len, u32, flags, u32, new_addr); +COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout); +COMPAT_SYSCALL_WRAP5(prctl, int, option, u32, arg2, u32, arg3, u32, arg4, u32, arg5); +COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, u32, size); +COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); +COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); +COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 707e37524d9f..ac12c0f1c983 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -154,77 +154,11 @@ ENTRY(compat_sys_writev_wrapper) llgfr %r4,%r4 # unsigned long jg compat_sys_writev # branch to system call -ENTRY(sys32_sched_getscheduler_wrapper) - lgfr %r2,%r2 # pid_t - jg sys_sched_getscheduler # branch to system call - -#sys32_sched_yield_wrapper # void - -ENTRY(sys32_sched_get_priority_max_wrapper) - lgfr %r2,%r2 # int - jg sys_sched_get_priority_max # branch to system call - -ENTRY(sys32_sched_get_priority_min_wrapper) - lgfr %r2,%r2 # int - jg sys_sched_get_priority_min # branch to system call - ENTRY(compat_sys_nanosleep_wrapper) llgtr %r2,%r2 # struct compat_timespec * llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call -ENTRY(sys32_mremap_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - llgfr %r5,%r5 # unsigned long - llgfr %r6,%r6 # unsigned long - jg sys_mremap # branch to system call - -ENTRY(sys32_poll_wrapper) - llgtr %r2,%r2 # struct pollfd * - llgfr %r3,%r3 # unsigned int - lgfr %r4,%r4 # int - jg sys_poll # branch to system call - -ENTRY(sys32_prctl_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - llgfr %r5,%r5 # unsigned long - llgfr %r6,%r6 # unsigned long - jg sys_prctl # branch to system call - -#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue - -ENTRY(sys32_getcwd_wrapper) - llgtr %r2,%r2 # char * - llgfr %r3,%r3 # unsigned long - jg sys_getcwd # branch to system call - -ENTRY(sys32_capget_wrapper) - llgtr %r2,%r2 # cap_user_header_t - llgtr %r3,%r3 # cap_user_data_t - jg sys_capget # branch to system call - -ENTRY(sys32_capset_wrapper) - llgtr %r2,%r2 # cap_user_header_t - llgtr %r3,%r3 # const cap_user_data_t - jg sys_capset # branch to system call - -#sys32_vfork_wrapper # done in vfork_glue - -ENTRY(sys32_lchown_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # uid_t - llgfr %r4,%r4 # gid_t - jg sys_lchown # branch to system call - -#sys32_getuid_wrapper # void -#sys32_getgid_wrapper # void -#sys32_geteuid_wrapper # void -#sys32_getegid_wrapper # void - ENTRY(sys32_setreuid_wrapper) llgfr %r2,%r2 # uid_t llgfr %r3,%r3 # uid_t diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index c667bb13a4d7..775856a77645 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -165,22 +165,22 @@ SYSCALL(sys_munlockall,sys_munlockall,sys_munlockall) SYSCALL(sys_sched_setparam,sys_sched_setparam,compat_sys_sched_setparam) SYSCALL(sys_sched_getparam,sys_sched_getparam,compat_sys_sched_getparam) /* 155 */ SYSCALL(sys_sched_setscheduler,sys_sched_setscheduler,compat_sys_sched_setscheduler) -SYSCALL(sys_sched_getscheduler,sys_sched_getscheduler,sys32_sched_getscheduler_wrapper) +SYSCALL(sys_sched_getscheduler,sys_sched_getscheduler,compat_sys_sched_getscheduler) SYSCALL(sys_sched_yield,sys_sched_yield,sys_sched_yield) -SYSCALL(sys_sched_get_priority_max,sys_sched_get_priority_max,sys32_sched_get_priority_max_wrapper) -SYSCALL(sys_sched_get_priority_min,sys_sched_get_priority_min,sys32_sched_get_priority_min_wrapper) /* 160 */ +SYSCALL(sys_sched_get_priority_max,sys_sched_get_priority_max,compat_sys_sched_get_priority_max) +SYSCALL(sys_sched_get_priority_min,sys_sched_get_priority_min,compat_sys_sched_get_priority_min) /* 160 */ SYSCALL(sys_sched_rr_get_interval,sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval) SYSCALL(sys_nanosleep,sys_nanosleep,compat_sys_nanosleep_wrapper) -SYSCALL(sys_mremap,sys_mremap,sys32_mremap_wrapper) +SYSCALL(sys_mremap,sys_mremap,compat_sys_mremap) SYSCALL(sys_setresuid16,sys_ni_syscall,compat_sys_s390_setresuid16) /* old setresuid16 syscall */ SYSCALL(sys_getresuid16,sys_ni_syscall,compat_sys_s390_getresuid16) /* 165 old getresuid16 syscall */ NI_SYSCALL /* for vm86 */ NI_SYSCALL /* old sys_query_module */ -SYSCALL(sys_poll,sys_poll,sys32_poll_wrapper) +SYSCALL(sys_poll,sys_poll,compat_sys_poll) NI_SYSCALL /* old nfsservctl */ SYSCALL(sys_setresgid16,sys_ni_syscall,compat_sys_s390_setresgid16) /* 170 old setresgid16 syscall */ SYSCALL(sys_getresgid16,sys_ni_syscall,compat_sys_s390_getresgid16) /* old getresgid16 syscall */ -SYSCALL(sys_prctl,sys_prctl,sys32_prctl_wrapper) +SYSCALL(sys_prctl,sys_prctl,compat_sys_prctl) SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,sys32_rt_sigreturn) SYSCALL(sys_rt_sigaction,sys_rt_sigaction,compat_sys_rt_sigaction) SYSCALL(sys_rt_sigprocmask,sys_rt_sigprocmask,compat_sys_rt_sigprocmask) /* 175 */ @@ -191,9 +191,9 @@ SYSCALL(sys_rt_sigsuspend,sys_rt_sigsuspend,compat_sys_rt_sigsuspend) SYSCALL(sys_pread64,sys_pread64,compat_sys_s390_pread64) /* 180 */ SYSCALL(sys_pwrite64,sys_pwrite64,compat_sys_s390_pwrite64) SYSCALL(sys_chown16,sys_ni_syscall,compat_sys_s390_chown16) /* old chown16 syscall */ -SYSCALL(sys_getcwd,sys_getcwd,sys32_getcwd_wrapper) -SYSCALL(sys_capget,sys_capget,sys32_capget_wrapper) -SYSCALL(sys_capset,sys_capset,sys32_capset_wrapper) /* 185 */ +SYSCALL(sys_getcwd,sys_getcwd,compat_sys_getcwd) +SYSCALL(sys_capget,sys_capget,compat_sys_capget) +SYSCALL(sys_capset,sys_capset,compat_sys_capset) /* 185 */ SYSCALL(sys_sigaltstack,sys_sigaltstack,compat_sys_sigaltstack) SYSCALL(sys_sendfile,sys_sendfile64,compat_sys_sendfile) NI_SYSCALL /* streams1 */ @@ -206,7 +206,7 @@ SYSCALL(sys_ftruncate64,sys_ni_syscall,compat_sys_s390_ftruncate64) SYSCALL(sys_stat64,sys_ni_syscall,compat_sys_s390_stat64) /* 195 */ SYSCALL(sys_lstat64,sys_ni_syscall,compat_sys_s390_lstat64) SYSCALL(sys_fstat64,sys_ni_syscall,compat_sys_s390_fstat64) -SYSCALL(sys_lchown,sys_lchown,sys32_lchown_wrapper) +SYSCALL(sys_lchown,sys_lchown,compat_sys_lchown) SYSCALL(sys_getuid,sys_getuid,sys_getuid) SYSCALL(sys_getgid,sys_getgid,sys_getgid) /* 200 */ SYSCALL(sys_geteuid,sys_geteuid,sys_geteuid) -- cgit v1.2.3-55-g7522 From 47b3ae9b8cb0a6778a9920efaf3c47b19b4e6468 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 27 Feb 2014 17:35:23 +0100 Subject: s390/compat: convert system call wrappers to C part 08 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++ arch/s390/kernel/compat_wrapper.S | 56 --------------------------------------- arch/s390/kernel/syscalls.S | 20 +++++++------- 3 files changed, 20 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 2e132f998d63..30167722231d 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -94,3 +94,13 @@ COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, u32, size); COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); +COMPAT_SYSCALL_WRAP2(setreuid, compat_uid_t, ruid, compat_uid_t, euid); +COMPAT_SYSCALL_WRAP2(setregid, compat_gid_t, rgid, compat_gid_t, egid); +COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, compat_gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, compat_gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP3(fchown, unsigned int, fd, compat_uid_t, user, compat_gid_t, group); +COMPAT_SYSCALL_WRAP3(setresuid, compat_uid_t, ruid, compat_uid_t, euid, compat_uid_t, suid); +COMPAT_SYSCALL_WRAP3(getresuid, compat_uid_t __user *, ruid, compat_uid_t __user *, euid, compat_uid_t __user *, suid); +COMPAT_SYSCALL_WRAP3(setresgid, compat_gid_t, rgid, compat_gid_t, egid, compat_gid_t, sgid); +COMPAT_SYSCALL_WRAP3(getresgid, compat_gid_t __user *, rgid, compat_gid_t __user *, egid, compat_gid_t __user *, sgid); +COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index ac12c0f1c983..e430f28896a8 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -159,62 +159,6 @@ ENTRY(compat_sys_nanosleep_wrapper) llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call -ENTRY(sys32_setreuid_wrapper) - llgfr %r2,%r2 # uid_t - llgfr %r3,%r3 # uid_t - jg sys_setreuid # branch to system call - -ENTRY(sys32_setregid_wrapper) - llgfr %r2,%r2 # gid_t - llgfr %r3,%r3 # gid_t - jg sys_setregid # branch to system call - -ENTRY(sys32_getgroups_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # gid_t * - jg sys_getgroups # branch to system call - -ENTRY(sys32_setgroups_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # gid_t * - jg sys_setgroups # branch to system call - -ENTRY(sys32_fchown_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # uid_t - llgfr %r4,%r4 # gid_t - jg sys_fchown # branch to system call - -ENTRY(sys32_setresuid_wrapper) - llgfr %r2,%r2 # uid_t - llgfr %r3,%r3 # uid_t - llgfr %r4,%r4 # uid_t - jg sys_setresuid # branch to system call - -ENTRY(sys32_getresuid_wrapper) - llgtr %r2,%r2 # uid_t * - llgtr %r3,%r3 # uid_t * - llgtr %r4,%r4 # uid_t * - jg sys_getresuid # branch to system call - -ENTRY(sys32_setresgid_wrapper) - llgfr %r2,%r2 # gid_t - llgfr %r3,%r3 # gid_t - llgfr %r4,%r4 # gid_t - jg sys_setresgid # branch to system call - -ENTRY(sys32_getresgid_wrapper) - llgtr %r2,%r2 # gid_t * - llgtr %r3,%r3 # gid_t * - llgtr %r4,%r4 # gid_t * - jg sys_getresgid # branch to system call - -ENTRY(sys32_chown_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # uid_t - llgfr %r4,%r4 # gid_t - jg sys_chown # branch to system call - ENTRY(sys32_setuid_wrapper) llgfr %r2,%r2 # uid_t jg sys_setuid # branch to system call diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 775856a77645..609de5ad6a5c 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -211,16 +211,16 @@ SYSCALL(sys_getuid,sys_getuid,sys_getuid) SYSCALL(sys_getgid,sys_getgid,sys_getgid) /* 200 */ SYSCALL(sys_geteuid,sys_geteuid,sys_geteuid) SYSCALL(sys_getegid,sys_getegid,sys_getegid) -SYSCALL(sys_setreuid,sys_setreuid,sys32_setreuid_wrapper) -SYSCALL(sys_setregid,sys_setregid,sys32_setregid_wrapper) -SYSCALL(sys_getgroups,sys_getgroups,sys32_getgroups_wrapper) /* 205 */ -SYSCALL(sys_setgroups,sys_setgroups,sys32_setgroups_wrapper) -SYSCALL(sys_fchown,sys_fchown,sys32_fchown_wrapper) -SYSCALL(sys_setresuid,sys_setresuid,sys32_setresuid_wrapper) -SYSCALL(sys_getresuid,sys_getresuid,sys32_getresuid_wrapper) -SYSCALL(sys_setresgid,sys_setresgid,sys32_setresgid_wrapper) /* 210 */ -SYSCALL(sys_getresgid,sys_getresgid,sys32_getresgid_wrapper) -SYSCALL(sys_chown,sys_chown,sys32_chown_wrapper) +SYSCALL(sys_setreuid,sys_setreuid,compat_sys_setreuid) +SYSCALL(sys_setregid,sys_setregid,compat_sys_setregid) +SYSCALL(sys_getgroups,sys_getgroups,compat_sys_getgroups) /* 205 */ +SYSCALL(sys_setgroups,sys_setgroups,compat_sys_setgroups) +SYSCALL(sys_fchown,sys_fchown,compat_sys_fchown) +SYSCALL(sys_setresuid,sys_setresuid,compat_sys_setresuid) +SYSCALL(sys_getresuid,sys_getresuid,compat_sys_getresuid) +SYSCALL(sys_setresgid,sys_setresgid,compat_sys_setresgid) /* 210 */ +SYSCALL(sys_getresgid,sys_getresgid,compat_sys_getresgid) +SYSCALL(sys_chown,sys_chown,compat_sys_chown) SYSCALL(sys_setuid,sys_setuid,sys32_setuid_wrapper) SYSCALL(sys_setgid,sys_setgid,sys32_setgid_wrapper) SYSCALL(sys_setfsuid,sys_setfsuid,sys32_setfsuid_wrapper) /* 215 */ -- cgit v1.2.3-55-g7522 From 24e4c2aaef149eafc1958205ace2b202de0dbf16 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 28 Feb 2014 10:31:37 +0100 Subject: s390/compat: convert system call wrappers to C part 09 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++ arch/s390/kernel/compat_wrapper.S | 57 --------------------------------------- arch/s390/kernel/syscalls.S | 20 +++++++------- 3 files changed, 20 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 30167722231d..84d2e256ddab 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -104,3 +104,13 @@ COMPAT_SYSCALL_WRAP3(getresuid, compat_uid_t __user *, ruid, compat_uid_t __user COMPAT_SYSCALL_WRAP3(setresgid, compat_gid_t, rgid, compat_gid_t, egid, compat_gid_t, sgid); COMPAT_SYSCALL_WRAP3(getresgid, compat_gid_t __user *, rgid, compat_gid_t __user *, egid, compat_gid_t __user *, sgid); COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); +COMPAT_SYSCALL_WRAP1(setuid, compat_uid_t, uid); +COMPAT_SYSCALL_WRAP1(setgid, compat_gid_t, gid); +COMPAT_SYSCALL_WRAP1(setfsuid, compat_uid_t, uid); +COMPAT_SYSCALL_WRAP1(setfsgid, compat_gid_t, gid); +COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old); +COMPAT_SYSCALL_WRAP3(mincore, compat_ulong_t, start, compat_size_t, len, unsigned char __user *, vec); +COMPAT_SYSCALL_WRAP3(madvise, compat_ulong_t, start, compat_size_t, len, int, behavior); +COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index e430f28896a8..1e1b71ff9fa6 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -159,39 +159,6 @@ ENTRY(compat_sys_nanosleep_wrapper) llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call -ENTRY(sys32_setuid_wrapper) - llgfr %r2,%r2 # uid_t - jg sys_setuid # branch to system call - -ENTRY(sys32_setgid_wrapper) - llgfr %r2,%r2 # gid_t - jg sys_setgid # branch to system call - -ENTRY(sys32_setfsuid_wrapper) - llgfr %r2,%r2 # uid_t - jg sys_setfsuid # branch to system call - -ENTRY(sys32_setfsgid_wrapper) - llgfr %r2,%r2 # gid_t - jg sys_setfsgid # branch to system call - -ENTRY(sys32_pivot_root_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - jg sys_pivot_root # branch to system call - -ENTRY(sys32_mincore_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - llgtr %r4,%r4 # unsigned char * - jg sys_mincore # branch to system call - -ENTRY(sys32_madvise_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t - lgfr %r4,%r4 # int - jg sys_madvise # branch to system call - ENTRY(sys32_getdents64_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * @@ -208,30 +175,6 @@ ENTRY(sys32_stime_wrapper) llgtr %r2,%r2 # long * jg compat_sys_stime # branch to system call -ENTRY(sys32_setxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - lgfr %r6,%r6 # int - jg sys_setxattr - -ENTRY(sys32_lsetxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - lgfr %r6,%r6 # int - jg sys_lsetxattr - -ENTRY(sys32_fsetxattr_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - lgfr %r6,%r6 # int - jg sys_fsetxattr - ENTRY(sys32_getxattr_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # char * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 609de5ad6a5c..053b2712fe28 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -221,20 +221,20 @@ SYSCALL(sys_getresuid,sys_getresuid,compat_sys_getresuid) SYSCALL(sys_setresgid,sys_setresgid,compat_sys_setresgid) /* 210 */ SYSCALL(sys_getresgid,sys_getresgid,compat_sys_getresgid) SYSCALL(sys_chown,sys_chown,compat_sys_chown) -SYSCALL(sys_setuid,sys_setuid,sys32_setuid_wrapper) -SYSCALL(sys_setgid,sys_setgid,sys32_setgid_wrapper) -SYSCALL(sys_setfsuid,sys_setfsuid,sys32_setfsuid_wrapper) /* 215 */ -SYSCALL(sys_setfsgid,sys_setfsgid,sys32_setfsgid_wrapper) -SYSCALL(sys_pivot_root,sys_pivot_root,sys32_pivot_root_wrapper) -SYSCALL(sys_mincore,sys_mincore,sys32_mincore_wrapper) -SYSCALL(sys_madvise,sys_madvise,sys32_madvise_wrapper) +SYSCALL(sys_setuid,sys_setuid,compat_sys_setuid) +SYSCALL(sys_setgid,sys_setgid,compat_sys_setgid) +SYSCALL(sys_setfsuid,sys_setfsuid,compat_sys_setfsuid) /* 215 */ +SYSCALL(sys_setfsgid,sys_setfsgid,compat_sys_setfsgid) +SYSCALL(sys_pivot_root,sys_pivot_root,compat_sys_pivot_root) +SYSCALL(sys_mincore,sys_mincore,compat_sys_mincore) +SYSCALL(sys_madvise,sys_madvise,compat_sys_madvise) SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */ SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) SYSCALL(sys_readahead,sys_readahead,compat_sys_s390_readahead) SYSCALL(sys_sendfile64,sys_ni_syscall,compat_sys_sendfile64) -SYSCALL(sys_setxattr,sys_setxattr,sys32_setxattr_wrapper) -SYSCALL(sys_lsetxattr,sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */ -SYSCALL(sys_fsetxattr,sys_fsetxattr,sys32_fsetxattr_wrapper) +SYSCALL(sys_setxattr,sys_setxattr,compat_sys_setxattr) +SYSCALL(sys_lsetxattr,sys_lsetxattr,compat_sys_lsetxattr) /* 225 */ +SYSCALL(sys_fsetxattr,sys_fsetxattr,compat_sys_fsetxattr) SYSCALL(sys_getxattr,sys_getxattr,sys32_getxattr_wrapper) SYSCALL(sys_lgetxattr,sys_lgetxattr,sys32_lgetxattr_wrapper) SYSCALL(sys_fgetxattr,sys_fgetxattr,sys32_fgetxattr_wrapper) -- cgit v1.2.3-55-g7522 From 18421166e8360bbb29b5eedd2cd3a9aedc0c90b3 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 28 Feb 2014 12:59:44 +0100 Subject: s390/compat: convert system call wrappers to C part 10 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 +++++++ arch/s390/kernel/compat_wrapper.S | 60 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++------- 3 files changed, 20 insertions(+), 70 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 84d2e256ddab..97197b8ab838 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -114,3 +114,13 @@ COMPAT_SYSCALL_WRAP3(madvise, compat_ulong_t, start, compat_size_t, len, int, be COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); +COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count); +COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, compat_size_t, size); +COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, compat_size_t, size); +COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, compat_size_t, size); +COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, compat_size_t, size); +COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, compat_size_t, size); +COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, compat_size_t, size); +COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); +COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); +COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 1e1b71ff9fa6..f23a462947a6 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -159,12 +159,6 @@ ENTRY(compat_sys_nanosleep_wrapper) llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call -ENTRY(sys32_getdents64_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # void * - llgfr %r4,%r4 # unsigned int - jg sys_getdents64 # branch to system call - ENTRY(compat_sys_fcntl64_wrapper) llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int @@ -175,60 +169,6 @@ ENTRY(sys32_stime_wrapper) llgtr %r2,%r2 # long * jg compat_sys_stime # branch to system call -ENTRY(sys32_getxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - jg sys_getxattr - -ENTRY(sys32_lgetxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - jg sys_lgetxattr - -ENTRY(sys32_fgetxattr_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # void * - llgfr %r5,%r5 # size_t - jg sys_fgetxattr - -ENTRY(sys32_listxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - jg sys_listxattr - -ENTRY(sys32_llistxattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - jg sys_llistxattr - -ENTRY(sys32_flistxattr_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - jg sys_flistxattr - -ENTRY(sys32_removexattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - jg sys_removexattr - -ENTRY(sys32_lremovexattr_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - jg sys_lremovexattr - -ENTRY(sys32_fremovexattr_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # char * - jg sys_fremovexattr - ENTRY(sys32_sched_setaffinity_wrapper) lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned int diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 053b2712fe28..cb6fc8abb707 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -228,22 +228,22 @@ SYSCALL(sys_setfsgid,sys_setfsgid,compat_sys_setfsgid) SYSCALL(sys_pivot_root,sys_pivot_root,compat_sys_pivot_root) SYSCALL(sys_mincore,sys_mincore,compat_sys_mincore) SYSCALL(sys_madvise,sys_madvise,compat_sys_madvise) -SYSCALL(sys_getdents64,sys_getdents64,sys32_getdents64_wrapper) /* 220 */ +SYSCALL(sys_getdents64,sys_getdents64,compat_sys_getdents64) /* 220 */ SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) SYSCALL(sys_readahead,sys_readahead,compat_sys_s390_readahead) SYSCALL(sys_sendfile64,sys_ni_syscall,compat_sys_sendfile64) SYSCALL(sys_setxattr,sys_setxattr,compat_sys_setxattr) SYSCALL(sys_lsetxattr,sys_lsetxattr,compat_sys_lsetxattr) /* 225 */ SYSCALL(sys_fsetxattr,sys_fsetxattr,compat_sys_fsetxattr) -SYSCALL(sys_getxattr,sys_getxattr,sys32_getxattr_wrapper) -SYSCALL(sys_lgetxattr,sys_lgetxattr,sys32_lgetxattr_wrapper) -SYSCALL(sys_fgetxattr,sys_fgetxattr,sys32_fgetxattr_wrapper) -SYSCALL(sys_listxattr,sys_listxattr,sys32_listxattr_wrapper) /* 230 */ -SYSCALL(sys_llistxattr,sys_llistxattr,sys32_llistxattr_wrapper) -SYSCALL(sys_flistxattr,sys_flistxattr,sys32_flistxattr_wrapper) -SYSCALL(sys_removexattr,sys_removexattr,sys32_removexattr_wrapper) -SYSCALL(sys_lremovexattr,sys_lremovexattr,sys32_lremovexattr_wrapper) -SYSCALL(sys_fremovexattr,sys_fremovexattr,sys32_fremovexattr_wrapper) /* 235 */ +SYSCALL(sys_getxattr,sys_getxattr,compat_sys_getxattr) +SYSCALL(sys_lgetxattr,sys_lgetxattr,compat_sys_lgetxattr) +SYSCALL(sys_fgetxattr,sys_fgetxattr,compat_sys_fgetxattr) +SYSCALL(sys_listxattr,sys_listxattr,compat_sys_listxattr) /* 230 */ +SYSCALL(sys_llistxattr,sys_llistxattr,compat_sys_llistxattr) +SYSCALL(sys_flistxattr,sys_flistxattr,compat_sys_flistxattr) +SYSCALL(sys_removexattr,sys_removexattr,compat_sys_removexattr) +SYSCALL(sys_lremovexattr,sys_lremovexattr,compat_sys_lremovexattr) +SYSCALL(sys_fremovexattr,sys_fremovexattr,compat_sys_fremovexattr) /* 235 */ SYSCALL(sys_gettid,sys_gettid,sys_gettid) SYSCALL(sys_tkill,sys_tkill,sys_tkill_wrapper) SYSCALL(sys_futex,sys_futex,compat_sys_futex) -- cgit v1.2.3-55-g7522 From 9c4d62fab4d29655a5ab198f3756693481a6b2da Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 28 Feb 2014 13:22:47 +0100 Subject: s390/compat: convert system call wrappers to C part 11 Signed-off-by: Heiko Carstens --- arch/s390/include/asm/compat.h | 1 + arch/s390/kernel/compat_wrap.c | 10 ++++++++ arch/s390/kernel/compat_wrapper.S | 48 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++++-------- 4 files changed, 21 insertions(+), 58 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 5d7e8cf83bd6..1174ea2b5e7c 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -65,6 +65,7 @@ typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; typedef s32 compat_key_t; typedef s32 compat_timer_t; +typedef u32 compat_aio_context_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 97197b8ab838..76d714e11370 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -124,3 +124,13 @@ COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, compat_size_t, si COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); +COMPAT_SYSCALL_WRAP1(exit_group, int, error_code); +COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr); +COMPAT_SYSCALL_WRAP1(epoll_create, int, size); +COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event); +COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout); +COMPAT_SYSCALL_WRAP1(timer_getoverrun, timer_t, timer_id); +COMPAT_SYSCALL_WRAP1(timer_delete, compat_timer_t, compat_timer_id); +COMPAT_SYSCALL_WRAP1(io_destroy, compat_aio_context_t, ctx); +COMPAT_SYSCALL_WRAP3(io_cancel, compat_aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); +COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index f23a462947a6..9ada8fbcb8cc 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -181,32 +181,6 @@ ENTRY(sys32_sched_getaffinity_wrapper) llgtr %r4,%r4 # unsigned long * jg compat_sys_sched_getaffinity -ENTRY(sys32_exit_group_wrapper) - lgfr %r2,%r2 # int - jg sys_exit_group # branch to system call - -ENTRY(sys32_set_tid_address_wrapper) - llgtr %r2,%r2 # int * - jg sys_set_tid_address # branch to system call - -ENTRY(sys_epoll_create_wrapper) - lgfr %r2,%r2 # int - jg sys_epoll_create # branch to system call - -ENTRY(sys_epoll_ctl_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - lgfr %r4,%r4 # int - llgtr %r5,%r5 # struct epoll_event * - jg sys_epoll_ctl # branch to system call - -ENTRY(sys_epoll_wait_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # struct epoll_event * - lgfr %r4,%r4 # int - lgfr %r5,%r5 # int - jg sys_epoll_wait # branch to system call - ENTRY(sys32_clock_settime_wrapper) lgfr %r2,%r2 # clockid_t (int) llgtr %r3,%r3 # struct compat_timespec * @@ -247,23 +221,11 @@ ENTRY(sys32_timer_gettime_wrapper) llgtr %r3,%r3 # struct compat_itimerspec * jg compat_sys_timer_gettime -ENTRY(sys32_timer_getoverrun_wrapper) - lgfr %r2,%r2 # timer_t (int) - jg sys_timer_getoverrun - -ENTRY(sys32_timer_delete_wrapper) - lgfr %r2,%r2 # timer_t (int) - jg sys_timer_delete - ENTRY(sys32_io_setup_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # u32 * jg compat_sys_io_setup -ENTRY(sys32_io_destroy_wrapper) - llgfr %r2,%r2 # (aio_context_t) u32 - jg sys_io_destroy - ENTRY(sys32_io_getevents_wrapper) llgfr %r2,%r2 # (aio_context_t) u32 lgfr %r3,%r3 # long @@ -278,12 +240,6 @@ ENTRY(sys32_io_submit_wrapper) llgtr %r4,%r4 # struct iocb ** jg compat_sys_io_submit -ENTRY(sys32_io_cancel_wrapper) - llgfr %r2,%r2 # (aio_context_t) u32 - llgtr %r3,%r3 # struct iocb * - llgtr %r4,%r4 # struct io_event * - jg sys_io_cancel - ENTRY(compat_sys_statfs64_wrapper) llgtr %r2,%r2 # const char * llgfr %r3,%r3 # compat_size_t @@ -303,10 +259,6 @@ ENTRY(compat_sys_mq_open_wrapper) llgtr %r5,%r5 # struct compat_mq_attr * jg compat_sys_mq_open -ENTRY(sys32_mq_unlink_wrapper) - llgtr %r2,%r2 # const char * - jg sys_mq_unlink - ENTRY(compat_sys_mq_timedsend_wrapper) lgfr %r2,%r2 # mqd_t llgtr %r3,%r3 # const char * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index cb6fc8abb707..927da9cb4d35 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -252,21 +252,21 @@ SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrap SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill_wrapper) NI_SYSCALL /* reserved for TUX */ SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper) -SYSCALL(sys_io_destroy,sys_io_destroy,sys32_io_destroy_wrapper) +SYSCALL(sys_io_destroy,sys_io_destroy,compat_sys_io_destroy) SYSCALL(sys_io_getevents,sys_io_getevents,sys32_io_getevents_wrapper) /* 245 */ SYSCALL(sys_io_submit,sys_io_submit,sys32_io_submit_wrapper) -SYSCALL(sys_io_cancel,sys_io_cancel,sys32_io_cancel_wrapper) -SYSCALL(sys_exit_group,sys_exit_group,sys32_exit_group_wrapper) -SYSCALL(sys_epoll_create,sys_epoll_create,sys_epoll_create_wrapper) -SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper) /* 250 */ -SYSCALL(sys_epoll_wait,sys_epoll_wait,sys_epoll_wait_wrapper) -SYSCALL(sys_set_tid_address,sys_set_tid_address,sys32_set_tid_address_wrapper) +SYSCALL(sys_io_cancel,sys_io_cancel,compat_sys_io_cancel) +SYSCALL(sys_exit_group,sys_exit_group,compat_sys_exit_group) +SYSCALL(sys_epoll_create,sys_epoll_create,compat_sys_epoll_create) +SYSCALL(sys_epoll_ctl,sys_epoll_ctl,compat_sys_epoll_ctl) /* 250 */ +SYSCALL(sys_epoll_wait,sys_epoll_wait,compat_sys_epoll_wait) +SYSCALL(sys_set_tid_address,sys_set_tid_address,compat_sys_set_tid_address) SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,compat_sys_s390_fadvise64) SYSCALL(sys_timer_create,sys_timer_create,sys32_timer_create_wrapper) SYSCALL(sys_timer_settime,sys_timer_settime,sys32_timer_settime_wrapper) /* 255 */ SYSCALL(sys_timer_gettime,sys_timer_gettime,sys32_timer_gettime_wrapper) -SYSCALL(sys_timer_getoverrun,sys_timer_getoverrun,sys32_timer_getoverrun_wrapper) -SYSCALL(sys_timer_delete,sys_timer_delete,sys32_timer_delete_wrapper) +SYSCALL(sys_timer_getoverrun,sys_timer_getoverrun,compat_sys_timer_getoverrun) +SYSCALL(sys_timer_delete,sys_timer_delete,compat_sys_timer_delete) SYSCALL(sys_clock_settime,sys_clock_settime,sys32_clock_settime_wrapper) SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */ SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) @@ -280,7 +280,7 @@ NI_SYSCALL /* 268 sys_mbind */ NI_SYSCALL /* 269 sys_get_mempolicy */ NI_SYSCALL /* 270 sys_set_mempolicy */ SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open_wrapper) -SYSCALL(sys_mq_unlink,sys_mq_unlink,sys32_mq_unlink_wrapper) +SYSCALL(sys_mq_unlink,sys_mq_unlink,compat_sys_mq_unlink) SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ -- cgit v1.2.3-55-g7522 From 20f7835c0e1836ba73516abac06725155d2149d2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 28 Feb 2014 13:46:09 +0100 Subject: s390/compat: convert system call wrappers to C part 12 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 ++++++ arch/s390/kernel/compat_wrapper.S | 66 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++------ 3 files changed, 20 insertions(+), 76 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 76d714e11370..a89daaf1e042 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -134,3 +134,13 @@ COMPAT_SYSCALL_WRAP1(timer_delete, compat_timer_t, compat_timer_id); COMPAT_SYSCALL_WRAP1(io_destroy, compat_aio_context_t, ctx); COMPAT_SYSCALL_WRAP3(io_cancel, compat_aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); +COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, compat_size_t, len, key_serial_t, id); +COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id); +COMPAT_SYSCALL_WRAP5(remap_file_pages, u32, start, u32, size, u32, prot, u32, pgoff, u32, flags); +COMPAT_SYSCALL_WRAP3(ioprio_set, int, which, int, who, int, ioprio); +COMPAT_SYSCALL_WRAP2(ioprio_get, int, which, int, who); +COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask); +COMPAT_SYSCALL_WRAP2(inotify_rm_watch, int, fd, __s32, wd); +COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); +COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, compat_uid_t, user, compat_gid_t, group, int, flag); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 9ada8fbcb8cc..74b81288a0c1 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -286,29 +286,6 @@ ENTRY(compat_sys_mq_getsetattr_wrapper) llgtr %r4,%r4 # struct compat_mq_attr * jg compat_sys_mq_getsetattr -ENTRY(compat_sys_add_key_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - llgtr %r4,%r4 # const void * - llgfr %r5,%r5 # size_t - llgfr %r6,%r6 # (key_serial_t) u32 - jg sys_add_key - -ENTRY(compat_sys_request_key_wrapper) - llgtr %r2,%r2 # const char * - llgtr %r3,%r3 # const char * - llgtr %r4,%r4 # const void * - llgfr %r5,%r5 # (key_serial_t) u32 - jg sys_request_key - -ENTRY(sys32_remap_file_pages_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # unsigned long - llgfr %r4,%r4 # unsigned long - llgfr %r5,%r5 # unsigned long - llgfr %r6,%r6 # unsigned long - jg sys_remap_file_pages - ENTRY(compat_sys_kexec_load_wrapper) llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # unsigned long @@ -316,49 +293,6 @@ ENTRY(compat_sys_kexec_load_wrapper) llgfr %r5,%r5 # unsigned long jg compat_sys_kexec_load -ENTRY(sys_ioprio_set_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - lgfr %r4,%r4 # int - jg sys_ioprio_set - -ENTRY(sys_ioprio_get_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_ioprio_get - -ENTRY(sys_inotify_add_watch_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # u32 - jg sys_inotify_add_watch - -ENTRY(sys_inotify_rm_watch_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # u32 - jg sys_inotify_rm_watch - -ENTRY(sys_mkdirat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - jg sys_mkdirat - -ENTRY(sys_mknodat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - llgfr %r5,%r5 # unsigned int - jg sys_mknodat - -ENTRY(sys_fchownat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # uid_t - llgfr %r5,%r5 # gid_t - lgfr %r6,%r6 # int - jg sys_fchownat - ENTRY(compat_sys_futimesat_wrapper) llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 927da9cb4d35..dbc9e4166a8e 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -275,7 +275,7 @@ NI_SYSCALL /* reserved for vserver */ SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,compat_sys_s390_fadvise64_64) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) -SYSCALL(sys_remap_file_pages,sys_remap_file_pages,sys32_remap_file_pages_wrapper) +SYSCALL(sys_remap_file_pages,sys_remap_file_pages,compat_sys_remap_file_pages) NI_SYSCALL /* 268 sys_mbind */ NI_SYSCALL /* 269 sys_get_mempolicy */ NI_SYSCALL /* 270 sys_set_mempolicy */ @@ -286,20 +286,20 @@ SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapp SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper) -SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) -SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) +SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key) +SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key) SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl_wrapper) /* 280 */ SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid) -SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper) -SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper) +SYSCALL(sys_ioprio_set,sys_ioprio_set,compat_sys_ioprio_set) +SYSCALL(sys_ioprio_get,sys_ioprio_get,compat_sys_ioprio_get) SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init) -SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper) /* 285 */ -SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper) +SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,compat_sys_inotify_add_watch) /* 285 */ +SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,compat_sys_inotify_rm_watch) NI_SYSCALL /* 287 sys_migrate_pages */ SYSCALL(sys_openat,sys_openat,compat_sys_openat) -SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper) -SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper) /* 290 */ -SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper) +SYSCALL(sys_mkdirat,sys_mkdirat,compat_sys_mkdirat) +SYSCALL(sys_mknodat,sys_mknodat,compat_sys_mknodat) /* 290 */ +SYSCALL(sys_fchownat,sys_fchownat,compat_sys_fchownat) SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) SYSCALL(sys_fstatat64,sys_newfstatat,compat_sys_s390_fstatat64) SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper) -- cgit v1.2.3-55-g7522 From 28798abc9c21087755a26e782868cde27801a1da Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 28 Feb 2014 15:33:00 +0100 Subject: s390/compat: convert system call wrappers to C part 13 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 ++++++ arch/s390/kernel/compat_wrapper.S | 67 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++------ 3 files changed, 20 insertions(+), 77 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index a89daaf1e042..df631af0900b 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -144,3 +144,13 @@ COMPAT_SYSCALL_WRAP2(inotify_rm_watch, int, fd, __s32, wd); COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, compat_uid_t, user, compat_gid_t, group, int, flag); +COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag); +COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname); +COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags); +COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname); +COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz); +COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode); +COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode); +COMPAT_SYSCALL_WRAP1(unshare, compat_ulong_t, unshare_flags); +COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, compat_size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, compat_size_t, len, unsigned int, flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 74b81288a0c1..583cac71df06 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -299,52 +299,6 @@ ENTRY(compat_sys_futimesat_wrapper) llgtr %r4,%r4 # struct timeval * jg compat_sys_futimesat -ENTRY(sys_unlinkat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - jg sys_unlinkat - -ENTRY(sys_renameat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - llgtr %r5,%r5 # const char * - jg sys_renameat - -ENTRY(sys_linkat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - llgtr %r5,%r5 # const char * - lgfr %r6,%r6 # int - jg sys_linkat - -ENTRY(sys_symlinkat_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - llgtr %r4,%r4 # const char * - jg sys_symlinkat - -ENTRY(sys_readlinkat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - llgtr %r4,%r4 # char * - lgfr %r5,%r5 # int - jg sys_readlinkat - -ENTRY(sys_fchmodat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # mode_t - jg sys_fchmodat - -ENTRY(sys_faccessat_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char * - lgfr %r4,%r4 # int - jg sys_faccessat - ENTRY(compat_sys_pselect6_wrapper) lgfr %r2,%r2 # int llgtr %r3,%r3 # fd_set * @@ -363,20 +317,6 @@ ENTRY(compat_sys_ppoll_wrapper) llgfr %r6,%r6 # size_t jg compat_sys_ppoll -ENTRY(sys_unshare_wrapper) - llgfr %r2,%r2 # unsigned long - jg sys_unshare - -ENTRY(sys_splice_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # loff_t * - lgfr %r4,%r4 # int - llgtr %r5,%r5 # loff_t * - llgfr %r6,%r6 # size_t - llgf %r0,164(%r15) # unsigned int - stg %r0,160(%r15) - jg sys_splice - ENTRY(sys_sync_file_range_wrapper) lgfr %r2,%r2 # int sllg %r3,%r3,32 # get high word of 64bit loff_t @@ -386,13 +326,6 @@ ENTRY(sys_sync_file_range_wrapper) llgf %r5,164(%r15) # unsigned int jg sys_sync_file_range -ENTRY(sys_tee_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - llgfr %r4,%r4 # size_t - llgfr %r5,%r5 # unsigned int - jg sys_tee - ENTRY(sys_getcpu_wrapper) llgtr %r2,%r2 # unsigned * llgtr %r3,%r3 # unsigned * diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index dbc9e4166a8e..7069bec56383 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -302,21 +302,21 @@ SYSCALL(sys_mknodat,sys_mknodat,compat_sys_mknodat) /* 290 */ SYSCALL(sys_fchownat,sys_fchownat,compat_sys_fchownat) SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) SYSCALL(sys_fstatat64,sys_newfstatat,compat_sys_s390_fstatat64) -SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper) -SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper) /* 295 */ -SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper) -SYSCALL(sys_symlinkat,sys_symlinkat,sys_symlinkat_wrapper) -SYSCALL(sys_readlinkat,sys_readlinkat,sys_readlinkat_wrapper) -SYSCALL(sys_fchmodat,sys_fchmodat,sys_fchmodat_wrapper) -SYSCALL(sys_faccessat,sys_faccessat,sys_faccessat_wrapper) /* 300 */ +SYSCALL(sys_unlinkat,sys_unlinkat,compat_sys_unlinkat) +SYSCALL(sys_renameat,sys_renameat,compat_sys_renameat) /* 295 */ +SYSCALL(sys_linkat,sys_linkat,compat_sys_linkat) +SYSCALL(sys_symlinkat,sys_symlinkat,compat_sys_symlinkat) +SYSCALL(sys_readlinkat,sys_readlinkat,compat_sys_readlinkat) +SYSCALL(sys_fchmodat,sys_fchmodat,compat_sys_fchmodat) +SYSCALL(sys_faccessat,sys_faccessat,compat_sys_faccessat) /* 300 */ SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper) SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper) -SYSCALL(sys_unshare,sys_unshare,sys_unshare_wrapper) +SYSCALL(sys_unshare,sys_unshare,compat_sys_unshare) SYSCALL(sys_set_robust_list,sys_set_robust_list,compat_sys_set_robust_list) SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list) -SYSCALL(sys_splice,sys_splice,sys_splice_wrapper) +SYSCALL(sys_splice,sys_splice,compat_sys_splice) SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper) -SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) +SYSCALL(sys_tee,sys_tee,compat_sys_tee) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) -- cgit v1.2.3-55-g7522 From 7f6afe87a02be1d889b36ce076d7beddd4cd5332 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 1 Mar 2014 11:52:48 +0100 Subject: s390/compat: convert system call wrappers to C part 14 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 10 ++++++++ arch/s390/kernel/compat_wrapper.S | 50 --------------------------------------- arch/s390/kernel/syscalls.S | 20 ++++++++-------- 3 files changed, 20 insertions(+), 60 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index df631af0900b..7b7c9f698d7f 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -154,3 +154,13 @@ COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mo COMPAT_SYSCALL_WRAP1(unshare, compat_ulong_t, unshare_flags); COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, compat_size_t, len, unsigned int, flags); COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, compat_size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache); +COMPAT_SYSCALL_WRAP1(eventfd, unsigned int, count); +COMPAT_SYSCALL_WRAP2(timerfd_create, int, clockid, int, flags); +COMPAT_SYSCALL_WRAP2(eventfd2, unsigned int, count, int, flags); +COMPAT_SYSCALL_WRAP1(inotify_init1, int, flags); +COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags); +COMPAT_SYSCALL_WRAP3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags); +COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); +COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); +COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 583cac71df06..d17bc862be3f 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -326,12 +326,6 @@ ENTRY(sys_sync_file_range_wrapper) llgf %r5,164(%r15) # unsigned int jg sys_sync_file_range -ENTRY(sys_getcpu_wrapper) - llgtr %r2,%r2 # unsigned * - llgtr %r3,%r3 # unsigned * - llgtr %r4,%r4 # struct getcpu_cache * - jg sys_getcpu - ENTRY(compat_sys_utimes_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_timeval * @@ -344,10 +338,6 @@ ENTRY(compat_sys_utimensat_wrapper) lgfr %r5,%r5 # int jg compat_sys_utimensat -ENTRY(sys_eventfd_wrapper) - llgfr %r2,%r2 # unsigned int - jg sys_eventfd - ENTRY(sys_fallocate_wrapper) lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -357,46 +347,6 @@ ENTRY(sys_fallocate_wrapper) l %r5,164(%r15) # get low word of 64bit loff_t jg sys_fallocate -ENTRY(sys_timerfd_create_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_timerfd_create - -ENTRY(sys_eventfd2_wrapper) - llgfr %r2,%r2 # unsigned int - lgfr %r3,%r3 # int - jg sys_eventfd2 - -ENTRY(sys_inotify_init1_wrapper) - lgfr %r2,%r2 # int - jg sys_inotify_init1 - -ENTRY(sys_pipe2_wrapper) - llgtr %r2,%r2 # u32 * - lgfr %r3,%r3 # int - jg sys_pipe2 # branch to system call - -ENTRY(sys_dup3_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - lgfr %r4,%r4 # int - jg sys_dup3 # branch to system call - -ENTRY(sys_epoll_create1_wrapper) - lgfr %r2,%r2 # int - jg sys_epoll_create1 # branch to system call - -ENTRY(sys_tkill_wrapper) - lgfr %r2,%r2 # pid_t - lgfr %r3,%r3 # int - jg sys_tkill # branch to system call - -ENTRY(sys_tgkill_wrapper) - lgfr %r2,%r2 # pid_t - lgfr %r3,%r3 # pid_t - lgfr %r4,%r4 # int - jg sys_tgkill # branch to system call - ENTRY(compat_sys_keyctl_wrapper) llgfr %r2,%r2 # u32 llgfr %r3,%r3 # u32 diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 7069bec56383..5cfbd427ce13 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -245,11 +245,11 @@ SYSCALL(sys_removexattr,sys_removexattr,compat_sys_removexattr) SYSCALL(sys_lremovexattr,sys_lremovexattr,compat_sys_lremovexattr) SYSCALL(sys_fremovexattr,sys_fremovexattr,compat_sys_fremovexattr) /* 235 */ SYSCALL(sys_gettid,sys_gettid,sys_gettid) -SYSCALL(sys_tkill,sys_tkill,sys_tkill_wrapper) +SYSCALL(sys_tkill,sys_tkill,compat_sys_tkill) SYSCALL(sys_futex,sys_futex,compat_sys_futex) SYSCALL(sys_sched_setaffinity,sys_sched_setaffinity,sys32_sched_setaffinity_wrapper) SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrapper) /* 240 */ -SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill_wrapper) +SYSCALL(sys_tgkill,sys_tgkill,compat_sys_tgkill) NI_SYSCALL /* reserved for TUX */ SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper) SYSCALL(sys_io_destroy,sys_io_destroy,compat_sys_io_destroy) @@ -319,23 +319,23 @@ SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper) SYSCALL(sys_tee,sys_tee,compat_sys_tee) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice) NI_SYSCALL /* 310 sys_move_pages */ -SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) +SYSCALL(sys_getcpu,sys_getcpu,compat_sys_getcpu) SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait) SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) SYSCALL(sys_s390_fallocate,sys_fallocate,sys_fallocate_wrapper) SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd) NI_SYSCALL /* 317 old sys_timer_fd */ -SYSCALL(sys_eventfd,sys_eventfd,sys_eventfd_wrapper) -SYSCALL(sys_timerfd_create,sys_timerfd_create,sys_timerfd_create_wrapper) +SYSCALL(sys_eventfd,sys_eventfd,compat_sys_eventfd) +SYSCALL(sys_timerfd_create,sys_timerfd_create,compat_sys_timerfd_create) SYSCALL(sys_timerfd_settime,sys_timerfd_settime,compat_sys_timerfd_settime) /* 320 */ SYSCALL(sys_timerfd_gettime,sys_timerfd_gettime,compat_sys_timerfd_gettime) SYSCALL(sys_signalfd4,sys_signalfd4,compat_sys_signalfd4) -SYSCALL(sys_eventfd2,sys_eventfd2,sys_eventfd2_wrapper) -SYSCALL(sys_inotify_init1,sys_inotify_init1,sys_inotify_init1_wrapper) -SYSCALL(sys_pipe2,sys_pipe2,sys_pipe2_wrapper) /* 325 */ -SYSCALL(sys_dup3,sys_dup3,sys_dup3_wrapper) -SYSCALL(sys_epoll_create1,sys_epoll_create1,sys_epoll_create1_wrapper) +SYSCALL(sys_eventfd2,sys_eventfd2,compat_sys_eventfd2) +SYSCALL(sys_inotify_init1,sys_inotify_init1,compat_sys_inotify_init1) +SYSCALL(sys_pipe2,sys_pipe2,compat_sys_pipe2) /* 325 */ +SYSCALL(sys_dup3,sys_dup3,compat_sys_dup3) +SYSCALL(sys_epoll_create1,sys_epoll_create1,compat_sys_epoll_create1) SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv) SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev) SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo) /* 330 */ -- cgit v1.2.3-55-g7522 From 00fcb1494f645be4e0cd703756448fc64ca2a44a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 1 Mar 2014 12:18:46 +0100 Subject: s390/compat: convert system call wrappers to C part 15 Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 12 +++++++ arch/s390/kernel/compat_wrapper.S | 74 --------------------------------------- arch/s390/kernel/entry.h | 1 + arch/s390/kernel/syscalls.S | 24 ++++++------- 4 files changed, 25 insertions(+), 86 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 7b7c9f698d7f..17600b15ae3a 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -164,3 +164,15 @@ COMPAT_SYSCALL_WRAP3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); +COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, u32, flags); +COMPAT_SYSCALL_WRAP5(clone, u32, newsp, u32, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); +COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); +COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); +COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); +COMPAT_SYSCALL_WRAP1(syncfs, int, fd); +COMPAT_SYSCALL_WRAP2(setns, int, fd, int, nstype); +COMPAT_SYSCALL_WRAP2(s390_runtime_instr, int, command, int, signum); +COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, u32, idx1, u32, idx2); +COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); +COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index d17bc862be3f..a1a13671922a 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -355,61 +355,17 @@ ENTRY(compat_sys_keyctl_wrapper) llgfr %r6,%r6 # u32 jg compat_sys_keyctl # branch to system call -ENTRY(sys_perf_event_open_wrapper) - llgtr %r2,%r2 # const struct perf_event_attr * - lgfr %r3,%r3 # pid_t - lgfr %r4,%r4 # int - lgfr %r5,%r5 # int - llgfr %r6,%r6 # unsigned long - jg sys_perf_event_open # branch to system call - -ENTRY(sys_clone_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # unsigned long - llgtr %r4,%r4 # int * - llgtr %r5,%r5 # int * - jg sys_clone # branch to system call - ENTRY(sys32_execve_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # compat_uptr_t * llgtr %r4,%r4 # compat_uptr_t * jg compat_sys_execve # branch to system call -ENTRY(sys_fanotify_init_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - jg sys_fanotify_init # branch to system call - -ENTRY(sys_prlimit64_wrapper) - lgfr %r2,%r2 # pid_t - llgfr %r3,%r3 # unsigned int - llgtr %r4,%r4 # const struct rlimit64 __user * - llgtr %r5,%r5 # struct rlimit64 __user * - jg sys_prlimit64 # branch to system call - -ENTRY(sys_name_to_handle_at_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char __user * - llgtr %r4,%r4 # struct file_handle __user * - llgtr %r5,%r5 # int __user * - lgfr %r6,%r6 # int - jg sys_name_to_handle_at - ENTRY(compat_sys_clock_adjtime_wrapper) lgfr %r2,%r2 # clockid_t (int) llgtr %r3,%r3 # struct compat_timex __user * jg compat_sys_clock_adjtime -ENTRY(sys_syncfs_wrapper) - lgfr %r2,%r2 # int - jg sys_syncfs - -ENTRY(sys_setns_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_setns - ENTRY(compat_sys_process_vm_readv_wrapper) lgfr %r2,%r2 # compat_pid_t llgtr %r3,%r3 # struct compat_iovec __user * @@ -429,33 +385,3 @@ ENTRY(compat_sys_process_vm_writev_wrapper) llgf %r0,164(%r15) # unsigned long stg %r0,160(%r15) jg compat_sys_process_vm_writev - -ENTRY(sys_s390_runtime_instr_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - jg sys_s390_runtime_instr - -ENTRY(sys_kcmp_wrapper) - lgfr %r2,%r2 # pid_t - lgfr %r3,%r3 # pid_t - lgfr %r4,%r4 # int - llgfr %r5,%r5 # unsigned long - llgfr %r6,%r6 # unsigned long - jg sys_kcmp - -ENTRY(sys_finit_module_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const char __user * - lgfr %r4,%r4 # int - jg sys_finit_module - -ENTRY(sys_sched_setattr_wrapper) - lgfr %r2,%r2 # pid_t - llgtr %r3,%r3 # struct sched_attr __user * - jg sys_sched_setattr - -ENTRY(sys_sched_getattr_wrapper) - lgfr %r2,%r2 # pid_t - llgtr %r3,%r3 # const char __user * - llgfr %r4,%r4 # unsigned int - jg sys_sched_getattr diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 8c6c022aeb71..e9167889ff1a 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -73,5 +73,6 @@ long sys32_sigreturn(void); long sys32_rt_sigreturn(void); long sys_s390_personality(unsigned int personality); +long sys_s390_runtime_instr(int command, int signum); #endif /* _ENTRY_H */ diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 5cfbd427ce13..3ad73a6f6159 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -128,7 +128,7 @@ SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) SYSCALL(sys_s390_ipc,sys_s390_ipc,compat_sys_s390_ipc) SYSCALL(sys_fsync,sys_fsync,compat_sys_fsync) SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) -SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */ +SYSCALL(sys_clone,sys_clone,compat_sys_clone) /* 120 */ SYSCALL(sys_setdomainname,sys_setdomainname,compat_sys_setdomainname) SYSCALL(sys_newuname,sys_newuname,compat_sys_newuname) NI_SYSCALL /* modify_ldt for i386 */ @@ -339,19 +339,19 @@ SYSCALL(sys_epoll_create1,sys_epoll_create1,compat_sys_epoll_create1) SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv) SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev) SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo) /* 330 */ -SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper) -SYSCALL(sys_fanotify_init,sys_fanotify_init,sys_fanotify_init_wrapper) +SYSCALL(sys_perf_event_open,sys_perf_event_open,compat_sys_perf_event_open) +SYSCALL(sys_fanotify_init,sys_fanotify_init,compat_sys_fanotify_init) SYSCALL(sys_fanotify_mark,sys_fanotify_mark,compat_sys_fanotify_mark) -SYSCALL(sys_prlimit64,sys_prlimit64,sys_prlimit64_wrapper) -SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,sys_name_to_handle_at_wrapper) /* 335 */ +SYSCALL(sys_prlimit64,sys_prlimit64,compat_sys_prlimit64) +SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,compat_sys_name_to_handle_at) /* 335 */ SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at) SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) -SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper) -SYSCALL(sys_setns,sys_setns,sys_setns_wrapper) +SYSCALL(sys_syncfs,sys_syncfs,compat_sys_syncfs) +SYSCALL(sys_setns,sys_setns,compat_sys_setns) SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */ SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper) -SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) -SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) -SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) -SYSCALL(sys_sched_setattr,sys_sched_setattr,sys_sched_setattr_wrapper) /* 345 */ -SYSCALL(sys_sched_getattr,sys_sched_getattr,sys_sched_getattr_wrapper) +SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,compat_sys_s390_runtime_instr) +SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp) +SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module) +SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */ +SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr) -- cgit v1.2.3-55-g7522 From 2c81fc4fb41f589454861bbdb90ffde73840b8f8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 1 Mar 2014 13:09:26 +0100 Subject: s390/compat: add sync_file_range and fallocate compat syscalls The compat syscall wrappers for sync_file_range and fallocate merged 32 bit parameters into 64 bit parameters. Therefore they did more than just the usual zero and/or sign extension of system call parameters. So convert these two wrappers to full s390 specific compat sytem calls. Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 14 ++++++++++++++ arch/s390/kernel/compat_linux.h | 3 +++ arch/s390/kernel/compat_wrapper.S | 18 ------------------ arch/s390/kernel/syscalls.S | 4 ++-- 4 files changed, 19 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 59097741f509..ca38139423ae 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -504,3 +504,17 @@ COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, arg a.advice = POSIX_FADV_NOREUSE; return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } + +COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, + u32, nhigh, u32, nlow, unsigned int, flags) +{ + return sys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow, + ((u64)nhigh << 32) + nlow, flags); +} + +COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow, + u32, lenhigh, u32, lenlow) +{ + return sys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow, + ((u64)lenhigh << 32) + lenlow); +} diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 7d2ce4bb84a6..330e11d164d7 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -110,4 +110,7 @@ long compat_sys_s390_read(unsigned int fd, char __user * buf, compat_size_t coun long compat_sys_s390_write(unsigned int fd, const char __user * buf, compat_size_t count); long compat_sys_s390_fadvise64(int fd, u32 high, u32 low, compat_size_t len, int advise); long compat_sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); +long compat_sys_s390_sync_file_range(int fd, u32 offhigh, u32 offlow, u32 nhigh, u32 nlow, unsigned int flags); +long compat_sys_s390_fallocate(int fd, int mode, u32 offhigh, u32 offlow, u32 lenhigh, u32 lenlow); + #endif /* _ASM_S390X_S390_H */ diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index a1a13671922a..23d9f8a7c6f5 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -317,15 +317,6 @@ ENTRY(compat_sys_ppoll_wrapper) llgfr %r6,%r6 # size_t jg compat_sys_ppoll -ENTRY(sys_sync_file_range_wrapper) - lgfr %r2,%r2 # int - sllg %r3,%r3,32 # get high word of 64bit loff_t - or %r3,%r4 # get low word of 64bit loff_t - sllg %r4,%r5,32 # get high word of 64bit loff_t - or %r4,%r6 # get low word of 64bit loff_t - llgf %r5,164(%r15) # unsigned int - jg sys_sync_file_range - ENTRY(compat_sys_utimes_wrapper) llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_timeval * @@ -338,15 +329,6 @@ ENTRY(compat_sys_utimensat_wrapper) lgfr %r5,%r5 # int jg compat_sys_utimensat -ENTRY(sys_fallocate_wrapper) - lgfr %r2,%r2 # int - lgfr %r3,%r3 # int - sllg %r4,%r4,32 # get high word of 64bit loff_t - lr %r4,%r5 # get low word of 64bit loff_t - sllg %r5,%r6,32 # get high word of 64bit loff_t - l %r5,164(%r15) # get low word of 64bit loff_t - jg sys_fallocate - ENTRY(compat_sys_keyctl_wrapper) llgfr %r2,%r2 # u32 llgfr %r3,%r3 # u32 diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 3ad73a6f6159..dbdec47e935a 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -315,14 +315,14 @@ SYSCALL(sys_unshare,sys_unshare,compat_sys_unshare) SYSCALL(sys_set_robust_list,sys_set_robust_list,compat_sys_set_robust_list) SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list) SYSCALL(sys_splice,sys_splice,compat_sys_splice) -SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper) +SYSCALL(sys_sync_file_range,sys_sync_file_range,compat_sys_s390_sync_file_range) SYSCALL(sys_tee,sys_tee,compat_sys_tee) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,compat_sys_getcpu) SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait) SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) -SYSCALL(sys_s390_fallocate,sys_fallocate,sys_fallocate_wrapper) +SYSCALL(sys_s390_fallocate,sys_fallocate,compat_sys_s390_fallocate) SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd) NI_SYSCALL /* 317 old sys_timer_fd */ -- cgit v1.2.3-55-g7522 From 28964d32d495a0753986d464c48c8e1ae73699be Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 3 Mar 2014 07:34:45 +0000 Subject: arm64: add AT_HWCAP2 support for 32-bit compat Add support for the ELF auxv entry AT_HWCAP2 when running 32-bit ELF binaries in compat mode. Signed-off-by: Ard Biesheuvel Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/hwcap.h | 3 ++- arch/arm64/kernel/setup.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index 6cddbb0c9f54..9a4cbd60c88e 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -41,7 +41,8 @@ #ifdef CONFIG_COMPAT #define COMPAT_ELF_HWCAP (compat_elf_hwcap) -extern unsigned int compat_elf_hwcap; +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) +extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; #endif extern unsigned long elf_hwcap; diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index c8e9effe52e1..349c49260f09 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -69,6 +69,7 @@ EXPORT_SYMBOL_GPL(elf_hwcap); COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV) unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT; +unsigned int compat_elf_hwcap2 __read_mostly; #endif static const char *cpu_name; -- cgit v1.2.3-55-g7522 From 4cf761cdccc3b050f768f25dc36342cdfec4efdd Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 3 Mar 2014 07:34:46 +0000 Subject: arm64: advertise ARMv8 extensions to 32-bit compat ELF binaries This adds support for advertising the presence of ARMv8 Crypto Extensions in the Aarch32 execution state to 32-bit ELF binaries running in 32-bit compat mode under the arm64 kernel. Signed-off-by: Ard Biesheuvel Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/hwcap.h | 6 ++++++ arch/arm64/kernel/setup.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index 9a4cbd60c88e..024c46183c3c 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -32,6 +32,12 @@ #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT) #define COMPAT_HWCAP_EVTSTRM (1 << 21) +#define COMPAT_HWCAP2_AES (1 << 0) +#define COMPAT_HWCAP2_PMULL (1 << 1) +#define COMPAT_HWCAP2_SHA1 (1 << 2) +#define COMPAT_HWCAP2_SHA2 (1 << 3) +#define COMPAT_HWCAP2_CRC32 (1 << 4) + #ifndef __ASSEMBLY__ /* * This yields a mask that user programs can use to figure out what diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 349c49260f09..67da30741a1b 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -243,6 +243,38 @@ static void __init setup_processor(void) block = (features >> 16) & 0xf; if (block && !(block & 0x8)) elf_hwcap |= HWCAP_CRC32; + +#ifdef CONFIG_COMPAT + /* + * ID_ISAR5_EL1 carries similar information as above, but pertaining to + * the Aarch32 32-bit execution state. + */ + features = read_cpuid(ID_ISAR5_EL1); + block = (features >> 4) & 0xf; + if (!(block & 0x8)) { + switch (block) { + default: + case 2: + compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL; + case 1: + compat_elf_hwcap2 |= COMPAT_HWCAP2_AES; + case 0: + break; + } + } + + block = (features >> 8) & 0xf; + if (block && !(block & 0x8)) + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1; + + block = (features >> 12) & 0xf; + if (block && !(block & 0x8)) + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2; + + block = (features >> 16) & 0xf; + if (block && !(block & 0x8)) + compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32; +#endif } static void __init setup_machine_fdt(phys_addr_t dt_phys) -- cgit v1.2.3-55-g7522 From ab4f8bba19323eb78b7473df42b225eb14090fcc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 1 Mar 2014 13:45:03 +0100 Subject: s390/compat: automatic zero, sign and pointer conversion of syscalls Instead of explicitly changing compat system call parameters from e.g. unsigned long to compat_ulong_t let the COMPAT_SYSCALL_WRAP macros automatically detect (unsigned) long parameters and zero and sign extend them automatically. The resulting binary is completely identical. In addition add a sys_[system call name] prototype for each system call wrapper. This will cause compile errors if the prototype does not match the prototype in include/linux/syscall.h. Therefore we should now always get the correct zero and sign extension of system call parameters. Pointers are handled like before. Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 134 +++++++++++++++++++++++------------------ include/linux/syscalls.h | 2 + 2 files changed, 77 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index 17600b15ae3a..d6a2cac1af12 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -15,11 +15,27 @@ #define COMPAT_SYSCALL_WRAP6(name, ...) \ COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) +#define __SC_COMPAT_CAST(t, a) \ +({ \ + long __ReS = a; \ + \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + if (__TYPE_IS_L(t)) \ + __ReS = (s32)a; \ + if (__TYPE_IS_UL(t)) \ + __ReS = (u32)a; \ + if (__TYPE_IS_PTR(t)) \ + __ReS = a & 0x7fffffff; \ + (t)__ReS; \ +}) + #define COMPAT_SYSCALL_WRAPx(x, name, ...) \ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ { \ - return sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ + return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ } COMPAT_SYSCALL_WRAP1(exit, int, error_code); @@ -40,22 +56,22 @@ COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname); COMPAT_SYSCALL_WRAP1(dup, unsigned int, fildes); COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes); -COMPAT_SYSCALL_WRAP1(brk, compat_ulong_t, brk); +COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); -COMPAT_SYSCALL_WRAP2(setpgid, compat_pid_t, pid, compat_pid_t, pgid); +COMPAT_SYSCALL_WRAP2(setpgid, pid_t, pid, pid_t, pgid); COMPAT_SYSCALL_WRAP1(umask, int, mask); COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename); COMPAT_SYSCALL_WRAP2(dup2, unsigned int, oldfd, unsigned int, newfd); -COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, compat_old_sigset_t, mask); +COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask); COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len); COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new); COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg); -COMPAT_SYSCALL_WRAP2(munmap, compat_ulong_t, addr, compat_size_t, len); +COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len); COMPAT_SYSCALL_WRAP2(fchmod, unsigned int, fd, umode_t, mode); COMPAT_SYSCALL_WRAP2(getpriority, int, which, int, who); COMPAT_SYSCALL_WRAP3(setpriority, int, which, int, who, int, niceval); @@ -64,63 +80,63 @@ COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); COMPAT_SYSCALL_WRAP1(fsync, unsigned int, fd); COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); -COMPAT_SYSCALL_WRAP3(mprotect, compat_ulong_t, start, compat_size_t, len, compat_ulong_t, prot); -COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, compat_ulong_t, len, const char __user *, uargs); +COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot); +COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs); COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags); COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr); -COMPAT_SYSCALL_WRAP1(getpgid, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP1(getpgid, pid_t, pid); COMPAT_SYSCALL_WRAP1(fchdir, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(bdflush, int, func, compat_long_t, data); -COMPAT_SYSCALL_WRAP3(sysfs, int, option, compat_ulong_t, arg1, compat_ulong_t, arg2); +COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data); +COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2); COMPAT_SYSCALL_WRAP1(s390_personality, unsigned int, personality); -COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, u32, high, u32, low, loff_t __user *, result, unsigned int, whence); +COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence); COMPAT_SYSCALL_WRAP2(flock, unsigned int, fd, unsigned int, cmd); -COMPAT_SYSCALL_WRAP3(msync, compat_ulong_t, start, compat_size_t, len, int, flags); -COMPAT_SYSCALL_WRAP1(getsid, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags); +COMPAT_SYSCALL_WRAP1(getsid, pid_t, pid); COMPAT_SYSCALL_WRAP1(fdatasync, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(mlock, compat_ulong_t, start, compat_size_t, len); -COMPAT_SYSCALL_WRAP2(munlock, compat_ulong_t, start, compat_size_t, len); +COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len); +COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len); COMPAT_SYSCALL_WRAP1(mlockall, int, flags); -COMPAT_SYSCALL_WRAP2(sched_setparam, compat_pid_t, pid, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP2(sched_getparam, compat_pid_t, pid, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP3(sched_setscheduler, compat_pid_t, pid, int, policy, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP1(sched_getscheduler, compat_pid_t, pid); +COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP1(sched_getscheduler, pid_t, pid); COMPAT_SYSCALL_WRAP1(sched_get_priority_max, int, policy); COMPAT_SYSCALL_WRAP1(sched_get_priority_min, int, policy); -COMPAT_SYSCALL_WRAP5(mremap, u32, addr, u32, old_len, u32, new_len, u32, flags, u32, new_addr); +COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr); COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout); -COMPAT_SYSCALL_WRAP5(prctl, int, option, u32, arg2, u32, arg3, u32, arg4, u32, arg5); -COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, u32, size); +COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5); +COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size); COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); -COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); -COMPAT_SYSCALL_WRAP2(setreuid, compat_uid_t, ruid, compat_uid_t, euid); -COMPAT_SYSCALL_WRAP2(setregid, compat_gid_t, rgid, compat_gid_t, egid); -COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, compat_gid_t __user *, grouplist); -COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, compat_gid_t __user *, grouplist); -COMPAT_SYSCALL_WRAP3(fchown, unsigned int, fd, compat_uid_t, user, compat_gid_t, group); -COMPAT_SYSCALL_WRAP3(setresuid, compat_uid_t, ruid, compat_uid_t, euid, compat_uid_t, suid); -COMPAT_SYSCALL_WRAP3(getresuid, compat_uid_t __user *, ruid, compat_uid_t __user *, euid, compat_uid_t __user *, suid); -COMPAT_SYSCALL_WRAP3(setresgid, compat_gid_t, rgid, compat_gid_t, egid, compat_gid_t, sgid); -COMPAT_SYSCALL_WRAP3(getresgid, compat_gid_t __user *, rgid, compat_gid_t __user *, egid, compat_gid_t __user *, sgid); -COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, compat_uid_t, user, compat_gid_t, group); -COMPAT_SYSCALL_WRAP1(setuid, compat_uid_t, uid); -COMPAT_SYSCALL_WRAP1(setgid, compat_gid_t, gid); -COMPAT_SYSCALL_WRAP1(setfsuid, compat_uid_t, uid); -COMPAT_SYSCALL_WRAP1(setfsgid, compat_gid_t, gid); +COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP2(setreuid, uid_t, ruid, uid_t, euid); +COMPAT_SYSCALL_WRAP2(setregid, gid_t, rgid, gid_t, egid); +COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP3(fchown, unsigned int, fd, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid); +COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid); +COMPAT_SYSCALL_WRAP3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid); +COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid); +COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP1(setuid, uid_t, uid); +COMPAT_SYSCALL_WRAP1(setgid, gid_t, gid); +COMPAT_SYSCALL_WRAP1(setfsuid, uid_t, uid); +COMPAT_SYSCALL_WRAP1(setfsgid, gid_t, gid); COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old); -COMPAT_SYSCALL_WRAP3(mincore, compat_ulong_t, start, compat_size_t, len, unsigned char __user *, vec); -COMPAT_SYSCALL_WRAP3(madvise, compat_ulong_t, start, compat_size_t, len, int, behavior); -COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); -COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); -COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, compat_size_t, size, int, flags); +COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec); +COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior); +COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags); COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count); -COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, compat_size_t, size); -COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, compat_size_t, size); -COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, compat_size_t, size); -COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, compat_size_t, size); -COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, compat_size_t, size); -COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, compat_size_t, size); +COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size); +COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size); +COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size); COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); @@ -131,19 +147,19 @@ COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout); COMPAT_SYSCALL_WRAP1(timer_getoverrun, timer_t, timer_id); COMPAT_SYSCALL_WRAP1(timer_delete, compat_timer_t, compat_timer_id); -COMPAT_SYSCALL_WRAP1(io_destroy, compat_aio_context_t, ctx); -COMPAT_SYSCALL_WRAP3(io_cancel, compat_aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); +COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx); +COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); -COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, compat_size_t, len, key_serial_t, id); +COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id); COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id); -COMPAT_SYSCALL_WRAP5(remap_file_pages, u32, start, u32, size, u32, prot, u32, pgoff, u32, flags); +COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags); COMPAT_SYSCALL_WRAP3(ioprio_set, int, which, int, who, int, ioprio); COMPAT_SYSCALL_WRAP2(ioprio_get, int, which, int, who); COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask); COMPAT_SYSCALL_WRAP2(inotify_rm_watch, int, fd, __s32, wd); COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); -COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, compat_uid_t, user, compat_gid_t, group, int, flag); +COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag); COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag); COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname); COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags); @@ -151,9 +167,9 @@ COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz); COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode); COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode); -COMPAT_SYSCALL_WRAP1(unshare, compat_ulong_t, unshare_flags); -COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, compat_size_t, len, unsigned int, flags); -COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, compat_size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags); +COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags); COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache); COMPAT_SYSCALL_WRAP1(eventfd, unsigned int, count); COMPAT_SYSCALL_WRAP2(timerfd_create, int, clockid, int, flags); @@ -164,15 +180,15 @@ COMPAT_SYSCALL_WRAP3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); -COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, u32, flags); -COMPAT_SYSCALL_WRAP5(clone, u32, newsp, u32, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); +COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); +COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); COMPAT_SYSCALL_WRAP1(syncfs, int, fd); COMPAT_SYSCALL_WRAP2(setns, int, fd, int, nstype); COMPAT_SYSCALL_WRAP2(s390_runtime_instr, int, command, int, signum); -COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, u32, idx1, u32, idx2); +COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2); COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a747a77ea584..1e67b7a5968c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -98,6 +98,8 @@ struct sigaltstack; #define __MAP(n,...) __MAP##n(__VA_ARGS__) #define __SC_DECL(t, a) t a +#define __TYPE_IS_L(t) (__same_type((t)0, 0L)) +#define __TYPE_IS_UL(t) (__same_type((t)0, 0UL)) #define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) #define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a #define __SC_CAST(t, a) (t) a -- cgit v1.2.3-55-g7522 From c2e7c3d0ef0d1a3765792a35ae9e6f91a3025214 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 3 Mar 2014 10:06:12 +0100 Subject: s390/compat: partial parameter conversion within syscall wrappers Parameter conversion within the system call wrappers is only needed for parameters which differ in size and have a size of eight bytes on 64 bit. For system call parameters with a size of less than eight byte the called system call itself will perform parameter conversion anyway. So we can save the double conversion of e.g. int parameters. The only types which need to be converted are therefore pointer and (unsigned) long parameters. Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrap.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c index d6a2cac1af12..d123f5d87b82 100644 --- a/arch/s390/kernel/compat_wrap.c +++ b/arch/s390/kernel/compat_wrap.c @@ -15,6 +15,9 @@ #define COMPAT_SYSCALL_WRAP6(name, ...) \ COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a + #define __SC_COMPAT_CAST(t, a) \ ({ \ long __ReS = a; \ @@ -30,10 +33,22 @@ (t)__ReS; \ }) +/* + * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of the upper + * 33 bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ #define COMPAT_SYSCALL_WRAPx(x, name, ...) \ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ - asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ - asmlinkage long compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ { \ return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ } -- cgit v1.2.3-55-g7522 From f6e763b93a6cd3411fd8df925344022719bcba62 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 4 Mar 2014 07:51:17 +0000 Subject: arm64: topology: Implement basic CPU topology support Add basic CPU topology support to arm64, based on the existing pre-v8 code and some work done by Mark Hambleton. This patch does not implement any topology discovery support since that should be based on information from firmware, it merely implements the scaffolding for integration of topology support in the architecture. No locking of the topology data is done since it is only modified during CPU bringup with external serialisation from the SMP code. The goal is to separate the architecture hookup for providing topology information from the DT parsing in order to ease review and avoid blocking the architecture code (which will be built on by other work) with the DT code review by providing something simple and basic. Following patches will implement support for interpreting topology information from MPIDR and for parsing the DT topology bindings for ARM, similar patches will be needed for ACPI. Signed-off-by: Mark Brown Acked-by: Mark Rutland [catalin.marinas@arm.com: removed CONFIG_CPU_TOPOLOGY, always on if SMP] Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 16 +++++++ arch/arm64/include/asm/topology.h | 39 ++++++++++++++++ arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/smp.c | 11 +++++ arch/arm64/kernel/topology.c | 95 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/topology.h create mode 100644 arch/arm64/kernel/topology.c (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c2056ca04ae2..140cd1a9dc0c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -165,6 +165,22 @@ config SMP If you don't know what to do here, say N. +config SCHED_MC + bool "Multi-core scheduler support" + depends on SMP + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + +config SCHED_SMT + bool "SMT scheduler support" + depends on SMP + help + Improves the CPU scheduler's decision making when dealing with + MultiThreading at a cost of slightly increased overhead in some + places. If unsure say N here. + config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h new file mode 100644 index 000000000000..0172e6d76bf3 --- /dev/null +++ b/arch/arm64/include/asm/topology.h @@ -0,0 +1,39 @@ +#ifndef __ASM_TOPOLOGY_H +#define __ASM_TOPOLOGY_H + +#ifdef CONFIG_SMP + +#include + +struct cpu_topology { + int thread_id; + int core_id; + int cluster_id; + cpumask_t thread_sibling; + cpumask_t core_sibling; +}; + +extern struct cpu_topology cpu_topology[NR_CPUS]; + +#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id) +#define topology_core_id(cpu) (cpu_topology[cpu].core_id) +#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling) +#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling) + +#define mc_capable() (cpu_topology[0].cluster_id != -1) +#define smt_capable() (cpu_topology[0].thread_id != -1) + +void init_cpu_topology(void); +void store_cpu_topology(unsigned int cpuid); +const struct cpumask *cpu_coregroup_mask(int cpu); + +#else + +static inline void init_cpu_topology(void) { } +static inline void store_cpu_topology(unsigned int cpuid) { } + +#endif + +#include + +#endif /* _ASM_ARM_TOPOLOGY_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index e52bcdc6f097..cfee8273fccb 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -14,7 +14,7 @@ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ sys_compat.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o -arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o +arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 5070dc3b65d2..f0a141dd5655 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -114,6 +114,11 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) return ret; } +static void smp_store_cpu_info(unsigned int cpuid) +{ + store_cpu_topology(cpuid); +} + /* * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. @@ -152,6 +157,8 @@ asmlinkage void secondary_start_kernel(void) */ notify_cpu_starting(cpu); + smp_store_cpu_info(cpu); + /* * OK, now it's safe to let the boot CPU continue. Wait for * the CPU migration code to notice that the CPU is online @@ -391,6 +398,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) int err; unsigned int cpu, ncores = num_possible_cpus(); + init_cpu_topology(); + + smp_store_cpu_info(smp_processor_id()); + /* * are we trying to boot more cores than exist? */ diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c new file mode 100644 index 000000000000..3e06b0be4ec8 --- /dev/null +++ b/arch/arm64/kernel/topology.c @@ -0,0 +1,95 @@ +/* + * arch/arm64/kernel/topology.c + * + * Copyright (C) 2011,2013,2014 Linaro Limited. + * + * Based on the arm32 version written by Vincent Guittot in turn based on + * arch/sh/kernel/topology.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * cpu topology table + */ +struct cpu_topology cpu_topology[NR_CPUS]; +EXPORT_SYMBOL_GPL(cpu_topology); + +const struct cpumask *cpu_coregroup_mask(int cpu) +{ + return &cpu_topology[cpu].core_sibling; +} + +static void update_siblings_masks(unsigned int cpuid) +{ + struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; + int cpu; + + if (cpuid_topo->cluster_id == -1) { + /* + * DT does not contain topology information for this cpu + * reset it to default behaviour + */ + pr_debug("CPU%u: No topology information configured\n", cpuid); + cpuid_topo->core_id = 0; + cpumask_set_cpu(cpuid, &cpuid_topo->core_sibling); + cpumask_set_cpu(cpuid, &cpuid_topo->thread_sibling); + return; + } + + /* update core and thread sibling masks */ + for_each_possible_cpu(cpu) { + cpu_topo = &cpu_topology[cpu]; + + if (cpuid_topo->cluster_id != cpu_topo->cluster_id) + continue; + + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); + + if (cpuid_topo->core_id != cpu_topo->core_id) + continue; + + cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling); + } +} + +void store_cpu_topology(unsigned int cpuid) +{ + update_siblings_masks(cpuid); +} + +/* + * init_cpu_topology is called at boot when only one cpu is running + * which prevent simultaneous write access to cpu_topology array + */ +void __init init_cpu_topology(void) +{ + unsigned int cpu; + + /* init core mask and power*/ + for_each_possible_cpu(cpu) { + struct cpu_topology *cpu_topo = &cpu_topology[cpu]; + + cpu_topo->thread_id = -1; + cpu_topo->core_id = -1; + cpu_topo->cluster_id = -1; + cpumask_clear(&cpu_topo->core_sibling); + cpumask_clear(&cpu_topo->thread_sibling); + } +} -- cgit v1.2.3-55-g7522 From a5f6ea29f9a918403629f8369ae55fac6b09cb53 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 3 Mar 2014 15:38:33 -0800 Subject: sh: prefix sh-specific "CCR" and "CCR2" by "SH_" Commit bcf24e1daa94 ("mmc: omap_hsmmc: use the generic config for omap2plus devices"), enabled the build for other platforms for compile testing. sh-allmodconfig now fails with: include/linux/omap-dma.h:171:8: error: expected identifier before numeric constant make[4]: *** [drivers/mmc/host/omap_hsmmc.o] Error 1 This happens because SuperH #defines "CCR", which is one of the enum values in include/linux/omap-dma.h. There's a similar issue with "CCR2" on sh2a. As "CCR" and "CCR2" are too generic names for global #defines, prefix them with "SH_" to fix this. Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/include/cpu-sh2/cpu/cache.h | 2 +- arch/sh/include/cpu-sh2a/cpu/cache.h | 4 ++-- arch/sh/include/cpu-sh3/cpu/cache.h | 2 +- arch/sh/include/cpu-sh4/cpu/cache.h | 2 +- arch/sh/kernel/cpu/init.c | 4 ++-- arch/sh/mm/cache-debugfs.c | 2 +- arch/sh/mm/cache-sh2.c | 4 ++-- arch/sh/mm/cache-sh2a.c | 6 ++++-- arch/sh/mm/cache-sh4.c | 4 ++-- arch/sh/mm/cache-shx3.c | 4 ++-- arch/sh/mm/cache.c | 4 ++-- 11 files changed, 20 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sh/include/cpu-sh2/cpu/cache.h b/arch/sh/include/cpu-sh2/cpu/cache.h index 673515bc4135..aa1b2b9088a7 100644 --- a/arch/sh/include/cpu-sh2/cpu/cache.h +++ b/arch/sh/include/cpu-sh2/cpu/cache.h @@ -18,7 +18,7 @@ #define SH_CACHE_ASSOC 8 #if defined(CONFIG_CPU_SUBTYPE_SH7619) -#define CCR 0xffffffec +#define SH_CCR 0xffffffec #define CCR_CACHE_CE 0x01 /* Cache enable */ #define CCR_CACHE_WT 0x02 /* CCR[bit1=1,bit2=1] */ diff --git a/arch/sh/include/cpu-sh2a/cpu/cache.h b/arch/sh/include/cpu-sh2a/cpu/cache.h index defb0baa5a06..b27ce92cb600 100644 --- a/arch/sh/include/cpu-sh2a/cpu/cache.h +++ b/arch/sh/include/cpu-sh2a/cpu/cache.h @@ -17,8 +17,8 @@ #define SH_CACHE_COMBINED 4 #define SH_CACHE_ASSOC 8 -#define CCR 0xfffc1000 /* CCR1 */ -#define CCR2 0xfffc1004 +#define SH_CCR 0xfffc1000 /* CCR1 */ +#define SH_CCR2 0xfffc1004 /* * Most of the SH-2A CCR1 definitions resemble the SH-4 ones. All others not diff --git a/arch/sh/include/cpu-sh3/cpu/cache.h b/arch/sh/include/cpu-sh3/cpu/cache.h index bee2d81c56bf..29700fd88c75 100644 --- a/arch/sh/include/cpu-sh3/cpu/cache.h +++ b/arch/sh/include/cpu-sh3/cpu/cache.h @@ -17,7 +17,7 @@ #define SH_CACHE_COMBINED 4 #define SH_CACHE_ASSOC 8 -#define CCR 0xffffffec /* Address of Cache Control Register */ +#define SH_CCR 0xffffffec /* Address of Cache Control Register */ #define CCR_CACHE_CE 0x01 /* Cache Enable */ #define CCR_CACHE_WT 0x02 /* Write-Through (for P0,U0,P3) (else writeback) */ diff --git a/arch/sh/include/cpu-sh4/cpu/cache.h b/arch/sh/include/cpu-sh4/cpu/cache.h index 7bfb9e8b069c..92c4cd119b66 100644 --- a/arch/sh/include/cpu-sh4/cpu/cache.h +++ b/arch/sh/include/cpu-sh4/cpu/cache.h @@ -17,7 +17,7 @@ #define SH_CACHE_COMBINED 4 #define SH_CACHE_ASSOC 8 -#define CCR 0xff00001c /* Address of Cache Control Register */ +#define SH_CCR 0xff00001c /* Address of Cache Control Register */ #define CCR_CACHE_OCE 0x0001 /* Operand Cache Enable */ #define CCR_CACHE_WT 0x0002 /* Write-Through (for P0,U0,P3) (else writeback)*/ #define CCR_CACHE_CB 0x0004 /* Copy-Back (for P1) (else writethrough) */ diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index ecf83cd158dc..0d7360d549c1 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -112,7 +112,7 @@ static void cache_init(void) unsigned long ccr, flags; jump_to_uncached(); - ccr = __raw_readl(CCR); + ccr = __raw_readl(SH_CCR); /* * At this point we don't know whether the cache is enabled or not - a @@ -189,7 +189,7 @@ static void cache_init(void) l2_cache_init(); - __raw_writel(flags, CCR); + __raw_writel(flags, SH_CCR); back_to_cached(); } #else diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 115725198038..777e50f33c00 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -36,7 +36,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) */ jump_to_uncached(); - ccr = __raw_readl(CCR); + ccr = __raw_readl(SH_CCR); if ((ccr & CCR_CACHE_ENABLE) == 0) { back_to_cached(); diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c index defcf719f2e8..a74259f2f981 100644 --- a/arch/sh/mm/cache-sh2.c +++ b/arch/sh/mm/cache-sh2.c @@ -63,9 +63,9 @@ static void sh2__flush_invalidate_region(void *start, int size) local_irq_save(flags); jump_to_uncached(); - ccr = __raw_readl(CCR); + ccr = __raw_readl(SH_CCR); ccr |= CCR_CACHE_INVALIDATE; - __raw_writel(ccr, CCR); + __raw_writel(ccr, SH_CCR); back_to_cached(); local_irq_restore(flags); diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c index 949e2d3138a0..ee87d081259b 100644 --- a/arch/sh/mm/cache-sh2a.c +++ b/arch/sh/mm/cache-sh2a.c @@ -134,7 +134,8 @@ static void sh2a__flush_invalidate_region(void *start, int size) /* If there are too many pages then just blow the cache */ if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) { - __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR); + __raw_writel(__raw_readl(SH_CCR) | CCR_OCACHE_INVALIDATE, + SH_CCR); } else { for (v = begin; v < end; v += L1_CACHE_BYTES) sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v); @@ -167,7 +168,8 @@ static void sh2a_flush_icache_range(void *args) /* I-Cache invalidate */ /* If there are too many pages then just blow the cache */ if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) { - __raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR); + __raw_writel(__raw_readl(SH_CCR) | CCR_ICACHE_INVALIDATE, + SH_CCR); } else { for (v = start; v < end; v += L1_CACHE_BYTES) sh2a_invalidate_line(CACHE_IC_ADDRESS_ARRAY, v); diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 0e529285b28d..51d8f7f31d1d 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -133,9 +133,9 @@ static void flush_icache_all(void) jump_to_uncached(); /* Flush I-cache */ - ccr = __raw_readl(CCR); + ccr = __raw_readl(SH_CCR); ccr |= CCR_CACHE_ICI; - __raw_writel(ccr, CCR); + __raw_writel(ccr, SH_CCR); /* * back_to_cached() will take care of the barrier for us, don't add diff --git a/arch/sh/mm/cache-shx3.c b/arch/sh/mm/cache-shx3.c index c0adbee97b5f..24c58b7dc022 100644 --- a/arch/sh/mm/cache-shx3.c +++ b/arch/sh/mm/cache-shx3.c @@ -19,7 +19,7 @@ void __init shx3_cache_init(void) { unsigned int ccr; - ccr = __raw_readl(CCR); + ccr = __raw_readl(SH_CCR); /* * If we've got cache aliases, resolve them in hardware. @@ -40,5 +40,5 @@ void __init shx3_cache_init(void) ccr |= CCR_CACHE_IBE; #endif - writel_uncached(ccr, CCR); + writel_uncached(ccr, SH_CCR); } diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 616966a96cba..097c2cdd117f 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -285,8 +285,8 @@ void __init cpu_cache_init(void) { unsigned int cache_disabled = 0; -#ifdef CCR - cache_disabled = !(__raw_readl(CCR) & CCR_CACHE_ENABLE); +#ifdef SH_CCR + cache_disabled = !(__raw_readl(SH_CCR) & CCR_CACHE_ENABLE); #endif compute_alias(&boot_cpu_data.icache); -- cgit v1.2.3-55-g7522 From 3e909599215456928e6b42a04f11c2517881570b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 15 Jan 2014 13:21:22 +0000 Subject: efi: Move facility flags to struct efi As we grow support for more EFI architectures they're going to want the ability to query which EFI features are available on the running system. Instead of storing this information in an architecture-specific place, stick it in the global 'struct efi', which is already the central location for EFI state. While we're at it, let's change the return value of efi_enabled() to be bool and replace all references to 'facility' with 'feature', which is the usual word used to describe the attributes of the running system. Signed-off-by: Matt Fleming --- arch/x86/include/asm/efi.h | 1 - arch/x86/kernel/setup.c | 6 +++--- arch/x86/platform/efi/efi.c | 21 +++++---------------- include/linux/efi.h | 18 +++++++++++++----- 4 files changed, 21 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 3d6b9f81cc68..a7a8bd89024e 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -119,7 +119,6 @@ extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, #endif /* CONFIG_X86_32 */ extern int add_efi_memmap; -extern unsigned long x86_efi_facility; extern struct efi_scratch efi_scratch; extern void efi_set_executable(efi_memory_desc_t *md, bool executable); extern int efi_memblock_x86_reserve_range(void); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 06853e670354..3b5d278b7d5b 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -926,11 +926,11 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_EFI if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, "EL32", 4)) { - set_bit(EFI_BOOT, &x86_efi_facility); + set_bit(EFI_BOOT, &efi.flags); } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, "EL64", 4)) { - set_bit(EFI_BOOT, &x86_efi_facility); - set_bit(EFI_64BIT, &x86_efi_facility); + set_bit(EFI_BOOT, &efi.flags); + set_bit(EFI_64BIT, &efi.flags); } if (efi_enabled(EFI_BOOT)) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 1a201ac7cef8..821562984452 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -67,8 +67,6 @@ struct efi_memory_map memmap; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -unsigned long x86_efi_facility; - static __initdata efi_config_table_type_t arch_tables[] = { #ifdef CONFIG_X86_UV {UV_SYSTEM_TABLE_GUID, "UVsystab", &efi.uv_systab}, @@ -78,15 +76,6 @@ static __initdata efi_config_table_type_t arch_tables[] = { u64 efi_setup; /* efi setup_data physical address */ -/* - * Returns 1 if 'facility' is enabled, 0 otherwise. - */ -int efi_enabled(int facility) -{ - return test_bit(facility, &x86_efi_facility) != 0; -} -EXPORT_SYMBOL(efi_enabled); - static bool __initdata disable_runtime = false; static int __init setup_noefi(char *arg) { @@ -455,7 +444,7 @@ void __init efi_reserve_boot_services(void) void __init efi_unmap_memmap(void) { - clear_bit(EFI_MEMMAP, &x86_efi_facility); + clear_bit(EFI_MEMMAP, &efi.flags); if (memmap.map) { early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); memmap.map = NULL; @@ -722,7 +711,7 @@ void __init efi_init(void) if (efi_systab_init(efi_phys.systab)) return; - set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); + set_bit(EFI_SYSTEM_TABLES, &efi.flags); efi.config_table = (unsigned long)efi.systab->tables; efi.fw_vendor = (unsigned long)efi.systab->fw_vendor; @@ -750,7 +739,7 @@ void __init efi_init(void) if (efi_config_init(arch_tables)) return; - set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); + set_bit(EFI_CONFIG_TABLES, &efi.flags); /* * Note: We currently don't support runtime services on an EFI @@ -762,12 +751,12 @@ void __init efi_init(void) else { if (disable_runtime || efi_runtime_init()) return; - set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility); + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); } if (efi_memmap_init()) return; - set_bit(EFI_MEMMAP, &x86_efi_facility); + set_bit(EFI_MEMMAP, &efi.flags); print_efi_memmap(); } diff --git a/include/linux/efi.h b/include/linux/efi.h index 0a819e7a60c9..214833b4a97d 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -573,6 +573,7 @@ extern struct efi { efi_reset_system_t *reset_system; efi_set_virtual_address_map_t *set_virtual_address_map; struct efi_memory_map *memmap; + unsigned long flags; } efi; static inline int @@ -660,17 +661,24 @@ extern int __init efi_setup_pcdp_console(char *); #ifdef CONFIG_EFI # ifdef CONFIG_X86 -extern int efi_enabled(int facility); + +/* + * Test whether the above EFI_* bits are enabled. + */ +static inline bool efi_enabled(int feature) +{ + return test_bit(feature, &efi.flags) != 0; +} # else -static inline int efi_enabled(int facility) +static inline bool efi_enabled(int feature) { - return 1; + return true; } # endif #else -static inline int efi_enabled(int facility) +static inline bool efi_enabled(int feature) { - return 0; + return false; } #endif -- cgit v1.2.3-55-g7522 From 0f8093a92da77afe24fd258a5a1037bb2b97a870 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 15 Jan 2014 13:36:33 +0000 Subject: efi: Set feature flags inside feature init functions It makes more sense to set the feature flag in the success path of the detection function than it does to rely on the caller doing it. Apart from it being more logical to group the code and data together, it sets a much better example for new EFI architectures. Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 11 +++++++---- drivers/firmware/efi/efi.c | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 821562984452..541e7db26c15 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -577,6 +577,8 @@ static int __init efi_systab_init(void *phys) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff); + set_bit(EFI_SYSTEM_TABLES, &efi.flags); + return 0; } @@ -612,6 +614,8 @@ static int __init efi_runtime_init(void) efi.get_time = phys_efi_get_time; early_iounmap(runtime, sizeof(efi_runtime_services_t)); + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return 0; } @@ -629,6 +633,8 @@ static int __init efi_memmap_init(void) if (add_efi_memmap) do_add_efi_memmap(); + set_bit(EFI_MEMMAP, &efi.flags); + return 0; } @@ -739,8 +745,6 @@ void __init efi_init(void) if (efi_config_init(arch_tables)) return; - set_bit(EFI_CONFIG_TABLES, &efi.flags); - /* * Note: We currently don't support runtime services on an EFI * that doesn't match the kernel 32/64-bit mode. @@ -751,7 +755,6 @@ void __init efi_init(void) else { if (disable_runtime || efi_runtime_init()) return; - set_bit(EFI_RUNTIME_SERVICES, &efi.flags); } if (efi_memmap_init()) return; @@ -1194,7 +1197,7 @@ static int __init parse_efi_cmdline(char *str) str++; if (!strncmp(str, "old_map", 7)) - set_bit(EFI_OLD_MEMMAP, &x86_efi_facility); + set_bit(EFI_OLD_MEMMAP, &efi.flags); return 0; } diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 4753bac65279..b25b36b1ef23 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -313,5 +313,8 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) } pr_cont("\n"); early_iounmap(config_tables, efi.systab->nr_tables * sz); + + set_bit(EFI_CONFIG_TABLES, &efi.flags); + return 0; } -- cgit v1.2.3-55-g7522 From 5db80c65140c6502d5c2345d0b0fa166eecedc61 Mon Sep 17 00:00:00 2001 From: Madper Xie Date: Sun, 10 Nov 2013 22:15:11 +0800 Subject: x86/efi: Delete out-of-date comments of efi_query_variable_store For now we only ensure about 5kb free space for avoiding our board refusing boot. But the comment lies that we retain 50% space. Signed-off-by: Madper Xie Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 541e7db26c15..dc1dd6d09dec 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -1110,9 +1110,8 @@ u64 efi_mem_attributes(unsigned long phys_addr) } /* - * Some firmware has serious problems when using more than 50% of the EFI - * variable store, i.e. it triggers bugs that can brick machines. Ensure that - * we never use more than this safe limit. + * Some firmware implementations refuse to boot if there's insufficient space + * in the variable store. Ensure that we never use more than a safe limit. * * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable * store. @@ -1131,10 +1130,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) return status; /* - * Some firmware implementations refuse to boot if there's insufficient - * space in the variable store. We account for that by refusing the - * write if permitting it would reduce the available space to under - * 5KB. This figure was provided by Samsung, so should be safe. + * We account for that by refusing the write if permitting it would + * reduce the available space to under 5KB. This figure was provided by + * Samsung, so should be safe. */ if ((remaining_size - size < EFI_MIN_RESERVE) && !efi_no_storage_paranoia) { -- cgit v1.2.3-55-g7522 From 9b7d204982cf6e4e5b9b0f8bff151e48250cce58 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 3 Jan 2014 16:08:48 -0800 Subject: x86/efi: Style neatening Coalesce formats and remove spaces before tabs. Move __initdata after the variable declaration. Signed-off-by: Joe Perches Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index dc1dd6d09dec..876dc5b9e4a3 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -67,7 +67,7 @@ struct efi_memory_map memmap; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -static __initdata efi_config_table_type_t arch_tables[] = { +static efi_config_table_type_t arch_tables[] __initdata = { #ifdef CONFIG_X86_UV {UV_SYSTEM_TABLE_GUID, "UVsystab", &efi.uv_systab}, #endif @@ -76,7 +76,7 @@ static __initdata efi_config_table_type_t arch_tables[] = { u64 efi_setup; /* efi setup_data physical address */ -static bool __initdata disable_runtime = false; +static bool disable_runtime __initdata = false; static int __init setup_noefi(char *arg) { disable_runtime = true; @@ -263,9 +263,9 @@ static efi_status_t __init phys_efi_get_time(efi_time_t *tm, int efi_set_rtc_mmss(const struct timespec *now) { unsigned long nowtime = now->tv_sec; - efi_status_t status; - efi_time_t eft; - efi_time_cap_t cap; + efi_status_t status; + efi_time_t eft; + efi_time_cap_t cap; struct rtc_time tm; status = efi.get_time(&eft, &cap); @@ -283,9 +283,8 @@ int efi_set_rtc_mmss(const struct timespec *now) eft.second = tm.tm_sec; eft.nanosecond = 0; } else { - printk(KERN_ERR - "%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n", - __FUNCTION__, nowtime); + pr_err("%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n", + __func__, nowtime); return -1; } @@ -401,8 +400,7 @@ static void __init print_efi_memmap(void) p < memmap.map_end; p += memmap.desc_size, i++) { md = p; - pr_info("mem%02u: type=%u, attr=0x%llx, " - "range=[0x%016llx-0x%016llx) (%lluMB)\n", + pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n", i, md->type, md->attribute, md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), (md->num_pages >> (20 - EFI_PAGE_SHIFT))); @@ -434,9 +432,8 @@ void __init efi_reserve_boot_services(void) memblock_is_region_reserved(start, size)) { /* Could not reserve, skip it */ md->num_pages = 0; - memblock_dbg("Could not reserve boot range " - "[0x%010llx-0x%010llx]\n", - start, start+size-1); + memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", + start, start+size-1); } else memblock_reserve(start, size); } @@ -572,8 +569,7 @@ static int __init efi_systab_init(void *phys) return -EINVAL; } if ((efi.systab->hdr.revision >> 16) == 0) - pr_err("Warning: System table version " - "%d.%02d, expected 1.00 or greater!\n", + pr_err("Warning: System table version %d.%02d, expected 1.00 or greater!\n", efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff); -- cgit v1.2.3-55-g7522 From ef6bea6ddf0e76077d0798e57b374015b23a837e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 18 Jan 2014 12:48:14 +0100 Subject: x86, ptdump: Add the functionality to dump an arbitrary pagetable With reusing the ->trampoline_pgd page table for mapping EFI regions in order to use them after having switched to EFI virtual mode, it is very useful to be able to dump aforementioned page table in dmesg. This adds that functionality through the walk_pgd_level() interface which can be called from somewhere else. The original functionality of dumping to debugfs remains untouched. Cc: Arjan van de Ven Signed-off-by: Borislav Petkov Tested-by: Toshi Kani Signed-off-by: Matt Fleming --- arch/x86/include/asm/pgtable.h | 3 +- arch/x86/mm/dump_pagetables.c | 84 +++++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5ad38ad07890..938ef1d0458e 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -15,9 +15,10 @@ : (prot)) #ifndef __ASSEMBLY__ - #include +void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd); + /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index 0002a3a33081..20621d753d5f 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c @@ -30,6 +30,7 @@ struct pg_state { unsigned long start_address; unsigned long current_address; const struct addr_marker *marker; + bool to_dmesg; }; struct addr_marker { @@ -88,10 +89,28 @@ static struct addr_marker address_markers[] = { #define PUD_LEVEL_MULT (PTRS_PER_PMD * PMD_LEVEL_MULT) #define PGD_LEVEL_MULT (PTRS_PER_PUD * PUD_LEVEL_MULT) +#define pt_dump_seq_printf(m, to_dmesg, fmt, args...) \ +({ \ + if (to_dmesg) \ + printk(KERN_INFO fmt, ##args); \ + else \ + if (m) \ + seq_printf(m, fmt, ##args); \ +}) + +#define pt_dump_cont_printf(m, to_dmesg, fmt, args...) \ +({ \ + if (to_dmesg) \ + printk(KERN_CONT fmt, ##args); \ + else \ + if (m) \ + seq_printf(m, fmt, ##args); \ +}) + /* * Print a readable form of a pgprot_t to the seq_file */ -static void printk_prot(struct seq_file *m, pgprot_t prot, int level) +static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg) { pgprotval_t pr = pgprot_val(prot); static const char * const level_name[] = @@ -99,47 +118,47 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level) if (!pgprot_val(prot)) { /* Not present */ - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); } else { if (pr & _PAGE_USER) - seq_printf(m, "USR "); + pt_dump_cont_printf(m, dmsg, "USR "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); if (pr & _PAGE_RW) - seq_printf(m, "RW "); + pt_dump_cont_printf(m, dmsg, "RW "); else - seq_printf(m, "ro "); + pt_dump_cont_printf(m, dmsg, "ro "); if (pr & _PAGE_PWT) - seq_printf(m, "PWT "); + pt_dump_cont_printf(m, dmsg, "PWT "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); if (pr & _PAGE_PCD) - seq_printf(m, "PCD "); + pt_dump_cont_printf(m, dmsg, "PCD "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); /* Bit 9 has a different meaning on level 3 vs 4 */ if (level <= 3) { if (pr & _PAGE_PSE) - seq_printf(m, "PSE "); + pt_dump_cont_printf(m, dmsg, "PSE "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); } else { if (pr & _PAGE_PAT) - seq_printf(m, "pat "); + pt_dump_cont_printf(m, dmsg, "pat "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); } if (pr & _PAGE_GLOBAL) - seq_printf(m, "GLB "); + pt_dump_cont_printf(m, dmsg, "GLB "); else - seq_printf(m, " "); + pt_dump_cont_printf(m, dmsg, " "); if (pr & _PAGE_NX) - seq_printf(m, "NX "); + pt_dump_cont_printf(m, dmsg, "NX "); else - seq_printf(m, "x "); + pt_dump_cont_printf(m, dmsg, "x "); } - seq_printf(m, "%s\n", level_name[level]); + pt_dump_cont_printf(m, dmsg, "%s\n", level_name[level]); } /* @@ -178,7 +197,8 @@ static void note_page(struct seq_file *m, struct pg_state *st, st->current_prot = new_prot; st->level = level; st->marker = address_markers; - seq_printf(m, "---[ %s ]---\n", st->marker->name); + pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n", + st->marker->name); } else if (prot != cur || level != st->level || st->current_address >= st->marker[1].start_address) { const char *unit = units; @@ -188,17 +208,17 @@ static void note_page(struct seq_file *m, struct pg_state *st, /* * Now print the actual finished series */ - seq_printf(m, "0x%0*lx-0x%0*lx ", - width, st->start_address, - width, st->current_address); + pt_dump_seq_printf(m, st->to_dmesg, "0x%0*lx-0x%0*lx ", + width, st->start_address, + width, st->current_address); delta = (st->current_address - st->start_address) >> 10; while (!(delta & 1023) && unit[1]) { delta >>= 10; unit++; } - seq_printf(m, "%9lu%c ", delta, *unit); - printk_prot(m, st->current_prot, st->level); + pt_dump_cont_printf(m, st->to_dmesg, "%9lu%c ", delta, *unit); + printk_prot(m, st->current_prot, st->level, st->to_dmesg); /* * We print markers for special areas of address space, @@ -207,7 +227,8 @@ static void note_page(struct seq_file *m, struct pg_state *st, */ if (st->current_address >= st->marker[1].start_address) { st->marker++; - seq_printf(m, "---[ %s ]---\n", st->marker->name); + pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n", + st->marker->name); } st->start_address = st->current_address; @@ -296,7 +317,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr, #define pgd_none(a) pud_none(__pud(pgd_val(a))) #endif -static void walk_pgd_level(struct seq_file *m) +void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd) { #ifdef CONFIG_X86_64 pgd_t *start = (pgd_t *) &init_level4_pgt; @@ -304,9 +325,12 @@ static void walk_pgd_level(struct seq_file *m) pgd_t *start = swapper_pg_dir; #endif int i; - struct pg_state st; + struct pg_state st = {}; - memset(&st, 0, sizeof(st)); + if (pgd) { + start = pgd; + st.to_dmesg = true; + } for (i = 0; i < PTRS_PER_PGD; i++) { st.current_address = normalize_addr(i * PGD_LEVEL_MULT); @@ -331,7 +355,7 @@ static void walk_pgd_level(struct seq_file *m) static int ptdump_show(struct seq_file *m, void *v) { - walk_pgd_level(m); + ptdump_walk_pgd_level(m, NULL); return 0; } -- cgit v1.2.3-55-g7522 From 11cc851254b4bc3bd4430be8db2a41469303a427 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 18 Jan 2014 12:48:15 +0100 Subject: x86/efi: Dump the EFI page table This is very useful for debugging issues with the recently added pagetable switching code for EFI virtual mode. Signed-off-by: Borislav Petkov Tested-by: Toshi Kani Signed-off-by: Matt Fleming --- arch/x86/Kconfig.debug | 9 +++++++++ arch/x86/include/asm/efi.h | 1 + arch/x86/platform/efi/efi.c | 1 + arch/x86/platform/efi/efi_32.c | 1 + arch/x86/platform/efi/efi_64.c | 9 +++++++++ 5 files changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 321a52ccf63a..61bd2ad94281 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -81,6 +81,15 @@ config X86_PTDUMP kernel. If in doubt, say "N" +config EFI_PGT_DUMP + bool "Dump the EFI pagetable" + depends on EFI && X86_PTDUMP + ---help--- + Enable this if you want to dump the EFI page table before + enabling virtual mode. This can be used to debug miscellaneous + issues with the mapping of the EFI runtime regions into that + table. + config DEBUG_RODATA bool "Write protect kernel read-only data structures" default y diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index a7a8bd89024e..4afd3b3b658f 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -133,6 +133,7 @@ extern void efi_setup_page_tables(void); extern void __init old_map_region(efi_memory_desc_t *md); extern void __init runtime_code_page_mkexec(void); extern void __init efi_runtime_mkexec(void); +extern void __init efi_dump_pagetable(void); struct efi_setup_data { u64 fw_vendor; diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 876dc5b9e4a3..37f20d71ec4b 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -1021,6 +1021,7 @@ void __init efi_enter_virtual_mode(void) efi_setup_page_tables(); efi_sync_low_kernel_mappings(); + efi_dump_pagetable(); if (!efi_setup) { status = phys_efi_set_virtual_address_map( diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 0b74cdf7f816..39496ae3928a 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -41,6 +41,7 @@ static unsigned long efi_rt_eflags; void efi_sync_low_kernel_mappings(void) {} void efi_setup_page_tables(void) {} +void __init efi_dump_pagetable(void) {} void __init efi_map_region(efi_memory_desc_t *md) { diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 0c2a234fef1e..e05c69b46f05 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -242,3 +242,12 @@ void __init efi_runtime_mkexec(void) if (__supported_pte_mask & _PAGE_NX) runtime_code_page_mkexec(); } + +void __init efi_dump_pagetable(void) +{ +#ifdef CONFIG_EFI_PGT_DUMP + pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); + + ptdump_walk_pgd_level(NULL, pgd); +#endif +} -- cgit v1.2.3-55-g7522 From 42a5477251f0e0f33ad5f6a95c48d685ec03191e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 18 Jan 2014 12:48:16 +0100 Subject: x86, pageattr: Export page unmapping interface We will use it in efi so expose it. Signed-off-by: Borislav Petkov Tested-by: Toshi Kani Signed-off-by: Matt Fleming --- arch/x86/include/asm/pgtable_types.h | 2 ++ arch/x86/mm/pageattr.c | 44 +++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 1aa9ccd43223..94e40f1efdfd 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -385,6 +385,8 @@ extern pte_t *lookup_address(unsigned long address, unsigned int *level); extern phys_addr_t slow_virt_to_phys(void *__address); extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address, unsigned numpages, unsigned long page_flags); +void kernel_unmap_pages_in_pgd(pgd_t *root, unsigned long address, + unsigned numpages); #endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_PGTABLE_DEFS_H */ diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index b3b19f46c016..a3488689e301 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -692,6 +692,18 @@ static bool try_to_free_pmd_page(pmd_t *pmd) return true; } +static bool try_to_free_pud_page(pud_t *pud) +{ + int i; + + for (i = 0; i < PTRS_PER_PUD; i++) + if (!pud_none(pud[i])) + return false; + + free_page((unsigned long)pud); + return true; +} + static bool unmap_pte_range(pmd_t *pmd, unsigned long start, unsigned long end) { pte_t *pte = pte_offset_kernel(pmd, start); @@ -805,6 +817,16 @@ static void unmap_pud_range(pgd_t *pgd, unsigned long start, unsigned long end) */ } +static void unmap_pgd_range(pgd_t *root, unsigned long addr, unsigned long end) +{ + pgd_t *pgd_entry = root + pgd_index(addr); + + unmap_pud_range(pgd_entry, addr, end); + + if (try_to_free_pud_page((pud_t *)pgd_page_vaddr(*pgd_entry))) + pgd_clear(pgd_entry); +} + static int alloc_pte_page(pmd_t *pmd) { pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK); @@ -999,9 +1021,8 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, static int populate_pgd(struct cpa_data *cpa, unsigned long addr) { pgprot_t pgprot = __pgprot(_KERNPG_TABLE); - bool allocd_pgd = false; - pgd_t *pgd_entry; pud_t *pud = NULL; /* shut up gcc */ + pgd_t *pgd_entry; int ret; pgd_entry = cpa->pgd + pgd_index(addr); @@ -1015,7 +1036,6 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) return -1; set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE)); - allocd_pgd = true; } pgprot_val(pgprot) &= ~pgprot_val(cpa->mask_clr); @@ -1023,19 +1043,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) ret = populate_pud(cpa, addr, pgd_entry, pgprot); if (ret < 0) { - unmap_pud_range(pgd_entry, addr, + unmap_pgd_range(cpa->pgd, addr, addr + (cpa->numpages << PAGE_SHIFT)); - - if (allocd_pgd) { - /* - * If I allocated this PUD page, I can just as well - * free it in this error path. - */ - pgd_clear(pgd_entry); - free_page((unsigned long)pud); - } return ret; } + cpa->numpages = ret; return 0; } @@ -1861,6 +1873,12 @@ out: return retval; } +void kernel_unmap_pages_in_pgd(pgd_t *root, unsigned long address, + unsigned numpages) +{ + unmap_pgd_range(root, address, address + (numpages << PAGE_SHIFT)); +} + /* * The testcases use internal knowledge of the implementation that shouldn't * be exposed to the rest of the kernel. Include these directly here. -- cgit v1.2.3-55-g7522 From b7b898ae0c0a82489511a1ce1b35f26215e6beb5 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 18 Jan 2014 12:48:17 +0100 Subject: x86/efi: Make efi virtual runtime map passing more robust Currently, running SetVirtualAddressMap() and passing the physical address of the virtual map array was working only by a lucky coincidence because the memory was present in the EFI page table too. Until Toshi went and booted this on a big HP box - the krealloc() manner of resizing the memmap we're doing did allocate from such physical addresses which were not mapped anymore and boom: http://lkml.kernel.org/r/1386806463.1791.295.camel@misato.fc.hp.com One way to take care of that issue is to reimplement the krealloc thing but with pages. We start with contiguous pages of order 1, i.e. 2 pages, and when we deplete that memory (shouldn't happen all that often but you know firmware) we realloc the next power-of-two pages. Having the pages, it is much more handy and easy to map them into the EFI page table with the already existing mapping code which we're using for building the virtual mappings. Thanks to Toshi Kani and Matt for the great debugging help. Reported-by: Toshi Kani Signed-off-by: Borislav Petkov Tested-by: Toshi Kani Signed-off-by: Matt Fleming --- arch/x86/include/asm/efi.h | 3 +- arch/x86/platform/efi/efi.c | 99 +++++++++++++++++++++++++++++++++--------- arch/x86/platform/efi/efi_32.c | 6 ++- arch/x86/platform/efi/efi_64.c | 32 ++++++++++++-- 4 files changed, 114 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 4afd3b3b658f..e985d6bf7d3a 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -129,7 +129,8 @@ extern void efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); extern void __init efi_map_region_fixed(efi_memory_desc_t *md); extern void efi_sync_low_kernel_mappings(void); -extern void efi_setup_page_tables(void); +extern int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); +extern void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init old_map_region(efi_memory_desc_t *md); extern void __init runtime_code_page_mkexec(void); extern void __init efi_runtime_mkexec(void); diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 37f20d71ec4b..576bb126593a 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -926,14 +926,36 @@ static void __init efi_map_regions_fixed(void) } +static void *realloc_pages(void *old_memmap, int old_shift) +{ + void *ret; + + ret = (void *)__get_free_pages(GFP_KERNEL, old_shift + 1); + if (!ret) + goto out; + + /* + * A first-time allocation doesn't have anything to copy. + */ + if (!old_memmap) + return ret; + + memcpy(ret, old_memmap, PAGE_SIZE << old_shift); + +out: + free_pages((unsigned long)old_memmap, old_shift); + return ret; +} + /* - * Map efi memory ranges for runtime serivce and update new_memmap with virtual - * addresses. + * Map the efi memory ranges of the runtime services and update new_mmap with + * virtual addresses. */ -static void * __init efi_map_regions(int *count) +static void * __init efi_map_regions(int *count, int *pg_shift) { + void *p, *new_memmap = NULL; + unsigned long left = 0; efi_memory_desc_t *md; - void *p, *tmp, *new_memmap = NULL; for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { md = p; @@ -948,20 +970,23 @@ static void * __init efi_map_regions(int *count) efi_map_region(md); get_systab_virt_addr(md); - tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size, - GFP_KERNEL); - if (!tmp) - goto out; - new_memmap = tmp; + if (left < memmap.desc_size) { + new_memmap = realloc_pages(new_memmap, *pg_shift); + if (!new_memmap) + return NULL; + + left += PAGE_SIZE << *pg_shift; + (*pg_shift)++; + } + memcpy(new_memmap + (*count * memmap.desc_size), md, memmap.desc_size); + + left -= memmap.desc_size; (*count)++; } return new_memmap; -out: - kfree(new_memmap); - return NULL; } /* @@ -987,9 +1012,9 @@ out: */ void __init efi_enter_virtual_mode(void) { - efi_status_t status; + int err, count = 0, pg_shift = 0; void *new_memmap = NULL; - int err, count = 0; + efi_status_t status; efi.systab = NULL; @@ -1006,20 +1031,24 @@ void __init efi_enter_virtual_mode(void) efi_map_regions_fixed(); } else { efi_merge_regions(); - new_memmap = efi_map_regions(&count); + new_memmap = efi_map_regions(&count, &pg_shift); if (!new_memmap) { pr_err("Error reallocating memory, EFI runtime non-functional!\n"); return; } - } - err = save_runtime_map(); - if (err) - pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n"); + err = save_runtime_map(); + if (err) + pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n"); + } BUG_ON(!efi.systab); - efi_setup_page_tables(); + if (!efi_setup) { + if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) + return; + } + efi_sync_low_kernel_mappings(); efi_dump_pagetable(); @@ -1060,7 +1089,35 @@ void __init efi_enter_virtual_mode(void) efi_runtime_mkexec(); - kfree(new_memmap); + + /* + * We mapped the descriptor array into the EFI pagetable above but we're + * not unmapping it here. Here's why: + * + * We're copying select PGDs from the kernel page table to the EFI page + * table and when we do so and make changes to those PGDs like unmapping + * stuff from them, those changes appear in the kernel page table and we + * go boom. + * + * From setup_real_mode(): + * + * ... + * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd; + * + * In this particular case, our allocation is in PGD 0 of the EFI page + * table but we've copied that PGD from PGD[272] of the EFI page table: + * + * pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272 + * + * where the direct memory mapping in kernel space is. + * + * new_memmap's VA comes from that direct mapping and thus clearing it, + * it would get cleared in the kernel page table too. + * + * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); + */ + if (!efi_setup) + free_pages((unsigned long)new_memmap, pg_shift); /* clean DUMMY object */ efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 39496ae3928a..9ee3491e31fb 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -40,8 +40,12 @@ static unsigned long efi_rt_eflags; void efi_sync_low_kernel_mappings(void) {} -void efi_setup_page_tables(void) {} void __init efi_dump_pagetable(void) {} +int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) +{ + return 0; +} +void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) {} void __init efi_map_region(efi_memory_desc_t *md) { diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index e05c69b46f05..19280900ec25 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -137,12 +137,38 @@ void efi_sync_low_kernel_mappings(void) sizeof(pgd_t) * num_pgds); } -void efi_setup_page_tables(void) +int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { + pgd_t *pgd; + + if (efi_enabled(EFI_OLD_MEMMAP)) + return 0; + efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd; + pgd = __va(efi_scratch.efi_pgt); - if (!efi_enabled(EFI_OLD_MEMMAP)) - efi_scratch.use_pgd = true; + /* + * It can happen that the physical address of new_memmap lands in memory + * which is not mapped in the EFI page table. Therefore we need to go + * and ident-map those pages containing the map before calling + * phys_efi_set_virtual_address_map(). + */ + if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) { + pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap); + return 1; + } + + efi_scratch.use_pgd = true; + + + return 0; +} + +void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) +{ + pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); + + kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages); } static void __init __map_region(efi_memory_desc_t *md, u64 va) -- cgit v1.2.3-55-g7522 From fabb37c736f9f688fe3eec98550a5c032a07cfaa Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sat, 18 Jan 2014 12:48:18 +0100 Subject: x86/efi: Split efi_enter_virtual_mode ... into a kexec flavor for better code readability and simplicity. The original one was getting ugly with ifdeffery. Signed-off-by: Borislav Petkov Tested-by: Toshi Kani Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 148 +++++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 576bb126593a..6f0a46730826 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -879,8 +879,9 @@ static void __init get_systab_virt_addr(efi_memory_desc_t *md) } } -static int __init save_runtime_map(void) +static void __init save_runtime_map(void) { +#ifdef CONFIG_KEXEC efi_memory_desc_t *md; void *tmp, *p, *q = NULL; int count = 0; @@ -902,28 +903,12 @@ static int __init save_runtime_map(void) } efi_runtime_map_setup(q, count, memmap.desc_size); + return; - return 0; out: kfree(q); - return -ENOMEM; -} - -/* - * Map efi regions which were passed via setup_data. The virt_addr is a fixed - * addr which was used in first kernel of a kexec boot. - */ -static void __init efi_map_regions_fixed(void) -{ - void *p; - efi_memory_desc_t *md; - - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { - md = p; - efi_map_region_fixed(md); /* FIXME: add error handling */ - get_systab_virt_addr(md); - } - + pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n"); +#endif } static void *realloc_pages(void *old_memmap, int old_shift) @@ -989,6 +974,72 @@ static void * __init efi_map_regions(int *count, int *pg_shift) return new_memmap; } +static void __init kexec_enter_virtual_mode(void) +{ +#ifdef CONFIG_KEXEC + efi_memory_desc_t *md; + void *p; + + efi.systab = NULL; + + /* + * We don't do virtual mode, since we don't do runtime services, on + * non-native EFI + */ + if (!efi_is_native()) { + efi_unmap_memmap(); + return; + } + + /* + * Map efi regions which were passed via setup_data. The virt_addr is a + * fixed addr which was used in first kernel of a kexec boot. + */ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; + efi_map_region_fixed(md); /* FIXME: add error handling */ + get_systab_virt_addr(md); + } + + save_runtime_map(); + + BUG_ON(!efi.systab); + + efi_sync_low_kernel_mappings(); + + /* + * Now that EFI is in virtual mode, update the function + * pointers in the runtime service table to the new virtual addresses. + * + * Call EFI services through wrapper functions. + */ + efi.runtime_version = efi_systab.hdr.revision; + efi.get_time = virt_efi_get_time; + efi.set_time = virt_efi_set_time; + efi.get_wakeup_time = virt_efi_get_wakeup_time; + efi.set_wakeup_time = virt_efi_set_wakeup_time; + efi.get_variable = virt_efi_get_variable; + efi.get_next_variable = virt_efi_get_next_variable; + efi.set_variable = virt_efi_set_variable; + efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; + efi.reset_system = virt_efi_reset_system; + efi.set_virtual_address_map = NULL; + efi.query_variable_info = virt_efi_query_variable_info; + efi.update_capsule = virt_efi_update_capsule; + efi.query_capsule_caps = virt_efi_query_capsule_caps; + + if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX)) + runtime_code_page_mkexec(); + + /* clean DUMMY object */ + efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); +#endif +} + /* * This function will switch the EFI runtime services to virtual mode. * Essentially, we look through the EFI memmap and map every region that @@ -1008,11 +1059,12 @@ static void * __init efi_map_regions(int *count, int *pg_shift) * * Specially for kexec boot, efi runtime maps in previous kernel should * be passed in via setup_data. In that case runtime ranges will be mapped - * to the same virtual addresses as the first kernel. + * to the same virtual addresses as the first kernel, see + * kexec_enter_virtual_mode(). */ -void __init efi_enter_virtual_mode(void) +static void __init __efi_enter_virtual_mode(void) { - int err, count = 0, pg_shift = 0; + int count = 0, pg_shift = 0; void *new_memmap = NULL; efi_status_t status; @@ -1027,43 +1079,33 @@ void __init efi_enter_virtual_mode(void) return; } - if (efi_setup) { - efi_map_regions_fixed(); - } else { - efi_merge_regions(); - new_memmap = efi_map_regions(&count, &pg_shift); - if (!new_memmap) { - pr_err("Error reallocating memory, EFI runtime non-functional!\n"); - return; - } - - err = save_runtime_map(); - if (err) - pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n"); + efi_merge_regions(); + new_memmap = efi_map_regions(&count, &pg_shift); + if (!new_memmap) { + pr_err("Error reallocating memory, EFI runtime non-functional!\n"); + return; } + save_runtime_map(); + BUG_ON(!efi.systab); - if (!efi_setup) { - if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) - return; - } + if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) + return; efi_sync_low_kernel_mappings(); efi_dump_pagetable(); - if (!efi_setup) { - status = phys_efi_set_virtual_address_map( + status = phys_efi_set_virtual_address_map( memmap.desc_size * count, memmap.desc_size, memmap.desc_version, (efi_memory_desc_t *)__pa(new_memmap)); - if (status != EFI_SUCCESS) { - pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n", - status); - panic("EFI call to SetVirtualAddressMap() failed!"); - } + if (status != EFI_SUCCESS) { + pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n", + status); + panic("EFI call to SetVirtualAddressMap() failed!"); } /* @@ -1089,7 +1131,6 @@ void __init efi_enter_virtual_mode(void) efi_runtime_mkexec(); - /* * We mapped the descriptor array into the EFI pagetable above but we're * not unmapping it here. Here's why: @@ -1116,8 +1157,7 @@ void __init efi_enter_virtual_mode(void) * * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); */ - if (!efi_setup) - free_pages((unsigned long)new_memmap, pg_shift); + free_pages((unsigned long)new_memmap, pg_shift); /* clean DUMMY object */ efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, @@ -1127,6 +1167,14 @@ void __init efi_enter_virtual_mode(void) 0, NULL); } +void __init efi_enter_virtual_mode(void) +{ + if (efi_setup) + kexec_enter_virtual_mode(); + else + __efi_enter_virtual_mode(); +} + /* * Convenience functions to obtain memory types and attributes */ -- cgit v1.2.3-55-g7522 From 092063808c498eccac8e891973bf143e7b60d723 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 15 Jan 2014 13:49:51 +0000 Subject: ia64/efi: Implement efi_enabled() There's no good reason to keep efi_enabled() under CONFIG_X86 anymore, since nothing about the implementation is specific to x86. Set EFI feature flags in the ia64 boot path instead of claiming to support all features. The old behaviour was actually buggy since efi.memmap never points to a valid memory map, so we shouldn't be claiming to support EFI_MEMMAP. Fortunately, this bug was never triggered because EFI_MEMMAP isn't used outside of arch/x86 currently, but that may not always be the case. Reviewed-and-tested-by: Tony Luck Signed-off-by: Matt Fleming --- arch/ia64/kernel/efi.c | 7 +++++++ include/linux/efi.h | 8 -------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index da5b462e6de6..741b99c1a0b1 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -477,6 +477,9 @@ efi_init (void) char *cp, vendor[100] = "unknown"; int i; + set_bit(EFI_BOOT, &efi.flags); + set_bit(EFI_64BIT, &efi.flags); + /* * It's too early to be able to use the standard kernel command line * support... @@ -529,6 +532,8 @@ efi_init (void) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); + set_bit(EFI_SYSTEM_TABLES, &efi.flags); + palo_phys = EFI_INVALID_TABLE_ADDR; if (efi_config_init(arch_tables) != 0) @@ -657,6 +662,8 @@ efi_enter_virtual_mode (void) return; } + set_bit(EFI_RUNTIME_SERVICES, &efi.flags); + /* * Now that EFI is in virtual mode, we call the EFI functions more * efficiently: diff --git a/include/linux/efi.h b/include/linux/efi.h index 214833b4a97d..64d532ca890a 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -660,8 +660,6 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_ARCH_1 6 /* First arch-specific bit */ #ifdef CONFIG_EFI -# ifdef CONFIG_X86 - /* * Test whether the above EFI_* bits are enabled. */ @@ -669,12 +667,6 @@ static inline bool efi_enabled(int feature) { return test_bit(feature, &efi.flags) != 0; } -# else -static inline bool efi_enabled(int feature) -{ - return true; -} -# endif #else static inline bool efi_enabled(int feature) { -- cgit v1.2.3-55-g7522 From c866cda47f2c6c8abb929933b7794e9a92d7c924 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:08 +0000 Subject: powerpc:eVh_pic: Kill irq_desc abuse I'm really grumpy about this one. The line: #include "../../../kernel/irq/settings.h" should have been an alarm sign for all people who added their SOB to this trainwreck. When I cleaned up the mess people made with interrupt descriptors a few years ago, I warned that I'm going to hunt down new offenders and treat them with stinking trouts. In this case I'll use frozen shark for a better educational value. The whole idiocy which was done there could have been avoided with two lines of perfectly fine code. And do not complain about the lack of correct examples in tree. The solution is simple: Remove the brainfart and use the proper functions, which should have been used in the first place Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: Ashish Kalra Cc: Timur Tabi Cc: Kumar Gala Cc: ppc Link: http://lkml.kernel.org/r/20140223212736.451970660@linutronix.de Signed-off-by: Thomas Gleixner --- arch/powerpc/sysdev/ehv_pic.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index b74085cea1af..2d20f10a4203 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -28,8 +28,6 @@ #include #include -#include "../../../kernel/irq/settings.h" - static struct ehv_pic *global_ehv_pic; static DEFINE_SPINLOCK(ehv_pic_lock); @@ -113,17 +111,13 @@ static unsigned int ehv_pic_type_to_vecpri(unsigned int type) int ehv_pic_set_irq_type(struct irq_data *d, unsigned int flow_type) { unsigned int src = virq_to_hw(d->irq); - struct irq_desc *desc = irq_to_desc(d->irq); unsigned int vecpri, vold, vnew, prio, cpu_dest; unsigned long flags; if (flow_type == IRQ_TYPE_NONE) flow_type = IRQ_TYPE_LEVEL_LOW; - irq_settings_clr_level(desc); - irq_settings_set_trigger_mask(desc, flow_type); - if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) - irq_settings_set_level(desc); + irqd_set_trigger_type(d, flow_type); vecpri = ehv_pic_type_to_vecpri(flow_type); @@ -144,7 +138,7 @@ int ehv_pic_set_irq_type(struct irq_data *d, unsigned int flow_type) ev_int_set_config(src, vecpri, prio, cpu_dest); spin_unlock_irqrestore(&ehv_pic_lock, flags); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } static struct irq_chip ehv_pic_irq_chip = { -- cgit v1.2.3-55-g7522 From a4e04c9f219d2c00764ffa7ba45500411815879d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:08 +0000 Subject: powerpc: Irq: Use generic_handle_irq No functional change Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: ppc Link: http://lkml.kernel.org/r/20140223212736.333718121@linutronix.de Signed-off-by: Thomas Gleixner --- arch/powerpc/kernel/irq.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 1d0848bba049..ca1cd7459c4a 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -465,7 +465,6 @@ static inline void check_stack_overflow(void) void __do_irq(struct pt_regs *regs) { - struct irq_desc *desc; unsigned int irq; irq_enter(); @@ -487,11 +486,8 @@ void __do_irq(struct pt_regs *regs) /* And finally process it */ if (unlikely(irq == NO_IRQ)) __get_cpu_var(irq_stat).spurious_irqs++; - else { - desc = irq_to_desc(irq); - if (likely(desc)) - desc->handle_irq(irq, desc); - } + else + generic_handle_irq(irq); trace_irq_exit(regs); -- cgit v1.2.3-55-g7522 From b8a9a11b976810ba12a43c4fe699a14892c97e52 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:09 +0000 Subject: powerpc: Eeh: Kill another abuse of irq_desc commit 91150af3a (powerpc/eeh: Fix unbalanced enable for IRQ) is another brilliant example of trainwreck engineering. The patch "fixes" the issue of an unbalanced call to irq_enable() which causes a prominent warning by checking the disabled state of the interrupt line and call conditionally into the core code. This is wrong in two aspects: 1) The warning is there to tell users, that they need to fix their asymetric enable/disable patterns by finding the root cause and solving it there. It's definitely not meant to work around it by conditionally calling into the core code depending on the random state of the irq line. Asymetric irq_disable/enable calls are a clear sign of wrong usage of the interfaces which have to be cured at the root and not by somehow hacking around it. 2) The abuse of core internal data structure instead of using the proper interfaces for retrieving the information for the 'hack around' irq_desc is core internal and it's clear enough stated. Replace at least the irq_desc abuse with the proper functions and add a big fat comment why this is absurd and completely wrong. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Gavin Shan Cc: Benjamin Herrenschmidt Cc: ppc Link: http://lkml.kernel.org/r/20140223212736.562906212@linutronix.de Signed-off-by: Thomas Gleixner --- arch/powerpc/kernel/eeh_driver.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index fdc679d309ec..3e1d7de6ea40 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -143,15 +143,31 @@ static void eeh_disable_irq(struct pci_dev *dev) static void eeh_enable_irq(struct pci_dev *dev) { struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); - struct irq_desc *desc; if ((edev->mode) & EEH_DEV_IRQ_DISABLED) { edev->mode &= ~EEH_DEV_IRQ_DISABLED; - - desc = irq_to_desc(dev->irq); - if (desc && desc->depth > 0) + /* + * FIXME !!!!! + * + * This is just ass backwards. This maze has + * unbalanced irq_enable/disable calls. So instead of + * finding the root cause it works around the warning + * in the irq_enable code by conditionally calling + * into it. + * + * That's just wrong.The warning in the core code is + * there to tell people to fix their assymetries in + * their own code, not by abusing the core information + * to avoid it. + * + * I so wish that the assymetry would be the other way + * round and a few more irq_disable calls render that + * shit unusable forever. + * + * tglx + */ + if (irqd_irq_disabled(irq_get_irq_data(dev->irq)) enable_irq(dev->irq); - } } /** -- cgit v1.2.3-55-g7522 From 8435cf757632a5559fbbf1cb79299716c8d5b651 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:12 +0000 Subject: arm: Replace various irq_desc accesses Use the proper functions. There is no need to fiddle with irq_desc. Signed-off-by: Thomas Gleixner Acked-by: Shawn Guo C Acked-by: Tony Lindgren Cc: Peter Zijlstra Cc: arm Cc: Russell King Link: http://lkml.kernel.org/r/20140223212737.099151500@linutronix.de Signed-off-by: Thomas Gleixner --- arch/arm/mach-imx/pm-imx6q.c | 7 +++---- arch/arm/mach-omap1/ams-delta-fiq.c | 7 ++----- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index 7a9b98589db7..29e3fe6a6669 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -120,7 +120,7 @@ static void imx6q_enable_wb(bool enable) int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) { - struct irq_desc *iomuxc_irq_desc; + struct irq_data *iomuxc_irq_data = irq_get_irq_data(32); u32 val = readl_relaxed(ccm_base + CLPCR); val &= ~BM_CLPCR_LPM; @@ -167,10 +167,9 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) * 3) Software should mask IRQ #32 right after CCM Low-Power mode * is set (set bits 0-1 of CCM_CLPCR). */ - iomuxc_irq_desc = irq_to_desc(32); - imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data); + imx_gpc_irq_unmask(iomuxc_irq_data); writel_relaxed(val, ccm_base + CLPCR); - imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data); + imx_gpc_irq_mask(iomuxc_irq_data); return 0; } diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index f12a12af3523..2ebc514123a7 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -44,13 +44,10 @@ static unsigned int irq_counter[16]; static irqreturn_t deferred_fiq(int irq, void *dev_id) { - struct irq_desc *irq_desc; - struct irq_chip *irq_chip = NULL; int gpio, irq_num, fiq_count; + struct irq_chip *irq_chip; - irq_desc = irq_to_desc(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); - if (irq_desc) - irq_chip = irq_desc->irq_data.chip; + irq_chip = irq_get_irq_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); /* * For each handled GPIO interrupt, keep calling its interrupt handler -- cgit v1.2.3-55-g7522 From 49f3fbc7b8576fd578f3504c65aae9b8a212d0f6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:13 +0000 Subject: arm: mmp: Remove pointless fiddling with irq internals The pm-mmp2 and pm-pxa910 power management related irq_set_wake callbacks fiddle pointlessly with the irq actions for no reason except for lack of understanding how the wakeup mechanism works. On supsend the core disables all interrupts lazily, i.e. it does not mask them at the irq controller level. So any interrupt which is firing during suspend will mark the corresponding interrupt line as pending. Just before the core powers down it checks whether there are interrupts pending from interrupt lines which are marked as wakeup sources and if so it aborts the suspend and resends the interrupts. If there was no interrupt at this point, the cpu goes into suspend with these interrupts unmasked. The IRQF_NO_SUSPEND flag for interrupt actions is a totally different mechanism. That allows the device driver to prevent the core from disabling the interrupt despite the fact that it is not marked as a wakeup source. This has nothing to do with the case at hand. It was introduced for special cases where lazy disable is not possible. Remove the nonsense along with the braindamaged boundary check. The core code does NOT call these functions out of boundary. Add a FIXME comment to an unhandled error path which merily printks some useless blurb instead of returning a proper error code. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: arm Cc: Eric Miao Cc: Haojian Zhuang Cc: Russell King Link: http://lkml.kernel.org/r/20140223212737.214342433@linutronix.de Signed-off-by: Thomas Gleixner --- arch/arm/mach-mmp/pm-mmp2.c | 16 +--------------- arch/arm/mach-mmp/pm-pxa910.c | 20 ++++---------------- 2 files changed, 5 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-mmp/pm-mmp2.c b/arch/arm/mach-mmp/pm-mmp2.c index 461a191a32d2..43b1a516957f 100644 --- a/arch/arm/mach-mmp/pm-mmp2.c +++ b/arch/arm/mach-mmp/pm-mmp2.c @@ -27,22 +27,8 @@ int mmp2_set_wake(struct irq_data *d, unsigned int on) { - int irq = d->irq; - struct irq_desc *desc = irq_to_desc(irq); unsigned long data = 0; - - if (unlikely(irq >= nr_irqs)) { - pr_err("IRQ nubmers are out of boundary!\n"); - return -EINVAL; - } - - if (on) { - if (desc->action) - desc->action->flags |= IRQF_NO_SUSPEND; - } else { - if (desc->action) - desc->action->flags &= ~IRQF_NO_SUSPEND; - } + int irq = d->irq; /* enable wakeup sources */ switch (irq) { diff --git a/arch/arm/mach-mmp/pm-pxa910.c b/arch/arm/mach-mmp/pm-pxa910.c index 48981ca801a5..04c9daf9f8d7 100644 --- a/arch/arm/mach-mmp/pm-pxa910.c +++ b/arch/arm/mach-mmp/pm-pxa910.c @@ -27,22 +27,8 @@ int pxa910_set_wake(struct irq_data *data, unsigned int on) { - int irq = data->irq; - struct irq_desc *desc = irq_to_desc(data->irq); uint32_t awucrm = 0, apcr = 0; - - if (unlikely(irq >= nr_irqs)) { - pr_err("IRQ nubmers are out of boundary!\n"); - return -EINVAL; - } - - if (on) { - if (desc->action) - desc->action->flags |= IRQF_NO_SUSPEND; - } else { - if (desc->action) - desc->action->flags &= ~IRQF_NO_SUSPEND; - } + int irq = data->irq; /* setting wakeup sources */ switch (irq) { @@ -115,9 +101,11 @@ int pxa910_set_wake(struct irq_data *data, unsigned int on) if (irq >= IRQ_GPIO_START && irq < IRQ_BOARD_START) { awucrm = MPMU_AWUCRM_WAKEUP(2); apcr |= MPMU_APCR_SLPWP2; - } else + } else { + /* FIXME: This should return a proper error code ! */ printk(KERN_ERR "Error: no defined wake up source irq: %d\n", irq); + } } if (on) { -- cgit v1.2.3-55-g7522 From 310ff2c87e72208e4f04f33687abe9d208ffefe3 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:14 +0000 Subject: mips: Use the core irq stats function Let the core do the irq_desc resolution. No functional change. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Ralf Baechle Cc: mips Link: http://lkml.kernel.org/r/20140223212737.517340416@linutronix.de Signed-off-by: Thomas Gleixner --- arch/mips/kernel/smtc.c | 2 +- arch/mips/sgi-ip22/ip22-int.c | 2 +- arch/mips/sgi-ip22/ip22-time.c | 2 +- arch/mips/sibyte/bcm1480/smp.c | 2 +- arch/mips/sibyte/sb1250/smp.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index dfc1b911be04..c1681d65dd5c 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1007,7 +1007,7 @@ static void __irq_entry smtc_clock_tick_interrupt(void) int irq = MIPS_CPU_IRQ_BASE + 1; irq_enter(); - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); cd = &per_cpu(mips_clockevent_device, cpu); cd->event_handler(cd); irq_exit(); diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 3db64d51798d..58b40ae59335 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -148,7 +148,7 @@ static void __irq_entry indy_buserror_irq(void) int irq = SGI_BUSERR_IRQ; irq_enter(); - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); ip22_be_interrupt(irq); irq_exit(); } diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index 607192449335..045aa89f28d8 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c @@ -123,7 +123,7 @@ void __irq_entry indy_8254timer_irq(void) char c; irq_enter(); - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index 54e2c4de15c1..70d9182b26f1 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -182,7 +182,7 @@ void bcm1480_mailbox_interrupt(void) int irq = K_BCM1480_INT_MBOX_0_0; unsigned int action; - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); /* Load the mailbox register to figure out what we're supposed to do */ action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff; diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index d7b942db0ea5..db976117dd4d 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c @@ -170,7 +170,7 @@ void sb1250_mailbox_interrupt(void) int irq = K_INT_MBOX_0; unsigned int action; - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); /* Load the mailbox register to figure out what we're supposed to do */ action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff; -- cgit v1.2.3-55-g7522 From 87a69ad6409b2c7a95e2e6e4ddbc380046cb7730 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:15 +0000 Subject: sparc: Use the core irq stats function Let the core do the irq_desc resolution. No functional change. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: David S. Miller Link: http://lkml.kernel.org/r/20140223212737.635609567@linutronix.de Signed-off-by: Thomas Gleixner --- arch/sparc/kernel/time_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c3d82b5f54ca..24e8b8705e7f 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -733,7 +733,7 @@ void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) irq_enter(); local_cpu_data().irq0_irqs++; - kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); + kstat_incr_irq_this_cpu(0); if (unlikely(!evt->event_handler)) { printk(KERN_WARNING -- cgit v1.2.3-55-g7522 From 770144ea7beb3e0537277a96b104ba1daa965f76 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:16 +0000 Subject: x86: Xen: Use the core irq stats function Let the core do the irq_desc resolution. No functional change. Signed-off-by: Thomas Gleixner Reviewed-by: David Vrabel Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: Xen Cc: x86 Link: http://lkml.kernel.org/r/20140223212737.869264085@linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/xen/spinlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 581521c843a5..4d3acc34a998 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -183,7 +183,7 @@ __visible void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want) local_irq_save(flags); - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); out: cpumask_clear_cpu(cpu, &waiting_cpus); w->lock = NULL; -- cgit v1.2.3-55-g7522 From a21748c93544901448777b5fa2abe1194c02c6dc Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:16 +0000 Subject: mn10300: Use the core irq stats function Let the core do the irq_desc resolution. No functional change. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: David Howells Cc: mn10300 Link: http://lkml.kernel.org/r/20140223212737.751487689@linutronix.de Signed-off-by: Thomas Gleixner --- arch/mn10300/kernel/mn10300-watchdog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c index db64a7166c09..a2d8e6938d67 100644 --- a/arch/mn10300/kernel/mn10300-watchdog.c +++ b/arch/mn10300/kernel/mn10300-watchdog.c @@ -142,7 +142,7 @@ void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep) NMICR = NMICR_WDIF; nmi_count(smp_processor_id())++; - kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); + kstat_incr_irq_this_cpu(irq); for_each_online_cpu(cpu) { -- cgit v1.2.3-55-g7522 From 3611587aa15f4ff75a2af3483d6a02accada8ec8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:17 +0000 Subject: ia64: Use the core irq stats function Let the core do the irq_desc resolution. No functional change. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Tony Luck Cc: Fenghua Yu Cc: ia64 Link: http://lkml.kernel.org/r/20140223212738.099977064@linutronix.de Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/irq_ia64.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 1034884b77da..c8a576b27736 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -489,14 +489,13 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) ia64_srlz_d(); while (vector != IA64_SPURIOUS_INT_VECTOR) { int irq = local_vector_to_irq(vector); - struct irq_desc *desc = irq_to_desc(irq); if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { smp_local_flush_tlb(); - kstat_incr_irqs_this_cpu(irq, desc); + kstat_incr_irq_this_cpu(irq); } else if (unlikely(IS_RESCHEDULE(vector))) { scheduler_ipi(); - kstat_incr_irqs_this_cpu(irq, desc); + kstat_incr_irq_this_cpu(irq); } else { ia64_setreg(_IA64_REG_CR_TPR, vector); ia64_srlz_d(); @@ -549,13 +548,12 @@ void ia64_process_pending_intr(void) */ while (vector != IA64_SPURIOUS_INT_VECTOR) { int irq = local_vector_to_irq(vector); - struct irq_desc *desc = irq_to_desc(irq); if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { smp_local_flush_tlb(); - kstat_incr_irqs_this_cpu(irq, desc); + kstat_incr_irq_this_cpu(irq); } else if (unlikely(IS_RESCHEDULE(vector))) { - kstat_incr_irqs_this_cpu(irq, desc); + kstat_incr_irq_this_cpu(irq); } else { struct pt_regs *old_regs = set_irq_regs(NULL); -- cgit v1.2.3-55-g7522 From 929320e4b4c10708d3477d7e395f0ce7b0cc8744 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:20 +0000 Subject: x86: Add proper vector accounting for HYPERVISOR_CALLBACK_VECTOR HyperV abuses a device interrupt to account for the HYPERVISOR_CALLBACK_VECTOR. Provide proper accounting as we have for the other vectors as well. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: K. Y. Srinivasan Cc: x86 Link: http://lkml.kernel.org/r/20140223212738.681855582@linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/hardirq.h | 3 +++ arch/x86/kernel/irq.c | 6 ++++++ 2 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index ab0ae1aa6d0a..afb6536ee3ac 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -33,6 +33,9 @@ typedef struct { #ifdef CONFIG_X86_MCE_THRESHOLD unsigned int irq_threshold_count; #endif +#if defined(CONFIG_HYPERV) || defined(CONFIG_XEN) + unsigned int irq_hv_callback_count; +#endif } ____cacheline_aligned irq_cpustat_t; DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index d99f31d9a750..42805fac0092 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -124,6 +124,12 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); seq_printf(p, " Machine check polls\n"); +#endif +#if defined(CONFIG_HYPERV) || defined(CONFIG_XEN) + seq_printf(p, "%*s: ", prec, "THR"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); + seq_printf(p, " Hypervisor callback interrupts\n"); #endif seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); #if defined(CONFIG_X86_IO_APIC) -- cgit v1.2.3-55-g7522 From 1aec169673d7db113c37367bbc371c2ba8109f06 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:22 +0000 Subject: x86: Hyperv: Cleanup the irq mess The vmbus/hyperv interrupt handling is another complete trainwreck and probably the worst of all currently in tree. If CONFIG_HYPERV=y then the interrupt delivery to the vmbus happens via the direct HYPERVISOR_CALLBACK_VECTOR. So far so good, but: The driver requests first a normal device interrupt. The only reason to do so is to increment the interrupt stats of that device interrupt. For no reason it also installs a private flow handler. We have proper accounting mechanisms for direct vectors, but of course it's too much effort to add that 5 lines of code. Aside of that the alloc_intr_gate() is not protected against reallocation which makes module reload impossible. Solution to the problem is simple to rip out the whole mess and implement it correctly. First of all move all that code to arch/x86/kernel/cpu/mshyperv.c and merily install the HYPERVISOR_CALLBACK_VECTOR with proper reallocation protection and use the proper direct vector accounting mechanism. Signed-off-by: Thomas Gleixner Acked-by: K. Y. Srinivasan Cc: Peter Zijlstra Cc: Greg Kroah-Hartman Cc: linuxdrivers Cc: x86 Link: http://lkml.kernel.org/r/20140223212739.028307673@linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/mshyperv.h | 4 ++- arch/x86/kernel/cpu/mshyperv.c | 78 +++++++++++++++++++++-------------------- drivers/hv/vmbus_drv.c | 39 +++------------------ 3 files changed, 47 insertions(+), 74 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index cd9c41938b8a..e98f66f35635 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -2,6 +2,7 @@ #define _ASM_X86_MSHYPER_H #include +#include #include struct ms_hyperv_info { @@ -16,6 +17,7 @@ void hyperv_callback_vector(void); #define trace_hyperv_callback_vector hyperv_callback_vector #endif void hyperv_vector_handler(struct pt_regs *regs); -void hv_register_vmbus_handler(int irq, irq_handler_t handler); +int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id); +void hv_remove_vmbus_irq(int irq, void *dev_id); #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 9f7ca266864a..1bd316cd32c8 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,45 @@ struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); +#ifdef CONFIG_HYPERV +static irq_handler_t *vmbus_handler; + +void hyperv_vector_handler(struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + exit_idle(); + + inc_irq_stat(irq_hv_callback_count); + if (vmbus_handler) + vmbus_handler(); + + irq_exit(); + set_irq_regs(old_regs); +} + +int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void *dev_id) +{ + vmbus_handler = handler; + /* + * Setup the IDT for hypervisor callback. Prevent reallocation + * at module reload. + */ + if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, + hyperv_callback_vector); +} + +void hv_remove_vmbus_irq(unsigned int irq, void *dev_id) +{ + /* We have no way to deallocate the interrupt gate */ + vmbus_handler = NULL; +} +EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq); +EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq); +#endif + static uint32_t __init ms_hyperv_platform(void) { u32 eax; @@ -113,41 +153,3 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { .init_platform = ms_hyperv_init_platform, }; EXPORT_SYMBOL(x86_hyper_ms_hyperv); - -#if IS_ENABLED(CONFIG_HYPERV) -static int vmbus_irq = -1; -static irq_handler_t vmbus_isr; - -void hv_register_vmbus_handler(int irq, irq_handler_t handler) -{ - /* - * Setup the IDT for hypervisor callback. - */ - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); - - vmbus_irq = irq; - vmbus_isr = handler; -} - -void hyperv_vector_handler(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - struct irq_desc *desc; - - irq_enter(); - exit_idle(); - - desc = irq_to_desc(vmbus_irq); - - if (desc) - generic_handle_irq_desc(vmbus_irq, desc); - - irq_exit(); - set_irq_regs(old_regs); -} -#else -void hv_register_vmbus_handler(int irq, irq_handler_t handler) -{ -} -#endif -EXPORT_SYMBOL_GPL(hv_register_vmbus_handler); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 077bb1bdac34..5a6909fff1c1 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -558,9 +557,6 @@ static struct bus_type hv_bus = { .dev_groups = vmbus_groups, }; -static const char *driver_name = "hyperv"; - - struct onmessage_work_context { struct work_struct work; struct hv_message msg; @@ -676,19 +672,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) return IRQ_NONE; } -/* - * vmbus interrupt flow handler: - * vmbus interrupts can concurrently occur on multiple CPUs and - * can be handled concurrently. - */ - -static void vmbus_flow_handler(unsigned int irq, struct irq_desc *desc) -{ - kstat_incr_irqs_this_cpu(irq, desc); - - desc->action->handler(irq, desc->action->dev_id); -} - /* * vmbus_bus_init -Main vmbus driver initialization routine. * @@ -715,26 +698,13 @@ static int vmbus_bus_init(int irq) if (ret) goto err_cleanup; - ret = request_irq(irq, vmbus_isr, 0, driver_name, hv_acpi_dev); + ret = hv_setup_vmbus_irq(irq, vmbus_isr, hv_acpi_dev); if (ret != 0) { - pr_err("Unable to request IRQ %d\n", - irq); + pr_err("Unable to request IRQ %d\n", irq); goto err_unregister; } - /* - * Vmbus interrupts can be handled concurrently on - * different CPUs. Establish an appropriate interrupt flow - * handler that can support this model. - */ - irq_set_handler(irq, vmbus_flow_handler); - - /* - * Register our interrupt handler. - */ - hv_register_vmbus_handler(irq, vmbus_isr); - ret = hv_synic_alloc(); if (ret) goto err_alloc; @@ -753,7 +723,7 @@ static int vmbus_bus_init(int irq) err_alloc: hv_synic_free(); - free_irq(irq, hv_acpi_dev); + hv_remove_vmbus_irq(irq, hv_acpi_dev); err_unregister: bus_unregister(&hv_bus); @@ -978,8 +948,7 @@ cleanup: static void __exit vmbus_exit(void) { - - free_irq(irq, hv_acpi_dev); + hv_remove_vmbus_irq(irq, hv_acpi_dev); vmbus_free_channels(); bus_unregister(&hv_bus); hv_cleanup(); -- cgit v1.2.3-55-g7522 From 6decf1a33c386d4addc2ed9d269c3868f08c70bb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:10 +0000 Subject: sh: Use irq_set_affinity instead of homebrewn code There is no point in having an incomplete copy of irq_set_affinity() for the hotplug irq migration code. Use the core function instead. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Paul Mundt Cc: sh Link: http://lkml.kernel.org/r/20140223212736.774961401@linutronix.de Signed-off-by: Thomas Gleixner --- arch/sh/kernel/irq.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 0833736afa32..65a1ecd77f96 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -217,19 +217,6 @@ void __init init_IRQ(void) } #ifdef CONFIG_HOTPLUG_CPU -static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_chip *chip = irq_data_get_irq_chip(data); - - printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n", - irq, data->node, cpu); - - raw_spin_lock_irq(&desc->lock); - chip->irq_set_affinity(data, cpumask_of(cpu), false); - raw_spin_unlock_irq(&desc->lock); -} - /* * The CPU has been marked offline. Migrate IRQs off this CPU. If * the affinity settings do not allow other CPUs, force them onto any @@ -250,11 +237,8 @@ void migrate_irqs(void) irq, cpu); cpumask_setall(data->affinity); - newcpu = cpumask_any_and(data->affinity, - cpu_online_mask); } - - route_irq(data, irq, newcpu); + irq_set_affinity(irq, data->affinity); } } } -- cgit v1.2.3-55-g7522 From b58d971da3433654787a88c40c6fca00f5bbaa04 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:10 +0000 Subject: xtensa: Use irq_set_affinity instead of homebrewn code There is no point in having an incomplete copy of irq_set_affinity() for the hotplug irq migration code. Use the core function instead and while at it switch to for_each_active_irq() Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Chris Zankel Cc: xtensa Link: http://lkml.kernel.org/r/20140223212736.664624945@linutronix.de Signed-off-by: Thomas Gleixner --- arch/xtensa/kernel/irq.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 482868a2de6e..3eee94f621eb 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -155,18 +155,6 @@ void __init init_IRQ(void) } #ifdef CONFIG_HOTPLUG_CPU -static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_chip *chip = irq_data_get_irq_chip(data); - unsigned long flags; - - raw_spin_lock_irqsave(&desc->lock, flags); - if (chip->irq_set_affinity) - chip->irq_set_affinity(data, cpumask_of(cpu), false); - raw_spin_unlock_irqrestore(&desc->lock, flags); -} - /* * The CPU has been marked offline. Migrate IRQs off this CPU. If * the affinity settings do not allow other CPUs, force them onto any @@ -175,10 +163,9 @@ static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) void migrate_irqs(void) { unsigned int i, cpu = smp_processor_id(); - struct irq_desc *desc; - for_each_irq_desc(i, desc) { - struct irq_data *data = irq_desc_get_irq_data(desc); + for_each_active_irq(i) { + struct irq_data *data = irq_get_irq_data(i); unsigned int newcpu; if (irqd_is_per_cpu(data)) @@ -194,11 +181,8 @@ void migrate_irqs(void) i, cpu); cpumask_setall(data->affinity); - newcpu = cpumask_any_and(data->affinity, - cpu_online_mask); } - - route_irq(data, i, newcpu); + irq_set_affinity(i, data->affinity); } } #endif /* CONFIG_HOTPLUG_CPU */ -- cgit v1.2.3-55-g7522 From 2958a489d7d31552fd1a0a8f54a5005c278d4606 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Tue, 4 Mar 2014 21:29:13 +0100 Subject: ia64: Remove deprecated IRQF_DISABLED This patch removes the IRQF_DISABLED flag from ia64 architecture code. It's a NOOP since 2.6.35 and it will be removed one day. Signed-off-by: Michael Opdenacker Cc: paul.gortmaker@windriver.com Cc: viro@zeniv.linux.org.uk Cc: srivatsa.bhat@linux.vnet.ibm.com Cc: andriy.shevchenko@linux.intel.com Cc: fenghua.yu@intel.com Cc: tony.luck@intel.com Link: http://lkml.kernel.org/r/1393964953-17002-1-git-send-email-michael.opdenacker@free-electrons.com Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/irq_ia64.c | 4 ---- arch/ia64/kernel/mca.c | 6 ------ arch/ia64/kernel/perfmon.c | 1 - arch/ia64/kernel/time.c | 2 +- 4 files changed, 1 insertion(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index c8a576b27736..0884f5ecbcc3 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -364,7 +364,6 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) static struct irqaction irq_move_irqaction = { .handler = smp_irq_move_cleanup_interrupt, - .flags = IRQF_DISABLED, .name = "irq_move" }; @@ -600,7 +599,6 @@ static irqreturn_t dummy_handler (int irq, void *dev_id) static struct irqaction ipi_irqaction = { .handler = handle_IPI, - .flags = IRQF_DISABLED, .name = "IPI" }; @@ -609,13 +607,11 @@ static struct irqaction ipi_irqaction = { */ static struct irqaction resched_irqaction = { .handler = dummy_handler, - .flags = IRQF_DISABLED, .name = "resched" }; static struct irqaction tlb_irqaction = { .handler = dummy_handler, - .flags = IRQF_DISABLED, .name = "tlb_flush" }; diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index b8edfa75a83f..33f1462b3379 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1772,38 +1772,32 @@ __setup("disable_cpe_poll", ia64_mca_disable_cpe_polling); static struct irqaction cmci_irqaction = { .handler = ia64_mca_cmc_int_handler, - .flags = IRQF_DISABLED, .name = "cmc_hndlr" }; static struct irqaction cmcp_irqaction = { .handler = ia64_mca_cmc_int_caller, - .flags = IRQF_DISABLED, .name = "cmc_poll" }; static struct irqaction mca_rdzv_irqaction = { .handler = ia64_mca_rendez_int_handler, - .flags = IRQF_DISABLED, .name = "mca_rdzv" }; static struct irqaction mca_wkup_irqaction = { .handler = ia64_mca_wakeup_int_handler, - .flags = IRQF_DISABLED, .name = "mca_wkup" }; #ifdef CONFIG_ACPI static struct irqaction mca_cpe_irqaction = { .handler = ia64_mca_cpe_int_handler, - .flags = IRQF_DISABLED, .name = "cpe_hndlr" }; static struct irqaction mca_cpep_irqaction = { .handler = ia64_mca_cpe_int_caller, - .flags = IRQF_DISABLED, .name = "cpe_poll" }; #endif /* CONFIG_ACPI */ diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index cb592773c78b..d841c4bd6864 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -6387,7 +6387,6 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) static struct irqaction perfmon_irqaction = { .handler = pfm_interrupt_handler, - .flags = IRQF_DISABLED, .name = "perfmon" }; diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index fbaac1afb844..71c52bc7c28d 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -380,7 +380,7 @@ static cycle_t itc_get_cycles(struct clocksource *cs) static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, + .flags = IRQF_IRQPOLL, .name = "timer" }; -- cgit v1.2.3-55-g7522 From 322a126a8fa8af80d9dc06e7168db11d1aabdba7 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Tue, 4 Mar 2014 21:31:51 +0100 Subject: mn10300: Remove deprecated IRQF_DISABLED This patch removes the IRQF_DISABLED flag from mn10300 architecture code. It's a NOOP since 2.6.35 and it will be removed one day. Signed-off-by: Michael Opdenacker Cc: srivatsa.bhat@linux.vnet.ibm.com Cc: linux-am33-list@redhat.com Cc: dhowells@redhat.com Cc: yasutake.koichi@jp.panasonic.com Link: http://lkml.kernel.org/r/1393965111-17092-1-git-send-email-michael.opdenacker@free-electrons.com Signed-off-by: Thomas Gleixner --- arch/mn10300/kernel/cevt-mn10300.c | 2 +- arch/mn10300/kernel/mn10300-serial.c | 6 +++--- arch/mn10300/kernel/smp.c | 2 +- arch/mn10300/unit-asb2364/irq-fpga.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c index ccce35e3e179..60f64ca1752a 100644 --- a/arch/mn10300/kernel/cevt-mn10300.c +++ b/arch/mn10300/kernel/cevt-mn10300.c @@ -113,7 +113,7 @@ int __init init_clockevents(void) cd->set_next_event = next_event; iact = &per_cpu(timer_irq, cpu); - iact->flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER; + iact->flags = IRQF_SHARED | IRQF_TIMER; iact->handler = timer_interrupt; clockevents_register_device(cd); diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index bf6e949a2f87..7ecf69879e2d 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c @@ -985,17 +985,17 @@ static int mn10300_serial_startup(struct uart_port *_port) irq_set_chip(port->tm_irq, &mn10300_serial_pic); if (request_irq(port->rx_irq, mn10300_serial_interrupt, - IRQF_DISABLED | IRQF_NOBALANCING, + IRQF_NOBALANCING, port->rx_name, port) < 0) goto error; if (request_irq(port->tx_irq, mn10300_serial_interrupt, - IRQF_DISABLED | IRQF_NOBALANCING, + IRQF_NOBALANCING, port->tx_name, port) < 0) goto error2; if (request_irq(port->tm_irq, mn10300_serial_interrupt, - IRQF_DISABLED | IRQF_NOBALANCING, + IRQF_NOBALANCING, port->tm_name, port) < 0) goto error3; mn10300_serial_mask_ack(port->tm_irq); diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index a17f9c9c14c9..f984193718b1 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c @@ -143,7 +143,7 @@ static struct irqaction call_function_ipi = { static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id); static struct irqaction local_timer_ipi = { .handler = smp_ipi_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .flags = IRQF_NOBALANCING, .name = "smp local timer IPI" }; #endif diff --git a/arch/mn10300/unit-asb2364/irq-fpga.c b/arch/mn10300/unit-asb2364/irq-fpga.c index e16c216f31dc..073e2ccc4a44 100644 --- a/arch/mn10300/unit-asb2364/irq-fpga.c +++ b/arch/mn10300/unit-asb2364/irq-fpga.c @@ -76,7 +76,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask) static struct irqaction fpga_irq[] = { [0] = { .handler = fpga_interrupt, - .flags = IRQF_DISABLED | IRQF_SHARED, + .flags = IRQF_SHARED, .name = "fpga", }, }; -- cgit v1.2.3-55-g7522 From d20d2efbf227042920d386b8eda878815f63c987 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Tue, 4 Mar 2014 21:35:05 +0100 Subject: x86: Remove deprecated IRQF_DISABLED This patch removes the IRQF_DISABLED flag from x86 architecture code. It's a NOOP since 2.6.35 and it will be removed one day. Signed-off-by: Michael Opdenacker Cc: venki@google.com Link: http://lkml.kernel.org/r/1393965305-17248-1-git-send-email-michael.opdenacker@free-electrons.com Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/floppy.h | 4 ++-- arch/x86/kernel/hpet.c | 2 +- arch/x86/kernel/time.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/floppy.h b/arch/x86/include/asm/floppy.h index d3d74698dce9..1c7eefe32502 100644 --- a/arch/x86/include/asm/floppy.h +++ b/arch/x86/include/asm/floppy.h @@ -145,10 +145,10 @@ static int fd_request_irq(void) { if (can_use_virtual_dma) return request_irq(FLOPPY_IRQ, floppy_hardint, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); else return request_irq(FLOPPY_IRQ, floppy_interrupt, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); } static unsigned long dma_mem_alloc(unsigned long size) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index da85a8e830a1..45d2ded7b1e2 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -521,7 +521,7 @@ static int hpet_setup_irq(struct hpet_dev *dev) { if (request_irq(dev->irq, hpet_interrupt_handler, - IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING, + IRQF_TIMER | IRQF_NOBALANCING, dev->name, dev)) return -1; diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index 24d3c91e9812..36b2cee629cb 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -62,7 +62,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, + .flags = IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, .name = "timer" }; -- cgit v1.2.3-55-g7522 From 86134a1b39fd056a7b6778608a5882f0ea1bc705 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 1 Aug 2013 13:33:26 +0100 Subject: x86/boot: Cleanup header.S by removing some #ifdefs handover_offset is now filled out by build.c. Don't set a default value as it will be overwritten anyway. Acked-by: Borislav Petkov Signed-off-by: Matt Fleming --- arch/x86/boot/header.S | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index ec3b8ba68096..d69d96653325 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -426,13 +426,7 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr #define INIT_SIZE VO_INIT_SIZE #endif init_size: .long INIT_SIZE # kernel initialization size -handover_offset: -#ifdef CONFIG_EFI_STUB - .long 0x30 # offset to the handover - # protocol entry point -#else - .long 0 -#endif +handover_offset: .long 0 # Filled in by build.c # End of setup header ##################################################### -- cgit v1.2.3-55-g7522 From 993c30a04e205fb239c0875b25b43ddef0499845 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 1 Aug 2013 14:18:49 +0100 Subject: x86, tools: Consolidate #ifdef code Instead of littering main() with #ifdef CONFIG_EFI_STUB, move the logic into separate functions that do nothing if the config option isn't set. This makes main() much easier to read. Acked-by: Borislav Petkov Signed-off-by: Matt Fleming --- arch/x86/boot/tools/build.c | 64 +++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index 8e15b22391fc..bf262077ec92 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -219,6 +219,45 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz) update_pecoff_section_header(".text", text_start, text_sz); } +static int reserve_pecoff_reloc_section(int c) +{ + /* Reserve 0x20 bytes for .reloc section */ + memset(buf+c, 0, PECOFF_RELOC_RESERVE); + return PECOFF_RELOC_RESERVE; +} + +static void efi_stub_defaults(void) +{ + /* Defaults for old kernel */ +#ifdef CONFIG_X86_32 + efi_pe_entry = 0x10; + efi_stub_entry = 0x30; +#else + efi_pe_entry = 0x210; + efi_stub_entry = 0x230; + startup_64 = 0x200; +#endif +} + +static void efi_stub_entry_update(void) +{ +#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */ + efi_stub_entry -= 0x200; +#endif + put_unaligned_le32(efi_stub_entry, &buf[0x264]); +} + +#else + +static inline void update_pecoff_setup_and_reloc(unsigned int) {} +static inline void update_pecoff_text(unsigned int, unsigned int) {} +static inline void efi_stub_defaults(void) {} +static inline void efi_stup_entry_update(void) {} + +static inline int reserve_pecoff_reloc_section(int c) +{ + return 0; +} #endif /* CONFIG_EFI_STUB */ @@ -271,15 +310,7 @@ int main(int argc, char ** argv) void *kernel; u32 crc = 0xffffffffUL; - /* Defaults for old kernel */ -#ifdef CONFIG_X86_32 - efi_pe_entry = 0x10; - efi_stub_entry = 0x30; -#else - efi_pe_entry = 0x210; - efi_stub_entry = 0x230; - startup_64 = 0x200; -#endif + efi_stub_defaults(); if (argc != 5) usage(); @@ -302,11 +333,7 @@ int main(int argc, char ** argv) die("Boot block hasn't got boot flag (0xAA55)"); fclose(file); -#ifdef CONFIG_EFI_STUB - /* Reserve 0x20 bytes for .reloc section */ - memset(buf+c, 0, PECOFF_RELOC_RESERVE); - c += PECOFF_RELOC_RESERVE; -#endif + c += reserve_pecoff_reloc_section(c); /* Pad unused space with zeros */ setup_sectors = (c + 511) / 512; @@ -315,9 +342,7 @@ int main(int argc, char ** argv) i = setup_sectors*512; memset(buf+c, 0, i-c); -#ifdef CONFIG_EFI_STUB update_pecoff_setup_and_reloc(i); -#endif /* Set the default root device */ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); @@ -342,14 +367,9 @@ int main(int argc, char ** argv) buf[0x1f1] = setup_sectors-1; put_unaligned_le32(sys_size, &buf[0x1f4]); -#ifdef CONFIG_EFI_STUB update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz)); -#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */ - efi_stub_entry -= 0x200; -#endif - put_unaligned_le32(efi_stub_entry, &buf[0x264]); -#endif + efi_stub_entry_update(); crc = partial_crc32(buf, i, crc); if (fwrite(buf, 1, i, dest) != i) -- cgit v1.2.3-55-g7522 From 426e34cc4f6094cefe4f3175764cdf583128e7cd Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 6 Dec 2013 21:13:04 +0000 Subject: x86/mm/pageattr: Always dump the right page table in an oops Now that we have EFI-specific page tables we need to lookup the pgd when dumping those page tables, rather than assuming that swapper_pgdir is the current pgdir. Remove the double underscore prefix, which is usually reserved for static functions. Acked-by: Borislav Petkov Signed-off-by: Matt Fleming --- arch/x86/include/asm/pgtable_types.h | 2 ++ arch/x86/mm/fault.c | 7 ++++++- arch/x86/mm/pageattr.c | 12 ++++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 1aa9ccd43223..24ae4211ba34 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -382,6 +382,8 @@ static inline void update_page_count(int level, unsigned long pages) { } * as a pte too. */ extern pte_t *lookup_address(unsigned long address, unsigned int *level); +extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, + unsigned int *level); extern phys_addr_t slow_virt_to_phys(void *__address); extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address, unsigned numpages, unsigned long page_flags); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 6dea040cc3a1..6055a2001b27 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -584,8 +584,13 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, if (error_code & PF_INSTR) { unsigned int level; + pgd_t *pgd; + pte_t *pte; - pte_t *pte = lookup_address(address, &level); + pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK); + pgd += pgd_index(address); + + pte = lookup_address_in_pgd(pgd, address, &level); if (pte && pte_present(*pte) && !pte_exec(*pte)) printk(nx_warning, from_kuid(&init_user_ns, current_uid())); diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index b3b19f46c016..14c656f0483b 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -323,8 +323,12 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, return prot; } -static pte_t *__lookup_address_in_pgd(pgd_t *pgd, unsigned long address, - unsigned int *level) +/* + * Lookup the page table entry for a virtual address in a specific pgd. + * Return a pointer to the entry and the level of the mapping. + */ +pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, + unsigned int *level) { pud_t *pud; pmd_t *pmd; @@ -365,7 +369,7 @@ static pte_t *__lookup_address_in_pgd(pgd_t *pgd, unsigned long address, */ pte_t *lookup_address(unsigned long address, unsigned int *level) { - return __lookup_address_in_pgd(pgd_offset_k(address), address, level); + return lookup_address_in_pgd(pgd_offset_k(address), address, level); } EXPORT_SYMBOL_GPL(lookup_address); @@ -373,7 +377,7 @@ static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, unsigned int *level) { if (cpa->pgd) - return __lookup_address_in_pgd(cpa->pgd + pgd_index(address), + return lookup_address_in_pgd(cpa->pgd + pgd_index(address), address, level); return lookup_address(address, level); -- cgit v1.2.3-55-g7522 From 099240ac111aac454962e6399c0cc51d1511504a Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 13:01:39 +0000 Subject: x86/efi: Delete dead code when checking for non-native Both efi_free_boot_services() and efi_enter_virtual_mode() are invoked from init/main.c, but only if the EFI runtime services are available. This is not the case for non-native boots, e.g. where a 64-bit kernel is booted with 32-bit EFI firmware. Delete the dead code. Acked-by: Borislav Petkov Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 1a201ac7cef8..b96ae7918a16 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -466,9 +466,6 @@ void __init efi_free_boot_services(void) { void *p; - if (!efi_is_native()) - return; - for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { efi_memory_desc_t *md = p; unsigned long long start = md->phys_addr; @@ -1005,15 +1002,6 @@ void __init efi_enter_virtual_mode(void) efi.systab = NULL; - /* - * We don't do virtual mode, since we don't do runtime services, on - * non-native EFI - */ - if (!efi_is_native()) { - efi_unmap_memmap(); - return; - } - if (efi_setup) { efi_map_regions_fixed(); } else { -- cgit v1.2.3-55-g7522 From 677703cef0a148ba07d37ced649ad25b1cda2f78 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 13:47:37 +0000 Subject: efi: Add separate 32-bit/64-bit definitions The traditional approach of using machine-specific types such as 'unsigned long' does not allow the kernel to interact with firmware running in a different CPU mode, e.g. 64-bit kernel with 32-bit EFI. Add distinct EFI structure definitions for both 32-bit and 64-bit so that we can use them in the 32-bit and 64-bit code paths. Acked-by: Borislav Petkov Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.h | 44 +++++++ include/linux/efi.h | 252 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) (limited to 'arch') diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index 81b6b652b46a..d487e727f1ec 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -37,6 +37,24 @@ struct efi_graphics_output_mode_info { u32 pixels_per_scan_line; } __packed; +struct efi_graphics_output_protocol_mode_32 { + u32 max_mode; + u32 mode; + u32 info; + u32 size_of_info; + u64 frame_buffer_base; + u32 frame_buffer_size; +} __packed; + +struct efi_graphics_output_protocol_mode_64 { + u32 max_mode; + u32 mode; + u64 info; + u64 size_of_info; + u64 frame_buffer_base; + u64 frame_buffer_size; +} __packed; + struct efi_graphics_output_protocol_mode { u32 max_mode; u32 mode; @@ -46,6 +64,20 @@ struct efi_graphics_output_protocol_mode { unsigned long frame_buffer_size; } __packed; +struct efi_graphics_output_protocol_32 { + u32 query_mode; + u32 set_mode; + u32 blt; + u32 mode; +}; + +struct efi_graphics_output_protocol_64 { + u64 query_mode; + u64 set_mode; + u64 blt; + u64 mode; +}; + struct efi_graphics_output_protocol { void *query_mode; unsigned long set_mode; @@ -53,6 +85,18 @@ struct efi_graphics_output_protocol { struct efi_graphics_output_protocol_mode *mode; }; +struct efi_uga_draw_protocol_32 { + u32 get_mode; + u32 set_mode; + u32 blt; +}; + +struct efi_uga_draw_protocol_64 { + u64 get_mode; + u64 set_mode; + u64 blt; +}; + struct efi_uga_draw_protocol { void *get_mode; void *set_mode; diff --git a/include/linux/efi.h b/include/linux/efi.h index 0a819e7a60c9..42c662729e13 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -153,6 +153,102 @@ typedef struct { u8 sets_to_zero; } efi_time_cap_t; +typedef struct { + efi_table_hdr_t hdr; + u32 raise_tpl; + u32 restore_tpl; + u32 allocate_pages; + u32 free_pages; + u32 get_memory_map; + u32 allocate_pool; + u32 free_pool; + u32 create_event; + u32 set_timer; + u32 wait_for_event; + u32 signal_event; + u32 close_event; + u32 check_event; + u32 install_protocol_interface; + u32 reinstall_protocol_interface; + u32 uninstall_protocol_interface; + u32 handle_protocol; + u32 __reserved; + u32 register_protocol_notify; + u32 locate_handle; + u32 locate_device_path; + u32 install_configuration_table; + u32 load_image; + u32 start_image; + u32 exit; + u32 unload_image; + u32 exit_boot_services; + u32 get_next_monotonic_count; + u32 stall; + u32 set_watchdog_timer; + u32 connect_controller; + u32 disconnect_controller; + u32 open_protocol; + u32 close_protocol; + u32 open_protocol_information; + u32 protocols_per_handle; + u32 locate_handle_buffer; + u32 locate_protocol; + u32 install_multiple_protocol_interfaces; + u32 uninstall_multiple_protocol_interfaces; + u32 calculate_crc32; + u32 copy_mem; + u32 set_mem; + u32 create_event_ex; +} __packed efi_boot_services_32_t; + +typedef struct { + efi_table_hdr_t hdr; + u64 raise_tpl; + u64 restore_tpl; + u64 allocate_pages; + u64 free_pages; + u64 get_memory_map; + u64 allocate_pool; + u64 free_pool; + u64 create_event; + u64 set_timer; + u64 wait_for_event; + u64 signal_event; + u64 close_event; + u64 check_event; + u64 install_protocol_interface; + u64 reinstall_protocol_interface; + u64 uninstall_protocol_interface; + u64 handle_protocol; + u64 __reserved; + u64 register_protocol_notify; + u64 locate_handle; + u64 locate_device_path; + u64 install_configuration_table; + u64 load_image; + u64 start_image; + u64 exit; + u64 unload_image; + u64 exit_boot_services; + u64 get_next_monotonic_count; + u64 stall; + u64 set_watchdog_timer; + u64 connect_controller; + u64 disconnect_controller; + u64 open_protocol; + u64 close_protocol; + u64 open_protocol_information; + u64 protocols_per_handle; + u64 locate_handle_buffer; + u64 locate_protocol; + u64 install_multiple_protocol_interfaces; + u64 uninstall_multiple_protocol_interfaces; + u64 calculate_crc32; + u64 copy_mem; + u64 set_mem; + u64 create_event_ex; +} __packed efi_boot_services_64_t; + /* * EFI Boot Services table */ @@ -231,12 +327,61 @@ typedef enum { EfiPciIoAttributeOperationMaximum } EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; +typedef struct { + u32 read; + u32 write; +} efi_pci_io_protocol_access_32_t; + +typedef struct { + u64 read; + u64 write; +} efi_pci_io_protocol_access_64_t; typedef struct { void *read; void *write; } efi_pci_io_protocol_access_t; +typedef struct { + u32 poll_mem; + u32 poll_io; + efi_pci_io_protocol_access_32_t mem; + efi_pci_io_protocol_access_32_t io; + efi_pci_io_protocol_access_32_t pci; + u32 copy_mem; + u32 map; + u32 unmap; + u32 allocate_buffer; + u32 free_buffer; + u32 flush; + u32 get_location; + u32 attributes; + u32 get_bar_attributes; + u32 set_bar_attributes; + uint64_t romsize; + void *romimage; +} efi_pci_io_protocol_32; + +typedef struct { + u64 poll_mem; + u64 poll_io; + efi_pci_io_protocol_access_64_t mem; + efi_pci_io_protocol_access_64_t io; + efi_pci_io_protocol_access_64_t pci; + u64 copy_mem; + u64 map; + u64 unmap; + u64 allocate_buffer; + u64 free_buffer; + u64 flush; + u64 get_location; + u64 attributes; + u64 get_bar_attributes; + u64 set_bar_attributes; + uint64_t romsize; + void *romimage; +} efi_pci_io_protocol_64; + typedef struct { void *poll_mem; void *poll_io; @@ -290,6 +435,42 @@ typedef struct { #define EFI_RUNTIME_SERVICES_SIGNATURE ((u64)0x5652453544e5552ULL) #define EFI_RUNTIME_SERVICES_REVISION 0x00010000 +typedef struct { + efi_table_hdr_t hdr; + u32 get_time; + u32 set_time; + u32 get_wakeup_time; + u32 set_wakeup_time; + u32 set_virtual_address_map; + u32 convert_pointer; + u32 get_variable; + u32 get_next_variable; + u32 set_variable; + u32 get_next_high_mono_count; + u32 reset_system; + u32 update_capsule; + u32 query_capsule_caps; + u32 query_variable_info; +} efi_runtime_services_32_t; + +typedef struct { + efi_table_hdr_t hdr; + u64 get_time; + u64 set_time; + u64 get_wakeup_time; + u64 set_wakeup_time; + u64 set_virtual_address_map; + u64 convert_pointer; + u64 get_variable; + u64 get_next_variable; + u64 set_variable; + u64 get_next_high_mono_count; + u64 reset_system; + u64 update_capsule; + u64 query_capsule_caps; + u64 query_variable_info; +} efi_runtime_services_64_t; + typedef struct { efi_table_hdr_t hdr; void *get_time; @@ -483,6 +664,38 @@ struct efi_memory_map { unsigned long desc_size; }; +typedef struct { + u32 revision; + u32 parent_handle; + u32 system_table; + u32 device_handle; + u32 file_path; + u32 reserved; + u32 load_options_size; + u32 load_options; + u32 image_base; + __aligned_u64 image_size; + unsigned int image_code_type; + unsigned int image_data_type; + unsigned long unload; +} efi_loaded_image_32_t; + +typedef struct { + u32 revision; + u64 parent_handle; + u64 system_table; + u64 device_handle; + u64 file_path; + u64 reserved; + u32 load_options_size; + u64 load_options; + u64 image_base; + __aligned_u64 image_size; + unsigned int image_code_type; + unsigned int image_data_type; + unsigned long unload; +} efi_loaded_image_64_t; + typedef struct { u32 revision; void *parent_handle; @@ -511,6 +724,34 @@ typedef struct { efi_char16_t filename[1]; } efi_file_info_t; +typedef struct { + u64 revision; + u32 open; + u32 close; + u32 delete; + u32 read; + u32 write; + u32 get_position; + u32 set_position; + u32 get_info; + u32 set_info; + u32 flush; +} efi_file_handle_32_t; + +typedef struct { + u64 revision; + u64 open; + u64 close; + u64 delete; + u64 read; + u64 write; + u64 get_position; + u64 set_position; + u64 get_info; + u64 set_info; + u64 flush; +} efi_file_handle_64_t; + typedef struct _efi_file_handle { u64 revision; efi_status_t (*open)(struct _efi_file_handle *, @@ -809,6 +1050,17 @@ struct efivar_entry { bool deleting; }; +struct efi_simple_text_output_protocol_32 { + u32 reset; + u32 output_string; + u32 test_string; +}; + +struct efi_simple_text_output_protocol_64 { + u64 reset; + u64 output_string; + u64 test_string; +}; struct efi_simple_text_output_protocol { void *reset; -- cgit v1.2.3-55-g7522 From 54b52d87268034859191d671505bb1cfce6bd74d Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 15:27:14 +0000 Subject: x86/efi: Build our own EFI services pointer table It's not possible to dereference the EFI System table directly when booting a 64-bit kernel on a 32-bit EFI firmware because the size of pointers don't match. In preparation for supporting the above use case, build a list of function pointers on boot so that callers don't have to worry about converting pointer sizes through multiple levels of indirection. Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.c | 319 ++++++++++++++++++++++++--------- arch/x86/boot/compressed/eboot.h | 16 ++ arch/x86/boot/compressed/head_32.S | 48 ++++- arch/x86/boot/compressed/head_64.S | 57 ++++-- drivers/firmware/efi/efi-stub-helper.c | 148 ++++----------- 5 files changed, 377 insertions(+), 211 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index a7677babf946..42548168bdc3 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -19,10 +19,145 @@ static efi_system_table_t *sys_table; +static struct efi_config *efi_early; + +#define BOOT_SERVICES(bits) \ +static void setup_boot_services##bits(struct efi_config *c) \ +{ \ + efi_system_table_##bits##_t *table; \ + efi_boot_services_##bits##_t *bt; \ + \ + table = (typeof(table))sys_table; \ + \ + c->text_output = table->con_out; \ + \ + bt = (typeof(bt))(unsigned long)(table->boottime); \ + \ + c->allocate_pool = bt->allocate_pool; \ + c->allocate_pages = bt->allocate_pages; \ + c->get_memory_map = bt->get_memory_map; \ + c->free_pool = bt->free_pool; \ + c->free_pages = bt->free_pages; \ + c->locate_handle = bt->locate_handle; \ + c->handle_protocol = bt->handle_protocol; \ + c->exit_boot_services = bt->exit_boot_services; \ +} +BOOT_SERVICES(32); +BOOT_SERVICES(64); -#include "../../../../drivers/firmware/efi/efi-stub-helper.c" +static void efi_printk(efi_system_table_t *, char *); +static void efi_char16_printk(efi_system_table_t *, efi_char16_t *); + +static efi_status_t +efi_file_size(efi_system_table_t *sys_table, void *__fh, + efi_char16_t *filename_16, void **handle, u64 *file_sz) +{ + efi_file_handle_t *h, *fh = __fh; + efi_file_info_t *info; + efi_status_t status; + efi_guid_t info_guid = EFI_FILE_INFO_ID; + u32 info_sz; + + status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, + EFI_FILE_MODE_READ, (u64)0); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to open file: "); + efi_char16_printk(sys_table, filename_16); + efi_printk(sys_table, "\n"); + return status; + } + + *handle = h; + + info_sz = 0; + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, + &info_sz, NULL); + if (status != EFI_BUFFER_TOO_SMALL) { + efi_printk(sys_table, "Failed to get file info size\n"); + return status; + } + +grow: + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + info_sz, (void **)&info); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to alloc mem for file info\n"); + return status; + } + + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, + &info_sz, info); + if (status == EFI_BUFFER_TOO_SMALL) { + efi_early->call(efi_early->free_pool, info); + goto grow; + } + + *file_sz = info->file_size; + efi_early->call(efi_early->free_pool, info); + + if (status != EFI_SUCCESS) + efi_printk(sys_table, "Failed to get initrd info\n"); + + return status; +} + +static inline efi_status_t +efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr) +{ + efi_file_handle_t *fh = __fh; + return efi_early->call((unsigned long)fh->read, handle, size, addr); +} + +static inline efi_status_t efi_file_close(void *__fh, void *handle) +{ + efi_file_handle_t *fh = __fh; + return efi_early->call((unsigned long)fh->close, handle); +} + +static inline efi_status_t +efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) +{ + efi_file_io_interface_t *io; + efi_loaded_image_t *image = __image; + efi_file_handle_t *fh; + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; + efi_status_t status; + void *handle = (void *)(unsigned long)image->device_handle; + u32 func; + + status = efi_early->call(efi_early->handle_protocol, handle, + &fs_proto, (void **)&io); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to handle fs_proto\n"); + return status; + } + func = (unsigned long)io->open_volume; + status = efi_early->call(func, io, &fh); + if (status != EFI_SUCCESS) + efi_printk(sys_table, "Failed to open volume\n"); + + *__fh = fh; + return status; +} + +static inline void +efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) +{ + struct efi_simple_text_output_protocol *out; + unsigned long output_string; + size_t offset; + unsigned long *func; + + offset = offsetof(typeof(*out), output_string); + output_string = efi_early->text_output + offset; + func = (unsigned long *)output_string; + + efi_early->call(*func, efi_early->text_output, str); +} + +#include "../../../../drivers/firmware/efi/efi-stub-helper.c" static void find_bits(unsigned long mask, u8 *pos, u8 *size) { @@ -51,7 +186,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; efi_status_t status; - void **pci_handle; + void **pci_handle = NULL; efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; unsigned long nr_pci, size = 0; int i; @@ -62,20 +197,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params) while (data && data->next) data = (struct setup_data *)(unsigned long)data->next; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &pci_proto, - NULL, &size, pci_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &pci_proto, NULL, &size, pci_handle); if (status == EFI_BUFFER_TOO_SMALL) { - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, size, &pci_handle); + status = efi_early->call(efi_early->allocate_pool, + EFI_LOADER_DATA, + size, (void **)&pci_handle); if (status != EFI_SUCCESS) return status; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &pci_proto, - NULL, &size, pci_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, &pci_proto, + NULL, &size, pci_handle); } if (status != EFI_SUCCESS) @@ -87,8 +223,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params) uint64_t attributes; struct pci_setup_rom *rom; - status = efi_call_phys3(sys_table->boottime->handle_protocol, - h, &pci_proto, &pci); + status = efi_early->call(efi_early->handle_protocol, h, + &pci_proto, (void **)&pci); if (status != EFI_SUCCESS) continue; @@ -97,13 +233,13 @@ static efi_status_t setup_efi_pci(struct boot_params *params) continue; #ifdef CONFIG_X86_64 - status = efi_call_phys4(pci->attributes, pci, - EfiPciIoAttributeOperationGet, 0, - &attributes); + status = efi_early->call((unsigned long)pci->attributes, pci, + EfiPciIoAttributeOperationGet, 0, + &attributes); #else - status = efi_call_phys5(pci->attributes, pci, - EfiPciIoAttributeOperationGet, 0, 0, - &attributes); + status = efi_early->call((unsigned long)pci->attributes, pci, + EfiPciIoAttributeOperationGet, 0, 0, + &attributes); #endif if (status != EFI_SUCCESS) continue; @@ -113,8 +249,8 @@ static efi_status_t setup_efi_pci(struct boot_params *params) size = pci->romsize + sizeof(*rom); - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, size, &rom); + status = efi_early->call(efi_early->allocate_pool, + EFI_LOADER_DATA, size, &rom); if (status != EFI_SUCCESS) continue; @@ -124,23 +260,23 @@ static efi_status_t setup_efi_pci(struct boot_params *params) rom->data.next = 0; rom->pcilen = pci->romsize; - status = efi_call_phys5(pci->pci.read, pci, - EfiPciIoWidthUint16, PCI_VENDOR_ID, - 1, &(rom->vendor)); + status = efi_early->call((unsigned long)pci->pci.read, pci, + EfiPciIoWidthUint16, PCI_VENDOR_ID, + 1, &(rom->vendor)); if (status != EFI_SUCCESS) goto free_struct; - status = efi_call_phys5(pci->pci.read, pci, - EfiPciIoWidthUint16, PCI_DEVICE_ID, - 1, &(rom->devid)); + status = efi_early->call((unsigned long)pci->pci.read, pci, + EfiPciIoWidthUint16, PCI_DEVICE_ID, + 1, &(rom->devid)); if (status != EFI_SUCCESS) goto free_struct; - status = efi_call_phys5(pci->get_location, pci, - &(rom->segment), &(rom->bus), - &(rom->device), &(rom->function)); + status = efi_early->call((unsigned long)pci->get_location, pci, + &(rom->segment), &(rom->bus), + &(rom->device), &(rom->function)); if (status != EFI_SUCCESS) goto free_struct; @@ -156,11 +292,11 @@ static efi_status_t setup_efi_pci(struct boot_params *params) continue; free_struct: - efi_call_phys1(sys_table->boottime->free_pool, rom); + efi_early->call(efi_early->free_pool, rom); } free_handle: - efi_call_phys1(sys_table->boottime->free_pool, pci_handle); + efi_early->call(efi_early->free_pool, pci_handle); return status; } @@ -174,21 +310,21 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, struct efi_pixel_bitmask pixel_info; unsigned long nr_gops; efi_status_t status; - void **gop_handle; + void **gop_handle = NULL; u16 width, height; u32 fb_base, fb_size; u32 pixels_per_scan_line; int pixel_format; int i; - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, size, &gop_handle); + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + size, (void **)&gop_handle); if (status != EFI_SUCCESS) return status; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, proto, - NULL, &size, gop_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + proto, NULL, &size, gop_handle); if (status != EFI_SUCCESS) goto free_handle; @@ -202,19 +338,18 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, void *dummy; void *h = gop_handle[i]; - status = efi_call_phys3(sys_table->boottime->handle_protocol, - h, proto, &gop); + status = efi_early->call(efi_early->handle_protocol, h, + proto, (void **)&gop); if (status != EFI_SUCCESS) continue; - status = efi_call_phys3(sys_table->boottime->handle_protocol, - h, &conout_proto, &dummy); - + status = efi_early->call(efi_early->handle_protocol, h, + &conout_proto, &dummy); if (status == EFI_SUCCESS) conout_found = true; - status = efi_call_phys4(gop->query_mode, gop, - gop->mode->mode, &size, &info); + status = efi_early->call((unsigned long)gop->query_mode, gop, + gop->mode->mode, &size, &info); if (status == EFI_SUCCESS && (!first_gop || conout_found)) { /* * Systems that use the UEFI Console Splitter may @@ -303,7 +438,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; free_handle: - efi_call_phys1(sys_table->boottime->free_pool, gop_handle); + efi_early->call(efi_early->free_pool, gop_handle); return status; } @@ -320,14 +455,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, void **uga_handle = NULL; int i; - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, size, &uga_handle); + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + size, (void **)&uga_handle); if (status != EFI_SUCCESS) return status; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, uga_proto, - NULL, &size, uga_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + uga_proto, NULL, &size, uga_handle); if (status != EFI_SUCCESS) goto free_handle; @@ -340,16 +475,16 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, u32 w, h, depth, refresh; void *pciio; - status = efi_call_phys3(sys_table->boottime->handle_protocol, - handle, uga_proto, &uga); + status = efi_early->call(efi_early->handle_protocol, handle, + uga_proto, (void **)&uga); if (status != EFI_SUCCESS) continue; - efi_call_phys3(sys_table->boottime->handle_protocol, - handle, &pciio_proto, &pciio); + efi_early->call(efi_early->handle_protocol, handle, + &pciio_proto, &pciio); - status = efi_call_phys5(uga->get_mode, uga, &w, &h, - &depth, &refresh); + status = efi_early->call((unsigned long)uga->get_mode, uga, + &w, &h, &depth, &refresh); if (status == EFI_SUCCESS && (!first_uga || pciio)) { width = w; height = h; @@ -386,7 +521,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, free_handle: - efi_call_phys1(sys_table->boottime->free_pool, uga_handle); + efi_early->call(efi_early->free_pool, uga_handle); return status; } @@ -404,29 +539,28 @@ void setup_graphics(struct boot_params *boot_params) memset(si, 0, sizeof(*si)); size = 0; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &graphics_proto, - NULL, &size, gop_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &graphics_proto, NULL, &size, gop_handle); if (status == EFI_BUFFER_TOO_SMALL) status = setup_gop(si, &graphics_proto, size); if (status != EFI_SUCCESS) { size = 0; - status = efi_call_phys5(sys_table->boottime->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &uga_proto, - NULL, &size, uga_handle); + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &uga_proto, NULL, &size, uga_handle); if (status == EFI_BUFFER_TOO_SMALL) setup_uga(si, &uga_proto, size); } } - /* * Because the x86 boot code expects to be passed a boot_params we * need to create one ourselves (usually the bootloader would create * one for us). */ -struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) +struct boot_params *make_boot_params(struct efi_config *c) { struct boot_params *boot_params; struct sys_desc_table *sdt; @@ -434,7 +568,7 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) struct setup_header *hdr; struct efi_info *efi; efi_loaded_image_t *image; - void *options; + void *options, *handle; efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; int options_size = 0; efi_status_t status; @@ -445,14 +579,21 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) unsigned long ramdisk_addr; unsigned long ramdisk_size; - sys_table = _table; + efi_early = c; + sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; + handle = (void *)(unsigned long)efi_early->image_handle; /* Check if we were booted by the EFI firmware */ if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) return NULL; - status = efi_call_phys3(sys_table->boottime->handle_protocol, - handle, &proto, (void *)&image); + if (efi_early->is64) + setup_boot_services64(efi_early); + else + setup_boot_services32(efi_early); + + status = efi_early->call(efi_early->handle_protocol, handle, + &proto, (void *)&image); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); return NULL; @@ -641,14 +782,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, sizeof(struct e820entry) * nr_desc; if (*e820ext) { - efi_call_phys1(sys_table->boottime->free_pool, *e820ext); + efi_early->call(efi_early->free_pool, *e820ext); *e820ext = NULL; *e820ext_size = 0; } - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, size, e820ext); - + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + size, (void **)e820ext); if (status == EFI_SUCCESS) *e820ext_size = size; @@ -691,7 +831,7 @@ get_map: if (status != EFI_SUCCESS) goto free_mem_map; - efi_call_phys1(sys_table->boottime->free_pool, mem_map); + efi_early->call(efi_early->free_pool, mem_map); goto get_map; /* Allocated memory, get map again */ } @@ -708,8 +848,7 @@ get_map: #endif /* Might as well exit boot services now */ - status = efi_call_phys2(sys_table->boottime->exit_boot_services, - handle, key); + status = efi_early->call(efi_early->exit_boot_services, handle, key); if (status != EFI_SUCCESS) { /* * ExitBootServices() will fail if any of the event @@ -722,7 +861,7 @@ get_map: goto free_mem_map; called_exit = true; - efi_call_phys1(sys_table->boottime->free_pool, mem_map); + efi_early->call(efi_early->free_pool, mem_map); goto get_map; } @@ -736,23 +875,31 @@ get_map: return EFI_SUCCESS; free_mem_map: - efi_call_phys1(sys_table->boottime->free_pool, mem_map); + efi_early->call(efi_early->free_pool, mem_map); return status; } - /* * On success we return a pointer to a boot_params structure, and NULL * on failure. */ -struct boot_params *efi_main(void *handle, efi_system_table_t *_table, +struct boot_params *efi_main(struct efi_config *c, struct boot_params *boot_params) { - struct desc_ptr *gdt; + struct desc_ptr *gdt = NULL; efi_loaded_image_t *image; struct setup_header *hdr = &boot_params->hdr; efi_status_t status; struct desc_struct *desc; + void *handle; + efi_system_table_t *_table; + bool is64; + + efi_early = c; + + _table = (efi_system_table_t *)(unsigned long)efi_early->table; + handle = (void *)(unsigned long)efi_early->image_handle; + is64 = efi_early->is64; sys_table = _table; @@ -760,13 +907,17 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) goto fail; + if (is64) + setup_boot_services64(efi_early); + else + setup_boot_services32(efi_early); + setup_graphics(boot_params); setup_efi_pci(boot_params); - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*gdt), - (void **)&gdt); + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + sizeof(*gdt), (void **)&gdt); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); goto fail; diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index d487e727f1ec..c88c31ecad12 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -103,4 +103,20 @@ struct efi_uga_draw_protocol { void *blt; }; +struct efi_config { + u64 image_handle; + u64 table; + u64 allocate_pool; + u64 allocate_pages; + u64 get_memory_map; + u64 free_pool; + u64 free_pages; + u64 locate_handle; + u64 handle_protocol; + u64 exit_boot_services; + u64 text_output; + efi_status_t (*call)(unsigned long, ...); + bool is64; +} __packed; + #endif /* BOOT_COMPRESSED_EBOOT_H */ diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 9116aac232c7..eed23c087d6c 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -42,26 +42,53 @@ ENTRY(startup_32) ENTRY(efi_pe_entry) add $0x4, %esp + call 1f +1: popl %esi + subl $1b, %esi + + popl %ecx + movl %ecx, efi32_config(%esi) /* Handle */ + popl %ecx + movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 88(%eax) + pushl %eax + call make_boot_params cmpl $0, %eax - je 1f - movl 0x4(%esp), %esi - movl (%esp), %ecx + je fail + popl %ecx pushl %eax - pushl %esi pushl %ecx - sub $0x4, %esp + jmp 2f /* Skip efi_config initialization */ ENTRY(efi_stub_entry) add $0x4, %esp + popl %ecx + popl %edx + + call 1f +1: popl %esi + subl $1b, %esi + + movl %ecx, efi32_config(%esi) /* Handle */ + movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 88(%eax) + pushl %eax +2: call efi_main cmpl $0, %eax movl %eax, %esi jne 2f -1: +fail: /* EFI init failed, so hang. */ hlt - jmp 1b + jmp fail 2: call 3f 3: @@ -202,6 +229,13 @@ relocated: xorl %ebx, %ebx jmp *%eax + .data +efi32_config: + .fill 11,8,0 + .long efi_call_phys + .long 0 + .byte 0 + /* * Stack and heap for uncompression */ diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index c5c1ae0997e7..1bc206fa4bd0 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -209,26 +209,55 @@ ENTRY(startup_64) jmp preferred_addr ENTRY(efi_pe_entry) - mov %rcx, %rdi - mov %rdx, %rsi - pushq %rdi - pushq %rsi + movq %rcx, efi64_config(%rip) /* Handle */ + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + addq %rbp, efi64_config+88(%rip) + + movq %rax, %rdi call make_boot_params cmpq $0,%rax - je 1f - mov %rax, %rdx - popq %rsi - popq %rdi + je fail + mov %rax, %rsi + jmp 2f /* Skip the relocation */ ENTRY(efi_stub_entry) + movq %rdi, efi64_config(%rip) /* Handle */ + movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + movq efi_config(%rip), %rax + addq %rbp, 88(%rax) + movq %rdx, %rsi +2: + movq efi_config(%rip), %rdi call efi_main movq %rax,%rsi cmpq $0,%rax jne 2f -1: +fail: /* EFI init failed, so hang. */ hlt - jmp 1b + jmp fail 2: call 3f 3: @@ -372,6 +401,14 @@ gdt: .quad 0x0000000000000000 /* TS continued */ gdt_end: +efi_config: + .quad 0 + + .global efi64_config +efi64_config: + .fill 11,8,0 + .quad efi_call6 + .byte 1 /* * Stack and heap for uncompression */ diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c index b6bffbfd3be7..a0282872d97d 100644 --- a/drivers/firmware/efi/efi-stub-helper.c +++ b/drivers/firmware/efi/efi-stub-helper.c @@ -16,18 +16,6 @@ struct file_info { u64 size; }; - - - -static void efi_char16_printk(efi_system_table_t *sys_table_arg, - efi_char16_t *str) -{ - struct efi_simple_text_output_protocol *out; - - out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out; - efi_call_phys2(out->output_string, out, str); -} - static void efi_printk(efi_system_table_t *sys_table_arg, char *str) { char *s8; @@ -65,20 +53,23 @@ again: * allocation which may be in a new descriptor region. */ *map_size += sizeof(*m); - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, - EFI_LOADER_DATA, *map_size, (void **)&m); + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + *map_size, (void **)&m); if (status != EFI_SUCCESS) goto fail; - status = efi_call_phys5(sys_table_arg->boottime->get_memory_map, - map_size, m, &key, desc_size, &desc_version); + *desc_size = 0; + key = 0; + status = efi_early->call(efi_early->get_memory_map, map_size, m, + &key, desc_size, &desc_version); if (status == EFI_BUFFER_TOO_SMALL) { - efi_call_phys1(sys_table_arg->boottime->free_pool, m); + efi_early->call(efi_early->free_pool, m); goto again; } if (status != EFI_SUCCESS) - efi_call_phys1(sys_table_arg->boottime->free_pool, m); + efi_early->call(efi_early->free_pool, m); + if (key_ptr && status == EFI_SUCCESS) *key_ptr = key; if (desc_ver && status == EFI_SUCCESS) @@ -158,9 +149,9 @@ again: if (!max_addr) status = EFI_NOT_FOUND; else { - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &max_addr); + status = efi_early->call(efi_early->allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &max_addr); if (status != EFI_SUCCESS) { max = max_addr; max_addr = 0; @@ -170,8 +161,7 @@ again: *addr = max_addr; } - efi_call_phys1(sys_table_arg->boottime->free_pool, map); - + efi_early->call(efi_early->free_pool, map); fail: return status; } @@ -231,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, if ((start + size) > end) continue; - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &start); + status = efi_early->call(efi_early->allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &start); if (status == EFI_SUCCESS) { *addr = start; break; @@ -243,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, if (i == map_size / desc_size) status = EFI_NOT_FOUND; - efi_call_phys1(sys_table_arg->boottime->free_pool, map); + efi_early->call(efi_early->free_pool, map); fail: return status; } @@ -257,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size, return; nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages); + efi_early->call(efi_early->free_pages, addr, nr_pages); } @@ -276,9 +266,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, { struct file_info *files; unsigned long file_addr; - efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; u64 file_size_total; - efi_file_io_interface_t *io; efi_file_handle_t *fh; efi_status_t status; int nr_files; @@ -319,10 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, if (!nr_files) return EFI_SUCCESS; - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, - EFI_LOADER_DATA, - nr_files * sizeof(*files), - (void **)&files); + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + nr_files * sizeof(*files), (void **)&files); if (status != EFI_SUCCESS) { efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n"); goto fail; @@ -331,13 +317,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, str = cmd_line; for (i = 0; i < nr_files; i++) { struct file_info *file; - efi_file_handle_t *h; - efi_file_info_t *info; efi_char16_t filename_16[256]; - unsigned long info_sz; - efi_guid_t info_guid = EFI_FILE_INFO_ID; efi_char16_t *p; - u64 file_sz; str = strstr(str, option_string); if (!str) @@ -368,71 +349,18 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, /* Only open the volume once. */ if (!i) { - efi_boot_services_t *boottime; - - boottime = sys_table_arg->boottime; - - status = efi_call_phys3(boottime->handle_protocol, - image->device_handle, &fs_proto, - (void **)&io); - if (status != EFI_SUCCESS) { - efi_printk(sys_table_arg, "Failed to handle fs_proto\n"); - goto free_files; - } - - status = efi_call_phys2(io->open_volume, io, &fh); - if (status != EFI_SUCCESS) { - efi_printk(sys_table_arg, "Failed to open volume\n"); + status = efi_open_volume(sys_table_arg, image, + (void **)&fh); + if (status != EFI_SUCCESS) goto free_files; - } } - status = efi_call_phys5(fh->open, fh, &h, filename_16, - EFI_FILE_MODE_READ, (u64)0); - if (status != EFI_SUCCESS) { - efi_printk(sys_table_arg, "Failed to open file: "); - efi_char16_printk(sys_table_arg, filename_16); - efi_printk(sys_table_arg, "\n"); + status = efi_file_size(sys_table_arg, fh, filename_16, + (void **)&file->handle, &file->size); + if (status != EFI_SUCCESS) goto close_handles; - } - file->handle = h; - - info_sz = 0; - status = efi_call_phys4(h->get_info, h, &info_guid, - &info_sz, NULL); - if (status != EFI_BUFFER_TOO_SMALL) { - efi_printk(sys_table_arg, "Failed to get file info size\n"); - goto close_handles; - } - -grow: - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, - EFI_LOADER_DATA, info_sz, - (void **)&info); - if (status != EFI_SUCCESS) { - efi_printk(sys_table_arg, "Failed to alloc mem for file info\n"); - goto close_handles; - } - - status = efi_call_phys4(h->get_info, h, &info_guid, - &info_sz, info); - if (status == EFI_BUFFER_TOO_SMALL) { - efi_call_phys1(sys_table_arg->boottime->free_pool, - info); - goto grow; - } - - file_sz = info->file_size; - efi_call_phys1(sys_table_arg->boottime->free_pool, info); - - if (status != EFI_SUCCESS) { - efi_printk(sys_table_arg, "Failed to get file info\n"); - goto close_handles; - } - - file->size = file_sz; - file_size_total += file_sz; + file_size_total += file->size; } if (file_size_total) { @@ -468,10 +396,10 @@ grow: chunksize = EFI_READ_CHUNK_SIZE; else chunksize = size; - status = efi_call_phys3(fh->read, - files[j].handle, - &chunksize, - (void *)addr); + + status = efi_file_read(fh, files[j].handle, + &chunksize, + (void *)addr); if (status != EFI_SUCCESS) { efi_printk(sys_table_arg, "Failed to read file\n"); goto free_file_total; @@ -480,12 +408,12 @@ grow: size -= chunksize; } - efi_call_phys1(fh->close, files[j].handle); + efi_file_close(fh, files[j].handle); } } - efi_call_phys1(sys_table_arg->boottime->free_pool, files); + efi_early->call(efi_early->free_pool, files); *load_addr = file_addr; *load_size = file_size_total; @@ -497,9 +425,9 @@ free_file_total: close_handles: for (k = j; k < i; k++) - efi_call_phys1(fh->close, files[k].handle); + efi_file_close(fh, files[k].handle); free_files: - efi_call_phys1(sys_table_arg->boottime->free_pool, files); + efi_early->call(efi_early->free_pool, files); fail: *load_addr = 0; *load_size = 0; @@ -545,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, * as possible while respecting the required alignment. */ nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &efi_addr); + status = efi_early->call(efi_early->allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &efi_addr); new_addr = efi_addr; /* * If preferred address allocation failed allocate as low as -- cgit v1.2.3-55-g7522 From 0154416a71c2a84c3746c8dd8ed25287e36934d3 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 15:37:17 +0000 Subject: x86/efi: Add early thunk code to go from 64-bit to 32-bit Implement the transition code to go from IA32e mode to protected mode in the EFI boot stub. This is required to use 32-bit EFI services from a 64-bit kernel. Since EFI boot stub is executed in an identity-mapped region, there's not much we need to do before invoking the 32-bit EFI boot services. However, we do reload the firmware's global descriptor table (efi32_boot_gdt) in case things like timer events are still running in the firmware. Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/efi_stub_64.S | 29 +++++++ arch/x86/platform/efi/efi_stub_64.S | 150 +++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) (limited to 'arch') diff --git a/arch/x86/boot/compressed/efi_stub_64.S b/arch/x86/boot/compressed/efi_stub_64.S index cedc60de86eb..7ff3632806b1 100644 --- a/arch/x86/boot/compressed/efi_stub_64.S +++ b/arch/x86/boot/compressed/efi_stub_64.S @@ -1 +1,30 @@ +#include +#include +#include + #include "../../platform/efi/efi_stub_64.S" + +#ifdef CONFIG_EFI_MIXED + .code64 + .text +ENTRY(efi64_thunk) + push %rbp + push %rbx + + subq $16, %rsp + leaq efi_exit32(%rip), %rax + movl %eax, 8(%rsp) + leaq efi_gdt64(%rip), %rax + movl %eax, 4(%rsp) + movl %eax, 2(%rax) /* Fixup the gdt base address */ + leaq efi32_boot_gdt(%rip), %rax + movl %eax, (%rsp) + + call __efi64_thunk + + addq $16, %rsp + pop %rbx + pop %rbp + ret +ENDPROC(efi64_thunk) +#endif /* CONFIG_EFI_MIXED */ diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 88073b140298..a790d69cc85e 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -7,6 +7,10 @@ */ #include +#include +#include +#include +#include #define SAVE_XMM \ mov %rsp, %rax; \ @@ -164,6 +168,152 @@ ENTRY(efi_call6) ret ENDPROC(efi_call6) +#ifdef CONFIG_EFI_MIXED + +/* + * We run this function from the 1:1 mapping. + * + * This function must be invoked with a 1:1 mapped stack. + */ +ENTRY(__efi64_thunk) + subq $32, %rsp + movl %esi, 0x0(%rsp) + movl %edx, 0x4(%rsp) + movl %ecx, 0x8(%rsp) + movq %r8, %rsi + movl %esi, 0xc(%rsp) + movq %r9, %rsi + movl %esi, 0x10(%rsp) + + sgdt save_gdt(%rip) + + leaq 1f(%rip), %rbx + movq %rbx, func_rt_ptr(%rip) + + /* Switch to gdt with 32-bit segments */ + movl 40(%rsp), %eax + lgdt (%rax) + + leaq efi_enter32(%rip), %rax + pushq $__KERNEL_CS + pushq %rax + lretq + +1: addq $32, %rsp + + lgdt save_gdt(%rip) + + /* + * Convert 32-bit status code into 64-bit. + */ + test %rax, %rax + jz 1f + movl %eax, %ecx + andl $0x0fffffff, %ecx + andl $0xf0000000, %eax + shl $32, %rax + or %rcx, %rax +1: + ret +ENDPROC(__efi64_thunk) + +ENTRY(efi_exit32) + xorq %rax, %rax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + + movq func_rt_ptr(%rip), %rax + push %rax + mov %rdi, %rax + ret +ENDPROC(efi_exit32) + + .code32 +/* + * EFI service pointer must be in %edi. + * + * The stack should represent the 32-bit calling convention. + */ +ENTRY(efi_enter32) + movl $__KERNEL_DS, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + + /* Reload pgtables */ + movl %cr3, %eax + movl %eax, %cr3 + + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + + /* Disable long mode via EFER */ + movl $MSR_EFER, %ecx + rdmsr + btrl $_EFER_LME, %eax + wrmsr + + call *%edi + + /* We must preserve return value */ + movl %eax, %edi + + movl 44(%esp), %eax + movl %eax, 2(%eax) + lgdtl (%eax) + + movl %cr4, %eax + btsl $(X86_CR4_PAE_BIT), %eax + movl %eax, %cr4 + + movl %cr3, %eax + movl %eax, %cr3 + + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + xorl %eax, %eax + lldt %ax + + movl 48(%esp), %eax + pushl $__KERNEL_CS + pushl %eax + + /* Enable paging */ + movl %cr0, %eax + btsl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + lret +ENDPROC(efi_enter32) + + .data + .balign 8 + .global efi32_boot_gdt +efi32_boot_gdt: .word 0 + .quad 0 + +save_gdt: .word 0 + .quad 0 +func_rt_ptr: .quad 0 + + .global efi_gdt64 +efi_gdt64: + .word efi_gdt64_end - efi_gdt64 + .long 0 /* Filled out by user */ + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ +efi_gdt64_end: +#endif /* CONFIG_EFI_MIXED */ + .data ENTRY(efi_scratch) .fill 3,8,0 -- cgit v1.2.3-55-g7522 From c116e8d60adabfd545a269fccab85e77febc1643 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 16 Jan 2014 11:35:43 +0000 Subject: x86/efi: Split the boot stub into 32/64 code paths Make the decision which code path to take at runtime based on efi_early->is64. Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.c | 818 ++++++++++++++++++++++++++++++--------- 1 file changed, 639 insertions(+), 179 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 42548168bdc3..ab1f3a2f1e1e 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -49,10 +49,63 @@ static void efi_printk(efi_system_table_t *, char *); static void efi_char16_printk(efi_system_table_t *, efi_char16_t *); static efi_status_t -efi_file_size(efi_system_table_t *sys_table, void *__fh, - efi_char16_t *filename_16, void **handle, u64 *file_sz) +__file_size32(void *__fh, efi_char16_t *filename_16, + void **handle, u64 *file_sz) +{ + efi_file_handle_32_t *h, *fh = __fh; + efi_file_info_t *info; + efi_status_t status; + efi_guid_t info_guid = EFI_FILE_INFO_ID; + u32 info_sz; + + status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, + EFI_FILE_MODE_READ, (u64)0); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to open file: "); + efi_char16_printk(sys_table, filename_16); + efi_printk(sys_table, "\n"); + return status; + } + + *handle = h; + + info_sz = 0; + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, + &info_sz, NULL); + if (status != EFI_BUFFER_TOO_SMALL) { + efi_printk(sys_table, "Failed to get file info size\n"); + return status; + } + +grow: + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + info_sz, (void **)&info); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to alloc mem for file info\n"); + return status; + } + + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, + &info_sz, info); + if (status == EFI_BUFFER_TOO_SMALL) { + efi_early->call(efi_early->free_pool, info); + goto grow; + } + + *file_sz = info->file_size; + efi_early->call(efi_early->free_pool, info); + + if (status != EFI_SUCCESS) + efi_printk(sys_table, "Failed to get initrd info\n"); + + return status; +} + +static efi_status_t +__file_size64(void *__fh, efi_char16_t *filename_16, + void **handle, u64 *file_sz) { - efi_file_handle_t *h, *fh = __fh; + efi_file_handle_64_t *h, *fh = __fh; efi_file_info_t *info; efi_status_t status; efi_guid_t info_guid = EFI_FILE_INFO_ID; @@ -100,31 +153,82 @@ grow: return status; } +static efi_status_t +efi_file_size(efi_system_table_t *sys_table, void *__fh, + efi_char16_t *filename_16, void **handle, u64 *file_sz) +{ + if (efi_early->is64) + return __file_size64(__fh, filename_16, handle, file_sz); + + return __file_size32(__fh, filename_16, handle, file_sz); +} static inline efi_status_t efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr) { - efi_file_handle_t *fh = __fh; - return efi_early->call((unsigned long)fh->read, handle, size, addr); + unsigned long func; + + if (efi_early->is64) { + efi_file_handle_64_t *fh = __fh; + + func = (unsigned long)fh->read; + return efi_early->call(func, handle, size, addr); + } else { + efi_file_handle_32_t *fh = __fh; + + func = (unsigned long)fh->read; + return efi_early->call(func, handle, size, addr); + } } static inline efi_status_t efi_file_close(void *__fh, void *handle) { - efi_file_handle_t *fh = __fh; + if (efi_early->is64) { + efi_file_handle_64_t *fh = __fh; - return efi_early->call((unsigned long)fh->close, handle); + return efi_early->call((unsigned long)fh->close, handle); + } else { + efi_file_handle_32_t *fh = __fh; + + return efi_early->call((unsigned long)fh->close, handle); + } } -static inline efi_status_t -efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) +static inline efi_status_t __open_volume32(void *__image, void **__fh) +{ + efi_file_io_interface_t *io; + efi_loaded_image_32_t *image = __image; + efi_file_handle_32_t *fh; + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; + efi_status_t status; + void *handle = (void *)(unsigned long)image->device_handle; + unsigned long func; + + status = efi_early->call(efi_early->handle_protocol, handle, + &fs_proto, (void **)&io); + if (status != EFI_SUCCESS) { + efi_printk(sys_table, "Failed to handle fs_proto\n"); + return status; + } + + func = (unsigned long)io->open_volume; + status = efi_early->call(func, io, &fh); + if (status != EFI_SUCCESS) + efi_printk(sys_table, "Failed to open volume\n"); + + *__fh = fh; + return status; +} + +static inline efi_status_t __open_volume64(void *__image, void **__fh) { efi_file_io_interface_t *io; - efi_loaded_image_t *image = __image; - efi_file_handle_t *fh; + efi_loaded_image_64_t *image = __image; + efi_file_handle_64_t *fh; efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; efi_status_t status; void *handle = (void *)(unsigned long)image->device_handle; - u32 func; + unsigned long func; status = efi_early->call(efi_early->handle_protocol, handle, &fs_proto, (void **)&io); @@ -142,19 +246,39 @@ efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) return status; } -static inline void -efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) +static inline efi_status_t +efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) +{ + if (efi_early->is64) + return __open_volume64(__image, __fh); + + return __open_volume32(__image, __fh); +} + +static void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) { - struct efi_simple_text_output_protocol *out; unsigned long output_string; size_t offset; - unsigned long *func; - offset = offsetof(typeof(*out), output_string); - output_string = efi_early->text_output + offset; - func = (unsigned long *)output_string; + if (efi_early->is64) { + struct efi_simple_text_output_protocol_64 *out; + u64 *func; + + offset = offsetof(typeof(*out), output_string); + output_string = efi_early->text_output + offset; + func = (u64 *)output_string; + + efi_early->call(*func, efi_early->text_output, str); + } else { + struct efi_simple_text_output_protocol_32 *out; + u32 *func; + + offset = offsetof(typeof(*out), output_string); + output_string = efi_early->text_output + offset; + func = (u32 *)output_string; - efi_early->call(*func, efi_early->text_output, str); + efi_early->call(*func, efi_early->text_output, str); + } } #include "../../../../drivers/firmware/efi/efi-stub-helper.c" @@ -182,46 +306,86 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } -static efi_status_t setup_efi_pci(struct boot_params *params) +static efi_status_t +__setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) { - efi_pci_io_protocol *pci; + struct pci_setup_rom *rom = NULL; efi_status_t status; - void **pci_handle = NULL; - efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; - unsigned long nr_pci, size = 0; - int i; - struct setup_data *data; + unsigned long size; + uint64_t attributes; - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; + status = efi_early->call(pci->attributes, pci, + EfiPciIoAttributeOperationGet, 0, 0, + &attributes); + if (status != EFI_SUCCESS) + return status; - while (data && data->next) - data = (struct setup_data *)(unsigned long)data->next; + if (!pci->romimage || !pci->romsize) + return EFI_INVALID_PARAMETER; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - &pci_proto, NULL, &size, pci_handle); + size = pci->romsize + sizeof(*rom); - if (status == EFI_BUFFER_TOO_SMALL) { - status = efi_early->call(efi_early->allocate_pool, - EFI_LOADER_DATA, - size, (void **)&pci_handle); + status = efi_early->call(efi_early->allocate_pool, + EFI_LOADER_DATA, size, &rom); - if (status != EFI_SUCCESS) - return status; + if (status != EFI_SUCCESS) + return status; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &pci_proto, - NULL, &size, pci_handle); - } + memset(rom, 0, sizeof(*rom)); + + rom->data.type = SETUP_PCI; + rom->data.len = size - sizeof(struct setup_data); + rom->data.next = 0; + rom->pcilen = pci->romsize; + *__rom = rom; + + status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, + PCI_VENDOR_ID, 1, &(rom->vendor)); if (status != EFI_SUCCESS) - goto free_handle; + goto free_struct; + + status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, + PCI_DEVICE_ID, 1, &(rom->devid)); + + if (status != EFI_SUCCESS) + goto free_struct; + + status = efi_early->call(pci->get_location, pci, &(rom->segment), + &(rom->bus), &(rom->device), &(rom->function)); + + if (status != EFI_SUCCESS) + goto free_struct; + + memcpy(rom->romdata, pci->romimage, pci->romsize); + return status; + +free_struct: + efi_early->call(efi_early->free_pool, rom); + return status; +} - nr_pci = size / sizeof(void *); +static efi_status_t +setup_efi_pci32(struct boot_params *params, void **pci_handle, + unsigned long size) +{ + efi_pci_io_protocol_32 *pci = NULL; + efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; + u32 *handles = (u32 *)(unsigned long)pci_handle; + efi_status_t status; + unsigned long nr_pci; + struct setup_data *data; + int i; + + data = (struct setup_data *)(unsigned long)params->hdr.setup_data; + + while (data && data->next) + data = (struct setup_data *)(unsigned long)data->next; + + nr_pci = size / sizeof(u32); for (i = 0; i < nr_pci; i++) { - void *h = pci_handle[i]; - uint64_t attributes; - struct pci_setup_rom *rom; + struct pci_setup_rom *rom = NULL; + u32 h = handles[i]; status = efi_early->call(efi_early->handle_protocol, h, &pci_proto, (void **)&pci); @@ -232,56 +396,114 @@ static efi_status_t setup_efi_pci(struct boot_params *params) if (!pci) continue; -#ifdef CONFIG_X86_64 - status = efi_early->call((unsigned long)pci->attributes, pci, - EfiPciIoAttributeOperationGet, 0, - &attributes); -#else - status = efi_early->call((unsigned long)pci->attributes, pci, - EfiPciIoAttributeOperationGet, 0, 0, - &attributes); -#endif + status = __setup_efi_pci32(pci, &rom); if (status != EFI_SUCCESS) continue; - if (!pci->romimage || !pci->romsize) - continue; + if (data) + data->next = (unsigned long)rom; + else + params->hdr.setup_data = (unsigned long)rom; - size = pci->romsize + sizeof(*rom); + data = (struct setup_data *)rom; - status = efi_early->call(efi_early->allocate_pool, - EFI_LOADER_DATA, size, &rom); + } - if (status != EFI_SUCCESS) - continue; + return status; +} + +static efi_status_t +__setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) +{ + struct pci_setup_rom *rom; + efi_status_t status; + unsigned long size; + uint64_t attributes; + + status = efi_early->call(pci->attributes, pci, + EfiPciIoAttributeOperationGet, 0, + &attributes); + if (status != EFI_SUCCESS) + return status; - rom->data.type = SETUP_PCI; - rom->data.len = size - sizeof(struct setup_data); - rom->data.next = 0; - rom->pcilen = pci->romsize; + if (!pci->romimage || !pci->romsize) + return EFI_INVALID_PARAMETER; - status = efi_early->call((unsigned long)pci->pci.read, pci, - EfiPciIoWidthUint16, PCI_VENDOR_ID, - 1, &(rom->vendor)); + size = pci->romsize + sizeof(*rom); - if (status != EFI_SUCCESS) - goto free_struct; + status = efi_early->call(efi_early->allocate_pool, + EFI_LOADER_DATA, size, &rom); + + if (status != EFI_SUCCESS) + return status; - status = efi_early->call((unsigned long)pci->pci.read, pci, - EfiPciIoWidthUint16, PCI_DEVICE_ID, - 1, &(rom->devid)); + rom->data.type = SETUP_PCI; + rom->data.len = size - sizeof(struct setup_data); + rom->data.next = 0; + rom->pcilen = pci->romsize; + *__rom = rom; - if (status != EFI_SUCCESS) - goto free_struct; + status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, + PCI_VENDOR_ID, 1, &(rom->vendor)); + + if (status != EFI_SUCCESS) + goto free_struct; + + status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, + PCI_DEVICE_ID, 1, &(rom->devid)); + + if (status != EFI_SUCCESS) + goto free_struct; + + status = efi_early->call(pci->get_location, pci, &(rom->segment), + &(rom->bus), &(rom->device), &(rom->function)); + + if (status != EFI_SUCCESS) + goto free_struct; + + memcpy(rom->romdata, pci->romimage, pci->romsize); + return status; + +free_struct: + efi_early->call(efi_early->free_pool, rom); + return status; + +} + +static efi_status_t +setup_efi_pci64(struct boot_params *params, void **pci_handle, + unsigned long size) +{ + efi_pci_io_protocol_64 *pci = NULL; + efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; + u64 *handles = (u64 *)(unsigned long)pci_handle; + efi_status_t status; + unsigned long nr_pci; + struct setup_data *data; + int i; + + data = (struct setup_data *)(unsigned long)params->hdr.setup_data; + + while (data && data->next) + data = (struct setup_data *)(unsigned long)data->next; + + nr_pci = size / sizeof(u64); + for (i = 0; i < nr_pci; i++) { + struct pci_setup_rom *rom = NULL; + u64 h = handles[i]; - status = efi_early->call((unsigned long)pci->get_location, pci, - &(rom->segment), &(rom->bus), - &(rom->device), &(rom->function)); + status = efi_early->call(efi_early->handle_protocol, h, + &pci_proto, (void **)&pci); if (status != EFI_SUCCESS) - goto free_struct; + continue; + + if (!pci) + continue; - memcpy(rom->romdata, pci->romimage, pci->romsize); + status = __setup_efi_pci64(pci, &rom); + if (status != EFI_SUCCESS) + continue; if (data) data->next = (unsigned long)rom; @@ -290,104 +512,52 @@ static efi_status_t setup_efi_pci(struct boot_params *params) data = (struct setup_data *)rom; - continue; - free_struct: - efi_early->call(efi_early->free_pool, rom); } -free_handle: - efi_early->call(efi_early->free_pool, pci_handle); return status; } -/* - * See if we have Graphics Output Protocol - */ -static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, - unsigned long size) +static efi_status_t setup_efi_pci(struct boot_params *params) { - struct efi_graphics_output_protocol *gop, *first_gop; - struct efi_pixel_bitmask pixel_info; - unsigned long nr_gops; efi_status_t status; - void **gop_handle = NULL; - u16 width, height; - u32 fb_base, fb_size; - u32 pixels_per_scan_line; - int pixel_format; - int i; - - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - size, (void **)&gop_handle); - if (status != EFI_SUCCESS) - return status; + void **pci_handle = NULL; + efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; + unsigned long size = 0; status = efi_early->call(efi_early->locate_handle, EFI_LOCATE_BY_PROTOCOL, - proto, NULL, &size, gop_handle); - if (status != EFI_SUCCESS) - goto free_handle; - - first_gop = NULL; + &pci_proto, NULL, &size, pci_handle); - nr_gops = size / sizeof(void *); - for (i = 0; i < nr_gops; i++) { - struct efi_graphics_output_mode_info *info; - efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; - bool conout_found = false; - void *dummy; - void *h = gop_handle[i]; + if (status == EFI_BUFFER_TOO_SMALL) { + status = efi_early->call(efi_early->allocate_pool, + EFI_LOADER_DATA, + size, (void **)&pci_handle); - status = efi_early->call(efi_early->handle_protocol, h, - proto, (void **)&gop); if (status != EFI_SUCCESS) - continue; - - status = efi_early->call(efi_early->handle_protocol, h, - &conout_proto, &dummy); - if (status == EFI_SUCCESS) - conout_found = true; - - status = efi_early->call((unsigned long)gop->query_mode, gop, - gop->mode->mode, &size, &info); - if (status == EFI_SUCCESS && (!first_gop || conout_found)) { - /* - * Systems that use the UEFI Console Splitter may - * provide multiple GOP devices, not all of which are - * backed by real hardware. The workaround is to search - * for a GOP implementing the ConOut protocol, and if - * one isn't found, to just fall back to the first GOP. - */ - width = info->horizontal_resolution; - height = info->vertical_resolution; - fb_base = gop->mode->frame_buffer_base; - fb_size = gop->mode->frame_buffer_size; - pixel_format = info->pixel_format; - pixel_info = info->pixel_information; - pixels_per_scan_line = info->pixels_per_scan_line; + return status; - /* - * Once we've found a GOP supporting ConOut, - * don't bother looking any further. - */ - first_gop = gop; - if (conout_found) - break; - } + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, &pci_proto, + NULL, &size, pci_handle); } - /* Did we find any GOPs? */ - if (!first_gop) + if (status != EFI_SUCCESS) goto free_handle; - /* EFI framebuffer */ - si->orig_video_isVGA = VIDEO_TYPE_EFI; + if (efi_early->is64) + status = setup_efi_pci64(params, pci_handle, size); + else + status = setup_efi_pci32(params, pci_handle, size); - si->lfb_width = width; - si->lfb_height = height; - si->lfb_base = fb_base; - si->pages = 1; +free_handle: + efi_early->call(efi_early->free_pool, pci_handle); + return status; +} +static void +setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, + struct efi_pixel_bitmask pixel_info, int pixel_format) +{ if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) { si->lfb_depth = 32; si->lfb_linelength = pixels_per_scan_line * 4; @@ -432,51 +602,310 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, si->rsvd_size = 0; si->rsvd_pos = 0; } +} + +static efi_status_t +__gop_query32(struct efi_graphics_output_protocol_32 *gop32, + struct efi_graphics_output_mode_info **info, + unsigned long *size, u32 *fb_base) +{ + struct efi_graphics_output_protocol_mode_32 *mode; + efi_status_t status; + unsigned long m; + + m = gop32->mode; + mode = (struct efi_graphics_output_protocol_mode_32 *)m; + + status = efi_early->call(gop32->query_mode, gop32, + mode->mode, size, info); + if (status != EFI_SUCCESS) + return status; + + *fb_base = mode->frame_buffer_base; + return status; +} + +static efi_status_t +setup_gop32(struct screen_info *si, efi_guid_t *proto, + unsigned long size, void **gop_handle) +{ + struct efi_graphics_output_protocol_32 *gop32, *first_gop; + unsigned long nr_gops; + u16 width, height; + u32 pixels_per_scan_line; + u32 fb_base; + struct efi_pixel_bitmask pixel_info; + int pixel_format; + efi_status_t status; + u32 *handles = (u32 *)(unsigned long)gop_handle; + int i; + + first_gop = NULL; + gop32 = NULL; + + nr_gops = size / sizeof(u32); + for (i = 0; i < nr_gops; i++) { + struct efi_graphics_output_mode_info *info = NULL; + efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; + bool conout_found = false; + void *dummy = NULL; + u32 h = handles[i]; + + status = efi_early->call(efi_early->handle_protocol, h, + proto, (void **)&gop32); + if (status != EFI_SUCCESS) + continue; + + status = efi_early->call(efi_early->handle_protocol, h, + &conout_proto, &dummy); + if (status == EFI_SUCCESS) + conout_found = true; + + status = __gop_query32(gop32, &info, &size, &fb_base); + if (status == EFI_SUCCESS && (!first_gop || conout_found)) { + /* + * Systems that use the UEFI Console Splitter may + * provide multiple GOP devices, not all of which are + * backed by real hardware. The workaround is to search + * for a GOP implementing the ConOut protocol, and if + * one isn't found, to just fall back to the first GOP. + */ + width = info->horizontal_resolution; + height = info->vertical_resolution; + pixel_format = info->pixel_format; + pixel_info = info->pixel_information; + pixels_per_scan_line = info->pixels_per_scan_line; + + /* + * Once we've found a GOP supporting ConOut, + * don't bother looking any further. + */ + first_gop = gop32; + if (conout_found) + break; + } + } + + /* Did we find any GOPs? */ + if (!first_gop) + goto out; + + /* EFI framebuffer */ + si->orig_video_isVGA = VIDEO_TYPE_EFI; + + si->lfb_width = width; + si->lfb_height = height; + si->lfb_base = fb_base; + si->pages = 1; + + setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); si->lfb_size = si->lfb_linelength * si->lfb_height; si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; +out: + return status; +} -free_handle: - efi_early->call(efi_early->free_pool, gop_handle); +static efi_status_t +__gop_query64(struct efi_graphics_output_protocol_64 *gop64, + struct efi_graphics_output_mode_info **info, + unsigned long *size, u32 *fb_base) +{ + struct efi_graphics_output_protocol_mode_64 *mode; + efi_status_t status; + unsigned long m; + + m = gop64->mode; + mode = (struct efi_graphics_output_protocol_mode_64 *)m; + + status = efi_early->call(gop64->query_mode, gop64, + mode->mode, size, info); + if (status != EFI_SUCCESS) + return status; + + *fb_base = mode->frame_buffer_base; + return status; +} + +static efi_status_t +setup_gop64(struct screen_info *si, efi_guid_t *proto, + unsigned long size, void **gop_handle) +{ + struct efi_graphics_output_protocol_64 *gop64, *first_gop; + unsigned long nr_gops; + u16 width, height; + u32 pixels_per_scan_line; + u32 fb_base; + struct efi_pixel_bitmask pixel_info; + int pixel_format; + efi_status_t status; + u64 *handles = (u64 *)(unsigned long)gop_handle; + int i; + + first_gop = NULL; + gop64 = NULL; + + nr_gops = size / sizeof(u64); + for (i = 0; i < nr_gops; i++) { + struct efi_graphics_output_mode_info *info = NULL; + efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; + bool conout_found = false; + void *dummy = NULL; + u64 h = handles[i]; + + status = efi_early->call(efi_early->handle_protocol, h, + proto, (void **)&gop64); + if (status != EFI_SUCCESS) + continue; + + status = efi_early->call(efi_early->handle_protocol, h, + &conout_proto, &dummy); + if (status == EFI_SUCCESS) + conout_found = true; + + status = __gop_query64(gop64, &info, &size, &fb_base); + if (status == EFI_SUCCESS && (!first_gop || conout_found)) { + /* + * Systems that use the UEFI Console Splitter may + * provide multiple GOP devices, not all of which are + * backed by real hardware. The workaround is to search + * for a GOP implementing the ConOut protocol, and if + * one isn't found, to just fall back to the first GOP. + */ + width = info->horizontal_resolution; + height = info->vertical_resolution; + pixel_format = info->pixel_format; + pixel_info = info->pixel_information; + pixels_per_scan_line = info->pixels_per_scan_line; + + /* + * Once we've found a GOP supporting ConOut, + * don't bother looking any further. + */ + first_gop = gop64; + if (conout_found) + break; + } + } + + /* Did we find any GOPs? */ + if (!first_gop) + goto out; + + /* EFI framebuffer */ + si->orig_video_isVGA = VIDEO_TYPE_EFI; + + si->lfb_width = width; + si->lfb_height = height; + si->lfb_base = fb_base; + si->pages = 1; + + setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); + + si->lfb_size = si->lfb_linelength * si->lfb_height; + + si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; +out: return status; } /* - * See if we have Universal Graphics Adapter (UGA) protocol + * See if we have Graphics Output Protocol */ -static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, +static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, unsigned long size) { - struct efi_uga_draw_protocol *uga, *first_uga; - unsigned long nr_ugas; efi_status_t status; - u32 width, height; - void **uga_handle = NULL; - int i; + void **gop_handle = NULL; status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - size, (void **)&uga_handle); + size, (void **)&gop_handle); if (status != EFI_SUCCESS) return status; status = efi_early->call(efi_early->locate_handle, EFI_LOCATE_BY_PROTOCOL, - uga_proto, NULL, &size, uga_handle); + proto, NULL, &size, gop_handle); if (status != EFI_SUCCESS) goto free_handle; + if (efi_early->is64) + status = setup_gop64(si, proto, size, gop_handle); + else + status = setup_gop32(si, proto, size, gop_handle); + +free_handle: + efi_early->call(efi_early->free_pool, gop_handle); + return status; +} + +static efi_status_t +setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) +{ + struct efi_uga_draw_protocol *uga = NULL, *first_uga; + efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID; + unsigned long nr_ugas; + u32 *handles = (u32 *)uga_handle;; + efi_status_t status; + int i; + first_uga = NULL; + nr_ugas = size / sizeof(u32); + for (i = 0; i < nr_ugas; i++) { + efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; + u32 w, h, depth, refresh; + void *pciio; + u32 handle = handles[i]; + + status = efi_early->call(efi_early->handle_protocol, handle, + &uga_proto, (void **)&uga); + if (status != EFI_SUCCESS) + continue; + + efi_early->call(efi_early->handle_protocol, handle, + &pciio_proto, &pciio); + + status = efi_early->call((unsigned long)uga->get_mode, uga, + &w, &h, &depth, &refresh); + if (status == EFI_SUCCESS && (!first_uga || pciio)) { + *width = w; + *height = h; + + /* + * Once we've found a UGA supporting PCIIO, + * don't bother looking any further. + */ + if (pciio) + break; + + first_uga = uga; + } + } + + return status; +} + +static efi_status_t +setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height) +{ + struct efi_uga_draw_protocol *uga = NULL, *first_uga; + efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID; + unsigned long nr_ugas; + u64 *handles = (u64 *)uga_handle;; + efi_status_t status; + int i; - nr_ugas = size / sizeof(void *); + first_uga = NULL; + nr_ugas = size / sizeof(u64); for (i = 0; i < nr_ugas; i++) { efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; - void *handle = uga_handle[i]; u32 w, h, depth, refresh; void *pciio; + u64 handle = handles[i]; status = efi_early->call(efi_early->handle_protocol, handle, - uga_proto, (void **)&uga); + &uga_proto, (void **)&uga); if (status != EFI_SUCCESS) continue; @@ -486,8 +915,8 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, status = efi_early->call((unsigned long)uga->get_mode, uga, &w, &h, &depth, &refresh); if (status == EFI_SUCCESS && (!first_uga || pciio)) { - width = w; - height = h; + *width = w; + *height = h; /* * Once we've found a UGA supporting PCIIO, @@ -500,7 +929,39 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, } } - if (!first_uga) + return status; +} + +/* + * See if we have Universal Graphics Adapter (UGA) protocol + */ +static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, + unsigned long size) +{ + efi_status_t status; + u32 width, height; + void **uga_handle = NULL; + + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, + size, (void **)&uga_handle); + if (status != EFI_SUCCESS) + return status; + + status = efi_early->call(efi_early->locate_handle, + EFI_LOCATE_BY_PROTOCOL, + uga_proto, NULL, &size, uga_handle); + if (status != EFI_SUCCESS) + goto free_handle; + + height = 0; + width = 0; + + if (efi_early->is64) + status = setup_uga64(uga_handle, size, &width, &height); + else + status = setup_uga32(uga_handle, size, &width, &height); + + if (!width && !height) goto free_handle; /* EFI framebuffer */ @@ -519,7 +980,6 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, si->rsvd_size = 8; si->rsvd_pos = 24; - free_handle: efi_early->call(efi_early->free_pool, uga_handle); return status; -- cgit v1.2.3-55-g7522 From b8ff87a6158886771677e6dc8139bac6e3cba717 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 15:54:31 +0000 Subject: x86/efi: Firmware agnostic handover entry points The EFI handover code only works if the "bitness" of the firmware and the kernel match, i.e. 64-bit firmware and 64-bit kernel - it is not possible to mix the two. This goes against the tradition that a 32-bit kernel can be loaded on a 64-bit BIOS platform without having to do anything special in the boot loader. Linux distributions, for one thing, regularly run only 32-bit kernels on their live media. Despite having only one 'handover_offset' field in the kernel header, EFI boot loaders use two separate entry points to enter the kernel based on the architecture the boot loader was compiled for, (1) 32-bit loader: handover_offset (2) 64-bit loader: handover_offset + 512 Since we already have two entry points, we can leverage them to infer the bitness of the firmware we're running on, without requiring any boot loader modifications, by making (1) and (2) valid entry points for both CONFIG_X86_32 and CONFIG_X86_64 kernels. To be clear, a 32-bit boot loader will always use (1) and a 64-bit boot loader will always use (2). It's just that, if a single kernel image supports (1) and (2) that image can be used with both 32-bit and 64-bit boot loaders, and hence both 32-bit and 64-bit EFI. (1) and (2) must be 512 bytes apart at all times, but that is already part of the boot ABI and we could never change that delta without breaking existing boot loaders anyhow. Signed-off-by: Matt Fleming --- arch/x86/boot/Makefile | 2 +- arch/x86/boot/compressed/eboot.c | 9 ++++-- arch/x86/boot/compressed/head_32.S | 2 +- arch/x86/boot/compressed/head_64.S | 62 +++++++++++++++++++++++++++++++++----- arch/x86/boot/tools/build.c | 22 +++++++++----- arch/x86/include/asm/efi.h | 6 ++-- 6 files changed, 80 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 878df7e88cd4..abb9eba61b50 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -80,7 +80,7 @@ targets += voffset.h $(obj)/voffset.h: vmlinux FORCE $(call if_changed,voffset) -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi_pe_entry\|efi_stub_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' quiet_cmd_zoffset = ZOFFSET $@ cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index ab1f3a2f1e1e..5e1ba4fa3f79 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -1256,12 +1256,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, } static efi_status_t exit_boot(struct boot_params *boot_params, - void *handle) + void *handle, bool is64) { struct efi_info *efi = &boot_params->efi_info; unsigned long map_sz, key, desc_size; efi_memory_desc_t *mem_map; struct setup_data *e820ext; + const char *signature; __u32 e820ext_size; __u32 nr_desc, prev_nr_desc; efi_status_t status; @@ -1295,7 +1296,9 @@ get_map: goto get_map; /* Allocated memory, get map again */ } - memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); + signature = is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE; + memcpy(&efi->efi_loader_signature, signature, sizeof(__u32)); + efi->efi_systab = (unsigned long)sys_table; efi->efi_memdesc_size = desc_size; efi->efi_memdesc_version = desc_version; @@ -1408,7 +1411,7 @@ struct boot_params *efi_main(struct efi_config *c, hdr->code32_start = bzimage_addr; } - status = exit_boot(boot_params, handle); + status = exit_boot(boot_params, handle, is64); if (status != EFI_SUCCESS) goto fail; diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index eed23c087d6c..cccc05f0681c 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -64,7 +64,7 @@ ENTRY(efi_pe_entry) pushl %ecx jmp 2f /* Skip efi_config initialization */ -ENTRY(efi_stub_entry) +ENTRY(efi32_stub_entry) add $0x4, %esp popl %ecx popl %edx diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 1bc206fa4bd0..37c741b0d2ac 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -178,6 +178,13 @@ ENTRY(startup_32) */ pushl $__KERNEL_CS leal startup_64(%ebp), %eax +#ifdef CONFIG_EFI_MIXED + movl efi32_config(%ebp), %ebx + cmp $0, %ebx + jz 1f + leal handover_entry(%ebp), %eax +1: +#endif pushl %eax /* Enter paged protected Mode, activating Long Mode */ @@ -188,6 +195,30 @@ ENTRY(startup_32) lret ENDPROC(startup_32) +#ifdef CONFIG_EFI_MIXED + .org 0x190 +ENTRY(efi32_stub_entry) + add $0x4, %esp /* Discard return address */ + popl %ecx + popl %edx + popl %esi + + leal (BP_scratch+4)(%esi), %esp + call 1f +1: pop %ebp + subl $1b, %ebp + + movl %ecx, efi32_config(%ebp) + movl %edx, efi32_config+8(%ebp) + sgdtl efi32_boot_gdt(%ebp) + + leal efi32_config(%ebp), %eax + movl %eax, efi_config(%ebp) + + jmp startup_32 +ENDPROC(efi32_stub_entry) +#endif + .code64 .org 0x200 ENTRY(startup_64) @@ -231,13 +262,7 @@ ENTRY(efi_pe_entry) mov %rax, %rsi jmp 2f /* Skip the relocation */ -ENTRY(efi_stub_entry) - movq %rdi, efi64_config(%rip) /* Handle */ - movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ - - leaq efi64_config(%rip), %rax - movq %rax, efi_config(%rip) - +handover_entry: call 1f 1: popq %rbp subq $1b, %rbp @@ -247,7 +272,6 @@ ENTRY(efi_stub_entry) */ movq efi_config(%rip), %rax addq %rbp, 88(%rax) - movq %rdx, %rsi 2: movq efi_config(%rip), %rdi call efi_main @@ -336,6 +360,20 @@ preferred_addr: leaq relocated(%rbx), %rax jmp *%rax +#ifdef CONFIG_EFI_STUB + .org 0x390 +ENTRY(efi64_stub_entry) + movq %rdi, efi64_config(%rip) /* Handle */ + movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + movq %rdx, %rsi + jmp handover_entry +ENDPROC(efi64_stub_entry) +#endif + .text relocated: @@ -404,6 +442,14 @@ gdt_end: efi_config: .quad 0 +#ifdef CONFIG_EFI_MIXED + .global efi32_config +efi32_config: + .fill 11,8,0 + .quad efi64_thunk + .byte 0 +#endif + .global efi64_config efi64_config: .fill 11,8,0 diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index bf262077ec92..4f07df5ac5d9 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -53,7 +53,8 @@ int is_big_kernel; #define PECOFF_RELOC_RESERVE 0x20 -unsigned long efi_stub_entry; +unsigned long efi32_stub_entry; +unsigned long efi64_stub_entry; unsigned long efi_pe_entry; unsigned long startup_64; @@ -231,20 +232,26 @@ static void efi_stub_defaults(void) /* Defaults for old kernel */ #ifdef CONFIG_X86_32 efi_pe_entry = 0x10; - efi_stub_entry = 0x30; #else efi_pe_entry = 0x210; - efi_stub_entry = 0x230; startup_64 = 0x200; #endif } static void efi_stub_entry_update(void) { -#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */ - efi_stub_entry -= 0x200; + unsigned long addr = efi32_stub_entry; + +#ifdef CONFIG_X86_64 + /* Yes, this is really how we defined it :( */ + addr = efi64_stub_entry - 0x200; +#endif + +#ifdef CONFIG_EFI_MIXED + if (efi32_stub_entry != addr) + die("32-bit and 64-bit EFI entry points do not match\n"); #endif - put_unaligned_le32(efi_stub_entry, &buf[0x264]); + put_unaligned_le32(addr, &buf[0x264]); } #else @@ -289,7 +296,8 @@ static void parse_zoffset(char *fname) p = (char *)buf; while (p && *p) { - PARSE_ZOFS(p, efi_stub_entry); + PARSE_ZOFS(p, efi32_stub_entry); + PARSE_ZOFS(p, efi64_stub_entry); PARSE_ZOFS(p, efi_pe_entry); PARSE_ZOFS(p, startup_64); diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 3d6b9f81cc68..85856868507b 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -19,9 +19,11 @@ */ #define EFI_OLD_MEMMAP EFI_ARCH_1 +#define EFI32_LOADER_SIGNATURE "EL32" +#define EFI64_LOADER_SIGNATURE "EL64" + #ifdef CONFIG_X86_32 -#define EFI_LOADER_SIGNATURE "EL32" extern unsigned long asmlinkage efi_call_phys(void *, ...); @@ -57,8 +59,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #else /* !CONFIG_X86_32 */ -#define EFI_LOADER_SIGNATURE "EL64" - extern u64 efi_call0(void *fp); extern u64 efi_call1(void *fp, u64 arg1); extern u64 efi_call2(void *fp, u64 arg1, u64 arg2); -- cgit v1.2.3-55-g7522 From 4f9dbcfc40299ddaa780fe8c1cd74998c1be3af5 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 18:48:30 +0000 Subject: x86/efi: Add mixed runtime services support Setup the runtime services based on whether we're booting in EFI native mode or not. For non-native mode we need to thunk from 64-bit into 32-bit mode before invoking the EFI runtime services. Using the runtime services after SetVirtualAddressMap() is slightly more complicated because we need to ensure that all the addresses we pass to the firmware are below the 4GB boundary so that they can be addressed with 32-bit pointers, see efi_setup_page_tables(). Signed-off-by: Matt Fleming --- arch/x86/include/asm/efi.h | 21 +++ arch/x86/platform/efi/Makefile | 1 + arch/x86/platform/efi/efi.c | 127 +++++++++---- arch/x86/platform/efi/efi_64.c | 335 ++++++++++++++++++++++++++++++++++- arch/x86/platform/efi/efi_stub_64.S | 1 + arch/x86/platform/efi/efi_thunk_64.S | 65 +++++++ 6 files changed, 517 insertions(+), 33 deletions(-) create mode 100644 arch/x86/platform/efi/efi_thunk_64.S (limited to 'arch') diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 85856868507b..85935e6f69f3 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -154,6 +154,27 @@ static inline bool efi_is_native(void) extern struct console early_efi_console; extern void parse_efi_setup(u64 phys_addr, u32 data_len); + +#ifdef CONFIG_EFI_MIXED +extern void efi_thunk_runtime_setup(void); +extern efi_status_t efi_thunk_set_virtual_address_map( + void *phys_set_virtual_address_map, + unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map); +#else +static inline void efi_thunk_runtime_setup(void) {} +static inline efi_status_t efi_thunk_set_virtual_address_map( + void *phys_set_virtual_address_map, + unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map) +{ + return EFI_SUCCESS; +} +#endif /* CONFIG_EFI_MIXED */ #else /* * IF EFI is not configured, have the EFI calls return -ENOSYS. diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index b7b0b35c1981..d51045afcaaf 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o +obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index b96ae7918a16..39f5b7bba695 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -588,37 +588,85 @@ static int __init efi_systab_init(void *phys) return 0; } -static int __init efi_runtime_init(void) +static int __init efi_runtime_init32(void) { - efi_runtime_services_t *runtime; + efi_runtime_services_32_t *runtime; + + runtime = early_ioremap((unsigned long)efi.systab->runtime, + sizeof(efi_runtime_services_32_t)); + if (!runtime) { + pr_err("Could not map the runtime service table!\n"); + return -ENOMEM; + } /* - * Check out the runtime services table. We need to map - * the runtime services table so that we can grab the physical - * address of several of the EFI runtime functions, needed to - * set the firmware into virtual mode. + * We will only need *early* access to the following two + * EFI runtime services before set_virtual_address_map + * is invoked. */ + efi_phys.get_time = (efi_get_time_t *) + (unsigned long)runtime->get_time; + efi_phys.set_virtual_address_map = + (efi_set_virtual_address_map_t *) + (unsigned long)runtime->set_virtual_address_map; + /* + * Make efi_get_time can be called before entering + * virtual mode. + */ + efi.get_time = phys_efi_get_time; + early_iounmap(runtime, sizeof(efi_runtime_services_32_t)); + + return 0; +} + +static int __init efi_runtime_init64(void) +{ + efi_runtime_services_64_t *runtime; + runtime = early_ioremap((unsigned long)efi.systab->runtime, - sizeof(efi_runtime_services_t)); + sizeof(efi_runtime_services_64_t)); if (!runtime) { pr_err("Could not map the runtime service table!\n"); return -ENOMEM; } + /* - * We will only need *early* access to the following - * two EFI runtime services before set_virtual_address_map + * We will only need *early* access to the following two + * EFI runtime services before set_virtual_address_map * is invoked. */ - efi_phys.get_time = (efi_get_time_t *)runtime->get_time; + efi_phys.get_time = (efi_get_time_t *) + (unsigned long)runtime->get_time; efi_phys.set_virtual_address_map = - (efi_set_virtual_address_map_t *) - runtime->set_virtual_address_map; + (efi_set_virtual_address_map_t *) + (unsigned long)runtime->set_virtual_address_map; /* * Make efi_get_time can be called before entering * virtual mode. */ efi.get_time = phys_efi_get_time; - early_iounmap(runtime, sizeof(efi_runtime_services_t)); + early_iounmap(runtime, sizeof(efi_runtime_services_64_t)); + + return 0; +} + +static int __init efi_runtime_init(void) +{ + int rv; + + /* + * Check out the runtime services table. We need to map + * the runtime services table so that we can grab the physical + * address of several of the EFI runtime functions, needed to + * set the firmware into virtual mode. + */ + if (efi_enabled(EFI_64BIT)) + rv = efi_runtime_init64(); + else + rv = efi_runtime_init32(); + + if (rv) + return rv; return 0; } @@ -841,6 +889,22 @@ void __init old_map_region(efi_memory_desc_t *md) (unsigned long long)md->phys_addr); } +static void native_runtime_setup(void) +{ + efi.get_time = virt_efi_get_time; + efi.set_time = virt_efi_set_time; + efi.get_wakeup_time = virt_efi_get_wakeup_time; + efi.set_wakeup_time = virt_efi_set_wakeup_time; + efi.get_variable = virt_efi_get_variable; + efi.get_next_variable = virt_efi_get_next_variable; + efi.set_variable = virt_efi_set_variable; + efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; + efi.reset_system = virt_efi_reset_system; + efi.query_variable_info = virt_efi_query_variable_info; + efi.update_capsule = virt_efi_update_capsule; + efi.query_capsule_caps = virt_efi_query_capsule_caps; +} + /* Merge contiguous regions of the same type and attribute */ static void __init efi_merge_regions(void) { @@ -1023,11 +1087,20 @@ void __init efi_enter_virtual_mode(void) efi_sync_low_kernel_mappings(); if (!efi_setup) { - status = phys_efi_set_virtual_address_map( - memmap.desc_size * count, - memmap.desc_size, - memmap.desc_version, - (efi_memory_desc_t *)__pa(new_memmap)); + if (efi_is_native()) { + status = phys_efi_set_virtual_address_map( + memmap.desc_size * count, + memmap.desc_size, + memmap.desc_version, + (efi_memory_desc_t *)__pa(new_memmap)); + } else { + status = efi_thunk_set_virtual_address_map( + efi_phys.set_virtual_address_map, + memmap.desc_size * count, + memmap.desc_size, + memmap.desc_version, + (efi_memory_desc_t *)__pa(new_memmap)); + } if (status != EFI_SUCCESS) { pr_alert("Unable to switch EFI into virtual mode (status=%lx)!\n", @@ -1043,19 +1116,13 @@ void __init efi_enter_virtual_mode(void) * Call EFI services through wrapper functions. */ efi.runtime_version = efi_systab.hdr.revision; - efi.get_time = virt_efi_get_time; - efi.set_time = virt_efi_set_time; - efi.get_wakeup_time = virt_efi_get_wakeup_time; - efi.set_wakeup_time = virt_efi_set_wakeup_time; - efi.get_variable = virt_efi_get_variable; - efi.get_next_variable = virt_efi_get_next_variable; - efi.set_variable = virt_efi_set_variable; - efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; - efi.reset_system = virt_efi_reset_system; + + if (efi_is_native()) + native_runtime_setup(); + else + efi_thunk_runtime_setup(); + efi.set_virtual_address_map = NULL; - efi.query_variable_info = virt_efi_query_variable_info; - efi.update_capsule = virt_efi_update_capsule; - efi.query_capsule_caps = virt_efi_query_capsule_caps; efi_runtime_mkexec(); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 0c2a234fef1e..12112ab4fd40 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -39,6 +39,7 @@ #include #include #include +#include static pgd_t *save_pgd __initdata; static unsigned long efi_flags __initdata; @@ -58,7 +59,8 @@ struct efi_scratch { u64 prev_cr3; pgd_t *efi_pgt; bool use_pgd; -}; + u64 phys_stack; +} __packed; static void __init early_code_mapping_set_exec(int executable) { @@ -139,10 +141,40 @@ void efi_sync_low_kernel_mappings(void) void efi_setup_page_tables(void) { + unsigned long text; + unsigned npages; + struct page *page; + efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd; - if (!efi_enabled(EFI_OLD_MEMMAP)) - efi_scratch.use_pgd = true; + if (efi_enabled(EFI_OLD_MEMMAP)) + return; + + efi_scratch.use_pgd = true; + + /* + * When making calls to the firmware everything needs to be 1:1 + * mapped and addressable with 32-bit pointers. Map the kernel + * text and allocate a new stack because we can't rely on the + * stack pointer being < 4GB. + */ + if (!IS_ENABLED(CONFIG_EFI_MIXED)) + return; + + page = alloc_page(GFP_KERNEL|__GFP_DMA32); + if (!page) + panic("Unable to allocate EFI runtime stack < 4GB\n"); + + efi_scratch.phys_stack = virt_to_phys(page_address(page)); + efi_scratch.phys_stack += PAGE_SIZE; /* stack grows down */ + + npages = (_end - _text) >> PAGE_SHIFT; + text = __pa(_text); + + if (kernel_map_pages_in_pgd(__va(efi_scratch.efi_pgt), + text >> PAGE_SHIFT, text, npages, 0)) { + pr_err("Failed to map kernel text 1:1\n"); + } } static void __init __map_region(efi_memory_desc_t *md, u64 va) @@ -173,6 +205,16 @@ void __init efi_map_region(efi_memory_desc_t *md) */ __map_region(md, md->phys_addr); + /* + * Enforce the 1:1 mapping as the default virtual address when + * booting in EFI mixed mode, because even though we may be + * running a 64-bit kernel, the firmware may only be 32-bit. + */ + if (!efi_is_native () && IS_ENABLED(CONFIG_EFI_MIXED)) { + md->virt_addr = md->phys_addr; + return; + } + efi_va -= size; /* Is PA 2M-aligned? */ @@ -242,3 +284,290 @@ void __init efi_runtime_mkexec(void) if (__supported_pte_mask & _PAGE_NX) runtime_code_page_mkexec(); } + +#ifdef CONFIG_EFI_MIXED +extern efi_status_t efi64_thunk(u32, ...); + +#define runtime_service32(func) \ +({ \ + u32 table = (u32)(unsigned long)efi.systab; \ + u32 *rt, *___f; \ + \ + rt = (u32 *)(table + offsetof(efi_system_table_32_t, runtime)); \ + ___f = (u32 *)(*rt + offsetof(efi_runtime_services_32_t, func)); \ + *___f; \ +}) + +/* + * Switch to the EFI page tables early so that we can access the 1:1 + * runtime services mappings which are not mapped in any other page + * tables. This function must be called before runtime_service32(). + * + * Also, disable interrupts because the IDT points to 64-bit handlers, + * which aren't going to function correctly when we switch to 32-bit. + */ +#define efi_thunk(f, ...) \ +({ \ + efi_status_t __s; \ + unsigned long flags; \ + u32 func; \ + \ + efi_sync_low_kernel_mappings(); \ + local_irq_save(flags); \ + \ + efi_scratch.prev_cr3 = read_cr3(); \ + write_cr3((unsigned long)efi_scratch.efi_pgt); \ + __flush_tlb_all(); \ + \ + func = runtime_service32(f); \ + __s = efi64_thunk(func, __VA_ARGS__); \ + \ + write_cr3(efi_scratch.prev_cr3); \ + __flush_tlb_all(); \ + local_irq_restore(flags); \ + \ + __s; \ +}) + +efi_status_t efi_thunk_set_virtual_address_map( + void *phys_set_virtual_address_map, + unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map) +{ + efi_status_t status; + unsigned long flags; + u32 func; + + efi_sync_low_kernel_mappings(); + local_irq_save(flags); + + efi_scratch.prev_cr3 = read_cr3(); + write_cr3((unsigned long)efi_scratch.efi_pgt); + __flush_tlb_all(); + + func = (u32)(unsigned long)phys_set_virtual_address_map; + status = efi64_thunk(func, memory_map_size, descriptor_size, + descriptor_version, virtual_map); + + write_cr3(efi_scratch.prev_cr3); + __flush_tlb_all(); + local_irq_restore(flags); + + return status; +} + +static efi_status_t efi_thunk_get_time(efi_time_t *tm, efi_time_cap_t *tc) +{ + efi_status_t status; + u32 phys_tm, phys_tc; + + spin_lock(&rtc_lock); + + phys_tm = virt_to_phys(tm); + phys_tc = virt_to_phys(tc); + + status = efi_thunk(get_time, phys_tm, phys_tc); + + spin_unlock(&rtc_lock); + + return status; +} + +static efi_status_t efi_thunk_set_time(efi_time_t *tm) +{ + efi_status_t status; + u32 phys_tm; + + spin_lock(&rtc_lock); + + phys_tm = virt_to_phys(tm); + + status = efi_thunk(set_time, phys_tm); + + spin_unlock(&rtc_lock); + + return status; +} + +static efi_status_t +efi_thunk_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending, + efi_time_t *tm) +{ + efi_status_t status; + u32 phys_enabled, phys_pending, phys_tm; + + spin_lock(&rtc_lock); + + phys_enabled = virt_to_phys(enabled); + phys_pending = virt_to_phys(pending); + phys_tm = virt_to_phys(tm); + + status = efi_thunk(get_wakeup_time, phys_enabled, + phys_pending, phys_tm); + + spin_unlock(&rtc_lock); + + return status; +} + +static efi_status_t +efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) +{ + efi_status_t status; + u32 phys_tm; + + spin_lock(&rtc_lock); + + phys_tm = virt_to_phys(tm); + + status = efi_thunk(set_wakeup_time, enabled, phys_tm); + + spin_unlock(&rtc_lock); + + return status; +} + + +static efi_status_t +efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, + u32 *attr, unsigned long *data_size, void *data) +{ + efi_status_t status; + u32 phys_name, phys_vendor, phys_attr; + u32 phys_data_size, phys_data; + + phys_data_size = virt_to_phys(data_size); + phys_vendor = virt_to_phys(vendor); + phys_name = virt_to_phys(name); + phys_attr = virt_to_phys(attr); + phys_data = virt_to_phys(data); + + status = efi_thunk(get_variable, phys_name, phys_vendor, + phys_attr, phys_data_size, phys_data); + + return status; +} + +static efi_status_t +efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, + u32 attr, unsigned long data_size, void *data) +{ + u32 phys_name, phys_vendor, phys_data; + efi_status_t status; + + phys_name = virt_to_phys(name); + phys_vendor = virt_to_phys(vendor); + phys_data = virt_to_phys(data); + + /* If data_size is > sizeof(u32) we've got problems */ + status = efi_thunk(set_variable, phys_name, phys_vendor, + attr, data_size, phys_data); + + return status; +} + +static efi_status_t +efi_thunk_get_next_variable(unsigned long *name_size, + efi_char16_t *name, + efi_guid_t *vendor) +{ + efi_status_t status; + u32 phys_name_size, phys_name, phys_vendor; + + phys_name_size = virt_to_phys(name_size); + phys_vendor = virt_to_phys(vendor); + phys_name = virt_to_phys(name); + + status = efi_thunk(get_next_variable, phys_name_size, + phys_name, phys_vendor); + + return status; +} + +static efi_status_t +efi_thunk_get_next_high_mono_count(u32 *count) +{ + efi_status_t status; + u32 phys_count; + + phys_count = virt_to_phys(count); + status = efi_thunk(get_next_high_mono_count, phys_count); + + return status; +} + +static void +efi_thunk_reset_system(int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data) +{ + u32 phys_data; + + phys_data = virt_to_phys(data); + + efi_thunk(reset_system, reset_type, status, data_size, phys_data); +} + +static efi_status_t +efi_thunk_update_capsule(efi_capsule_header_t **capsules, + unsigned long count, unsigned long sg_list) +{ + /* + * To properly support this function we would need to repackage + * 'capsules' because the firmware doesn't understand 64-bit + * pointers. + */ + return EFI_UNSUPPORTED; +} + +static efi_status_t +efi_thunk_query_variable_info(u32 attr, u64 *storage_space, + u64 *remaining_space, + u64 *max_variable_size) +{ + efi_status_t status; + u32 phys_storage, phys_remaining, phys_max; + + if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) + return EFI_UNSUPPORTED; + + phys_storage = virt_to_phys(storage_space); + phys_remaining = virt_to_phys(remaining_space); + phys_max = virt_to_phys(max_variable_size); + + status = efi_thunk(query_variable_info, phys_storage, + phys_remaining, phys_max); + + return status; +} + +static efi_status_t +efi_thunk_query_capsule_caps(efi_capsule_header_t **capsules, + unsigned long count, u64 *max_size, + int *reset_type) +{ + /* + * To properly support this function we would need to repackage + * 'capsules' because the firmware doesn't understand 64-bit + * pointers. + */ + return EFI_UNSUPPORTED; +} + +void efi_thunk_runtime_setup(void) +{ + efi.get_time = efi_thunk_get_time; + efi.set_time = efi_thunk_set_time; + efi.get_wakeup_time = efi_thunk_get_wakeup_time; + efi.set_wakeup_time = efi_thunk_set_wakeup_time; + efi.get_variable = efi_thunk_get_variable; + efi.get_next_variable = efi_thunk_get_next_variable; + efi.set_variable = efi_thunk_set_variable; + efi.get_next_high_mono_count = efi_thunk_get_next_high_mono_count; + efi.reset_system = efi_thunk_reset_system; + efi.query_variable_info = efi_thunk_query_variable_info; + efi.update_capsule = efi_thunk_update_capsule; + efi.query_capsule_caps = efi_thunk_query_capsule_caps; +} +#endif /* CONFIG_EFI_MIXED */ diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index a790d69cc85e..e811514beeac 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -318,3 +318,4 @@ efi_gdt64_end: ENTRY(efi_scratch) .fill 3,8,0 .byte 0 + .quad 0 diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S new file mode 100644 index 000000000000..8806fa73e6e6 --- /dev/null +++ b/arch/x86/platform/efi/efi_thunk_64.S @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 Intel Corporation; author Matt Fleming + */ + +#include +#include + + .text + .code64 +ENTRY(efi64_thunk) + push %rbp + push %rbx + + /* + * Switch to 1:1 mapped 32-bit stack pointer. + */ + movq %rsp, efi_saved_sp(%rip) + movq efi_scratch+25(%rip), %rsp + + /* + * Calculate the physical address of the kernel text. + */ + movq $__START_KERNEL_map, %rax + subq phys_base(%rip), %rax + + /* + * Push some physical addresses onto the stack. This is easier + * to do now in a code64 section while the assembler can address + * 64-bit values. Note that all the addresses on the stack are + * 32-bit. + */ + subq $16, %rsp + leaq efi_exit32(%rip), %rbx + subq %rax, %rbx + movl %ebx, 8(%rsp) + leaq efi_gdt64(%rip), %rbx + subq %rax, %rbx + movl %ebx, 2(%ebx) + movl %ebx, 4(%rsp) + leaq efi_gdt32(%rip), %rbx + subq %rax, %rbx + movl %ebx, 2(%ebx) + movl %ebx, (%rsp) + + leaq __efi64_thunk(%rip), %rbx + subq %rax, %rbx + call *%rbx + + movq efi_saved_sp(%rip), %rsp + pop %rbx + pop %rbp + retq +ENDPROC(efi64_thunk) + + .data +efi_gdt32: + .word efi_gdt32_end - efi_gdt32 + .long 0 /* Filled out above */ + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00cf9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf93000000ffff /* __KERNEL_DS */ +efi_gdt32_end: + +efi_saved_sp: .quad 0 -- cgit v1.2.3-55-g7522 From 7d453eee36ae4cf30fc2f2faae54f634c4f863b7 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 10 Jan 2014 18:52:06 +0000 Subject: x86/efi: Wire up CONFIG_EFI_MIXED Add the Kconfig option and bump the kernel header version so that boot loaders can check whether the handover code is available if they want. The xloadflags field in the bzImage header is also updated to reflect that the kernel supports both entry points by setting both of XLF_EFI_HANDOVER_32 and XLF_EFI_HANDOVER_64 when CONFIG_EFI_MIXED=y. XLF_CAN_BE_LOADED_ABOVE_4G is disabled so that the kernel text is guaranteed to be addressable with 32-bits. Note that no boot loaders should be using the bits set in xloadflags to decide which entry point to jump to. The entire scheme is based on the concept that 32-bit bootloaders always jump to ->handover_offset and 64-bit loaders always jump to ->handover_offset + 512. We set both bits merely to inform the boot loader that it's safe to use the native handover offset even if the machine type in the PE/COFF header claims otherwise. Signed-off-by: Matt Fleming --- arch/x86/Kconfig | 14 ++++++++++++++ arch/x86/boot/header.S | 15 ++++++++++----- arch/x86/include/asm/efi.h | 11 +++++++++++ arch/x86/kernel/setup.c | 2 +- arch/x86/platform/efi/efi.c | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0af5250d914f..8453fe1342ea 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1585,6 +1585,20 @@ config EFI_STUB See Documentation/efi-stub.txt for more information. +config EFI_MIXED + bool "EFI mixed-mode support" + depends on EFI_STUB && X86_64 + ---help--- + Enabling this feature allows a 64-bit kernel to be booted + on a 32-bit firmware, provided that your CPU supports 64-bit + mode. + + Note that it is not possible to boot a mixed-mode enabled + kernel via the EFI boot stub - a bootloader that supports + the EFI handover protocol must be used. + + If unsure, say N. + config SECCOMP def_bool y prompt "Enable seccomp to safely compute untrusted bytecode" diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index d69d96653325..256388260c88 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -283,7 +283,7 @@ _start: # Part 2 of the header, from the old setup.S .ascii "HdrS" # header signature - .word 0x020c # header version number (>= 0x0105) + .word 0x020d # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) .globl realmode_swtch realmode_swtch: .word 0, 0 # default_switch, SETUPSEG @@ -375,7 +375,8 @@ xloadflags: # define XLF0 0 #endif -#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) && \ + !defined(CONFIG_EFI_MIXED) /* kernel/boot_param/ramdisk could be loaded above 4g */ # define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G #else @@ -383,10 +384,14 @@ xloadflags: #endif #ifdef CONFIG_EFI_STUB -# ifdef CONFIG_X86_64 -# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */ +# ifdef CONFIG_EFI_MIXED +# define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64) # else -# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */ +# ifdef CONFIG_X86_64 +# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */ +# else +# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */ +# endif # endif #else # define XLF23 0 diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 85935e6f69f3..a3837254e320 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -152,6 +152,17 @@ static inline bool efi_is_native(void) return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); } +static inline bool efi_runtime_supported(void) +{ + if (efi_is_native()) + return true; + + if (IS_ENABLED(CONFIG_EFI_MIXED) && !efi_enabled(EFI_OLD_MEMMAP)) + return true; + + return false; +} + extern struct console early_efi_console; extern void parse_efi_setup(u64 phys_addr, u32 data_len); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 06853e670354..ff9b3a62a05c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1243,7 +1243,7 @@ void __init setup_arch(char **cmdline_p) * mismatched firmware/kernel archtectures since there is no * support for runtime services. */ - if (efi_enabled(EFI_BOOT) && !efi_is_native()) { + if (efi_enabled(EFI_BOOT) && !efi_runtime_supported()) { pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); efi_unmap_memmap(); } diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 39f5b7bba695..395decedfa2b 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -802,7 +802,7 @@ void __init efi_init(void) * that doesn't match the kernel 32/64-bit mode. */ - if (!efi_is_native()) + if (!efi_runtime_supported()) pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); else { if (disable_runtime || efi_runtime_init()) -- cgit v1.2.3-55-g7522 From 108d3f44b16be2ecf0e44c2f2863752918eb7bce Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 24 Feb 2014 13:37:29 +0000 Subject: x86/boot: Don't overwrite cr4 when enabling PAE Some EFI firmware makes use of the FPU during boottime services and clearing X86_CR4_OSFXSR by overwriting %cr4 causes the firmware to crash. Add the PAE bit explicitly instead of trashing the existing contents, leaving the rest of the bits as the firmware set them. Cc: H. Peter Anvin Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/head_64.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 37c741b0d2ac..4f40cddd025d 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -113,7 +113,8 @@ ENTRY(startup_32) lgdt gdt(%ebp) /* Enable PAE mode */ - movl $(X86_CR4_PAE), %eax + movl %cr4, %eax + orl $X86_CR4_PAE, %eax movl %eax, %cr4 /* -- cgit v1.2.3-55-g7522 From 18c46461d9e42d398536055f31f58cdcd2c6347e Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 24 Feb 2014 18:07:26 +0000 Subject: x86/efi: Re-disable interrupts after calling firmware services Some firmware appears to enable interrupts during boot service calls, even if we've explicitly disabled them prior to the call. This is actually allowed per the UEFI spec because boottime services expect to be called with interrupts enabled. So that's fine, we just need to ensure that we disable them again in efi_enter32() before switching to a 64-bit GDT, otherwise an interrupt may fire causing a 32-bit IRQ handler to run after we've left compatibility mode. Despite efi_enter32() being called both for boottime and runtime services, this really only affects boottime because the runtime services callchain is executed with interrupts disabled. See efi_thunk(). Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi_stub_64.S | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index e811514beeac..65b787a9fc4e 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -261,6 +261,12 @@ ENTRY(efi_enter32) /* We must preserve return value */ movl %eax, %edi + /* + * Some firmware will return with interrupts enabled. Be sure to + * disable them before we switch GDTs. + */ + cli + movl 44(%esp), %eax movl %eax, 2(%eax) lgdtl (%eax) -- cgit v1.2.3-55-g7522 From ae72758f1dd93bd367dc7719702f24a9bfb3bad9 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Mon, 11 Nov 2013 08:28:33 -0500 Subject: c6x: fix build failure caused by cache.h A patch to linux/irqflags.h uncovered a problem with c6x asm/cache.h which causes a build failure: /arch/c6x/include/asm/cache.h:63:20: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c6x_cache_init’ extern void __init c6x_cache_init(void); The asm/cache.h was relying on linux/irqflags.h to pull in linux/init.h but the recent patch changed that. The c6x header should have included linux/init.h all along. Signed-off-by: Mark Salter --- arch/c6x/include/asm/cache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h index 09c5a0f5f4d1..86648c083bb4 100644 --- a/arch/c6x/include/asm/cache.h +++ b/arch/c6x/include/asm/cache.h @@ -12,6 +12,7 @@ #define _ASM_C6X_CACHE_H #include +#include /* * Cache line size -- cgit v1.2.3-55-g7522 From 3c433679ab666fb76a9399679819a303989e8ead Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 23:39:58 +0100 Subject: x86: hyperv: Make it build with CONFIG_HYPERV=m again Commit 1aec16967 (x86: Hyperv: Cleanup the irq mess) removed the ability to build the hyperv stuff as a module. Bring it back. Reported-by: fengguang.wu@intel.com Signed-off-by: Thomas Gleixner Cc: K. Y. Srinivasan Cc: Peter Zijlstra Cc: Greg Kroah-Hartman Cc: linuxdrivers Cc: x86 --- arch/x86/kernel/cpu/mshyperv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 1bd316cd32c8..316e106e26f0 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -31,7 +31,7 @@ struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); -#ifdef CONFIG_HYPERV +#if IS_ENABLED(CONFIG_HYPERV) static irq_handler_t *vmbus_handler; void hyperv_vector_handler(struct pt_regs *regs) -- cgit v1.2.3-55-g7522 From 13b5be56d1c5ed302df53f6dfbe19b9f4e3fd3ce Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 23:51:34 +0100 Subject: x86: hyperv: Fix brown paperbag typos reported by Fenguangs build robot Reported-by: fengguang.wu@intel.com Signed-off-by: Thomas Gleixner Cc: K. Y. Srinivasan Cc: Peter Zijlstra Cc: Greg Kroah-Hartman Cc: linuxdrivers Cc: x86 --- arch/x86/kernel/cpu/mshyperv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 316e106e26f0..a6f5f351f7af 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -32,7 +32,7 @@ struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); #if IS_ENABLED(CONFIG_HYPERV) -static irq_handler_t *vmbus_handler; +static irq_handler_t vmbus_handler; void hyperv_vector_handler(struct pt_regs *regs) { @@ -49,7 +49,7 @@ void hyperv_vector_handler(struct pt_regs *regs) set_irq_regs(old_regs); } -int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void *dev_id) +int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id) { vmbus_handler = handler; /* @@ -61,7 +61,7 @@ int hv_setup_vmbus_irq(int irq, irq_handler_t *handler, void *dev_id) hyperv_callback_vector); } -void hv_remove_vmbus_irq(unsigned int irq, void *dev_id) +void hv_remove_vmbus_irq(int irq, void *dev_id) { /* We have no way to deallocate the interrupt gate */ vmbus_handler = NULL; -- cgit v1.2.3-55-g7522 From 257ceab7456bd2a2657fd1c689384cabc95e3d30 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 23:57:29 +0100 Subject: s390: Do not rely on magic indirect includes commit: 8f945a33 (genirq: Move kstat_incr_irqs_this_cpu() to core) unearthed the following: arch/s390/kernel/irq.c: In function 'init_IRQ': >> arch/s390/kernel/irq.c:93:2: error: implicit declaration of function 'irq_reserve_irqs' [-Werror=implicit-function-declaration] .... cc1: some warnings being treated as errors -- drivers/s390/cio/cio.c: In function 'init_cio_interrupts': >> drivers/s390/cio/cio.c:594:2: error: implicit declaration of function 'irq_set_chip_and_handler' [-Werror=implicit-function-declaration] [-Werror=implicit-function-declaration] .... cc1: some warnings being treated as errors The reason is that those files require linux/irq.h and magically pulled that in via linux/kernel_stat.h The commit above got rid of the pointless include of linux/irq.h in linux/kernel_stat.h and therefor broke the build. Include linux/irq.h Reported-by: fengguang.wu@intel.com Signed-off-by: Thomas Gleixner Cc: Martin Schwidefsky Cc: s390 --- arch/s390/kernel/irq.c | 1 + drivers/s390/cio/cio.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index bb27a262c44a..a770be97db4d 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f711f0b91104..5829ddc976f3 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-55-g7522 From 57310c3c99eb6fab2ecbd63aa3f7c323341ca77e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 5 Mar 2014 00:06:11 +0100 Subject: powerpc: eeh: Fixup the brown paperbag fallout of the "cleanup" Commit b8a9a11b9 (powerpc: eeh: Kill another abuse of irq_desc) is missing some brackets ..... It's not a good idea to write patches in grumpy mode and then forget to at least compile test them or rely on the few eyeballs discussing that patch to spot it..... Reported-by: fengguang.wu@intel.com Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Gavin Shan Cc: Benjamin Herrenschmidt Cc: ppc --- arch/powerpc/kernel/eeh_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 3e1d7de6ea40..bb61ca58ca6d 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -166,8 +166,9 @@ static void eeh_enable_irq(struct pci_dev *dev) * * tglx */ - if (irqd_irq_disabled(irq_get_irq_data(dev->irq)) + if (irqd_irq_disabled(irq_get_irq_data(dev->irq))) enable_irq(dev->irq); + } } /** -- cgit v1.2.3-55-g7522 From a5d90c923bcfb9632d998ed06e9569216ad695f3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 4 Mar 2014 17:02:17 +0100 Subject: x86/efi: Quirk out SGI UV Alex reported hitting the following BUG after the EFI 1:1 virtual mapping work was merged, kernel BUG at arch/x86/mm/init_64.c:351! invalid opcode: 0000 [#1] SMP Call Trace: [] init_extra_mapping_uc+0x13/0x15 [] uv_system_init+0x22b/0x124b [] ? clockevents_register_device+0x138/0x13d [] ? setup_APIC_timer+0xc5/0xc7 [] ? clockevent_delta2ns+0xb/0xd [] ? setup_boot_APIC_clock+0x4a8/0x4b7 [] ? printk+0x72/0x74 [] native_smp_prepare_cpus+0x389/0x3d6 [] kernel_init_freeable+0xb7/0x1fb [] ? rest_init+0x74/0x74 [] kernel_init+0x9/0xff [] ret_from_fork+0x7c/0xb0 [] ? rest_init+0x74/0x74 Getting this thing to work with the new mapping scheme would need more work, so automatically switch to the old memmap layout for SGI UV. Acked-by: Russ Anderson Cc: Alex Thorlton Signed-off-by: Matt Fleming --- arch/x86/include/asm/efi.h | 1 + arch/x86/kernel/setup.c | 10 ++-------- arch/x86/platform/efi/efi.c | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 3d6b9f81cc68..acd86c850414 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -134,6 +134,7 @@ extern void efi_setup_page_tables(void); extern void __init old_map_region(efi_memory_desc_t *md); extern void __init runtime_code_page_mkexec(void); extern void __init efi_runtime_mkexec(void); +extern void __init efi_apply_memmap_quirks(void); struct efi_setup_data { u64 fw_vendor; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 06853e670354..ce72964b2f46 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1239,14 +1239,8 @@ void __init setup_arch(char **cmdline_p) register_refined_jiffies(CLOCK_TICK_RATE); #ifdef CONFIG_EFI - /* Once setup is done above, unmap the EFI memory map on - * mismatched firmware/kernel archtectures since there is no - * support for runtime services. - */ - if (efi_enabled(EFI_BOOT) && !efi_is_native()) { - pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); - efi_unmap_memmap(); - } + if (efi_enabled(EFI_BOOT)) + efi_apply_memmap_quirks(); #endif } diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 1a201ac7cef8..b97acecf3fd9 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -52,6 +52,7 @@ #include #include #include +#include #define EFI_DEBUG @@ -1210,3 +1211,22 @@ static int __init parse_efi_cmdline(char *str) return 0; } early_param("efi", parse_efi_cmdline); + +void __init efi_apply_memmap_quirks(void) +{ + /* + * Once setup is done earlier, unmap the EFI memory map on mismatched + * firmware/kernel architectures since there is no support for runtime + * services. + */ + if (!efi_is_native()) { + pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + efi_unmap_memmap(); + } + + /* + * UV doesn't support the new EFI pagetable mapping yet. + */ + if (is_uv_system()) + set_bit(EFI_OLD_MEMMAP, &x86_efi_facility); +} -- cgit v1.2.3-55-g7522 From 0ac09f9f8cd1fb028a48330edba6023d347d3cea Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 28 Feb 2014 17:05:26 +0100 Subject: x86, trace: Fix CR2 corruption when tracing page faults The trace_do_page_fault function trigger tracepoint and then handles the actual page fault. This could lead to error if the tracepoint caused page fault. The original cr2 value gets lost and the original page fault handler kills current process with SIGSEGV. This happens if you record page faults with callchain data, the user part of it will cause tracepoint handler to page fault: # perf record -g -e exceptions:page_fault_user ls Fixing this by saving the original cr2 value and using it after tracepoint handler is done. v2: Moving the cr2 read before exception_enter, because it could trigger tracepoint as well. Reported-by: Arnaldo Carvalho de Melo Reported-by: Vince Weaver Tested-by: Vince Weaver Acked-by: Steven Rostedt Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Seiji Aguchi Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1402211701380.6395@vincent-weaver-1.um.maine.edu Link: http://lkml.kernel.org/r/20140228160526.GD1133@krava.brq.redhat.com --- arch/x86/mm/fault.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 6dea040cc3a1..e7fa28bf3262 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1022,11 +1022,11 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs) * routines. */ static void __kprobes -__do_page_fault(struct pt_regs *regs, unsigned long error_code) +__do_page_fault(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { struct vm_area_struct *vma; struct task_struct *tsk; - unsigned long address; struct mm_struct *mm; int fault; unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; @@ -1034,9 +1034,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) tsk = current; mm = tsk->mm; - /* Get the faulting address: */ - address = read_cr2(); - /* * Detect and handle instructions that would cause a page fault for * both a tracked kernel page and a userspace page. @@ -1252,9 +1249,11 @@ dotraplinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { enum ctx_state prev_state; + /* Get the faulting address: */ + unsigned long address = read_cr2(); prev_state = exception_enter(); - __do_page_fault(regs, error_code); + __do_page_fault(regs, error_code, address); exception_exit(prev_state); } @@ -1271,9 +1270,16 @@ dotraplinkage void __kprobes trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) { enum ctx_state prev_state; + /* + * The exception_enter and tracepoint processing could + * trigger another page faults (user space callchain + * reading) and destroy the original cr2 value, so read + * the faulting address now. + */ + unsigned long address = read_cr2(); prev_state = exception_enter(); trace_page_fault_entries(regs, error_code); - __do_page_fault(regs, error_code); + __do_page_fault(regs, error_code, address); exception_exit(prev_state); } -- cgit v1.2.3-55-g7522 From b663a685831905066e3efcb4c173cd8b3f46228b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 5 Mar 2014 10:03:59 +0000 Subject: x86, tools: Fix up compiler warnings The kbuild test robot reported the following errors that were introduced with commit 993c30a04e20 ("x86, tools: Consolidate #ifdef code"), arch/x86/boot/tools/build.c: In function 'update_pecoff_setup_and_reloc': >> arch/x86/boot/tools/build.c:252:1: error: parameter name omitted static inline void update_pecoff_setup_and_reloc(unsigned int) {} ^ arch/x86/boot/tools/build.c: In function 'update_pecoff_text': >> arch/x86/boot/tools/build.c:253:1: error: parameter name omitted static inline void update_pecoff_text(unsigned int, unsigned int) {} ^ >> arch/x86/boot/tools/build.c:253:1: error: parameter name omitted arch/x86/boot/tools/build.c: In function 'main': >> arch/x86/boot/tools/build.c:372:2: warning: implicit declaration of function 'efi_stub_entry_update' [-Wimplicit-function-declaration] efi_stub_entry_update(); ^ Signed-off-by: Matt Fleming --- arch/x86/boot/tools/build.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index 4f07df5ac5d9..1a2f2121cada 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -256,10 +256,11 @@ static void efi_stub_entry_update(void) #else -static inline void update_pecoff_setup_and_reloc(unsigned int) {} -static inline void update_pecoff_text(unsigned int, unsigned int) {} +static inline void update_pecoff_setup_and_reloc(unsigned int size) {} +static inline void update_pecoff_text(unsigned int text_start, + unsigned int file_sz) {} static inline void efi_stub_defaults(void) {} -static inline void efi_stup_entry_update(void) {} +static inline void efi_stub_entry_update(void) {} static inline int reserve_pecoff_reloc_section(int c) { -- cgit v1.2.3-55-g7522 From 3db4cafdfd05717dc939780134e53023a3c1f15f Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 5 Mar 2014 10:15:55 +0000 Subject: x86/boot: Fix non-EFI build The kbuild test robot reported the following errors, introduced with commit 54b52d872680 ("x86/efi: Build our own EFI services pointer table"), arch/x86/boot/compressed/head_32.o: In function `efi32_config': >> (.data+0x58): undefined reference to `efi_call_phys' arch/x86/boot/compressed/head_64.o: In function `efi64_config': >> (.data+0x90): undefined reference to `efi_call6' Wrap the efi*_config structures in #ifdef CONFIG_EFI_STUB so that we don't make references to EFI functions if they're not compiled in. Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/head_32.S | 2 ++ arch/x86/boot/compressed/head_64.S | 3 +++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index cccc05f0681c..de9d4200d305 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -229,12 +229,14 @@ relocated: xorl %ebx, %ebx jmp *%eax +#ifdef CONFIG_EFI_STUB .data efi32_config: .fill 11,8,0 .long efi_call_phys .long 0 .byte 0 +#endif /* * Stack and heap for uncompression diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 4f40cddd025d..57e58a5fa210 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -440,6 +440,7 @@ gdt: .quad 0x0000000000000000 /* TS continued */ gdt_end: +#ifdef CONFIG_EFI_STUB efi_config: .quad 0 @@ -456,6 +457,8 @@ efi64_config: .fill 11,8,0 .quad efi_call6 .byte 1 +#endif /* CONFIG_EFI_STUB */ + /* * Stack and heap for uncompression */ -- cgit v1.2.3-55-g7522 From abcfc543bec803a53c5bd2925d3293df4ede84b0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 5 Mar 2014 13:28:32 +0100 Subject: m68k: Do not rely on magic indirect includes commit: 8f945a33 (genirq: Move kstat_incr_irqs_this_cpu() to core) unearthed the following: arch/m68k/kernel/ints.c:34:15: error: variable 'auto_irq_chip' has initializer but incomplete type arch/m68k/kernel/ints.c:35:2: error: unknown field 'name' specified in initializer arch/m68k/kernel/ints.c:35:2: warning: excess elements in struct initializer [enabled by default] The reason is that this file requires linux/irq.h and magically pulled that in via linux/kernel_stat.h The commit above got rid of the pointless include of linux/irq.h in linux/kernel_stat.h and therefor broke the build. Include linux/irq.h Reported-by: fengguang.wu@intel.com Signed-off-by: Thomas Gleixner --- arch/m68k/kernel/ints.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 077d3a70fed1..5b8d66fbf383 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -10,9 +10,9 @@ #include #include #include -#include #include #include +#include #include #include -- cgit v1.2.3-55-g7522 From 76d388cd72ab08c2c56b1e2bd430e7422fc40168 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 5 Mar 2014 13:42:14 +0100 Subject: x86: hyperv: Fixup the (brain) damage caused by the irq cleanup Compiling last minute changes without setting the proper config options is not really clever. Reported-by: Fengguang Wu Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/mshyperv.h | 4 ++-- arch/x86/kernel/cpu/mshyperv.c | 6 +++--- drivers/hv/vmbus_drv.c | 26 ++++++-------------------- 3 files changed, 11 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index e98f66f35635..c163215abb9a 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -17,7 +17,7 @@ void hyperv_callback_vector(void); #define trace_hyperv_callback_vector hyperv_callback_vector #endif void hyperv_vector_handler(struct pt_regs *regs); -int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id); -void hv_remove_vmbus_irq(int irq, void *dev_id); +void hv_setup_vmbus_irq(void (*handler)(void)); +void hv_remove_vmbus_irq(void); #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a6f5f351f7af..b4dcca124918 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -32,7 +32,7 @@ struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); #if IS_ENABLED(CONFIG_HYPERV) -static irq_handler_t vmbus_handler; +static void (*vmbus_handler)(void); void hyperv_vector_handler(struct pt_regs *regs) { @@ -49,7 +49,7 @@ void hyperv_vector_handler(struct pt_regs *regs) set_irq_regs(old_regs); } -int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id) +void hv_setup_vmbus_irq(void (*handler)(void)) { vmbus_handler = handler; /* @@ -61,7 +61,7 @@ int hv_setup_vmbus_irq(int irq, irq_handler_t handler, void *dev_id) hyperv_callback_vector); } -void hv_remove_vmbus_irq(int irq, void *dev_id) +void hv_remove_vmbus_irq(void) { /* We have no way to deallocate the interrupt gate */ vmbus_handler = NULL; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 5a6909fff1c1..3f0a95290e14 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -615,7 +615,7 @@ static void vmbus_on_msg_dpc(unsigned long data) } } -static irqreturn_t vmbus_isr(int irq, void *dev_id) +static void vmbus_isr(void) { int cpu = smp_processor_id(); void *page_addr; @@ -625,7 +625,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) page_addr = hv_context.synic_event_page[cpu]; if (page_addr == NULL) - return IRQ_NONE; + return; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; @@ -661,15 +661,8 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; /* Check if there are actual msgs to be processed */ - if (msg->header.message_type != HVMSG_NONE) { - handled = true; + if (msg->header.message_type != HVMSG_NONE) tasklet_schedule(&msg_dpc); - } - - if (handled) - return IRQ_HANDLED; - else - return IRQ_NONE; } /* @@ -698,12 +691,7 @@ static int vmbus_bus_init(int irq) if (ret) goto err_cleanup; - ret = hv_setup_vmbus_irq(irq, vmbus_isr, hv_acpi_dev); - - if (ret != 0) { - pr_err("Unable to request IRQ %d\n", irq); - goto err_unregister; - } + hv_setup_vmbus_irq(vmbus_isr); ret = hv_synic_alloc(); if (ret) @@ -723,9 +711,8 @@ static int vmbus_bus_init(int irq) err_alloc: hv_synic_free(); - hv_remove_vmbus_irq(irq, hv_acpi_dev); + hv_remove_vmbus_irq(); -err_unregister: bus_unregister(&hv_bus); err_cleanup: @@ -917,7 +904,6 @@ static int __init hv_acpi_init(void) /* * Get irq resources first. */ - ret = acpi_bus_register_driver(&vmbus_acpi_driver); if (ret) @@ -948,7 +934,7 @@ cleanup: static void __exit vmbus_exit(void) { - hv_remove_vmbus_irq(irq, hv_acpi_dev); + hv_remove_vmbus_irq(); vmbus_free_channels(); bus_unregister(&hv_bus); hv_cleanup(); -- cgit v1.2.3-55-g7522 From a4f1987e4c5489a3877eaa7451a68d28c5a3f664 Mon Sep 17 00:00:00 2001 From: Li, Aubrey Date: Sun, 2 Mar 2014 18:39:02 +0800 Subject: x86, reboot: Add EFI and CF9 reboot methods into the default list Reboot is the last service linux OS provides to the end user. We are supposed to make this function more robust than today. This patch adds all of the known reboot methods into the default attempt list. The machines requiring reboot=efi or reboot=p or reboot=bios get a chance to reboot automatically now. If there is a new reboot method emerged, we are supposed to add it to the default list as well, instead of adding the endless dmidecode entry. If one method required is in the default list in this patch but the machine reboot still hangs, that means some methods ahead of the required method cause the system hangs, then reboot the machine by passing reboot= arguments and submit the reboot dmidecode table quirk. We are supposed to remove the reboot dmidecode table from the kernel, but to be safe, we keep it. This patch prevents us from adding more. If you happened to have a machine listed in the reboot dmidecode table and this patch makes reboot work on your machine, please submit a patch to remove the quirk. The default reboot order with this patch is now: ACPI > KBD > ACPI > KBD > EFI > CF9_COND > BIOS Because BIOS and TRIPLE are mutually exclusive (either will either work or hang the machine) that method is not included. [ hpa: as with any changes to the reboot order, this patch will have to be monitored carefully for regressions. ] Signed-off-by: Aubrey Li Acked-by: Matthew Garrett Link: http://lkml.kernel.org/r/53130A46.1010801@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/reboot.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index c752cb43e52f..f6012953e0d8 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -464,9 +464,12 @@ void __attribute__((weak)) mach_reboot_fixups(void) * 2) If still alive, write to the keyboard controller * 3) If still alive, write to the ACPI reboot register again * 4) If still alive, write to the keyboard controller again + * 5) If still alive, call the EFI runtime service to reboot + * 6) If still alive, write to the PCI IO port 0xCF9 to reboot + * 7) If still alive, inform BIOS to do a proper reboot * * If the machine is still alive at this stage, it gives up. We default to - * following the same pattern, except that if we're still alive after (4) we'll + * following the same pattern, except that if we're still alive after (7) we'll * try to force a triple fault and then cycle between hitting the keyboard * controller and doing that */ @@ -502,7 +505,7 @@ static void native_machine_emergency_restart(void) attempt = 1; reboot_type = BOOT_ACPI; } else { - reboot_type = BOOT_TRIPLE; + reboot_type = BOOT_EFI; } break; @@ -510,13 +513,15 @@ static void native_machine_emergency_restart(void) load_idt(&no_idt); __asm__ __volatile__("int3"); + /* We're probably dead after this, but... */ reboot_type = BOOT_KBD; break; case BOOT_BIOS: machine_real_restart(MRR_BIOS); - reboot_type = BOOT_KBD; + /* We're probably dead after this, but... */ + reboot_type = BOOT_TRIPLE; break; case BOOT_ACPI: @@ -530,7 +535,7 @@ static void native_machine_emergency_restart(void) EFI_RESET_WARM : EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); - reboot_type = BOOT_KBD; + reboot_type = BOOT_CF9; break; case BOOT_CF9: @@ -548,7 +553,7 @@ static void native_machine_emergency_restart(void) outb(cf9|reboot_code, 0xcf9); udelay(50); } - reboot_type = BOOT_KBD; + reboot_type = BOOT_BIOS; break; } } -- cgit v1.2.3-55-g7522 From fb3bd7b19b2b6ef779d18573c10c00c53cd8add6 Mon Sep 17 00:00:00 2001 From: H. Peter Anvin Date: Wed, 5 Mar 2014 15:41:15 -0800 Subject: x86, reboot: Only use CF9_COND automatically, not CF9 Only CF9_COND is appropriate for inclusion in the default chain, not CF9; the latter will poke that register unconditionally, whereas CF9_COND will at least look for PCI configuration method #1 or #2 first (a weak check, but better than nothing.) CF9 should be used for explicit system configuration (command line or DMI) only. Cc: Aubrey Li Cc: Matthew Garrett Link: http://lkml.kernel.org/r/53130A46.1010801@linux.intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/reboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index f6012953e0d8..654b46574b91 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -535,7 +535,7 @@ static void native_machine_emergency_restart(void) EFI_RESET_WARM : EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); - reboot_type = BOOT_CF9; + reboot_type = BOOT_CF9_COND; break; case BOOT_CF9: -- cgit v1.2.3-55-g7522 From e571c58f313d35c56e0018470e3375ddd1fd320e Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Thu, 6 Mar 2014 10:29:27 +1100 Subject: m68k: Skip futex_atomic_cmpxchg_inatomic() test Skip the futex_atomic_cmpxchg_inatomic() test in futex_init(). It causes a fatal exception on 68030 (and presumably 68020 also). Signed-off-by: Finn Thain Acked-by: Geert Uytterhoeven Link: http://lkml.kernel.org/r/alpine.LNX.2.00.1403061006440.5525@nippy.intranet Signed-off-by: Thomas Gleixner --- arch/m68k/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index dbdd2231c75d..b2e322939256 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -17,6 +17,7 @@ config M68K select FPU if MMU select ARCH_WANT_IPC_PARSE_VERSION select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE + select HAVE_FUTEX_CMPXCHG if MMU && FUTEX select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_REL select MODULES_USE_ELF_RELA -- cgit v1.2.3-55-g7522 From 7ff42473ebdee32ed3ac34f6bf4b4080c7455840 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 6 Mar 2014 12:08:37 +0100 Subject: x86: hardirq: Make irq_hv_callback_count available for CONFIG_HYPERV=m as well Reported-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/hardirq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index afb6536ee3ac..230853da4ec0 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -33,7 +33,7 @@ typedef struct { #ifdef CONFIG_X86_MCE_THRESHOLD unsigned int irq_threshold_count; #endif -#if defined(CONFIG_HYPERV) || defined(CONFIG_XEN) +#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) unsigned int irq_hv_callback_count; #endif } ____cacheline_aligned irq_cpustat_t; -- cgit v1.2.3-55-g7522 From 378a10f3ae2e8a67ecc8f548c8e5ff25881bd88a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 5 Mar 2014 10:43:51 +0100 Subject: fs/compat: optional preadv64/pwrite64 compat system calls The preadv64/pwrite64 have been implemented for the x32 ABI, in order to allow passing 64 bit arguments from user space without splitting them into two 32 bit parameters, like it would be necessary for usual compat tasks. Howevert these two system calls are only being used for the x32 ABI, so add __ARCH_WANT_COMPAT defines for these two compat syscalls and make these two only visible for x86. Signed-off-by: Heiko Carstens --- arch/x86/include/asm/unistd.h | 2 ++ fs/read_write.c | 36 ++++++++++++++++++++++++++++-------- include/linux/compat.h | 13 +++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index f4b5795d7e34..3f556c6a0157 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h @@ -24,6 +24,8 @@ # include # define __ARCH_WANT_COMPAT_SYS_TIME # define __ARCH_WANT_COMPAT_SYS_GETDENTS64 +# define __ARCH_WANT_COMPAT_SYS_PREADV64 +# define __ARCH_WANT_COMPAT_SYS_PWRITEV64 # endif diff --git a/fs/read_write.c b/fs/read_write.c index edc5746a902a..72c09b4a01a4 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -982,9 +982,9 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, return ret; } -COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, - const struct compat_iovec __user *,vec, - unsigned long, vlen, loff_t, pos) +static long __compat_sys_preadv64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos) { struct fd f; ssize_t ret; @@ -1001,12 +1001,22 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, return ret; } +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 +COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos) +{ + return __compat_sys_preadv64(fd, vec, vlen, pos); +} +#endif + COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, const struct compat_iovec __user *,vec, compat_ulong_t, vlen, u32, pos_low, u32, pos_high) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; - return compat_sys_preadv64(fd, vec, vlen, pos); + + return __compat_sys_preadv64(fd, vec, vlen, pos); } static size_t compat_writev(struct file *file, @@ -1049,9 +1059,9 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, return ret; } -COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, - const struct compat_iovec __user *,vec, - unsigned long, vlen, loff_t, pos) +static long __compat_sys_pwritev64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos) { struct fd f; ssize_t ret; @@ -1068,12 +1078,22 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, return ret; } +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 +COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos) +{ + return __compat_sys_pwritev64(fd, vec, vlen, pos); +} +#endif + COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, const struct compat_iovec __user *,vec, compat_ulong_t, vlen, u32, pos_low, u32, pos_high) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; - return compat_sys_pwritev64(fd, vec, vlen, pos); + + return __compat_sys_pwritev64(fd, vec, vlen, pos); } #endif diff --git a/include/linux/compat.h b/include/linux/compat.h index 179b1da9e19f..1c457428ec0a 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -340,6 +340,19 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, const struct compat_iovec __user *vec, compat_ulong_t vlen, u32 pos_low, u32 pos_high); + +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64 +asmlinkage long compat_sys_preadv64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos); +#endif + +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64 +asmlinkage long compat_sys_pwritev64(unsigned long fd, + const struct compat_iovec __user *vec, + unsigned long vlen, loff_t pos); +#endif + asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, -- cgit v1.2.3-55-g7522 From 932602e238329da99f8482c1b721549531fbfe7f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 4 Mar 2014 16:07:52 +0100 Subject: fs/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types Some fs compat system calls have unsigned long parameters instead of compat_ulong_t. In order to allow the COMPAT_SYSCALL_DEFINE macro generate code that performs proper zero and sign extension convert all 64 bit parameters their corresponding 32 bit counterparts. compat_sys_io_getevents() is a bit different: the non-compat version has signed parameters for the "min_nr" and "nr" parameters while the compat version has unsigned parameters. So change this as well. For all practical purposes this shouldn't make any difference (doesn't fix a real bug). Also introduce a generic compat_aio_context_t type which can be used everywhere. The access_ok() check within compat_sys_io_getevents() got also removed since the non-compat sys_io_getevents() should be able to handle everything anyway. Signed-off-by: Heiko Carstens --- arch/s390/include/asm/compat.h | 1 - fs/compat.c | 44 +++++++++++++++++------------------------- fs/compat_ioctl.c | 5 +++-- include/linux/compat.h | 18 +++++++++-------- 4 files changed, 31 insertions(+), 37 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 1174ea2b5e7c..5d7e8cf83bd6 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -65,7 +65,6 @@ typedef u32 compat_caddr_t; typedef __kernel_fsid_t compat_fsid_t; typedef s32 compat_key_t; typedef s32 compat_timer_t; -typedef u32 compat_aio_context_t; typedef s32 compat_int_t; typedef s32 compat_long_t; diff --git a/fs/compat.c b/fs/compat.c index 6d8312b7a51d..19252b97f0cc 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -399,8 +399,8 @@ static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *u } #endif -asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, - unsigned long arg) +COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, + compat_ulong_t, arg) { mm_segment_t old_fs; struct flock f; @@ -468,8 +468,8 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, return ret; } -asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, - unsigned long arg) +COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, + compat_ulong_t, arg) { if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64)) return -EINVAL; @@ -495,32 +495,24 @@ COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p) return ret; } -asmlinkage long -compat_sys_io_getevents(aio_context_t ctx_id, - unsigned long min_nr, - unsigned long nr, - struct io_event __user *events, - struct compat_timespec __user *timeout) +COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id, + compat_long_t, min_nr, + compat_long_t, nr, + struct io_event __user *, events, + struct compat_timespec __user *, timeout) { - long ret; struct timespec t; struct timespec __user *ut = NULL; - ret = -EFAULT; - if (unlikely(!access_ok(VERIFY_WRITE, events, - nr * sizeof(struct io_event)))) - goto out; if (timeout) { if (get_compat_timespec(&t, timeout)) - goto out; + return -EFAULT; ut = compat_alloc_user_space(sizeof(*ut)); if (copy_to_user(ut, &t, sizeof(t)) ) - goto out; + return -EFAULT; } - ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut); -out: - return ret; + return sys_io_getevents(ctx_id, min_nr, nr, events, ut); } /* A write operation does a read from user space and vice versa */ @@ -616,8 +608,8 @@ copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64) #define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) -asmlinkage long -compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb) +COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, + int, nr, u32 __user *, iocb) { struct iocb __user * __user *iocb64; long ret; @@ -769,10 +761,10 @@ static int do_nfs4_super_data_conv(void *raw_data) #define NCPFS_NAME "ncpfs" #define NFS4_NAME "nfs4" -asmlinkage long compat_sys_mount(const char __user * dev_name, - const char __user * dir_name, - const char __user * type, unsigned long flags, - const void __user * data) +COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, + const char __user *, dir_name, + const char __user *, type, compat_ulong_t, flags, + const void __user *, data) { char *kernel_type; unsigned long data_page; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 3881610b6438..e82289047272 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1538,9 +1538,10 @@ static int compat_ioctl_check_table(unsigned int xcmd) return ioctl_pointer[i] == xcmd; } -asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg) +COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, + compat_ulong_t, arg32) { + unsigned long arg = arg32; struct fd f = fdget(fd); int error = -EBADF; if (!f.file) diff --git a/include/linux/compat.h b/include/linux/compat.h index 1c457428ec0a..fea8ee9afe22 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -71,6 +71,8 @@ typedef struct compat_sigaltstack { typedef __compat_uid32_t compat_uid_t; typedef __compat_gid32_t compat_gid_t; +typedef compat_ulong_t compat_aio_context_t; + struct compat_sel_arg_struct; struct rusage; @@ -497,20 +499,20 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname, asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user *buf); asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, - unsigned long arg); + compat_ulong_t arg); asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, - unsigned long arg); + compat_ulong_t arg); asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); -asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, - unsigned long min_nr, - unsigned long nr, +asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id, + compat_long_t min_nr, + compat_long_t nr, struct io_event __user *events, struct compat_timespec __user *timeout); -asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, +asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr, u32 __user *iocb); asmlinkage long compat_sys_mount(const char __user *dev_name, const char __user *dir_name, - const char __user *type, unsigned long flags, + const char __user *type, compat_ulong_t flags, const void __user *data); asmlinkage long compat_sys_old_readdir(unsigned int fd, struct compat_old_linux_dirent __user *, @@ -633,7 +635,7 @@ asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig, struct compat_siginfo __user *uinfo); asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, - unsigned long arg); + compat_ulong_t arg); asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, struct compat_timespec __user *utime, u32 __user *uaddr2, u32 val3); -- cgit v1.2.3-55-g7522 From 9a205286bcca84b38d3ab1689f16236d1935af2d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 5 Mar 2014 12:55:06 +0100 Subject: s390/compat: build error for large compat syscall args Enforce 32 bit types for all compat syscall argument types. This way we can make sure that all arguments get correct sign or zero extension. Otherwise incorrect code would be generated. E.g. for a 'long' type the COMPAT_SYSCALL_DEFINE macro wouldn't generate code that would cause sign extension of the passed in 32 bit user space parameter. This can cause quite subtle bugs like e.g. the one that was fixed with dfd948e32af2e "fs/compat: fix parameter handling for compat readv/writev syscalls". Signed-off-by: Heiko Carstens --- arch/s390/include/asm/compat.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 5d7e8cf83bd6..d350ed9d0fbb 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -8,7 +8,11 @@ #include #define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) -#define __SC_DELOUSE(t,v) (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)) + +#define __SC_DELOUSE(t,v) ({ \ + BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ + (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ +}) #define PSW32_MASK_PER 0x40000000UL #define PSW32_MASK_DAT 0x04000000UL -- cgit v1.2.3-55-g7522 From 5b098c204827ed21961988b4206b411f90cc89c8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 5 Mar 2014 10:05:56 +0100 Subject: s390/compat: get rid of compat wrapper assembly code Now that all compat syscalls have been converted to use the COMPAT_SYSCALL_DEFINE macros, we don't need to compat syscall wrapper assembly code anymore. So remove it and fix up the system call table accordingly. Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 1 - arch/s390/kernel/compat_linux.h | 2 + arch/s390/kernel/compat_signal.c | 4 +- arch/s390/kernel/compat_wrap.c | 209 --------------------- arch/s390/kernel/compat_wrapper.S | 369 -------------------------------------- arch/s390/kernel/compat_wrapper.c | 209 +++++++++++++++++++++ arch/s390/kernel/entry.h | 5 - arch/s390/kernel/syscalls.S | 124 ++++++------- 8 files changed, 275 insertions(+), 648 deletions(-) delete mode 100644 arch/s390/kernel/compat_wrap.c delete mode 100644 arch/s390/kernel/compat_wrapper.S create mode 100644 arch/s390/kernel/compat_wrapper.c (limited to 'arch') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 725515f9c5db..1b3ac09c11b6 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -50,7 +50,6 @@ compat-obj-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ compat_wrapper.o compat_exec_domain.o \ $(compat-obj-y) -obj-$(CONFIG_COMPAT) += compat_wrap.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_KPROBES) += kprobes.o diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 330e11d164d7..39ddfdb40ae8 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -112,5 +112,7 @@ long compat_sys_s390_fadvise64(int fd, u32 high, u32 low, compat_size_t len, int long compat_sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); long compat_sys_s390_sync_file_range(int fd, u32 offhigh, u32 offlow, u32 nhigh, u32 nlow, unsigned int flags); long compat_sys_s390_fallocate(int fd, int mode, u32 offhigh, u32 offlow, u32 lenhigh, u32 lenlow); +long compat_sys_sigreturn(void); +long compat_sys_rt_sigreturn(void); #endif /* _ASM_S390X_S390_H */ diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 8b84bc373e94..7df5ed9f44d7 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -241,7 +241,7 @@ static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs) return 0; } -asmlinkage long sys32_sigreturn(void) +COMPAT_SYSCALL_DEFINE0(sigreturn) { struct pt_regs *regs = task_pt_regs(current); sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; @@ -260,7 +260,7 @@ badframe: return 0; } -asmlinkage long sys32_rt_sigreturn(void) +COMPAT_SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = task_pt_regs(current); rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; diff --git a/arch/s390/kernel/compat_wrap.c b/arch/s390/kernel/compat_wrap.c deleted file mode 100644 index d123f5d87b82..000000000000 --- a/arch/s390/kernel/compat_wrap.c +++ /dev/null @@ -1,209 +0,0 @@ -#include -#include -#include "entry.h" - -#define COMPAT_SYSCALL_WRAP1(name, ...) \ - COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP2(name, ...) \ - COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP3(name, ...) \ - COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP4(name, ...) \ - COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP5(name, ...) \ - COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) -#define COMPAT_SYSCALL_WRAP6(name, ...) \ - COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) - -#define __SC_COMPAT_TYPE(t, a) \ - __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a - -#define __SC_COMPAT_CAST(t, a) \ -({ \ - long __ReS = a; \ - \ - BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ - !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ - if (__TYPE_IS_L(t)) \ - __ReS = (s32)a; \ - if (__TYPE_IS_UL(t)) \ - __ReS = (u32)a; \ - if (__TYPE_IS_PTR(t)) \ - __ReS = a & 0x7fffffff; \ - (t)__ReS; \ -}) - -/* - * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by - * compat tasks. These wrappers will only be used for system calls where only - * the system call arguments need sign or zero extension or zeroing of the upper - * 33 bits of pointers. - * Note: since the wrapper function will afterwards call a system call which - * again performs zero and sign extension for all system call arguments with - * a size of less than eight bytes, these compat wrappers only touch those - * system call arguments with a size of eight bytes ((unsigned) long and - * pointers). Zero and sign extension for e.g. int parameters will be done by - * the regular system call wrappers. - */ -#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ - asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ - asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ - asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ - { \ - return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ - } - -COMPAT_SYSCALL_WRAP1(exit, int, error_code); -COMPAT_SYSCALL_WRAP1(close, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); -COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); -COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); -COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename); -COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev); -COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode); -COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name); -COMPAT_SYSCALL_WRAP1(alarm, unsigned int, seconds); -COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode); -COMPAT_SYSCALL_WRAP1(nice, int, increment); -COMPAT_SYSCALL_WRAP2(kill, int, pid, int, sig); -COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname); -COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode); -COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname); -COMPAT_SYSCALL_WRAP1(dup, unsigned int, fildes); -COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes); -COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); -COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); -COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); -COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); -COMPAT_SYSCALL_WRAP2(setpgid, pid_t, pid, pid_t, pgid); -COMPAT_SYSCALL_WRAP1(umask, int, mask); -COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename); -COMPAT_SYSCALL_WRAP2(dup2, unsigned int, oldfd, unsigned int, newfd); -COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask); -COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len); -COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new); -COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); -COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); -COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); -COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg); -COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len); -COMPAT_SYSCALL_WRAP2(fchmod, unsigned int, fd, umode_t, mode); -COMPAT_SYSCALL_WRAP2(getpriority, int, which, int, who); -COMPAT_SYSCALL_WRAP3(setpriority, int, which, int, who, int, niceval); -COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len); -COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); -COMPAT_SYSCALL_WRAP1(fsync, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); -COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); -COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot); -COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs); -COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags); -COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr); -COMPAT_SYSCALL_WRAP1(getpgid, pid_t, pid); -COMPAT_SYSCALL_WRAP1(fchdir, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data); -COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2); -COMPAT_SYSCALL_WRAP1(s390_personality, unsigned int, personality); -COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence); -COMPAT_SYSCALL_WRAP2(flock, unsigned int, fd, unsigned int, cmd); -COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags); -COMPAT_SYSCALL_WRAP1(getsid, pid_t, pid); -COMPAT_SYSCALL_WRAP1(fdatasync, unsigned int, fd); -COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len); -COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len); -COMPAT_SYSCALL_WRAP1(mlockall, int, flags); -COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param); -COMPAT_SYSCALL_WRAP1(sched_getscheduler, pid_t, pid); -COMPAT_SYSCALL_WRAP1(sched_get_priority_max, int, policy); -COMPAT_SYSCALL_WRAP1(sched_get_priority_min, int, policy); -COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr); -COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout); -COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5); -COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size); -COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); -COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); -COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group); -COMPAT_SYSCALL_WRAP2(setreuid, uid_t, ruid, uid_t, euid); -COMPAT_SYSCALL_WRAP2(setregid, gid_t, rgid, gid_t, egid); -COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist); -COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist); -COMPAT_SYSCALL_WRAP3(fchown, unsigned int, fd, uid_t, user, gid_t, group); -COMPAT_SYSCALL_WRAP3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid); -COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid); -COMPAT_SYSCALL_WRAP3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid); -COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid); -COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group); -COMPAT_SYSCALL_WRAP1(setuid, uid_t, uid); -COMPAT_SYSCALL_WRAP1(setgid, gid_t, gid); -COMPAT_SYSCALL_WRAP1(setfsuid, uid_t, uid); -COMPAT_SYSCALL_WRAP1(setfsgid, gid_t, gid); -COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old); -COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec); -COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior); -COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); -COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); -COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags); -COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count); -COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); -COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); -COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size); -COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size); -COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size); -COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size); -COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); -COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); -COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); -COMPAT_SYSCALL_WRAP1(exit_group, int, error_code); -COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr); -COMPAT_SYSCALL_WRAP1(epoll_create, int, size); -COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event); -COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout); -COMPAT_SYSCALL_WRAP1(timer_getoverrun, timer_t, timer_id); -COMPAT_SYSCALL_WRAP1(timer_delete, compat_timer_t, compat_timer_id); -COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx); -COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); -COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); -COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id); -COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id); -COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags); -COMPAT_SYSCALL_WRAP3(ioprio_set, int, which, int, who, int, ioprio); -COMPAT_SYSCALL_WRAP2(ioprio_get, int, which, int, who); -COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask); -COMPAT_SYSCALL_WRAP2(inotify_rm_watch, int, fd, __s32, wd); -COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); -COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); -COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag); -COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag); -COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname); -COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags); -COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname); -COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz); -COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode); -COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode); -COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags); -COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); -COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags); -COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache); -COMPAT_SYSCALL_WRAP1(eventfd, unsigned int, count); -COMPAT_SYSCALL_WRAP2(timerfd_create, int, clockid, int, flags); -COMPAT_SYSCALL_WRAP2(eventfd2, unsigned int, count, int, flags); -COMPAT_SYSCALL_WRAP1(inotify_init1, int, flags); -COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags); -COMPAT_SYSCALL_WRAP3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags); -COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); -COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); -COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); -COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); -COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); -COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); -COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); -COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); -COMPAT_SYSCALL_WRAP1(syncfs, int, fd); -COMPAT_SYSCALL_WRAP2(setns, int, fd, int, nstype); -COMPAT_SYSCALL_WRAP2(s390_runtime_instr, int, command, int, signum); -COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2); -COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); -COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); -COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S deleted file mode 100644 index 23d9f8a7c6f5..000000000000 --- a/arch/s390/kernel/compat_wrapper.S +++ /dev/null @@ -1,369 +0,0 @@ -/* -* wrapper for 31 bit compatible system calls. -* -* Copyright IBM Corp. 2000, 2006 -* Author(s): Gerhard Tonn (ton@de.ibm.com), -* Thomas Spatzier (tspat@de.ibm.com) -*/ - -#include - -ENTRY(sys32_time_wrapper) - llgtr %r2,%r2 # int * - jg compat_sys_time # branch to system call - -#sys32_getpid_wrapper # void - -ENTRY(sys32_mount_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # char * - llgfr %r5,%r5 # unsigned long - llgtr %r6,%r6 # void * - jg compat_sys_mount # branch to system call - -ENTRY(sys32_ptrace_wrapper) - lgfr %r2,%r2 # long - lgfr %r3,%r3 # long - llgtr %r4,%r4 # long - llgfr %r5,%r5 # long - jg compat_sys_ptrace # branch to system call - -ENTRY(compat_sys_utime_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct compat_utimbuf * - jg compat_sys_utime # branch to system call - -ENTRY(compat_sys_times_wrapper) - llgtr %r2,%r2 # struct compat_tms * - jg compat_sys_times # branch to system call - -ENTRY(compat_sys_ioctl_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - llgfr %r4,%r4 # unsigned int - jg compat_sys_ioctl # branch to system call - -ENTRY(compat_sys_fcntl_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - llgfr %r4,%r4 # unsigned long - jg compat_sys_fcntl # branch to system call - -ENTRY(sys32_ustat_wrapper) - llgfr %r2,%r2 # dev_t - llgtr %r3,%r3 # struct ustat * - jg compat_sys_ustat - -ENTRY(compat_sys_sigpending_wrapper) - llgtr %r2,%r2 # compat_old_sigset_t * - jg compat_sys_sigpending # branch to system call - -ENTRY(compat_sys_setrlimit_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct rlimit_emu31 * - jg compat_sys_setrlimit # branch to system call - -ENTRY(compat_sys_old_getrlimit_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct rlimit_emu31 * - jg compat_sys_old_getrlimit # branch to system call - -ENTRY(compat_sys_getrlimit_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct rlimit_emu31 * - jg compat_sys_getrlimit # branch to system call - -ENTRY(compat_sys_gettimeofday_wrapper) - llgtr %r2,%r2 # struct timeval_emu31 * - llgtr %r3,%r3 # struct timezone * - jg compat_sys_gettimeofday # branch to system call - -ENTRY(compat_sys_settimeofday_wrapper) - llgtr %r2,%r2 # struct timeval_emu31 * - llgtr %r3,%r3 # struct timezone * - jg compat_sys_settimeofday # branch to system call - -ENTRY(old32_readdir_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # void * - llgfr %r4,%r4 # unsigned int - jg compat_sys_old_readdir # branch to system call - -ENTRY(compat_sys_statfs_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct compat_statfs * - jg compat_sys_statfs # branch to system call - -ENTRY(compat_sys_fstatfs_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct compat_statfs * - jg compat_sys_fstatfs # branch to system call - -ENTRY(compat_sys_socketcall_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # u32 * - jg compat_sys_socketcall # branch to system call - -ENTRY(compat_sys_newstat_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct stat_emu31 * - jg compat_sys_newstat # branch to system call - -ENTRY(compat_sys_newlstat_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct stat_emu31 * - jg compat_sys_newlstat # branch to system call - -ENTRY(compat_sys_newfstat_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # struct stat_emu31 * - jg compat_sys_newfstat # branch to system call - -ENTRY(compat_sys_sysinfo_wrapper) - llgtr %r2,%r2 # struct sysinfo_emu31 * - jg compat_sys_sysinfo # branch to system call - -ENTRY(compat_sys_adjtimex_wrapper) - llgtr %r2,%r2 # struct compat_timex * - jg compat_sys_adjtimex # branch to system call - -ENTRY(sys32_getdents_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # void * - llgfr %r4,%r4 # unsigned int - jg compat_sys_getdents # branch to system call - -ENTRY(compat_sys_select_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # compat_fd_set * - llgtr %r4,%r4 # compat_fd_set * - llgtr %r5,%r5 # compat_fd_set * - llgtr %r6,%r6 # struct compat_timeval * - jg compat_sys_select # branch to system call - -ENTRY(compat_sys_readv_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const struct compat_iovec * - llgfr %r4,%r4 # unsigned long - jg compat_sys_readv # branch to system call - -ENTRY(compat_sys_writev_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # const struct compat_iovec * - llgfr %r4,%r4 # unsigned long - jg compat_sys_writev # branch to system call - -ENTRY(compat_sys_nanosleep_wrapper) - llgtr %r2,%r2 # struct compat_timespec * - llgtr %r3,%r3 # struct compat_timespec * - jg compat_sys_nanosleep # branch to system call - -ENTRY(compat_sys_fcntl64_wrapper) - llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int - llgfr %r4,%r4 # unsigned long - jg compat_sys_fcntl64 # branch to system call - -ENTRY(sys32_stime_wrapper) - llgtr %r2,%r2 # long * - jg compat_sys_stime # branch to system call - -ENTRY(sys32_sched_setaffinity_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # unsigned int - llgtr %r4,%r4 # unsigned long * - jg compat_sys_sched_setaffinity - -ENTRY(sys32_sched_getaffinity_wrapper) - lgfr %r2,%r2 # int - llgfr %r3,%r3 # unsigned int - llgtr %r4,%r4 # unsigned long * - jg compat_sys_sched_getaffinity - -ENTRY(sys32_clock_settime_wrapper) - lgfr %r2,%r2 # clockid_t (int) - llgtr %r3,%r3 # struct compat_timespec * - jg compat_sys_clock_settime - -ENTRY(sys32_clock_gettime_wrapper) - lgfr %r2,%r2 # clockid_t (int) - llgtr %r3,%r3 # struct compat_timespec * - jg compat_sys_clock_gettime - -ENTRY(sys32_clock_getres_wrapper) - lgfr %r2,%r2 # clockid_t (int) - llgtr %r3,%r3 # struct compat_timespec * - jg compat_sys_clock_getres - -ENTRY(sys32_clock_nanosleep_wrapper) - lgfr %r2,%r2 # clockid_t (int) - lgfr %r3,%r3 # int - llgtr %r4,%r4 # struct compat_timespec * - llgtr %r5,%r5 # struct compat_timespec * - jg compat_sys_clock_nanosleep - -ENTRY(sys32_timer_create_wrapper) - lgfr %r2,%r2 # timer_t (int) - llgtr %r3,%r3 # struct compat_sigevent * - llgtr %r4,%r4 # timer_t * - jg compat_sys_timer_create - -ENTRY(sys32_timer_settime_wrapper) - lgfr %r2,%r2 # timer_t (int) - lgfr %r3,%r3 # int - llgtr %r4,%r4 # struct compat_itimerspec * - llgtr %r5,%r5 # struct compat_itimerspec * - jg compat_sys_timer_settime - -ENTRY(sys32_timer_gettime_wrapper) - lgfr %r2,%r2 # timer_t (int) - llgtr %r3,%r3 # struct compat_itimerspec * - jg compat_sys_timer_gettime - -ENTRY(sys32_io_setup_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # u32 * - jg compat_sys_io_setup - -ENTRY(sys32_io_getevents_wrapper) - llgfr %r2,%r2 # (aio_context_t) u32 - lgfr %r3,%r3 # long - lgfr %r4,%r4 # long - llgtr %r5,%r5 # struct io_event * - llgtr %r6,%r6 # struct compat_timespec * - jg compat_sys_io_getevents - -ENTRY(sys32_io_submit_wrapper) - llgfr %r2,%r2 # (aio_context_t) u32 - lgfr %r3,%r3 # long - llgtr %r4,%r4 # struct iocb ** - jg compat_sys_io_submit - -ENTRY(compat_sys_statfs64_wrapper) - llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # compat_size_t - llgtr %r4,%r4 # struct compat_statfs64 * - jg compat_sys_statfs64 - -ENTRY(compat_sys_fstatfs64_wrapper) - llgfr %r2,%r2 # unsigned int fd - llgfr %r3,%r3 # compat_size_t - llgtr %r4,%r4 # struct compat_statfs64 * - jg compat_sys_fstatfs64 - -ENTRY(compat_sys_mq_open_wrapper) - llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int - llgfr %r4,%r4 # mode_t - llgtr %r5,%r5 # struct compat_mq_attr * - jg compat_sys_mq_open - -ENTRY(compat_sys_mq_timedsend_wrapper) - lgfr %r2,%r2 # mqd_t - llgtr %r3,%r3 # const char * - llgfr %r4,%r4 # size_t - llgfr %r5,%r5 # unsigned int - llgtr %r6,%r6 # const struct compat_timespec * - jg compat_sys_mq_timedsend - -ENTRY(compat_sys_mq_timedreceive_wrapper) - lgfr %r2,%r2 # mqd_t - llgtr %r3,%r3 # char * - llgfr %r4,%r4 # size_t - llgtr %r5,%r5 # unsigned int * - llgtr %r6,%r6 # const struct compat_timespec * - jg compat_sys_mq_timedreceive - -ENTRY(compat_sys_mq_notify_wrapper) - lgfr %r2,%r2 # mqd_t - llgtr %r3,%r3 # struct compat_sigevent * - jg compat_sys_mq_notify - -ENTRY(compat_sys_mq_getsetattr_wrapper) - lgfr %r2,%r2 # mqd_t - llgtr %r3,%r3 # struct compat_mq_attr * - llgtr %r4,%r4 # struct compat_mq_attr * - jg compat_sys_mq_getsetattr - -ENTRY(compat_sys_kexec_load_wrapper) - llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # unsigned long - llgtr %r4,%r4 # struct kexec_segment * - llgfr %r5,%r5 # unsigned long - jg compat_sys_kexec_load - -ENTRY(compat_sys_futimesat_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # struct timeval * - jg compat_sys_futimesat - -ENTRY(compat_sys_pselect6_wrapper) - lgfr %r2,%r2 # int - llgtr %r3,%r3 # fd_set * - llgtr %r4,%r4 # fd_set * - llgtr %r5,%r5 # fd_set * - llgtr %r6,%r6 # struct timespec * - llgt %r0,164(%r15) # void * - stg %r0,160(%r15) - jg compat_sys_pselect6 - -ENTRY(compat_sys_ppoll_wrapper) - llgtr %r2,%r2 # struct pollfd * - llgfr %r3,%r3 # unsigned int - llgtr %r4,%r4 # struct timespec * - llgtr %r5,%r5 # const sigset_t * - llgfr %r6,%r6 # size_t - jg compat_sys_ppoll - -ENTRY(compat_sys_utimes_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # struct compat_timeval * - jg compat_sys_utimes - -ENTRY(compat_sys_utimensat_wrapper) - llgfr %r2,%r2 # unsigned int - llgtr %r3,%r3 # char * - llgtr %r4,%r4 # struct compat_timespec * - lgfr %r5,%r5 # int - jg compat_sys_utimensat - -ENTRY(compat_sys_keyctl_wrapper) - llgfr %r2,%r2 # u32 - llgfr %r3,%r3 # u32 - llgfr %r4,%r4 # u32 - llgfr %r5,%r5 # u32 - llgfr %r6,%r6 # u32 - jg compat_sys_keyctl # branch to system call - -ENTRY(sys32_execve_wrapper) - llgtr %r2,%r2 # char * - llgtr %r3,%r3 # compat_uptr_t * - llgtr %r4,%r4 # compat_uptr_t * - jg compat_sys_execve # branch to system call - -ENTRY(compat_sys_clock_adjtime_wrapper) - lgfr %r2,%r2 # clockid_t (int) - llgtr %r3,%r3 # struct compat_timex __user * - jg compat_sys_clock_adjtime - -ENTRY(compat_sys_process_vm_readv_wrapper) - lgfr %r2,%r2 # compat_pid_t - llgtr %r3,%r3 # struct compat_iovec __user * - llgfr %r4,%r4 # unsigned long - llgtr %r5,%r5 # struct compat_iovec __user * - llgfr %r6,%r6 # unsigned long - llgf %r0,164(%r15) # unsigned long - stg %r0,160(%r15) - jg compat_sys_process_vm_readv - -ENTRY(compat_sys_process_vm_writev_wrapper) - lgfr %r2,%r2 # compat_pid_t - llgtr %r3,%r3 # struct compat_iovec __user * - llgfr %r4,%r4 # unsigned long - llgtr %r5,%r5 # struct compat_iovec __user * - llgfr %r6,%r6 # unsigned long - llgf %r0,164(%r15) # unsigned long - stg %r0,160(%r15) - jg compat_sys_process_vm_writev diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c new file mode 100644 index 000000000000..d123f5d87b82 --- /dev/null +++ b/arch/s390/kernel/compat_wrapper.c @@ -0,0 +1,209 @@ +#include +#include +#include "entry.h" + +#define COMPAT_SYSCALL_WRAP1(name, ...) \ + COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP2(name, ...) \ + COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP3(name, ...) \ + COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP4(name, ...) \ + COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP5(name, ...) \ + COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) +#define COMPAT_SYSCALL_WRAP6(name, ...) \ + COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) + +#define __SC_COMPAT_TYPE(t, a) \ + __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a + +#define __SC_COMPAT_CAST(t, a) \ +({ \ + long __ReS = a; \ + \ + BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ + !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ + if (__TYPE_IS_L(t)) \ + __ReS = (s32)a; \ + if (__TYPE_IS_UL(t)) \ + __ReS = (u32)a; \ + if (__TYPE_IS_PTR(t)) \ + __ReS = a & 0x7fffffff; \ + (t)__ReS; \ +}) + +/* + * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by + * compat tasks. These wrappers will only be used for system calls where only + * the system call arguments need sign or zero extension or zeroing of the upper + * 33 bits of pointers. + * Note: since the wrapper function will afterwards call a system call which + * again performs zero and sign extension for all system call arguments with + * a size of less than eight bytes, these compat wrappers only touch those + * system call arguments with a size of eight bytes ((unsigned) long and + * pointers). Zero and sign extension for e.g. int parameters will be done by + * the regular system call wrappers. + */ +#define COMPAT_SYSCALL_WRAPx(x, name, ...) \ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ + asmlinkage long compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ + { \ + return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ + } + +COMPAT_SYSCALL_WRAP1(exit, int, error_code); +COMPAT_SYSCALL_WRAP1(close, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); +COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); +COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename); +COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev); +COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode); +COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name); +COMPAT_SYSCALL_WRAP1(alarm, unsigned int, seconds); +COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode); +COMPAT_SYSCALL_WRAP1(nice, int, increment); +COMPAT_SYSCALL_WRAP2(kill, int, pid, int, sig); +COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname); +COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname); +COMPAT_SYSCALL_WRAP1(dup, unsigned int, fildes); +COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes); +COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); +COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); +COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); +COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); +COMPAT_SYSCALL_WRAP2(setpgid, pid_t, pid, pid_t, pgid); +COMPAT_SYSCALL_WRAP1(umask, int, mask); +COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename); +COMPAT_SYSCALL_WRAP2(dup2, unsigned int, oldfd, unsigned int, newfd); +COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask); +COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len); +COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new); +COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); +COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); +COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); +COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg); +COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len); +COMPAT_SYSCALL_WRAP2(fchmod, unsigned int, fd, umode_t, mode); +COMPAT_SYSCALL_WRAP2(getpriority, int, which, int, who); +COMPAT_SYSCALL_WRAP3(setpriority, int, which, int, who, int, niceval); +COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len); +COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); +COMPAT_SYSCALL_WRAP1(fsync, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); +COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); +COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot); +COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs); +COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr); +COMPAT_SYSCALL_WRAP1(getpgid, pid_t, pid); +COMPAT_SYSCALL_WRAP1(fchdir, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data); +COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2); +COMPAT_SYSCALL_WRAP1(s390_personality, unsigned int, personality); +COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence); +COMPAT_SYSCALL_WRAP2(flock, unsigned int, fd, unsigned int, cmd); +COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags); +COMPAT_SYSCALL_WRAP1(getsid, pid_t, pid); +COMPAT_SYSCALL_WRAP1(fdatasync, unsigned int, fd); +COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len); +COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len); +COMPAT_SYSCALL_WRAP1(mlockall, int, flags); +COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param); +COMPAT_SYSCALL_WRAP1(sched_getscheduler, pid_t, pid); +COMPAT_SYSCALL_WRAP1(sched_get_priority_max, int, policy); +COMPAT_SYSCALL_WRAP1(sched_get_priority_min, int, policy); +COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr); +COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout); +COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5); +COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size); +COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); +COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); +COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP2(setreuid, uid_t, ruid, uid_t, euid); +COMPAT_SYSCALL_WRAP2(setregid, gid_t, rgid, gid_t, egid); +COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist); +COMPAT_SYSCALL_WRAP3(fchown, unsigned int, fd, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid); +COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid); +COMPAT_SYSCALL_WRAP3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid); +COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid); +COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group); +COMPAT_SYSCALL_WRAP1(setuid, uid_t, uid); +COMPAT_SYSCALL_WRAP1(setgid, gid_t, gid); +COMPAT_SYSCALL_WRAP1(setfsuid, uid_t, uid); +COMPAT_SYSCALL_WRAP1(setfsgid, gid_t, gid); +COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old); +COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec); +COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior); +COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); +COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags); +COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count); +COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size); +COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size); +COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size); +COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size); +COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); +COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); +COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); +COMPAT_SYSCALL_WRAP1(exit_group, int, error_code); +COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr); +COMPAT_SYSCALL_WRAP1(epoll_create, int, size); +COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event); +COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout); +COMPAT_SYSCALL_WRAP1(timer_getoverrun, timer_t, timer_id); +COMPAT_SYSCALL_WRAP1(timer_delete, compat_timer_t, compat_timer_id); +COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx); +COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); +COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); +COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id); +COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id); +COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags); +COMPAT_SYSCALL_WRAP3(ioprio_set, int, which, int, who, int, ioprio); +COMPAT_SYSCALL_WRAP2(ioprio_get, int, which, int, who); +COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask); +COMPAT_SYSCALL_WRAP2(inotify_rm_watch, int, fd, __s32, wd); +COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); +COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); +COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag); +COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag); +COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname); +COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags); +COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname); +COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz); +COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode); +COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode); +COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags); +COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags); +COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache); +COMPAT_SYSCALL_WRAP1(eventfd, unsigned int, count); +COMPAT_SYSCALL_WRAP2(timerfd_create, int, clockid, int, flags); +COMPAT_SYSCALL_WRAP2(eventfd2, unsigned int, count, int, flags); +COMPAT_SYSCALL_WRAP1(inotify_init1, int, flags); +COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags); +COMPAT_SYSCALL_WRAP3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags); +COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); +COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); +COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); +COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); +COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); +COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); +COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); +COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); +COMPAT_SYSCALL_WRAP1(syncfs, int, fd); +COMPAT_SYSCALL_WRAP2(setns, int, fd, int, nstype); +COMPAT_SYSCALL_WRAP2(s390_runtime_instr, int, command, int, signum); +COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2); +COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); +COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); +COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index e9167889ff1a..6ac78192455f 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -67,11 +67,6 @@ struct s390_mmap_arg_struct; struct fadvise64_64_args; struct old_sigaction; -long sys_sigreturn(void); -long sys_rt_sigreturn(void); -long sys32_sigreturn(void); -long sys32_rt_sigreturn(void); - long sys_s390_personality(unsigned int personality); long sys_s390_runtime_instr(int command, int signum); diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index dbdec47e935a..542ef488bac1 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -19,9 +19,9 @@ SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall) SYSCALL(sys_creat,sys_creat,compat_sys_creat) SYSCALL(sys_link,sys_link,compat_sys_link) SYSCALL(sys_unlink,sys_unlink,compat_sys_unlink) /* 10 */ -SYSCALL(sys_execve,sys_execve,sys32_execve_wrapper) +SYSCALL(sys_execve,sys_execve,compat_sys_execve) SYSCALL(sys_chdir,sys_chdir,compat_sys_chdir) -SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ +SYSCALL(sys_time,sys_ni_syscall,compat_sys_time) /* old time syscall */ SYSCALL(sys_mknod,sys_mknod,compat_sys_mknod) SYSCALL(sys_chmod,sys_chmod,compat_sys_chmod) /* 15 */ SYSCALL(sys_lchown16,sys_ni_syscall,compat_sys_s390_lchown16) /* old lchown16 syscall*/ @@ -29,16 +29,16 @@ NI_SYSCALL /* old break syscall holder */ NI_SYSCALL /* old stat syscall holder */ SYSCALL(sys_lseek,sys_lseek,compat_sys_lseek) SYSCALL(sys_getpid,sys_getpid,sys_getpid) /* 20 */ -SYSCALL(sys_mount,sys_mount,sys32_mount_wrapper) +SYSCALL(sys_mount,sys_mount,compat_sys_mount) SYSCALL(sys_oldumount,sys_oldumount,compat_sys_oldumount) SYSCALL(sys_setuid16,sys_ni_syscall,compat_sys_s390_setuid16) /* old setuid16 syscall*/ SYSCALL(sys_getuid16,sys_ni_syscall,compat_sys_s390_getuid16) /* old getuid16 syscall*/ -SYSCALL(sys_stime,sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */ -SYSCALL(sys_ptrace,sys_ptrace,sys32_ptrace_wrapper) +SYSCALL(sys_stime,sys_ni_syscall,compat_sys_stime) /* 25 old stime syscall */ +SYSCALL(sys_ptrace,sys_ptrace,compat_sys_ptrace) SYSCALL(sys_alarm,sys_alarm,compat_sys_alarm) NI_SYSCALL /* old fstat syscall */ SYSCALL(sys_pause,sys_pause,sys_pause) -SYSCALL(sys_utime,sys_utime,compat_sys_utime_wrapper) /* 30 */ +SYSCALL(sys_utime,sys_utime,compat_sys_utime) /* 30 */ NI_SYSCALL /* old stty syscall */ NI_SYSCALL /* old gtty syscall */ SYSCALL(sys_access,sys_access,compat_sys_access) @@ -51,7 +51,7 @@ SYSCALL(sys_mkdir,sys_mkdir,compat_sys_mkdir) SYSCALL(sys_rmdir,sys_rmdir,compat_sys_rmdir) /* 40 */ SYSCALL(sys_dup,sys_dup,compat_sys_dup) SYSCALL(sys_pipe,sys_pipe,compat_sys_pipe) -SYSCALL(sys_times,sys_times,compat_sys_times_wrapper) +SYSCALL(sys_times,sys_times,compat_sys_times) NI_SYSCALL /* old prof syscall */ SYSCALL(sys_brk,sys_brk,compat_sys_brk) /* 45 */ SYSCALL(sys_setgid16,sys_ni_syscall,compat_sys_s390_setgid16) /* old setgid16 syscall*/ @@ -62,15 +62,15 @@ SYSCALL(sys_getegid16,sys_ni_syscall,compat_sys_s390_getegid16) /* 50 old getegi SYSCALL(sys_acct,sys_acct,compat_sys_acct) SYSCALL(sys_umount,sys_umount,compat_sys_umount) NI_SYSCALL /* old lock syscall */ -SYSCALL(sys_ioctl,sys_ioctl,compat_sys_ioctl_wrapper) -SYSCALL(sys_fcntl,sys_fcntl,compat_sys_fcntl_wrapper) /* 55 */ +SYSCALL(sys_ioctl,sys_ioctl,compat_sys_ioctl) +SYSCALL(sys_fcntl,sys_fcntl,compat_sys_fcntl) /* 55 */ NI_SYSCALL /* intel mpx syscall */ SYSCALL(sys_setpgid,sys_setpgid,compat_sys_setpgid) NI_SYSCALL /* old ulimit syscall */ NI_SYSCALL /* old uname syscall */ SYSCALL(sys_umask,sys_umask,compat_sys_umask) /* 60 */ SYSCALL(sys_chroot,sys_chroot,compat_sys_chroot) -SYSCALL(sys_ustat,sys_ustat,sys32_ustat_wrapper) +SYSCALL(sys_ustat,sys_ustat,compat_sys_ustat) SYSCALL(sys_dup2,sys_dup2,compat_sys_dup2) SYSCALL(sys_getppid,sys_getppid,sys_getppid) SYSCALL(sys_getpgrp,sys_getpgrp,sys_getpgrp) /* 65 */ @@ -81,13 +81,13 @@ NI_SYSCALL /* old ssetmask syscall*/ SYSCALL(sys_setreuid16,sys_ni_syscall,compat_sys_s390_setreuid16) /* old setreuid16 syscall */ SYSCALL(sys_setregid16,sys_ni_syscall,compat_sys_s390_setregid16) /* old setregid16 syscall */ SYSCALL(sys_sigsuspend,sys_sigsuspend,compat_sys_sigsuspend) -SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending_wrapper) +SYSCALL(sys_sigpending,sys_sigpending,compat_sys_sigpending) SYSCALL(sys_sethostname,sys_sethostname,compat_sys_sethostname) -SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */ -SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper) +SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit) /* 75 */ +SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit) SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage) -SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper) -SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper) +SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday) +SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday) SYSCALL(sys_getgroups16,sys_ni_syscall,compat_sys_s390_getgroups16) /* 80 old getgroups16 syscall */ SYSCALL(sys_setgroups16,sys_ni_syscall,compat_sys_s390_setgroups16) /* old setgroups16 syscall */ NI_SYSCALL /* old select syscall */ @@ -97,7 +97,7 @@ SYSCALL(sys_readlink,sys_readlink,compat_sys_readlink) /* 85 */ SYSCALL(sys_uselib,sys_uselib,compat_sys_uselib) SYSCALL(sys_swapon,sys_swapon,compat_sys_swapon) SYSCALL(sys_reboot,sys_reboot,compat_sys_reboot) -SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ +SYSCALL(sys_ni_syscall,sys_ni_syscall,compat_sys_old_readdir) /* old readdir syscall */ SYSCALL(sys_old_mmap,sys_old_mmap,compat_sys_s390_old_mmap) /* 90 */ SYSCALL(sys_munmap,sys_munmap,compat_sys_munmap) SYSCALL(sys_truncate,sys_truncate,compat_sys_truncate) @@ -107,16 +107,16 @@ SYSCALL(sys_fchown16,sys_ni_syscall,compat_sys_s390_fchown16) /* 95 old fchown16 SYSCALL(sys_getpriority,sys_getpriority,compat_sys_getpriority) SYSCALL(sys_setpriority,sys_setpriority,compat_sys_setpriority) NI_SYSCALL /* old profil syscall */ -SYSCALL(sys_statfs,sys_statfs,compat_sys_statfs_wrapper) -SYSCALL(sys_fstatfs,sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */ +SYSCALL(sys_statfs,sys_statfs,compat_sys_statfs) +SYSCALL(sys_fstatfs,sys_fstatfs,compat_sys_fstatfs) /* 100 */ NI_SYSCALL /* ioperm for i386 */ -SYSCALL(sys_socketcall,sys_socketcall,compat_sys_socketcall_wrapper) +SYSCALL(sys_socketcall,sys_socketcall,compat_sys_socketcall) SYSCALL(sys_syslog,sys_syslog,compat_sys_syslog) SYSCALL(sys_setitimer,sys_setitimer,compat_sys_setitimer) SYSCALL(sys_getitimer,sys_getitimer,compat_sys_getitimer) /* 105 */ -SYSCALL(sys_newstat,sys_newstat,compat_sys_newstat_wrapper) -SYSCALL(sys_newlstat,sys_newlstat,compat_sys_newlstat_wrapper) -SYSCALL(sys_newfstat,sys_newfstat,compat_sys_newfstat_wrapper) +SYSCALL(sys_newstat,sys_newstat,compat_sys_newstat) +SYSCALL(sys_newlstat,sys_newlstat,compat_sys_newlstat) +SYSCALL(sys_newfstat,sys_newfstat,compat_sys_newfstat) NI_SYSCALL /* old uname syscall */ SYSCALL(sys_lookup_dcookie,sys_lookup_dcookie,compat_sys_lookup_dcookie) /* 110 */ SYSCALL(sys_vhangup,sys_vhangup,sys_vhangup) @@ -124,15 +124,15 @@ NI_SYSCALL /* old "idle" system call */ NI_SYSCALL /* vm86old for i386 */ SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4) SYSCALL(sys_swapoff,sys_swapoff,compat_sys_swapoff) /* 115 */ -SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) +SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo) SYSCALL(sys_s390_ipc,sys_s390_ipc,compat_sys_s390_ipc) SYSCALL(sys_fsync,sys_fsync,compat_sys_fsync) -SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) +SYSCALL(sys_sigreturn,sys_sigreturn,compat_sys_sigreturn) SYSCALL(sys_clone,sys_clone,compat_sys_clone) /* 120 */ SYSCALL(sys_setdomainname,sys_setdomainname,compat_sys_setdomainname) SYSCALL(sys_newuname,sys_newuname,compat_sys_newuname) NI_SYSCALL /* modify_ldt for i386 */ -SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper) +SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex) SYSCALL(sys_mprotect,sys_mprotect,compat_sys_mprotect) /* 125 */ SYSCALL(sys_sigprocmask,sys_sigprocmask,compat_sys_sigprocmask) NI_SYSCALL /* old "create module" */ @@ -149,12 +149,12 @@ NI_SYSCALL /* for afs_syscall */ SYSCALL(sys_setfsuid16,sys_ni_syscall,compat_sys_s390_setfsuid16) /* old setfsuid16 syscall */ SYSCALL(sys_setfsgid16,sys_ni_syscall,compat_sys_s390_setfsgid16) /* old setfsgid16 syscall */ SYSCALL(sys_llseek,sys_llseek,compat_sys_llseek) /* 140 */ -SYSCALL(sys_getdents,sys_getdents,sys32_getdents_wrapper) -SYSCALL(sys_select,sys_select,compat_sys_select_wrapper) +SYSCALL(sys_getdents,sys_getdents,compat_sys_getdents) +SYSCALL(sys_select,sys_select,compat_sys_select) SYSCALL(sys_flock,sys_flock,compat_sys_flock) SYSCALL(sys_msync,sys_msync,compat_sys_msync) -SYSCALL(sys_readv,sys_readv,compat_sys_readv_wrapper) /* 145 */ -SYSCALL(sys_writev,sys_writev,compat_sys_writev_wrapper) +SYSCALL(sys_readv,sys_readv,compat_sys_readv) /* 145 */ +SYSCALL(sys_writev,sys_writev,compat_sys_writev) SYSCALL(sys_getsid,sys_getsid,compat_sys_getsid) SYSCALL(sys_fdatasync,sys_fdatasync,compat_sys_fdatasync) SYSCALL(sys_sysctl,sys_sysctl,compat_sys_sysctl) @@ -170,7 +170,7 @@ SYSCALL(sys_sched_yield,sys_sched_yield,sys_sched_yield) SYSCALL(sys_sched_get_priority_max,sys_sched_get_priority_max,compat_sys_sched_get_priority_max) SYSCALL(sys_sched_get_priority_min,sys_sched_get_priority_min,compat_sys_sched_get_priority_min) /* 160 */ SYSCALL(sys_sched_rr_get_interval,sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval) -SYSCALL(sys_nanosleep,sys_nanosleep,compat_sys_nanosleep_wrapper) +SYSCALL(sys_nanosleep,sys_nanosleep,compat_sys_nanosleep) SYSCALL(sys_mremap,sys_mremap,compat_sys_mremap) SYSCALL(sys_setresuid16,sys_ni_syscall,compat_sys_s390_setresuid16) /* old setresuid16 syscall */ SYSCALL(sys_getresuid16,sys_ni_syscall,compat_sys_s390_getresuid16) /* 165 old getresuid16 syscall */ @@ -181,7 +181,7 @@ NI_SYSCALL /* old nfsservctl */ SYSCALL(sys_setresgid16,sys_ni_syscall,compat_sys_s390_setresgid16) /* 170 old setresgid16 syscall */ SYSCALL(sys_getresgid16,sys_ni_syscall,compat_sys_s390_getresgid16) /* old getresgid16 syscall */ SYSCALL(sys_prctl,sys_prctl,compat_sys_prctl) -SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,sys32_rt_sigreturn) +SYSCALL(sys_rt_sigreturn,sys_rt_sigreturn,compat_sys_rt_sigreturn) SYSCALL(sys_rt_sigaction,sys_rt_sigaction,compat_sys_rt_sigaction) SYSCALL(sys_rt_sigprocmask,sys_rt_sigprocmask,compat_sys_rt_sigprocmask) /* 175 */ SYSCALL(sys_rt_sigpending,sys_rt_sigpending,compat_sys_rt_sigpending) @@ -199,7 +199,7 @@ SYSCALL(sys_sendfile,sys_sendfile64,compat_sys_sendfile) NI_SYSCALL /* streams1 */ NI_SYSCALL /* streams2 */ SYSCALL(sys_vfork,sys_vfork,sys_vfork) /* 190 */ -SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit_wrapper) +SYSCALL(sys_getrlimit,sys_getrlimit,compat_sys_getrlimit) SYSCALL(sys_mmap2,sys_mmap2,compat_sys_s390_mmap2) SYSCALL(sys_truncate64,sys_ni_syscall,compat_sys_s390_truncate64) SYSCALL(sys_ftruncate64,sys_ni_syscall,compat_sys_s390_ftruncate64) @@ -229,7 +229,7 @@ SYSCALL(sys_pivot_root,sys_pivot_root,compat_sys_pivot_root) SYSCALL(sys_mincore,sys_mincore,compat_sys_mincore) SYSCALL(sys_madvise,sys_madvise,compat_sys_madvise) SYSCALL(sys_getdents64,sys_getdents64,compat_sys_getdents64) /* 220 */ -SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64_wrapper) +SYSCALL(sys_fcntl64,sys_ni_syscall,compat_sys_fcntl64) SYSCALL(sys_readahead,sys_readahead,compat_sys_s390_readahead) SYSCALL(sys_sendfile64,sys_ni_syscall,compat_sys_sendfile64) SYSCALL(sys_setxattr,sys_setxattr,compat_sys_setxattr) @@ -247,14 +247,14 @@ SYSCALL(sys_fremovexattr,sys_fremovexattr,compat_sys_fremovexattr) /* 235 */ SYSCALL(sys_gettid,sys_gettid,sys_gettid) SYSCALL(sys_tkill,sys_tkill,compat_sys_tkill) SYSCALL(sys_futex,sys_futex,compat_sys_futex) -SYSCALL(sys_sched_setaffinity,sys_sched_setaffinity,sys32_sched_setaffinity_wrapper) -SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrapper) /* 240 */ +SYSCALL(sys_sched_setaffinity,sys_sched_setaffinity,compat_sys_sched_setaffinity) +SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,compat_sys_sched_getaffinity) /* 240 */ SYSCALL(sys_tgkill,sys_tgkill,compat_sys_tgkill) NI_SYSCALL /* reserved for TUX */ -SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper) +SYSCALL(sys_io_setup,sys_io_setup,compat_sys_io_setup) SYSCALL(sys_io_destroy,sys_io_destroy,compat_sys_io_destroy) -SYSCALL(sys_io_getevents,sys_io_getevents,sys32_io_getevents_wrapper) /* 245 */ -SYSCALL(sys_io_submit,sys_io_submit,sys32_io_submit_wrapper) +SYSCALL(sys_io_getevents,sys_io_getevents,compat_sys_io_getevents) /* 245 */ +SYSCALL(sys_io_submit,sys_io_submit,compat_sys_io_submit) SYSCALL(sys_io_cancel,sys_io_cancel,compat_sys_io_cancel) SYSCALL(sys_exit_group,sys_exit_group,compat_sys_exit_group) SYSCALL(sys_epoll_create,sys_epoll_create,compat_sys_epoll_create) @@ -262,33 +262,33 @@ SYSCALL(sys_epoll_ctl,sys_epoll_ctl,compat_sys_epoll_ctl) /* 250 */ SYSCALL(sys_epoll_wait,sys_epoll_wait,compat_sys_epoll_wait) SYSCALL(sys_set_tid_address,sys_set_tid_address,compat_sys_set_tid_address) SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,compat_sys_s390_fadvise64) -SYSCALL(sys_timer_create,sys_timer_create,sys32_timer_create_wrapper) -SYSCALL(sys_timer_settime,sys_timer_settime,sys32_timer_settime_wrapper) /* 255 */ -SYSCALL(sys_timer_gettime,sys_timer_gettime,sys32_timer_gettime_wrapper) +SYSCALL(sys_timer_create,sys_timer_create,compat_sys_timer_create) +SYSCALL(sys_timer_settime,sys_timer_settime,compat_sys_timer_settime) /* 255 */ +SYSCALL(sys_timer_gettime,sys_timer_gettime,compat_sys_timer_gettime) SYSCALL(sys_timer_getoverrun,sys_timer_getoverrun,compat_sys_timer_getoverrun) SYSCALL(sys_timer_delete,sys_timer_delete,compat_sys_timer_delete) -SYSCALL(sys_clock_settime,sys_clock_settime,sys32_clock_settime_wrapper) -SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */ -SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) -SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) +SYSCALL(sys_clock_settime,sys_clock_settime,compat_sys_clock_settime) +SYSCALL(sys_clock_gettime,sys_clock_gettime,compat_sys_clock_gettime) /* 260 */ +SYSCALL(sys_clock_getres,sys_clock_getres,compat_sys_clock_getres) +SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,compat_sys_clock_nanosleep) NI_SYSCALL /* reserved for vserver */ SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,compat_sys_s390_fadvise64_64) -SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) -SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) +SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64) +SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64) SYSCALL(sys_remap_file_pages,sys_remap_file_pages,compat_sys_remap_file_pages) NI_SYSCALL /* 268 sys_mbind */ NI_SYSCALL /* 269 sys_get_mempolicy */ NI_SYSCALL /* 270 sys_set_mempolicy */ -SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open_wrapper) +SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open) SYSCALL(sys_mq_unlink,sys_mq_unlink,compat_sys_mq_unlink) -SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) -SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) -SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ -SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) -SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper) +SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend) +SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive) +SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify) /* 275 */ +SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr) +SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load) SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key) SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key) -SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl_wrapper) /* 280 */ +SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid) SYSCALL(sys_ioprio_set,sys_ioprio_set,compat_sys_ioprio_set) SYSCALL(sys_ioprio_get,sys_ioprio_get,compat_sys_ioprio_get) @@ -300,7 +300,7 @@ SYSCALL(sys_openat,sys_openat,compat_sys_openat) SYSCALL(sys_mkdirat,sys_mkdirat,compat_sys_mkdirat) SYSCALL(sys_mknodat,sys_mknodat,compat_sys_mknodat) /* 290 */ SYSCALL(sys_fchownat,sys_fchownat,compat_sys_fchownat) -SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper) +SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat) SYSCALL(sys_fstatat64,sys_newfstatat,compat_sys_s390_fstatat64) SYSCALL(sys_unlinkat,sys_unlinkat,compat_sys_unlinkat) SYSCALL(sys_renameat,sys_renameat,compat_sys_renameat) /* 295 */ @@ -309,8 +309,8 @@ SYSCALL(sys_symlinkat,sys_symlinkat,compat_sys_symlinkat) SYSCALL(sys_readlinkat,sys_readlinkat,compat_sys_readlinkat) SYSCALL(sys_fchmodat,sys_fchmodat,compat_sys_fchmodat) SYSCALL(sys_faccessat,sys_faccessat,compat_sys_faccessat) /* 300 */ -SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper) -SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper) +SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6) +SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll) SYSCALL(sys_unshare,sys_unshare,compat_sys_unshare) SYSCALL(sys_set_robust_list,sys_set_robust_list,compat_sys_set_robust_list) SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list) @@ -321,9 +321,9 @@ SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,compat_sys_getcpu) SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait) -SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) +SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes) SYSCALL(sys_s390_fallocate,sys_fallocate,compat_sys_s390_fallocate) -SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ +SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat) /* 315 */ SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd) NI_SYSCALL /* 317 old sys_timer_fd */ SYSCALL(sys_eventfd,sys_eventfd,compat_sys_eventfd) @@ -345,11 +345,11 @@ SYSCALL(sys_fanotify_mark,sys_fanotify_mark,compat_sys_fanotify_mark) SYSCALL(sys_prlimit64,sys_prlimit64,compat_sys_prlimit64) SYSCALL(sys_name_to_handle_at,sys_name_to_handle_at,compat_sys_name_to_handle_at) /* 335 */ SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at) -SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper) +SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime) SYSCALL(sys_syncfs,sys_syncfs,compat_sys_syncfs) SYSCALL(sys_setns,sys_setns,compat_sys_setns) -SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv_wrapper) /* 340 */ -SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev_wrapper) +SYSCALL(sys_process_vm_readv,sys_process_vm_readv,compat_sys_process_vm_readv) /* 340 */ +SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev) SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,compat_sys_s390_runtime_instr) SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp) SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module) -- cgit v1.2.3-55-g7522 From d4078e232267ff53f3b030b9698a3c001db4dbec Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 5 Mar 2014 14:07:49 +0100 Subject: x86, trace: Further robustify CR2 handling vs tracing Building on commit 0ac09f9f8cd1 ("x86, trace: Fix CR2 corruption when tracing page faults") this patch addresses another few issues: - Now that read_cr2() is lifted into trace_do_page_fault(), we should pass the address to trace_page_fault_entries() to avoid it re-reading a potentially changed cr2. - Put both trace_do_page_fault() and trace_page_fault_entries() under CONFIG_TRACING. - Mark both fault entry functions {,trace_}do_page_fault() as notrace to avoid getting __mcount or other function entry trace callbacks before we've observed CR2. - Mark __do_page_fault() as noinline to guarantee the function tracer does get to see the fault. Cc: Cc: Acked-by: Steven Rostedt Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140306145300.GO9987@twins.programming.kicks-ass.net Signed-off-by: H. Peter Anvin --- arch/x86/mm/fault.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e7fa28bf3262..a10c8c792161 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1020,8 +1020,12 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs) * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. + * + * This function must have noinline because both callers + * {,trace_}do_page_fault() have notrace on. Having this an actual function + * guarantees there's a function trace entry. */ -static void __kprobes +static void __kprobes noinline __do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address) { @@ -1245,31 +1249,38 @@ good_area: up_read(&mm->mmap_sem); } -dotraplinkage void __kprobes +dotraplinkage void __kprobes notrace do_page_fault(struct pt_regs *regs, unsigned long error_code) { + unsigned long address = read_cr2(); /* Get the faulting address */ enum ctx_state prev_state; - /* Get the faulting address: */ - unsigned long address = read_cr2(); + + /* + * We must have this function tagged with __kprobes, notrace and call + * read_cr2() before calling anything else. To avoid calling any kind + * of tracing machinery before we've observed the CR2 value. + * + * exception_{enter,exit}() contain all sorts of tracepoints. + */ prev_state = exception_enter(); __do_page_fault(regs, error_code, address); exception_exit(prev_state); } -static void trace_page_fault_entries(struct pt_regs *regs, +#ifdef CONFIG_TRACING +static void trace_page_fault_entries(unsigned long address, struct pt_regs *regs, unsigned long error_code) { if (user_mode(regs)) - trace_page_fault_user(read_cr2(), regs, error_code); + trace_page_fault_user(address, regs, error_code); else - trace_page_fault_kernel(read_cr2(), regs, error_code); + trace_page_fault_kernel(address, regs, error_code); } -dotraplinkage void __kprobes +dotraplinkage void __kprobes notrace trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) { - enum ctx_state prev_state; /* * The exception_enter and tracepoint processing could * trigger another page faults (user space callchain @@ -1277,9 +1288,11 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) * the faulting address now. */ unsigned long address = read_cr2(); + enum ctx_state prev_state; prev_state = exception_enter(); - trace_page_fault_entries(regs, error_code); + trace_page_fault_entries(address, regs, error_code); __do_page_fault(regs, error_code, address); exception_exit(prev_state); } +#endif /* CONFIG_TRACING */ -- cgit v1.2.3-55-g7522 From f5179287b016cc61d6ad77b4a15fab9b6932df83 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 10 Feb 2014 18:00:17 +0100 Subject: MIPS: Fix randconfig build error. CC arch/mips/kernel/ptrace.o In file included from arch/mips/kernel/ptrace.c:42:0: arch/mips/kernel/ptrace.c: In function ‘mips_get_syscall_arg’: /home/ralf/src/linux/linux-mips/arch/mips/include/asm/syscall.h:60:1: error: control reaches end of non-void function [-Werror=return-type] cc1: all warnings being treated as errors make[2]: *** [arch/mips/kernel/ptrace.o] Error 1 make[1]: *** [arch/mips/kernel] Error 2 make: *** [arch/mips] Error 2 Fixed by marking the end of mips_get_syscall_arg() as unreachable. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 33e8dbfc1b63..5ce530fcb11f 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -13,6 +13,7 @@ #ifndef __ASM_MIPS_SYSCALL_H #define __ASM_MIPS_SYSCALL_H +#include #include #include #include @@ -57,6 +58,8 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg, default: BUG(); } + + unreachable(); } static inline long syscall_get_return_value(struct task_struct *task, -- cgit v1.2.3-55-g7522 From d334c2b9de03c62767d04d8d927bc6d06f3fbd62 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 20 Feb 2014 14:37:40 +0100 Subject: MIPS: Alchemy: Fix unchecked kstrtoul return value enabled __must_check logic triggers a build error for mtx1 and gpr in the prom init code. Fix by checking the kstrtoul() return value. Signed-off-by: Manuel Lauss Cc: Linux-MIPS Patchwork: https://patchwork.linux-mips.org/patch/6574/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/board-gpr.c | 4 +--- arch/mips/alchemy/board-mtx1.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c index 9edc35ff8cf1..acf9a2a37f5a 100644 --- a/arch/mips/alchemy/board-gpr.c +++ b/arch/mips/alchemy/board-gpr.c @@ -53,10 +53,8 @@ void __init prom_init(void) prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) + if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) memsize = 0x04000000; - else - strict_strtoul(memsize_str, 0, &memsize); add_memory_region(0, memsize, BOOT_MEM_RAM); } diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 9969dbab19e3..25a59a23547e 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -52,10 +52,8 @@ void __init prom_init(void) prom_init_cmdline(); memsize_str = prom_getenv("memsize"); - if (!memsize_str) + if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) memsize = 0x04000000; - else - strict_strtoul(memsize_str, 0, &memsize); add_memory_region(0, memsize, BOOT_MEM_RAM); } -- cgit v1.2.3-55-g7522 From 4890e2eb69d0461cbc532265e03280ffce670ee8 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 19 Feb 2014 10:17:18 +0000 Subject: MIPS: bcm47xx: Include missing errno.h for ENXIO Fixes the following build problen on allmodconfig: arch/mips/bcm47xx/board.c: In function 'bcm47xx_board_detect': arch/mips/bcm47xx/board.c:291:14: error: 'ENXIO' undeclared (first use in this function) Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6571/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/board.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index 6d612e2b949b..cdd8246f92b3 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -1,3 +1,4 @@ +#include #include #include #include -- cgit v1.2.3-55-g7522 From 9c1f6e008297e184a7f701f2f03c9269011fd049 Mon Sep 17 00:00:00 2001 From: Deng-Cheng Zhu Date: Fri, 28 Feb 2014 10:23:01 -0800 Subject: MIPS: APRP: Fix the linking of rtlx interrupt hook There are 2 errors with the existing aprp_hook linking: - The prefix CONFIG_ is missing; - The hook should be linked exclusively in the cases of MT and CMP. Signed-off-by: Deng-Cheng Zhu Reviewed-by: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: john@phrozen.org Patchwork: https://patchwork.linux-mips.org/patch/6588/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-int.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index ca3e3a46a42f..2242181a6284 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -119,7 +119,7 @@ static void malta_hw0_irqdispatch(void) do_IRQ(MALTA_INT_BASE + irq); -#ifdef MIPS_VPE_APSP_API +#ifdef CONFIG_MIPS_VPE_APSP_API_MT if (aprp_hook) aprp_hook(); #endif @@ -310,7 +310,7 @@ static void ipi_call_dispatch(void) static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) { -#ifdef MIPS_VPE_APSP_API +#ifdef CONFIG_MIPS_VPE_APSP_API_CMP if (aprp_hook) aprp_hook(); #endif -- cgit v1.2.3-55-g7522 From eee5794881d50e8ac3a56c74d3131f2364f200b9 Mon Sep 17 00:00:00 2001 From: Deng-Cheng Zhu Date: Fri, 28 Feb 2014 10:23:02 -0800 Subject: MIPS: APRP: Unregister rtlx interrupt hook at module exit If the aprp_hook is not assigned back to NULL, it will still be called after module exits. This is not wanted. Reviewed-by: Steven J. Hill Signed-off-by: Deng-Cheng Zhu Cc: linux-mips@linux-mips.org Cc: john@phrozen.org Patchwork: https://patchwork.linux-mips.org/patch/6590/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/rtlx-cmp.c | 3 +++ arch/mips/kernel/rtlx-mt.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/mips/kernel/rtlx-cmp.c b/arch/mips/kernel/rtlx-cmp.c index 56dc69635153..758fb3cd2326 100644 --- a/arch/mips/kernel/rtlx-cmp.c +++ b/arch/mips/kernel/rtlx-cmp.c @@ -112,5 +112,8 @@ void __exit rtlx_module_exit(void) for (i = 0; i < RTLX_CHANNELS; i++) device_destroy(mt_class, MKDEV(major, i)); + unregister_chrdev(major, RTLX_MODULE_NAME); + + aprp_hook = NULL; } diff --git a/arch/mips/kernel/rtlx-mt.c b/arch/mips/kernel/rtlx-mt.c index 91d61ba422b4..9c1aca00fd54 100644 --- a/arch/mips/kernel/rtlx-mt.c +++ b/arch/mips/kernel/rtlx-mt.c @@ -144,5 +144,8 @@ void __exit rtlx_module_exit(void) for (i = 0; i < RTLX_CHANNELS; i++) device_destroy(mt_class, MKDEV(major, i)); + unregister_chrdev(major, RTLX_MODULE_NAME); + + aprp_hook = NULL; } -- cgit v1.2.3-55-g7522 From 031365b471e3268e3b8d6991b2cf0bae6b5e8bdc Mon Sep 17 00:00:00 2001 From: Deng-Cheng Zhu Date: Fri, 28 Feb 2014 10:23:03 -0800 Subject: MIPS: APRP: Choose the correct VPE loader by fixing the linking Now we have CONFIG_MIPS_VPE_LOADER and CONFIG_MIPS_VPE_LOADER_[CMP|MT]. The latter two are used by the 2 exclusive flavors. The vpe_run in malta-amon.c is for CMP APRP. Without the fix, this vpe_run will be used in MT APRP. Reviewed-by: Steven J. Hill Signed-off-by: Deng-Cheng Zhu Cc: linux-mips@linux-mips.org Cc: john@phrozen.org Patchwork: https://patchwork.linux-mips.org/patch/6589/ Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-amon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mti-malta/malta-amon.c b/arch/mips/mti-malta/malta-amon.c index 592ac0427426..84ac523b0ce0 100644 --- a/arch/mips/mti-malta/malta-amon.c +++ b/arch/mips/mti-malta/malta-amon.c @@ -72,7 +72,7 @@ int amon_cpu_start(int cpu, return 0; } -#ifdef CONFIG_MIPS_VPE_LOADER +#ifdef CONFIG_MIPS_VPE_LOADER_CMP int vpe_run(struct vpe *v) { struct vpe_notifications *n; -- cgit v1.2.3-55-g7522 From 2432e1364bbee83cb6e63e026c91785031704ba5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 6 Feb 2014 09:41:28 -0500 Subject: x86: Nuke the supervisor_stack field in i386 thread_info Nothing references the supervisor_stack in the thread_info field, and it does not exist in x86_64. To make the two more the same, it is being removed. Acked-by: Thomas Gleixner Cc: Andrew Morton Cc: Peter Zijlstra Cc: Brian Gerst Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20110806012353.546183789@goodmis.org Link: http://lkml.kernel.org/r/20140206144321.203619611@goodmis.org Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/thread_info.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e1940c06ed02..b7aa975561e2 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -36,7 +36,6 @@ struct thread_info { unsigned long previous_esp; /* ESP of the previous stack in case of nested (IRQ) stacks */ - __u8 supervisor_stack[0]; #endif unsigned int sig_on_uaccess_error:1; unsigned int uaccess_err:1; /* uaccess failed */ -- cgit v1.2.3-55-g7522 From b807902a88c470eb06d0acdf3b6590f27f5dce81 Mon Sep 17 00:00:00 2001 From: Steven Rostedt (Red Hat) Date: Thu, 6 Feb 2014 09:41:29 -0500 Subject: x86: Nuke GET_THREAD_INFO_WITH_ESP() macro for i386 According to a git log -p, GET_THREAD_INFO_WITH_ESP() has only been defined and never been used. Get rid of it. Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20140206144321.409045251@goodmis.org Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/thread_info.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index b7aa975561e2..1cb3501636d2 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -182,10 +182,6 @@ static inline struct thread_info *current_thread_info(void) movl $-THREAD_SIZE, reg; \ andl %esp, reg -/* use this one if reg already contains %esp */ -#define GET_THREAD_INFO_WITH_ESP(reg) \ - andl $-THREAD_SIZE, reg - #endif #else /* X86_32 */ -- cgit v1.2.3-55-g7522 From 0788aa6a23cb9d693fc5040ec774b979f1e906cd Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 6 Feb 2014 09:41:30 -0500 Subject: x86: Prepare removal of previous_esp from i386 thread_info structure The i386 thread_info contains a previous_esp field that is used to daisy chain the different stacks for dump_stack() (ie. irq, softirq, thread stacks). The goal is to eventual make i386 handling of thread_info the same as x86_64, which means that the thread_info will not be in the stack but as a per_cpu variable. We will no longer depend on thread_info being able to daisy chain different stacks as it will only exist in one location (the thread stack). By moving previous_esp to the end of thread_info and referencing it as an offset instead of using a thread_info field, this becomes a stepping stone to moving the thread_info. The offset to get to the previous stack is rather ugly in this patch, but this is only temporary and the prev_esp will be changed in the next commit. This commit is more for sanity checks of the change. Cc: Andrew Morton Cc: Peter Zijlstra Cc: Brian Gerst Cc: Robert Richter Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20110806012353.891757693@goodmis.org Link: http://lkml.kernel.org/r/20140206144321.608754481@goodmis.org Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/thread_info.h | 5 +++-- arch/x86/kernel/dumpstack_32.c | 11 ++++++++++- arch/x86/kernel/irq_32.c | 15 +++++++++++---- arch/x86/kernel/ptrace.c | 8 ++++---- 4 files changed, 28 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 1cb3501636d2..ca2de1b48fac 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -32,13 +32,14 @@ struct thread_info { mm_segment_t addr_limit; struct restart_block restart_block; void __user *sysenter_return; + unsigned int sig_on_uaccess_error:1; + unsigned int uaccess_err:1; /* uaccess failed */ #ifdef CONFIG_X86_32 unsigned long previous_esp; /* ESP of the previous stack in case of nested (IRQ) stacks + (Moved to end, to be removed soon) */ #endif - unsigned int sig_on_uaccess_error:1; - unsigned int uaccess_err:1; /* uaccess failed */ }; #define INIT_THREAD_INFO(tsk) \ diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index f2a1770ca176..187d6a749c19 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -22,6 +22,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, const struct stacktrace_ops *ops, void *data) { int graph = 0; + u32 *prev_esp; if (!task) task = current; @@ -44,9 +45,17 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, ((unsigned long)stack & (~(THREAD_SIZE - 1))); bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph); - stack = (unsigned long *)context->previous_esp; + /* Stop if not on irq stack */ + if (task_stack_page(task) == context) + break; + + /* The previous esp is just above the context */ + prev_esp = (u32 *) ((char *)context + sizeof(struct thread_info) - + sizeof(long)); + stack = (unsigned long *)*prev_esp; if (!stack) break; + if (ops->stack(data, "IRQ") < 0) break; touch_nmi_watchdog(); diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index d7fcbedc9c43..f135cc2ff301 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -81,7 +81,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { union irq_ctx *curctx, *irqctx; - u32 *isp, arg1, arg2; + u32 *isp, *prev_esp, arg1, arg2; curctx = (union irq_ctx *) current_thread_info(); irqctx = __this_cpu_read(hardirq_ctx); @@ -98,7 +98,10 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) /* build the stack frame on the IRQ stack */ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); irqctx->tinfo.task = curctx->tinfo.task; - irqctx->tinfo.previous_esp = current_stack_pointer; + /* Save the next esp after thread_info */ + prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - + sizeof(long)); + *prev_esp = current_stack_pointer; if (unlikely(overflow)) call_on_stack(print_stack_overflow, isp); @@ -149,16 +152,20 @@ void do_softirq_own_stack(void) { struct thread_info *curctx; union irq_ctx *irqctx; - u32 *isp; + u32 *isp, *prev_esp; curctx = current_thread_info(); irqctx = __this_cpu_read(softirq_ctx); irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_esp = current_stack_pointer; /* build the stack frame on the softirq stack */ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); + /* Push the previous esp onto the stack */ + prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - + sizeof(long)); + *prev_esp = current_stack_pointer; + call_on_stack(__do_softirq, isp); } diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 7461f50d5bb1..f352a7cc43a1 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -184,14 +184,14 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) { unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); unsigned long sp = (unsigned long)®s->sp; - struct thread_info *tinfo; + u32 *prev_esp; if (context == (sp & ~(THREAD_SIZE - 1))) return sp; - tinfo = (struct thread_info *)context; - if (tinfo->previous_esp) - return tinfo->previous_esp; + prev_esp = (u32 *)(context + sizeof(struct thread_info) - sizeof(long)); + if (prev_esp) + return (unsigned long)prev_esp; return (unsigned long)regs; } -- cgit v1.2.3-55-g7522 From 198d208df4371734ac4728f69cb585c284d20a15 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 6 Feb 2014 09:41:31 -0500 Subject: x86: Keep thread_info on thread stack in x86_32 x86_64 uses a per_cpu variable kernel_stack to always point to the thread stack of current. This is where the thread_info is stored and is accessed from this location even when the irq or exception stack is in use. This removes the complexity of having to maintain the thread info on the stack when interrupts are running and having to copy the preempt_count and other fields to the interrupt stack. x86_32 uses the old method of copying the thread_info from the thread stack to the exception stack just before executing the exception. Having the two different requires #ifdefs and also the x86_32 way is a bit of a pain to maintain. By converting x86_32 to the same method of x86_64, we can remove #ifdefs, clean up the x86_32 code a little, and remove the overhead of the copy. Cc: Andrew Morton Cc: Peter Zijlstra Cc: Brian Gerst Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20110806012354.263834829@goodmis.org Link: http://lkml.kernel.org/r/20140206144321.852942014@goodmis.org Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/processor.h | 9 +++++ arch/x86/include/asm/thread_info.h | 49 +++---------------------- arch/x86/kernel/cpu/common.c | 8 ++--- arch/x86/kernel/dumpstack_32.c | 41 +++++++++++++++++---- arch/x86/kernel/irq_32.c | 74 ++++++++++++++++---------------------- arch/x86/kernel/process_32.c | 4 +++ arch/x86/kernel/ptrace.c | 2 +- arch/x86/kernel/smpboot.c | 2 +- 8 files changed, 89 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index fdedd38fd0fc..a4ea02351f4d 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -449,6 +449,15 @@ struct stack_canary { }; DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); #endif +/* + * per-CPU IRQ handling stacks + */ +struct irq_stack { + u32 stack[THREAD_SIZE/sizeof(u32)]; +} __aligned(THREAD_SIZE); + +DECLARE_PER_CPU(struct irq_stack *, hardirq_stack); +DECLARE_PER_CPU(struct irq_stack *, softirq_stack); #endif /* X86_64 */ extern unsigned int xstate_size; diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index ca2de1b48fac..47e5de25ba79 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -9,6 +9,7 @@ #include #include +#include #include /* @@ -34,12 +35,6 @@ struct thread_info { void __user *sysenter_return; unsigned int sig_on_uaccess_error:1; unsigned int uaccess_err:1; /* uaccess failed */ -#ifdef CONFIG_X86_32 - unsigned long previous_esp; /* ESP of the previous stack in - case of nested (IRQ) stacks - (Moved to end, to be removed soon) - */ -#endif }; #define INIT_THREAD_INFO(tsk) \ @@ -153,9 +148,9 @@ struct thread_info { #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) -#ifdef CONFIG_X86_32 +#define STACK_WARN (THREAD_SIZE/8) +#define KERNEL_STACK_OFFSET (5*(BITS_PER_LONG/8)) -#define STACK_WARN (THREAD_SIZE/8) /* * macros/functions for gaining access to the thread information structure * @@ -163,38 +158,6 @@ struct thread_info { */ #ifndef __ASSEMBLY__ -#define current_stack_pointer ({ \ - unsigned long sp; \ - asm("mov %%esp,%0" : "=g" (sp)); \ - sp; \ -}) - -/* how to get the thread information struct from C */ -static inline struct thread_info *current_thread_info(void) -{ - return (struct thread_info *) - (current_stack_pointer & ~(THREAD_SIZE - 1)); -} - -#else /* !__ASSEMBLY__ */ - -/* how to get the thread information struct from ASM */ -#define GET_THREAD_INFO(reg) \ - movl $-THREAD_SIZE, reg; \ - andl %esp, reg - -#endif - -#else /* X86_32 */ - -#include -#define KERNEL_STACK_OFFSET (5*8) - -/* - * macros/functions for gaining access to the thread information structure - * preempt_count needs to be 1 initially, until the scheduler is functional. - */ -#ifndef __ASSEMBLY__ DECLARE_PER_CPU(unsigned long, kernel_stack); static inline struct thread_info *current_thread_info(void) @@ -209,8 +172,8 @@ static inline struct thread_info *current_thread_info(void) /* how to get the thread information struct from ASM */ #define GET_THREAD_INFO(reg) \ - movq PER_CPU_VAR(kernel_stack),reg ; \ - subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg + _ASM_MOV PER_CPU_VAR(kernel_stack),reg ; \ + _ASM_SUB $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg ; /* * Same if PER_CPU_VAR(kernel_stack) is, perhaps with some offset, already in @@ -220,8 +183,6 @@ static inline struct thread_info *current_thread_info(void) #endif -#endif /* !X86_32 */ - /* * Thread-synchronous status. * diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8e28bf2fc3ef..29c1944a98ac 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1078,6 +1078,10 @@ static __init int setup_disablecpuid(char *arg) } __setup("clearcpuid=", setup_disablecpuid); +DEFINE_PER_CPU(unsigned long, kernel_stack) = + (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; +EXPORT_PER_CPU_SYMBOL(kernel_stack); + #ifdef CONFIG_X86_64 struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1, @@ -1094,10 +1098,6 @@ DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = &init_task; EXPORT_PER_CPU_SYMBOL(current_task); -DEFINE_PER_CPU(unsigned long, kernel_stack) = - (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; -EXPORT_PER_CPU_SYMBOL(kernel_stack); - DEFINE_PER_CPU(char *, irq_stack_ptr) = init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 187d6a749c19..dca820b627d6 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -16,11 +16,33 @@ #include +static void *is_irq_stack(void *p, void *irq) +{ + if (p < irq || p >= (irq + THREAD_SIZE)) + return NULL; + return irq + THREAD_SIZE; +} + + +static void *is_hardirq_stack(unsigned long *stack, int cpu) +{ + void *irq = per_cpu(hardirq_stack, cpu); + + return is_irq_stack(stack, irq); +} + +static void *is_softirq_stack(unsigned long *stack, int cpu) +{ + void *irq = per_cpu(softirq_stack, cpu); + + return is_irq_stack(stack, irq); +} void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data) { + const unsigned cpu = get_cpu(); int graph = 0; u32 *prev_esp; @@ -40,18 +62,22 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, for (;;) { struct thread_info *context; + void *end_stack; + + end_stack = is_hardirq_stack(stack, cpu); + if (!end_stack) + end_stack = is_softirq_stack(stack, cpu); - context = (struct thread_info *) - ((unsigned long)stack & (~(THREAD_SIZE - 1))); - bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph); + context = task_thread_info(task); + bp = ops->walk_stack(context, stack, bp, ops, data, + end_stack, &graph); /* Stop if not on irq stack */ - if (task_stack_page(task) == context) + if (!end_stack) break; - /* The previous esp is just above the context */ - prev_esp = (u32 *) ((char *)context + sizeof(struct thread_info) - - sizeof(long)); + /* The previous esp is saved on the bottom of the stack */ + prev_esp = (u32 *)(end_stack - THREAD_SIZE); stack = (unsigned long *)*prev_esp; if (!stack) break; @@ -60,6 +86,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, break; touch_nmi_watchdog(); } + put_cpu(); } EXPORT_SYMBOL(dump_trace); diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index f135cc2ff301..988dc8bcaebf 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -55,16 +55,8 @@ static inline int check_stack_overflow(void) { return 0; } static inline void print_stack_overflow(void) { } #endif -/* - * per-CPU IRQ handling contexts (thread information and stack) - */ -union irq_ctx { - struct thread_info tinfo; - u32 stack[THREAD_SIZE/sizeof(u32)]; -} __attribute__((aligned(THREAD_SIZE))); - -static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx); -static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx); +DEFINE_PER_CPU(struct irq_stack *, hardirq_stack); +DEFINE_PER_CPU(struct irq_stack *, softirq_stack); static void call_on_stack(void *func, void *stack) { @@ -77,14 +69,22 @@ static void call_on_stack(void *func, void *stack) : "memory", "cc", "edx", "ecx", "eax"); } +/* how to get the current stack pointer from C */ +register unsigned long current_stack_pointer asm("esp") __used; + +static inline void *current_stack(void) +{ + return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); +} + static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { - union irq_ctx *curctx, *irqctx; + struct irq_stack *curstk, *irqstk; u32 *isp, *prev_esp, arg1, arg2; - curctx = (union irq_ctx *) current_thread_info(); - irqctx = __this_cpu_read(hardirq_ctx); + curstk = (struct irq_stack *) current_stack(); + irqstk = __this_cpu_read(hardirq_stack); /* * this is where we switch to the IRQ stack. However, if we are @@ -92,15 +92,13 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) * handler) we can't do that and just have to keep using the * current stack (which is the irq stack already after all) */ - if (unlikely(curctx == irqctx)) + if (unlikely(curstk == irqstk)) return 0; - /* build the stack frame on the IRQ stack */ - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); - irqctx->tinfo.task = curctx->tinfo.task; - /* Save the next esp after thread_info */ - prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - - sizeof(long)); + isp = (u32 *) ((char *)irqstk + sizeof(*irqstk)); + + /* Save the next esp at the bottom of the stack */ + prev_esp = (u32 *)irqstk; *prev_esp = current_stack_pointer; if (unlikely(overflow)) @@ -121,49 +119,39 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) */ void irq_ctx_init(int cpu) { - union irq_ctx *irqctx; + struct irq_stack *irqstk; - if (per_cpu(hardirq_ctx, cpu)) + if (per_cpu(hardirq_stack, cpu)) return; - irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), + irqstk = page_address(alloc_pages_node(cpu_to_node(cpu), THREADINFO_GFP, THREAD_SIZE_ORDER)); - memset(&irqctx->tinfo, 0, sizeof(struct thread_info)); - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); + per_cpu(hardirq_stack, cpu) = irqstk; - per_cpu(hardirq_ctx, cpu) = irqctx; - - irqctx = page_address(alloc_pages_node(cpu_to_node(cpu), + irqstk = page_address(alloc_pages_node(cpu_to_node(cpu), THREADINFO_GFP, THREAD_SIZE_ORDER)); - memset(&irqctx->tinfo, 0, sizeof(struct thread_info)); - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - - per_cpu(softirq_ctx, cpu) = irqctx; + per_cpu(softirq_stack, cpu) = irqstk; printk(KERN_DEBUG "CPU %u irqstacks, hard=%p soft=%p\n", - cpu, per_cpu(hardirq_ctx, cpu), per_cpu(softirq_ctx, cpu)); + cpu, per_cpu(hardirq_stack, cpu), per_cpu(softirq_stack, cpu)); } void do_softirq_own_stack(void) { - struct thread_info *curctx; - union irq_ctx *irqctx; + struct thread_info *curstk; + struct irq_stack *irqstk; u32 *isp, *prev_esp; - curctx = current_thread_info(); - irqctx = __this_cpu_read(softirq_ctx); - irqctx->tinfo.task = curctx->task; + curstk = current_stack(); + irqstk = __this_cpu_read(softirq_stack); /* build the stack frame on the softirq stack */ - isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); + isp = (u32 *) ((char *)irqstk + sizeof(*irqstk)); /* Push the previous esp onto the stack */ - prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - - sizeof(long)); + prev_esp = (u32 *)irqstk; *prev_esp = current_stack_pointer; call_on_stack(__do_softirq, isp); diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 0de43e98ce08..7bc86bbe7485 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -314,6 +314,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ arch_end_context_switch(next_p); + this_cpu_write(kernel_stack, + (unsigned long)task_stack_page(next_p) + + THREAD_SIZE - KERNEL_STACK_OFFSET); + /* * Restore %gs if needed (which is common) */ diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index f352a7cc43a1..678c0ada3b3c 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -189,7 +189,7 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) if (context == (sp & ~(THREAD_SIZE - 1))) return sp; - prev_esp = (u32 *)(context + sizeof(struct thread_info) - sizeof(long)); + prev_esp = (u32 *)(context); if (prev_esp) return (unsigned long)prev_esp; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a32da804252e..867d53ea88a3 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -758,10 +758,10 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) #else clear_tsk_thread_flag(idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); +#endif per_cpu(kernel_stack, cpu) = (unsigned long)task_stack_page(idle) - KERNEL_STACK_OFFSET + THREAD_SIZE; -#endif early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); initial_code = (unsigned long)start_secondary; stack_start = idle->thread.sp; -- cgit v1.2.3-55-g7522 From 2223f6f6eeaad6ea0a3acd3f4bc1ae45e8117ddc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 6 Feb 2014 09:41:32 -0500 Subject: x86: Clean up dumpstack_64.c code The dump_trace() function in dumpstack_64.c is hard to follow. The test for exception stack is processed differently than the test for irq stack, and the normal stack is outside completely. By restructuring this code to have all the stacks determined by a single function that returns an enum of the following: STACK_IS_NORMAL STACK_IS_EXCEPTION STACK_IS_IRQ STACK_IS_UNKNOWN and has the logic of each within a switch statement. This should make the code much easier to read and understand. Link: http://lkml.kernel.org/r/20110806012354.684598995@goodmis.org Cc: Andrew Morton Cc: Peter Zijlstra Cc: Brian Gerst Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20140206144322.086050042@goodmis.org Signed-off-by: H. Peter Anvin --- arch/x86/kernel/dumpstack_64.c | 117 +++++++++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index addb207dab92..346b1df2412e 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -104,6 +104,45 @@ in_irq_stack(unsigned long *stack, unsigned long *irq_stack, return (stack >= irq_stack && stack < irq_stack_end); } +static const unsigned long irq_stack_size = + (IRQ_STACK_SIZE - 64) / sizeof(unsigned long); + +enum stack_type { + STACK_IS_UNKNOWN, + STACK_IS_NORMAL, + STACK_IS_EXCEPTION, + STACK_IS_IRQ, +}; + +static enum stack_type +analyze_stack(int cpu, struct task_struct *task, + unsigned long *stack, unsigned long **stack_end, char **id) +{ + unsigned long *irq_stack; + unsigned long addr; + unsigned used = 0; + + addr = ((unsigned long)stack & (~(THREAD_SIZE - 1))); + if ((unsigned long)task_stack_page(task) == addr) + return STACK_IS_NORMAL; + + *stack_end = in_exception_stack(cpu, (unsigned long)stack, + &used, id); + if (*stack_end) + return STACK_IS_EXCEPTION; + + *stack_end = (unsigned long *)per_cpu(irq_stack_ptr, cpu); + if (!*stack_end) + return STACK_IS_UNKNOWN; + + irq_stack = *stack_end - irq_stack_size; + + if (in_irq_stack(stack, irq_stack, *stack_end)) + return STACK_IS_IRQ; + + return STACK_IS_UNKNOWN; +} + /* * x86-64 can have up to three kernel stacks: * process stack @@ -116,12 +155,11 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, const struct stacktrace_ops *ops, void *data) { const unsigned cpu = get_cpu(); - unsigned long *irq_stack_end = - (unsigned long *)per_cpu(irq_stack_ptr, cpu); - unsigned used = 0; struct thread_info *tinfo; - int graph = 0; + unsigned long *irq_stack; unsigned long dummy; + int graph = 0; + int done = 0; if (!task) task = current; @@ -143,49 +181,60 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, * exceptions */ tinfo = task_thread_info(task); - for (;;) { + while (!done) { + unsigned long *stack_end; + enum stack_type stype; char *id; - unsigned long *estack_end; - estack_end = in_exception_stack(cpu, (unsigned long)stack, - &used, &id); - if (estack_end) { + stype = analyze_stack(cpu, task, stack, &stack_end, &id); + + /* Default finish unless specified to continue */ + done = 1; + + switch (stype) { + + /* Break out early if we are on the thread stack */ + case STACK_IS_NORMAL: + break; + + case STACK_IS_EXCEPTION: + if (ops->stack(data, id) < 0) break; bp = ops->walk_stack(tinfo, stack, bp, ops, - data, estack_end, &graph); + data, stack_end, &graph); ops->stack(data, ""); /* * We link to the next stack via the * second-to-last pointer (index -2 to end) in the * exception stack: */ - stack = (unsigned long *) estack_end[-2]; - continue; - } - if (irq_stack_end) { - unsigned long *irq_stack; - irq_stack = irq_stack_end - - (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); - - if (in_irq_stack(stack, irq_stack, irq_stack_end)) { - if (ops->stack(data, "IRQ") < 0) - break; - bp = ops->walk_stack(tinfo, stack, bp, - ops, data, irq_stack_end, &graph); - /* - * We link to the next stack (which would be - * the process stack normally) the last - * pointer (index -1 to end) in the IRQ stack: - */ - stack = (unsigned long *) (irq_stack_end[-1]); - irq_stack_end = NULL; - ops->stack(data, "EOI"); - continue; - } + stack = (unsigned long *) stack_end[-2]; + done = 0; + break; + + case STACK_IS_IRQ: + + if (ops->stack(data, "IRQ") < 0) + break; + bp = ops->walk_stack(tinfo, stack, bp, + ops, data, stack_end, &graph); + /* + * We link to the next stack (which would be + * the process stack normally) the last + * pointer (index -1 to end) in the IRQ stack: + */ + stack = (unsigned long *) (stack_end[-1]); + irq_stack = stack_end - irq_stack_size; + ops->stack(data, "EOI"); + done = 0; + break; + + case STACK_IS_UNKNOWN: + ops->stack(data, "UNK"); + break; } - break; } /* -- cgit v1.2.3-55-g7522 From 621b5060e823301d0cba4cb52a7ee3491922d291 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 3 Mar 2014 14:21:40 +1100 Subject: powerpc/tm: Fix crash when forking inside a transaction When we fork/clone we currently don't copy any of the TM state to the new thread. This results in a TM bad thing (program check) when the new process is switched in as the kernel does a tmrechkpt with TEXASR FS not set. Also, since R1 is from userspace, we trigger the bad kernel stack pointer detection. So we end up with something like this: Bad kernel stack pointer 0 at c0000000000404fc cpu 0x2: Vector: 700 (Program Check) at [c00000003ffefd40] pc: c0000000000404fc: restore_gprs+0xc0/0x148 lr: 0000000000000000 sp: 0 msr: 9000000100201030 current = 0xc000001dd1417c30 paca = 0xc00000000fe00800 softe: 0 irq_happened: 0x01 pid = 0, comm = swapper/2 WARNING: exception is not recoverable, can't continue The below fixes this by flushing the TM state before we copy the task_struct to the clone. To do this we go through the tmreclaim patch, which removes the checkpointed registers from the CPU and transitions the CPU out of TM suspend mode. Hence we need to call tmrechkpt after to restore the checkpointed state and the TM mode for the current task. To make this fail from userspace is simply: tbegin li r0, 2 sc Kudos to Adhemerval Zanella Neto for finding this. Signed-off-by: Michael Neuling cc: Adhemerval Zanella Neto cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/process.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 8d4c247f1738..af064d28b365 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1048,6 +1048,15 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) flush_altivec_to_thread(src); flush_vsx_to_thread(src); flush_spe_to_thread(src); + /* + * Flush TM state out so we can copy it. __switch_to_tm() does this + * flush but it removes the checkpointed state from the current CPU and + * transitions the CPU out of TM mode. Hence we need to call + * tm_recheckpoint_new_task() (on the same task) to restore the + * checkpointed state back and the TM mode. + */ + __switch_to_tm(src); + tm_recheckpoint_new_task(src); *dst = *src; -- cgit v1.2.3-55-g7522 From a5b2cf5b1af424ee3dd9e3ce6d5cea18cb927e67 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 4 Mar 2014 08:31:24 +1100 Subject: powerpc: Align p_dyn, p_rela and p_st symbols The 64bit relocation code places a few symbols in the text segment. These symbols are only 4 byte aligned where they need to be 8 byte aligned. Add an explicit alignment. Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org Tested-by: Laurent Dufour Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/reloc_64.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S index 1482327cfeba..d88736fbece6 100644 --- a/arch/powerpc/kernel/reloc_64.S +++ b/arch/powerpc/kernel/reloc_64.S @@ -81,6 +81,7 @@ _GLOBAL(relocate) 6: blr +.balign 8 p_dyn: .llong __dynamic_start - 0b p_rela: .llong __rela_dyn_start - 0b p_st: .llong _stext - 0b -- cgit v1.2.3-55-g7522 From 6967037baf08860407d275fdd6475d2ee41bd9b7 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Fri, 28 Feb 2014 17:35:52 +0100 Subject: s390/appldata_os: fix cpu array size calculation The cpu array size calculation uses the NR_CPUS config option, which was recently increased from 64 to 256. With a value of 256, the cpu array will no longer fit into one APPLDATA record and loading the appldata_os module fails with the following error: could not insert 'appldata_os': Cannot allocate memory Use num_possible_cpus() instead of NR_CPUS. For z/VM, this will still result in a value of 64. This is not true for LPAR, but the appldata feature is not available for LPAR. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/appldata/appldata_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index de8e2b3b0180..69b23b25ac34 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -171,7 +171,7 @@ static int __init appldata_os_init(void) int rc, max_size; max_size = sizeof(struct appldata_os_data) + - (NR_CPUS * sizeof(struct appldata_os_per_cpu)); + (num_possible_cpus() * sizeof(struct appldata_os_per_cpu)); if (max_size > APPLDATA_MAX_REC_SIZE) { pr_err("Maximum OS record size %i exceeds the maximum " "record size %i\n", max_size, APPLDATA_MAX_REC_SIZE); -- cgit v1.2.3-55-g7522 From 0563416b8ac2711f315b50aa6efc84b112e5420a Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 26 Feb 2014 18:13:06 -0800 Subject: s390: select CONFIG_TTY for use of tty in unconditional keyboard driver The unconditionally built keyboard driver, drivers/s390/char/keyboard.c, requires CONFIG_TTY, so select it from CONFIG_S390 to prevent a build error. Signed-off-by: Josh Triplett Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 86db5a8e6586..cbe56154c6e3 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -140,6 +140,7 @@ config S390 select OLD_SIGACTION select OLD_SIGSUSPEND3 select SYSCTL_EXCEPTION_TRACE + select TTY select VIRT_CPU_ACCOUNTING select VIRT_TO_BUS -- cgit v1.2.3-55-g7522 From fa2a0627ac70d007c313da150d9bf3705729e9c8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 6 Mar 2014 11:24:41 +0100 Subject: s390/compat: remove compat exec domain The whole compat exec domain code doesn't make any difference. From the registered s390_exec_domain: - exec domain name is only displayed in /proc/execdomains - handler is unused - pers_low and pers_high are only used internally to find this specific exec domain otherwise the default exec domain will be used - all other fields match the default exec domain So let's get rid of this. Reported-by: Thomas Gleixner Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/Makefile | 5 ++--- arch/s390/kernel/compat_exec_domain.c | 29 ----------------------------- 2 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 arch/s390/kernel/compat_exec_domain.c (limited to 'arch') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 1b3ac09c11b6..a95c4ca99617 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -47,9 +47,8 @@ obj-$(CONFIG_SCHED_BOOK) += topology.o obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o obj-$(CONFIG_AUDIT) += audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o -obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ - compat_wrapper.o compat_exec_domain.o \ - $(compat-obj-y) +obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o +obj-$(CONFIG_COMPAT) += compat_wrapper.o $(compat-obj-y) obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_KPROBES) += kprobes.o diff --git a/arch/s390/kernel/compat_exec_domain.c b/arch/s390/kernel/compat_exec_domain.c deleted file mode 100644 index 765fabdada9f..000000000000 --- a/arch/s390/kernel/compat_exec_domain.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Support for 32-bit Linux for S390 personality. - * - * Copyright IBM Corp. 2000 - * Author(s): Gerhard Tonn (ton@de.ibm.com) - * - * - */ - -#include -#include -#include -#include - -static struct exec_domain s390_exec_domain; - -static int __init s390_init (void) -{ - s390_exec_domain.name = "Linux/s390"; - s390_exec_domain.handler = NULL; - s390_exec_domain.pers_low = PER_LINUX32; - s390_exec_domain.pers_high = PER_LINUX32; - s390_exec_domain.signal_map = default_exec_domain.signal_map; - s390_exec_domain.signal_invmap = default_exec_domain.signal_invmap; - register_exec_domain(&s390_exec_domain); - return 0; -} - -__initcall(s390_init); -- cgit v1.2.3-55-g7522 From 43eab381181c76a19734298b5c925c45fb1afe45 Mon Sep 17 00:00:00 2001 From: Philipp Hachtmann Date: Wed, 26 Feb 2014 16:19:22 +0100 Subject: s390/topology: Remove call to update_cpu_masks() The call to update_cpu_masks() from within topology_init() is completely redundant. This patch removes it. Signed-off-by: Philipp Hachtmann Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/topology.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 4b2e3e317004..6298fed11ced 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -451,7 +451,6 @@ static int __init topology_init(void) } set_topology_timer(); out: - update_cpu_masks(); return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); } device_initcall(topology_init); -- cgit v1.2.3-55-g7522 From b053940df41808f0f27568eb36820d10a8a987f8 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 7 Mar 2014 13:22:22 +0530 Subject: ARC: Use correct PTAG register for icache flush This fixes a subtle issue with cache flush which could potentially cause random userspace crashes because of stale icache lines. This error crept in when consolidating the cache flush code Fixes: bd12976c3664 (ARC: cacheflush refactor #3: Unify the {d,i}cache) Signed-off-by: Vineet Gupta Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 3.13 Cc: arc-linux-dev@synopsys.com Signed-off-by: Linus Torvalds --- arch/arc/mm/cache_arc700.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 6b58c1de7577..400c663b21c2 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -282,7 +282,7 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr, #else /* if V-P const for loop, PTAG can be written once outside loop */ if (full_page_op) - write_aux_reg(ARC_REG_DC_PTAG, paddr); + write_aux_reg(aux_tag, paddr); #endif while (num_lines-- > 0) { @@ -296,7 +296,7 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr, write_aux_reg(aux_cmd, vaddr); vaddr += L1_CACHE_BYTES; #else - write_aux_reg(aux, paddr); + write_aux_reg(aux_cmd, paddr); paddr += L1_CACHE_BYTES; #endif } -- cgit v1.2.3-55-g7522 From 006fa2599bf0daf107cbb7a8a99fcfb9a998a169 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 26 Feb 2014 19:40:46 +0000 Subject: ARM: fix noMMU kallsyms symbol filtering With noMMU, CONFIG_PAGE_OFFSET was not being set correctly. As there's no MMU, PAGE_OFFSET should be equal to PHYS_OFFSET in all cases. This commit makes that explicit. Since we do this, we don't need to mess around in asm/memory.h with ifdefs to sort this out, so let's get rid of that, and there's no point offering the "Memory split" option for noMMU as that's meaningless there. Fixes: b9b32bf70f2f ("ARM: use linker magic for vectors and vector stubs") Cc: Signed-off-by: Russell King --- arch/arm/Kconfig | 2 ++ arch/arm/include/asm/memory.h | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e25419817791..2a232ce56d9c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1578,6 +1578,7 @@ config BL_SWITCHER_DUMMY_IF choice prompt "Memory split" + depends on MMU default VMSPLIT_3G help Select the desired split between kernel and user memory. @@ -1595,6 +1596,7 @@ endchoice config PAGE_OFFSET hex + default PHYS_OFFSET if !MMU default 0x40000000 if VMSPLIT_1G default 0x80000000 if VMSPLIT_2G default 0xC0000000 diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 8756e4bcdba0..4afb376d9c7c 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -30,14 +30,15 @@ */ #define UL(x) _AC(x, UL) +/* PAGE_OFFSET - the virtual address of the start of the kernel image */ +#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) + #ifdef CONFIG_MMU /* - * PAGE_OFFSET - the virtual address of the start of the kernel image * TASK_SIZE - the maximum size of a user space task. * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area */ -#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) #define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) @@ -104,10 +105,6 @@ #define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE) #endif -#ifndef PAGE_OFFSET -#define PAGE_OFFSET PLAT_PHYS_OFFSET -#endif - /* * The module can be at any place in ram in nommu mode. */ -- cgit v1.2.3-55-g7522 From 052450fdc55894a39fbae93d9bbe43947956f663 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 25 Feb 2014 22:41:41 +0100 Subject: ARM: 7991/1: sa1100: fix compile problem on Collie Due to a problem in the MFD Kconfig it was not possible to compile the UCB battery driver for the Collie SA1100 system, in turn making it impossible to compile in the battery driver. (See patch "mfd: include all drivers in subsystem menu".) After fixing the MFD Kconfig (separate patch) a compile error appears in the Collie battery driver due to the implicitly requiring through via prior to commit 40ca061b "ARM: 7841/1: sa1100: remove complex GPIO interface". Fix this up by including the required header into . Cc: stable@vger.kernel.org Cc: Andrea Adami Cc: Dmitry Eremin-Solenikov Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-sa1100/include/mach/collie.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h index f33679d2d3ee..50e1d850ee2e 100644 --- a/arch/arm/mach-sa1100/include/mach/collie.h +++ b/arch/arm/mach-sa1100/include/mach/collie.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARCH_COLLIE_H #define __ASM_ARCH_COLLIE_H +#include "hardware.h" /* Gives GPIO_MAX */ + extern void locomolcd_power(int on); #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) -- cgit v1.2.3-55-g7522 From 38e0b088d322e5762ac21fb4df433e83faf128eb Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 26 Feb 2014 17:21:26 +0100 Subject: ARM: 7992/1: boot: compressed: ignore bswapsdi2.S Commit 017f161a55b4 (ARM: 7877/1: use built-in byte swap function) added bswapsdi2.{o,S} to arch/arm/boot/compressed/Makefile, but didn't update the .gitignore. Thus after a a build git status shows bswapsdi2.S as a new file, which is a little annoying. This patch updates arch/arm/boot/compressed/.gitignore to ignore bswapsdi2.S, as we already do for ashldi3.S and others. Signed-off-by: Mark Rutland Acked-by: Nicolas Pitre Acked-by: Kim Phillips Cc: David Woodhouse Signed-off-by: Russell King --- arch/arm/boot/compressed/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index 47279aa96a6a..0714e0334e33 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -1,4 +1,5 @@ ashldi3.S +bswapsdi2.S font.c lib1funcs.S hyp-stub.S -- cgit v1.2.3-55-g7522 From 5fa10196bdb5f190f595ebd048490ee52dddea0f Mon Sep 17 00:00:00 2001 From: H. Peter Anvin Date: Fri, 7 Mar 2014 15:05:20 -0800 Subject: x86: Ignore NMIs that come in during early boot Don Zickus reports: A customer generated an external NMI using their iLO to test kdump worked. Unfortunately, the machine hung. Disabling the nmi_watchdog made things work. I speculated the external NMI fired, caused the machine to panic (as expected) and the perf NMI from the watchdog came in and was latched. My guess was this somehow caused the hang. ---- It appears that the latched NMI stays latched until the early page table generation on 64 bits, which causes exceptions to happen which end in IRET, which re-enable NMI. Therefore, ignore NMIs that come in during early execution, until we have proper exception handling. Reported-and-tested-by: Don Zickus Link: http://lkml.kernel.org/r/1394221143-29713-1-git-send-email-dzickus@redhat.com Signed-off-by: H. Peter Anvin Cc: # v3.5+, older with some backport effort --- arch/x86/kernel/head_32.S | 7 ++++++- arch/x86/kernel/head_64.S | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 81ba27679f18..d2a21590794a 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -544,6 +544,10 @@ ENDPROC(early_idt_handlers) /* This is global to keep gas from relaxing the jumps */ ENTRY(early_idt_handler) cld + + cmpl $X86_TRAP_NMI,(%esp) + je is_nmi # Ignore NMI + cmpl $2,%ss:early_recursion_flag je hlt_loop incl %ss:early_recursion_flag @@ -594,8 +598,9 @@ ex_entry: pop %edx pop %ecx pop %eax - addl $8,%esp /* drop vector number and error code */ decl %ss:early_recursion_flag +is_nmi: + addl $8,%esp /* drop vector number and error code */ iret ENDPROC(early_idt_handler) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index e1aabdb314c8..33f36c78594e 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -343,6 +343,9 @@ early_idt_handlers: ENTRY(early_idt_handler) cld + cmpl $X86_TRAP_NMI,(%rsp) + je is_nmi # Ignore NMI + cmpl $2,early_recursion_flag(%rip) jz 1f incl early_recursion_flag(%rip) @@ -405,8 +408,9 @@ ENTRY(early_idt_handler) popq %rdx popq %rcx popq %rax - addq $16,%rsp # drop vector number and error code decl early_recursion_flag(%rip) +is_nmi: + addq $16,%rsp # drop vector number and error code INTERRUPT_RETURN ENDPROC(early_idt_handler) -- cgit v1.2.3-55-g7522 From b01d4e68933ec23e43b1046fa35d593cefcf37d1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 7 Mar 2014 18:58:40 -0800 Subject: x86: fix compile error due to X86_TRAP_NMI use in asm files It's an enum, not a #define, you can't use it in asm files. Introduced in commit 5fa10196bdb5 ("x86: Ignore NMIs that come in during early boot"), and sadly I didn't compile-test things like I should have before pushing out. My weak excuse is that the x86 tree generally doesn't introduce stupid things like this (and the ARM pull afterwards doesn't cause me to do a compile-test either, since I don't cross-compile). Cc: Don Zickus Cc: H. Peter Anvin Signed-off-by: Linus Torvalds --- arch/x86/kernel/head_32.S | 2 +- arch/x86/kernel/head_64.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index d2a21590794a..f36bd42d6f0c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -545,7 +545,7 @@ ENDPROC(early_idt_handlers) ENTRY(early_idt_handler) cld - cmpl $X86_TRAP_NMI,(%esp) + cmpl $2,(%esp) # X86_TRAP_NMI je is_nmi # Ignore NMI cmpl $2,%ss:early_recursion_flag diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 33f36c78594e..a468c0a65c42 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -343,7 +343,7 @@ early_idt_handlers: ENTRY(early_idt_handler) cld - cmpl $X86_TRAP_NMI,(%rsp) + cmpl $2,(%rsp) # X86_TRAP_NMI je is_nmi # Ignore NMI cmpl $2,early_recursion_flag(%rip) -- cgit v1.2.3-55-g7522 From d152d22a18c240286c19997a6249ee76ea055926 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 10 Mar 2014 10:36:52 +0000 Subject: arm64: barriers: add dmb barrier Commit 8adbf57fc429 ("irqchip: gic: use dmb ishst instead of dsb when raising a softirq") added an explicit dmb(...) call to the GIC driver. This patch adds a simple dmb() macro to arm64, which expands to a DMB SY instruction. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/barrier.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 409ca370cfe2..66eb7648043b 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -25,6 +25,7 @@ #define wfi() asm volatile("wfi" : : : "memory") #define isb() asm volatile("isb" : : : "memory") +#define dmb(opt) asm volatile("dmb sy" : : : "memory") #define dsb(opt) asm volatile("dsb sy" : : : "memory") #define mb() dsb() -- cgit v1.2.3-55-g7522 From a91c406c742b3fc28969ec3316c9588acde66e5a Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sat, 15 Feb 2014 15:45:29 +1100 Subject: m68k: Remove CONSOLE_PENGUIN macro, adopt CONFIG_LOGO Allow CONFIG_LOGO to enable/disable the head.S penguin logo as well as the framebuffer console logo. This should save a few bytes. It also gets rid of the obscure CONSOLE_PENGUIN macro. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- arch/m68k/kernel/head.S | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 4c99bab7e664..cea4af91cbd3 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -275,7 +275,6 @@ #ifdef CONFIG_FRAMEBUFFER_CONSOLE #define CONSOLE -#define CONSOLE_PENGUIN #endif #ifdef CONFIG_EARLY_PRINTK @@ -907,15 +906,15 @@ L(nothp): */ #ifdef CONFIG_MAC is_not_mac(L(nocon)) -#ifdef CONSOLE +# ifdef CONSOLE console_init -#ifdef CONSOLE_PENGUIN +# ifdef CONFIG_LOGO console_put_penguin -#endif /* CONSOLE_PENGUIN */ +# endif /* CONFIG_LOGO */ console_put_stats -#endif /* CONSOLE */ +# endif /* CONSOLE */ L(nocon): -#endif /* CONFIG_MAC */ +#endif /* CONFIG_MAC */ putc '\n' @@ -3456,7 +3455,7 @@ func_start console_put_stats,%a0/%d7 func_return console_put_stats -#ifdef CONSOLE_PENGUIN +#ifdef CONFIG_LOGO func_start console_put_penguin,%a0-%a1/%d0-%d7 /* * Get 'that_penguin' onto the screen in the upper right corner -- cgit v1.2.3-55-g7522 From 7ce0526a6c2681f8edd1f9940c3d668e4cde4cf2 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sat, 15 Feb 2014 15:46:24 +1100 Subject: m68k: Remove dead code Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- arch/m68k/kernel/head.S | 55 ------------------------------------------------- 1 file changed, 55 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index cea4af91cbd3..cb9c40e04e7e 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -657,27 +657,6 @@ ENTRY(__start) movel %a0@,%a1@ #endif -#if 0 - /* - * Clear the screen - */ - lea %pc@(L(mac_videobase)),%a0 - movel %a0@,%a1 - lea %pc@(L(mac_dimensions)),%a0 - movel %a0@,%d1 - swap %d1 /* #rows is high bytes */ - andl #0xFFFF,%d1 /* rows */ - subl #10,%d1 - lea %pc@(L(mac_rowbytes)),%a0 -loopy2: - movel %a0@,%d0 - subql #1,%d0 -loopx2: - moveb #0x55, %a1@+ - dbra %d0,loopx2 - dbra %d1,loopy2 -#endif - L(test_notmac): #endif /* CONFIG_MAC */ @@ -3323,7 +3302,6 @@ func_return set_leds #define Lconsole_struct_num_columns 8 #define Lconsole_struct_num_rows 12 #define Lconsole_struct_left_edge 16 -#define Lconsole_struct_penguin_putc 20 func_start console_init,%a0-%a4/%d0-%d7 /* @@ -3798,38 +3776,6 @@ L(console_plot_pixel_exit): func_return console_plot_pixel #endif /* CONSOLE */ -#if 0 -/* - * This is some old code lying around. I don't believe - * it's used or important anymore. My guess is it contributed - * to getting to this point, but it's done for now. - * It was still in the 2.1.77 head.S, so it's still here. - * (And still not used!) - */ -L(showtest): - moveml %a0/%d7,%sp@- - puts "A=" - putn %a1 - - .long 0xf0119f15 | ptestr #5,%a1@,#7,%a0 - - puts "DA=" - putn %a0 - - puts "D=" - putn %a0@ - - puts "S=" - lea %pc@(L(mmu)),%a0 - .long 0xf0106200 | pmove %psr,%a0@ - clrl %d7 - movew %a0@,%d7 - putn %d7 - - putc '\n' - moveml %sp@+,%a0/%d7 - rts -#endif /* 0 */ __INITDATA .align 4 @@ -3848,7 +3794,6 @@ L(console_globals): .long 0 /* max num columns */ .long 0 /* max num rows */ .long 0 /* left edge */ - .long 0 /* mac putc */ L(console_font): .long 0 /* pointer to console font (struct font_desc) */ L(console_font_data): -- cgit v1.2.3-55-g7522 From ecc79d4964c4154b8bc2de2a8ffed108f009c405 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 16 Feb 2014 11:49:15 +0100 Subject: m68k: head.S - Remove bogus L prefix in comment Signed-off-by: Geert Uytterhoeven --- arch/m68k/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index cb9c40e04e7e..3ab329b88521 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -3308,7 +3308,7 @@ func_start console_init,%a0-%a4/%d0-%d7 * Some of the register usage that follows * a0 = pointer to boot_info * a1 = pointer to screen - * a2 = pointer to Lconsole_globals + * a2 = pointer to console_globals * d3 = pixel width of screen * d4 = pixel height of screen * (d3,d4) ~= (x,y) of a point just below -- cgit v1.2.3-55-g7522 From e97ca8e5b864f88b028c1759ba8536fa827d6d96 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Mon, 10 Mar 2014 15:49:43 -0700 Subject: mm: fix GFP_THISNODE callers and clarify GFP_THISNODE is for callers that implement their own clever fallback to remote nodes. It restricts the allocation to the specified node and does not invoke reclaim, assuming that the caller will take care of it when the fallback fails, e.g. through a subsequent allocation request without GFP_THISNODE set. However, many current GFP_THISNODE users only want the node exclusive aspect of the flag, without actually implementing their own fallback or triggering reclaim if necessary. This results in things like page migration failing prematurely even when there is easily reclaimable memory available, unless kswapd happens to be running already or a concurrent allocation attempt triggers the necessary reclaim. Convert all callsites that don't implement their own fallback strategy to __GFP_THISNODE. This restricts the allocation a single node too, but at the same time allows the allocator to enter the slowpath, wake kswapd, and invoke direct reclaim if necessary, to make the allocation happen when memory is full. Signed-off-by: Johannes Weiner Acked-by: Rik van Riel Cc: Jan Stancek Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/uncached.c | 2 +- arch/powerpc/platforms/cell/ras.c | 3 ++- drivers/misc/sgi-xp/xpc_uv.c | 2 +- include/linux/gfp.h | 4 ++++ include/linux/mmzone.h | 4 ++-- include/linux/slab.h | 2 +- kernel/profile.c | 4 ++-- mm/migrate.c | 11 ++++++----- 8 files changed, 19 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index a96bcf83a735..20e8a9b21d75 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -98,7 +98,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid) /* attempt to allocate a granule's worth of cached memory pages */ page = alloc_pages_exact_node(nid, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, IA64_GRANULE_SHIFT-PAGE_SHIFT); if (!page) { mutex_unlock(&uc_pool->add_chunk_mutex); diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 5ec1e47a0d77..e865d748179b 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -123,7 +123,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) area->nid = nid; area->order = order; - area->pages = alloc_pages_exact_node(area->nid, GFP_KERNEL|GFP_THISNODE, + area->pages = alloc_pages_exact_node(area->nid, + GFP_KERNEL|__GFP_THISNODE, area->order); if (!area->pages) { diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index b9e2000969f0..95c894482fdd 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -240,7 +240,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, nid = cpu_to_node(cpu); page = alloc_pages_exact_node(nid, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, pg_order); if (page == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0437439bc047..39b81dc7d01a 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -123,6 +123,10 @@ struct vm_area_struct; __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \ __GFP_NO_KSWAPD) +/* + * GFP_THISNODE does not perform any reclaim, you most likely want to + * use __GFP_THISNODE to allocate from a given node without fallback! + */ #ifdef CONFIG_NUMA #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) #else diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 5f2052c83154..9b61b9bf81ac 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -590,10 +590,10 @@ static inline bool zone_is_empty(struct zone *zone) /* * The NUMA zonelists are doubled because we need zonelists that restrict the - * allocations to a single node for GFP_THISNODE. + * allocations to a single node for __GFP_THISNODE. * * [0] : Zonelist with fallback - * [1] : No fallback (GFP_THISNODE) + * [1] : No fallback (__GFP_THISNODE) */ #define MAX_ZONELISTS 2 diff --git a/include/linux/slab.h b/include/linux/slab.h index 9260abdd67df..b5b2df60299e 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -410,7 +410,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) * * %GFP_NOWAIT - Allocation will not sleep. * - * %GFP_THISNODE - Allocate node-local memory only. + * %__GFP_THISNODE - Allocate node-local memory only. * * %GFP_DMA - Allocation suitable for DMA. * Should only be used for kmalloc() caches. Otherwise, use a diff --git a/kernel/profile.c b/kernel/profile.c index 6631e1ef55ab..ebdd9c1a86b4 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -549,14 +549,14 @@ static int create_hash_tables(void) struct page *page; page = alloc_pages_exact_node(node, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, 0); if (!page) goto out_cleanup; per_cpu(cpu_profile_hits, cpu)[1] = (struct profile_hit *)page_address(page); page = alloc_pages_exact_node(node, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, 0); if (!page) goto out_cleanup; diff --git a/mm/migrate.c b/mm/migrate.c index 482a33d89134..b494fdb9a636 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1158,7 +1158,7 @@ static struct page *new_page_node(struct page *p, unsigned long private, pm->node); else return alloc_pages_exact_node(pm->node, - GFP_HIGHUSER_MOVABLE | GFP_THISNODE, 0); + GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0); } /* @@ -1544,9 +1544,9 @@ static struct page *alloc_misplaced_dst_page(struct page *page, struct page *newpage; newpage = alloc_pages_exact_node(nid, - (GFP_HIGHUSER_MOVABLE | GFP_THISNODE | - __GFP_NOMEMALLOC | __GFP_NORETRY | - __GFP_NOWARN) & + (GFP_HIGHUSER_MOVABLE | + __GFP_THISNODE | __GFP_NOMEMALLOC | + __GFP_NORETRY | __GFP_NOWARN) & ~GFP_IOFS, 0); return newpage; @@ -1747,7 +1747,8 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, goto out_dropref; new_page = alloc_pages_node(node, - (GFP_TRANSHUGE | GFP_THISNODE) & ~__GFP_WAIT, HPAGE_PMD_ORDER); + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_WAIT, + HPAGE_PMD_ORDER); if (!new_page) goto out_fail; -- cgit v1.2.3-55-g7522 From 0eb808eb753cd44e740da8e64f5c97a2a8e07578 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 10 Mar 2014 15:49:52 -0700 Subject: cris: convert ffs from an object-like macro to a function-like macro This avoids bad interactions with code using identifiers called "ffs": drivers/usb/gadget/f_fs.c: In function 'ffsmod_init': drivers/usb/gadget/f_fs.c:2693:494: error: 'ffsusb_func' undeclared (first use in this function) drivers/usb/gadget/f_fs.c:2693:494: note: each undeclared identifier is reported only once for each function it appears in drivers/usb/gadget/f_fs.c: In function 'ffsmod_exit': drivers/usb/gadget/f_fs.c:2693:677: error: 'ffsusb_func' undeclared (first use in this function) drivers/usb/gadget/f_fs.c: At top level: drivers/usb/gadget/f_fs.c:2693:35: warning: 'kernel_ffsusb_func' defined but not used [-Wunused-variable] drivers/usb/gadget/f_fs.c: In function 'ffsmod_init': drivers/usb/gadget/f_fs.c:2693:15: warning: control reaches end of non-void function [-Wreturn-type] See http://kisskb.ellerman.id.au/kisskb/buildresult/10715817/ Signed-off-by: Geert Uytterhoeven Cc: Mikael Starvik Cc: Jesper Nilsson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/include/asm/bitops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h index 184066ceb1f6..053c17b36559 100644 --- a/arch/cris/include/asm/bitops.h +++ b/arch/cris/include/asm/bitops.h @@ -144,7 +144,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) * definition, which doesn't have the same semantics. We don't want to * use -fno-builtin, so just hide the name ffs. */ -#define ffs kernel_ffs +#define ffs(x) kernel_ffs(x) #include #include -- cgit v1.2.3-55-g7522 From 6cce16f99d7be23cec7cabdf32a8166eec6e5393 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 7 Mar 2014 08:52:32 +0100 Subject: x86, threadinfo: Redo "x86: Use inline assembler to get sp" This patch restores the changes of commit dff38e3e93 "x86: Use inline assembler instead of global register variable to get sp". They got lost in commit 198d208df4 "x86: Keep thread_info on thread stack in x86_32" while moving the code to arch/x86/kernel/irq_32.c. Quoting Andi from commit dff38e3e93: """ LTO in gcc 4.6/47. has trouble with global register variables. They were used to read the stack pointer. Use a simple inline assembler statement with a mov instead. This also helps LLVM/clang, which does not support global register variables. """ Cc: Steven Rostedt Cc: Andrew Morton Cc: Peter Zijlstra Cc: Brian Gerst Cc: Andi Kleen Signed-off-by: Mathias Krause Link: http://lkml.kernel.org/r/1394178752-18047-1-git-send-email-minipli@googlemail.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/irq_32.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 988dc8bcaebf..63ce838e5a54 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -70,7 +70,11 @@ static void call_on_stack(void *func, void *stack) } /* how to get the current stack pointer from C */ -register unsigned long current_stack_pointer asm("esp") __used; +#define current_stack_pointer ({ \ + unsigned long sp; \ + asm("mov %%esp,%0" : "=g" (sp)); \ + sp; \ +}) static inline void *current_stack(void) { -- cgit v1.2.3-55-g7522 From ef11dadb8373fcbe53bdd09ceb262b2f18da10c5 Mon Sep 17 00:00:00 2001 From: Dongsheng Yang Date: Wed, 5 Mar 2014 17:58:36 +0800 Subject: perf/x86/uncore: Add __init for uncore_cpumask_init() Commit: 411cf180fa00 perf/x86/uncore: fix initialization of cpumask introduced the function uncore_cpumask_init(), which is only called in __init intel_uncore_init(). But it is not marked with __init, which produces the following warning: WARNING: vmlinux.o(.text+0x2464a): Section mismatch in reference from the function uncore_cpumask_init() to the function .init.text:uncore_cpu_setup() The function uncore_cpumask_init() references the function __init uncore_cpu_setup(). This is often because uncore_cpumask_init lacks a __init annotation or the annotation of uncore_cpu_setup is wrong. This patch marks uncore_cpumask_init() with __init. Signed-off-by: Dongsheng Yang Acked-by: Stephane Eranian Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: "H. Peter Anvin" Link: http://lkml.kernel.org/r/1394013516-4964-1-git-send-email-yangds.fnst@cn.fujitsu.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index b262c6124cf3..5c2537af0a25 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -4229,7 +4229,7 @@ static int __init uncore_pmus_register(void) return 0; } -static void uncore_cpumask_init(void) +static void __init uncore_cpumask_init(void) { int cpu; -- cgit v1.2.3-55-g7522 From b7b4839d93e50adccef29eccb694807cdcb8bee3 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 6 Mar 2014 12:20:28 -0500 Subject: perf/x86: Fix leak in uncore_type_init failure paths The error path of uncore_type_init() frees up any allocations that were made along the way, but it relies upon type->pmus being set, which only happens if the function succeeds. As type->pmus remains null in this case, the call to uncore_type_exit will do nothing. Moving the assignment earlier will allow us to actually free those allocations should something go awry. Signed-off-by: Dave Jones Acked-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140306172028.GA552@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index c88f7f4b03ee..047f540cf3f7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -3334,6 +3334,8 @@ static int __init uncore_type_init(struct intel_uncore_type *type) if (!pmus) return -ENOMEM; + type->pmus = pmus; + type->unconstrainted = (struct event_constraint) __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, 0, type->num_counters, 0, 0); @@ -3369,7 +3371,6 @@ static int __init uncore_type_init(struct intel_uncore_type *type) } type->pmu_group = &uncore_pmu_attr_group; - type->pmus = pmus; return 0; fail: uncore_type_exit(type); -- cgit v1.2.3-55-g7522 From 7743a536beda6225eef4a0758c5370f761fb0616 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 7 Mar 2014 10:52:42 -0500 Subject: i386: Remove unneeded test of 'task' in dump_trace() (again) Commit 028a690a1ebc8b "i386: Remove unneeded test of 'task' in dump_trace()" correctly removed the unneeded 'task != NULL' check because it would be set to current if it was NULL. Commit 2bc5f927d489 "i386: split out dumpstack code from traps_32.c" moved the code from traps_32.c to its own file dump_stack.c for preparation of the i386 / x86_64 merge. Commit 8a541665b906 "dumpstack: x86: various small unification steps" worked to make i386 and x86_64 dump_stack logic similar. But this actually reverted the correct change from 028a690a1ebc8b. Commit d0caf292505d "x86/dumpstack: Remove unneeded check in dump_trace()" removed the unneeded "task != NULL" check for x86_64 but left that same unneeded check for i386, that was added because x86_64 had it! This chain of events ironically had i386 add back the unneeded task != NULL check because x86_64 did it, and then the fix for x86_64 was fixed by Dan. And even more ironically, it was Dan's smatch bot that told me that a change to dump_stack_32 I made may be wrong if current can be NULL (it can't), as there was a check for it by assigning task to current, and then checking if task is NULL. Reported-by: Dan Carpenter Signed-off-by: Steven Rostedt Acked-by: Alexander van Heukelum Cc: Jesper Juhl Link: http://lkml.kernel.org/r/20140307105242.79a0befd@gandalf.local.home Signed-off-by: Ingo Molnar --- arch/x86/kernel/dumpstack_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index f2a1770ca176..a21d49c071db 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -30,7 +30,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long dummy; stack = &dummy; - if (task && task != current) + if (task != current) stack = (unsigned long *)task->thread.sp; } -- cgit v1.2.3-55-g7522 From ea7bdc65bca8cf837a63e0ff7b75daed83222511 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 27 Jan 2014 20:14:06 +0100 Subject: x86/apic: Plug racy xAPIC access of CPU hotplug code apic_icr_write() and its users in smpboot.c were apparently written under the assumption that this code would only run during early boot. But nowadays we also execute it when onlining a CPU later on while the system is fully running. That will make wakeup_cpu_via_init_nmi and, thus, also native_apic_icr_write run in plain process context. If we migrate the caller to a different CPU at the wrong time or interrupt it and write to ICR/ICR2 to send unrelated IPIs, we can end up sending INIT, SIPI or NMIs to wrong CPUs. Fix this by disabling interrupts during the write to the ICR halves and disable preemption around waiting for ICR availability and using it. Signed-off-by: Jan Kiszka Tested-By: Igor Mammedov Link: http://lkml.kernel.org/r/52E6AFFE.3030004@siemens.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/apic.c | 4 ++++ arch/x86/kernel/smpboot.c | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index f824d697db19..53e20531470e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -286,8 +286,12 @@ u32 native_safe_apic_wait_icr_idle(void) void native_apic_icr_write(u32 low, u32 id) { + unsigned long flags; + + local_irq_save(flags); apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); apic_write(APIC_ICR, low); + local_irq_restore(flags); } u64 native_apic_icr_read(void) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c77acc69ecf6..60179ec39d4c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -702,11 +702,15 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, int id; int boot_error; + preempt_disable(); + /* * Wake up AP by INIT, INIT, STARTUP sequence. */ - if (cpu) - return wakeup_secondary_cpu_via_init(apicid, start_ip); + if (cpu) { + boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); + goto out; + } /* * Wake up BSP by nmi. @@ -726,6 +730,9 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); } +out: + preempt_enable(); + return boot_error; } -- cgit v1.2.3-55-g7522 From 36fc5500bb1907bea7e9b4785dd00abf714d556f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 4 Mar 2014 14:07:37 -0700 Subject: sched: Remove unused mc_capable() and smt_capable() Remove mc_capable() and smt_capable(). Neither is used. Both were added by 5c45bf279d37 ("sched: mc/smt power savings sched policy"). Uses of both were removed by 8e7fbcbc22c1 ("sched: Remove stale power aware scheduling remnants and dysfunctional knobs"). Signed-off-by: Bjorn Helgaas Signed-off-by: Peter Zijlstra Acked-by: Thomas Gleixner Acked-by: David S. Miller Acked-by: Benjamin Herrenschmidt Link: http://lkml.kernel.org/r/20140304210737.16893.54289.stgit@bhelgaas-glaptop.roam.corp.google.com Signed-off-by: Ingo Molnar --- arch/arm/include/asm/topology.h | 3 --- arch/ia64/include/asm/topology.h | 1 - arch/mips/include/asm/topology.h | 4 ---- arch/powerpc/include/asm/topology.h | 1 - arch/sparc/include/asm/topology_64.h | 2 -- arch/x86/include/asm/topology.h | 6 ------ 6 files changed, 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index 58b8b84adcd2..2fe85fff5cca 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -20,9 +20,6 @@ extern struct cputopo_arm cpu_topology[NR_CPUS]; #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling) #define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling) -#define mc_capable() (cpu_topology[0].socket_id != -1) -#define smt_capable() (cpu_topology[0].thread_id != -1) - void init_cpu_topology(void); void store_cpu_topology(unsigned int cpuid); const struct cpumask *cpu_coregroup_mask(int cpu); diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h index a2496e449b75..5cb55a1e606b 100644 --- a/arch/ia64/include/asm/topology.h +++ b/arch/ia64/include/asm/topology.h @@ -77,7 +77,6 @@ void build_cpu_to_node_map(void); #define topology_core_id(cpu) (cpu_data(cpu)->core_id) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) -#define smt_capable() (smp_num_siblings > 1) #endif extern void arch_fix_phys_package_id(int num, u32 slot); diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h index 12609a17dc8b..20ea4859c822 100644 --- a/arch/mips/include/asm/topology.h +++ b/arch/mips/include/asm/topology.h @@ -10,8 +10,4 @@ #include -#ifdef CONFIG_SMP -#define smt_capable() (smp_num_siblings > 1) -#endif - #endif /* __ASM_TOPOLOGY_H */ diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index d0b5fca6b077..c9202151079f 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -99,7 +99,6 @@ static inline int prrn_is_enabled(void) #ifdef CONFIG_SMP #include -#define smt_capable() (cpu_has_feature(CPU_FTR_SMT)) #ifdef CONFIG_PPC64 #include diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index 1754390a426f..a2d10fc64faf 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h @@ -42,8 +42,6 @@ static inline int pcibus_to_node(struct pci_bus *pbus) #define topology_core_id(cpu) (cpu_data(cpu).core_id) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) -#define mc_capable() (sparc64_multi_core) -#define smt_capable() (sparc64_multi_core) #endif /* CONFIG_SMP */ extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index d35f24e231cd..9bcc724cafdd 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -133,12 +133,6 @@ static inline void arch_fix_phys_package_id(int num, u32 slot) struct pci_bus; void x86_pci_root_bus_resources(int bus, struct list_head *resources); -#ifdef CONFIG_SMP -#define mc_capable() ((boot_cpu_data.x86_max_cores > 1) && \ - (cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)) -#define smt_capable() (smp_num_siblings > 1) -#endif - #ifdef CONFIG_NUMA extern int get_mp_bus_to_node(int busnum); extern void set_mp_bus_to_node(int busnum, int node); -- cgit v1.2.3-55-g7522 From 070826820daf423eee83ee4e90bf3daf2cdd85c2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 4 Mar 2014 14:07:44 -0700 Subject: sparc64, sched: Remove unused sparc64_multi_core Remove sparc64_multi_core because it's not used any more. It was added by a2f9f6bbb30e ("Fix {mc,smt}_capable()"), and the last uses were removed by e637d96bf462 ("sched: Remove unused mc_capable() and smt_capable()"). Signed-off-by: Bjorn Helgaas Signed-off-by: Peter Zijlstra Acked-by: David S. Miller Link: http://lkml.kernel.org/r/20140304210744.16893.75929.stgit@bhelgaas-glaptop.roam.corp.google.com Signed-off-by: Ingo Molnar --- arch/sparc/include/asm/smp_64.h | 1 - arch/sparc/kernel/mdesc.c | 4 ---- arch/sparc/kernel/prom_64.c | 3 --- arch/sparc/kernel/smp_64.c | 2 -- 4 files changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index dd3bef4b9896..05710393959f 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -32,7 +32,6 @@ DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); extern cpumask_t cpu_core_map[NR_CPUS]; -extern int sparc64_multi_core; extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index b90bf23e3aab..a1a4400d4025 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -896,10 +896,6 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask); -#ifdef CONFIG_SMP - sparc64_multi_core = 1; -#endif - hp = mdesc_grab(); set_core_ids(hp); diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index 6b39125eb927..9a690d39c01b 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -555,9 +555,6 @@ static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg) cpu_data(cpuid).core_id = portid + 1; cpu_data(cpuid).proc_id = portid; -#ifdef CONFIG_SMP - sparc64_multi_core = 1; -#endif } else { cpu_data(cpuid).dcache_size = of_getintprop_default(dp, "dcache-size", 16 * 1024); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index b085311dcd0e..9781048161ab 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -53,8 +53,6 @@ #include "cpumap.h" -int sparc64_multi_core __read_mostly; - DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; cpumask_t cpu_core_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; -- cgit v1.2.3-55-g7522 From 09df7c4c8097ca4a11393b1edd4997d786daad52 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 10 Mar 2014 19:32:22 -0400 Subject: x86: Remove CONFIG_X86_OOSTORE This was an optimization that made memcpy type benchmarks a little faster on ancient (Circa 1998) IDT Winchip CPUs. In real-life workloads, it wasn't even noticable, and I doubt anyone is running benchmarks on 16 year old silicon any more. Given this code has likely seen very little use over the last decade, let's just remove it. Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- arch/x86/Kconfig.cpu | 4 - arch/x86/include/asm/barrier.h | 8 +- arch/x86/include/asm/io.h | 2 +- arch/x86/include/asm/spinlock.h | 5 +- arch/x86/kernel/cpu/centaur.c | 272 ---------------------------------------- arch/x86/um/asm/barrier.h | 4 - 6 files changed, 5 insertions(+), 290 deletions(-) (limited to 'arch') diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index c026cca5602c..f3aaf231b4e5 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -341,10 +341,6 @@ config X86_USE_3DNOW def_bool y depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML -config X86_OOSTORE - def_bool y - depends on (MWINCHIP3D || MWINCHIPC6) && MTRR - # # P6_NOPs are a relatively minor optimization that require a family >= # 6 processor, except that it is broken on certain VIA chips. diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 04a48903b2eb..69bbb4845020 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -85,11 +85,7 @@ #else # define smp_rmb() barrier() #endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif +#define smp_wmb() barrier() #define smp_read_barrier_depends() read_barrier_depends() #define set_mb(var, value) do { (void)xchg(&var, value); } while (0) #else /* !SMP */ @@ -100,7 +96,7 @@ #define set_mb(var, value) do { var = value; barrier(); } while (0) #endif /* SMP */ -#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE) +#if defined(CONFIG_X86_PPRO_FENCE) /* * For either of these options x86 doesn't have a strong TSO memory diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 34f69cb9350a..91d9c69a629e 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -237,7 +237,7 @@ memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) static inline void flush_write_buffers(void) { -#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE) +#if defined(CONFIG_X86_PPRO_FENCE) asm volatile("lock; addl $0,0(%%esp)": : :"memory"); #endif } diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index bf156ded74b5..0f62f5482d91 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -26,10 +26,9 @@ # define LOCK_PTR_REG "D" #endif -#if defined(CONFIG_X86_32) && \ - (defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)) +#if defined(CONFIG_X86_32) && (defined(CONFIG_X86_PPRO_FENCE)) /* - * On PPro SMP or if we are using OOSTORE, we use a locked operation to unlock + * On PPro SMP, we use a locked operation to unlock * (PPro errata 66, 92) */ # define UNLOCK_LOCK_PREFIX LOCK_PREFIX diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 8779edab684e..d8fba5c15fbd 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -8,236 +8,6 @@ #include "cpu.h" -#ifdef CONFIG_X86_OOSTORE - -static u32 power2(u32 x) -{ - u32 s = 1; - - while (s <= x) - s <<= 1; - - return s >>= 1; -} - - -/* - * Set up an actual MCR - */ -static void centaur_mcr_insert(int reg, u32 base, u32 size, int key) -{ - u32 lo, hi; - - hi = base & ~0xFFF; - lo = ~(size-1); /* Size is a power of 2 so this makes a mask */ - lo &= ~0xFFF; /* Remove the ctrl value bits */ - lo |= key; /* Attribute we wish to set */ - wrmsr(reg+MSR_IDT_MCR0, lo, hi); - mtrr_centaur_report_mcr(reg, lo, hi); /* Tell the mtrr driver */ -} - -/* - * Figure what we can cover with MCR's - * - * Shortcut: We know you can't put 4Gig of RAM on a winchip - */ -static u32 ramtop(void) -{ - u32 clip = 0xFFFFFFFFUL; - u32 top = 0; - int i; - - for (i = 0; i < e820.nr_map; i++) { - unsigned long start, end; - - if (e820.map[i].addr > 0xFFFFFFFFUL) - continue; - /* - * Don't MCR over reserved space. Ignore the ISA hole - * we frob around that catastrophe already - */ - if (e820.map[i].type == E820_RESERVED) { - if (e820.map[i].addr >= 0x100000UL && - e820.map[i].addr < clip) - clip = e820.map[i].addr; - continue; - } - start = e820.map[i].addr; - end = e820.map[i].addr + e820.map[i].size; - if (start >= end) - continue; - if (end > top) - top = end; - } - /* - * Everything below 'top' should be RAM except for the ISA hole. - * Because of the limited MCR's we want to map NV/ACPI into our - * MCR range for gunk in RAM - * - * Clip might cause us to MCR insufficient RAM but that is an - * acceptable failure mode and should only bite obscure boxes with - * a VESA hole at 15Mb - * - * The second case Clip sometimes kicks in is when the EBDA is marked - * as reserved. Again we fail safe with reasonable results - */ - if (top > clip) - top = clip; - - return top; -} - -/* - * Compute a set of MCR's to give maximum coverage - */ -static int centaur_mcr_compute(int nr, int key) -{ - u32 mem = ramtop(); - u32 root = power2(mem); - u32 base = root; - u32 top = root; - u32 floor = 0; - int ct = 0; - - while (ct < nr) { - u32 fspace = 0; - u32 high; - u32 low; - - /* - * Find the largest block we will fill going upwards - */ - high = power2(mem-top); - - /* - * Find the largest block we will fill going downwards - */ - low = base/2; - - /* - * Don't fill below 1Mb going downwards as there - * is an ISA hole in the way. - */ - if (base <= 1024*1024) - low = 0; - - /* - * See how much space we could cover by filling below - * the ISA hole - */ - - if (floor == 0) - fspace = 512*1024; - else if (floor == 512*1024) - fspace = 128*1024; - - /* And forget ROM space */ - - /* - * Now install the largest coverage we get - */ - if (fspace > high && fspace > low) { - centaur_mcr_insert(ct, floor, fspace, key); - floor += fspace; - } else if (high > low) { - centaur_mcr_insert(ct, top, high, key); - top += high; - } else if (low > 0) { - base -= low; - centaur_mcr_insert(ct, base, low, key); - } else - break; - ct++; - } - /* - * We loaded ct values. We now need to set the mask. The caller - * must do this bit. - */ - return ct; -} - -static void centaur_create_optimal_mcr(void) -{ - int used; - int i; - - /* - * Allocate up to 6 mcrs to mark as much of ram as possible - * as write combining and weak write ordered. - * - * To experiment with: Linux never uses stack operations for - * mmio spaces so we could globally enable stack operation wc - * - * Load the registers with type 31 - full write combining, all - * writes weakly ordered. - */ - used = centaur_mcr_compute(6, 31); - - /* - * Wipe unused MCRs - */ - for (i = used; i < 8; i++) - wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -static void winchip2_create_optimal_mcr(void) -{ - u32 lo, hi; - int used; - int i; - - /* - * Allocate up to 6 mcrs to mark as much of ram as possible - * as write combining, weak store ordered. - * - * Load the registers with type 25 - * 8 - weak write ordering - * 16 - weak read ordering - * 1 - write combining - */ - used = centaur_mcr_compute(6, 25); - - /* - * Mark the registers we are using. - */ - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - for (i = 0; i < used; i++) - lo |= 1<<(9+i); - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - - /* - * Wipe unused MCRs - */ - - for (i = used; i < 8; i++) - wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -/* - * Handle the MCR key on the Winchip 2. - */ -static void winchip2_unprotect_mcr(void) -{ - u32 lo, hi; - u32 key; - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - lo &= ~0x1C0; /* blank bits 8-6 */ - key = (lo>>17) & 7; - lo |= key<<6; /* replace with unlock key */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} - -static void winchip2_protect_mcr(void) -{ - u32 lo, hi; - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - lo &= ~0x1C0; /* blank bits 8-6 */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} -#endif /* CONFIG_X86_OOSTORE */ - #define ACE_PRESENT (1 << 6) #define ACE_ENABLED (1 << 7) #define ACE_FCR (1 << 28) /* MSR_VIA_FCR */ @@ -362,20 +132,6 @@ static void init_centaur(struct cpuinfo_x86 *c) fcr_clr = DPDC; printk(KERN_NOTICE "Disabling bugged TSC.\n"); clear_cpu_cap(c, X86_FEATURE_TSC); -#ifdef CONFIG_X86_OOSTORE - centaur_create_optimal_mcr(); - /* - * Enable: - * write combining on non-stack, non-string - * write combining on string, all types - * weak write ordering - * - * The C6 original lacks weak read order - * - * Note 0x120 is write only on Winchip 1 - */ - wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); -#endif break; case 8: switch (c->x86_mask) { @@ -392,40 +148,12 @@ static void init_centaur(struct cpuinfo_x86 *c) fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| E2MMX|EAMD3D; fcr_clr = DPDC; -#ifdef CONFIG_X86_OOSTORE - winchip2_unprotect_mcr(); - winchip2_create_optimal_mcr(); - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - /* - * Enable: - * write combining on non-stack, non-string - * write combining on string, all types - * weak write ordering - */ - lo |= 31; - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - winchip2_protect_mcr(); -#endif break; case 9: name = "3"; fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK| E2MMX|EAMD3D; fcr_clr = DPDC; -#ifdef CONFIG_X86_OOSTORE - winchip2_unprotect_mcr(); - winchip2_create_optimal_mcr(); - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - /* - * Enable: - * write combining on non-stack, non-string - * write combining on string, all types - * weak write ordering - */ - lo |= 31; - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - winchip2_protect_mcr(); -#endif break; default: name = "??"; diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h index 7d01b8c56c00..cc04e67bfd05 100644 --- a/arch/x86/um/asm/barrier.h +++ b/arch/x86/um/asm/barrier.h @@ -40,11 +40,7 @@ #define smp_rmb() barrier() #endif /* CONFIG_X86_PPRO_FENCE */ -#ifdef CONFIG_X86_OOSTORE -#define smp_wmb() wmb() -#else /* CONFIG_X86_OOSTORE */ #define smp_wmb() barrier() -#endif /* CONFIG_X86_OOSTORE */ #define smp_read_barrier_depends() read_barrier_depends() #define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -- cgit v1.2.3-55-g7522 From 731bd6a93a6e9172094a2322bd0ee964bb1f4d63 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Sun, 2 Feb 2014 22:56:23 -0800 Subject: x86, fpu: Check tsk_used_math() in kernel_fpu_end() for eager FPU For non-eager fpu mode, thread's fpu state is allocated during the first fpu usage (in the context of device not available exception). This (math_state_restore()) can be a blocking call and hence we enable interrupts (which were originally disabled when the exception happened), allocate memory and disable interrupts etc. But the eager-fpu mode, call's the same math_state_restore() from kernel_fpu_end(). The assumption being that tsk_used_math() is always set for the eager-fpu mode and thus avoid the code path of enabling interrupts, allocating fpu state using blocking call and disable interrupts etc. But the below issue was noticed by Maarten Baert, Nate Eldredge and few others: If a user process dumps core on an ecrypt fs while aesni-intel is loaded, we get a BUG() in __find_get_block() complaining that it was called with interrupts disabled; then all further accesses to our ecrypt fs hang and we have to reboot. The aesni-intel code (encrypting the core file that we are writing) needs the FPU and quite properly wraps its code in kernel_fpu_{begin,end}(), the latter of which calls math_state_restore(). So after kernel_fpu_end(), interrupts may be disabled, which nobody seems to expect, and they stay that way until we eventually get to __find_get_block() which barfs. For eager fpu, most the time, tsk_used_math() is true. At few instances during thread exit, signal return handling etc, tsk_used_math() might be false. In kernel_fpu_end(), for eager-fpu, call math_state_restore() only if tsk_used_math() is set. Otherwise, don't bother. Kernel code path which cleared tsk_used_math() knows what needs to be done with the fpu state. Reported-by: Maarten Baert Reported-by: Nate Eldredge Suggested-by: Linus Torvalds Signed-off-by: Suresh Siddha Link: http://lkml.kernel.org/r/1391410583.3801.6.camel@europa Cc: George Spelvin Signed-off-by: H. Peter Anvin --- arch/x86/kernel/i387.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index e8368c6dd2a2..d5dd80814419 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -86,10 +86,19 @@ EXPORT_SYMBOL(__kernel_fpu_begin); void __kernel_fpu_end(void) { - if (use_eager_fpu()) - math_state_restore(); - else + if (use_eager_fpu()) { + /* + * For eager fpu, most the time, tsk_used_math() is true. + * Restore the user math as we are done with the kernel usage. + * At few instances during thread exit, signal handling etc, + * tsk_used_math() is false. Those few places will take proper + * actions, so we don't need to restore the math here. + */ + if (likely(tsk_used_math(current))) + math_state_restore(); + } else { stts(); + } } EXPORT_SYMBOL(__kernel_fpu_end); -- cgit v1.2.3-55-g7522 From f656d46bbb2d3ecdb71c998ccf657dccea8d19a9 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 10 Mar 2014 15:37:18 +0100 Subject: ARM: at91: fix network interface ordering for sama5d36 On the newly introduced sama5d36, Gigabit and 10/100 Ethernet network interfaces are probed in a different order than for the sama5d35. Moreover, users are accustomed to this order in bootloaders and backports for older kernel revisions. So this patch switches DT node order as it is done for the other dual-Ethernet sama5d3 SoC. Better interface numbering which does not depend on DT node order is being developed for stronger interface identification. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre Signed-off-by: Olof Johansson --- arch/arm/boot/dts/sama5d36.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sama5d36.dtsi b/arch/arm/boot/dts/sama5d36.dtsi index 6c31c26e6cc0..db58cad6acd3 100644 --- a/arch/arm/boot/dts/sama5d36.dtsi +++ b/arch/arm/boot/dts/sama5d36.dtsi @@ -8,8 +8,8 @@ */ #include "sama5d3.dtsi" #include "sama5d3_can.dtsi" -#include "sama5d3_emac.dtsi" #include "sama5d3_gmac.dtsi" +#include "sama5d3_emac.dtsi" #include "sama5d3_lcd.dtsi" #include "sama5d3_mci2.dtsi" #include "sama5d3_tcb1.dtsi" -- cgit v1.2.3-55-g7522 From 9affbd2458eca452e63b108e1a6258cf370f6eb9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 21 Jan 2014 15:04:14 +0100 Subject: ARM: u300: move timer driver to clocksource Move the U300 timer driver down to the clocksource driver subsystem and keep arch/arm clean. Cc: Daniel Lezcano Cc: Thomas Gleixner Signed-off-by: Linus Walleij Signed-off-by: Daniel Lezcano --- MAINTAINERS | 1 + arch/arm/mach-u300/Makefile | 2 +- arch/arm/mach-u300/timer.c | 451 --------------------------------------- drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-u300.c | 447 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 450 insertions(+), 452 deletions(-) delete mode 100644 arch/arm/mach-u300/timer.c create mode 100644 drivers/clocksource/timer-u300.c (limited to 'arch') diff --git a/MAINTAINERS b/MAINTAINERS index b2cf5cfb4d29..edd6139c7c7c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1319,6 +1319,7 @@ M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: arch/arm/mach-u300/ +F: drivers/clocksource/timer-u300.c F: drivers/i2c/busses/i2c-stu300.c F: drivers/rtc/rtc-coh901331.c F: drivers/watchdog/coh901327_wdt.c diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 0f362b64fb87..3ec74ac95bc1 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel, U300 machine. # -obj-y := core.o timer.o +obj-y := core.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c deleted file mode 100644 index fe08fd34c0ce..000000000000 --- a/arch/arm/mach-u300/timer.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * - * arch/arm/mach-u300/timer.c - * - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Timer COH 901 328, runs the OS timer interrupt. - * Author: Linus Walleij - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Generic stuff */ -#include -#include - -/* - * APP side special timer registers - * This timer contains four timers which can fire an interrupt each. - * OS (operating system) timer @ 32768 Hz - * DD (device driver) timer @ 1 kHz - * GP1 (general purpose 1) timer @ 1MHz - * GP2 (general purpose 2) timer @ 1MHz - */ - -/* Reset OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_ROST (0x0000) -#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000) -/* Enable OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_EOST (0x0004) -#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000) -/* Disable OS Timer 32bit (-/W) */ -#define U300_TIMER_APP_DOST (0x0008) -#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000) -/* OS Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SOSTM (0x000c) -#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001) -/* OS Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_OSTS (0x0010) -#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020) -#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080) -/* OS Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_OSTCC (0x0014) -/* OS Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_OSTTC (0x0018) -/* OS Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_OSTIE (0x001c) -#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001) -/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_OSTIA (0x0020) -#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080) - -/* Reset DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_RDDT (0x0040) -#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000) -/* Enable DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_EDDT (0x0044) -#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000) -/* Disable DD Timer 32bit (-/W) */ -#define U300_TIMER_APP_DDDT (0x0048) -#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000) -/* DD Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SDDTM (0x004c) -#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001) -/* DD Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_DDTS (0x0050) -#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020) -#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080) -/* DD Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_DDTCC (0x0054) -/* DD Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_DDTTC (0x0058) -/* DD Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_DDTIE (0x005c) -#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001) -/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_DDTIA (0x0060) -#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080) - -/* Reset GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_RGPT1 (0x0080) -#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000) -/* Enable GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_EGPT1 (0x0084) -#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000) -/* Disable GP1 Timer 32bit (-/W) */ -#define U300_TIMER_APP_DGPT1 (0x0088) -#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000) -/* GP1 Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SGPT1M (0x008c) -#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001) -/* GP1 Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT1S (0x0090) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020) -#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080) -/* GP1 Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT1CC (0x0094) -/* GP1 Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_GPT1TC (0x0098) -/* GP1 Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT1IE (0x009c) -#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001) -/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT1IA (0x00a0) -#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080) - -/* Reset GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_RGPT2 (0x00c0) -#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000) -/* Enable GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_EGPT2 (0x00c4) -#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000) -/* Disable GP2 Timer 32bit (-/W) */ -#define U300_TIMER_APP_DGPT2 (0x00c8) -#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000) -/* GP2 Timer Mode Register 32bit (-/W) */ -#define U300_TIMER_APP_SGPT2M (0x00cc) -#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001) -/* GP2 Timer Status Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT2S (0x00d0) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001) -#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002) -#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010) -#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020) -#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000) -#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020) -#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040) -#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080) -/* GP2 Timer Current Count Register 32bit (R/-) */ -#define U300_TIMER_APP_GPT2CC (0x00d4) -/* GP2 Timer Terminal Count Register 32bit (R/W) */ -#define U300_TIMER_APP_GPT2TC (0x00d8) -/* GP2 Timer Interrupt Enable Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT2IE (0x00dc) -#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000) -#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001) -/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */ -#define U300_TIMER_APP_GPT2IA (0x00e0) -#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080) - -/* Clock request control register - all four timers */ -#define U300_TIMER_APP_CRC (0x100) -#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001) - -static void __iomem *u300_timer_base; - -struct u300_clockevent_data { - struct clock_event_device cevd; - unsigned ticks_per_jiffy; -}; - -/* - * The u300_set_mode() function is always called first, if we - * have oneshot timer active, the oneshot scheduling function - * u300_set_next_event() is called immediately after. - */ -static void u300_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - struct u300_clockevent_data *cevdata = - container_of(evt, struct u300_clockevent_data, cevd); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* - * Set the periodic mode to a certain number of ticks per - * jiffy. - */ - writel(cevdata->ticks_per_jiffy, - u300_timer_base + U300_TIMER_APP_GPT1TC); - /* - * Set continuous mode, so the timer keeps triggering - * interrupts. - */ - writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable timer interrupts */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Then enable the OS timer again */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - break; - case CLOCK_EVT_MODE_ONESHOT: - /* Just break; here? */ - /* - * The actual event will be programmed by the next event hook, - * so we just set a dummy value somewhere at the end of the - * universe here. - */ - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* - * Expire far in the future, u300_set_next_event() will be - * called soon... - */ - writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); - /* We run one shot per tick here! */ - writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable interrupts for this timer */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Enable timer */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - /* Disable interrupts on GP1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - break; - case CLOCK_EVT_MODE_RESUME: - /* Ignore this call */ - break; - } -} - -/* - * The app timer in one shot mode obviously has to be reprogrammed - * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace - * the interrupt disable + timer disable commands with a reset command, - * it will fail miserably. Apparently (and I found this the hard way) - * the timer is very sensitive to the instruction order, though you don't - * get that impression from the data sheet. - */ -static int u300_set_next_event(unsigned long cycles, - struct clock_event_device *evt) - -{ - /* Disable interrupts on GPT1 */ - writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Disable GP1 while we're reprogramming it. */ - writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DGPT1); - /* Reset the General Purpose timer 1. */ - writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT1); - /* IRQ in n * cycles */ - writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC); - /* - * We run one shot per tick here! (This is necessary to reconfigure, - * the timer will tilt if you don't!) - */ - writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, - u300_timer_base + U300_TIMER_APP_SGPT1M); - /* Enable timer interrupts */ - writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, - u300_timer_base + U300_TIMER_APP_GPT1IE); - /* Then enable the OS timer again */ - writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT1); - return 0; -} - -static struct u300_clockevent_data u300_clockevent_data = { - /* Use general purpose timer 1 as clock event */ - .cevd = { - .name = "GPT1", - /* Reasonably fast and accurate clock event */ - .rating = 300, - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = u300_set_next_event, - .set_mode = u300_set_mode, - }, -}; - -/* Clock event timer interrupt handler */ -static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &u300_clockevent_data.cevd; - /* ACK/Clear timer IRQ for the APP GPT1 Timer */ - - writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, - u300_timer_base + U300_TIMER_APP_GPT1IA); - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static struct irqaction u300_timer_irq = { - .name = "U300 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = u300_timer_interrupt, -}; - -/* - * Override the global weak sched_clock symbol with this - * local implementation which uses the clocksource to get some - * better resolution when scheduling the kernel. We accept that - * this wraps around for now, since it is just a relative time - * stamp. (Inspired by OMAP implementation.) - */ - -static u64 notrace u300_read_sched_clock(void) -{ - return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); -} - -static unsigned long u300_read_current_timer(void) -{ - return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); -} - -static struct delay_timer u300_delay_timer; - -/* - * This sets up the system timers, clock source and clock event. - */ -static void __init u300_timer_init_of(struct device_node *np) -{ - unsigned int irq; - struct clk *clk; - unsigned long rate; - - u300_timer_base = of_iomap(np, 0); - if (!u300_timer_base) - panic("could not ioremap system timer\n"); - - /* Get the IRQ for the GP1 timer */ - irq = irq_of_parse_and_map(np, 2); - if (!irq) - panic("no IRQ for system timer\n"); - - pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); - - /* Clock the interrupt controller */ - clk = of_clk_get(np, 0); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - rate = clk_get_rate(clk); - - u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); - - sched_clock_register(u300_read_sched_clock, 32, rate); - - u300_delay_timer.read_current_timer = &u300_read_current_timer; - u300_delay_timer.freq = rate; - register_current_timer_delay(&u300_delay_timer); - - /* - * Disable the "OS" and "DD" timers - these are designed for Symbian! - * Example usage in cnh1601578 cpu subsystem pd_timer_app.c - */ - writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, - u300_timer_base + U300_TIMER_APP_CRC); - writel(U300_TIMER_APP_ROST_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_ROST); - writel(U300_TIMER_APP_DOST_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DOST); - writel(U300_TIMER_APP_RDDT_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RDDT); - writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, - u300_timer_base + U300_TIMER_APP_DDDT); - - /* Reset the General Purpose timer 1. */ - writel(U300_TIMER_APP_RGPT1_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT1); - - /* Set up the IRQ handler */ - setup_irq(irq, &u300_timer_irq); - - /* Reset the General Purpose timer 2 */ - writel(U300_TIMER_APP_RGPT2_TIMER_RESET, - u300_timer_base + U300_TIMER_APP_RGPT2); - /* Set this timer to run around forever */ - writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC); - /* Set continuous mode so it wraps around */ - writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, - u300_timer_base + U300_TIMER_APP_SGPT2M); - /* Disable timer interrupts */ - writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, - u300_timer_base + U300_TIMER_APP_GPT2IE); - /* Then enable the GP2 timer to use as a free running us counter */ - writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, - u300_timer_base + U300_TIMER_APP_EGPT2); - - /* Use general purpose timer 2 as clock source */ - if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, - "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) - pr_err("timer: failed to initialize U300 clock source\n"); - - /* Configure and register the clockevent */ - clockevents_config_and_register(&u300_clockevent_data.cevd, rate, - 1, 0xffffffff); - - /* - * TODO: init and register the rest of the timers too, they can be - * used by hrtimers! - */ -} - -CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", - u300_timer_init_of); diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index c7ca50a9c232..01e5435315ca 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_ARCH_MARCO) += timer-marco.o obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o obj-$(CONFIG_ARCH_MXS) += mxs_timer.o obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o +obj-$(CONFIG_ARCH_U300) += timer-u300.o obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c new file mode 100644 index 000000000000..e63d469661fd --- /dev/null +++ b/drivers/clocksource/timer-u300.c @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Timer COH 901 328, runs the OS timer interrupt. + * Author: Linus Walleij + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Generic stuff */ +#include +#include + +/* + * APP side special timer registers + * This timer contains four timers which can fire an interrupt each. + * OS (operating system) timer @ 32768 Hz + * DD (device driver) timer @ 1 kHz + * GP1 (general purpose 1) timer @ 1MHz + * GP2 (general purpose 2) timer @ 1MHz + */ + +/* Reset OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_ROST (0x0000) +#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000) +/* Enable OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_EOST (0x0004) +#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000) +/* Disable OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_DOST (0x0008) +#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000) +/* OS Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SOSTM (0x000c) +#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001) +/* OS Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_OSTS (0x0010) +#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020) +#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080) +/* OS Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_OSTCC (0x0014) +/* OS Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_OSTTC (0x0018) +/* OS Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_OSTIE (0x001c) +#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001) +/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_OSTIA (0x0020) +#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080) + +/* Reset DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_RDDT (0x0040) +#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000) +/* Enable DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_EDDT (0x0044) +#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000) +/* Disable DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_DDDT (0x0048) +#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000) +/* DD Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SDDTM (0x004c) +#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001) +/* DD Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_DDTS (0x0050) +#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020) +#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080) +/* DD Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_DDTCC (0x0054) +/* DD Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_DDTTC (0x0058) +/* DD Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_DDTIE (0x005c) +#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001) +/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_DDTIA (0x0060) +#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080) + +/* Reset GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_RGPT1 (0x0080) +#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000) +/* Enable GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_EGPT1 (0x0084) +#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000) +/* Disable GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_DGPT1 (0x0088) +#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000) +/* GP1 Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SGPT1M (0x008c) +#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001) +/* GP1 Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT1S (0x0090) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020) +#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080) +/* GP1 Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT1CC (0x0094) +/* GP1 Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_GPT1TC (0x0098) +/* GP1 Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT1IE (0x009c) +#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001) +/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT1IA (0x00a0) +#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080) + +/* Reset GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_RGPT2 (0x00c0) +#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000) +/* Enable GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_EGPT2 (0x00c4) +#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000) +/* Disable GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_DGPT2 (0x00c8) +#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000) +/* GP2 Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SGPT2M (0x00cc) +#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001) +/* GP2 Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT2S (0x00d0) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020) +#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080) +/* GP2 Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT2CC (0x00d4) +/* GP2 Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_GPT2TC (0x00d8) +/* GP2 Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT2IE (0x00dc) +#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001) +/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT2IA (0x00e0) +#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080) + +/* Clock request control register - all four timers */ +#define U300_TIMER_APP_CRC (0x100) +#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001) + +static void __iomem *u300_timer_base; + +struct u300_clockevent_data { + struct clock_event_device cevd; + unsigned ticks_per_jiffy; +}; + +/* + * The u300_set_mode() function is always called first, if we + * have oneshot timer active, the oneshot scheduling function + * u300_set_next_event() is called immediately after. + */ +static void u300_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + struct u300_clockevent_data *cevdata = + container_of(evt, struct u300_clockevent_data, cevd); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DGPT1); + /* + * Set the periodic mode to a certain number of ticks per + * jiffy. + */ + writel(cevdata->ticks_per_jiffy, + u300_timer_base + U300_TIMER_APP_GPT1TC); + /* + * Set continuous mode, so the timer keeps triggering + * interrupts. + */ + writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, + u300_timer_base + U300_TIMER_APP_SGPT1M); + /* Enable timer interrupts */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Then enable the OS timer again */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + u300_timer_base + U300_TIMER_APP_EGPT1); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* Just break; here? */ + /* + * The actual event will be programmed by the next event hook, + * so we just set a dummy value somewhere at the end of the + * universe here. + */ + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DGPT1); + /* + * Expire far in the future, u300_set_next_event() will be + * called soon... + */ + writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC); + /* We run one shot per tick here! */ + writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, + u300_timer_base + U300_TIMER_APP_SGPT1M); + /* Enable interrupts for this timer */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Enable timer */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + u300_timer_base + U300_TIMER_APP_EGPT1); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + /* Disable interrupts on GP1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Disable GP1 */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DGPT1); + break; + case CLOCK_EVT_MODE_RESUME: + /* Ignore this call */ + break; + } +} + +/* + * The app timer in one shot mode obviously has to be reprogrammed + * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace + * the interrupt disable + timer disable commands with a reset command, + * it will fail miserably. Apparently (and I found this the hard way) + * the timer is very sensitive to the instruction order, though you don't + * get that impression from the data sheet. + */ +static int u300_set_next_event(unsigned long cycles, + struct clock_event_device *evt) + +{ + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DGPT1); + /* Reset the General Purpose timer 1. */ + writel(U300_TIMER_APP_RGPT1_TIMER_RESET, + u300_timer_base + U300_TIMER_APP_RGPT1); + /* IRQ in n * cycles */ + writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC); + /* + * We run one shot per tick here! (This is necessary to reconfigure, + * the timer will tilt if you don't!) + */ + writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, + u300_timer_base + U300_TIMER_APP_SGPT1M); + /* Enable timer interrupts */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + u300_timer_base + U300_TIMER_APP_GPT1IE); + /* Then enable the OS timer again */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + u300_timer_base + U300_TIMER_APP_EGPT1); + return 0; +} + +static struct u300_clockevent_data u300_clockevent_data = { + /* Use general purpose timer 1 as clock event */ + .cevd = { + .name = "GPT1", + /* Reasonably fast and accurate clock event */ + .rating = 300, + .features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = u300_set_next_event, + .set_mode = u300_set_mode, + }, +}; + +/* Clock event timer interrupt handler */ +static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &u300_clockevent_data.cevd; + /* ACK/Clear timer IRQ for the APP GPT1 Timer */ + + writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, + u300_timer_base + U300_TIMER_APP_GPT1IA); + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction u300_timer_irq = { + .name = "U300 Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = u300_timer_interrupt, +}; + +/* + * Override the global weak sched_clock symbol with this + * local implementation which uses the clocksource to get some + * better resolution when scheduling the kernel. We accept that + * this wraps around for now, since it is just a relative time + * stamp. (Inspired by OMAP implementation.) + */ + +static u64 notrace u300_read_sched_clock(void) +{ + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); +} + +static unsigned long u300_read_current_timer(void) +{ + return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); +} + +static struct delay_timer u300_delay_timer; + +/* + * This sets up the system timers, clock source and clock event. + */ +static void __init u300_timer_init_of(struct device_node *np) +{ + unsigned int irq; + struct clk *clk; + unsigned long rate; + + u300_timer_base = of_iomap(np, 0); + if (!u300_timer_base) + panic("could not ioremap system timer\n"); + + /* Get the IRQ for the GP1 timer */ + irq = irq_of_parse_and_map(np, 2); + if (!irq) + panic("no IRQ for system timer\n"); + + pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq); + + /* Clock the interrupt controller */ + clk = of_clk_get(np, 0); + BUG_ON(IS_ERR(clk)); + clk_prepare_enable(clk); + rate = clk_get_rate(clk); + + u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); + + sched_clock_register(u300_read_sched_clock, 32, rate); + + u300_delay_timer.read_current_timer = &u300_read_current_timer; + u300_delay_timer.freq = rate; + register_current_timer_delay(&u300_delay_timer); + + /* + * Disable the "OS" and "DD" timers - these are designed for Symbian! + * Example usage in cnh1601578 cpu subsystem pd_timer_app.c + */ + writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, + u300_timer_base + U300_TIMER_APP_CRC); + writel(U300_TIMER_APP_ROST_TIMER_RESET, + u300_timer_base + U300_TIMER_APP_ROST); + writel(U300_TIMER_APP_DOST_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DOST); + writel(U300_TIMER_APP_RDDT_TIMER_RESET, + u300_timer_base + U300_TIMER_APP_RDDT); + writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, + u300_timer_base + U300_TIMER_APP_DDDT); + + /* Reset the General Purpose timer 1. */ + writel(U300_TIMER_APP_RGPT1_TIMER_RESET, + u300_timer_base + U300_TIMER_APP_RGPT1); + + /* Set up the IRQ handler */ + setup_irq(irq, &u300_timer_irq); + + /* Reset the General Purpose timer 2 */ + writel(U300_TIMER_APP_RGPT2_TIMER_RESET, + u300_timer_base + U300_TIMER_APP_RGPT2); + /* Set this timer to run around forever */ + writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC); + /* Set continuous mode so it wraps around */ + writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, + u300_timer_base + U300_TIMER_APP_SGPT2M); + /* Disable timer interrupts */ + writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, + u300_timer_base + U300_TIMER_APP_GPT2IE); + /* Then enable the GP2 timer to use as a free running us counter */ + writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, + u300_timer_base + U300_TIMER_APP_EGPT2); + + /* Use general purpose timer 2 as clock source */ + if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC, + "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) + pr_err("timer: failed to initialize U300 clock source\n"); + + /* Configure and register the clockevent */ + clockevents_config_and_register(&u300_clockevent_data.cevd, rate, + 1, 0xffffffff); + + /* + * TODO: init and register the rest of the timers too, they can be + * used by hrtimers! + */ +} + +CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer", + u300_timer_init_of); -- cgit v1.2.3-55-g7522 From b4f26440d932d022e109fb7a0518ae291e72f399 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 6 Feb 2014 10:40:32 +0100 Subject: ARM: sunxi: dt: Convert to the new clocksource compatible Switch the device tree to the new compatibles introduced in the timer driver to have a common pattern accross all Allwinner SoCs. Signed-off-by: Maxime Ripard Signed-off-by: Daniel Lezcano --- arch/arm/boot/dts/sun4i-a10.dtsi | 2 +- arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +- arch/arm/boot/dts/sun5i-a13.dtsi | 2 +- arch/arm/boot/dts/sun6i-a31.dtsi | 2 +- arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 040bb0eba152..dd64cc0dbef3 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -403,7 +403,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; interrupts = <22>; clocks = <&osc24M>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index ea16054857a4..9cee110bd894 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -366,7 +366,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; interrupts = <22>; clocks = <&osc24M>; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index 320335abfccd..f5cba632fd95 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -329,7 +329,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; interrupts = <22>; clocks = <&osc24M>; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 5256ad9be52c..996fff54c8a2 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -231,7 +231,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0xa0>; interrupts = <0 18 4>, <0 19 4>, diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 119f066f0d98..4bc5c6f4cada 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -435,7 +435,7 @@ }; timer@01c20c00 { - compatible = "allwinner,sun4i-timer"; + compatible = "allwinner,sun4i-a10-timer"; reg = <0x01c20c00 0x90>; interrupts = <0 22 4>, <0 23 4>, -- cgit v1.2.3-55-g7522 From aeb8fb7910fc7344d0ee0c9306eb45f11327c600 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 20 Feb 2014 12:54:46 +0100 Subject: ARM: shmobile: Remove CMT, TMU and STI Kconfig entries Now when drivers/clocksource/Kconfig has been updated with entires for CMT, TMU, MTU2, and STI it is safe to remove these from mach-shmobile. Also select timers per SoC via SYS_SUPPORTS_xxx. Signed-off-by: Magnus Damm Acked-by: John Stultz Signed-off-by: Wolfram Sang Signed-off-by: Daniel Lezcano --- arch/arm/mach-shmobile/Kconfig | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 338640631e08..c1a9538fb6bb 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -24,17 +24,21 @@ comment "Renesas ARM SoCs System Type" config ARCH_EMEV2 bool "Emma Mobile EV2" + select SYS_SUPPORTS_EM_STI config ARCH_R7S72100 bool "RZ/A1H (R7S72100)" + select SYS_SUPPORTS_SH_MTU2 config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT config ARCH_R8A7791 bool "R-Car M2 (R8A77910)" select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT comment "Renesas ARM SoCs Board Type" @@ -68,6 +72,8 @@ config ARCH_SH7372 select ARM_CPU_SUSPEND if PM || CPU_IDLE select CPU_V7 select SH_CLK_CPG + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_SH73A0 bool "SH-Mobile AG5 (R8A73A00)" @@ -77,6 +83,8 @@ config ARCH_SH73A0 select I2C select SH_CLK_CPG select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A73A4 bool "R-Mobile APE6 (R8A73A40)" @@ -87,6 +95,8 @@ config ARCH_R8A73A4 select RENESAS_IRQC select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7740 bool "R-Mobile A1 (R8A77400)" @@ -95,6 +105,8 @@ config ARCH_R8A7740 select CPU_V7 select SH_CLK_CPG select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7778 bool "R-Car M1A (R8A77781)" @@ -104,6 +116,7 @@ config ARCH_R8A7778 select ARM_GIC select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_OHCI + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7779 bool "R-Car H1 (R8A77790)" @@ -114,6 +127,7 @@ config ARCH_R8A7779 select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_OHCI select RENESAS_INTC_IRQPIN + select SYS_SUPPORTS_SH_TMU config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" @@ -123,6 +137,7 @@ config ARCH_R8A7790 select MIGHT_HAVE_PCI select SH_CLK_CPG select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT config ARCH_R8A7791 bool "R-Car M2 (R8A77910)" @@ -132,6 +147,7 @@ config ARCH_R8A7791 select MIGHT_HAVE_PCI select SH_CLK_CPG select RENESAS_IRQC + select SYS_SUPPORTS_SH_CMT config ARCH_EMEV2 bool "Emma Mobile EV2" @@ -141,6 +157,7 @@ config ARCH_EMEV2 select MIGHT_HAVE_PCI select USE_OF select AUTO_ZRELADDR + select SYS_SUPPORTS_EM_STI config ARCH_R7S72100 bool "RZ/A1H (R7S72100)" @@ -148,6 +165,7 @@ config ARCH_R7S72100 select ARM_GIC select CPU_V7 select SH_CLK_CPG + select SYS_SUPPORTS_SH_MTU2 comment "Renesas ARM SoCs Board Type" @@ -321,24 +339,6 @@ config SHMOBILE_TIMER_HZ want to select a HZ value such as 128 that can evenly divide RCLK. A HZ value that does not divide evenly may cause timer drift. -config SH_TIMER_CMT - bool "CMT timer driver" - default y - help - This enables build of the CMT timer driver. - -config SH_TIMER_TMU - bool "TMU timer driver" - default y - help - This enables build of the TMU timer driver. - -config EM_TIMER_STI - bool "STI timer driver" - default y - help - This enables build of the STI timer driver. - endmenu endif -- cgit v1.2.3-55-g7522 From fbfa893458edb0daf18a0add33d3341b1e9f6d44 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 20 Feb 2014 12:54:47 +0100 Subject: sh: Remove Kconfig entries for TMU, CMT and MTU2 Now when drivers/clocksource/Kconfig has been updated with entires for CMT, TMU and MTU2 it is safe to remove these from SH. Signed-off-by: Magnus Damm Acked-by: John Stultz Signed-off-by: Wolfram Sang Signed-off-by: Daniel Lezcano --- arch/sh/Kconfig | 76 +++++++++++++++++---------------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 6357710753d5..364d204298fa 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -123,15 +123,6 @@ config SYS_SUPPORTS_NUMA config SYS_SUPPORTS_PCI bool -config SYS_SUPPORTS_CMT - bool - -config SYS_SUPPORTS_MTU2 - bool - -config SYS_SUPPORTS_TMU - bool - config STACKTRACE_SUPPORT def_bool y @@ -191,14 +182,14 @@ config CPU_SH3 bool select CPU_HAS_INTEVT select CPU_HAS_SR_RB - select SYS_SUPPORTS_TMU + select SYS_SUPPORTS_SH_TMU config CPU_SH4 bool select CPU_HAS_INTEVT select CPU_HAS_SR_RB select CPU_HAS_FPU if !CPU_SH4AL_DSP - select SYS_SUPPORTS_TMU + select SYS_SUPPORTS_SH_TMU select SYS_SUPPORTS_HUGETLBFS if MMU config CPU_SH4A @@ -213,7 +204,7 @@ config CPU_SH4AL_DSP config CPU_SH5 bool select CPU_HAS_FPU - select SYS_SUPPORTS_TMU + select SYS_SUPPORTS_SH_TMU select SYS_SUPPORTS_HUGETLBFS if MMU config CPU_SHX2 @@ -250,7 +241,7 @@ choice config CPU_SUBTYPE_SH7619 bool "Support SH7619 processor" select CPU_SH2 - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT # SH-2A Processor Support @@ -258,50 +249,50 @@ config CPU_SUBTYPE_SH7201 bool "Support SH7201 processor" select CPU_SH2A select CPU_HAS_FPU - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_MTU2 config CPU_SUBTYPE_SH7203 bool "Support SH7203 processor" select CPU_SH2A select CPU_HAS_FPU - select SYS_SUPPORTS_CMT - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_MTU2 select ARCH_WANT_OPTIONAL_GPIOLIB select PINCTRL config CPU_SUBTYPE_SH7206 bool "Support SH7206 processor" select CPU_SH2A - select SYS_SUPPORTS_CMT - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_MTU2 config CPU_SUBTYPE_SH7263 bool "Support SH7263 processor" select CPU_SH2A select CPU_HAS_FPU - select SYS_SUPPORTS_CMT - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_MTU2 config CPU_SUBTYPE_SH7264 bool "Support SH7264 processor" select CPU_SH2A select CPU_HAS_FPU - select SYS_SUPPORTS_CMT - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_MTU2 select PINCTRL config CPU_SUBTYPE_SH7269 bool "Support SH7269 processor" select CPU_SH2A select CPU_HAS_FPU - select SYS_SUPPORTS_CMT - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_CMT + select SYS_SUPPORTS_SH_MTU2 select PINCTRL config CPU_SUBTYPE_MXG bool "Support MX-G processor" select CPU_SH2A - select SYS_SUPPORTS_MTU2 + select SYS_SUPPORTS_SH_MTU2 help Select MX-G if running on an R8A03022BG part. @@ -354,7 +345,7 @@ config CPU_SUBTYPE_SH7720 bool "Support SH7720 processor" select CPU_SH3 select CPU_HAS_DSP - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT select ARCH_WANT_OPTIONAL_GPIOLIB select USB_ARCH_HAS_OHCI select USB_OHCI_SH if USB_OHCI_HCD @@ -366,7 +357,7 @@ config CPU_SUBTYPE_SH7721 bool "Support SH7721 processor" select CPU_SH3 select CPU_HAS_DSP - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT select USB_ARCH_HAS_OHCI select USB_OHCI_SH if USB_OHCI_HCD help @@ -422,7 +413,7 @@ config CPU_SUBTYPE_SH7723 select CPU_SHX2 select ARCH_SHMOBILE select ARCH_SPARSEMEM_ENABLE - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT select ARCH_WANT_OPTIONAL_GPIOLIB select PINCTRL help @@ -434,7 +425,7 @@ config CPU_SUBTYPE_SH7724 select CPU_SHX2 select ARCH_SHMOBILE select ARCH_SPARSEMEM_ENABLE - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT select ARCH_WANT_OPTIONAL_GPIOLIB select PINCTRL help @@ -514,7 +505,7 @@ config CPU_SUBTYPE_SH7343 bool "Support SH7343 processor" select CPU_SH4AL_DSP select ARCH_SHMOBILE - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT config CPU_SUBTYPE_SH7722 bool "Support SH7722 processor" @@ -523,7 +514,7 @@ config CPU_SUBTYPE_SH7722 select ARCH_SHMOBILE select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT select ARCH_WANT_OPTIONAL_GPIOLIB select PINCTRL @@ -534,7 +525,7 @@ config CPU_SUBTYPE_SH7366 select ARCH_SHMOBILE select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_CMT + select SYS_SUPPORTS_SH_CMT endchoice @@ -567,27 +558,6 @@ source "arch/sh/boards/Kconfig" menu "Timer and clock configuration" -config SH_TIMER_TMU - bool "TMU timer driver" - depends on SYS_SUPPORTS_TMU - default y - help - This enables the build of the TMU timer driver. - -config SH_TIMER_CMT - bool "CMT timer driver" - depends on SYS_SUPPORTS_CMT - default y - help - This enables build of the CMT timer driver. - -config SH_TIMER_MTU2 - bool "MTU2 timer driver" - depends on SYS_SUPPORTS_MTU2 - default y - help - This enables build of the MTU2 timer driver. - config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" depends on SH_CLK_CPG_LEGACY -- cgit v1.2.3-55-g7522 From 61f1fc7e9258a169ac8afb5ddf657a181e60d052 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Wed, 19 Feb 2014 15:14:43 -0800 Subject: arm: zynq: Don't use arm_global_timer with cpufreq The timer frequency of the arm_global_timer depends on the CPU frequency. With cpufreq altering that frequency the arm_global_timer does not maintain a stable time base. Therefore don't enable that timer in case cpufreq is enabled. Cc: Russell King Signed-off-by: Soren Brinkmann Signed-off-by: Daniel Lezcano Acked-by: Michal Simek --- arch/arm/mach-zynq/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index 6b04260aa142..f84fab14f0b7 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -13,6 +13,6 @@ config ARCH_ZYNQ select HAVE_SMP select SPARSE_IRQ select CADENCE_TTC_TIMER - select ARM_GLOBAL_TIMER + select ARM_GLOBAL_TIMER if !CPU_FREQ help Support for Xilinx Zynq ARM Cortex A9 Platform -- cgit v1.2.3-55-g7522 From cd325295871fbd172340a73f323f6a19c0b0525d Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Wed, 19 Feb 2014 15:14:44 -0800 Subject: arm: zynq: Add support for cpufreq The generic cpufreq-cpu0 driver can scale the CPU frequency on Zynq SOCs. Add the required platform device to the BSP and appropriate OPPs to the dts. Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Russell King Cc: devicetree@vger.kernel.org Signed-off-by: Soren Brinkmann Signed-off-by: Daniel Lezcano Acked-by: Michal Simek --- arch/arm/boot/dts/zynq-7000.dtsi | 6 ++++++ arch/arm/mach-zynq/Kconfig | 2 ++ arch/arm/mach-zynq/common.c | 3 +++ 3 files changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index 8b67b19392ec..789d0bacc110 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -24,6 +24,12 @@ device_type = "cpu"; reg = <0>; clocks = <&clkc 3>; + operating-points = < + /* kHz uV */ + 666667 1000000 + 333334 1000000 + 222223 1000000 + >; }; cpu@1 { diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index f84fab14f0b7..f03e75bd0b2b 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -2,6 +2,8 @@ config ARCH_ZYNQ bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7 select ARM_AMBA select ARM_GIC + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select COMMON_CLK select CPU_V7 select GENERIC_CLOCKEVENTS diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 1db2a5ca9ab8..644468151c04 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -51,6 +51,8 @@ static struct platform_device zynq_cpuidle_device = { */ static void __init zynq_init_machine(void) { + struct platform_device_info devinfo = { .name = "cpufreq-cpu0", }; + /* * 64KB way size, 8-way associativity, parity disabled */ @@ -59,6 +61,7 @@ static void __init zynq_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); platform_device_register(&zynq_cpuidle_device); + platform_device_register_full(&devinfo); } static void __init zynq_timer_init(void) -- cgit v1.2.3-55-g7522 From 51061b8876a3906aa5bf173582f180596f9d6455 Mon Sep 17 00:00:00 2001 From: Deng-Cheng Zhu Date: Thu, 6 Mar 2014 17:05:27 -0800 Subject: MIPS: math-emu: Fix prefx detection and COP1X function field definition When running applications which contain the instruction "prefx" on FPU-less CPUs, a message "Illegal instruction" will be seen. This instruction is supposed to be ignored by the FPU emulator. However, its current detection and function field encoding are incorrect. This patch fix the issue. Signed-off-by: Deng-Cheng Zhu Reviewed-by: Leonid Yegoshin Reviewed-by: Paul Burton Acked-by: David Daney Cc: linux-mips@linux-mips.org Cc: Steven.Hill@imgtec.com Patchwork: https://patchwork.linux-mips.org/patch/6608/ Signed-off-by: Ralf Baechle --- arch/mips/include/uapi/asm/inst.h | 4 ++-- arch/mips/math-emu/cp1emu.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index b39ba25b41cc..f25181b19941 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h @@ -163,8 +163,8 @@ enum cop1_sdw_func { */ enum cop1x_func { lwxc1_op = 0x00, ldxc1_op = 0x01, - pfetch_op = 0x07, swxc1_op = 0x08, - sdxc1_op = 0x09, madd_s_op = 0x20, + swxc1_op = 0x08, sdxc1_op = 0x09, + pfetch_op = 0x0f, madd_s_op = 0x20, madd_d_op = 0x21, madd_e_op = 0x22, msub_s_op = 0x28, msub_d_op = 0x29, msub_e_op = 0x2a, nmadd_s_op = 0x30, diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 506925b2c3f3..0b4e2e38294b 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1538,10 +1538,10 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, break; } - case 0x7: /* 7 */ - if (MIPSInst_FUNC(ir) != pfetch_op) { + case 0x3: + if (MIPSInst_FUNC(ir) != pfetch_op) return SIGILL; - } + /* ignore prefx operation */ break; -- cgit v1.2.3-55-g7522 From fdfaf64e75397567257e1051931f9a3377360665 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Mon, 10 Mar 2014 15:56:51 -0700 Subject: x86: bpf_jit: support negative offsets Commit a998d4342337 claimed to introduce negative offset support to x86 jit, but it couldn't be working, since at the time of the execution of LD+ABS or LD+IND instructions via call into bpf_internal_load_pointer_neg_helper() the %edx (3rd argument of this func) had junk value instead of access size in bytes (1 or 2 or 4). Store size into %edx instead of %ecx (what original commit intended to do) Fixes: a998d4342337 ("bpf jit: Let the x86 jit handle negative offsets") Signed-off-by: Alexei Starovoitov Cc: Jan Seiffert Cc: Eric Dumazet Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- arch/x86/net/bpf_jit.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S index 877b9a1b2152..01495755701b 100644 --- a/arch/x86/net/bpf_jit.S +++ b/arch/x86/net/bpf_jit.S @@ -140,7 +140,7 @@ bpf_slow_path_byte_msh: push %r9; \ push SKBDATA; \ /* rsi already has offset */ \ - mov $SIZE,%ecx; /* size */ \ + mov $SIZE,%edx; /* size */ \ call bpf_internal_load_pointer_neg_helper; \ test %rax,%rax; \ pop SKBDATA; \ -- cgit v1.2.3-55-g7522 From 4191c29f0593e82d19c3cd05de67e55467aca6b5 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 12 Mar 2014 00:53:30 +0100 Subject: perf/x86/uncore: Fix compilation warning in snb_uncore_imc_init_box() This patch fixes a compilation problem (unused variable) with the new SNB/IVB/HSW uncore IMC code. [ In -v2 we simplify the fix as suggested by Peter Zjilstra. ] Reported-by: Stephen Rothwell Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140311235329.GA28624@quad Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 5c2537af0a25..dfd50ea5ee0c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1722,15 +1722,16 @@ static struct attribute_group snb_uncore_imc_format_group = { static void snb_uncore_imc_init_box(struct intel_uncore_box *box) { struct pci_dev *pdev = box->pci_dev; - u32 addr_lo, addr_hi; + int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET; resource_size_t addr; + u32 pci_dword; - pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET, &addr_lo); - addr = addr_lo; + pci_read_config_dword(pdev, where, &pci_dword); + addr = pci_dword; #ifdef CONFIG_PHYS_ADDR_T_64BIT - pci_read_config_dword(pdev, SNB_UNCORE_PCI_IMC_BAR_OFFSET+4, &addr_hi); - addr = ((resource_size_t)addr_hi << 32) | addr_lo; + pci_read_config_dword(pdev, where + 4, &pci_dword); + addr |= ((resource_size_t)pci_dword << 32); #endif addr &= ~(PAGE_SIZE - 1); -- cgit v1.2.3-55-g7522 From 785aebd0cfff52e735ad4fd188d3726b5affc8e5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 20:43:38 +0000 Subject: ia64: Validate online cpus in irq_set_affinity() callbacks The [user space] interface does not filter out offline cpus. It merily guarantees that the mask contains at least one online cpu. So the selector in the irq chip implementation needs to make sure to pick only an online cpu because otherwise: Offline Core 1 Set affinity to 0xe (is valid due to online mask 0xd) cpumask_first will pick core 1, which is offline Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Tony Luck Cc: Fenghua Yu Cc: ia64 Link: http://lkml.kernel.org/r/20140304203100.650414633@linutronix.de Signed-off-by: Thomas Gleixner --- arch/ia64/kernel/msi_ia64.c | 10 ++-------- arch/ia64/sn/kernel/irq.c | 4 ++-- arch/ia64/sn/kernel/msi_sn.c | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index fb2f1e622877..c430f9198d1b 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -17,12 +17,9 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata, { struct msi_msg msg; u32 addr, data; - int cpu = first_cpu(*cpu_mask); + int cpu = cpumask_first_and(cpu_mask, cpu_online_mask); unsigned int irq = idata->irq; - if (!cpu_online(cpu)) - return -1; - if (irq_prepare_move(irq, cpu)) return -1; @@ -139,10 +136,7 @@ static int dmar_msi_set_affinity(struct irq_data *data, unsigned int irq = data->irq; struct irq_cfg *cfg = irq_cfg + irq; struct msi_msg msg; - int cpu = cpumask_first(mask); - - if (!cpu_online(cpu)) - return -1; + int cpu = cpumask_first_and(mask, cpu_online_mask); if (irq_prepare_move(irq, cpu)) return -1; diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 62cf4dde6a04..85d095154902 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -209,8 +209,8 @@ static int sn_set_affinity_irq(struct irq_data *data, nasid_t nasid; int slice; - nasid = cpuid_to_nasid(cpumask_first(mask)); - slice = cpuid_to_slice(cpumask_first(mask)); + nasid = cpuid_to_nasid(cpumask_first_and(mask, cpu_online_mask)); + slice = cpuid_to_slice(cpumask_first_and(mask, cpu_online_mask)); list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, sn_irq_lh[irq], list) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 2b98b9e088de..afc58d2799ad 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -166,7 +166,7 @@ static int sn_set_msi_irq_affinity(struct irq_data *data, struct sn_pcibus_provider *provider; unsigned int cpu, irq = data->irq; - cpu = cpumask_first(cpu_mask); + cpu = cpumask_first_and(cpu_mask, cpu_online_mask); sn_irq_info = sn_msi_info[irq].sn_irq_info; if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) return -1; -- cgit v1.2.3-55-g7522 From 421d1563c6620423d23e394711e3f209e585c161 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 20:43:39 +0000 Subject: mips: Validate online cpus in irq_set_affinity() callbacks The [user space] interface does not filter out offline cpus. It merily guarantees that the mask contains at least one online cpu. So the selector in the irq chip implementation needs to make sure to pick only an online cpu because otherwise: Offline Core 1 Set affinity to 0xe (is valid due to online mask 0xd) cpumask_first will pick core 1, which is offline Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Link: http://lkml.kernel.org/r/20140304203100.744800502@linutronix.de Signed-off-by: Thomas Gleixner --- arch/mips/sibyte/bcm1480/irq.c | 2 +- arch/mips/sibyte/sb1250/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 09d6e16a70f1..59cfe2659771 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -95,7 +95,7 @@ static int bcm1480_set_affinity(struct irq_data *d, const struct cpumask *mask, u64 cur_ints; unsigned long flags; - i = cpumask_first(mask); + i = cpumask_first_and(mask, cpu_online_mask); /* Convert logical CPU to physical CPU */ cpu = cpu_logical_map(i); diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index fca0cdb99509..6d8dba5cf348 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -88,7 +88,7 @@ static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask, u64 cur_ints; unsigned long flags; - i = cpumask_first(mask); + i = cpumask_first_and(mask, cpu_online_mask); /* Convert logical CPU to physical CPU */ cpu = cpu_logical_map(i); -- cgit v1.2.3-55-g7522 From 1ed71e59bca79e866c4bebbe1efc0bc18245119d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 20:43:40 +0000 Subject: parisc: Validate online cpus in irq_set_affinity() callbacks The [user space] interface does not filter out offline cpus. It merily guarantees that the mask contains at least one online cpu. So the selector in the irq chip implementation needs to make sure to pick only an online cpu because otherwise: Offline Core 1 Set affinity to 0xe (is valid due to online mask 0xd) cpumask_first will pick core 1, which is offline Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: James E.J. Bottomley Cc: Helge Deller Cc: linux-parisc@vger.kernel.org Link: http://lkml.kernel.org/r/20140304203100.859489993@linutronix.de Signed-off-by: Thomas Gleixner --- arch/parisc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 8ceac4785609..cfe056fe7f5c 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -117,7 +117,7 @@ int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest) return -EINVAL; /* whatever mask they set, we just allow one CPU */ - cpu_dest = first_cpu(*dest); + cpu_dest = cpumask_first_and(dest, cpu_online_mask); return cpu_dest; } -- cgit v1.2.3-55-g7522 From 596f3142d2b7be307a1652d59e7b93adab918437 Mon Sep 17 00:00:00 2001 From: Radim Krčmář Date: Tue, 11 Mar 2014 19:11:18 +0100 Subject: KVM: SVM: fix cr8 intercept window We always disable cr8 intercept in its handler, but only re-enable it if handling KVM_REQ_EVENT, so there can be a window where we do not intercept cr8 writes, which allows an interrupt to disrupt a higher priority task. Fix this by disabling intercepts in the same function that re-enables them when needed. This fixes BSOD in Windows 2008. Cc: Signed-off-by: Radim Krčmář Reviewed-by: Marcelo Tosatti Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index e81df8fce027..2de1bc09a8d4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3002,10 +3002,8 @@ static int cr8_write_interception(struct vcpu_svm *svm) u8 cr8_prev = kvm_get_cr8(&svm->vcpu); /* instruction emulation calls kvm_set_cr8() */ r = cr_interception(svm); - if (irqchip_in_kernel(svm->vcpu.kvm)) { - clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); + if (irqchip_in_kernel(svm->vcpu.kvm)) return r; - } if (cr8_prev <= kvm_get_cr8(&svm->vcpu)) return r; kvm_run->exit_reason = KVM_EXIT_SET_TPR; @@ -3567,6 +3565,8 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) if (is_guest_mode(vcpu) && (vcpu->arch.hflags & HF_VINTR_MASK)) return; + clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); + if (irr == -1) return; -- cgit v1.2.3-55-g7522 From a5b0ccb0b5d080c0decb4c9208d9bb6072defa50 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 13 Mar 2014 20:02:02 +1100 Subject: KVM: PPC: Book3S HV: Remove bogus duplicate code Commit 7b490411c37f ("KVM: PPC: Book3S HV: Add new state for transactional memory") incorrectly added some duplicate code to the guest exit path because I didn't manage to clean up after a rebase correctly. This removes the extraneous material. The presence of this extraneous code causes host crashes whenever a guest is run. Signed-off-by: Paul Mackerras Signed-off-by: Paolo Bonzini --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 67 --------------------------------- 1 file changed, 67 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index e66d4ec04d95..781e6bf69afb 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1504,73 +1504,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) 1: addi r8,r8,16 .endr - /* Save DEC */ - mfspr r5,SPRN_DEC - mftb r6 - extsw r5,r5 - add r5,r5,r6 - std r5,VCPU_DEC_EXPIRES(r9) - -BEGIN_FTR_SECTION - b 8f -END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) - /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */ - mfmsr r8 - li r0, 1 - rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG - mtmsrd r8 - - /* Save POWER8-specific registers */ - mfspr r5, SPRN_IAMR - mfspr r6, SPRN_PSPB - mfspr r7, SPRN_FSCR - std r5, VCPU_IAMR(r9) - stw r6, VCPU_PSPB(r9) - std r7, VCPU_FSCR(r9) - mfspr r5, SPRN_IC - mfspr r6, SPRN_VTB - mfspr r7, SPRN_TAR - std r5, VCPU_IC(r9) - std r6, VCPU_VTB(r9) - std r7, VCPU_TAR(r9) -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - mfspr r5, SPRN_TFHAR - mfspr r6, SPRN_TFIAR - mfspr r7, SPRN_TEXASR - std r5, VCPU_TFHAR(r9) - std r6, VCPU_TFIAR(r9) - std r7, VCPU_TEXASR(r9) -#endif - mfspr r8, SPRN_EBBHR - std r8, VCPU_EBBHR(r9) - mfspr r5, SPRN_EBBRR - mfspr r6, SPRN_BESCR - mfspr r7, SPRN_CSIGR - mfspr r8, SPRN_TACR - std r5, VCPU_EBBRR(r9) - std r6, VCPU_BESCR(r9) - std r7, VCPU_CSIGR(r9) - std r8, VCPU_TACR(r9) - mfspr r5, SPRN_TCSCR - mfspr r6, SPRN_ACOP - mfspr r7, SPRN_PID - mfspr r8, SPRN_WORT - std r5, VCPU_TCSCR(r9) - std r6, VCPU_ACOP(r9) - stw r7, VCPU_GUEST_PID(r9) - std r8, VCPU_WORT(r9) -8: - - /* Save and reset AMR and UAMOR before turning on the MMU */ -BEGIN_FTR_SECTION - mfspr r5,SPRN_AMR - mfspr r6,SPRN_UAMOR - std r5,VCPU_AMR(r9) - std r6,VCPU_UAMOR(r9) - li r6,0 - mtspr SPRN_AMR,r6 -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) - /* Unset guest mode */ li r0, KVM_GUEST_MODE_NONE stb r0, HSTATE_IN_GUEST(r13) -- cgit v1.2.3-55-g7522 From e724f080f5dd03881bc6d378750c37f7374cae7e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 13 Mar 2014 20:02:48 +1100 Subject: KVM: PPC: Book3S HV: Fix register usage when loading/saving VRSAVE Commit 595e4f7e697e ("KVM: PPC: Book3S HV: Use load/store_fp_state functions in HV guest entry/exit") changed the register usage in kvmppc_save_fp() and kvmppc_load_fp() but omitted changing the instructions that load and save VRSAVE. The result is that the VRSAVE value was loaded from a constant address, and saved to a location past the end of the vcpu struct, causing host kernel memory corruption and various kinds of host kernel crashes. This fixes the problem by using register r31, which contains the vcpu pointer, instead of r3 and r4. Signed-off-by: Paul Mackerras Signed-off-by: Paolo Bonzini --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 781e6bf69afb..818dce344e82 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2136,7 +2136,7 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif mfspr r6,SPRN_VRSAVE - stw r6,VCPU_VRSAVE(r3) + stw r6,VCPU_VRSAVE(r31) mtlr r30 mtmsrd r5 isync @@ -2173,7 +2173,7 @@ BEGIN_FTR_SECTION bl .load_vr_state END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif - lwz r7,VCPU_VRSAVE(r4) + lwz r7,VCPU_VRSAVE(r31) mtspr SPRN_VRSAVE,r7 mtlr r30 mr r4,r31 -- cgit v1.2.3-55-g7522 From de2db7432917a82b62d55bb59635586eeca6d1bd Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 12 Mar 2014 16:07:06 +0000 Subject: arm64: Make DMA coherent and strongly ordered mappings not executable pgprot_{dmacoherent,writecombine,noncached} don't need to generate executable mappings with side-effects like __sync_icache_dcache() being called when the mapping is in user space. Signed-off-by: Catalin Marinas Reported-by: Bharat Bhushan Tested-by: Laura Abbott Tested-by: Bharat Bhushan Cc: --- arch/arm64/include/asm/pgtable.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index b524dcd17243..2d3cede62709 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void) * Mark the prot value as uncacheable and unbufferable. */ #define pgprot_noncached(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) #define pgprot_writecombine(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) #define pgprot_dmacoherent(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) #define __HAVE_PHYS_MEM_ACCESS_PROT struct file; extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, -- cgit v1.2.3-55-g7522 From 71fdb6bf61bf0692f004f9daf5650392c0cfe300 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 12 Mar 2014 16:28:09 +0000 Subject: arm64: Do not synchronise I and D caches for special ptes Special pte mappings are not intended to be executable and do not even have an associated struct page. This patch ensures that we do not call __sync_icache_dcache() on such ptes. Signed-off-by: Catalin Marinas Reported-by: Steve Capper Tested-by: Laura Abbott Tested-by: Bharat Bhushan Cc: --- arch/arm64/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 2d3cede62709..72c9ac38cdd9 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -199,7 +199,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { if (pte_valid_user(pte)) { - if (pte_exec(pte)) + if (!pte_special(pte) && pte_exec(pte)) __sync_icache_dcache(pte, addr); if (pte_dirty(pte) && pte_write(pte)) pte_val(pte) &= ~PTE_RDONLY; -- cgit v1.2.3-55-g7522 From 87366d8cf7b3f6dc34633938aa8766e5a390ce33 Mon Sep 17 00:00:00 2001 From: Radha Mohan Chintakuntla Date: Fri, 7 Mar 2014 08:49:25 +0000 Subject: arm64: Add boot time configuration of Intermediate Physical Address size ARMv8 supports a range of physical address bit sizes. The PARange bits from ID_AA64MMFR0_EL1 register are read during boot-time and the intermediate physical address size bits are written in the translation control registers (TCR_EL1 and VTCR_EL2). There is no change in the VA bits and levels of translation. Signed-off-by: Radha Mohan Chintakuntla Reviewed-by: Will Deacon Acked-by: Marc Zyngier Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/kvm_arm.h | 15 ++++++--------- arch/arm64/include/asm/pgtable-hwdef.h | 5 ++--- arch/arm64/kvm/hyp-init.S | 6 ++++++ arch/arm64/mm/proc.S | 8 +++++++- 4 files changed, 21 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 0eb398655378..21ef48d32ff2 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -106,7 +106,6 @@ /* VTCR_EL2 Registers bits */ #define VTCR_EL2_PS_MASK (7 << 16) -#define VTCR_EL2_PS_40B (2 << 16) #define VTCR_EL2_TG0_MASK (1 << 14) #define VTCR_EL2_TG0_4K (0 << 14) #define VTCR_EL2_TG0_64K (1 << 14) @@ -129,10 +128,9 @@ * 64kB pages (TG0 = 1) * 2 level page tables (SL = 1) */ -#define VTCR_EL2_FLAGS (VTCR_EL2_PS_40B | VTCR_EL2_TG0_64K | \ - VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \ - VTCR_EL2_IRGN0_WBWA | VTCR_EL2_SL0_LVL1 | \ - VTCR_EL2_T0SZ_40B) +#define VTCR_EL2_FLAGS (VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \ + VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ + VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B) #define VTTBR_X (38 - VTCR_EL2_T0SZ_40B) #else /* @@ -142,10 +140,9 @@ * 4kB pages (TG0 = 0) * 3 level page tables (SL = 1) */ -#define VTCR_EL2_FLAGS (VTCR_EL2_PS_40B | VTCR_EL2_TG0_4K | \ - VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \ - VTCR_EL2_IRGN0_WBWA | VTCR_EL2_SL0_LVL1 | \ - VTCR_EL2_T0SZ_40B) +#define VTCR_EL2_FLAGS (VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \ + VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \ + VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B) #define VTTBR_X (37 - VTCR_EL2_T0SZ_40B) #endif diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index b1d2e26c3c88..f7af66b54cb2 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -100,9 +100,9 @@ #define PTE_HYP PTE_USER /* - * 40-bit physical address supported. + * Highest possible physical address supported. */ -#define PHYS_MASK_SHIFT (40) +#define PHYS_MASK_SHIFT (48) #define PHYS_MASK ((UL(1) << PHYS_MASK_SHIFT) - 1) /* @@ -122,7 +122,6 @@ #define TCR_SHARED ((UL(3) << 12) | (UL(3) << 28)) #define TCR_TG0_64K (UL(1) << 14) #define TCR_TG1_64K (UL(1) << 30) -#define TCR_IPS_40BIT (UL(2) << 32) #define TCR_ASID16 (UL(1) << 36) #define TCR_TBI0 (UL(1) << 37) diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 2b0244d65c16..d968796f4b2d 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -68,6 +68,12 @@ __do_hyp_init: msr tcr_el2, x4 ldr x4, =VTCR_EL2_FLAGS + /* + * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in + * VTCR_EL2. + */ + mrs x5, ID_AA64MMFR0_EL1 + bfi x4, x5, #16, #3 msr vtcr_el2, x4 mrs x4, mair_el1 diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index e0ef63cd05dc..e085ee6ef4e2 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -209,8 +209,14 @@ ENTRY(__cpu_setup) * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for * both user and kernel. */ - ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT | \ + ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | \ TCR_ASID16 | TCR_TBI0 | (1 << 31) + /* + * Read the PARange bits from ID_AA64MMFR0_EL1 and set the IPS bits in + * TCR_EL1. + */ + mrs x9, ID_AA64MMFR0_EL1 + bfi x10, x9, #32, #3 #ifdef CONFIG_ARM64_64K_PAGES orr x10, x10, TCR_TG0_64K orr x10, x10, TCR_TG1_64K -- cgit v1.2.3-55-g7522 From 2ee0d7fd36a3f87bc5b29b1ec54ad6728deedb41 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Mon, 3 Feb 2014 19:18:27 +0100 Subject: ARM64: perf: add support for perf registers API This patch implements the functions required for the perf registers API, allowing the perf tool to interface kernel register dumps with libunwind in order to provide userspace backtracing. Compat mode is also supported. Only the general purpose user space registers are exported, i.e.: PERF_REG_ARM_X0, ... PERF_REG_ARM_X28, PERF_REG_ARM_FP, PERF_REG_ARM_LR, PERF_REG_ARM_SP, PERF_REG_ARM_PC and not the PERF_REG_ARM_V* registers. Signed-off-by: Jean Pihet Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 2 ++ arch/arm64/include/asm/ptrace.h | 1 + arch/arm64/include/uapi/asm/Kbuild | 1 + arch/arm64/include/uapi/asm/perf_regs.h | 40 ++++++++++++++++++++++++++++++ arch/arm64/kernel/Makefile | 3 ++- arch/arm64/kernel/perf_regs.c | 44 +++++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/uapi/asm/perf_regs.h create mode 100644 arch/arm64/kernel/perf_regs.c (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 140cd1a9dc0c..507ab6e53522 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -39,6 +39,8 @@ config ARM64 select HAVE_MEMBLOCK select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select IRQ_DOMAIN select MODULES_USE_ELF_RELA select NO_BOOTMEM diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 5233966fba3d..35ff2f9de072 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -68,6 +68,7 @@ /* Architecturally defined mapping between AArch32 and AArch64 registers */ #define compat_usr(x) regs[(x)] +#define compat_fp regs[11] #define compat_sp regs[13] #define compat_lr regs[14] #define compat_sp_hyp regs[15] diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild index e4b78bdca19e..942376d37d22 100644 --- a/arch/arm64/include/uapi/asm/Kbuild +++ b/arch/arm64/include/uapi/asm/Kbuild @@ -9,6 +9,7 @@ header-y += byteorder.h header-y += fcntl.h header-y += hwcap.h header-y += kvm_para.h +header-y += perf_regs.h header-y += param.h header-y += ptrace.h header-y += setup.h diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..172b8317ee49 --- /dev/null +++ b/arch/arm64/include/uapi/asm/perf_regs.h @@ -0,0 +1,40 @@ +#ifndef _ASM_ARM64_PERF_REGS_H +#define _ASM_ARM64_PERF_REGS_H + +enum perf_event_arm_regs { + PERF_REG_ARM64_X0, + PERF_REG_ARM64_X1, + PERF_REG_ARM64_X2, + PERF_REG_ARM64_X3, + PERF_REG_ARM64_X4, + PERF_REG_ARM64_X5, + PERF_REG_ARM64_X6, + PERF_REG_ARM64_X7, + PERF_REG_ARM64_X8, + PERF_REG_ARM64_X9, + PERF_REG_ARM64_X10, + PERF_REG_ARM64_X11, + PERF_REG_ARM64_X12, + PERF_REG_ARM64_X13, + PERF_REG_ARM64_X14, + PERF_REG_ARM64_X15, + PERF_REG_ARM64_X16, + PERF_REG_ARM64_X17, + PERF_REG_ARM64_X18, + PERF_REG_ARM64_X19, + PERF_REG_ARM64_X20, + PERF_REG_ARM64_X21, + PERF_REG_ARM64_X22, + PERF_REG_ARM64_X23, + PERF_REG_ARM64_X24, + PERF_REG_ARM64_X25, + PERF_REG_ARM64_X26, + PERF_REG_ARM64_X27, + PERF_REG_ARM64_X28, + PERF_REG_ARM64_X29, + PERF_REG_ARM64_LR, + PERF_REG_ARM64_SP, + PERF_REG_ARM64_PC, + PERF_REG_ARM64_MAX, +}; +#endif /* _ASM_ARM64_PERF_REGS_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index cfee8273fccb..7d811d9522bc 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -15,8 +15,9 @@ arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ sys_compat.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o +arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o -arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o +arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c new file mode 100644 index 000000000000..f2d6f0a36d63 --- /dev/null +++ b/arch/arm64/kernel/perf_regs.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX)) + return 0; + + /* + * Compat (i.e. 32 bit) mode: + * - PC has been set in the pt_regs struct in kernel_entry, + * - Handle SP and LR here. + */ + if (compat_user_mode(regs)) { + if ((u32)idx == PERF_REG_ARM64_SP) + return regs->compat_sp; + if ((u32)idx == PERF_REG_ARM64_LR) + return regs->compat_lr; + } + + return regs->regs[idx]; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + if (is_compat_thread(task_thread_info(task))) + return PERF_SAMPLE_REGS_ABI_32; + else + return PERF_SAMPLE_REGS_ABI_64; +} -- cgit v1.2.3-55-g7522 From 23c7d70d55c6d963f225744cd1b996dee68c88d1 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Mon, 3 Feb 2014 19:18:28 +0100 Subject: ARM64: perf: add support for frame pointer unwinding in compat mode When profiling a 32-bit application, user space callchain unwinding using the frame pointer is performed in compat mode. The code is taken over from the AARCH32 code and adapted to work on AARCH64. Signed-off-by: Jean Pihet Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/perf_event.c | 75 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 5b1cd792274a..e868c72a7938 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1348,8 +1348,8 @@ early_initcall(init_hw_perf_events); * Callchain handling code. */ struct frame_tail { - struct frame_tail __user *fp; - unsigned long lr; + struct frame_tail __user *fp; + unsigned long lr; } __attribute__((packed)); /* @@ -1386,22 +1386,80 @@ user_backtrace(struct frame_tail __user *tail, return buftail.fp; } +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct compat_frame_tail *)(xxx->fp)-1 + * + * This code has been adapted from the ARM OProfile support. + */ +struct compat_frame_tail { + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */ + u32 sp; + u32 lr; +} __attribute__((packed)); + +static struct compat_frame_tail __user * +compat_user_backtrace(struct compat_frame_tail __user *tail, + struct perf_callchain_entry *entry) +{ + struct compat_frame_tail buftail; + unsigned long err; + + /* Also check accessibility of one struct frame_tail beyond */ + if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) + return NULL; + + pagefault_disable(); + err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail)); + pagefault_enable(); + + if (err) + return NULL; + + perf_callchain_store(entry, buftail.lr); + + /* + * Frame pointers should strictly progress back up the stack + * (towards higher addresses). + */ + if (tail + 1 >= (struct compat_frame_tail __user *) + compat_ptr(buftail.fp)) + return NULL; + + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1; +} + void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) { - struct frame_tail __user *tail; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } perf_callchain_store(entry, regs->pc); - tail = (struct frame_tail __user *)regs->regs[29]; - while (entry->nr < PERF_MAX_STACK_DEPTH && - tail && !((unsigned long)tail & 0xf)) - tail = user_backtrace(tail, entry); + if (!compat_user_mode(regs)) { + /* AARCH64 mode */ + struct frame_tail __user *tail; + + tail = (struct frame_tail __user *)regs->regs[29]; + + while (entry->nr < PERF_MAX_STACK_DEPTH && + tail && !((unsigned long)tail & 0xf)) + tail = user_backtrace(tail, entry); + } else { + /* AARCH32 compat mode */ + struct compat_frame_tail __user *tail; + + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1; + + while ((entry->nr < PERF_MAX_STACK_DEPTH) && + tail && !((unsigned long)tail & 0x3)) + tail = compat_user_backtrace(tail, entry); + } } /* @@ -1429,6 +1487,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, frame.fp = regs->regs[29]; frame.sp = regs->sp; frame.pc = regs->pc; + walk_stackframe(&frame, callchain_trace, entry); } -- cgit v1.2.3-55-g7522 From 5f888a1d33c48900012e6b4c18296ce7c715dc6c Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Mon, 3 Feb 2014 19:18:29 +0100 Subject: ARM64: perf: support dwarf unwinding in compat mode Add support for unwinding using the dwarf information in compat mode. Using the correct user stack pointer allows perf to record the frames correctly in the native and compat modes. Note that although the dwarf frame unwinding works ok using libunwind in native mode (on ARMv7 & ARMv8), some changes are required to the libunwind code for the compat mode. Those changes are posted separately on the libunwind mailing list. Tested on ARMv8 platform with v8 and compat v7 binaries, the latter are statically built. Signed-off-by: Jean Pihet Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/compat.h | 2 +- arch/arm64/include/asm/ptrace.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index fda2704b3f9f..e71f81fe127a 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h @@ -228,7 +228,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) return (u32)(unsigned long)uptr; } -#define compat_user_stack_pointer() (current_pt_regs()->compat_sp) +#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs())) static inline void __user *arch_compat_alloc_user_space(long len) { diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 35ff2f9de072..c7ba261dd4b3 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -133,7 +133,7 @@ struct pt_regs { (!((regs)->pstate & PSR_F_BIT)) #define user_stack_pointer(regs) \ - ((regs)->sp) + (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp) /* * Are the current registers suitable for user mode? (used to maintain -- cgit v1.2.3-55-g7522 From 242c04bc4be959ae28618772e439c27e87a7d880 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 5 Mar 2014 05:34:32 +0000 Subject: arm64: debug: make local symbols static Make local symbols static, because these are used only in this file. Signed-off-by: Jingoo Han Signed-off-by: Catalin Marinas --- arch/arm64/kernel/debug-monitors.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 13f87def8ea1..14ba23c61153 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -189,7 +189,7 @@ static void clear_regs_spsr_ss(struct pt_regs *regs) /* EL1 Single Step Handler hooks */ static LIST_HEAD(step_hook); -DEFINE_RWLOCK(step_hook_lock); +static DEFINE_RWLOCK(step_hook_lock); void register_step_hook(struct step_hook *hook) { @@ -276,7 +276,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr, * Use reader/writer locks instead of plain spinlock. */ static LIST_HEAD(break_hook); -DEFINE_RWLOCK(break_hook_lock); +static DEFINE_RWLOCK(break_hook_lock); void register_break_hook(struct break_hook *hook) { -- cgit v1.2.3-55-g7522 From 7184659bed3090248e382d98a49a3c1bcfe11174 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 5 Mar 2014 05:35:45 +0000 Subject: arm64: smp: make local symbol static Make smp_spin_table_cpu_postboot() static, because this function is used only in this file. Signed-off-by: Jingoo Han Signed-off-by: Catalin Marinas --- arch/arm64/kernel/smp_spin_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index 44c22805d2e2..7a530d2cc807 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -128,7 +128,7 @@ static int smp_spin_table_cpu_boot(unsigned int cpu) return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; } -void smp_spin_table_cpu_postboot(void) +static void smp_spin_table_cpu_postboot(void) { /* * Let the primary processor know we're out of the pen. -- cgit v1.2.3-55-g7522 From 073d8224d299528778e90773becd1e890953443c Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 5 Mar 2014 17:24:12 +0100 Subject: arch: Remove stub cputime.h headers Many architectures have a stub cputime.h that only include the default cputime.h Lets remove the useless headers, we only need to mention that we want the default headers on the Kbuild files. Cc: Archs Cc: Ingo Molnar Cc: Marcelo Tosatti Cc: Peter Zijlstra Cc: Thomas Gleixner Acked-by: Rik van Riel Signed-off-by: Frederic Weisbecker --- arch/alpha/include/asm/Kbuild | 1 + arch/alpha/include/asm/cputime.h | 6 ------ arch/cris/include/asm/Kbuild | 1 + arch/cris/include/asm/cputime.h | 6 ------ arch/frv/include/asm/Kbuild | 1 + arch/frv/include/asm/cputime.h | 6 ------ arch/m32r/include/asm/Kbuild | 1 + arch/m32r/include/asm/cputime.h | 6 ------ arch/microblaze/include/asm/Kbuild | 1 + arch/microblaze/include/asm/cputime.h | 1 - arch/mn10300/include/asm/Kbuild | 1 + arch/mn10300/include/asm/cputime.h | 1 - arch/score/include/asm/Kbuild | 1 + arch/score/include/asm/cputime.h | 6 ------ arch/x86/include/asm/Kbuild | 1 + arch/x86/include/asm/cputime.h | 1 - 16 files changed, 8 insertions(+), 33 deletions(-) delete mode 100644 arch/alpha/include/asm/cputime.h delete mode 100644 arch/cris/include/asm/cputime.h delete mode 100644 arch/frv/include/asm/cputime.h delete mode 100644 arch/m32r/include/asm/cputime.h delete mode 100644 arch/microblaze/include/asm/cputime.h delete mode 100644 arch/mn10300/include/asm/cputime.h delete mode 100644 arch/score/include/asm/cputime.h delete mode 100644 arch/x86/include/asm/cputime.h (limited to 'arch') diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index 7736f426ff3b..96e54bed5088 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += mcs_spinlock.h diff --git a/arch/alpha/include/asm/cputime.h b/arch/alpha/include/asm/cputime.h deleted file mode 100644 index 19577fd93230..000000000000 --- a/arch/alpha/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ALPHA_CPUTIME_H -#define __ALPHA_CPUTIME_H - -#include - -#endif /* __ALPHA_CPUTIME_H */ diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 056027f38351..afff5105909d 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -5,6 +5,7 @@ header-y += arch-v32/ generic-y += barrier.h generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += kvm_para.h diff --git a/arch/cris/include/asm/cputime.h b/arch/cris/include/asm/cputime.h deleted file mode 100644 index 4446a65656fa..000000000000 --- a/arch/cris/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __CRIS_CPUTIME_H -#define __CRIS_CPUTIME_H - -#include - -#endif /* __CRIS_CPUTIME_H */ diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index babb9338ebf8..87b95eb8aee5 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -1,5 +1,6 @@ generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += mcs_spinlock.h diff --git a/arch/frv/include/asm/cputime.h b/arch/frv/include/asm/cputime.h deleted file mode 100644 index f6c373ad2b80..000000000000 --- a/arch/frv/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_CPUTIME_H -#define _ASM_CPUTIME_H - -#include - -#endif /* _ASM_CPUTIME_H */ diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index 5825a35b2c56..67779a74b62d 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -1,5 +1,6 @@ generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += mcs_spinlock.h diff --git a/arch/m32r/include/asm/cputime.h b/arch/m32r/include/asm/cputime.h deleted file mode 100644 index 0a47550df2b7..000000000000 --- a/arch/m32r/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __M32R_CPUTIME_H -#define __M32R_CPUTIME_H - -#include - -#endif /* __M32R_CPUTIME_H */ diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 1f590ab8f323..c98ed95c0541 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += barrier.h generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += mcs_spinlock.h diff --git a/arch/microblaze/include/asm/cputime.h b/arch/microblaze/include/asm/cputime.h deleted file mode 100644 index 6d68ad7e0ea3..000000000000 --- a/arch/microblaze/include/asm/cputime.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index cbc6b9bf45da..654d5ba6e310 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += barrier.h generic-y += clkdev.h +generic-y += cputime.h generic-y += exec.h generic-y += hash.h generic-y += mcs_spinlock.h diff --git a/arch/mn10300/include/asm/cputime.h b/arch/mn10300/include/asm/cputime.h deleted file mode 100644 index 6d68ad7e0ea3..000000000000 --- a/arch/mn10300/include/asm/cputime.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index 4630cf217b5b..2f947aba4bd4 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -4,6 +4,7 @@ header-y += generic-y += barrier.h generic-y += clkdev.h +generic-y += cputime.h generic-y += hash.h generic-y += mcs_spinlock.h generic-y += preempt.h diff --git a/arch/score/include/asm/cputime.h b/arch/score/include/asm/cputime.h deleted file mode 100644 index 1fced99f0d67..000000000000 --- a/arch/score/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_SCORE_CPUTIME_H -#define _ASM_SCORE_CPUTIME_H - -#include - -#endif /* _ASM_SCORE_CPUTIME_H */ diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index a8fee078b92f..4acddc43ee0c 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -5,4 +5,5 @@ genhdr-y += unistd_64.h genhdr-y += unistd_x32.h generic-y += clkdev.h +generic-y += cputime.h generic-y += mcs_spinlock.h diff --git a/arch/x86/include/asm/cputime.h b/arch/x86/include/asm/cputime.h deleted file mode 100644 index 6d68ad7e0ea3..000000000000 --- a/arch/x86/include/asm/cputime.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.2.3-55-g7522 From 3e920b532a0f49d05e4c0f7d1b46b0ab8f471e09 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 12 Mar 2014 15:13:02 +0100 Subject: x86, boot: Correct max ramdisk size name The name in struct bootparam is ->initrd_addr_max and not ramdisk_max. Fix that. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394633584-5509-2-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- Documentation/x86/boot.txt | 4 ++-- arch/x86/boot/header.S | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index cb81741d3b0b..a75e3adaa39d 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt @@ -182,7 +182,7 @@ Offset Proto Name Meaning 0226/1 2.02+(3 ext_loader_ver Extended boot loader version 0227/1 2.02+(3 ext_loader_type Extended boot loader ID 0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line -022C/4 2.03+ ramdisk_max Highest legal initrd address +022C/4 2.03+ initrd_addr_max Highest legal initrd address 0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not 0235/1 2.10+ min_alignment Minimum alignment, as a power of two @@ -534,7 +534,7 @@ Protocol: 2.02+ zero, the kernel will assume that your boot loader does not support the 2.02+ protocol. -Field name: ramdisk_max +Field name: initrd_addr_max Type: read Offset/size: 0x22c/4 Protocol: 2.03+ diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index ec3b8ba68096..46f5a220b0ad 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -350,7 +350,7 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later) # can be located anywhere in # low memory 0x10000 or higher. -ramdisk_max: .long 0x7fffffff +initrd_addr_max: .long 0x7fffffff # (Header version 0x0203 or later) # The highest safe address for # the contents of an initrd -- cgit v1.2.3-55-g7522 From 5314feebabd92535a16295a8067b3fd79815cd16 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 12 Mar 2014 15:13:03 +0100 Subject: x86, crash: Unify ifdef Merge two back-to-back CONFIG_X86_32 ifdefs into one. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394633584-5509-3-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/kernel/crash.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a57902efe2d5..507de8066594 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -57,9 +57,7 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs) { #ifdef CONFIG_X86_32 struct pt_regs fixed_regs; -#endif -#ifdef CONFIG_X86_32 if (!user_mode_vm(regs)) { crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; -- cgit v1.2.3-55-g7522 From b82ad3d3944193e5f95319c30fd24e39d0d7b510 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Wed, 12 Mar 2014 15:13:04 +0100 Subject: x86, pageattr: Correct WBINVD spelling in comment It is WBINVD, for INValiDate and not "wbindv". Use caps for instruction names, while at it. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394633584-5509-4-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/mm/pageattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index b3b19f46c016..ba957c9b677c 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -1377,10 +1377,10 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, cache = cache_attr(mask_set); /* - * On success we use clflush, when the CPU supports it to - * avoid the wbindv. If the CPU does not support it and in the + * On success we use CLFLUSH, when the CPU supports it to + * avoid the WBINVD. If the CPU does not support it and in the * error case we fall back to cpa_flush_all (which uses - * wbindv): + * WBINVD): */ if (!ret && cpu_has_clflush) { if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { -- cgit v1.2.3-55-g7522 From 22085a66c2fab6cf9b9393c056a3600a6b4735de Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 9 Mar 2014 18:05:23 +0100 Subject: x86: Add another set of MSR accessor functions We very often need to set or clear a bit in an MSR as a result of doing some sort of a hardware configuration. Add generic versions of that repeated functionality in order to save us a bunch of duplicated code in the early CPU vendor detection/config code. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394384725-10796-2-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/msr.h | 2 ++ arch/x86/lib/msr.c | 89 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index e139b13f2a33..de36f22eb0b9 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -214,6 +214,8 @@ do { \ struct msr *msrs_alloc(void); void msrs_free(struct msr *msrs); +int msr_set_bit(u32 msr, u8 bit); +int msr_clear_bit(u32 msr, u8 bit); #ifdef CONFIG_SMP int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index 8f8eebdca7d4..db9db446b71a 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c @@ -8,7 +8,7 @@ struct msr *msrs_alloc(void) msrs = alloc_percpu(struct msr); if (!msrs) { - pr_warning("%s: error allocating msrs\n", __func__); + pr_warn("%s: error allocating msrs\n", __func__); return NULL; } @@ -21,3 +21,90 @@ void msrs_free(struct msr *msrs) free_percpu(msrs); } EXPORT_SYMBOL(msrs_free); + +/** + * Read an MSR with error handling + * + * @msr: MSR to read + * @m: value to read into + * + * It returns read data only on success, otherwise it doesn't change the output + * argument @m. + * + */ +int msr_read(u32 msr, struct msr *m) +{ + int err; + u64 val; + + err = rdmsrl_safe(msr, &val); + if (!err) + m->q = val; + + return err; +} + +/** + * Write an MSR with error handling + * + * @msr: MSR to write + * @m: value to write + */ +int msr_write(u32 msr, struct msr *m) +{ + return wrmsrl_safe(msr, m->q); +} + +static inline int __flip_bit(u32 msr, u8 bit, bool set) +{ + struct msr m, m1; + int err = -EINVAL; + + if (bit > 63) + return err; + + err = msr_read(msr, &m); + if (err) + return err; + + m1 = m; + if (set) + m1.q |= BIT_64(bit); + else + m1.q &= ~BIT_64(bit); + + if (m1.q == m.q) + return 0; + + err = msr_write(msr, &m); + if (err) + return err; + + return 1; +} + +/** + * Set @bit in a MSR @msr. + * + * Retval: + * < 0: An error was encountered. + * = 0: Bit was already set. + * > 0: Hardware accepted the MSR write. + */ +int msr_set_bit(u32 msr, u8 bit) +{ + return __flip_bit(msr, bit, true); +} + +/** + * Clear @bit in a MSR @msr. + * + * Retval: + * < 0: An error was encountered. + * = 0: Bit was already cleared. + * > 0: Hardware accepted the MSR write. + */ +int msr_clear_bit(u32 msr, u8 bit) +{ + return __flip_bit(msr, bit, false); +} -- cgit v1.2.3-55-g7522 From 8f86a7373a1c8ee52d3cc64adf7f2ace13fd24ed Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 9 Mar 2014 18:05:24 +0100 Subject: x86, AMD: Convert to the new bit access MSR accessors ... and save us a bunch of code. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394384725-10796-3-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 48 ++++++++++++----------------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index c67ffa686064..b85e43a5a462 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -233,9 +233,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c) if (c->x86_model >= 6 && c->x86_model <= 10) { if (!cpu_has(c, X86_FEATURE_XMM)) { printk(KERN_INFO "Enabling disabled K7/SSE Support.\n"); - rdmsr(MSR_K7_HWCR, l, h); - l &= ~0x00008000; - wrmsr(MSR_K7_HWCR, l, h); + msr_clear_bit(MSR_K7_HWCR, 15); set_cpu_cap(c, X86_FEATURE_XMM); } } @@ -509,14 +507,8 @@ static void early_init_amd(struct cpuinfo_x86 *c) #endif /* F16h erratum 793, CVE-2013-6885 */ - if (c->x86 == 0x16 && c->x86_model <= 0xf) { - u64 val; - - rdmsrl(MSR_AMD64_LS_CFG, val); - if (!(val & BIT(15))) - wrmsrl(MSR_AMD64_LS_CFG, val | BIT(15)); - } - + if (c->x86 == 0x16 && c->x86_model <= 0xf) + msr_set_bit(MSR_AMD64_LS_CFG, 15); } static const int amd_erratum_383[]; @@ -536,11 +528,8 @@ static void init_amd(struct cpuinfo_x86 *c) * Errata 63 for SH-B3 steppings * Errata 122 for all steppings (F+ have it disabled by default) */ - if (c->x86 == 0xf) { - rdmsrl(MSR_K7_HWCR, value); - value |= 1 << 6; - wrmsrl(MSR_K7_HWCR, value); - } + if (c->x86 == 0xf) + msr_set_bit(MSR_K7_HWCR, 6); #endif early_init_amd(c); @@ -623,14 +612,11 @@ static void init_amd(struct cpuinfo_x86 *c) (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && !cpu_has(c, X86_FEATURE_TOPOEXT)) { - if (!rdmsrl_safe(0xc0011005, &value)) { - value |= 1ULL << 54; - wrmsrl_safe(0xc0011005, value); + if (msr_set_bit(0xc0011005, 54) > 0) { rdmsrl(0xc0011005, value); - if (value & (1ULL << 54)) { + if (value & BIT_64(54)) { set_cpu_cap(c, X86_FEATURE_TOPOEXT); - printk(KERN_INFO FW_INFO "CPU: Re-enabling " - "disabled Topology Extensions Support\n"); + pr_info(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n"); } } } @@ -709,19 +695,12 @@ static void init_amd(struct cpuinfo_x86 *c) * Disable GART TLB Walk Errors on Fam10h. We do this here * because this is always needed when GART is enabled, even in a * kernel which has no MCE support built in. - * BIOS should disable GartTlbWlk Errors themself. If - * it doesn't do it here as suggested by the BKDG. + * BIOS should disable GartTlbWlk Errors already. If + * it doesn't, do it here as suggested by the BKDG. * * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012 */ - u64 mask; - int err; - - err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); - if (err == 0) { - mask |= (1 << 10); - wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask); - } + msr_set_bit(MSR_AMD64_MCx_MASK(4), 10); /* * On family 10h BIOS may not have properly enabled WC+ support, @@ -733,10 +712,7 @@ static void init_amd(struct cpuinfo_x86 *c) * NOTE: we want to use the _safe accessors so as not to #GP kvm * guests on older kvm hosts. */ - - rdmsrl_safe(MSR_AMD64_BU_CFG2, &value); - value &= ~(1ULL << 24); - wrmsrl_safe(MSR_AMD64_BU_CFG2, value); + msr_clear_bit(MSR_AMD64_BU_CFG2, 24); if (cpu_has_amd_erratum(c, amd_erratum_383)) set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); -- cgit v1.2.3-55-g7522 From c0a639ad0bc6b178b46996bd1f821a04643e2bde Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 9 Mar 2014 18:05:25 +0100 Subject: x86, Intel: Convert to the new bit access MSR accessors ... and save some lines of code. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1394384725-10796-4-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin --- arch/x86/include/uapi/asm/msr-index.h | 9 ++++++--- arch/x86/kernel/cpu/intel.c | 30 +++++++----------------------- 2 files changed, 13 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index c19fc60ff062..045e6db6f58a 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -368,14 +368,16 @@ #define THERM_LOG_THRESHOLD1 (1 << 9) /* MISC_ENABLE bits: architectural */ -#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) +#define MSR_BIT_FAST_STRING 0 +#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << MSR_BIT_FAST_STRING) #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) #define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) #define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) #define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) #define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) -#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) +#define MSR_BIT_LIMIT_CPUID 22 +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_BIT_LIMIT_CPUID); #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) #define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) @@ -385,7 +387,8 @@ #define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) #define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) #define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) -#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) +#define MSR_BIT_PRF_DIS 9 +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << MSR_BIT_PRF_DIS) #define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) #define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) #define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 5cd9bfabd645..44ca6317af43 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -31,11 +31,7 @@ static void early_init_intel(struct cpuinfo_x86 *c) /* Unmask CPUID levels if masked: */ if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { - rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); - - if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) { - misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; - wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); + if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_LIMIT_CPUID) > 0) { c->cpuid_level = cpuid_eax(0); get_cpu_cap(c); } @@ -129,16 +125,9 @@ static void early_init_intel(struct cpuinfo_x86 *c) * Ingo Molnar reported a Pentium D (model 6) and a Xeon * (model 2) with the same problem. */ - if (c->x86 == 15) { - rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); - - if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING) { - printk(KERN_INFO "kmemcheck: Disabling fast string operations\n"); - - misc_enable &= ~MSR_IA32_MISC_ENABLE_FAST_STRING; - wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); - } - } + if (c->x86 == 15) + if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_FAST_STRING) > 0) + pr_info("kmemcheck: Disabling fast string operations\n"); #endif /* @@ -197,8 +186,6 @@ static void intel_smp_check(struct cpuinfo_x86 *c) static void intel_workarounds(struct cpuinfo_x86 *c) { - unsigned long lo, hi; - #ifdef CONFIG_X86_F00F_BUG /* * All current models of Pentium and Pentium with MMX technology CPUs @@ -229,12 +216,9 @@ static void intel_workarounds(struct cpuinfo_x86 *c) * Hardware prefetcher may cause stale data to be loaded into the cache. */ if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { - rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); - if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) { - printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); - printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); - lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; - wrmsr(MSR_IA32_MISC_ENABLE, lo, hi); + if (msr_set_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_PRF_DIS) > 0) { + pr_info("CPU: C0 stepping P4 Xeon detected.\n"); + pr_info("CPU: Disabling hardware prefetching (Errata 037)\n"); } } -- cgit v1.2.3-55-g7522 From 0b131be8d4125b32eb5b94e84f4f9dee6a0ef797 Mon Sep 17 00:00:00 2001 From: H. Peter Anvin Date: Thu, 13 Mar 2014 15:40:52 -0700 Subject: x86, intel: Make MSR_IA32_MISC_ENABLE bit constants systematic Replace somewhat arbitrary constants for bits in MSR_IA32_MISC_ENABLE with verbose but systematic ones. Add _BIT defines for all the rest of them, too. Signed-off-by: H. Peter Anvin --- arch/x86/include/uapi/asm/msr-index.h | 78 ++++++++++++++++++++++------------- arch/x86/kernel/cpu/intel.c | 10 +++-- 2 files changed, 57 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index 045e6db6f58a..4924f4be2b99 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h @@ -368,36 +368,58 @@ #define THERM_LOG_THRESHOLD1 (1 << 9) /* MISC_ENABLE bits: architectural */ -#define MSR_BIT_FAST_STRING 0 -#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << MSR_BIT_FAST_STRING) -#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) -#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) -#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) -#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) -#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) -#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) -#define MSR_BIT_LIMIT_CPUID 22 -#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_BIT_LIMIT_CPUID); -#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) -#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) +#define MSR_IA32_MISC_ENABLE_FAST_STRING_BIT 0 +#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << MSR_IA32_MISC_ENABLE_FAST_STRING_BIT) +#define MSR_IA32_MISC_ENABLE_TCC_BIT 1 +#define MSR_IA32_MISC_ENABLE_TCC (1ULL << MSR_IA32_MISC_ENABLE_TCC_BIT) +#define MSR_IA32_MISC_ENABLE_EMON_BIT 7 +#define MSR_IA32_MISC_ENABLE_EMON (1ULL << MSR_IA32_MISC_ENABLE_EMON_BIT) +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT 11 +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT) +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT 12 +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT) +#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT 16 +#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT) +#define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18 +#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT) +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22 +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT); +#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23 +#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34 +#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT) /* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ -#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) -#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) -#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) -#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) -#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) -#define MSR_BIT_PRF_DIS 9 -#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << MSR_BIT_PRF_DIS) -#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) -#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) -#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) -#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) -#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) -#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) -#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) -#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) -#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) +#define MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT 2 +#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT) +#define MSR_IA32_MISC_ENABLE_TM1_BIT 3 +#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << MSR_IA32_MISC_ENABLE_TM1_BIT) +#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT 4 +#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT 6 +#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT 8 +#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT) +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT 9 +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_FERR_BIT 10 +#define MSR_IA32_MISC_ENABLE_FERR (1ULL << MSR_IA32_MISC_ENABLE_FERR_BIT) +#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT 10 +#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT) +#define MSR_IA32_MISC_ENABLE_TM2_BIT 13 +#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << MSR_IA32_MISC_ENABLE_TM2_BIT) +#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT 19 +#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT 20 +#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT) +#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT 24 +#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT) +#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT 37 +#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT 38 +#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT) +#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT 39 +#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT) #define MSR_IA32_TSC_DEADLINE 0x000006E0 diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 44ca6317af43..34bbb555e269 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -31,7 +31,8 @@ static void early_init_intel(struct cpuinfo_x86 *c) /* Unmask CPUID levels if masked: */ if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { - if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_LIMIT_CPUID) > 0) { + if (msr_clear_bit(MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) { c->cpuid_level = cpuid_eax(0); get_cpu_cap(c); } @@ -126,7 +127,8 @@ static void early_init_intel(struct cpuinfo_x86 *c) * (model 2) with the same problem. */ if (c->x86 == 15) - if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_FAST_STRING) > 0) + if (msr_clear_bit(MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_FAST_STRING_BIT) > 0) pr_info("kmemcheck: Disabling fast string operations\n"); #endif @@ -216,7 +218,9 @@ static void intel_workarounds(struct cpuinfo_x86 *c) * Hardware prefetcher may cause stale data to be loaded into the cache. */ if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { - if (msr_set_bit(MSR_IA32_MISC_ENABLE, MSR_BIT_PRF_DIS) > 0) { + if (msr_set_bit(MSR_IA32_MISC_ENABLE, + MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT) + > 0) { pr_info("CPU: C0 stepping P4 Xeon detected.\n"); pr_info("CPU: Disabling hardware prefetching (Errata 037)\n"); } -- cgit v1.2.3-55-g7522 From 81827ed8d85e892311965dc9ec4120b2b2e745bd Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 13 Mar 2014 13:04:36 +0100 Subject: perf/x86/uncore: Fix missing end markers for SNB/IVB/HSW IMC PMU This patch fixes a bug with the SNB/IVB/HSW uncore mmeory controller support. The PCI Ids tables for the memory controller were missing end markers. That could cause random crashes on boot during or after PCI device registration. Signed-off-by: Stephane Erainan Cc: peterz@infradead.org Cc: zheng.z.yan@intel.com Cc: bp@alien8.de Cc: ak@linux.intel.com Link: http://lkml.kernel.org/r/20140313120436.GA14236@quad Signed-off-by: Ingo Molnar -- --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index dfd50ea5ee0c..618d502a7026 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1989,6 +1989,7 @@ static DEFINE_PCI_DEVICE_TABLE(snb_uncore_pci_ids) = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC), .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, + { /* end: all zeroes */ }, }; static DEFINE_PCI_DEVICE_TABLE(ivb_uncore_pci_ids) = { @@ -1996,6 +1997,7 @@ static DEFINE_PCI_DEVICE_TABLE(ivb_uncore_pci_ids) = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC), .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, + { /* end: all zeroes */ }, }; static DEFINE_PCI_DEVICE_TABLE(hsw_uncore_pci_ids) = { @@ -2003,6 +2005,7 @@ static DEFINE_PCI_DEVICE_TABLE(hsw_uncore_pci_ids) = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, + { /* end: all zeroes */ }, }; static struct pci_driver snb_uncore_pci_driver = { -- cgit v1.2.3-55-g7522 From 847d7970defb45540735b3fb4e88471c27cacd85 Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Thu, 13 Mar 2014 19:43:01 +0800 Subject: x86/amd/numa: Fix northbridge quirk to assign correct NUMA node For systems with multiple servers and routed fabric, all northbridges get assigned to the first server. Fix this by also using the node reported from the PCI bus. For single-fabric systems, the northbriges are on PCI bus 0 by definition, which are on NUMA node 0 by definition, so this is invarient on most systems. Tested on fam10h and fam15h single and multi-fabric systems and candidate for stable. Signed-off-by: Daniel J Blueman Acked-by: Steffen Persvold Acked-by: Borislav Petkov Cc: Link: http://lkml.kernel.org/r/1394710981-3596-1-git-send-email-daniel@numascale.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 7c6acd4b8995..ff898bbf579d 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -529,7 +529,7 @@ static void quirk_amd_nb_node(struct pci_dev *dev) return; pci_read_config_dword(nb_ht, 0x60, &val); - node = val & 7; + node = pcibus_to_node(dev->bus) | (val & 7); /* * Some hardware may return an invalid node ID, * so check it first: -- cgit v1.2.3-55-g7522 From 443fc8a3e01cef95f2c7c26605457d49e63da6b1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 11 Mar 2014 10:49:20 +0100 Subject: s390/perf: make print_debug_cf() static Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/perf_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 5d2dfa31c4ef..61595c1f0a0f 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -121,7 +121,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) : PERF_RECORD_MISC_KERNEL; } -void print_debug_cf(void) +static void print_debug_cf(void) { struct cpumf_ctr_info cf_info; int cpu = smp_processor_id(); -- cgit v1.2.3-55-g7522 From 818a330c4e1be9c39fa7ca9221e044907d92b4bb Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 14 Mar 2014 12:01:08 +0100 Subject: s390/ptrace: add support for PTRACE_SINGLEBLOCK The PTRACE_SINGLEBLOCK option is used to get control whenever the inferior has executed a successful branch. The PER option to implement block stepping is successful-branching event, bit 32 in the PER-event mask. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ptrace.h | 1 + arch/s390/include/asm/thread_info.h | 1 + arch/s390/include/uapi/asm/ptrace.h | 6 ++++++ arch/s390/kernel/ptrace.c | 13 ++++++++++++- 4 files changed, 20 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 9c82cebddabd..f4783c0b7b43 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -83,6 +83,7 @@ struct per_struct_kernel { * These are defined as per linux/ptrace.h, which see. */ #define arch_has_single_step() (1) +#define arch_has_block_step() (1) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index d2e53d667a92..3ccd71b90345 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -92,6 +92,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ #define TIF_SINGLE_STEP 20 /* This task is single stepped */ +#define TIF_BLOCK_STEP 21 /* This task is block stepped */ #define _TIF_SYSCALL (1<. + */ +#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */ + /* * PT_PROT definition is loosely based on hppa bsd definition in * gdb/hppab-nat.c diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f6be6087a0e9..4ac8fafec95f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -85,7 +85,10 @@ void update_cr_regs(struct task_struct *task) /* merge TIF_SINGLE_STEP into user specified PER registers. */ if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { - new.control |= PER_EVENT_IFETCH; + if (test_tsk_thread_flag(task, TIF_BLOCK_STEP)) + new.control |= PER_EVENT_BRANCH; + else + new.control |= PER_EVENT_IFETCH; #ifdef CONFIG_64BIT new.control |= PER_CONTROL_SUSPENSION; new.control |= PER_EVENT_TRANSACTION_END; @@ -107,14 +110,22 @@ void update_cr_regs(struct task_struct *task) void user_enable_single_step(struct task_struct *task) { + clear_tsk_thread_flag(task, TIF_BLOCK_STEP); set_tsk_thread_flag(task, TIF_SINGLE_STEP); } void user_disable_single_step(struct task_struct *task) { + clear_tsk_thread_flag(task, TIF_BLOCK_STEP); clear_tsk_thread_flag(task, TIF_SINGLE_STEP); } +void user_enable_block_step(struct task_struct *task) +{ + set_tsk_thread_flag(task, TIF_SINGLE_STEP); + set_tsk_thread_flag(task, TIF_BLOCK_STEP); +} + /* * Called by kernel/ptrace.c when detaching.. * -- cgit v1.2.3-55-g7522 From 09504a7d76452c5891ff3bad7f8892376eb133f2 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 7 Feb 2014 21:50:26 +0100 Subject: ARM: sunxi: dt: Convert to the new irq controller compatibles Switch the device tree to the new compatibles introduced in the irqchip drivers to have a common pattern accross all Allwinner SoCs. Signed-off-by: Maxime Ripard Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Thomas Gleixner --- arch/arm/boot/dts/sun4i-a10.dtsi | 2 +- arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +- arch/arm/boot/dts/sun5i-a13.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index d4d2763f4794..491ce8fdf9ca 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -331,7 +331,7 @@ }; intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; + compatible = "allwinner,sun4i-a10-ic"; reg = <0x01c20400 0x400>; interrupt-controller; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 79fd412005b0..a005a5657755 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -294,7 +294,7 @@ }; intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; + compatible = "allwinner,sun4i-a10-ic"; reg = <0x01c20400 0x400>; interrupt-controller; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index c463fd730c91..49f2f1bcc24d 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -275,7 +275,7 @@ ranges; intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; + compatible = "allwinner,sun4i-a10-ic"; reg = <0x01c20400 0x400>; interrupt-controller; #interrupt-cells = <1>; -- cgit v1.2.3-55-g7522 From f5868f05dc976ecd849d2a8115fab80301c127cd Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sun, 9 Feb 2014 14:32:25 +0100 Subject: MIPS: Replace CONFIG_MIPS64 and CONFIG_MIPS32_R2 Commit 597ce1723e0f ("MIPS: Support for 64-bit FP with O32 binaries") introduced references to two undefined Kconfig macros. CONFIG_MIPS32_R2 should clearly be replaced with CONFIG_CPU_MIPS32_R2. And CONFIG_MIPS64 should be replaced with CONFIG_64BIT. Signed-off-by: Paul Bolle Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/6522/ Tested-by: Aaro Koskinen Signed-off-by: Ralf Baechle --- arch/mips/include/asm/asmmacro.h | 4 ++-- arch/mips/include/asm/fpu.h | 2 +- arch/mips/kernel/r4k_fpu.S | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 3220c93ea981..69a9a22d014a 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -106,7 +106,7 @@ .endm .macro fpu_save_double thread status tmp -#if defined(CONFIG_MIPS64) || defined(CONFIG_CPU_MIPS32_R2) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) sll \tmp, \status, 5 bgez \tmp, 10f fpu_save_16odd \thread @@ -159,7 +159,7 @@ .endm .macro fpu_restore_double thread status tmp -#if defined(CONFIG_MIPS64) || defined(CONFIG_CPU_MIPS32_R2) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) sll \tmp, \status, 5 bgez \tmp, 10f # 16 register mode? diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 6b9749540edf..58e50cbdb1a6 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -57,7 +57,7 @@ static inline int __enable_fpu(enum fpu_mode mode) return 0; case FPU_64BIT: -#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_MIPS64)) +#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) /* we only have a 32-bit FPU */ return SIGFPE; #endif diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 253b2fb52026..841ffc234464 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -35,9 +35,9 @@ LEAF(_save_fp_context) cfc1 t1, fcr31 -#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS32_R2) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) .set push -#ifdef CONFIG_MIPS32_R2 +#ifdef CONFIG_CPU_MIPS32_R2 .set mips64r2 mfc0 t0, CP0_STATUS sll t0, t0, 5 @@ -148,9 +148,9 @@ LEAF(_save_fp_context32) LEAF(_restore_fp_context) EX lw t0, SC_FPC_CSR(a0) -#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS32_R2) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) .set push -#ifdef CONFIG_MIPS32_R2 +#ifdef CONFIG_CPU_MIPS32_R2 .set mips64r2 mfc0 t0, CP0_STATUS sll t0, t0, 5 -- cgit v1.2.3-55-g7522 From b616365e6dafb5d7c1cf2a8b6e8cb376a3f4a387 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Fri, 7 Feb 2014 22:31:33 +0800 Subject: MIPS: FPU: Fix conflict of register usage In _restore_fp_context/_restore_fp_context32, t0 is used for both CP0_Status and CP1_FCSR. This is a mistake and cause FP exeception on boot, so fix it. Signed-off-by: Huacai Chen Tested-by: Aaro Koskinen Tested-by: Andreas Barth Cc: John Crispin Cc: Steven J. Hill Cc: Aurelien Jarno Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Patchwork: https://patchwork.linux-mips.org/patch/6507/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/r4k_fpu.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 841ffc234464..73b0ddf910d4 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -146,7 +146,7 @@ LEAF(_save_fp_context32) * - cp1 status/control register */ LEAF(_restore_fp_context) - EX lw t0, SC_FPC_CSR(a0) + EX lw t1, SC_FPC_CSR(a0) #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) .set push @@ -191,7 +191,7 @@ LEAF(_restore_fp_context) EX ldc1 $f26, SC_FPREGS+208(a0) EX ldc1 $f28, SC_FPREGS+224(a0) EX ldc1 $f30, SC_FPREGS+240(a0) - ctc1 t0, fcr31 + ctc1 t1, fcr31 jr ra li v0, 0 # success END(_restore_fp_context) @@ -199,7 +199,7 @@ LEAF(_restore_fp_context) #ifdef CONFIG_MIPS32_COMPAT LEAF(_restore_fp_context32) /* Restore an o32 sigcontext. */ - EX lw t0, SC32_FPC_CSR(a0) + EX lw t1, SC32_FPC_CSR(a0) mfc0 t0, CP0_STATUS sll t0, t0, 5 @@ -239,7 +239,7 @@ LEAF(_restore_fp_context32) EX ldc1 $f26, SC32_FPREGS+208(a0) EX ldc1 $f28, SC32_FPREGS+224(a0) EX ldc1 $f30, SC32_FPREGS+240(a0) - ctc1 t0, fcr31 + ctc1 t1, fcr31 jr ra li v0, 0 # success END(_restore_fp_context32) -- cgit v1.2.3-55-g7522 From 3be1a5c4f75989cf457f13f38ff0913dff6d4996 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 4 Mar 2014 01:10:04 +0000 Subject: arm64: enable generic CPU feature modalias matching for this architecture This enables support for the generic CPU feature modalias implementation that wires up optional CPU features to udev based module autoprobing. A file is provided that maps CPU feature numbers to elf_hwcap bits, which is the standard way on arm64 to advertise optional CPU features both internally and to user space. Signed-off-by: Ard Biesheuvel [catalin.marinas@arm.com: removed unnecessary "!!"] Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/cpufeature.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm64/include/asm/cpufeature.h (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 507ab6e53522..8cabe36e285c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -16,6 +16,7 @@ config ARM64 select DCACHE_WORD_ACCESS select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select GENERIC_CPU_AUTOPROBE select GENERIC_IOMAP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h new file mode 100644 index 000000000000..cd4ac0516488 --- /dev/null +++ b/arch/arm64/include/asm/cpufeature.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_CPUFEATURE_H +#define __ASM_CPUFEATURE_H + +#include + +/* + * In the arm64 world (as in the ARM world), elf_hwcap is used both internally + * in the kernel and for user space to keep track of which optional features + * are supported by the current system. So let's map feature 'x' to HWCAP_x. + * Note that HWCAP_x constants are bit fields so we need to take the log. + */ + +#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap)) +#define cpu_feature(x) ilog2(HWCAP_ ## x) + +static inline bool cpu_have_feature(unsigned int num) +{ + return elf_hwcap & (1UL << num); +} + +#endif -- cgit v1.2.3-55-g7522 From c209f79940ac0c75ae8d2f503a2b9d86255e266c Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 14 Mar 2014 17:47:05 +0000 Subject: arm64: rwsem: use asm-generic rwsem implementation asm-generic offers an atomic-add based rwsem implementation, which can avoid the need for heavier, spinlock-based synchronisation on the fast path. This patch makes use of the optimised implementation for arm64 CPUs. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 2 +- arch/arm64/include/asm/Kbuild | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 8cabe36e285c..4723fc14cf2d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -77,7 +77,7 @@ config LOCKDEP_SUPPORT config TRACE_IRQFLAGS_SUPPORT def_bool y -config RWSEM_GENERIC_SPINLOCK +config RWSEM_XCHGADD_ALGORITHM def_bool y config GENERIC_HWEIGHT diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 71c53ecfcc3a..41cde70943fb 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -29,6 +29,7 @@ generic-y += pci.h generic-y += poll.h generic-y += posix_types.h generic-y += resource.h +generic-y += rwsem.h generic-y += scatterlist.h generic-y += sections.h generic-y += segment.h -- cgit v1.2.3-55-g7522 From 9c7e535fcc1725fc2e2d4f0d9dd14137f0243e23 Mon Sep 17 00:00:00 2001 From: Steve Capper Date: Tue, 25 Feb 2014 10:02:13 +0000 Subject: arm64: mm: Route pmd thp functions through pte equivalents Rather than have separate hugetlb and transparent huge page pmd manipulation functions, re-wire our thp functions to simply call the pte equivalents. This allows THP to take advantage of the new PTE_WRITE logic introduced in: c2c93e5 arm64: mm: Introduce PTE_WRITE To represent splitting THPs we use the PTE_SPECIAL bit as this is not used for pmds. Signed-off-by: Steve Capper Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/pgtable.h | 52 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 28 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 72c9ac38cdd9..ae10350f75ec 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -227,36 +227,36 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, #define __HAVE_ARCH_PTE_SPECIAL -/* - * Software PMD bits for THP - */ +static inline pte_t pmd_pte(pmd_t pmd) +{ + return __pte(pmd_val(pmd)); +} -#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55) -#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57) +static inline pmd_t pte_pmd(pte_t pte) +{ + return __pmd(pte_val(pte)); +} /* * THP definitions. */ -#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF) - -#define __HAVE_ARCH_PMD_WRITE -#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY)) #ifdef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) -#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING) +#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd)) #endif -#define PMD_BIT_FUNC(fn,op) \ -static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; } +#define pmd_young(pmd) pte_young(pmd_pte(pmd)) +#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) +#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd))) +#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) +#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) +#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) +#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) +#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK)) -PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY); -PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF); -PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING); -PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY); -PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY); -PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF); -PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK); +#define __HAVE_ARCH_PMD_WRITE +#define pmd_write(pmd) pte_write(pmd_pte(pmd)) #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT)) @@ -266,15 +266,6 @@ PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK); #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) -static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) -{ - const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN | - PMD_SECT_RDONLY | PMD_SECT_PROT_NONE | - PMD_SECT_VALID; - pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask); - return pmd; -} - #define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd) static inline int has_transparent_hugepage(void) @@ -383,6 +374,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return pte; } +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) +{ + return pte_pmd(pte_modify(pmd_pte(pmd), newprot)); +} + extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; -- cgit v1.2.3-55-g7522 From 7f02c463057fc527f52066742b84d9d89b22e83d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 10 Feb 2014 18:42:57 +0000 Subject: MIPS: Octeon: Fix fall through on bar type OCTEON_DMA_BAR_TYPE_SMALL Bar type OCTEON_DMA_BAR_TYPE_SMALL assigns lo and hi addresses and then falls through to OCTEON_DMA_BAR_TYPE_BIG that re-assignes lo and hi addresses with totally different values. Add a break so we don't fall through. Signed-off-by: Colin Ian King Acked-by: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/6529/ Signed-off-by: Ralf Baechle --- arch/mips/pci/msi-octeon.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c index d37be36dc659..2b91b0e61566 100644 --- a/arch/mips/pci/msi-octeon.c +++ b/arch/mips/pci/msi-octeon.c @@ -150,6 +150,7 @@ msi_irq_allocated: msg.address_lo = ((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff; msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32; + break; case OCTEON_DMA_BAR_TYPE_BIG: /* When using big bar, Bar 0 is based at 0 */ msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff; -- cgit v1.2.3-55-g7522 From a8031d2ce15bdb90baeae02d7a231ccece73da8b Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Wed, 22 Jan 2014 14:39:57 +0000 Subject: MIPS: asm: syscall: Fix copying system call arguments The syscall_get_arguments function expects the arguments to be copied to the '*args' argument but instead a local variable was used to hold the system call argument. As a result of which, this variable was never passed to the filter and any filter testing the system call arguments would fail. This is fixed by passing the '*args' variable as the destination memory for the system call arguments. Signed-off-by: Markos Chandras Reviewed-by: Paul Burton Reviewed-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6402/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 5ce530fcb11f..a7e8a532f144 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -86,11 +86,10 @@ static inline void syscall_get_arguments(struct task_struct *task, unsigned int i, unsigned int n, unsigned long *args) { - unsigned long arg; int ret; while (n--) - ret |= mips_get_syscall_arg(&arg, task, regs, i++); + ret |= mips_get_syscall_arg(args++, task, regs, i++); /* * No way to communicate an error because this is a void function. -- cgit v1.2.3-55-g7522 From 86ca57b5a5525dbf89fc2a3285781fae807276b0 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Mon, 17 Mar 2014 12:14:13 +0100 Subject: MIPS: Fix syscall tracing interface Fix pointer computation for stack-based arguments. Signed-off-by: Lars Persson Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6620/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/syscall.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index a7e8a532f144..f35b131977e6 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -40,14 +40,14 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg, #ifdef CONFIG_32BIT case 4: case 5: case 6: case 7: - return get_user(*arg, (int *)usp + 4 * n); + return get_user(*arg, (int *)usp + n); #endif #ifdef CONFIG_64BIT case 4: case 5: case 6: case 7: #ifdef CONFIG_MIPS32_O32 if (test_thread_flag(TIF_32BIT_REGS)) - return get_user(*arg, (int *)usp + 4 * n); + return get_user(*arg, (int *)usp + n); else #endif *arg = regs->regs[4 + n]; -- cgit v1.2.3-55-g7522 From a4671094227d11985c06ee1178d7205c5fd39f8a Mon Sep 17 00:00:00 2001 From: Viller Hsiao Date: Sat, 22 Feb 2014 15:46:49 +0800 Subject: MIPS: ftrace: Fix icache flush range error In 32-bit mode, the start address passed to flush_icache_range is shifted by 4 bytes before the second safe_store_code() call. This causes system crash from time to time because the first 4 bytes might not be flushed properly. This bug exists since linux-3.8. Also remove obsoleted comment while at it. Signed-off-by: Viller Hsiao Cc: linux-mips@linux-mips.org Cc: rostedt@goodmis.org Cc: fweisbec@gmail.com Cc: mingo@redhat.com Cc: Qais.Yousef@imgtec.com Patchwork: https://patchwork.linux-mips.org/patch/6586/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/ftrace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 185ba258361b..374ed74cd516 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -111,11 +111,10 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, safe_store_code(new_code1, ip, faulted); if (unlikely(faulted)) return -EFAULT; - ip += 4; - safe_store_code(new_code2, ip, faulted); + safe_store_code(new_code2, ip + 4, faulted); if (unlikely(faulted)) return -EFAULT; - flush_icache_range(ip, ip + 8); /* original ip + 12 */ + flush_icache_range(ip, ip + 8); return 0; } #endif -- cgit v1.2.3-55-g7522 From 184d0f0c06afb8f3b583db7b8d712caae06a24dd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 14 Mar 2014 18:02:01 +0100 Subject: s390: update defconfigs Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/configs/default_defconfig | 46 ++++++++++++++++++++++++++++----- arch/s390/configs/gcov_defconfig | 33 ++++++++++++++++++----- arch/s390/configs/performance_defconfig | 33 ++++++++++++++++++----- arch/s390/configs/zfcpdump_defconfig | 1 - arch/s390/defconfig | 10 +++++++ 5 files changed, 103 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig index e0af2ee58751..ddaae2f5c913 100644 --- a/arch/s390/configs/default_defconfig +++ b/arch/s390/configs/default_defconfig @@ -46,6 +46,7 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_DEFAULT_DEADLINE=y CONFIG_MARCH_Z9_109=y +CONFIG_NR_CPUS=256 CONFIG_PREEMPT=y CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y @@ -58,7 +59,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -CONFIG_ZFCPDUMP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -101,7 +101,6 @@ CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -111,6 +110,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y @@ -135,7 +135,17 @@ CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NETFILTER_TPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_CT=m +CONFIG_NFT_RBTREE=m +CONFIG_NFT_HASH=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_NAT=m +CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -204,7 +214,9 @@ CONFIG_IP_SET_HASH_IP=m CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NETPORTNET=m CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m @@ -227,6 +239,11 @@ CONFIG_IP_VS_FTP=m CONFIG_IP_VS_PE_SIP=m CONFIG_NF_CONNTRACK_IPV4=m # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_TABLES_IPV4=m +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NFT_CHAIN_NAT_IPV4=m +CONFIG_NF_TABLES_ARP=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -249,6 +266,9 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_TABLES_IPV6=m +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -268,6 +288,7 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_NF_NAT_IPV6=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m CONFIG_NET_SCTPPROBE=m CONFIG_RDS=m CONFIG_RDS_RDMA=m @@ -314,6 +335,7 @@ CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m @@ -381,8 +403,8 @@ CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m -CONFIG_DM_RAID=m CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m @@ -434,7 +456,6 @@ CONFIG_TN3270_FS=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_SOFT_WATCHDOG=m -CONFIG_ZVM_WATCHDOG=m # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_INFINIBAND=m @@ -534,13 +555,23 @@ CONFIG_UNUSED_SYMBOLS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_PAGEALLOC=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_SELFTEST=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_WORK=y +CONFIG_DEBUG_OBJECTS_RCU_HEAD=y +CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y CONFIG_SLUB_DEBUG_ON=y CONFIG_SLUB_STATS=y +CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_VM=y CONFIG_DEBUG_VM_RB=y CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m CONFIG_DEBUG_PER_CPU_MAPS=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_HUNG_TASK=y CONFIG_TIMER_STATS=y CONFIG_DEBUG_RT_MUTEXES=y CONFIG_RT_MUTEX_TESTER=y @@ -573,9 +604,11 @@ CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_KPROBE_EVENT is not set CONFIG_LKDTM=m +CONFIG_TEST_LIST_SORT=y CONFIG_KPROBES_SANITY_TEST=y -CONFIG_RBTREE_TEST=m +CONFIG_RBTREE_TEST=y CONFIG_INTERVAL_TREE_TEST=m +CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y CONFIG_DMA_API_DEBUG=y # CONFIG_STRICT_DEVMEM is not set @@ -638,7 +671,6 @@ CONFIG_CRYPTO_AES_S390=m CONFIG_CRYPTO_GHASH_S390=m CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m -CONFIG_PUBLIC_KEY_ALGO_RSA=m CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_CRC7=m CONFIG_CRC8=m diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig index b9f6b4cab927..c81a74e3e25a 100644 --- a/arch/s390/configs/gcov_defconfig +++ b/arch/s390/configs/gcov_defconfig @@ -46,6 +46,7 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_DEFAULT_DEADLINE=y CONFIG_MARCH_Z9_109=y +CONFIG_NR_CPUS=256 CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -56,7 +57,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -CONFIG_ZFCPDUMP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -99,7 +99,6 @@ CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -109,6 +108,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y @@ -133,7 +133,17 @@ CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NETFILTER_TPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_CT=m +CONFIG_NFT_RBTREE=m +CONFIG_NFT_HASH=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_NAT=m +CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -202,7 +212,9 @@ CONFIG_IP_SET_HASH_IP=m CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NETPORTNET=m CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m @@ -225,6 +237,11 @@ CONFIG_IP_VS_FTP=m CONFIG_IP_VS_PE_SIP=m CONFIG_NF_CONNTRACK_IPV4=m # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_TABLES_IPV4=m +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NFT_CHAIN_NAT_IPV4=m +CONFIG_NF_TABLES_ARP=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -247,6 +264,9 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_TABLES_IPV6=m +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -266,6 +286,7 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_NF_NAT_IPV6=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m CONFIG_NET_SCTPPROBE=m CONFIG_RDS=m CONFIG_RDS_RDMA=m @@ -311,6 +332,7 @@ CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m @@ -378,8 +400,8 @@ CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m -CONFIG_DM_RAID=m CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m @@ -431,7 +453,6 @@ CONFIG_TN3270_FS=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_SOFT_WATCHDOG=m -CONFIG_ZVM_WATCHDOG=m # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_INFINIBAND=m @@ -540,6 +561,7 @@ CONFIG_BLK_DEV_IO_TRACE=y CONFIG_LKDTM=m CONFIG_RBTREE_TEST=m CONFIG_INTERVAL_TREE_TEST=m +CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y # CONFIG_STRICT_DEVMEM is not set CONFIG_S390_PTDUMP=y @@ -601,7 +623,6 @@ CONFIG_CRYPTO_AES_S390=m CONFIG_CRYPTO_GHASH_S390=m CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m -CONFIG_PUBLIC_KEY_ALGO_RSA=m CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_CRC7=m CONFIG_CRC8=m diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index 91087b43e8fa..b5ba8fe1cc64 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig @@ -44,6 +44,7 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_DEFAULT_DEADLINE=y CONFIG_MARCH_Z9_109=y +CONFIG_NR_CPUS=256 CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -54,7 +55,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_S390=y CONFIG_CHSC_SCH=y CONFIG_CRASH_DUMP=y -CONFIG_ZFCPDUMP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -97,7 +97,6 @@ CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m @@ -107,6 +106,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m CONFIG_IPV6_GRE=m CONFIG_IPV6_MULTIPLE_TABLES=y @@ -131,7 +131,17 @@ CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NETFILTER_TPROXY=m +CONFIG_NF_TABLES=m +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_CT=m +CONFIG_NFT_RBTREE=m +CONFIG_NFT_HASH=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_NAT=m +CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -200,7 +210,9 @@ CONFIG_IP_SET_HASH_IP=m CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NETPORTNET=m CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m @@ -223,6 +235,11 @@ CONFIG_IP_VS_FTP=m CONFIG_IP_VS_PE_SIP=m CONFIG_NF_CONNTRACK_IPV4=m # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_TABLES_IPV4=m +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NFT_CHAIN_NAT_IPV4=m +CONFIG_NF_TABLES_ARP=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -245,6 +262,9 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_TABLES_IPV6=m +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -264,6 +284,7 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_NF_NAT_IPV6=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m CONFIG_NET_SCTPPROBE=m CONFIG_RDS=m CONFIG_RDS_RDMA=m @@ -309,6 +330,7 @@ CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_GACT=m @@ -376,8 +398,8 @@ CONFIG_BLK_DEV_DM=m CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m -CONFIG_DM_RAID=m CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m @@ -429,7 +451,6 @@ CONFIG_TN3270_FS=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_SOFT_WATCHDOG=m -CONFIG_ZVM_WATCHDOG=m # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_INFINIBAND=m @@ -532,6 +553,7 @@ CONFIG_LATENCYTOP=y CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_KPROBE_EVENT is not set CONFIG_LKDTM=m +CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y # CONFIG_STRICT_DEVMEM is not set CONFIG_S390_PTDUMP=y @@ -593,7 +615,6 @@ CONFIG_CRYPTO_AES_S390=m CONFIG_CRYPTO_GHASH_S390=m CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m -CONFIG_PUBLIC_KEY_ALGO_RSA=m CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_CRC7=m CONFIG_CRC8=m diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index d725c4d956e4..cef073ca1f07 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -19,7 +19,6 @@ CONFIG_HZ_100=y # CONFIG_CHSC_SCH is not set # CONFIG_SCM_BUS is not set CONFIG_CRASH_DUMP=y -CONFIG_ZFCPDUMP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_SECCOMP is not set # CONFIG_IUCV is not set diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 33f57514f424..4557cb7ffddf 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -40,6 +40,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_IBM_PARTITION=y CONFIG_DEFAULT_DEADLINE=y CONFIG_MARCH_Z196=y +CONFIG_NR_CPUS=256 CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -122,22 +123,31 @@ CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y +CONFIG_DETECT_HUNG_TASK=y CONFIG_TIMER_STATS=y +CONFIG_DEBUG_RT_MUTEXES=y CONFIG_PROVE_LOCKING=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_WRITECOUNT=y CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_SG=y CONFIG_DEBUG_NOTIFIERS=y CONFIG_PROVE_RCU=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_TRACE=y CONFIG_LATENCYTOP=y +CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_KPROBES_SANITY_TEST=y # CONFIG_STRICT_DEVMEM is not set +CONFIG_S390_PTDUMP=y CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m -- cgit v1.2.3-55-g7522 From 36a554021b44d146178ae98e598c9502a1269f7d Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 17 Mar 2014 11:31:28 +0100 Subject: hypfs: Add clarification for "weight_min" attribute The "weight_min" attribute got the wrong name. The value represents the number of non-stopped (operating) CPUS. Therefore add a note and rename the struct member to "ocpus". Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/hypfs/hypfs_vm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index 24908ce149f1..32040ace00ea 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c @@ -32,7 +32,7 @@ struct diag2fc_data { __u32 pcpus; __u32 lcpus; __u32 vcpus; - __u32 cpu_min; + __u32 ocpus; __u32 cpu_max; __u32 cpu_shares; __u32 cpu_use_samp; @@ -142,7 +142,12 @@ static int hpyfs_vm_create_guest(struct dentry *systems_dir, ATTRIBUTE(cpus_dir, "capped", capped_value); ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag); ATTRIBUTE(cpus_dir, "count", data->vcpus); - ATTRIBUTE(cpus_dir, "weight_min", data->cpu_min); + /* + * Note: The "weight_min" attribute got the wrong name. + * The value represents the number of non-stopped (operating) + * CPUS. + */ + ATTRIBUTE(cpus_dir, "weight_min", data->ocpus); ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max); ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares); -- cgit v1.2.3-55-g7522 From cf813db0b448b45b454f0983329c3c7b007f9ab7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 10 Mar 2014 14:50:16 +0100 Subject: s390/smp: limit number of cpus in possible cpu mask Limit the number of bits to the maximum number of cpus a machine can have. possible_cpu_mask typically will have more bits set than a machine may physically have. This results in wasted memory during per-cpu memory allocations, if the possible mask contains more cpus than physically possible for a given configuration. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sclp.h | 1 + arch/s390/kernel/smp.c | 8 ++++---- drivers/s390/char/sclp_early.c | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index abaca2275c7a..2f5e9932b4de 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -46,6 +46,7 @@ int sclp_cpu_configure(u8 cpu); int sclp_cpu_deconfigure(u8 cpu); unsigned long long sclp_get_rnmax(void); unsigned long long sclp_get_rzm(void); +unsigned int sclp_get_max_cpu(void); int sclp_sdias_blk_count(void); int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); int sclp_chp_configure(struct chp_id chpid); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index a7125b62a9a6..8827883310dd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -773,11 +773,11 @@ void __noreturn cpu_die(void) void __init smp_fill_possible_mask(void) { - unsigned int possible, cpu; + unsigned int possible, sclp, cpu; - possible = setup_possible_cpus; - if (!possible) - possible = MACHINE_IS_VM ? 64 : nr_cpu_ids; + sclp = sclp_get_max_cpu() ?: nr_cpu_ids; + possible = setup_possible_cpus ?: nr_cpu_ids; + possible = min(possible, sclp); for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) set_cpu_possible(cpu, true); } diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 2c6aac66e2b0..14196ea0fdf3 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -20,7 +20,9 @@ struct read_info_sccb { struct sccb_header header; /* 0-7 */ u16 rnmax; /* 8-9 */ u8 rnsize; /* 10 */ - u8 _reserved0[24 - 11]; /* 11-15 */ + u8 _reserved0[16 - 11]; /* 11-15 */ + u16 ncpurl; /* 16-17 */ + u8 _reserved7[24 - 18]; /* 18-23 */ u8 loadparm[8]; /* 24-31 */ u8 _reserved1[48 - 32]; /* 32-47 */ u64 facilities; /* 48-55 */ @@ -32,13 +34,16 @@ struct read_info_sccb { u8 _reserved4[100 - 92]; /* 92-99 */ u32 rnsize2; /* 100-103 */ u64 rnmax2; /* 104-111 */ - u8 _reserved5[4096 - 112]; /* 112-4095 */ + u8 _reserved5[120 - 112]; /* 112-119 */ + u16 hcpua; /* 120-121 */ + u8 _reserved6[4096 - 122]; /* 122-4095 */ } __packed __aligned(PAGE_SIZE); static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; static unsigned int sclp_con_has_vt220 __initdata; static unsigned int sclp_con_has_linemode __initdata; static unsigned long sclp_hsa_size; +static unsigned int sclp_max_cpu; static struct sclp_ipl_info sclp_ipl_info; u64 sclp_facilities; @@ -102,6 +107,15 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp_rzm <<= 20; + if (!sccb->hcpua) { + if (MACHINE_IS_VM) + sclp_max_cpu = 64; + else + sclp_max_cpu = sccb->ncpurl; + } else { + sclp_max_cpu = sccb->hcpua + 1; + } + /* Save IPL information */ sclp_ipl_info.is_valid = 1; if (sccb->flags & 0x2) @@ -129,6 +143,11 @@ unsigned long long sclp_get_rzm(void) return sclp_rzm; } +unsigned int sclp_get_max_cpu(void) +{ + return sclp_max_cpu; +} + /* * This function will be called after sclp_facilities_detect(), which gets * called from early.c code. The sclp_facilities_detect() function retrieves -- cgit v1.2.3-55-g7522 From 06e2e88292e9ea6f5a23ead2e9c5ccf8bbd99e93 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 14 Feb 2014 17:55:18 +0000 Subject: MIPS: mark O32+FP64 experimental for now Commit 597ce1723e0f "MIPS: Support for 64-bit FP with O32 binaries" introduced support for setting Status.FR=1 for O32 binaries with the EF_MIPS_FP64 ELF header flag set. Whilst this flag is currently supported by binutils it does introduce an ABI break within userland. Objects built with EF_MIPS_FP64 cannot be safely linked with those built without it since code in either object may assume behaviour specific to a value of FR. More recently there has been discussion around avoiding further fragmentation of the O32 ABI whilst still allowing the use of FR=1 and features such as MSA which depend upon it. Details of the plan to allow this are still being worked on, and whilst the kernel will need the ability to handle FR=1 with O32 tasks it is unclear what else it may need to provide to a userland which seeks to avoid another ABI break. In order to prevent the proliferation of userland which may rely upon the current EF_MIPS_FP64 behaviour this patch marks the kernel support for it experimental & disables it by default. Under current proposals it is likely that this support can simply be enabled again later, but possibly after the introduction of further interfaces with userland and support for the MIPS R5 UFR feature. Signed-off-by: Paul Burton Cc: Matthew Fortune Cc: linux-mips@linux-mips.org Cc: Paul Burton Patchwork: https://patchwork.linux-mips.org/patch/6549/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index dcae3a7035db..153447452d5e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2353,9 +2353,8 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config MIPS_O32_FP64_SUPPORT - bool "Support for O32 binaries using 64-bit FP" + bool "Support for O32 binaries using 64-bit FP (EXPERIMENTAL)" depends on 32BIT || MIPS32_O32 - default y help When this is enabled, the kernel will support use of 64-bit floating point registers with binaries using the O32 ABI along with the @@ -2367,7 +2366,14 @@ config MIPS_O32_FP64_SUPPORT of your kernel & potentially improve FP emulation performance by saying N here. - If unsure, say Y. + Although binutils currently supports use of this flag the details + concerning its effect upon the O32 ABI in userland are still being + worked on. In order to avoid userland becoming dependant upon current + behaviour before the details have been finalised, this option should + be considered experimental and only enabled by those working upon + said details. + + If unsure, say N. config USE_OF bool -- cgit v1.2.3-55-g7522 From 71b70ee9350f239ea021bbb737771ebd5d02c020 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Fri, 14 Mar 2014 17:53:18 -0600 Subject: arm64: Add APM X-Gene SoC 15Gbps Multi-purpose PHY DTS entries This patch adds the DTS entries for the APM X-Gene SoC 15Gbps Multi-purpose PHY driver. The PHY for SATA controller 2 and 3 are enabled by default. Signed-off-by: Loc Ho Signed-off-by: Tuan Phan Signed-off-by: Suman Tripathi Acked-by: Arnd Bergmann Signed-off-by: Tejun Heo --- arch/arm64/boot/dts/apm-storm.dtsi | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index d37d7369e260..6d4f493aac9a 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -176,6 +176,48 @@ reg-names = "csr-reg"; clock-output-names = "eth8clk"; }; + + sataphy1clk: sataphy1clk@1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy1clk"; + status = "disabled"; + csr-offset = <0x4>; + csr-mask = <0x00>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; + + sataphy2clk: sataphy1clk@1f22c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f22c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy2clk"; + status = "ok"; + csr-offset = <0x4>; + csr-mask = <0x3a>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; + + sataphy3clk: sataphy1clk@1f23c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f23c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sataphy3clk"; + status = "ok"; + csr-offset = <0x4>; + csr-mask = <0x3a>; + enable-offset = <0x0>; + enable-mask = <0x06>; + }; }; serial0: serial@1c020000 { @@ -187,5 +229,35 @@ interrupt-parent = <&gic>; interrupts = <0x0 0x4c 0x4>; }; + + phy1: phy@1f21a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f21a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy1clk 0>; + status = "disabled"; + apm,tx-boost-gain = <30 30 30 30 30 30>; + apm,tx-eye-tuning = <2 10 10 2 10 10>; + }; + + phy2: phy@1f22a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f22a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy2clk 0>; + status = "ok"; + apm,tx-boost-gain = <30 30 30 30 30 30>; + apm,tx-eye-tuning = <1 10 10 2 10 10>; + }; + + phy3: phy@1f23a000 { + compatible = "apm,xgene-phy"; + reg = <0x0 0x1f23a000 0x0 0x100>; + #phy-cells = <1>; + clocks = <&sataphy3clk 0>; + status = "ok"; + apm,tx-boost-gain = <31 31 31 31 31 31>; + apm,tx-eye-tuning = <2 10 10 2 10 10>; + }; }; }; -- cgit v1.2.3-55-g7522 From db8c0286d18c2d3eaec2c4da34767db0f4f6ffaa Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Fri, 14 Mar 2014 17:53:21 -0600 Subject: arm64: Add APM X-Gene SoC AHCI SATA host controller DTS entries This patch adds APM X-Gene SoC AHCI SATA host controller DTS entries. Signed-off-by: Loc Ho Signed-off-by: Tuan Phan Signed-off-by: Suman Tripathi Acked-by: Arnd Bergmann Signed-off-by: Tejun Heo --- arch/arm64/boot/dts/apm-storm.dtsi | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'arch') diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index 6d4f493aac9a..93f4b2dd9248 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -218,6 +218,45 @@ enable-offset = <0x0>; enable-mask = <0x06>; }; + + sata01clk: sata01clk@1f21c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f21c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata01clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; + + sata23clk: sata23clk@1f22c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f22c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata23clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; + + sata45clk: sata45clk@1f23c000 { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <&socplldiv2 0>; + reg = <0x0 0x1f23c000 0x0 0x1000>; + reg-names = "csr-reg"; + clock-output-names = "sata45clk"; + csr-offset = <0x4>; + csr-mask = <0x05>; + enable-offset = <0x0>; + enable-mask = <0x39>; + }; }; serial0: serial@1c020000 { @@ -259,5 +298,46 @@ apm,tx-boost-gain = <31 31 31 31 31 31>; apm,tx-eye-tuning = <2 10 10 2 10 10>; }; + + sata1: sata@1a000000 { + compatible = "apm,xgene-ahci"; + reg = <0x0 0x1a000000 0x0 0x1000>, + <0x0 0x1f210000 0x0 0x1000>, + <0x0 0x1f21d000 0x0 0x1000>, + <0x0 0x1f21e000 0x0 0x1000>, + <0x0 0x1f217000 0x0 0x1000>; + interrupts = <0x0 0x86 0x4>; + status = "disabled"; + clocks = <&sata01clk 0>; + phys = <&phy1 0>; + phy-names = "sata-phy"; + }; + + sata2: sata@1a400000 { + compatible = "apm,xgene-ahci"; + reg = <0x0 0x1a400000 0x0 0x1000>, + <0x0 0x1f220000 0x0 0x1000>, + <0x0 0x1f22d000 0x0 0x1000>, + <0x0 0x1f22e000 0x0 0x1000>, + <0x0 0x1f227000 0x0 0x1000>; + interrupts = <0x0 0x87 0x4>; + status = "ok"; + clocks = <&sata23clk 0>; + phys = <&phy2 0>; + phy-names = "sata-phy"; + }; + + sata3: sata@1a800000 { + compatible = "apm,xgene-ahci"; + reg = <0x0 0x1a800000 0x0 0x1000>, + <0x0 0x1f230000 0x0 0x1000>, + <0x0 0x1f23d000 0x0 0x1000>, + <0x0 0x1f23e000 0x0 0x1000>; + interrupts = <0x0 0x88 0x4>; + status = "ok"; + clocks = <&sata45clk 0>; + phys = <&phy3 0>; + phy-names = "sata-phy"; + }; }; }; -- cgit v1.2.3-55-g7522 From 1535bd8adbdedd60a0ee62e28fd5225d66434371 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 14 Mar 2014 10:42:01 -0500 Subject: sparc64: don't treat 64-bit syscall return codes as 32-bit When checking a system call return code for an error, linux_sparc_syscall was sign-extending the lower 32-bit value and comparing it to -ERESTART_RESTARTBLOCK. lseek can return valid return codes whose lower 32-bits alone would indicate a failure (such as 4G-1). Use the whole 64-bit value to check for errors. Only the 32-bit path should sign extend the lower 32-bit value. Signed-off-by: Dave Kleikamp Acked-by: Bob Picco Acked-by: Allen Pais Cc: David S. Miller Cc: sparclinux@vger.kernel.org Signed-off-by: David S. Miller --- arch/sparc/kernel/syscalls.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 87729fff13b9..33a17e7b3ccd 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -189,7 +189,8 @@ linux_sparc_syscall32: mov %i0, %l5 ! IEU1 5: call %l7 ! CTI Group brk forced srl %i5, 0, %o5 ! IEU1 - ba,a,pt %xcc, 3f + ba,pt %xcc, 3f + sra %o0, 0, %o0 /* Linux native system calls enter here... */ .align 32 @@ -217,7 +218,6 @@ linux_sparc_syscall: 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] ret_sys_call: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 - sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 sllx %g2, 32, %g2 -- cgit v1.2.3-55-g7522 From 151b628f104566a450125a6a0f6775a35bde58d6 Mon Sep 17 00:00:00 2001 From: Doug Wilson Date: Fri, 7 Mar 2014 16:29:03 +0530 Subject: sparc64:tsb.c:use array size macro rather than number This is a small patch which uses ARRAY_SIZE macro rather than a number to make code readability better. Signed-off-by: Doug Wilson Signed-off-by: David S. Miller --- arch/sparc/mm/tsb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 3b3a360b429a..f5d506fdddad 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -273,7 +273,7 @@ void __init pgtable_cache_init(void) prom_halt(); } - for (i = 0; i < 8; i++) { + for (i = 0; i < ARRAY_SIZE(tsb_cache_names); i++) { unsigned long size = 8192 << i; const char *name = tsb_cache_names[i]; -- cgit v1.2.3-55-g7522 From e10848a26a962e404ac00c897dfe54f14290806d Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 13 Mar 2014 14:58:42 +0000 Subject: x86/efi: Preserve segment registers in mixed mode I was triggering a #GP(0) from userland when running with CONFIG_EFI_MIXED and CONFIG_IA32_EMULATION, from what looked like register corruption. Turns out that the mixed mode code was trashing the contents of %ds, %es and %ss in __efi64_thunk(). Save and restore the contents of these segment registers across the call to __efi64_thunk() so that we don't corrupt the CPU context. Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi_stub_64.S | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 65b787a9fc4e..e0984ef0374b 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -176,6 +176,13 @@ ENDPROC(efi_call6) * This function must be invoked with a 1:1 mapped stack. */ ENTRY(__efi64_thunk) + movl %ds, %eax + push %rax + movl %es, %eax + push %rax + movl %ss, %eax + push %rax + subq $32, %rsp movl %esi, 0x0(%rsp) movl %edx, 0x4(%rsp) @@ -191,7 +198,7 @@ ENTRY(__efi64_thunk) movq %rbx, func_rt_ptr(%rip) /* Switch to gdt with 32-bit segments */ - movl 40(%rsp), %eax + movl 64(%rsp), %eax lgdt (%rax) leaq efi_enter32(%rip), %rax @@ -203,6 +210,13 @@ ENTRY(__efi64_thunk) lgdt save_gdt(%rip) + pop %rbx + movl %ebx, %ss + pop %rbx + movl %ebx, %es + pop %rbx + movl %ebx, %ds + /* * Convert 32-bit status code into 64-bit. */ @@ -218,11 +232,6 @@ ENTRY(__efi64_thunk) ENDPROC(__efi64_thunk) ENTRY(efi_exit32) - xorq %rax, %rax - movl %eax, %ds - movl %eax, %es - movl %eax, %ss - movq func_rt_ptr(%rip), %rax push %rax mov %rdi, %rax @@ -267,7 +276,7 @@ ENTRY(efi_enter32) */ cli - movl 44(%esp), %eax + movl 68(%esp), %eax movl %eax, 2(%eax) lgdtl (%eax) @@ -286,7 +295,7 @@ ENTRY(efi_enter32) xorl %eax, %eax lldt %ax - movl 48(%esp), %eax + movl 72(%esp), %eax pushl $__KERNEL_CS pushl %eax -- cgit v1.2.3-55-g7522 From 3f4a7836e33134d4ac34fa7c99788f0c6a79fa1c Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 13 Mar 2014 19:41:08 +0000 Subject: x86/efi: Rip out phys_efi_get_time() Dan reported that phys_efi_get_time() is doing kmalloc(..., GFP_KERNEL) under a spinlock which is very clearly a bug. Since phys_efi_get_time() has no users let's just delete it instead of trying to fix it. Note that since there are no users of phys_efi_get_time(), it is not possible to actually trigger a GFP_KERNEL alloc under the spinlock. Reported-by: Dan Carpenter Cc: Ingo Molnar Cc: H. Peter Anvin Cc: Nathan Zimmer Cc: Matthew Garrett Cc: Jan Beulich Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 43e7cf6c6111..3781dd39e8bd 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -246,21 +246,6 @@ static efi_status_t __init phys_efi_set_virtual_address_map( return status; } -static efi_status_t __init phys_efi_get_time(efi_time_t *tm, - efi_time_cap_t *tc) -{ - unsigned long flags; - efi_status_t status; - - spin_lock_irqsave(&rtc_lock, flags); - efi_call_phys_prelog(); - status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), - virt_to_phys(tc)); - efi_call_phys_epilog(); - spin_unlock_irqrestore(&rtc_lock, flags); - return status; -} - int efi_set_rtc_mmss(const struct timespec *now) { unsigned long nowtime = now->tv_sec; @@ -592,16 +577,9 @@ static int __init efi_runtime_init32(void) * EFI runtime services before set_virtual_address_map * is invoked. */ - efi_phys.get_time = (efi_get_time_t *) - (unsigned long)runtime->get_time; efi_phys.set_virtual_address_map = (efi_set_virtual_address_map_t *) (unsigned long)runtime->set_virtual_address_map; - /* - * Make efi_get_time can be called before entering - * virtual mode. - */ - efi.get_time = phys_efi_get_time; early_iounmap(runtime, sizeof(efi_runtime_services_32_t)); return 0; @@ -623,16 +601,9 @@ static int __init efi_runtime_init64(void) * EFI runtime services before set_virtual_address_map * is invoked. */ - efi_phys.get_time = (efi_get_time_t *) - (unsigned long)runtime->get_time; efi_phys.set_virtual_address_map = (efi_set_virtual_address_map_t *) (unsigned long)runtime->set_virtual_address_map; - /* - * Make efi_get_time can be called before entering - * virtual mode. - */ - efi.get_time = phys_efi_get_time; early_iounmap(runtime, sizeof(efi_runtime_services_64_t)); return 0; -- cgit v1.2.3-55-g7522 From 9a11040ff962304c1838aa9a9f33be78784eae47 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 16 Mar 2014 17:46:46 +0000 Subject: x86/efi: Restore 'attr' argument to query_variable_info() In the thunk patches the 'attr' argument was dropped to query_variable_info(). Restore it otherwise the firmware will return EFI_INVALID_PARAMETER. Signed-off-by: Matt Fleming --- arch/x86/platform/efi/efi_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 7e7f195aa5cf..290d397e1dd9 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -567,7 +567,7 @@ efi_thunk_query_variable_info(u32 attr, u64 *storage_space, phys_remaining = virt_to_phys(remaining_space); phys_max = virt_to_phys(max_variable_size); - status = efi_thunk(query_variable_info, phys_storage, + status = efi_thunk(query_variable_info, attr, phys_storage, phys_remaining, phys_max); return status; -- cgit v1.2.3-55-g7522 From e4362d1e64ff6da64118dcf74ff450cd0a029deb Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 21 Jan 2014 11:22:35 +0000 Subject: MIPS: Fix possible build error with transparent hugepages enabled If CONFIG_TRANSPARENT_HUGEPAGE is enabled, but CONFIG_HUGETLB_PAGE is not, it is possible to end up with a configuration that fails to build with the following error: include/linux/huge_mm.h:125:2: error: #error "hugepages can't be allocated by the buddy allocator" This is due to CONFIG_FORCE_MAX_ZONEORDER defaulting to 11. It already has ranges that change the valid values when HUGETLB_PAGE is enabled, but this is not done for TRANSPARENT_HUGEPAGE. Fix by changing the HUGETLB_PAGE dependencies to MIPS_HUGE_TLB_SUPPORT, which includes both TRANSPARENT_HUGEPAGE and HUGETLB_PAGE. Signed-off-by: Alex Smith Reviewed-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6391/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 153447452d5e..95fa1f1d5c8b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1776,12 +1776,12 @@ endchoice config FORCE_MAX_ZONEORDER int "Maximum zone order" - range 14 64 if HUGETLB_PAGE && PAGE_SIZE_64KB - default "14" if HUGETLB_PAGE && PAGE_SIZE_64KB - range 13 64 if HUGETLB_PAGE && PAGE_SIZE_32KB - default "13" if HUGETLB_PAGE && PAGE_SIZE_32KB - range 12 64 if HUGETLB_PAGE && PAGE_SIZE_16KB - default "12" if HUGETLB_PAGE && PAGE_SIZE_16KB + range 14 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB + default "14" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB + range 13 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_32KB + default "13" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_32KB + range 12 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB + default "12" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_16KB range 11 64 default "11" help -- cgit v1.2.3-55-g7522 From 707d4eefbdb31f8e588277157056b0ce637d6c68 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 18 Mar 2014 14:26:12 -0600 Subject: Revert "[PATCH] Insert GART region into resource map" This reverts commit 56dd669a138c, which makes the GART visible in /proc/iomem. This fixes a regression: e501b3d87f00 ("agp: Support 64-bit APBASE") exposed an existing problem with a conflict between the GART region and a PCI BAR region. The GART addresses are bus addresses, not CPU addresses, and therefore should not be inserted in iomem_resource. On many machines, the GART region is addressable by the CPU as well as by an AGP master, but CPU addressability is not required by the spec. On some of these machines, the GART is mapped by a PCI BAR, and in that case, the PCI core automatically inserts it into iomem_resource, just as it does for all BARs. Inserting it here means we'll have a conflict if the PCI core later tries to claim the GART region, so let's drop the insertion here. The conflict indirectly causes X failures, as reported by Jouni in the bugzilla below. We detected the conflict even before e501b3d87f00, but after it the AGP code (fix_northbridge()) uses the PCI resource (which is zeroed because of the conflict) instead of reading the BAR again. Conflicts: arch/x86_64/kernel/aperture.c Fixes: e501b3d87f00 agp: Support 64-bit APBASE Link: https://bugzilla.kernel.org/show_bug.cgi?id=72201 Reported-and-tested-by: Jouni Mettälä Signed-off-by: Bjorn Helgaas --- arch/x86/kernel/aperture_64.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index fd972a3e4cbb..9fa8aa051f54 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -54,18 +53,6 @@ int fallback_aper_force __initdata; int fix_aperture __initdata = 1; -static struct resource gart_resource = { - .name = "GART", - .flags = IORESOURCE_MEM, -}; - -static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) -{ - gart_resource.start = aper_base; - gart_resource.end = aper_base + aper_size - 1; - insert_resource(&iomem_resource, &gart_resource); -} - /* This code runs before the PCI subsystem is initialized, so just access the northbridge directly. */ @@ -96,7 +83,6 @@ static u32 __init allocate_aperture(void) memblock_reserve(addr, aper_size); printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, addr); - insert_aperture_resource((u32)addr, aper_size); register_nosave_region(addr >> PAGE_SHIFT, (addr+aper_size) >> PAGE_SHIFT); @@ -444,12 +430,8 @@ int __init gart_iommu_hole_init(void) out: if (!fix && !fallback_aper_force) { - if (last_aper_base) { - unsigned long n = (32 * 1024 * 1024) << last_aper_order; - - insert_aperture_resource((u32)last_aper_base, n); + if (last_aper_base) return 1; - } return 0; } -- cgit v1.2.3-55-g7522 From 4fe2169acecb6e62821dfe14bc5c5852870b516f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 13 Feb 2014 17:48:12 +0100 Subject: MIPS: BCM47XX: Check all (32) GPIOs when looking for a pin Broadcom boards support 32 GPIOs and NVRAM may have entires for higher ones too. Example: gpio23=wombo_reset Signed-off-by: Rafa? Mi?ecki Acked-by: Hauke Mehrtens Cc: linux-mips@linux-mips.org Cc: Rafał Miłecki Patchwork: https://patchwork.linux-mips.org/patch/6547/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/nvram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 6decb27cf48b..2bed73a684ae 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -196,7 +196,7 @@ int bcm47xx_nvram_gpio_pin(const char *name) char nvram_var[10]; char buf[30]; - for (i = 0; i < 16; i++) { + for (i = 0; i < 32; i++) { err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i); if (err <= 0) continue; -- cgit v1.2.3-55-g7522 From 14b4319a44f2e0385e1794bf41a07d872908b539 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 19 Mar 2014 11:17:40 +0100 Subject: m68k: amiga: Add linux/irq.h to make it compile again The removal of linux/irq.h from kernel_stat.h causes arch/m68k/amiga/cia.c:171: error: 'handle_simple_irq' undeclared Reported-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/m68k/amiga/cia.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 18c0e29976e3..2081b8cd5591 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3-55-g7522 From 74397174989e5f704bcefde7af02e12cc32cb164 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 11 Mar 2014 13:17:31 +0000 Subject: arm64: Fix duplicated Kconfig entries Probably due to rebasing over the lengthy time it took to get the patch merged commit addea9ef055b (cpufreq: enable ARM drivers on arm64) added a duplicate Power management options section. Add CPUfreq to the CPU power management section and remove a duplicate include of the main power section. Signed-off-by: Mark Brown Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4723fc14cf2d..516d8a7ca697 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -321,12 +321,6 @@ menu "CPU Power Management" source "drivers/cpuidle/Kconfig" -endmenu - -menu "Power management options" - -source "kernel/power/Kconfig" - source "drivers/cpufreq/Kconfig" endmenu -- cgit v1.2.3-55-g7522 From b08ac66b4026f0151d712903695bf266042fbe2c Mon Sep 17 00:00:00 2001 From: Viller Hsiao Date: Tue, 18 Mar 2014 15:39:34 +0800 Subject: MIPS: ftrace: Tweak safe_load()/safe_store() macros Due to name collision in ftrace safe_load and safe_store macros, these macros cannot take expressions as operands. For example, compiler will complain for a macro call like the following: safe_store_code(new_code2, ip + 4, faulted); arch/mips/include/asm/ftrace.h:61:6: note: in definition of macro 'safe_store' : [dst] "r" (dst), [src] "r" (src)\ ^ arch/mips/kernel/ftrace.c:118:2: note: in expansion of macro 'safe_store_code' safe_store_code(new_code2, ip + 4, faulted); ^ arch/mips/kernel/ftrace.c:118:32: error: undefined named operand 'ip + 4' safe_store_code(new_code2, ip + 4, faulted); ^ arch/mips/include/asm/ftrace.h:61:6: note: in definition of macro 'safe_store' : [dst] "r" (dst), [src] "r" (src)\ ^ arch/mips/kernel/ftrace.c:118:2: note: in expansion of macro 'safe_store_code' safe_store_code(new_code2, ip + 4, faulted); ^ This build error is triggered by a4671094 [MIPS: ftrace: Fix icache flush range error]. Tweak variable naming in those macros to allow flexible operands. Signed-off-by: Viller Hsiao Cc: linux-mips@linux-mips.org Cc: rostedt@goodmis.org Cc: fweisbec@gmail.com Cc: mingo@redhat.com Cc: Qais.Yousef@imgtec.com Patchwork: https://patchwork.linux-mips.org/patch/6622/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/ftrace.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h index ce35c9af0c28..992aaba603b5 100644 --- a/arch/mips/include/asm/ftrace.h +++ b/arch/mips/include/asm/ftrace.h @@ -22,12 +22,12 @@ extern void _mcount(void); #define safe_load(load, src, dst, error) \ do { \ asm volatile ( \ - "1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\ - " li %[" STR(error) "], 0\n" \ + "1: " load " %[tmp_dst], 0(%[tmp_src])\n" \ + " li %[tmp_err], 0\n" \ "2:\n" \ \ ".section .fixup, \"ax\"\n" \ - "3: li %[" STR(error) "], 1\n" \ + "3: li %[tmp_err], 1\n" \ " j 2b\n" \ ".previous\n" \ \ @@ -35,8 +35,8 @@ do { \ STR(PTR) "\t1b, 3b\n\t" \ ".previous\n" \ \ - : [dst] "=&r" (dst), [error] "=r" (error)\ - : [src] "r" (src) \ + : [tmp_dst] "=&r" (dst), [tmp_err] "=r" (error)\ + : [tmp_src] "r" (src) \ : "memory" \ ); \ } while (0) @@ -44,12 +44,12 @@ do { \ #define safe_store(store, src, dst, error) \ do { \ asm volatile ( \ - "1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\ - " li %[" STR(error) "], 0\n" \ + "1: " store " %[tmp_src], 0(%[tmp_dst])\n"\ + " li %[tmp_err], 0\n" \ "2:\n" \ \ ".section .fixup, \"ax\"\n" \ - "3: li %[" STR(error) "], 1\n" \ + "3: li %[tmp_err], 1\n" \ " j 2b\n" \ ".previous\n" \ \ @@ -57,8 +57,8 @@ do { \ STR(PTR) "\t1b, 3b\n\t" \ ".previous\n" \ \ - : [error] "=r" (error) \ - : [dst] "r" (dst), [src] "r" (src)\ + : [tmp_err] "=r" (error) \ + : [tmp_dst] "r" (dst), [tmp_src] "r" (src)\ : "memory" \ ); \ } while (0) -- cgit v1.2.3-55-g7522 From 2eddb708d83ead02b5d41c65bfb26bab5afc8210 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 19 Mar 2014 23:03:30 +0100 Subject: MIPS: Octeon: Fix warning in of_device_alloc on cn3xxx Starting with commit 3da5278727a895d49a601f67fd49dffa0b80f9a5 (of/irq: Rework of_irq_count()) the following warning is triggered on octeon cn3xxx: [ 0.887281] WARNING: CPU: 0 PID: 1 at drivers/of/platform.c:171 of_device_alloc+0x228/0x230() [ 0.895642] Modules linked in: [ 0.898689] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-rc7-00012-g9ae51f2-dirty #41 [ 0.906860] Stack : c8b439581166d96e ffffffff816b0000 0000000040808000 ffffffff81185ddc [ 0.906860] 0000000000000000 0000000000000000 0000000000000000 000000000000000b [ 0.906860] 000000000000000a 000000000000000a 0000000000000000 0000000000000000 [ 0.906860] ffffffff81740000 ffffffff81720000 ffffffff81615900 ffffffff816b0177 [ 0.906860] ffffffff81727d10 800000041f868fb0 0000000000000001 0000000000000000 [ 0.906860] 0000000000000000 0000000000000038 0000000000000001 ffffffff81568484 [ 0.906860] 800000041f86faa8 ffffffff81145ddc 0000000000000000 ffffffff811873f4 [ 0.906860] 800000041f868b88 800000041f86f9c0 0000000000000000 ffffffff81569c9c [ 0.906860] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 0.906860] 0000000000000000 ffffffff811205e0 0000000000000000 0000000000000000 [ 0.906860] ... [ 0.971695] Call Trace: [ 0.974139] [] show_stack+0x68/0x80 [ 0.979183] [] dump_stack+0x8c/0xe0 [ 0.984196] [] warn_slowpath_common+0x84/0xb8 [ 0.990110] [] of_device_alloc+0x228/0x230 [ 0.995726] [] of_platform_device_create_pdata+0x48/0xd0 [ 1.002593] [] of_platform_bus_create+0x134/0x1e8 [ 1.008837] [] of_platform_bus_create+0x198/0x1e8 [ 1.015064] [] of_platform_bus_probe+0xa4/0x100 [ 1.021149] [] do_one_initcall+0xd8/0x128 [ 1.026701] [] kernel_init_freeable+0x144/0x210 [ 1.032753] [] kernel_init+0x14/0x110 [ 1.037973] [] ret_from_kernel_thread+0x14/0x1c With this commit the kernel starts mapping the interrupts listed for gpio-controller node. irq_domain_ops for CIU (octeon_irq_ciu_map and octeon_irq_ciu_xlat) refuse to handle the GPIO lines (returning -EINVAL) and this is causing above warning in of_device_alloc(). Modify irq_domain_ops for CIU and CIU2 to "gracefully handle" GPIO lines (neither return error code nor call octeon_irq_set_ciu_mapping for it). This should avoid the warning. (As before the real setup for GPIO lines will happen using irq_domain_ops of gpio-controller.) This patch is based on Wei's patch v2 (see http://marc.info/?l=linux-mips&m=139511814813247). Signed-off-by: Andreas Herrmann Reported-by: Yang Wei Acked-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6624/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/octeon-irq.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 25fbfae06c1f..c2bb4f896ce7 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -975,10 +975,6 @@ static int octeon_irq_ciu_xlat(struct irq_domain *d, if (ciu > 1 || bit > 63) return -EINVAL; - /* These are the GPIO lines */ - if (ciu == 0 && bit >= 16 && bit < 32) - return -EINVAL; - *out_hwirq = (ciu << 6) | bit; *out_type = 0; @@ -1007,6 +1003,10 @@ static int octeon_irq_ciu_map(struct irq_domain *d, if (!octeon_irq_virq_in_range(virq)) return -EINVAL; + /* Don't map irq if it is reserved for GPIO. */ + if (line == 0 && bit >= 16 && bit <32) + return 0; + if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0) return -EINVAL; @@ -1525,10 +1525,6 @@ static int octeon_irq_ciu2_xlat(struct irq_domain *d, ciu = intspec[0]; bit = intspec[1]; - /* Line 7 are the GPIO lines */ - if (ciu > 6 || bit > 63) - return -EINVAL; - *out_hwirq = (ciu << 6) | bit; *out_type = 0; @@ -1570,8 +1566,14 @@ static int octeon_irq_ciu2_map(struct irq_domain *d, if (!octeon_irq_virq_in_range(virq)) return -EINVAL; - /* Line 7 are the GPIO lines */ - if (line > 6 || octeon_irq_ciu_to_irq[line][bit] != 0) + /* + * Don't map irq if it is reserved for GPIO. + * (Line 7 are the GPIO lines.) + */ + if (line == 7) + return 0; + + if (line > 7 || octeon_irq_ciu_to_irq[line][bit] != 0) return -EINVAL; if (octeon_irq_ciu2_is_edge(line, bit)) -- cgit v1.2.3-55-g7522 From 06325190bd577e11429444d54f454b9d13f560c9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:02 +0000 Subject: x86, hash: Fix build failure with older binutils Just like for other ISA extension instruction uses we should check whether the assembler actually supports them. The fallback here simply is to encode an instruction with fixed operands (%eax and %ecx). [ hpa: tagging for -stable as a build fix ] Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F0996020000780011FBE7@nat28.tlf.novell.com Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Acked-by: Daniel Borkmann Signed-off-by: H. Peter Anvin Cc: # v3.14 --- arch/x86/Makefile | 1 + arch/x86/lib/hash.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86/Makefile b/arch/x86/Makefile index eeda43abed6e..f8842c444560 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -152,6 +152,7 @@ cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTI # does binutils support specific instructions? asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1) +asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1) avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1) avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 3056702e81fb..060cc4415bd9 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -39,7 +39,11 @@ static inline u32 crc32_u32(u32 crc, u32 val) { +#ifdef CONFIG_AS_CRC32 asm ("crc32l %1,%0\n" : "+r" (crc) : "rm" (val)); +#else + asm (".byte 0xf2, 0x0f, 0x38, 0xf1, 0xc1" : "+a" (crc) : "c" (val)); +#endif return crc; } -- cgit v1.2.3-55-g7522 From c5cdfdf90901c51363441365997eecd58efd9374 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:34 +0000 Subject: x86, hash: Swap arguments passed to crc32_u32() ... to match the function's parameters. While reportedly commutative, using the proper order allows for leveraging the instruction permitting the source operand to be in memory. [ hpa: This code originated in the dpdk toolkit. This was a bug in dpdk which has recently been fixed in part due to an earlier version of this patch. ] Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F09B6020000780011FBEB@nat28.tlf.novell.com Acked-by: Daniel Borkmann Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Signed-off-by: H. Peter Anvin --- arch/x86/lib/hash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 060cc4415bd9..ac628aa93a51 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -53,7 +53,7 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) u32 i, tmp = 0; for (i = 0; i < len / 4; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); switch (3 - (len & 0x03)) { case 0: @@ -64,7 +64,7 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) /* fallthrough */ case 2: tmp |= *((const u8 *) p32); - seed = crc32_u32(tmp, seed); + seed = crc32_u32(seed, tmp); default: break; } @@ -78,7 +78,7 @@ static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) u32 i; for (i = 0; i < len; i++) - seed = crc32_u32(*p32++, seed); + seed = crc32_u32(seed, *p32++); return seed; } -- cgit v1.2.3-55-g7522 From 7a5917e9787dd73284f04e35c3cfdb39a67bf0d5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 27 Feb 2014 08:47:58 +0000 Subject: x86, hash: Simplify switch, add __init annotation Minor cleanups: - simplify switch statement - add __init annotation to setup_arch_fast_hash() Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/530F09CE020000780011FBEF@nat28.tlf.novell.com Cc: Francesco Fusco Cc: Thomas Graf Cc: David S. Miller Acked-by: Daniel Borkmann Signed-off-by: H. Peter Anvin --- arch/x86/lib/hash.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index ac628aa93a51..ff4fa51a5b1f 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -32,6 +32,7 @@ */ #include +#include #include #include @@ -55,17 +56,16 @@ static u32 intel_crc4_2_hash(const void *data, u32 len, u32 seed) for (i = 0; i < len / 4; i++) seed = crc32_u32(seed, *p32++); - switch (3 - (len & 0x03)) { - case 0: + switch (len & 3) { + case 3: tmp |= *((const u8 *) p32 + 2) << 16; /* fallthrough */ - case 1: + case 2: tmp |= *((const u8 *) p32 + 1) << 8; /* fallthrough */ - case 2: + case 1: tmp |= *((const u8 *) p32); seed = crc32_u32(seed, tmp); - default: break; } @@ -83,7 +83,7 @@ static u32 intel_crc4_2_hash2(const u32 *data, u32 len, u32 seed) return seed; } -void setup_arch_fast_hash(struct fast_hash_ops *ops) +void __init setup_arch_fast_hash(struct fast_hash_ops *ops) { if (cpu_has_xmm4_2) { ops->hash = intel_crc4_2_hash; -- cgit v1.2.3-55-g7522 From b718102e7d4ce2f9640805251fbbb3619fbb9a46 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 20 Mar 2014 12:40:30 +0100 Subject: m68k: atari: Fix the last kernel_stat.h fallout Reported-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/m68k/atari/ataints.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 3e73a63c066f..3d2b63bedf05 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -41,6 +41,7 @@ #include #include #include +#include #include -- cgit v1.2.3-55-g7522 From b524ca742ef304970f61c32af320e5c5bdb355ff Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 20 Mar 2014 12:44:02 +0100 Subject: arm: omap: Fix typo in ams-delta-fiq.c 8435cf757 (arm: Replace various irq_desc accesses) typoed irq_get_irq_chip() instead of irq_get_chip(). Reported-by: Fengguang Wu Signed-off-by: Thomas Gleixner --- arch/arm/mach-omap1/ams-delta-fiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c index 2ebc514123a7..d1f12095f315 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq.c +++ b/arch/arm/mach-omap1/ams-delta-fiq.c @@ -47,7 +47,7 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id) int gpio, irq_num, fiq_count; struct irq_chip *irq_chip; - irq_chip = irq_get_irq_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); + irq_chip = irq_get_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); /* * For each handled GPIO interrupt, keep calling its interrupt handler -- cgit v1.2.3-55-g7522 From 71ca75888953166b72cf7a65b4c2b6a50fc0ce3b Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Wed, 27 Nov 2013 15:34:50 -0500 Subject: MIPS: Make local_irq_disable macro safe for non-Mipsr2 For non-mipsr2 processors, the local_irq_disable contains an mfc0-mtc0 pair with instructions inbetween. With preemption enabled, this sequence may get preempted and effect a stale value of CP0_STATUS when executing the mtc0 instruction. This commit avoids this scenario by incrementing the preempt count before the mfc0 and decrementing it after the mtc9. [ralf@linux-mips.org: This patch is sorting out the part that were missed by e97c5b6098 [MIPS: Make irqflags.h functions preempt-safe for non-mipsr2 cpus.] I also re-enabled the inclusion of at the top of ]. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: cernekee@gmail.com Patchwork: https://patchwork.linux-mips.org/patch/6164/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/asmmacro.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 69a9a22d014a..4225e99bd7bf 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -9,6 +9,7 @@ #define _ASM_ASMMACRO_H #include +#include #ifdef CONFIG_32BIT #include @@ -54,11 +55,21 @@ .endm .macro local_irq_disable reg=t0 +#ifdef CONFIG_PREEMPT + lw \reg, TI_PRE_COUNT($28) + addi \reg, \reg, 1 + sw \reg, TI_PRE_COUNT($28) +#endif mfc0 \reg, CP0_STATUS ori \reg, \reg, 1 xori \reg, \reg, 1 mtc0 \reg, CP0_STATUS irq_disable_hazard +#ifdef CONFIG_PREEMPT + lw \reg, TI_PRE_COUNT($28) + addi \reg, \reg, -1 + sw \reg, TI_PRE_COUNT($28) +#endif .endm #endif /* CONFIG_MIPS_MT_SMTC */ -- cgit v1.2.3-55-g7522 From 31b1e940c5d47ee1a01baeccfb1b2b8890822d1a Mon Sep 17 00:00:00 2001 From: Christopher Covington Date: Wed, 19 Mar 2014 16:29:37 +0000 Subject: arm64: Fix __range_ok macro Without this, the following scenario is incorrectly determined to be invalid. addr 0x7f_ffffe000 size 8192 addr_limit 0x80_00000000 This behavior was observed while trying to vmsplice the stack as part of a CRIU dump of a process on a system started with the norandmaps kernel parameter. Signed-off-by: Christopher Covington Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/uaccess.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 6c0f684aca81..3bf8f4e99a51 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -83,7 +83,7 @@ static inline void set_fs(mm_segment_t fs) * Returns 1 if the range is valid, 0 otherwise. * * This is equivalent to the following test: - * (u65)addr + (u65)size < (u65)current->addr_limit + * (u65)addr + (u65)size <= current->addr_limit * * This needs 65-bit arithmetic. */ @@ -91,7 +91,7 @@ static inline void set_fs(mm_segment_t fs) ({ \ unsigned long flag, roksum; \ __chk_user_ptr(addr); \ - asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, cc" \ + asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \ : "=&r" (flag), "=&r" (roksum) \ : "1" (addr), "Ir" (size), \ "r" (current_thread_info()->addr_limit) \ -- cgit v1.2.3-55-g7522 From 8c90487cdc64847b4fdd812ab3047f426fec4d13 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 26 Feb 2014 10:49:49 -0500 Subject: Rename TAINT_UNSAFE_SMP to TAINT_CPU_OUT_OF_SPEC Rename TAINT_UNSAFE_SMP to TAINT_CPU_OUT_OF_SPEC, so we can repurpose the flag to encompass a wider range of pushing the CPU beyond its warrany. Signed-off-by: Dave Jones Link: http://lkml.kernel.org/r/20140226154949.GA770@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 2 +- include/linux/kernel.h | 2 +- kernel/module.c | 2 +- kernel/panic.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index b85e43a5a462..ce8b8ff0e0ef 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -218,7 +218,7 @@ static void amd_k7_smp_check(struct cpuinfo_x86 *c) */ WARN_ONCE(1, "WARNING: This combination of AMD" " processors is not suitable for SMP.\n"); - add_taint(TAINT_UNSAFE_SMP, LOCKDEP_NOW_UNRELIABLE); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); } static void init_amd_k7(struct cpuinfo_x86 *c) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 196d1ea86df0..08fb02477641 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -458,7 +458,7 @@ extern enum system_states { #define TAINT_PROPRIETARY_MODULE 0 #define TAINT_FORCED_MODULE 1 -#define TAINT_UNSAFE_SMP 2 +#define TAINT_CPU_OUT_OF_SPEC 2 #define TAINT_FORCED_RMMOD 3 #define TAINT_MACHINE_CHECK 4 #define TAINT_BAD_PAGE 5 diff --git a/kernel/module.c b/kernel/module.c index d24fcf29cb64..ca2c1aded7ee 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1015,7 +1015,7 @@ static size_t module_flags_taint(struct module *mod, char *buf) buf[l++] = 'C'; /* * TAINT_FORCED_RMMOD: could be added. - * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't + * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't * apply to modules. */ return l; diff --git a/kernel/panic.c b/kernel/panic.c index 6d6300375090..2270cfd1d6be 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -199,7 +199,7 @@ struct tnt { static const struct tnt tnts[] = { { TAINT_PROPRIETARY_MODULE, 'P', 'G' }, { TAINT_FORCED_MODULE, 'F', ' ' }, - { TAINT_UNSAFE_SMP, 'S', ' ' }, + { TAINT_CPU_OUT_OF_SPEC, 'S', ' ' }, { TAINT_FORCED_RMMOD, 'R', ' ' }, { TAINT_MACHINE_CHECK, 'M', ' ' }, { TAINT_BAD_PAGE, 'B', ' ' }, -- cgit v1.2.3-55-g7522 From 69f2366c9456d0ce784cf5aba87ee77eeadc1d5e Mon Sep 17 00:00:00 2001 From: Chris Bainbridge Date: Fri, 7 Mar 2014 18:40:42 +0700 Subject: x86, cpu: Add forcepae parameter for booting PAE kernels on PAE-disabled Pentium M Many Pentium M systems disable PAE but may have a functionally usable PAE implementation. This adds the "forcepae" parameter which bypasses the boot check for PAE, and sets the CPU as being PAE capable. Using this parameter will taint the kernel with TAINT_CPU_OUT_OF_SPEC. Signed-off-by: Chris Bainbridge Link: http://lkml.kernel.org/r/20140307114040.GA4997@localhost Acked-by: Borislav Petkov Signed-off-by: H. Peter Anvin --- Documentation/kernel-parameters.txt | 7 +++++++ arch/x86/boot/cpucheck.c | 20 ++++++++++++++++++++ arch/x86/kernel/cpu/intel.c | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+) (limited to 'arch') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7116fda7077f..06600cc9a26c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1011,6 +1011,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. parameter will force ia64_sal_cache_flush to call ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. + forcepae [X86-32] + Forcefully enable Physical Address Extension (PAE). + Many Pentium M systems disable PAE but may have a + functionally usable PAE implementation. + Warning: use of this parameter will taint the kernel + and may cause unknown problems. + ftrace=[tracer] [FTRACE] will set and start the specified tracer as early as possible in order to facilitate early diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c index 100a9a10076a..f0d0b20fe149 100644 --- a/arch/x86/boot/cpucheck.c +++ b/arch/x86/boot/cpucheck.c @@ -67,6 +67,13 @@ static int is_transmeta(void) cpu_vendor[2] == A32('M', 'x', '8', '6'); } +static int is_intel(void) +{ + return cpu_vendor[0] == A32('G', 'e', 'n', 'u') && + cpu_vendor[1] == A32('i', 'n', 'e', 'I') && + cpu_vendor[2] == A32('n', 't', 'e', 'l'); +} + /* Returns a bitmask of which words we have error bits in */ static int check_cpuflags(void) { @@ -153,6 +160,19 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr) asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); err = check_cpuflags(); + } else if (err == 0x01 && + !(err_flags[0] & ~(1 << X86_FEATURE_PAE)) && + is_intel() && cpu.level == 6 && + (cpu.model == 9 || cpu.model == 13)) { + /* PAE is disabled on this Pentium M but can be forced */ + if (cmdline_find_option_bool("forcepae")) { + puts("WARNING: Forcing PAE in CPU flags\n"); + set_bit(X86_FEATURE_PAE, cpu.flags); + err = check_cpuflags(); + } + else { + puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n"); + } } if (err_flags_ptr) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 34bbb555e269..897d6201ef10 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -186,6 +186,14 @@ static void intel_smp_check(struct cpuinfo_x86 *c) } } +static int forcepae; +static int __init forcepae_setup(char *__unused) +{ + forcepae = 1; + return 1; +} +__setup("forcepae", forcepae_setup); + static void intel_workarounds(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_F00F_BUG @@ -213,6 +221,17 @@ static void intel_workarounds(struct cpuinfo_x86 *c) if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) clear_cpu_cap(c, X86_FEATURE_SEP); + /* + * PAE CPUID issue: many Pentium M report no PAE but may have a + * functionally usable PAE implementation. + * Forcefully enable PAE if kernel parameter "forcepae" is present. + */ + if (forcepae) { + printk(KERN_WARNING "PAE forced!\n"); + set_cpu_cap(c, X86_FEATURE_PAE); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); + } + /* * P4 Xeon errata 037 workaround. * Hardware prefetcher may cause stale data to be loaded into the cache. -- cgit v1.2.3-55-g7522 From c7c5be73ccc05da9899b313b9fa0042aae56502f Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Wed, 19 Mar 2014 10:13:22 +0100 Subject: s390/mm: fixing comment so that parameter name match Signed-off-by: Dominik Dingel Signed-off-by: Martin Schwidefsky --- arch/s390/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index f8b58a7a3048..27a1b931f17d 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -748,7 +748,7 @@ EXPORT_SYMBOL_GPL(gmap_unregister_ipte_notifier); /** * gmap_ipte_notify - mark a range of ptes for invalidation notification * @gmap: pointer to guest mapping meta data structure - * @address: virtual address in the guest address space + * @start: virtual address in the guest address space * @len: size of area * * Returns 0 if for each page in the given range a gmap mapping exists and -- cgit v1.2.3-55-g7522 From aaeff84a2dfa224611fc9fee89cb20277469c454 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Wed, 19 Mar 2014 10:18:49 +0100 Subject: s390/mm: remove unnecessary parameter from gmap_do_ipte_notify Signed-off-by: Dominik Dingel Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 4 ++-- arch/s390/mm/pgtable.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index a7dd672c97f8..9602154401d2 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -841,7 +841,7 @@ void __gmap_zap(unsigned long address, struct gmap *); void gmap_register_ipte_notifier(struct gmap_notifier *); void gmap_unregister_ipte_notifier(struct gmap_notifier *); int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len); -void gmap_do_ipte_notify(struct mm_struct *, unsigned long addr, pte_t *); +void gmap_do_ipte_notify(struct mm_struct *, pte_t *); static inline pgste_t pgste_ipte_notify(struct mm_struct *mm, unsigned long addr, @@ -850,7 +850,7 @@ static inline pgste_t pgste_ipte_notify(struct mm_struct *mm, #ifdef CONFIG_PGSTE if (pgste_val(pgste) & PGSTE_IN_BIT) { pgste_val(pgste) &= ~PGSTE_IN_BIT; - gmap_do_ipte_notify(mm, addr, ptep); + gmap_do_ipte_notify(mm, ptep); } #endif return pgste; diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 27a1b931f17d..796c9320c709 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -802,13 +802,12 @@ EXPORT_SYMBOL_GPL(gmap_ipte_notify); /** * gmap_do_ipte_notify - call all invalidation callbacks for a specific pte. * @mm: pointer to the process mm_struct - * @addr: virtual address in the process address space * @pte: pointer to the page table entry * * This function is assumed to be called with the page table lock held * for the pte to notify. */ -void gmap_do_ipte_notify(struct mm_struct *mm, unsigned long addr, pte_t *pte) +void gmap_do_ipte_notify(struct mm_struct *mm, pte_t *pte) { unsigned long segment_offset; struct gmap_notifier *nb; -- cgit v1.2.3-55-g7522 From 6e5a40a49fe16f8032c4dcd4fa5ff866da09d445 Mon Sep 17 00:00:00 2001 From: Dominik Dingel Date: Wed, 19 Mar 2014 10:19:35 +0100 Subject: s390/mm: remove unecessary parameter from pgste_ipte_notify Signed-off-by: Dominik Dingel Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 9602154401d2..1ab75eaacbd4 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -844,7 +844,6 @@ int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len); void gmap_do_ipte_notify(struct mm_struct *, pte_t *); static inline pgste_t pgste_ipte_notify(struct mm_struct *mm, - unsigned long addr, pte_t *ptep, pgste_t pgste) { #ifdef CONFIG_PGSTE @@ -1104,7 +1103,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, if (mm_has_pgste(vma->vm_mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(vma->vm_mm, addr, ptep, pgste); + pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste); } pte = *ptep; @@ -1150,7 +1149,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, if (mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(mm, address, ptep, pgste); + pgste = pgste_ipte_notify(mm, ptep, pgste); } pte = *ptep; @@ -1174,7 +1173,7 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, if (mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); - pgste_ipte_notify(mm, address, ptep, pgste); + pgste_ipte_notify(mm, ptep, pgste); } pte = *ptep; @@ -1211,7 +1210,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, if (mm_has_pgste(vma->vm_mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste); + pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste); } pte = *ptep; @@ -1245,7 +1244,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, if (!full && mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(mm, address, ptep, pgste); + pgste = pgste_ipte_notify(mm, ptep, pgste); } pte = *ptep; @@ -1270,7 +1269,7 @@ static inline pte_t ptep_set_wrprotect(struct mm_struct *mm, if (pte_write(pte)) { if (mm_has_pgste(mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(mm, address, ptep, pgste); + pgste = pgste_ipte_notify(mm, ptep, pgste); } ptep_flush_lazy(mm, address, ptep); @@ -1296,7 +1295,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma, return 0; if (mm_has_pgste(vma->vm_mm)) { pgste = pgste_get_lock(ptep); - pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste); + pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste); } ptep_flush_direct(vma->vm_mm, address, ptep); -- cgit v1.2.3-55-g7522 From 4b02a72a266b58268979cb6f9c5d4dd002148634 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sat, 1 Mar 2014 17:41:22 -0500 Subject: parisc: Remove unused CONFIG_PARISC_TMPALIAS code The attached change removes the unused and experimental CONFIG_PARISC_TMPALIAS code. It doesn't work and I don't believe it will ever be used. Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/include/asm/page.h | 11 -------- arch/parisc/kernel/cache.c | 64 ------------------------------------------ 2 files changed, 75 deletions(-) (limited to 'arch') diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 637fe031aa84..60d5d174dfe4 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -32,17 +32,6 @@ void copy_page_asm(void *to, void *from); void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg); -/* #define CONFIG_PARISC_TMPALIAS */ - -#ifdef CONFIG_PARISC_TMPALIAS -void clear_user_highpage(struct page *page, unsigned long vaddr); -#define clear_user_highpage clear_user_highpage -struct vm_area_struct; -void copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr, struct vm_area_struct *vma); -#define __HAVE_ARCH_COPY_USER_HIGHPAGE -#endif - /* * These are used to make use of C type-checking.. */ diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index ac87a40502e6..a6ffc775a9f8 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -581,67 +581,3 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); } } - -#ifdef CONFIG_PARISC_TMPALIAS - -void clear_user_highpage(struct page *page, unsigned long vaddr) -{ - void *vto; - unsigned long flags; - - /* Clear using TMPALIAS region. The page doesn't need to - be flushed but the kernel mapping needs to be purged. */ - - vto = kmap_atomic(page); - - /* The PA-RISC 2.0 Architecture book states on page F-6: - "Before a write-capable translation is enabled, *all* - non-equivalently-aliased translations must be removed - from the page table and purged from the TLB. (Note - that the caches are not required to be flushed at this - time.) Before any non-equivalent aliased translation - is re-enabled, the virtual address range for the writeable - page (the entire page) must be flushed from the cache, - and the write-capable translation removed from the page - table and purged from the TLB." */ - - purge_kernel_dcache_page_asm((unsigned long)vto); - purge_tlb_start(flags); - pdtlb_kernel(vto); - purge_tlb_end(flags); - preempt_disable(); - clear_user_page_asm(vto, vaddr); - preempt_enable(); - - pagefault_enable(); /* kunmap_atomic(addr, KM_USER0); */ -} - -void copy_user_highpage(struct page *to, struct page *from, - unsigned long vaddr, struct vm_area_struct *vma) -{ - void *vfrom, *vto; - unsigned long flags; - - /* Copy using TMPALIAS region. This has the advantage - that the `from' page doesn't need to be flushed. However, - the `to' page must be flushed in copy_user_page_asm since - it can be used to bring in executable code. */ - - vfrom = kmap_atomic(from); - vto = kmap_atomic(to); - - purge_kernel_dcache_page_asm((unsigned long)vto); - purge_tlb_start(flags); - pdtlb_kernel(vto); - pdtlb_kernel(vfrom); - purge_tlb_end(flags); - preempt_disable(); - copy_user_page_asm(vto, vfrom, vaddr); - flush_dcache_page_asm(__pa(vto), vaddr); - preempt_enable(); - - pagefault_enable(); /* kunmap_atomic(addr, KM_USER1); */ - pagefault_enable(); /* kunmap_atomic(addr, KM_USER0); */ -} - -#endif /* CONFIG_PARISC_TMPALIAS */ -- cgit v1.2.3-55-g7522 From e9af8b7aba1fd5f2175ec552ec36d5efe57f6c1d Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 23 Mar 2014 15:24:40 +0100 Subject: parisc: wire up sys_utimes We seem to be nearly the only platform which does not provide the sys_utimes syscall. Adding it now makes our life much easier with userspace applications (like dietlibc and e2fsprogs) since we then behave like all other platforms too and don't need extra patches which are hard to get upstream anyway because we are not a mainstream architecture. Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v3.13 --- arch/parisc/include/uapi/asm/unistd.h | 4 ++-- arch/parisc/kernel/syscall_table.S | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index 42706794a36f..265ae5190b0a 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h @@ -828,13 +828,13 @@ #define __NR_finit_module (__NR_Linux + 333) #define __NR_sched_setattr (__NR_Linux + 334) #define __NR_sched_getattr (__NR_Linux + 335) +#define __NR_utimes (__NR_Linux + 336) -#define __NR_Linux_syscalls (__NR_sched_getattr + 1) +#define __NR_Linux_syscalls (__NR_utimes + 1) #define __IGNORE_select /* newselect */ #define __IGNORE_fadvise64 /* fadvise64_64 */ -#define __IGNORE_utimes /* utime */ #define HPUX_GATEWAY_ADDR 0xC0000004 diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 8fa3fbb3e4d3..80e5dd248934 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -431,6 +431,7 @@ ENTRY_SAME(finit_module) ENTRY_SAME(sched_setattr) ENTRY_SAME(sched_getattr) /* 335 */ + ENTRY_COMP(utimes) /* Nothing yet */ -- cgit v1.2.3-55-g7522 From a34fe10750ebe524a39f97bd78ab4d232a554edb Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 21 Feb 2014 17:34:57 +0000 Subject: parisc: locks: remove redundant arch_*_relax operations Now that the arch_{spin,read,write}_relax macros default to cpu_relax(), remove the redundant definitions for parisc. Cc: Helge Deller Signed-off-by: Will Deacon Signed-off-by: Helge Deller --- arch/parisc/include/asm/spinlock.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 3516e0b27044..64f2992e439f 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -191,8 +191,4 @@ static __inline__ int arch_write_can_lock(arch_rwlock_t *rw) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) -#define arch_spin_relax(lock) cpu_relax() -#define arch_read_relax(lock) cpu_relax() -#define arch_write_relax(lock) cpu_relax() - #endif /* __ASM_SPINLOCK_H */ -- cgit v1.2.3-55-g7522 From 6e8d7968e92f7668a2a615773ad3940f0219dcbd Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Fri, 14 Mar 2014 19:52:23 +0000 Subject: arm64: Implement custom mmap functions for dma mapping The current dma_ops do not specify an mmap function so maping falls back to the default implementation. There are at least two issues with using the default implementation: 1) The pgprot is always pgprot_noncached (strongly ordered) memory even with coherent operations 2) dma_common_mmap calls virt_to_page on the remapped non-coherent address which leads to invalid memory being mapped. Fix both these issue by implementing a custom mmap function which correctly accounts for remapped addresses and sets vm_pg_prot appropriately. Signed-off-by: Laura Abbott [catalin.marinas@arm.com: replaced "arm64_" with "__" prefix for consistency] Signed-off-by: Catalin Marinas --- arch/arm64/mm/dma-mapping.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'arch') diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 88fbc5e5bae7..81eea3d3249f 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -221,9 +221,52 @@ static void __swiotlb_sync_sg_for_device(struct device *dev, sg->length, dir); } +/* vma->vm_page_prot must be set appropriately before calling this function */ +static int __dma_common_mmap(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + int ret = -ENXIO; + unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> + PAGE_SHIFT; + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; + unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT; + unsigned long off = vma->vm_pgoff; + + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) + return ret; + + if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) { + ret = remap_pfn_range(vma, vma->vm_start, + pfn + off, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + } + + return ret; +} + +static int __swiotlb_mmap_noncoherent(struct device *dev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size, + struct dma_attrs *attrs) +{ + vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); +} + +static int __swiotlb_mmap_coherent(struct device *dev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size, + struct dma_attrs *attrs) +{ + /* Just use whatever page_prot attributes were specified */ + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); +} + struct dma_map_ops noncoherent_swiotlb_dma_ops = { .alloc = __dma_alloc_noncoherent, .free = __dma_free_noncoherent, + .mmap = __swiotlb_mmap_noncoherent, .map_page = __swiotlb_map_page, .unmap_page = __swiotlb_unmap_page, .map_sg = __swiotlb_map_sg_attrs, @@ -240,6 +283,7 @@ EXPORT_SYMBOL(noncoherent_swiotlb_dma_ops); struct dma_map_ops coherent_swiotlb_dma_ops = { .alloc = __dma_alloc_coherent, .free = __dma_free_coherent, + .mmap = __swiotlb_mmap_coherent, .map_page = swiotlb_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = swiotlb_map_sg_attrs, -- cgit v1.2.3-55-g7522 From 214fdbe74a096c3aeb7af81d7900e2ab966b10d6 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Fri, 14 Mar 2014 19:52:24 +0000 Subject: arm64: Support DMA_ATTR_WRITE_COMBINE DMA_ATTR_WRITE_COMBINE is currently ignored. Set the pgprot appropriately for non coherent opperations. Signed-off-by: Laura Abbott Signed-off-by: Catalin Marinas --- arch/arm64/mm/dma-mapping.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 81eea3d3249f..5bba6be1a3f1 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -30,6 +30,16 @@ struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); +static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot, + bool coherent) +{ + if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) + return pgprot_writecombine(prot); + else if (!coherent) + return pgprot_dmacoherent(prot); + return prot; +} + static void *__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags, struct dma_attrs *attrs) @@ -104,7 +114,7 @@ static void *__dma_alloc_noncoherent(struct device *dev, size_t size, for (i = 0; i < (size >> PAGE_SHIFT); i++) map[i] = page + i; coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP, - pgprot_dmacoherent(pgprot_default)); + __get_dma_pgprot(attrs, pgprot_default, false)); kfree(map); if (!coherent_ptr) goto no_map; @@ -250,7 +260,7 @@ static int __swiotlb_mmap_noncoherent(struct device *dev, void *cpu_addr, dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) { - vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, false); return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size); } -- cgit v1.2.3-55-g7522 From 196adf2f3015eacac0567278ba538e3ffdd16d0e Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 24 Mar 2014 10:35:35 +0000 Subject: arm64: Remove pgprot_dmacoherent() Since this macro is identical to pgprot_writecombine() and is only used in a single place, remove it completely to avoid confusion. On ARMv7+ processors, the coherent DMA mapping must be Normal NonCacheable (a.k.a. writecombine) to avoid mismatched hardware attribute aliases (with the kernel linear mapping as Normal Cacheable). Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/pgtable.h | 2 -- arch/arm64/mm/dma-mapping.c | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index ae10350f75ec..da92265bd798 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -280,8 +280,6 @@ static inline int has_transparent_hugepage(void) __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) #define pgprot_writecombine(prot) \ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) -#define pgprot_dmacoherent(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) #define __HAVE_PHYS_MEM_ACCESS_PROT struct file; extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 5bba6be1a3f1..0ba347e59f06 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -33,10 +33,8 @@ EXPORT_SYMBOL(dma_ops); static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot, bool coherent) { - if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) + if (!coherent || dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs)) return pgprot_writecombine(prot); - else if (!coherent) - return pgprot_dmacoherent(prot); return prot; } -- cgit v1.2.3-55-g7522 From 9dd721c6dbfc310f94306902611f86dda87a45fa Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 10 Mar 2014 13:42:48 -0700 Subject: x86, kaslr: fix module lock ordering problem There was a potential lock ordering problem with the module kASLR patch ("x86, kaslr: randomize module base load address"). This patch removes the usage of the module_mutex and creates a new mutex to protect the module base address offset value. Chain exists of: text_mutex --> kprobe_insn_slots.mutex --> module_mutex [ 0.515561] Possible unsafe locking scenario: [ 0.515561] [ 0.515561] CPU0 CPU1 [ 0.515561] ---- ---- [ 0.515561] lock(module_mutex); [ 0.515561] lock(kprobe_insn_slots.mutex); [ 0.515561] lock(module_mutex); [ 0.515561] lock(text_mutex); [ 0.515561] [ 0.515561] *** DEADLOCK *** Reported-by: Fengguang Wu Signed-off-by: Andy Honig Signed-off-by: Kees Cook Reviewed-by: Masami Hiramatsu Signed-off-by: H. Peter Anvin --- arch/x86/kernel/module.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 49483137371f..e69f9882bf95 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -48,6 +48,9 @@ do { \ static unsigned long module_load_offset; static int randomize_modules = 1; +/* Mutex protects the module_load_offset. */ +static DEFINE_MUTEX(module_kaslr_mutex); + static int __init parse_nokaslr(char *p) { randomize_modules = 0; @@ -58,7 +61,7 @@ early_param("nokaslr", parse_nokaslr); static unsigned long int get_module_load_offset(void) { if (randomize_modules) { - mutex_lock(&module_mutex); + mutex_lock(&module_kaslr_mutex); /* * Calculate the module_load_offset the first time this * code is called. Once calculated it stays the same until @@ -67,7 +70,7 @@ static unsigned long int get_module_load_offset(void) if (module_load_offset == 0) module_load_offset = (get_random_int() % 1024 + 1) * PAGE_SIZE; - mutex_unlock(&module_mutex); + mutex_unlock(&module_kaslr_mutex); } return module_load_offset; } -- cgit v1.2.3-55-g7522 From cb3042d609e30e6144024801c89be3925106752b Mon Sep 17 00:00:00 2001 From: David S. Miller Date: Mon, 24 Mar 2014 14:45:12 -0400 Subject: sparc64: Make sure %pil interrupts are enabled during hypervisor yield. In arch_cpu_idle() we must enable %pil based interrupts before potentially invoking the hypervisor cpu yield call. As per the Hypervisor API documentation for cpu_yield: Interrupts which are blocked by some mechanism other that pstate.ie (for example %pil) are not guaranteed to cause a return from this service. It seems that only first generation Niagara chips are hit by this bug. My best guess is that later chips implement this in hardware and wake up anyways from %pil events, whereas in first generation chips the yield is implemented completely in hypervisor code and requires %pil to be enabled in order to wake properly from this call. Fixes: 87fa05aeb3a5 ("sparc: Use generic idle loop") Reported-by: Fabio M. Di Nitto Reported-by: Jan Engelhardt Tested-by: Jan Engelhardt Signed-off-by: David S. Miller --- arch/sparc/kernel/process_64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 32a280ec38c1..d7b4967f8fa6 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -58,9 +58,12 @@ void arch_cpu_idle(void) { if (tlb_type != hypervisor) { touch_nmi_watchdog(); + local_irq_enable(); } else { unsigned long pstate; + local_irq_enable(); + /* The sun4v sleeping code requires that we have PSTATE.IE cleared over * the cpu sleep hypervisor call. */ @@ -82,7 +85,6 @@ void arch_cpu_idle(void) : "=&r" (pstate) : "i" (PSTATE_IE)); } - local_irq_enable(); } #ifdef CONFIG_HOTPLUG_CPU -- cgit v1.2.3-55-g7522 From 5926f87fdaad4be3ed10cec563bf357915e55a86 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 25 Mar 2014 10:38:37 +0000 Subject: Revert "xen: properly account for _PAGE_NUMA during xen pte translations" This reverts commit a9c8e4beeeb64c22b84c803747487857fe424b68. PTEs in Xen PV guests must contain machine addresses if _PAGE_PRESENT is set and pseudo-physical addresses is _PAGE_PRESENT is clear. This is because during a domain save/restore (migration) the page table entries are "canonicalised" and uncanonicalised". i.e., MFNs are converted to PFNs during domain save so that on a restore the page table entries may be rewritten with the new MFNs on the destination. This canonicalisation is only done for PTEs that are present. This change resulted in writing PTEs with MFNs if _PAGE_PROTNONE (or _PAGE_NUMA) was set but _PAGE_PRESENT was clear. These PTEs would be migrated as-is which would result in unexpected behaviour in the destination domain. Either a) the MFN would be translated to the wrong PFN/page; b) setting the _PAGE_PRESENT bit would clear the PTE because the MFN is no longer owned by the domain; or c) the present bit would not get set. Symptoms include "Bad page" reports when munmapping after migrating a domain. Signed-off-by: David Vrabel Acked-by: Konrad Rzeszutek Wilk Cc: [3.12+] --- arch/x86/include/asm/pgtable.h | 14 ++------------ arch/x86/xen/mmu.c | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5ad38ad07890..bbc8b12fa443 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -445,20 +445,10 @@ static inline int pte_same(pte_t a, pte_t b) return a.pte == b.pte; } -static inline int pteval_present(pteval_t pteval) -{ - /* - * Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this - * way clearly states that the intent is that protnone and numa - * hinting ptes are considered present for the purposes of - * pagetable operations like zapping, protection changes, gup etc. - */ - return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA); -} - static inline int pte_present(pte_t a) { - return pteval_present(pte_flags(a)); + return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE | + _PAGE_NUMA); } #define pte_accessible pte_accessible diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 256282e7888b..2423ef04ffea 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, /* Assume pteval_t is equivalent to all the other *val_t types. */ static pteval_t pte_mfn_to_pfn(pteval_t val) { - if (pteval_present(val)) { + if (val & _PAGE_PRESENT) { unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; unsigned long pfn = mfn_to_pfn(mfn); @@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) static pteval_t pte_pfn_to_mfn(pteval_t val) { - if (pteval_present(val)) { + if (val & _PAGE_PRESENT) { unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; pteval_t flags = val & PTE_FLAGS_MASK; unsigned long mfn; -- cgit v1.2.3-55-g7522 From b712c8dae05931a76b6c17a4254f403798e6caef Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Mar 2014 14:20:45 +0000 Subject: x86: hpet: Use proper destructor for delayed work destroy_timer_on_stack() is hardly the right thing for a delayed work. We leak a tracking object for the work itself when DEBUG_OBJECTS is enabled. Signed-off-by: Thomas Gleixner Cc: Vince Weaver Cc: x86@kernel.org Link: http://lkml.kernel.org/r/20140323141940.034005322@linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/kernel/hpet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index da85a8e830a1..b91abfdd4931 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -699,7 +699,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n, /* FIXME: add schedule_work_on() */ schedule_delayed_work_on(cpu, &work.work, 0); wait_for_completion(&work.complete); - destroy_timer_on_stack(&work.work.timer); + destroy_delayed_work_on_stack(&work.work); break; case CPU_DEAD: if (hdev) { -- cgit v1.2.3-55-g7522 From 080c492df02bd1171963d70daf7305a72443873d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 25 Mar 2014 19:51:41 +0100 Subject: ARM: davinci: da850: update SATA AHCI support Update SATA AHCI support to make use of the new ahci_da850 host driver (instead of the generic ahci_platform one) and remove deprecated ahci_platform_data code. Cc: Sekhar Nori Cc: Kevin Hilman Cc: Hans de Goede Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- arch/arm/mach-davinci/da850.c | 2 +- arch/arm/mach-davinci/devices-da8xx.c | 99 +++-------------------------------- 2 files changed, 9 insertions(+), 92 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 2ab00434b2eb..85399c98f84a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -472,7 +472,7 @@ static struct clk_lookup da850_clks[] = { CLK("spi_davinci.0", NULL, &spi0_clk), CLK("spi_davinci.1", NULL, &spi1_clk), CLK("vpif", NULL, &vpif_clk), - CLK("ahci", NULL, &sata_clk), + CLK("ahci_da850", NULL, &sata_clk), CLK("davinci-rproc.0", NULL, &dsp_clk), CLK("ehrpwm", "fck", &ehrpwm_clk), CLK("ehrpwm", "tbclk", &ehrpwm_tbclk), diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 0486cdf28c8d..56ea41d5f849 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -1020,111 +1020,29 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect) } #ifdef CONFIG_ARCH_DAVINCI_DA850 - static struct resource da850_sata_resources[] = { { .start = DA850_SATA_BASE, .end = DA850_SATA_BASE + 0x1fff, .flags = IORESOURCE_MEM, }, + { + .start = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG, + .end = DA8XX_SYSCFG1_BASE + DA8XX_PWRDN_REG + 0x3, + .flags = IORESOURCE_MEM, + }, { .start = IRQ_DA850_SATAINT, .flags = IORESOURCE_IRQ, }, }; -/* SATA PHY Control Register offset from AHCI base */ -#define SATA_P0PHYCR_REG 0x178 - -#define SATA_PHY_MPY(x) ((x) << 0) -#define SATA_PHY_LOS(x) ((x) << 6) -#define SATA_PHY_RXCDR(x) ((x) << 10) -#define SATA_PHY_RXEQ(x) ((x) << 13) -#define SATA_PHY_TXSWING(x) ((x) << 19) -#define SATA_PHY_ENPLL(x) ((x) << 31) - -static struct clk *da850_sata_clk; -static unsigned long da850_sata_refclkpn; - -/* Supported DA850 SATA crystal frequencies */ -#define KHZ_TO_HZ(freq) ((freq) * 1000) -static unsigned long da850_sata_xtal[] = { - KHZ_TO_HZ(300000), - KHZ_TO_HZ(250000), - 0, /* Reserved */ - KHZ_TO_HZ(187500), - KHZ_TO_HZ(150000), - KHZ_TO_HZ(125000), - KHZ_TO_HZ(120000), - KHZ_TO_HZ(100000), - KHZ_TO_HZ(75000), - KHZ_TO_HZ(60000), -}; - -static int da850_sata_init(struct device *dev, void __iomem *addr) -{ - int i, ret; - unsigned int val; - - da850_sata_clk = clk_get(dev, NULL); - if (IS_ERR(da850_sata_clk)) - return PTR_ERR(da850_sata_clk); - - ret = clk_prepare_enable(da850_sata_clk); - if (ret) - goto err0; - - /* Enable SATA clock receiver */ - val = __raw_readl(DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); - val &= ~BIT(0); - __raw_writel(val, DA8XX_SYSCFG1_VIRT(DA8XX_PWRDN_REG)); - - /* Get the multiplier needed for 1.5GHz PLL output */ - for (i = 0; i < ARRAY_SIZE(da850_sata_xtal); i++) - if (da850_sata_xtal[i] == da850_sata_refclkpn) - break; - - if (i == ARRAY_SIZE(da850_sata_xtal)) { - ret = -EINVAL; - goto err1; - } - - val = SATA_PHY_MPY(i + 1) | - SATA_PHY_LOS(1) | - SATA_PHY_RXCDR(4) | - SATA_PHY_RXEQ(1) | - SATA_PHY_TXSWING(3) | - SATA_PHY_ENPLL(1); - - __raw_writel(val, addr + SATA_P0PHYCR_REG); - - return 0; - -err1: - clk_disable_unprepare(da850_sata_clk); -err0: - clk_put(da850_sata_clk); - return ret; -} - -static void da850_sata_exit(struct device *dev) -{ - clk_disable_unprepare(da850_sata_clk); - clk_put(da850_sata_clk); -} - -static struct ahci_platform_data da850_sata_pdata = { - .init = da850_sata_init, - .exit = da850_sata_exit, -}; - static u64 da850_sata_dmamask = DMA_BIT_MASK(32); static struct platform_device da850_sata_device = { - .name = "ahci", + .name = "ahci_da850", .id = -1, .dev = { - .platform_data = &da850_sata_pdata, .dma_mask = &da850_sata_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), }, @@ -1134,9 +1052,8 @@ static struct platform_device da850_sata_device = { int __init da850_register_sata(unsigned long refclkpn) { - da850_sata_refclkpn = refclkpn; - if (!da850_sata_refclkpn) - return -EINVAL; + /* please see comment in drivers/ata/ahci_da850.c */ + BUG_ON(refclkpn != 100 * 1000 * 1000); return platform_device_register(&da850_sata_device); } -- cgit v1.2.3-55-g7522 From 8ff973a26763ef2f2d45c1649c618dfff528a502 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 19 Mar 2014 20:21:18 +0100 Subject: ARM: sun7i/sun6i: dts: Add NMI irqchip support This patch adds DTS entries for NMI controller as child of GIC. Signed-off-by: Carlo Caione Cc: linux-arm-kernel@lists.infradead.org Cc: linux-sunxi@googlegroups.com Cc: mark.rutland@arm.com Cc: hdegoede@redhat.com Acked-by: maxime.ripard@free-electrons.com Link: http://lkml.kernel.org/r/1395256879-8475-3-git-send-email-carlo@caione.org Signed-off-by: Thomas Gleixner --- arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++++++ arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ 2 files changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 5256ad9be52c..eea6033f7109 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -190,6 +190,14 @@ #size-cells = <1>; ranges; + nmi_intc: interrupt-controller@01f00c0c { + compatible = "allwinner,sun6i-a31-sc-nmi"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01f00c0c 0x38>; + interrupts = <0 0 4>; + }; + pio: pinctrl@01c20800 { compatible = "allwinner,sun6i-a31-pinctrl"; reg = <0x01c20800 0x400>; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 6f25cf559ad0..7637f126a270 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -339,6 +339,14 @@ #size-cells = <1>; ranges; + nmi_intc: interrupt-controller@01c00030 { + compatible = "allwinner,sun7i-a20-sc-nmi"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01c00030 0x0c>; + interrupts = <0 0 4>; + }; + emac: ethernet@01c0b000 { compatible = "allwinner,sun4i-a10-emac"; reg = <0x01c0b000 0x1000>; -- cgit v1.2.3-55-g7522 From 204b0a1a4b92612c957a042df1a3be0e9cc79391 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sat, 22 Mar 2014 10:09:01 +0000 Subject: x86, efi: Abstract x86 efi_early calls The ARM EFI boot stub doesn't need to care about the efi_early infrastructure that x86 requires in order to do mixed mode thunking. So wrap everything up in an efi_call_early() macro. This allows x86 to do the necessary indirection jumps to call whatever firmware interface is necessary (native or mixed mode), but also allows the ARM folks to mask the fact that they don't support relocation in the boot stub and need to pass 'sys_table_arg' to every function. [ hpa: there are no object code changes from this patch ] Signed-off-by: Matt Fleming Link: http://lkml.kernel.org/r/20140326091011.GB2958@console-pimps.org Cc: Roy Franz Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/eboot.c | 155 ++++++++++++++++----------------- drivers/firmware/efi/efi-stub-helper.c | 44 +++++----- 2 files changed, 98 insertions(+), 101 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 5e1ba4fa3f79..1e6146137f8e 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -21,6 +21,9 @@ static efi_system_table_t *sys_table; static struct efi_config *efi_early; +#define efi_call_early(f, ...) \ + efi_early->call(efi_early->f, __VA_ARGS__); + #define BOOT_SERVICES(bits) \ static void setup_boot_services##bits(struct efi_config *c) \ { \ @@ -78,8 +81,8 @@ __file_size32(void *__fh, efi_char16_t *filename_16, } grow: - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - info_sz, (void **)&info); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + info_sz, (void **)&info); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to alloc mem for file info\n"); return status; @@ -88,12 +91,12 @@ grow: status = efi_early->call((unsigned long)h->get_info, h, &info_guid, &info_sz, info); if (status == EFI_BUFFER_TOO_SMALL) { - efi_early->call(efi_early->free_pool, info); + efi_call_early(free_pool, info); goto grow; } *file_sz = info->file_size; - efi_early->call(efi_early->free_pool, info); + efi_call_early(free_pool, info); if (status != EFI_SUCCESS) efi_printk(sys_table, "Failed to get initrd info\n"); @@ -131,8 +134,8 @@ __file_size64(void *__fh, efi_char16_t *filename_16, } grow: - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - info_sz, (void **)&info); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + info_sz, (void **)&info); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to alloc mem for file info\n"); return status; @@ -141,12 +144,12 @@ grow: status = efi_early->call((unsigned long)h->get_info, h, &info_guid, &info_sz, info); if (status == EFI_BUFFER_TOO_SMALL) { - efi_early->call(efi_early->free_pool, info); + efi_call_early(free_pool, info); goto grow; } *file_sz = info->file_size; - efi_early->call(efi_early->free_pool, info); + efi_call_early(free_pool, info); if (status != EFI_SUCCESS) efi_printk(sys_table, "Failed to get initrd info\n"); @@ -204,8 +207,8 @@ static inline efi_status_t __open_volume32(void *__image, void **__fh) void *handle = (void *)(unsigned long)image->device_handle; unsigned long func; - status = efi_early->call(efi_early->handle_protocol, handle, - &fs_proto, (void **)&io); + status = efi_call_early(handle_protocol, handle, + &fs_proto, (void **)&io); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to handle fs_proto\n"); return status; @@ -230,8 +233,8 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh) void *handle = (void *)(unsigned long)image->device_handle; unsigned long func; - status = efi_early->call(efi_early->handle_protocol, handle, - &fs_proto, (void **)&io); + status = efi_call_early(handle_protocol, handle, + &fs_proto, (void **)&io); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to handle fs_proto\n"); return status; @@ -325,9 +328,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) size = pci->romsize + sizeof(*rom); - status = efi_early->call(efi_early->allocate_pool, - EFI_LOADER_DATA, size, &rom); - + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); if (status != EFI_SUCCESS) return status; @@ -361,7 +362,7 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) return status; free_struct: - efi_early->call(efi_early->free_pool, rom); + efi_call_early(free_pool, rom); return status; } @@ -387,8 +388,8 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle, struct pci_setup_rom *rom = NULL; u32 h = handles[i]; - status = efi_early->call(efi_early->handle_protocol, h, - &pci_proto, (void **)&pci); + status = efi_call_early(handle_protocol, h, + &pci_proto, (void **)&pci); if (status != EFI_SUCCESS) continue; @@ -431,9 +432,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) size = pci->romsize + sizeof(*rom); - status = efi_early->call(efi_early->allocate_pool, - EFI_LOADER_DATA, size, &rom); - + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); if (status != EFI_SUCCESS) return status; @@ -465,7 +464,7 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) return status; free_struct: - efi_early->call(efi_early->free_pool, rom); + efi_call_early(free_pool, rom); return status; } @@ -492,8 +491,8 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle, struct pci_setup_rom *rom = NULL; u64 h = handles[i]; - status = efi_early->call(efi_early->handle_protocol, h, - &pci_proto, (void **)&pci); + status = efi_call_early(handle_protocol, h, + &pci_proto, (void **)&pci); if (status != EFI_SUCCESS) continue; @@ -524,21 +523,21 @@ static efi_status_t setup_efi_pci(struct boot_params *params) efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; unsigned long size = 0; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - &pci_proto, NULL, &size, pci_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &pci_proto, NULL, &size, pci_handle); if (status == EFI_BUFFER_TOO_SMALL) { - status = efi_early->call(efi_early->allocate_pool, - EFI_LOADER_DATA, - size, (void **)&pci_handle); + status = efi_call_early(allocate_pool, + EFI_LOADER_DATA, + size, (void **)&pci_handle); if (status != EFI_SUCCESS) return status; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, &pci_proto, - NULL, &size, pci_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, &pci_proto, + NULL, &size, pci_handle); } if (status != EFI_SUCCESS) @@ -550,7 +549,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params) status = setup_efi_pci32(params, pci_handle, size); free_handle: - efi_early->call(efi_early->free_pool, pci_handle); + efi_call_early(free_pool, pci_handle); return status; } @@ -651,13 +650,13 @@ setup_gop32(struct screen_info *si, efi_guid_t *proto, void *dummy = NULL; u32 h = handles[i]; - status = efi_early->call(efi_early->handle_protocol, h, - proto, (void **)&gop32); + status = efi_call_early(handle_protocol, h, + proto, (void **)&gop32); if (status != EFI_SUCCESS) continue; - status = efi_early->call(efi_early->handle_protocol, h, - &conout_proto, &dummy); + status = efi_call_early(handle_protocol, h, + &conout_proto, &dummy); if (status == EFI_SUCCESS) conout_found = true; @@ -754,13 +753,13 @@ setup_gop64(struct screen_info *si, efi_guid_t *proto, void *dummy = NULL; u64 h = handles[i]; - status = efi_early->call(efi_early->handle_protocol, h, - proto, (void **)&gop64); + status = efi_call_early(handle_protocol, h, + proto, (void **)&gop64); if (status != EFI_SUCCESS) continue; - status = efi_early->call(efi_early->handle_protocol, h, - &conout_proto, &dummy); + status = efi_call_early(handle_protocol, h, + &conout_proto, &dummy); if (status == EFI_SUCCESS) conout_found = true; @@ -819,14 +818,14 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, efi_status_t status; void **gop_handle = NULL; - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - size, (void **)&gop_handle); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + size, (void **)&gop_handle); if (status != EFI_SUCCESS) return status; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - proto, NULL, &size, gop_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, + proto, NULL, &size, gop_handle); if (status != EFI_SUCCESS) goto free_handle; @@ -836,7 +835,7 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, status = setup_gop32(si, proto, size, gop_handle); free_handle: - efi_early->call(efi_early->free_pool, gop_handle); + efi_call_early(free_pool, gop_handle); return status; } @@ -858,13 +857,12 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) void *pciio; u32 handle = handles[i]; - status = efi_early->call(efi_early->handle_protocol, handle, - &uga_proto, (void **)&uga); + status = efi_call_early(handle_protocol, handle, + &uga_proto, (void **)&uga); if (status != EFI_SUCCESS) continue; - efi_early->call(efi_early->handle_protocol, handle, - &pciio_proto, &pciio); + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio); status = efi_early->call((unsigned long)uga->get_mode, uga, &w, &h, &depth, &refresh); @@ -904,13 +902,12 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height) void *pciio; u64 handle = handles[i]; - status = efi_early->call(efi_early->handle_protocol, handle, - &uga_proto, (void **)&uga); + status = efi_call_early(handle_protocol, handle, + &uga_proto, (void **)&uga); if (status != EFI_SUCCESS) continue; - efi_early->call(efi_early->handle_protocol, handle, - &pciio_proto, &pciio); + efi_call_early(handle_protocol, handle, &pciio_proto, &pciio); status = efi_early->call((unsigned long)uga->get_mode, uga, &w, &h, &depth, &refresh); @@ -942,14 +939,14 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, u32 width, height; void **uga_handle = NULL; - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - size, (void **)&uga_handle); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + size, (void **)&uga_handle); if (status != EFI_SUCCESS) return status; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - uga_proto, NULL, &size, uga_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, + uga_proto, NULL, &size, uga_handle); if (status != EFI_SUCCESS) goto free_handle; @@ -981,7 +978,7 @@ static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, si->rsvd_pos = 24; free_handle: - efi_early->call(efi_early->free_pool, uga_handle); + efi_call_early(free_pool, uga_handle); return status; } @@ -999,17 +996,17 @@ void setup_graphics(struct boot_params *boot_params) memset(si, 0, sizeof(*si)); size = 0; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - &graphics_proto, NULL, &size, gop_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &graphics_proto, NULL, &size, gop_handle); if (status == EFI_BUFFER_TOO_SMALL) status = setup_gop(si, &graphics_proto, size); if (status != EFI_SUCCESS) { size = 0; - status = efi_early->call(efi_early->locate_handle, - EFI_LOCATE_BY_PROTOCOL, - &uga_proto, NULL, &size, uga_handle); + status = efi_call_early(locate_handle, + EFI_LOCATE_BY_PROTOCOL, + &uga_proto, NULL, &size, uga_handle); if (status == EFI_BUFFER_TOO_SMALL) setup_uga(si, &uga_proto, size); } @@ -1052,8 +1049,8 @@ struct boot_params *make_boot_params(struct efi_config *c) else setup_boot_services32(efi_early); - status = efi_early->call(efi_early->handle_protocol, handle, - &proto, (void *)&image); + status = efi_call_early(handle_protocol, handle, + &proto, (void *)&image); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); return NULL; @@ -1242,13 +1239,13 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, sizeof(struct e820entry) * nr_desc; if (*e820ext) { - efi_early->call(efi_early->free_pool, *e820ext); + efi_call_early(free_pool, *e820ext); *e820ext = NULL; *e820ext_size = 0; } - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - size, (void **)e820ext); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + size, (void **)e820ext); if (status == EFI_SUCCESS) *e820ext_size = size; @@ -1292,7 +1289,7 @@ get_map: if (status != EFI_SUCCESS) goto free_mem_map; - efi_early->call(efi_early->free_pool, mem_map); + efi_call_early(free_pool, mem_map); goto get_map; /* Allocated memory, get map again */ } @@ -1311,7 +1308,7 @@ get_map: #endif /* Might as well exit boot services now */ - status = efi_early->call(efi_early->exit_boot_services, handle, key); + status = efi_call_early(exit_boot_services, handle, key); if (status != EFI_SUCCESS) { /* * ExitBootServices() will fail if any of the event @@ -1324,7 +1321,7 @@ get_map: goto free_mem_map; called_exit = true; - efi_early->call(efi_early->free_pool, mem_map); + efi_call_early(free_pool, mem_map); goto get_map; } @@ -1338,7 +1335,7 @@ get_map: return EFI_SUCCESS; free_mem_map: - efi_early->call(efi_early->free_pool, mem_map); + efi_call_early(free_pool, mem_map); return status; } @@ -1379,8 +1376,8 @@ struct boot_params *efi_main(struct efi_config *c, setup_efi_pci(boot_params); - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - sizeof(*gdt), (void **)&gdt); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + sizeof(*gdt), (void **)&gdt); if (status != EFI_SUCCESS) { efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); goto fail; diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c index a0282872d97d..ff50aeebf0d9 100644 --- a/drivers/firmware/efi/efi-stub-helper.c +++ b/drivers/firmware/efi/efi-stub-helper.c @@ -53,22 +53,22 @@ again: * allocation which may be in a new descriptor region. */ *map_size += sizeof(*m); - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - *map_size, (void **)&m); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + *map_size, (void **)&m); if (status != EFI_SUCCESS) goto fail; *desc_size = 0; key = 0; - status = efi_early->call(efi_early->get_memory_map, map_size, m, - &key, desc_size, &desc_version); + status = efi_call_early(get_memory_map, map_size, m, + &key, desc_size, &desc_version); if (status == EFI_BUFFER_TOO_SMALL) { - efi_early->call(efi_early->free_pool, m); + efi_call_early(free_pool, m); goto again; } if (status != EFI_SUCCESS) - efi_early->call(efi_early->free_pool, m); + efi_call_early(free_pool, m); if (key_ptr && status == EFI_SUCCESS) *key_ptr = key; @@ -149,9 +149,9 @@ again: if (!max_addr) status = EFI_NOT_FOUND; else { - status = efi_early->call(efi_early->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &max_addr); + status = efi_call_early(allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &max_addr); if (status != EFI_SUCCESS) { max = max_addr; max_addr = 0; @@ -161,7 +161,7 @@ again: *addr = max_addr; } - efi_early->call(efi_early->free_pool, map); + efi_call_early(free_pool, map); fail: return status; } @@ -221,9 +221,9 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, if ((start + size) > end) continue; - status = efi_early->call(efi_early->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &start); + status = efi_call_early(allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &start); if (status == EFI_SUCCESS) { *addr = start; break; @@ -233,7 +233,7 @@ static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, if (i == map_size / desc_size) status = EFI_NOT_FOUND; - efi_early->call(efi_early->free_pool, map); + efi_call_early(free_pool, map); fail: return status; } @@ -247,7 +247,7 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size, return; nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - efi_early->call(efi_early->free_pages, addr, nr_pages); + efi_call_early(free_pages, addr, nr_pages); } @@ -307,8 +307,8 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, if (!nr_files) return EFI_SUCCESS; - status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, - nr_files * sizeof(*files), (void **)&files); + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + nr_files * sizeof(*files), (void **)&files); if (status != EFI_SUCCESS) { efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n"); goto fail; @@ -413,7 +413,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, } - efi_early->call(efi_early->free_pool, files); + efi_call_early(free_pool, files); *load_addr = file_addr; *load_size = file_size_total; @@ -427,7 +427,7 @@ close_handles: for (k = j; k < i; k++) efi_file_close(fh, files[k].handle); free_files: - efi_early->call(efi_early->free_pool, files); + efi_call_early(free_pool, files); fail: *load_addr = 0; *load_size = 0; @@ -473,9 +473,9 @@ static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, * as possible while respecting the required alignment. */ nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; - status = efi_early->call(efi_early->allocate_pages, - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, - nr_pages, &efi_addr); + status = efi_call_early(allocate_pages, + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, + nr_pages, &efi_addr); new_addr = efi_addr; /* * If preferred address allocation failed allocate as low as -- cgit v1.2.3-55-g7522 From ca3ba2a2f4a49a308e7d78c784d51b2332064f15 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 28 Feb 2014 11:30:29 +0800 Subject: x86, hyperv: Bypass the timer_irq_works() check This patch bypass the timer_irq_works() check for hyperv guest since: - It was guaranteed to work. - timer_irq_works() may fail sometime due to the lpj calibration were inaccurate in a hyperv guest or a buggy host. In the future, we should get the tsc frequency from hypervisor and use preset lpj instead. [ hpa: I would prefer to not defer things to "the future" in the future... ] Cc: K. Y. Srinivasan Cc: Haiyang Zhang Cc: Acked-by: K. Y. Srinivasan Signed-off-by: Jason Wang Link: http://lkml.kernel.org/r/1393558229-14755-1-git-send-email-jasowang@redhat.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mshyperv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 9f7ca266864a..832d05a914ba 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -26,6 +26,7 @@ #include #include #include +#include struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); @@ -105,6 +106,11 @@ static void __init ms_hyperv_init_platform(void) if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); + +#ifdef CONFIG_X86_IO_APIC + no_timer_check = 1; +#endif + } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { -- cgit v1.2.3-55-g7522 From 825600c0f20e595daaa7a6dd8970f84fa2a2ee57 Mon Sep 17 00:00:00 2001 From: Artem Fetishev Date: Fri, 28 Mar 2014 13:33:39 -0700 Subject: x86: fix boot on uniprocessor systems On x86 uniprocessor systems topology_physical_package_id() returns -1 which causes rapl_cpu_prepare() to leave rapl_pmu variable uninitialized which leads to GPF in rapl_pmu_init(). See arch/x86/kernel/cpu/perf_event_intel_rapl.c. It turns out that physical_package_id and core_id can actually be retreived for uniprocessor systems too. Enabling them also fixes rapl_pmu code. Signed-off-by: Artem Fetishev Cc: Stephane Eranian Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/include/asm/topology.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index d35f24e231cd..1306d117967d 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -119,9 +119,10 @@ static inline void setup_node_to_cpumask_map(void) { } extern const struct cpumask *cpu_coregroup_mask(int cpu); -#ifdef ENABLE_TOPO_DEFINES #define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id) #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) + +#ifdef ENABLE_TOPO_DEFINES #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) #endif -- cgit v1.2.3-55-g7522 From 4c332c3238ab41fa9bc18d6ccb8e8aec1c87a426 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 15 Mar 2014 13:11:18 -0700 Subject: [IA64] Keep format strings from leaking into printk The buffer being sent to printk has already had format strings resolved. The string should not be reinterpreted again to avoid any unintended format strings from leaking into printk. Signed-off-by: Kees Cook Signed-off-by: Tony Luck --- arch/ia64/kernel/mca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index b8edfa75a83f..601502ab7141 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -217,7 +217,7 @@ void ia64_mca_printk(const char *fmt, ...) /* Copy the output into mlogbuf */ if (oops_in_progress) { /* mlogbuf was abandoned, use printk directly instead. */ - printk(temp_buf); + printk("%s", temp_buf); } else { spin_lock(&mlogbuf_wlock); for (p = temp_buf; *p; p++) { @@ -268,7 +268,7 @@ void ia64_mlogbuf_dump(void) } *p = '\0'; if (temp_buf[0]) - printk(temp_buf); + printk("%s", temp_buf); mlogbuf_start = index; mlogbuf_timestamp = 0; -- cgit v1.2.3-55-g7522 From 1e4ec6217dcf4b26cf959b70298a3b990479c955 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 29 Mar 2014 10:50:47 +0100 Subject: s390/compat: add copyright statement Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrapper.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index d123f5d87b82..824c39dfddfc 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -1,3 +1,9 @@ +/* + * Compat sytem call wrappers. + * + * Copyright IBM Corp. 2014 + */ + #include #include #include "entry.h" -- cgit v1.2.3-55-g7522 From 8acc8722d3b5755abbfbe73f732dec576f28757a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 22 Feb 2014 09:28:27 +0100 Subject: avr32: remove cpu_data macro to fix compiles Having cpu_data as a parameterless macro can easily cause build failures because it can be a variable name like in linux/pm_domain.h [1]. So, remove the macro and convert its only user. Because this architecture cannot do SMP, remove the whole SMP block, too. Only compile tested due to no hardware. Signed-off-by: Wolfram Sang Acked-by: Hans-Christian Egtvedt [1] https://lists.01.org/pipermail/kbuild-all/2014-February/003252.html --- arch/avr32/include/asm/bugs.h | 2 +- arch/avr32/include/asm/processor.h | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/avr32/include/asm/bugs.h b/arch/avr32/include/asm/bugs.h index 7635e770622e..278661bbd1b0 100644 --- a/arch/avr32/include/asm/bugs.h +++ b/arch/avr32/include/asm/bugs.h @@ -9,7 +9,7 @@ static void __init check_bugs(void) { - cpu_data->loops_per_jiffy = loops_per_jiffy; + boot_cpu_data.loops_per_jiffy = loops_per_jiffy; } #endif /* __ASM_AVR32_BUGS_H */ diff --git a/arch/avr32/include/asm/processor.h b/arch/avr32/include/asm/processor.h index 48d71c5c898a..972adcc1e8f4 100644 --- a/arch/avr32/include/asm/processor.h +++ b/arch/avr32/include/asm/processor.h @@ -83,13 +83,8 @@ static inline unsigned int avr32_get_chip_revision(struct avr32_cpuinfo *cpu) extern struct avr32_cpuinfo boot_cpu_data; -#ifdef CONFIG_SMP -extern struct avr32_cpuinfo cpu_data[]; -#define current_cpu_data cpu_data[smp_processor_id()] -#else -#define cpu_data (&boot_cpu_data) +/* No SMP support so far */ #define current_cpu_data boot_cpu_data -#endif /* This decides where the kernel will search for a free chunk of vm * space during mmap's -- cgit v1.2.3-55-g7522 From 2601566d01026d6ad46b1e967466aee7fbce948e Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Sun, 9 Mar 2014 05:35:46 +0800 Subject: arch/avr32/mm/cache.c: export symbol flush_icache_range() for module using Need export symbol flush_icache_range() to modules, just like another platforms have done, or can not pass compiling. The related error (with allmodconfig under avr32): ERROR: "flush_icache_range" [drivers/misc/lkdtm.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 Signed-off-by: Chen Gang Acked-by: Hans-Christian Egtvedt --- arch/avr32/mm/cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c index 6a46ecd56cfd..85d635cd7b28 100644 --- a/arch/avr32/mm/cache.c +++ b/arch/avr32/mm/cache.c @@ -111,6 +111,7 @@ void flush_icache_range(unsigned long start, unsigned long end) __flush_icache_range(start & ~(linesz - 1), (end + linesz - 1) & ~(linesz - 1)); } +EXPORT_SYMBOL(flush_icache_range); /* * This one is called from __do_fault() and do_swap_page(). -- cgit v1.2.3-55-g7522 From 536a44d4277709303755e6365a059f54f4aa5403 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 27 Mar 2014 18:02:38 +0100 Subject: ARM: sun7i/sun6i: dts: Fix IRQ number for sun6i NMI controller The IRQ line used in sun6i-a31.dtsi for the NMI controller is wrong. This causes a IRQ storm since the NMI controller is repeatedly fired. This patch fixes this problem assigning the correct IRQ number to the NMI controller. Signed-off-by: Hans de Goede Signed-off-by: Carlo Caione Cc: maxime.ripard@free-electrons.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-sunxi@googlegroups.com Link: http://lkml.kernel.org/r/1395939759-11135-2-git-send-email-carlo@caione.org Signed-off-by: Thomas Gleixner --- arch/arm/boot/dts/sun6i-a31.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index eea6033f7109..fbdf88facf8d 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -195,7 +195,7 @@ interrupt-controller; #interrupt-cells = <2>; reg = <0x01f00c0c 0x38>; - interrupts = <0 0 4>; + interrupts = <0 32 4>; }; pio: pinctrl@01c20800 { -- cgit v1.2.3-55-g7522 From 50be9eba831da114e1979726f4119d342698e651 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 4 Feb 2014 21:19:17 +0100 Subject: m68k: Update defconfigs for v3.14-rc1 Signed-off-by: Geert Uytterhoeven --- arch/m68k/configs/amiga_defconfig | 10 ++++++---- arch/m68k/configs/apollo_defconfig | 10 ++++++---- arch/m68k/configs/atari_defconfig | 10 ++++++---- arch/m68k/configs/bvme6000_defconfig | 10 ++++++---- arch/m68k/configs/hp300_defconfig | 10 ++++++---- arch/m68k/configs/mac_defconfig | 10 ++++++---- arch/m68k/configs/multi_defconfig | 10 ++++++---- arch/m68k/configs/mvme147_defconfig | 10 ++++++---- arch/m68k/configs/mvme16x_defconfig | 10 ++++++---- arch/m68k/configs/q40_defconfig | 10 ++++++---- arch/m68k/configs/sun3_defconfig | 10 ++++++---- arch/m68k/configs/sun3x_defconfig | 10 ++++++---- 12 files changed, 72 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 559ff3af8ff7..96da4963d14b 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -24,6 +24,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y @@ -85,6 +87,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -94,6 +97,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -126,6 +131,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -163,8 +169,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -190,7 +194,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -512,7 +515,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index cb1f55df69b6..1b8739f50cbf 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -25,6 +25,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y @@ -83,6 +85,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -92,6 +95,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -124,6 +129,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -161,8 +167,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -188,7 +192,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -470,7 +473,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index e880cfbb62d9..6ea4e91f0caa 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -24,6 +24,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y @@ -82,6 +84,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -91,6 +94,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -123,6 +128,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -160,8 +166,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -187,7 +191,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -487,7 +490,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 4aa4f45e52a8..e5a12739ff2d 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -24,6 +24,8 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y CONFIG_M68060=y CONFIG_VME=y @@ -81,6 +83,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -90,6 +93,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -122,6 +127,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -159,8 +165,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -186,7 +190,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -463,7 +466,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 7cd9d9f456fb..8936d7fb0f0f 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -25,6 +25,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y @@ -83,6 +85,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -92,6 +95,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -124,6 +129,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -161,8 +167,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -188,7 +192,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -472,7 +475,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 31f5bd061d14..be5342cca25b 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -24,6 +24,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68030=y CONFIG_M68040=y @@ -82,6 +84,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -91,6 +94,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -123,6 +128,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -160,8 +166,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -187,7 +191,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -495,7 +498,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 4e5adff326ee..f27194ade167 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -20,6 +20,8 @@ CONFIG_SOLARIS_X86_PARTITION=y CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68020=y CONFIG_M68040=y CONFIG_M68060=y @@ -91,6 +93,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -100,6 +103,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -132,6 +137,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -169,8 +175,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -196,7 +200,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -571,7 +574,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 02cdbac5565e..c3887603c1db 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -24,6 +24,8 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68030=y CONFIG_VME=y CONFIG_MVME147=y @@ -80,6 +82,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -89,6 +92,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -121,6 +126,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -158,8 +164,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -185,7 +189,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -463,7 +466,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 05a990a9dbd4..f7ff784d05ac 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -24,6 +24,8 @@ CONFIG_UNIXWARE_DISKLABEL=y CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y CONFIG_M68060=y CONFIG_VME=y @@ -81,6 +83,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -90,6 +93,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -122,6 +127,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -159,8 +165,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -186,7 +190,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -464,7 +467,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 568e2a98f976..f0c72ab037be 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -25,6 +25,8 @@ CONFIG_SUN_PARTITION=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_M68040=y CONFIG_M68060=y CONFIG_Q40=y @@ -81,6 +83,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -90,6 +93,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -122,6 +127,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -159,8 +165,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -186,7 +190,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -485,7 +488,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 60b0aeac5742..7bca0f464521 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -24,6 +24,8 @@ CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_SUN3=y # CONFIG_COMPACTION is not set CONFIG_CLEANCACHE=y @@ -78,6 +80,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -87,6 +90,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -119,6 +124,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -156,8 +162,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -183,7 +187,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -464,7 +467,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 21bda331eebb..317f3e1fec95 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -24,6 +24,8 @@ CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_EFI_PARTITION is not set CONFIG_SYSV68_PARTITION=y CONFIG_IOSCHED_DEADLINE=m +CONFIG_KEXEC=y +CONFIG_BOOTINFO_PROC=y CONFIG_SUN3X=y # CONFIG_COMPACTION is not set CONFIG_CLEANCACHE=y @@ -78,6 +80,7 @@ CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m CONFIG_NFT_EXTHDR=m CONFIG_NFT_META=m CONFIG_NFT_CT=m @@ -87,6 +90,8 @@ CONFIG_NFT_COUNTER=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m CONFIG_NFT_COMPAT=m CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m @@ -119,6 +124,7 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -156,8 +162,6 @@ CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_TABLES_IPV4=m -CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_CHAIN_NAT_IPV4=m CONFIG_NF_TABLES_ARP=m @@ -183,7 +187,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_NF_TABLES_IPV6=m CONFIG_NFT_CHAIN_ROUTE_IPV6=m CONFIG_NFT_CHAIN_NAT_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -464,7 +467,6 @@ CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_T10DIF=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y -- cgit v1.2.3-55-g7522 From 6f8a1b335fde143b7407036e2368d3cd6eb55674 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 12 Mar 2014 14:44:33 -0400 Subject: x86: Adjust irq remapping quirk for older revisions of 5500/5520 chipsets Commit 03bbcb2e7e2 (iommu/vt-d: add quirk for broken interrupt remapping on 55XX chipsets) properly disables irq remapping on the 5500/5520 chipsets that don't correctly perform that feature. However, when I wrote it, I followed the errata sheet linked in that commit too closely, and explicitly tied the activation of the quirk to revision 0x13 of the chip, under the assumption that earlier revisions were not in the field. Recently a system was reported to be suffering from this remap bug and the quirk hadn't triggered, because the revision id register read at a lower value that 0x13, so the quirk test failed improperly. Given this, it seems only prudent to adjust this quirk so that any revision less than 0x13 has the quirk asserted. [ tglx: Removed the 0x12 comparison of pci id 3405 as this is covered by the <= 0x13 check already ] Signed-off-by: Neil Horman Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1394649873-14913-1-git-send-email-nhorman@tuxdriver.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/early-quirks.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index bc4a088f9023..6d7d5a1260a6 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -203,18 +203,15 @@ static void __init intel_remapping_check(int num, int slot, int func) revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID); /* - * Revision 13 of all triggering devices id in this quirk have - * a problem draining interrupts when irq remapping is enabled, - * and should be flagged as broken. Additionally revisions 0x12 - * and 0x22 of device id 0x3405 has this problem. + * Revision <= 13 of all triggering devices id in this quirk + * have a problem draining interrupts when irq remapping is + * enabled, and should be flagged as broken. Additionally + * revision 0x22 of device id 0x3405 has this problem. */ - if (revision == 0x13) + if (revision <= 0x13) set_irq_remapping_broken(); - else if ((device == 0x3405) && - ((revision == 0x12) || - (revision == 0x22))) + else if (device == 0x3405 && revision == 0x22) set_irq_remapping_broken(); - } /* -- cgit v1.2.3-55-g7522 From 4c3b7df4ed541f934e7aad7a52aee12d44b9c2ff Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 31 Mar 2014 20:42:42 -0400 Subject: avr32: replace simple_strtoul() with kstrtoul() simple_strtoul() is marked for obsoletion; use the newer and more pleasant kstrtoul() in its place. Cc: Alexey Dobriyan Cc: Haavard Skinnemoen Cc: Hans-Christian Egtvedt Signed-off-by: Ramkumar Ramachandra Signed-off-by: Hans-Christian Egtvedt --- arch/avr32/kernel/cpu.c | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c index 2233be71e2e8..0341ae27c9ec 100644 --- a/arch/avr32/kernel/cpu.c +++ b/arch/avr32/kernel/cpu.c @@ -39,10 +39,12 @@ static ssize_t store_pc0event(struct device *dev, size_t count) { unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf || val > 0x3f) + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + if (val > 0x3f) return -EINVAL; val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff); sysreg_write(PCCR, val); @@ -61,11 +63,11 @@ static ssize_t store_pc0count(struct device *dev, const char *buf, size_t count) { unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; sysreg_write(PCNT0, val); return count; @@ -84,10 +86,12 @@ static ssize_t store_pc1event(struct device *dev, size_t count) { unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf || val > 0x3f) + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + if (val > 0x3f) return -EINVAL; val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff); sysreg_write(PCCR, val); @@ -106,11 +110,11 @@ static ssize_t store_pc1count(struct device *dev, size_t count) { unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; sysreg_write(PCNT1, val); return count; @@ -129,11 +133,11 @@ static ssize_t store_pccycles(struct device *dev, size_t count) { unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; sysreg_write(PCCNT, val); return count; @@ -152,11 +156,11 @@ static ssize_t store_pcenable(struct device *dev, size_t count) { unsigned long pccr, val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (endp == buf) - return -EINVAL; + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; if (val) val = 1; -- cgit v1.2.3-55-g7522