diff options
author | Jens Axboe <axboe@kernel.dk> | 2013-07-02 02:31:48 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-07-02 02:31:48 -0400 |
commit | 5f0e5afa0de4522abb3ea7d1369039b94e740ec5 (patch) | |
tree | 6a5be3db9ecfed8ef2150c6146f6d1e0d658ac8b /arch/powerpc | |
parent | d752b2696072ed52fd5afab08b601e2220a3b87e (diff) | |
parent | 9e895ace5d82df8929b16f58e9f515f6d54ab82d (diff) |
Merge tag 'v3.10-rc7' into for-3.11/drivers
Linux 3.10-rc7
Pull this in early to avoid doing it with the bcache merge,
since there are a number of changes to bcache between my old
base (3.10-rc1) and the new pull request.
Diffstat (limited to 'arch/powerpc')
82 files changed, 1208 insertions, 483 deletions
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 5416e28a7538..863d877e0b5f 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI | |||
262 | Select this to enable early debugging for the PowerNV platform | 262 | Select this to enable early debugging for the PowerNV platform |
263 | using an "hvsi" console | 263 | using an "hvsi" console |
264 | 264 | ||
265 | config PPC_EARLY_DEBUG_MEMCONS | ||
266 | bool "In memory console" | ||
267 | help | ||
268 | Select this to enable early debugging using an in memory console. | ||
269 | This console provides input and output buffers stored within the | ||
270 | kernel BSS and should be safe to select on any system. A debugger | ||
271 | can then be used to read kernel output or send input to the console. | ||
265 | endchoice | 272 | endchoice |
266 | 273 | ||
274 | config PPC_MEMCONS_OUTPUT_SIZE | ||
275 | int "In memory console output buffer size" | ||
276 | depends on PPC_EARLY_DEBUG_MEMCONS | ||
277 | default 4096 | ||
278 | help | ||
279 | Selects the size of the output buffer (in bytes) of the in memory | ||
280 | console. | ||
281 | |||
282 | config PPC_MEMCONS_INPUT_SIZE | ||
283 | int "In memory console input buffer size" | ||
284 | depends on PPC_EARLY_DEBUG_MEMCONS | ||
285 | default 128 | ||
286 | help | ||
287 | Selects the size of the input buffer (in bytes) of the in memory | ||
288 | console. | ||
289 | |||
267 | config PPC_EARLY_DEBUG_OPAL | 290 | config PPC_EARLY_DEBUG_OPAL |
268 | def_bool y | 291 | def_bool y |
269 | depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI | 292 | depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI |
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index f79196232917..139a8308070c 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig | |||
@@ -136,7 +136,6 @@ CONFIG_HID_SMARTJOYPLUS=m | |||
136 | CONFIG_USB_HIDDEV=y | 136 | CONFIG_USB_HIDDEV=y |
137 | CONFIG_USB=m | 137 | CONFIG_USB=m |
138 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | 138 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y |
139 | CONFIG_USB_SUSPEND=y | ||
140 | CONFIG_USB_MON=m | 139 | CONFIG_USB_MON=m |
141 | CONFIG_USB_EHCI_HCD=m | 140 | CONFIG_USB_EHCI_HCD=m |
142 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set | 141 | # CONFIG_USB_EHCI_HCD_PPC_OF is not set |
diff --git a/arch/powerpc/include/asm/context_tracking.h b/arch/powerpc/include/asm/context_tracking.h new file mode 100644 index 000000000000..b6f5a33b8ee2 --- /dev/null +++ b/arch/powerpc/include/asm/context_tracking.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef _ASM_POWERPC_CONTEXT_TRACKING_H | ||
2 | #define _ASM_POWERPC_CONTEXT_TRACKING_H | ||
3 | |||
4 | #ifdef CONFIG_CONTEXT_TRACKING | ||
5 | #define SCHEDULE_USER bl .schedule_user | ||
6 | #else | ||
7 | #define SCHEDULE_USER bl .schedule | ||
8 | #endif | ||
9 | |||
10 | #endif | ||
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 26807e5aff51..6f3887d884d2 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -176,6 +176,7 @@ extern const char *powerpc_base_platform; | |||
176 | #define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000) | 176 | #define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000) |
177 | #define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) | 177 | #define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000) |
178 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) | 178 | #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) |
179 | #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) | ||
179 | 180 | ||
180 | #ifndef __ASSEMBLY__ | 181 | #ifndef __ASSEMBLY__ |
181 | 182 | ||
@@ -394,19 +395,20 @@ extern const char *powerpc_base_platform; | |||
394 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \ | 395 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \ |
395 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \ | 396 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \ |
396 | CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \ | 397 | CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \ |
397 | CPU_FTR_HVMODE) | 398 | CPU_FTR_HVMODE | CPU_FTR_DABRX) |
398 | #define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 399 | #define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
399 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 400 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
400 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 401 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
401 | CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \ | 402 | CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \ |
402 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB) | 403 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_DABRX) |
403 | #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 404 | #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
404 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 405 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
405 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 406 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
406 | CPU_FTR_COHERENT_ICACHE | \ | 407 | CPU_FTR_COHERENT_ICACHE | \ |
407 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ | 408 | CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ |
408 | CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \ | 409 | CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \ |
409 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR) | 410 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR | \ |
411 | CPU_FTR_DABRX) | ||
410 | #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 412 | #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
411 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ | 413 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ |
412 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 414 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
@@ -415,7 +417,7 @@ extern const char *powerpc_base_platform; | |||
415 | CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ | 417 | CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ |
416 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 418 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
417 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ | 419 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \ |
418 | CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR) | 420 | CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX) |
419 | #define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 421 | #define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
420 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ | 422 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ |
421 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 423 | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
@@ -430,14 +432,15 @@ extern const char *powerpc_base_platform; | |||
430 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 432 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
431 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 433 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
432 | CPU_FTR_PAUSE_ZERO | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \ | 434 | CPU_FTR_PAUSE_ZERO | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \ |
433 | CPU_FTR_UNALIGNED_LD_STD) | 435 | CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_DABRX) |
434 | #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 436 | #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
435 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \ | 437 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \ |
436 | CPU_FTR_PURR | CPU_FTR_REAL_LE) | 438 | CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX) |
437 | #define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2) | 439 | #define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2) |
438 | 440 | ||
439 | #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \ | 441 | #define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \ |
440 | CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX) | 442 | CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \ |
443 | CPU_FTR_ICSWX | CPU_FTR_DABRX ) | ||
441 | 444 | ||
442 | #ifdef __powerpc64__ | 445 | #ifdef __powerpc64__ |
443 | #ifdef CONFIG_PPC_BOOK3E | 446 | #ifdef CONFIG_PPC_BOOK3E |
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 8e5fae8beaf6..46793b58a761 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
@@ -513,7 +513,7 @@ label##_common: \ | |||
513 | */ | 513 | */ |
514 | #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ | 514 | #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ |
515 | EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ | 515 | EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \ |
516 | FINISH_NAP;RUNLATCH_ON;DISABLE_INTS) | 516 | FINISH_NAP;DISABLE_INTS;RUNLATCH_ON) |
517 | 517 | ||
518 | /* | 518 | /* |
519 | * When the idle code in power4_idle puts the CPU into NAP mode, | 519 | * When the idle code in power4_idle puts the CPU into NAP mode, |
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 0df54646f968..681bc0314b6b 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h | |||
@@ -52,6 +52,7 @@ | |||
52 | #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) | 52 | #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) |
53 | #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) | 53 | #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) |
54 | #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) | 54 | #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) |
55 | #define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000) | ||
55 | 56 | ||
56 | #ifndef __ASSEMBLY__ | 57 | #ifndef __ASSEMBLY__ |
57 | 58 | ||
@@ -69,7 +70,8 @@ enum { | |||
69 | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | | 70 | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | |
70 | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, | 71 | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, |
71 | FW_FEATURE_PSERIES_ALWAYS = 0, | 72 | FW_FEATURE_PSERIES_ALWAYS = 0, |
72 | FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2, | 73 | FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 | |
74 | FW_FEATURE_OPALv3, | ||
73 | FW_FEATURE_POWERNV_ALWAYS = 0, | 75 | FW_FEATURE_POWERNV_ALWAYS = 0, |
74 | FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, | 76 | FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, |
75 | FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, | 77 | FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index cf4df8e2139a..0c7f2bfcf134 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -264,6 +264,7 @@ | |||
264 | #define H_GET_MPP 0x2D4 | 264 | #define H_GET_MPP 0x2D4 |
265 | #define H_HOME_NODE_ASSOCIATIVITY 0x2EC | 265 | #define H_HOME_NODE_ASSOCIATIVITY 0x2EC |
266 | #define H_BEST_ENERGY 0x2F4 | 266 | #define H_BEST_ENERGY 0x2F4 |
267 | #define H_XIRR_X 0x2FC | ||
267 | #define H_RANDOM 0x300 | 268 | #define H_RANDOM 0x300 |
268 | #define H_COP 0x304 | 269 | #define H_COP 0x304 |
269 | #define H_GET_MPP_X 0x314 | 270 | #define H_GET_MPP_X 0x314 |
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index d615b28dda82..ba713f166fa5 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h | |||
@@ -96,11 +96,12 @@ static inline bool arch_irqs_disabled(void) | |||
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #define hard_irq_disable() do { \ | 98 | #define hard_irq_disable() do { \ |
99 | u8 _was_enabled = get_paca()->soft_enabled; \ | ||
99 | __hard_irq_disable(); \ | 100 | __hard_irq_disable(); \ |
100 | if (local_paca->soft_enabled) \ | ||
101 | trace_hardirqs_off(); \ | ||
102 | get_paca()->soft_enabled = 0; \ | 101 | get_paca()->soft_enabled = 0; \ |
103 | get_paca()->irq_happened |= PACA_IRQ_HARD_DIS; \ | 102 | get_paca()->irq_happened |= PACA_IRQ_HARD_DIS; \ |
103 | if (_was_enabled) \ | ||
104 | trace_hardirqs_off(); \ | ||
104 | } while(0) | 105 | } while(0) |
105 | 106 | ||
106 | static inline bool lazy_irq_pending(void) | 107 | static inline bool lazy_irq_pending(void) |
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index b9dd382cb349..851bac7afa4b 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
@@ -54,8 +54,16 @@ | |||
54 | #define BOOKE_INTERRUPT_DEBUG 15 | 54 | #define BOOKE_INTERRUPT_DEBUG 15 |
55 | 55 | ||
56 | /* E500 */ | 56 | /* E500 */ |
57 | #define BOOKE_INTERRUPT_SPE_UNAVAIL 32 | 57 | #define BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL 32 |
58 | #define BOOKE_INTERRUPT_SPE_FP_DATA 33 | 58 | #define BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST 33 |
59 | /* | ||
60 | * TODO: Unify 32-bit and 64-bit kernel exception handlers to use same defines | ||
61 | */ | ||
62 | #define BOOKE_INTERRUPT_SPE_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL | ||
63 | #define BOOKE_INTERRUPT_SPE_FP_DATA BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST | ||
64 | #define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL | ||
65 | #define BOOKE_INTERRUPT_ALTIVEC_ASSIST \ | ||
66 | BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST | ||
59 | #define BOOKE_INTERRUPT_SPE_FP_ROUND 34 | 67 | #define BOOKE_INTERRUPT_SPE_FP_ROUND 34 |
60 | #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 | 68 | #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 |
61 | #define BOOKE_INTERRUPT_DOORBELL 36 | 69 | #define BOOKE_INTERRUPT_DOORBELL 36 |
@@ -67,10 +75,6 @@ | |||
67 | #define BOOKE_INTERRUPT_HV_SYSCALL 40 | 75 | #define BOOKE_INTERRUPT_HV_SYSCALL 40 |
68 | #define BOOKE_INTERRUPT_HV_PRIV 41 | 76 | #define BOOKE_INTERRUPT_HV_PRIV 41 |
69 | 77 | ||
70 | /* altivec */ | ||
71 | #define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42 | ||
72 | #define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43 | ||
73 | |||
74 | /* book3s */ | 78 | /* book3s */ |
75 | 79 | ||
76 | #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 | 80 | #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index b6c8b58b1d76..cbb9305ab15a 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -243,7 +243,8 @@ enum OpalMCE_TlbErrorType { | |||
243 | 243 | ||
244 | enum OpalThreadStatus { | 244 | enum OpalThreadStatus { |
245 | OPAL_THREAD_INACTIVE = 0x0, | 245 | OPAL_THREAD_INACTIVE = 0x0, |
246 | OPAL_THREAD_STARTED = 0x1 | 246 | OPAL_THREAD_STARTED = 0x1, |
247 | OPAL_THREAD_UNAVAILABLE = 0x2 /* opal-v3 */ | ||
247 | }; | 248 | }; |
248 | 249 | ||
249 | enum OpalPciBusCompare { | 250 | enum OpalPciBusCompare { |
@@ -563,6 +564,8 @@ extern void opal_nvram_init(void); | |||
563 | 564 | ||
564 | extern int opal_machine_check(struct pt_regs *regs); | 565 | extern int opal_machine_check(struct pt_regs *regs); |
565 | 566 | ||
567 | extern void opal_shutdown(void); | ||
568 | |||
566 | #endif /* __ASSEMBLY__ */ | 569 | #endif /* __ASSEMBLY__ */ |
567 | 570 | ||
568 | #endif /* __OPAL_H */ | 571 | #endif /* __OPAL_H */ |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 8b11b5bd9938..2c1d8cb9b265 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -174,6 +174,8 @@ struct pci_dn { | |||
174 | /* Get the pointer to a device_node's pci_dn */ | 174 | /* Get the pointer to a device_node's pci_dn */ |
175 | #define PCI_DN(dn) ((struct pci_dn *) (dn)->data) | 175 | #define PCI_DN(dn) ((struct pci_dn *) (dn)->data) |
176 | 176 | ||
177 | extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev); | ||
178 | |||
177 | extern void * update_dn_pci_info(struct device_node *dn, void *data); | 179 | extern void * update_dn_pci_info(struct device_node *dn, void *data); |
178 | 180 | ||
179 | static inline int pci_device_from_OF_node(struct device_node *np, | 181 | static inline int pci_device_from_OF_node(struct device_node *np, |
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 91acb12bac92..b66ae722a8e9 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h | |||
@@ -186,7 +186,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | |||
186 | 186 | ||
187 | static inline pgtable_t pmd_pgtable(pmd_t pmd) | 187 | static inline pgtable_t pmd_pgtable(pmd_t pmd) |
188 | { | 188 | { |
189 | return (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE); | 189 | return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS); |
190 | } | 190 | } |
191 | 191 | ||
192 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 192 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index cea8496091ff..2f1b6c5f8174 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -523,6 +523,17 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946) | |||
523 | #define PPC440EP_ERR42 | 523 | #define PPC440EP_ERR42 |
524 | #endif | 524 | #endif |
525 | 525 | ||
526 | /* The following stops all load and store data streams associated with stream | ||
527 | * ID (ie. streams created explicitly). The embedded and server mnemonics for | ||
528 | * dcbt are different so we use machine "power4" here explicitly. | ||
529 | */ | ||
530 | #define DCBT_STOP_ALL_STREAM_IDS(scratch) \ | ||
531 | .machine push ; \ | ||
532 | .machine "power4" ; \ | ||
533 | lis scratch,0x60000000@h; \ | ||
534 | dcbt r0,scratch,0b01010; \ | ||
535 | .machine pop | ||
536 | |||
526 | /* | 537 | /* |
527 | * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them | 538 | * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them |
528 | * keep the address intact to be compatible with code shared with | 539 | * keep the address intact to be compatible with code shared with |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index d7e67ca8b4a6..14a658363698 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -284,6 +284,12 @@ struct thread_struct { | |||
284 | unsigned long ebbrr; | 284 | unsigned long ebbrr; |
285 | unsigned long ebbhr; | 285 | unsigned long ebbhr; |
286 | unsigned long bescr; | 286 | unsigned long bescr; |
287 | unsigned long siar; | ||
288 | unsigned long sdar; | ||
289 | unsigned long sier; | ||
290 | unsigned long mmcr0; | ||
291 | unsigned long mmcr2; | ||
292 | unsigned long mmcra; | ||
287 | #endif | 293 | #endif |
288 | }; | 294 | }; |
289 | 295 | ||
@@ -403,21 +409,16 @@ static inline void prefetchw(const void *x) | |||
403 | #endif | 409 | #endif |
404 | 410 | ||
405 | #ifdef CONFIG_PPC64 | 411 | #ifdef CONFIG_PPC64 |
406 | static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) | 412 | static inline unsigned long get_clean_sp(unsigned long sp, int is_32) |
407 | { | 413 | { |
408 | unsigned long sp; | ||
409 | |||
410 | if (is_32) | 414 | if (is_32) |
411 | sp = regs->gpr[1] & 0x0ffffffffUL; | 415 | return sp & 0x0ffffffffUL; |
412 | else | ||
413 | sp = regs->gpr[1]; | ||
414 | |||
415 | return sp; | 416 | return sp; |
416 | } | 417 | } |
417 | #else | 418 | #else |
418 | static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32) | 419 | static inline unsigned long get_clean_sp(unsigned long sp, int is_32) |
419 | { | 420 | { |
420 | return regs->gpr[1]; | 421 | return sp; |
421 | } | 422 | } |
422 | #endif | 423 | #endif |
423 | 424 | ||
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h index 3e13e23e4fdf..d836d945068d 100644 --- a/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/arch/powerpc/include/asm/pte-hash64-64k.h | |||
@@ -47,7 +47,7 @@ | |||
47 | * generic accessors and iterators here | 47 | * generic accessors and iterators here |
48 | */ | 48 | */ |
49 | #define __real_pte(e,p) ((real_pte_t) { \ | 49 | #define __real_pte(e,p) ((real_pte_t) { \ |
50 | (e), ((e) & _PAGE_COMBO) ? \ | 50 | (e), (pte_val(e) & _PAGE_COMBO) ? \ |
51 | (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) | 51 | (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) |
52 | #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ | 52 | #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ |
53 | (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) | 53 | (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a6136515c7f2..4a9e408644fe 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -111,17 +111,6 @@ | |||
111 | #define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T) | 111 | #define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T) |
112 | #define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S) | 112 | #define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S) |
113 | 113 | ||
114 | /* Reason codes describing kernel causes for transaction aborts. By | ||
115 | convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if | ||
116 | the failure is persistent. | ||
117 | */ | ||
118 | #define TM_CAUSE_RESCHED 0xfe | ||
119 | #define TM_CAUSE_TLBI 0xfc | ||
120 | #define TM_CAUSE_FAC_UNAV 0xfa | ||
121 | #define TM_CAUSE_SYSCALL 0xf9 /* Persistent */ | ||
122 | #define TM_CAUSE_MISC 0xf6 | ||
123 | #define TM_CAUSE_SIGNAL 0xf4 | ||
124 | |||
125 | #if defined(CONFIG_PPC_BOOK3S_64) | 114 | #if defined(CONFIG_PPC_BOOK3S_64) |
126 | #define MSR_64BIT MSR_SF | 115 | #define MSR_64BIT MSR_SF |
127 | 116 | ||
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index a8bc2bb4adc9..34fd70488d83 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
@@ -264,6 +264,8 @@ extern void rtas_progress(char *s, unsigned short hex); | |||
264 | extern void rtas_initialize(void); | 264 | extern void rtas_initialize(void); |
265 | extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); | 265 | extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); |
266 | extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); | 266 | extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); |
267 | extern int rtas_online_cpus_mask(cpumask_var_t cpus); | ||
268 | extern int rtas_offline_cpus_mask(cpumask_var_t cpus); | ||
267 | extern int rtas_ibm_suspend_me(struct rtas_args *); | 269 | extern int rtas_ibm_suspend_me(struct rtas_args *); |
268 | 270 | ||
269 | struct rtc_time; | 271 | struct rtc_time; |
diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h index fbe66c463891..9322c28aebd2 100644 --- a/arch/powerpc/include/asm/signal.h +++ b/arch/powerpc/include/asm/signal.h | |||
@@ -3,5 +3,8 @@ | |||
3 | 3 | ||
4 | #define __ARCH_HAS_SA_RESTORER | 4 | #define __ARCH_HAS_SA_RESTORER |
5 | #include <uapi/asm/signal.h> | 5 | #include <uapi/asm/signal.h> |
6 | #include <uapi/asm/ptrace.h> | ||
7 | |||
8 | extern unsigned long get_tm_stackpointer(struct pt_regs *regs); | ||
6 | 9 | ||
7 | #endif /* _ASM_POWERPC_SIGNAL_H */ | 10 | #endif /* _ASM_POWERPC_SIGNAL_H */ |
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 8ceea14d6fe4..ba7b1973866e 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h | |||
@@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void) | |||
97 | #define TIF_PERFMON_CTXSW 6 /* perfmon needs ctxsw calls */ | 97 | #define TIF_PERFMON_CTXSW 6 /* perfmon needs ctxsw calls */ |
98 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ | 98 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ |
99 | #define TIF_SINGLESTEP 8 /* singlestepping active */ | 99 | #define TIF_SINGLESTEP 8 /* singlestepping active */ |
100 | #define TIF_MEMDIE 9 /* is terminating due to OOM killer */ | 100 | #define TIF_NOHZ 9 /* in adaptive nohz mode */ |
101 | #define TIF_SECCOMP 10 /* secure computing */ | 101 | #define TIF_SECCOMP 10 /* secure computing */ |
102 | #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ | 102 | #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ |
103 | #define TIF_NOERROR 12 /* Force successful syscall return */ | 103 | #define TIF_NOERROR 12 /* Force successful syscall return */ |
@@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void) | |||
106 | #define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */ | 106 | #define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */ |
107 | #define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation | 107 | #define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation |
108 | for stack store? */ | 108 | for stack store? */ |
109 | #define TIF_MEMDIE 17 /* is terminating due to OOM killer */ | ||
109 | 110 | ||
110 | /* as above, but as bit values */ | 111 | /* as above, but as bit values */ |
111 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 112 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
@@ -124,8 +125,10 @@ static inline struct thread_info *current_thread_info(void) | |||
124 | #define _TIF_UPROBE (1<<TIF_UPROBE) | 125 | #define _TIF_UPROBE (1<<TIF_UPROBE) |
125 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) | 126 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
126 | #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) | 127 | #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) |
128 | #define _TIF_NOHZ (1<<TIF_NOHZ) | ||
127 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ | 129 | #define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ |
128 | _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT) | 130 | _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \ |
131 | _TIF_NOHZ) | ||
129 | 132 | ||
130 | #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 133 | #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ |
131 | _TIF_NOTIFY_RESUME | _TIF_UPROBE) | 134 | _TIF_NOTIFY_RESUME | _TIF_UPROBE) |
diff --git a/arch/powerpc/include/asm/tm.h b/arch/powerpc/include/asm/tm.h index 4b4449abf3f8..9dfbc34bdbf5 100644 --- a/arch/powerpc/include/asm/tm.h +++ b/arch/powerpc/include/asm/tm.h | |||
@@ -5,6 +5,8 @@ | |||
5 | * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation. | 5 | * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <uapi/asm/tm.h> | ||
9 | |||
8 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 10 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
9 | extern void do_load_up_transact_fpu(struct thread_struct *thread); | 11 | extern void do_load_up_transact_fpu(struct thread_struct *thread); |
10 | extern void do_load_up_transact_altivec(struct thread_struct *thread); | 12 | extern void do_load_up_transact_altivec(struct thread_struct *thread); |
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h index 5a7510e9d09d..dc590919f8eb 100644 --- a/arch/powerpc/include/asm/udbg.h +++ b/arch/powerpc/include/asm/udbg.h | |||
@@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void); | |||
52 | extern void __init udbg_init_cpm(void); | 52 | extern void __init udbg_init_cpm(void); |
53 | extern void __init udbg_init_usbgecko(void); | 53 | extern void __init udbg_init_usbgecko(void); |
54 | extern void __init udbg_init_wsp(void); | 54 | extern void __init udbg_init_wsp(void); |
55 | extern void __init udbg_init_memcons(void); | ||
55 | extern void __init udbg_init_ehv_bc(void); | 56 | extern void __init udbg_init_ehv_bc(void); |
56 | extern void __init udbg_init_ps3gelic(void); | 57 | extern void __init udbg_init_ps3gelic(void); |
57 | extern void __init udbg_init_debug_opal_raw(void); | 58 | extern void __init udbg_init_debug_opal_raw(void); |
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index f7bca6370745..5182c8622b54 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild | |||
@@ -40,6 +40,7 @@ header-y += statfs.h | |||
40 | header-y += swab.h | 40 | header-y += swab.h |
41 | header-y += termbits.h | 41 | header-y += termbits.h |
42 | header-y += termios.h | 42 | header-y += termios.h |
43 | header-y += tm.h | ||
43 | header-y += types.h | 44 | header-y += types.h |
44 | header-y += ucontext.h | 45 | header-y += ucontext.h |
45 | header-y += unistd.h | 46 | header-y += unistd.h |
diff --git a/arch/powerpc/include/uapi/asm/tm.h b/arch/powerpc/include/uapi/asm/tm.h new file mode 100644 index 000000000000..85059a00f560 --- /dev/null +++ b/arch/powerpc/include/uapi/asm/tm.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _ASM_POWERPC_TM_H | ||
2 | #define _ASM_POWERPC_TM_H | ||
3 | |||
4 | /* Reason codes describing kernel causes for transaction aborts. By | ||
5 | * convention, bit0 is copied to TEXASR[56] (IBM bit 7) which is set if | ||
6 | * the failure is persistent. PAPR saves 0xff-0xe0 for the hypervisor. | ||
7 | */ | ||
8 | #define TM_CAUSE_PERSISTENT 0x01 | ||
9 | #define TM_CAUSE_RESCHED 0xde | ||
10 | #define TM_CAUSE_TLBI 0xdc | ||
11 | #define TM_CAUSE_FAC_UNAV 0xda | ||
12 | #define TM_CAUSE_SYSCALL 0xd8 /* future use */ | ||
13 | #define TM_CAUSE_MISC 0xd6 /* future use */ | ||
14 | #define TM_CAUSE_SIGNAL 0xd4 | ||
15 | #define TM_CAUSE_ALIGNMENT 0xd2 | ||
16 | #define TM_CAUSE_EMULATE 0xd0 | ||
17 | |||
18 | #endif | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index b51a97cfedf8..6f16ffafa6f0 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -127,6 +127,12 @@ int main(void) | |||
127 | DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); | 127 | DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); |
128 | DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); | 128 | DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); |
129 | DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); | 129 | DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); |
130 | DEFINE(THREAD_SIAR, offsetof(struct thread_struct, siar)); | ||
131 | DEFINE(THREAD_SDAR, offsetof(struct thread_struct, sdar)); | ||
132 | DEFINE(THREAD_SIER, offsetof(struct thread_struct, sier)); | ||
133 | DEFINE(THREAD_MMCR0, offsetof(struct thread_struct, mmcr0)); | ||
134 | DEFINE(THREAD_MMCR2, offsetof(struct thread_struct, mmcr2)); | ||
135 | DEFINE(THREAD_MMCRA, offsetof(struct thread_struct, mmcra)); | ||
130 | #endif | 136 | #endif |
131 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 137 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
132 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); | 138 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index a283b6442b26..18b5b9cf8e37 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -135,8 +135,12 @@ __init_HFSCR: | |||
135 | blr | 135 | blr |
136 | 136 | ||
137 | __init_TLB: | 137 | __init_TLB: |
138 | /* Clear the TLB */ | 138 | /* |
139 | li r6,128 | 139 | * Clear the TLB using the "IS 3" form of tlbiel instruction |
140 | * (invalidate by congruence class). P7 has 128 CCs, P8 has 512 | ||
141 | * so we just always do 512 | ||
142 | */ | ||
143 | li r6,512 | ||
140 | mtctr r6 | 144 | mtctr r6 |
141 | li r7,0xc00 /* IS field = 0b11 */ | 145 | li r7,0xc00 /* IS field = 0b11 */ |
142 | ptesync | 146 | ptesync |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index c60bbec25c1f..2a45d0f04385 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -452,7 +452,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
452 | .mmu_features = MMU_FTRS_POWER8, | 452 | .mmu_features = MMU_FTRS_POWER8, |
453 | .icache_bsize = 128, | 453 | .icache_bsize = 128, |
454 | .dcache_bsize = 128, | 454 | .dcache_bsize = 128, |
455 | .oprofile_type = PPC_OPROFILE_POWER4, | 455 | .oprofile_type = PPC_OPROFILE_INVALID, |
456 | .oprofile_cpu_type = "ppc64/ibm-compat-v1", | 456 | .oprofile_cpu_type = "ppc64/ibm-compat-v1", |
457 | .cpu_setup = __setup_cpu_power8, | 457 | .cpu_setup = __setup_cpu_power8, |
458 | .cpu_restore = __restore_cpu_power8, | 458 | .cpu_restore = __restore_cpu_power8, |
@@ -482,7 +482,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
482 | .cpu_name = "POWER7+ (raw)", | 482 | .cpu_name = "POWER7+ (raw)", |
483 | .cpu_features = CPU_FTRS_POWER7, | 483 | .cpu_features = CPU_FTRS_POWER7, |
484 | .cpu_user_features = COMMON_USER_POWER7, | 484 | .cpu_user_features = COMMON_USER_POWER7, |
485 | .cpu_user_features = COMMON_USER2_POWER7, | 485 | .cpu_user_features2 = COMMON_USER2_POWER7, |
486 | .mmu_features = MMU_FTRS_POWER7, | 486 | .mmu_features = MMU_FTRS_POWER7, |
487 | .icache_bsize = 128, | 487 | .icache_bsize = 128, |
488 | .dcache_bsize = 128, | 488 | .dcache_bsize = 128, |
@@ -507,7 +507,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
507 | .num_pmcs = 6, | 507 | .num_pmcs = 6, |
508 | .pmc_type = PPC_PMC_IBM, | 508 | .pmc_type = PPC_PMC_IBM, |
509 | .oprofile_cpu_type = "ppc64/power8", | 509 | .oprofile_cpu_type = "ppc64/power8", |
510 | .oprofile_type = PPC_OPROFILE_POWER4, | 510 | .oprofile_type = PPC_OPROFILE_INVALID, |
511 | .cpu_setup = __setup_cpu_power8, | 511 | .cpu_setup = __setup_cpu_power8, |
512 | .cpu_restore = __restore_cpu_power8, | 512 | .cpu_restore = __restore_cpu_power8, |
513 | .platform = "power8", | 513 | .platform = "power8", |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index e514de57a125..22b45a4955cd 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -439,8 +439,6 @@ ret_from_fork: | |||
439 | ret_from_kernel_thread: | 439 | ret_from_kernel_thread: |
440 | REST_NVGPRS(r1) | 440 | REST_NVGPRS(r1) |
441 | bl schedule_tail | 441 | bl schedule_tail |
442 | li r3,0 | ||
443 | stw r3,0(r1) | ||
444 | mtlr r14 | 442 | mtlr r14 |
445 | mr r3,r15 | 443 | mr r3,r15 |
446 | PPC440EP_ERR42 | 444 | PPC440EP_ERR42 |
@@ -851,7 +849,7 @@ resume_kernel: | |||
851 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ | 849 | /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ |
852 | CURRENT_THREAD_INFO(r9, r1) | 850 | CURRENT_THREAD_INFO(r9, r1) |
853 | lwz r8,TI_FLAGS(r9) | 851 | lwz r8,TI_FLAGS(r9) |
854 | andis. r8,r8,_TIF_EMULATE_STACK_STORE@h | 852 | andis. r0,r8,_TIF_EMULATE_STACK_STORE@h |
855 | beq+ 1f | 853 | beq+ 1f |
856 | 854 | ||
857 | addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ | 855 | addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 915fbb4fc2fe..8741c854e03d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/irqflags.h> | 33 | #include <asm/irqflags.h> |
34 | #include <asm/ftrace.h> | 34 | #include <asm/ftrace.h> |
35 | #include <asm/hw_irq.h> | 35 | #include <asm/hw_irq.h> |
36 | #include <asm/context_tracking.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * System calls. | 39 | * System calls. |
@@ -376,8 +377,6 @@ _GLOBAL(ret_from_fork) | |||
376 | _GLOBAL(ret_from_kernel_thread) | 377 | _GLOBAL(ret_from_kernel_thread) |
377 | bl .schedule_tail | 378 | bl .schedule_tail |
378 | REST_NVGPRS(r1) | 379 | REST_NVGPRS(r1) |
379 | li r3,0 | ||
380 | std r3,0(r1) | ||
381 | ld r14, 0(r14) | 380 | ld r14, 0(r14) |
382 | mtlr r14 | 381 | mtlr r14 |
383 | mr r3,r15 | 382 | mr r3,r15 |
@@ -488,6 +487,13 @@ BEGIN_FTR_SECTION | |||
488 | ldarx r6,0,r1 | 487 | ldarx r6,0,r1 |
489 | END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS) | 488 | END_FTR_SECTION_IFSET(CPU_FTR_STCX_CHECKS_ADDRESS) |
490 | 489 | ||
490 | #ifdef CONFIG_PPC_BOOK3S | ||
491 | /* Cancel all explict user streams as they will have no use after context | ||
492 | * switch and will stop the HW from creating streams itself | ||
493 | */ | ||
494 | DCBT_STOP_ALL_STREAM_IDS(r6) | ||
495 | #endif | ||
496 | |||
491 | addi r6,r4,-THREAD /* Convert THREAD to 'current' */ | 497 | addi r6,r4,-THREAD /* Convert THREAD to 'current' */ |
492 | std r6,PACACURRENT(r13) /* Set new 'current' */ | 498 | std r6,PACACURRENT(r13) /* Set new 'current' */ |
493 | 499 | ||
@@ -634,7 +640,7 @@ _GLOBAL(ret_from_except_lite) | |||
634 | andi. r0,r4,_TIF_NEED_RESCHED | 640 | andi. r0,r4,_TIF_NEED_RESCHED |
635 | beq 1f | 641 | beq 1f |
636 | bl .restore_interrupts | 642 | bl .restore_interrupts |
637 | bl .schedule | 643 | SCHEDULE_USER |
638 | b .ret_from_except_lite | 644 | b .ret_from_except_lite |
639 | 645 | ||
640 | 1: bl .save_nvgprs | 646 | 1: bl .save_nvgprs |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 42a756eec9ff..645170a07ada 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -489,7 +489,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
489 | */ | 489 | */ |
490 | 490 | ||
491 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ | 491 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ |
492 | andis. r15,r14,DBSR_IC@h | 492 | andis. r15,r14,(DBSR_IC|DBSR_BT)@h |
493 | beq+ 1f | 493 | beq+ 1f |
494 | 494 | ||
495 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) | 495 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) |
@@ -500,7 +500,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
500 | bge+ cr1,1f | 500 | bge+ cr1,1f |
501 | 501 | ||
502 | /* here it looks like we got an inappropriate debug exception. */ | 502 | /* here it looks like we got an inappropriate debug exception. */ |
503 | lis r14,DBSR_IC@h /* clear the IC event */ | 503 | lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ |
504 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ | 504 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ |
505 | mtspr SPRN_DBSR,r14 | 505 | mtspr SPRN_DBSR,r14 |
506 | mtspr SPRN_CSRR1,r11 | 506 | mtspr SPRN_CSRR1,r11 |
@@ -555,7 +555,7 @@ kernel_dbg_exc: | |||
555 | */ | 555 | */ |
556 | 556 | ||
557 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ | 557 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ |
558 | andis. r15,r14,DBSR_IC@h | 558 | andis. r15,r14,(DBSR_IC|DBSR_BT)@h |
559 | beq+ 1f | 559 | beq+ 1f |
560 | 560 | ||
561 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) | 561 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) |
@@ -566,7 +566,7 @@ kernel_dbg_exc: | |||
566 | bge+ cr1,1f | 566 | bge+ cr1,1f |
567 | 567 | ||
568 | /* here it looks like we got an inappropriate debug exception. */ | 568 | /* here it looks like we got an inappropriate debug exception. */ |
569 | lis r14,DBSR_IC@h /* clear the IC event */ | 569 | lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ |
570 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ | 570 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ |
571 | mtspr SPRN_DBSR,r14 | 571 | mtspr SPRN_DBSR,r14 |
572 | mtspr SPRN_DSRR1,r11 | 572 | mtspr SPRN_DSRR1,r11 |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e6eba1bf61ad..40e4a17c8ba0 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -454,38 +454,14 @@ BEGIN_FTR_SECTION | |||
454 | xori r10,r10,(MSR_FE0|MSR_FE1) | 454 | xori r10,r10,(MSR_FE0|MSR_FE1) |
455 | mtmsrd r10 | 455 | mtmsrd r10 |
456 | sync | 456 | sync |
457 | fmr 0,0 | 457 | |
458 | fmr 1,1 | 458 | #define FMR2(n) fmr (n), (n) ; fmr n+1, n+1 |
459 | fmr 2,2 | 459 | #define FMR4(n) FMR2(n) ; FMR2(n+2) |
460 | fmr 3,3 | 460 | #define FMR8(n) FMR4(n) ; FMR4(n+4) |
461 | fmr 4,4 | 461 | #define FMR16(n) FMR8(n) ; FMR8(n+8) |
462 | fmr 5,5 | 462 | #define FMR32(n) FMR16(n) ; FMR16(n+16) |
463 | fmr 6,6 | 463 | FMR32(0) |
464 | fmr 7,7 | 464 | |
465 | fmr 8,8 | ||
466 | fmr 9,9 | ||
467 | fmr 10,10 | ||
468 | fmr 11,11 | ||
469 | fmr 12,12 | ||
470 | fmr 13,13 | ||
471 | fmr 14,14 | ||
472 | fmr 15,15 | ||
473 | fmr 16,16 | ||
474 | fmr 17,17 | ||
475 | fmr 18,18 | ||
476 | fmr 19,19 | ||
477 | fmr 20,20 | ||
478 | fmr 21,21 | ||
479 | fmr 22,22 | ||
480 | fmr 23,23 | ||
481 | fmr 24,24 | ||
482 | fmr 25,25 | ||
483 | fmr 26,26 | ||
484 | fmr 27,27 | ||
485 | fmr 28,28 | ||
486 | fmr 29,29 | ||
487 | fmr 30,30 | ||
488 | fmr 31,31 | ||
489 | FTR_SECTION_ELSE | 465 | FTR_SECTION_ELSE |
490 | /* | 466 | /* |
491 | * To denormalise we need to move a copy of the register to itself. | 467 | * To denormalise we need to move a copy of the register to itself. |
@@ -495,39 +471,25 @@ FTR_SECTION_ELSE | |||
495 | oris r10,r10,MSR_VSX@h | 471 | oris r10,r10,MSR_VSX@h |
496 | mtmsrd r10 | 472 | mtmsrd r10 |
497 | sync | 473 | sync |
498 | XVCPSGNDP(0,0,0) | 474 | |
499 | XVCPSGNDP(1,1,1) | 475 | #define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1) |
500 | XVCPSGNDP(2,2,2) | 476 | #define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2) |
501 | XVCPSGNDP(3,3,3) | 477 | #define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4) |
502 | XVCPSGNDP(4,4,4) | 478 | #define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8) |
503 | XVCPSGNDP(5,5,5) | 479 | #define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16) |
504 | XVCPSGNDP(6,6,6) | 480 | XVCPSGNDP32(0) |
505 | XVCPSGNDP(7,7,7) | 481 | |
506 | XVCPSGNDP(8,8,8) | ||
507 | XVCPSGNDP(9,9,9) | ||
508 | XVCPSGNDP(10,10,10) | ||
509 | XVCPSGNDP(11,11,11) | ||
510 | XVCPSGNDP(12,12,12) | ||
511 | XVCPSGNDP(13,13,13) | ||
512 | XVCPSGNDP(14,14,14) | ||
513 | XVCPSGNDP(15,15,15) | ||
514 | XVCPSGNDP(16,16,16) | ||
515 | XVCPSGNDP(17,17,17) | ||
516 | XVCPSGNDP(18,18,18) | ||
517 | XVCPSGNDP(19,19,19) | ||
518 | XVCPSGNDP(20,20,20) | ||
519 | XVCPSGNDP(21,21,21) | ||
520 | XVCPSGNDP(22,22,22) | ||
521 | XVCPSGNDP(23,23,23) | ||
522 | XVCPSGNDP(24,24,24) | ||
523 | XVCPSGNDP(25,25,25) | ||
524 | XVCPSGNDP(26,26,26) | ||
525 | XVCPSGNDP(27,27,27) | ||
526 | XVCPSGNDP(28,28,28) | ||
527 | XVCPSGNDP(29,29,29) | ||
528 | XVCPSGNDP(30,30,30) | ||
529 | XVCPSGNDP(31,31,31) | ||
530 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) | 482 | ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) |
483 | |||
484 | BEGIN_FTR_SECTION | ||
485 | b denorm_done | ||
486 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | ||
487 | /* | ||
488 | * To denormalise we need to move a copy of the register to itself. | ||
489 | * For POWER8 we need to do that for all 64 VSX registers | ||
490 | */ | ||
491 | XVCPSGNDP32(32) | ||
492 | denorm_done: | ||
531 | mtspr SPRN_HSRR0,r11 | 493 | mtspr SPRN_HSRR0,r11 |
532 | mtcrf 0x80,r9 | 494 | mtcrf 0x80,r9 |
533 | ld r9,PACA_EXGEN+EX_R9(r13) | 495 | ld r9,PACA_EXGEN+EX_R9(r13) |
@@ -721,7 +683,7 @@ machine_check_common: | |||
721 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 683 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
722 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 684 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
723 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 685 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
724 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception) | 686 | STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt) |
725 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) | 687 | STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) |
726 | #ifdef CONFIG_PPC_DOORBELL | 688 | #ifdef CONFIG_PPC_DOORBELL |
727 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) | 689 | STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception) |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5cbcf4d5a808..ea185e0b3cae 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void) | |||
162 | * in case we also had a rollover while hard disabled | 162 | * in case we also had a rollover while hard disabled |
163 | */ | 163 | */ |
164 | local_paca->irq_happened &= ~PACA_IRQ_DEC; | 164 | local_paca->irq_happened &= ~PACA_IRQ_DEC; |
165 | if (decrementer_check_overflow()) | 165 | if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow()) |
166 | return 0x900; | 166 | return 0x900; |
167 | 167 | ||
168 | /* Finally check if an external interrupt happened */ | 168 | /* Finally check if an external interrupt happened */ |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 466a2908bb63..611acdf30096 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/cpu.h> | 19 | #include <linux/cpu.h> |
20 | #include <linux/hardirq.h> | ||
20 | 21 | ||
21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
22 | #include <asm/current.h> | 23 | #include <asm/current.h> |
@@ -335,10 +336,13 @@ void default_machine_kexec(struct kimage *image) | |||
335 | pr_debug("kexec: Starting switchover sequence.\n"); | 336 | pr_debug("kexec: Starting switchover sequence.\n"); |
336 | 337 | ||
337 | /* switch to a staticly allocated stack. Based on irq stack code. | 338 | /* switch to a staticly allocated stack. Based on irq stack code. |
339 | * We setup preempt_count to avoid using VMX in memcpy. | ||
338 | * XXX: the task struct will likely be invalid once we do the copy! | 340 | * XXX: the task struct will likely be invalid once we do the copy! |
339 | */ | 341 | */ |
340 | kexec_stack.thread_info.task = current_thread_info()->task; | 342 | kexec_stack.thread_info.task = current_thread_info()->task; |
341 | kexec_stack.thread_info.flags = 0; | 343 | kexec_stack.thread_info.flags = 0; |
344 | kexec_stack.thread_info.preempt_count = HARDIRQ_OFFSET; | ||
345 | kexec_stack.thread_info.cpu = current_thread_info()->cpu; | ||
342 | 346 | ||
343 | /* We need a static PACA, too; copy this CPU's PACA over and switch to | 347 | /* We need a static PACA, too; copy this CPU's PACA over and switch to |
344 | * it. Also poison per_cpu_offset to catch anyone using non-static | 348 | * it. Also poison per_cpu_offset to catch anyone using non-static |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 19e096bd0e73..e469f30e6eeb 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -657,6 +657,17 @@ _GLOBAL(__ucmpdi2) | |||
657 | li r3,2 | 657 | li r3,2 |
658 | blr | 658 | blr |
659 | 659 | ||
660 | _GLOBAL(__bswapdi2) | ||
661 | rotlwi r9,r4,8 | ||
662 | rotlwi r10,r3,8 | ||
663 | rlwimi r9,r4,24,0,7 | ||
664 | rlwimi r10,r3,24,0,7 | ||
665 | rlwimi r9,r4,24,16,23 | ||
666 | rlwimi r10,r3,24,16,23 | ||
667 | mr r3,r9 | ||
668 | mr r4,r10 | ||
669 | blr | ||
670 | |||
660 | _GLOBAL(abs) | 671 | _GLOBAL(abs) |
661 | srawi r4,r3,31 | 672 | srawi r4,r3,31 |
662 | xor r3,r3,r4 | 673 | xor r3,r3,r4 |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 5cfa8008693b..6820e45f557b 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -234,6 +234,17 @@ _GLOBAL(__flush_dcache_icache) | |||
234 | isync | 234 | isync |
235 | blr | 235 | blr |
236 | 236 | ||
237 | _GLOBAL(__bswapdi2) | ||
238 | srdi r8,r3,32 | ||
239 | rlwinm r7,r3,8,0xffffffff | ||
240 | rlwimi r7,r3,24,0,7 | ||
241 | rlwinm r9,r8,8,0xffffffff | ||
242 | rlwimi r7,r3,24,16,23 | ||
243 | rlwimi r9,r8,24,0,7 | ||
244 | rlwimi r9,r8,24,16,23 | ||
245 | sldi r7,r7,32 | ||
246 | or r3,r7,r9 | ||
247 | blr | ||
237 | 248 | ||
238 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) | 249 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) |
239 | /* | 250 | /* |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f5c5c90799a7..eabeec991016 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -359,7 +359,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
359 | enum pci_mmap_state mmap_state, | 359 | enum pci_mmap_state mmap_state, |
360 | int write_combine) | 360 | int write_combine) |
361 | { | 361 | { |
362 | unsigned long prot = pgprot_val(protection); | ||
363 | 362 | ||
364 | /* Write combine is always 0 on non-memory space mappings. On | 363 | /* Write combine is always 0 on non-memory space mappings. On |
365 | * memory space, if the user didn't pass 1, we check for a | 364 | * memory space, if the user didn't pass 1, we check for a |
@@ -376,9 +375,9 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
376 | 375 | ||
377 | /* XXX would be nice to have a way to ask for write-through */ | 376 | /* XXX would be nice to have a way to ask for write-through */ |
378 | if (write_combine) | 377 | if (write_combine) |
379 | return pgprot_noncached_wc(prot); | 378 | return pgprot_noncached_wc(protection); |
380 | else | 379 | else |
381 | return pgprot_noncached(prot); | 380 | return pgprot_noncached(protection); |
382 | } | 381 | } |
383 | 382 | ||
384 | /* | 383 | /* |
@@ -658,15 +657,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
658 | * ranges. However, some machines (thanks Apple !) tend to split their | 657 | * ranges. However, some machines (thanks Apple !) tend to split their |
659 | * space into lots of small contiguous ranges. So we have to coalesce. | 658 | * space into lots of small contiguous ranges. So we have to coalesce. |
660 | * | 659 | * |
661 | * - We can only cope with all memory ranges having the same offset | ||
662 | * between CPU addresses and PCI addresses. Unfortunately, some bridges | ||
663 | * are setup for a large 1:1 mapping along with a small "window" which | ||
664 | * maps PCI address 0 to some arbitrary high address of the CPU space in | ||
665 | * order to give access to the ISA memory hole. | ||
666 | * The way out of here that I've chosen for now is to always set the | ||
667 | * offset based on the first resource found, then override it if we | ||
668 | * have a different offset and the previous was set by an ISA hole. | ||
669 | * | ||
670 | * - Some busses have IO space not starting at 0, which causes trouble with | 660 | * - Some busses have IO space not starting at 0, which causes trouble with |
671 | * the way we do our IO resource renumbering. The code somewhat deals with | 661 | * the way we do our IO resource renumbering. The code somewhat deals with |
672 | * it for 64 bits but I would expect problems on 32 bits. | 662 | * it for 64 bits but I would expect problems on 32 bits. |
@@ -681,10 +671,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
681 | int rlen; | 671 | int rlen; |
682 | int pna = of_n_addr_cells(dev); | 672 | int pna = of_n_addr_cells(dev); |
683 | int np = pna + 5; | 673 | int np = pna + 5; |
684 | int memno = 0, isa_hole = -1; | 674 | int memno = 0; |
685 | u32 pci_space; | 675 | u32 pci_space; |
686 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; | 676 | unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; |
687 | unsigned long long isa_mb = 0; | ||
688 | struct resource *res; | 677 | struct resource *res; |
689 | 678 | ||
690 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", | 679 | printk(KERN_INFO "PCI host bridge %s %s ranges:\n", |
@@ -778,8 +767,6 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
778 | } | 767 | } |
779 | /* Handles ISA memory hole space here */ | 768 | /* Handles ISA memory hole space here */ |
780 | if (pci_addr == 0) { | 769 | if (pci_addr == 0) { |
781 | isa_mb = cpu_addr; | ||
782 | isa_hole = memno; | ||
783 | if (primary || isa_mem_base == 0) | 770 | if (primary || isa_mem_base == 0) |
784 | isa_mem_base = cpu_addr; | 771 | isa_mem_base = cpu_addr; |
785 | hose->isa_mem_phys = cpu_addr; | 772 | hose->isa_mem_phys = cpu_addr; |
@@ -840,6 +827,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev) | |||
840 | } | 827 | } |
841 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 828 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
842 | struct resource *res = dev->resource + i; | 829 | struct resource *res = dev->resource + i; |
830 | struct pci_bus_region reg; | ||
843 | if (!res->flags) | 831 | if (!res->flags) |
844 | continue; | 832 | continue; |
845 | 833 | ||
@@ -848,8 +836,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev) | |||
848 | * at 0 as unset as well, except if PCI_PROBE_ONLY is also set | 836 | * at 0 as unset as well, except if PCI_PROBE_ONLY is also set |
849 | * since in that case, we don't want to re-assign anything | 837 | * since in that case, we don't want to re-assign anything |
850 | */ | 838 | */ |
839 | pcibios_resource_to_bus(dev, ®, res); | ||
851 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || | 840 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || |
852 | (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { | 841 | (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { |
853 | /* Only print message if not re-assigning */ | 842 | /* Only print message if not re-assigning */ |
854 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) | 843 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) |
855 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " | 844 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " |
@@ -1521,9 +1510,10 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, | |||
1521 | for (i = 0; i < 3; ++i) { | 1510 | for (i = 0; i < 3; ++i) { |
1522 | res = &hose->mem_resources[i]; | 1511 | res = &hose->mem_resources[i]; |
1523 | if (!res->flags) { | 1512 | if (!res->flags) { |
1524 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | 1513 | if (i == 0) |
1525 | "host bridge %s (domain %d)\n", | 1514 | printk(KERN_ERR "PCI: Memory resource 0 not set for " |
1526 | hose->dn->full_name, hose->global_number); | 1515 | "host bridge %s (domain %d)\n", |
1516 | hose->dn->full_name, hose->global_number); | ||
1527 | continue; | 1517 | continue; |
1528 | } | 1518 | } |
1529 | offset = hose->mem_offset[i]; | 1519 | offset = hose->mem_offset[i]; |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 873050d26840..2e8629654ca8 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -266,3 +266,13 @@ int pcibus_to_node(struct pci_bus *bus) | |||
266 | } | 266 | } |
267 | EXPORT_SYMBOL(pcibus_to_node); | 267 | EXPORT_SYMBOL(pcibus_to_node); |
268 | #endif | 268 | #endif |
269 | |||
270 | static void quirk_radeon_32bit_msi(struct pci_dev *dev) | ||
271 | { | ||
272 | struct pci_dn *pdn = pci_get_pdn(dev); | ||
273 | |||
274 | if (pdn) | ||
275 | pdn->force_32bit_msi = 1; | ||
276 | } | ||
277 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi); | ||
278 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi); | ||
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index e7af165f8b9d..df038442548a 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c | |||
@@ -32,6 +32,14 @@ | |||
32 | #include <asm/ppc-pci.h> | 32 | #include <asm/ppc-pci.h> |
33 | #include <asm/firmware.h> | 33 | #include <asm/firmware.h> |
34 | 34 | ||
35 | struct pci_dn *pci_get_pdn(struct pci_dev *pdev) | ||
36 | { | ||
37 | struct device_node *dn = pci_device_to_OF_node(pdev); | ||
38 | if (!dn) | ||
39 | return NULL; | ||
40 | return PCI_DN(dn); | ||
41 | } | ||
42 | |||
35 | /* | 43 | /* |
36 | * Traverse_func that inits the PCI fields of the device node. | 44 | * Traverse_func that inits the PCI fields of the device node. |
37 | * NOTE: this *must* be done before read/write config to the device. | 45 | * NOTE: this *must* be done before read/write config to the device. |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 78b8766fd79e..c29666586998 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -143,7 +143,8 @@ EXPORT_SYMBOL(__lshrdi3); | |||
143 | int __ucmpdi2(unsigned long long, unsigned long long); | 143 | int __ucmpdi2(unsigned long long, unsigned long long); |
144 | EXPORT_SYMBOL(__ucmpdi2); | 144 | EXPORT_SYMBOL(__ucmpdi2); |
145 | #endif | 145 | #endif |
146 | 146 | long long __bswapdi2(long long); | |
147 | EXPORT_SYMBOL(__bswapdi2); | ||
147 | EXPORT_SYMBOL(memcpy); | 148 | EXPORT_SYMBOL(memcpy); |
148 | EXPORT_SYMBOL(memset); | 149 | EXPORT_SYMBOL(memset); |
149 | EXPORT_SYMBOL(memmove); | 150 | EXPORT_SYMBOL(memmove); |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ceb4e7b62cf4..076d1242507a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -339,6 +339,13 @@ static void set_debug_reg_defaults(struct thread_struct *thread) | |||
339 | 339 | ||
340 | static void prime_debug_regs(struct thread_struct *thread) | 340 | static void prime_debug_regs(struct thread_struct *thread) |
341 | { | 341 | { |
342 | /* | ||
343 | * We could have inherited MSR_DE from userspace, since | ||
344 | * it doesn't get cleared on exception entry. Make sure | ||
345 | * MSR_DE is clear before we enable any debug events. | ||
346 | */ | ||
347 | mtmsr(mfmsr() & ~MSR_DE); | ||
348 | |||
342 | mtspr(SPRN_IAC1, thread->iac1); | 349 | mtspr(SPRN_IAC1, thread->iac1); |
343 | mtspr(SPRN_IAC2, thread->iac2); | 350 | mtspr(SPRN_IAC2, thread->iac2); |
344 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 351 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
@@ -392,7 +399,8 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) | |||
392 | static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) | 399 | static inline int __set_dabr(unsigned long dabr, unsigned long dabrx) |
393 | { | 400 | { |
394 | mtspr(SPRN_DABR, dabr); | 401 | mtspr(SPRN_DABR, dabr); |
395 | mtspr(SPRN_DABRX, dabrx); | 402 | if (cpu_has_feature(CPU_FTR_DABRX)) |
403 | mtspr(SPRN_DABRX, dabrx); | ||
396 | return 0; | 404 | return 0; |
397 | } | 405 | } |
398 | #else | 406 | #else |
@@ -971,6 +979,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
971 | * do some house keeping and then return from the fork or clone | 979 | * do some house keeping and then return from the fork or clone |
972 | * system call, using the stack frame created above. | 980 | * system call, using the stack frame created above. |
973 | */ | 981 | */ |
982 | ((unsigned long *)sp)[0] = 0; | ||
974 | sp -= sizeof(struct pt_regs); | 983 | sp -= sizeof(struct pt_regs); |
975 | kregs = (struct pt_regs *) sp; | 984 | kregs = (struct pt_regs *) sp; |
976 | sp -= STACK_FRAME_OVERHEAD; | 985 | sp -= STACK_FRAME_OVERHEAD; |
@@ -1360,7 +1369,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) | |||
1360 | 1369 | ||
1361 | #ifdef CONFIG_PPC64 | 1370 | #ifdef CONFIG_PPC64 |
1362 | /* Called with hard IRQs off */ | 1371 | /* Called with hard IRQs off */ |
1363 | void __ppc64_runlatch_on(void) | 1372 | void notrace __ppc64_runlatch_on(void) |
1364 | { | 1373 | { |
1365 | struct thread_info *ti = current_thread_info(); | 1374 | struct thread_info *ti = current_thread_info(); |
1366 | unsigned long ctrl; | 1375 | unsigned long ctrl; |
@@ -1373,7 +1382,7 @@ void __ppc64_runlatch_on(void) | |||
1373 | } | 1382 | } |
1374 | 1383 | ||
1375 | /* Called with hard IRQs off */ | 1384 | /* Called with hard IRQs off */ |
1376 | void __ppc64_runlatch_off(void) | 1385 | void notrace __ppc64_runlatch_off(void) |
1377 | { | 1386 | { |
1378 | struct thread_info *ti = current_thread_info(); | 1387 | struct thread_info *ti = current_thread_info(); |
1379 | unsigned long ctrl; | 1388 | unsigned long ctrl; |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 3b14d320e69f..98c2fc198712 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <trace/syscall.h> | 32 | #include <trace/syscall.h> |
33 | #include <linux/hw_breakpoint.h> | 33 | #include <linux/hw_breakpoint.h> |
34 | #include <linux/perf_event.h> | 34 | #include <linux/perf_event.h> |
35 | #include <linux/context_tracking.h> | ||
35 | 36 | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
@@ -1788,6 +1789,8 @@ long do_syscall_trace_enter(struct pt_regs *regs) | |||
1788 | { | 1789 | { |
1789 | long ret = 0; | 1790 | long ret = 0; |
1790 | 1791 | ||
1792 | user_exit(); | ||
1793 | |||
1791 | secure_computing_strict(regs->gpr[0]); | 1794 | secure_computing_strict(regs->gpr[0]); |
1792 | 1795 | ||
1793 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | 1796 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
@@ -1832,4 +1835,6 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
1832 | step = test_thread_flag(TIF_SINGLESTEP); | 1835 | step = test_thread_flag(TIF_SINGLESTEP); |
1833 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) | 1836 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) |
1834 | tracehook_report_syscall_exit(regs, step); | 1837 | tracehook_report_syscall_exit(regs, step); |
1838 | |||
1839 | user_enter(); | ||
1835 | } | 1840 | } |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 1fd6e7b2f390..52add6f3e201 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/cpu.h> | ||
22 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
23 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
24 | #include <linux/cpumask.h> | 25 | #include <linux/cpumask.h> |
@@ -807,6 +808,95 @@ static void rtas_percpu_suspend_me(void *info) | |||
807 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); | 808 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); |
808 | } | 809 | } |
809 | 810 | ||
811 | enum rtas_cpu_state { | ||
812 | DOWN, | ||
813 | UP, | ||
814 | }; | ||
815 | |||
816 | #ifndef CONFIG_SMP | ||
817 | static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, | ||
818 | cpumask_var_t cpus) | ||
819 | { | ||
820 | if (!cpumask_empty(cpus)) { | ||
821 | cpumask_clear(cpus); | ||
822 | return -EINVAL; | ||
823 | } else | ||
824 | return 0; | ||
825 | } | ||
826 | #else | ||
827 | /* On return cpumask will be altered to indicate CPUs changed. | ||
828 | * CPUs with states changed will be set in the mask, | ||
829 | * CPUs with status unchanged will be unset in the mask. */ | ||
830 | static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, | ||
831 | cpumask_var_t cpus) | ||
832 | { | ||
833 | int cpu; | ||
834 | int cpuret = 0; | ||
835 | int ret = 0; | ||
836 | |||
837 | if (cpumask_empty(cpus)) | ||
838 | return 0; | ||
839 | |||
840 | for_each_cpu(cpu, cpus) { | ||
841 | switch (state) { | ||
842 | case DOWN: | ||
843 | cpuret = cpu_down(cpu); | ||
844 | break; | ||
845 | case UP: | ||
846 | cpuret = cpu_up(cpu); | ||
847 | break; | ||
848 | } | ||
849 | if (cpuret) { | ||
850 | pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", | ||
851 | __func__, | ||
852 | ((state == UP) ? "up" : "down"), | ||
853 | cpu, cpuret); | ||
854 | if (!ret) | ||
855 | ret = cpuret; | ||
856 | if (state == UP) { | ||
857 | /* clear bits for unchanged cpus, return */ | ||
858 | cpumask_shift_right(cpus, cpus, cpu); | ||
859 | cpumask_shift_left(cpus, cpus, cpu); | ||
860 | break; | ||
861 | } else { | ||
862 | /* clear bit for unchanged cpu, continue */ | ||
863 | cpumask_clear_cpu(cpu, cpus); | ||
864 | } | ||
865 | } | ||
866 | } | ||
867 | |||
868 | return ret; | ||
869 | } | ||
870 | #endif | ||
871 | |||
872 | int rtas_online_cpus_mask(cpumask_var_t cpus) | ||
873 | { | ||
874 | int ret; | ||
875 | |||
876 | ret = rtas_cpu_state_change_mask(UP, cpus); | ||
877 | |||
878 | if (ret) { | ||
879 | cpumask_var_t tmp_mask; | ||
880 | |||
881 | if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) | ||
882 | return ret; | ||
883 | |||
884 | /* Use tmp_mask to preserve cpus mask from first failure */ | ||
885 | cpumask_copy(tmp_mask, cpus); | ||
886 | rtas_offline_cpus_mask(tmp_mask); | ||
887 | free_cpumask_var(tmp_mask); | ||
888 | } | ||
889 | |||
890 | return ret; | ||
891 | } | ||
892 | EXPORT_SYMBOL(rtas_online_cpus_mask); | ||
893 | |||
894 | int rtas_offline_cpus_mask(cpumask_var_t cpus) | ||
895 | { | ||
896 | return rtas_cpu_state_change_mask(DOWN, cpus); | ||
897 | } | ||
898 | EXPORT_SYMBOL(rtas_offline_cpus_mask); | ||
899 | |||
810 | int rtas_ibm_suspend_me(struct rtas_args *args) | 900 | int rtas_ibm_suspend_me(struct rtas_args *args) |
811 | { | 901 | { |
812 | long state; | 902 | long state; |
@@ -814,6 +904,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
814 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | 904 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
815 | struct rtas_suspend_me_data data; | 905 | struct rtas_suspend_me_data data; |
816 | DECLARE_COMPLETION_ONSTACK(done); | 906 | DECLARE_COMPLETION_ONSTACK(done); |
907 | cpumask_var_t offline_mask; | ||
908 | int cpuret; | ||
817 | 909 | ||
818 | if (!rtas_service_present("ibm,suspend-me")) | 910 | if (!rtas_service_present("ibm,suspend-me")) |
819 | return -ENOSYS; | 911 | return -ENOSYS; |
@@ -837,11 +929,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
837 | return 0; | 929 | return 0; |
838 | } | 930 | } |
839 | 931 | ||
932 | if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) | ||
933 | return -ENOMEM; | ||
934 | |||
840 | atomic_set(&data.working, 0); | 935 | atomic_set(&data.working, 0); |
841 | atomic_set(&data.done, 0); | 936 | atomic_set(&data.done, 0); |
842 | atomic_set(&data.error, 0); | 937 | atomic_set(&data.error, 0); |
843 | data.token = rtas_token("ibm,suspend-me"); | 938 | data.token = rtas_token("ibm,suspend-me"); |
844 | data.complete = &done; | 939 | data.complete = &done; |
940 | |||
941 | /* All present CPUs must be online */ | ||
942 | cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask); | ||
943 | cpuret = rtas_online_cpus_mask(offline_mask); | ||
944 | if (cpuret) { | ||
945 | pr_err("%s: Could not bring present CPUs online.\n", __func__); | ||
946 | atomic_set(&data.error, cpuret); | ||
947 | goto out; | ||
948 | } | ||
949 | |||
845 | stop_topology_update(); | 950 | stop_topology_update(); |
846 | 951 | ||
847 | /* Call function on all CPUs. One of us will make the | 952 | /* Call function on all CPUs. One of us will make the |
@@ -857,6 +962,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
857 | 962 | ||
858 | start_topology_update(); | 963 | start_topology_update(); |
859 | 964 | ||
965 | /* Take down CPUs not online prior to suspend */ | ||
966 | cpuret = rtas_offline_cpus_mask(offline_mask); | ||
967 | if (cpuret) | ||
968 | pr_warn("%s: Could not restore CPUs to offline state.\n", | ||
969 | __func__); | ||
970 | |||
971 | out: | ||
972 | free_cpumask_var(offline_mask); | ||
860 | return atomic_read(&data.error); | 973 | return atomic_read(&data.error); |
861 | } | 974 | } |
862 | #else /* CONFIG_PPC_PSERIES */ | 975 | #else /* CONFIG_PPC_PSERIES */ |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 5b3022470126..2f3cdb01506d 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
@@ -89,6 +89,7 @@ | |||
89 | 89 | ||
90 | /* Array sizes */ | 90 | /* Array sizes */ |
91 | #define VALIDATE_BUF_SIZE 4096 | 91 | #define VALIDATE_BUF_SIZE 4096 |
92 | #define VALIDATE_MSG_LEN 256 | ||
92 | #define RTAS_MSG_MAXLEN 64 | 93 | #define RTAS_MSG_MAXLEN 64 |
93 | 94 | ||
94 | /* Quirk - RTAS requires 4k list length and block size */ | 95 | /* Quirk - RTAS requires 4k list length and block size */ |
@@ -466,7 +467,7 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf) | |||
466 | } | 467 | } |
467 | 468 | ||
468 | static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | 469 | static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, |
469 | char *msg) | 470 | char *msg, int msglen) |
470 | { | 471 | { |
471 | int n; | 472 | int n; |
472 | 473 | ||
@@ -474,7 +475,8 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | |||
474 | n = sprintf(msg, "%d\n", args_buf->update_results); | 475 | n = sprintf(msg, "%d\n", args_buf->update_results); |
475 | if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || | 476 | if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || |
476 | (args_buf->update_results == VALIDATE_TMP_UPDATE)) | 477 | (args_buf->update_results == VALIDATE_TMP_UPDATE)) |
477 | n += sprintf(msg + n, "%s\n", args_buf->buf); | 478 | n += snprintf(msg + n, msglen - n, "%s\n", |
479 | args_buf->buf); | ||
478 | } else { | 480 | } else { |
479 | n = sprintf(msg, "%d\n", args_buf->status); | 481 | n = sprintf(msg, "%d\n", args_buf->status); |
480 | } | 482 | } |
@@ -486,11 +488,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, | |||
486 | { | 488 | { |
487 | struct rtas_validate_flash_t *const args_buf = | 489 | struct rtas_validate_flash_t *const args_buf = |
488 | &rtas_validate_flash_data; | 490 | &rtas_validate_flash_data; |
489 | char msg[RTAS_MSG_MAXLEN]; | 491 | char msg[VALIDATE_MSG_LEN]; |
490 | int msglen; | 492 | int msglen; |
491 | 493 | ||
492 | mutex_lock(&rtas_validate_flash_mutex); | 494 | mutex_lock(&rtas_validate_flash_mutex); |
493 | msglen = get_validate_flash_msg(args_buf, msg); | 495 | msglen = get_validate_flash_msg(args_buf, msg, VALIDATE_MSG_LEN); |
494 | mutex_unlock(&rtas_validate_flash_mutex); | 496 | mutex_unlock(&rtas_validate_flash_mutex); |
495 | 497 | ||
496 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); | 498 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index cf12eae02de5..457e97aa2945 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -13,10 +13,12 @@ | |||
13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
14 | #include <linux/uprobes.h> | 14 | #include <linux/uprobes.h> |
15 | #include <linux/key.h> | 15 | #include <linux/key.h> |
16 | #include <linux/context_tracking.h> | ||
16 | #include <asm/hw_breakpoint.h> | 17 | #include <asm/hw_breakpoint.h> |
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
18 | #include <asm/unistd.h> | 19 | #include <asm/unistd.h> |
19 | #include <asm/debug.h> | 20 | #include <asm/debug.h> |
21 | #include <asm/tm.h> | ||
20 | 22 | ||
21 | #include "signal.h" | 23 | #include "signal.h" |
22 | 24 | ||
@@ -24,18 +26,18 @@ | |||
24 | * through debug.exception-trace sysctl. | 26 | * through debug.exception-trace sysctl. |
25 | */ | 27 | */ |
26 | 28 | ||
27 | int show_unhandled_signals = 0; | 29 | int show_unhandled_signals = 1; |
28 | 30 | ||
29 | /* | 31 | /* |
30 | * Allocate space for the signal frame | 32 | * Allocate space for the signal frame |
31 | */ | 33 | */ |
32 | void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 34 | void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, |
33 | size_t frame_size, int is_32) | 35 | size_t frame_size, int is_32) |
34 | { | 36 | { |
35 | unsigned long oldsp, newsp; | 37 | unsigned long oldsp, newsp; |
36 | 38 | ||
37 | /* Default to using normal stack */ | 39 | /* Default to using normal stack */ |
38 | oldsp = get_clean_sp(regs, is_32); | 40 | oldsp = get_clean_sp(sp, is_32); |
39 | 41 | ||
40 | /* Check for alt stack */ | 42 | /* Check for alt stack */ |
41 | if ((ka->sa.sa_flags & SA_ONSTACK) && | 43 | if ((ka->sa.sa_flags & SA_ONSTACK) && |
@@ -159,6 +161,8 @@ static int do_signal(struct pt_regs *regs) | |||
159 | 161 | ||
160 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | 162 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) |
161 | { | 163 | { |
164 | user_exit(); | ||
165 | |||
162 | if (thread_info_flags & _TIF_UPROBE) | 166 | if (thread_info_flags & _TIF_UPROBE) |
163 | uprobe_notify_resume(regs); | 167 | uprobe_notify_resume(regs); |
164 | 168 | ||
@@ -169,4 +173,41 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | |||
169 | clear_thread_flag(TIF_NOTIFY_RESUME); | 173 | clear_thread_flag(TIF_NOTIFY_RESUME); |
170 | tracehook_notify_resume(regs); | 174 | tracehook_notify_resume(regs); |
171 | } | 175 | } |
176 | |||
177 | user_enter(); | ||
178 | } | ||
179 | |||
180 | unsigned long get_tm_stackpointer(struct pt_regs *regs) | ||
181 | { | ||
182 | /* When in an active transaction that takes a signal, we need to be | ||
183 | * careful with the stack. It's possible that the stack has moved back | ||
184 | * up after the tbegin. The obvious case here is when the tbegin is | ||
185 | * called inside a function that returns before a tend. In this case, | ||
186 | * the stack is part of the checkpointed transactional memory state. | ||
187 | * If we write over this non transactionally or in suspend, we are in | ||
188 | * trouble because if we get a tm abort, the program counter and stack | ||
189 | * pointer will be back at the tbegin but our in memory stack won't be | ||
190 | * valid anymore. | ||
191 | * | ||
192 | * To avoid this, when taking a signal in an active transaction, we | ||
193 | * need to use the stack pointer from the checkpointed state, rather | ||
194 | * than the speculated state. This ensures that the signal context | ||
195 | * (written tm suspended) will be written below the stack required for | ||
196 | * the rollback. The transaction is aborted becuase of the treclaim, | ||
197 | * so any memory written between the tbegin and the signal will be | ||
198 | * rolled back anyway. | ||
199 | * | ||
200 | * For signals taken in non-TM or suspended mode, we use the | ||
201 | * normal/non-checkpointed stack pointer. | ||
202 | */ | ||
203 | |||
204 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
205 | if (MSR_TM_ACTIVE(regs->msr)) { | ||
206 | tm_enable(); | ||
207 | tm_reclaim(¤t->thread, regs->msr, TM_CAUSE_SIGNAL); | ||
208 | if (MSR_TM_TRANSACTIONAL(regs->msr)) | ||
209 | return current->thread.ckpt_regs.gpr[1]; | ||
210 | } | ||
211 | #endif | ||
212 | return regs->gpr[1]; | ||
172 | } | 213 | } |
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index ec84c901ceab..c69b9aeb9f23 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); | 13 | extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); |
14 | 14 | ||
15 | extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 15 | extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp, |
16 | size_t frame_size, int is_32); | 16 | size_t frame_size, int is_32); |
17 | 17 | ||
18 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, | 18 | extern int handle_signal32(unsigned long sig, struct k_sigaction *ka, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 95068bf569ad..201385c3a1ae 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -503,12 +503,6 @@ static int save_tm_user_regs(struct pt_regs *regs, | |||
503 | { | 503 | { |
504 | unsigned long msr = regs->msr; | 504 | unsigned long msr = regs->msr; |
505 | 505 | ||
506 | /* tm_reclaim rolls back all reg states, updating thread.ckpt_regs, | ||
507 | * thread.transact_fpr[], thread.transact_vr[], etc. | ||
508 | */ | ||
509 | tm_enable(); | ||
510 | tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); | ||
511 | |||
512 | /* Make sure floating point registers are stored in regs */ | 506 | /* Make sure floating point registers are stored in regs */ |
513 | flush_fp_to_thread(current); | 507 | flush_fp_to_thread(current); |
514 | 508 | ||
@@ -965,7 +959,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
965 | 959 | ||
966 | /* Set up Signal Frame */ | 960 | /* Set up Signal Frame */ |
967 | /* Put a Real Time Context onto stack */ | 961 | /* Put a Real Time Context onto stack */ |
968 | rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1); | 962 | rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1); |
969 | addr = rt_sf; | 963 | addr = rt_sf; |
970 | if (unlikely(rt_sf == NULL)) | 964 | if (unlikely(rt_sf == NULL)) |
971 | goto badframe; | 965 | goto badframe; |
@@ -1403,7 +1397,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1403 | unsigned long tramp; | 1397 | unsigned long tramp; |
1404 | 1398 | ||
1405 | /* Set up Signal Frame */ | 1399 | /* Set up Signal Frame */ |
1406 | frame = get_sigframe(ka, regs, sizeof(*frame), 1); | 1400 | frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1); |
1407 | if (unlikely(frame == NULL)) | 1401 | if (unlikely(frame == NULL)) |
1408 | goto badframe; | 1402 | goto badframe; |
1409 | sc = (struct sigcontext __user *) &frame->sctx; | 1403 | sc = (struct sigcontext __user *) &frame->sctx; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index c1794286098c..345947367ec0 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -154,11 +154,12 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
154 | * As above, but Transactional Memory is in use, so deliver sigcontexts | 154 | * As above, but Transactional Memory is in use, so deliver sigcontexts |
155 | * containing checkpointed and transactional register states. | 155 | * containing checkpointed and transactional register states. |
156 | * | 156 | * |
157 | * To do this, we treclaim to gather both sets of registers and set up the | 157 | * To do this, we treclaim (done before entering here) to gather both sets of |
158 | * 'normal' sigcontext registers with rolled-back register values such that a | 158 | * registers and set up the 'normal' sigcontext registers with rolled-back |
159 | * simple signal handler sees a correct checkpointed register state. | 159 | * register values such that a simple signal handler sees a correct |
160 | * If interested, a TM-aware sighandler can examine the transactional registers | 160 | * checkpointed register state. If interested, a TM-aware sighandler can |
161 | * in the 2nd sigcontext to determine the real origin of the signal. | 161 | * examine the transactional registers in the 2nd sigcontext to determine the |
162 | * real origin of the signal. | ||
162 | */ | 163 | */ |
163 | static long setup_tm_sigcontexts(struct sigcontext __user *sc, | 164 | static long setup_tm_sigcontexts(struct sigcontext __user *sc, |
164 | struct sigcontext __user *tm_sc, | 165 | struct sigcontext __user *tm_sc, |
@@ -184,16 +185,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, | |||
184 | 185 | ||
185 | BUG_ON(!MSR_TM_ACTIVE(regs->msr)); | 186 | BUG_ON(!MSR_TM_ACTIVE(regs->msr)); |
186 | 187 | ||
187 | /* tm_reclaim rolls back all reg states, saving checkpointed (older) | ||
188 | * GPRs to thread.ckpt_regs and (if used) FPRs to (newer) | ||
189 | * thread.transact_fp and/or VRs to (newer) thread.transact_vr. | ||
190 | * THEN we save out FP/VRs, if necessary, to the checkpointed (older) | ||
191 | * thread.fr[]/vr[]s. The transactional (newer) GPRs are on the | ||
192 | * stack, in *regs. | ||
193 | */ | ||
194 | tm_enable(); | ||
195 | tm_reclaim(¤t->thread, msr, TM_CAUSE_SIGNAL); | ||
196 | |||
197 | flush_fp_to_thread(current); | 188 | flush_fp_to_thread(current); |
198 | 189 | ||
199 | #ifdef CONFIG_ALTIVEC | 190 | #ifdef CONFIG_ALTIVEC |
@@ -711,7 +702,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
711 | unsigned long newsp = 0; | 702 | unsigned long newsp = 0; |
712 | long err = 0; | 703 | long err = 0; |
713 | 704 | ||
714 | frame = get_sigframe(ka, regs, sizeof(*frame), 0); | 705 | frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0); |
715 | if (unlikely(frame == NULL)) | 706 | if (unlikely(frame == NULL)) |
716 | goto badframe; | 707 | goto badframe; |
717 | 708 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 83efa2f7d926..c0e5caf8ccc7 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/kdebug.h> | 35 | #include <linux/kdebug.h> |
36 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
37 | #include <linux/ratelimit.h> | 37 | #include <linux/ratelimit.h> |
38 | #include <linux/context_tracking.h> | ||
38 | 39 | ||
39 | #include <asm/emulated_ops.h> | 40 | #include <asm/emulated_ops.h> |
40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
@@ -52,6 +53,7 @@ | |||
52 | #ifdef CONFIG_PPC64 | 53 | #ifdef CONFIG_PPC64 |
53 | #include <asm/firmware.h> | 54 | #include <asm/firmware.h> |
54 | #include <asm/processor.h> | 55 | #include <asm/processor.h> |
56 | #include <asm/tm.h> | ||
55 | #endif | 57 | #endif |
56 | #include <asm/kexec.h> | 58 | #include <asm/kexec.h> |
57 | #include <asm/ppc-opcode.h> | 59 | #include <asm/ppc-opcode.h> |
@@ -667,6 +669,7 @@ int machine_check_generic(struct pt_regs *regs) | |||
667 | 669 | ||
668 | void machine_check_exception(struct pt_regs *regs) | 670 | void machine_check_exception(struct pt_regs *regs) |
669 | { | 671 | { |
672 | enum ctx_state prev_state = exception_enter(); | ||
670 | int recover = 0; | 673 | int recover = 0; |
671 | 674 | ||
672 | __get_cpu_var(irq_stat).mce_exceptions++; | 675 | __get_cpu_var(irq_stat).mce_exceptions++; |
@@ -683,7 +686,7 @@ void machine_check_exception(struct pt_regs *regs) | |||
683 | recover = cur_cpu_spec->machine_check(regs); | 686 | recover = cur_cpu_spec->machine_check(regs); |
684 | 687 | ||
685 | if (recover > 0) | 688 | if (recover > 0) |
686 | return; | 689 | goto bail; |
687 | 690 | ||
688 | #if defined(CONFIG_8xx) && defined(CONFIG_PCI) | 691 | #if defined(CONFIG_8xx) && defined(CONFIG_PCI) |
689 | /* the qspan pci read routines can cause machine checks -- Cort | 692 | /* the qspan pci read routines can cause machine checks -- Cort |
@@ -693,20 +696,23 @@ void machine_check_exception(struct pt_regs *regs) | |||
693 | * -- BenH | 696 | * -- BenH |
694 | */ | 697 | */ |
695 | bad_page_fault(regs, regs->dar, SIGBUS); | 698 | bad_page_fault(regs, regs->dar, SIGBUS); |
696 | return; | 699 | goto bail; |
697 | #endif | 700 | #endif |
698 | 701 | ||
699 | if (debugger_fault_handler(regs)) | 702 | if (debugger_fault_handler(regs)) |
700 | return; | 703 | goto bail; |
701 | 704 | ||
702 | if (check_io_access(regs)) | 705 | if (check_io_access(regs)) |
703 | return; | 706 | goto bail; |
704 | 707 | ||
705 | die("Machine check", regs, SIGBUS); | 708 | die("Machine check", regs, SIGBUS); |
706 | 709 | ||
707 | /* Must die if the interrupt is not recoverable */ | 710 | /* Must die if the interrupt is not recoverable */ |
708 | if (!(regs->msr & MSR_RI)) | 711 | if (!(regs->msr & MSR_RI)) |
709 | panic("Unrecoverable Machine check"); | 712 | panic("Unrecoverable Machine check"); |
713 | |||
714 | bail: | ||
715 | exception_exit(prev_state); | ||
710 | } | 716 | } |
711 | 717 | ||
712 | void SMIException(struct pt_regs *regs) | 718 | void SMIException(struct pt_regs *regs) |
@@ -716,20 +722,29 @@ void SMIException(struct pt_regs *regs) | |||
716 | 722 | ||
717 | void unknown_exception(struct pt_regs *regs) | 723 | void unknown_exception(struct pt_regs *regs) |
718 | { | 724 | { |
725 | enum ctx_state prev_state = exception_enter(); | ||
726 | |||
719 | printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", | 727 | printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", |
720 | regs->nip, regs->msr, regs->trap); | 728 | regs->nip, regs->msr, regs->trap); |
721 | 729 | ||
722 | _exception(SIGTRAP, regs, 0, 0); | 730 | _exception(SIGTRAP, regs, 0, 0); |
731 | |||
732 | exception_exit(prev_state); | ||
723 | } | 733 | } |
724 | 734 | ||
725 | void instruction_breakpoint_exception(struct pt_regs *regs) | 735 | void instruction_breakpoint_exception(struct pt_regs *regs) |
726 | { | 736 | { |
737 | enum ctx_state prev_state = exception_enter(); | ||
738 | |||
727 | if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, | 739 | if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, |
728 | 5, SIGTRAP) == NOTIFY_STOP) | 740 | 5, SIGTRAP) == NOTIFY_STOP) |
729 | return; | 741 | goto bail; |
730 | if (debugger_iabr_match(regs)) | 742 | if (debugger_iabr_match(regs)) |
731 | return; | 743 | goto bail; |
732 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | 744 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); |
745 | |||
746 | bail: | ||
747 | exception_exit(prev_state); | ||
733 | } | 748 | } |
734 | 749 | ||
735 | void RunModeException(struct pt_regs *regs) | 750 | void RunModeException(struct pt_regs *regs) |
@@ -739,15 +754,20 @@ void RunModeException(struct pt_regs *regs) | |||
739 | 754 | ||
740 | void __kprobes single_step_exception(struct pt_regs *regs) | 755 | void __kprobes single_step_exception(struct pt_regs *regs) |
741 | { | 756 | { |
757 | enum ctx_state prev_state = exception_enter(); | ||
758 | |||
742 | clear_single_step(regs); | 759 | clear_single_step(regs); |
743 | 760 | ||
744 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, | 761 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, |
745 | 5, SIGTRAP) == NOTIFY_STOP) | 762 | 5, SIGTRAP) == NOTIFY_STOP) |
746 | return; | 763 | goto bail; |
747 | if (debugger_sstep(regs)) | 764 | if (debugger_sstep(regs)) |
748 | return; | 765 | goto bail; |
749 | 766 | ||
750 | _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); | 767 | _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); |
768 | |||
769 | bail: | ||
770 | exception_exit(prev_state); | ||
751 | } | 771 | } |
752 | 772 | ||
753 | /* | 773 | /* |
@@ -913,6 +933,28 @@ static int emulate_isel(struct pt_regs *regs, u32 instword) | |||
913 | return 0; | 933 | return 0; |
914 | } | 934 | } |
915 | 935 | ||
936 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
937 | static inline bool tm_abort_check(struct pt_regs *regs, int cause) | ||
938 | { | ||
939 | /* If we're emulating a load/store in an active transaction, we cannot | ||
940 | * emulate it as the kernel operates in transaction suspended context. | ||
941 | * We need to abort the transaction. This creates a persistent TM | ||
942 | * abort so tell the user what caused it with a new code. | ||
943 | */ | ||
944 | if (MSR_TM_TRANSACTIONAL(regs->msr)) { | ||
945 | tm_enable(); | ||
946 | tm_abort(cause); | ||
947 | return true; | ||
948 | } | ||
949 | return false; | ||
950 | } | ||
951 | #else | ||
952 | static inline bool tm_abort_check(struct pt_regs *regs, int reason) | ||
953 | { | ||
954 | return false; | ||
955 | } | ||
956 | #endif | ||
957 | |||
916 | static int emulate_instruction(struct pt_regs *regs) | 958 | static int emulate_instruction(struct pt_regs *regs) |
917 | { | 959 | { |
918 | u32 instword; | 960 | u32 instword; |
@@ -952,6 +994,9 @@ static int emulate_instruction(struct pt_regs *regs) | |||
952 | 994 | ||
953 | /* Emulate load/store string insn. */ | 995 | /* Emulate load/store string insn. */ |
954 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { | 996 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { |
997 | if (tm_abort_check(regs, | ||
998 | TM_CAUSE_EMULATE | TM_CAUSE_PERSISTENT)) | ||
999 | return -EINVAL; | ||
955 | PPC_WARN_EMULATED(string, regs); | 1000 | PPC_WARN_EMULATED(string, regs); |
956 | return emulate_string_inst(regs, instword); | 1001 | return emulate_string_inst(regs, instword); |
957 | } | 1002 | } |
@@ -1005,6 +1050,7 @@ int is_valid_bugaddr(unsigned long addr) | |||
1005 | 1050 | ||
1006 | void __kprobes program_check_exception(struct pt_regs *regs) | 1051 | void __kprobes program_check_exception(struct pt_regs *regs) |
1007 | { | 1052 | { |
1053 | enum ctx_state prev_state = exception_enter(); | ||
1008 | unsigned int reason = get_reason(regs); | 1054 | unsigned int reason = get_reason(regs); |
1009 | extern int do_mathemu(struct pt_regs *regs); | 1055 | extern int do_mathemu(struct pt_regs *regs); |
1010 | 1056 | ||
@@ -1014,26 +1060,26 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1014 | if (reason & REASON_FP) { | 1060 | if (reason & REASON_FP) { |
1015 | /* IEEE FP exception */ | 1061 | /* IEEE FP exception */ |
1016 | parse_fpe(regs); | 1062 | parse_fpe(regs); |
1017 | return; | 1063 | goto bail; |
1018 | } | 1064 | } |
1019 | if (reason & REASON_TRAP) { | 1065 | if (reason & REASON_TRAP) { |
1020 | /* Debugger is first in line to stop recursive faults in | 1066 | /* Debugger is first in line to stop recursive faults in |
1021 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ | 1067 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ |
1022 | if (debugger_bpt(regs)) | 1068 | if (debugger_bpt(regs)) |
1023 | return; | 1069 | goto bail; |
1024 | 1070 | ||
1025 | /* trap exception */ | 1071 | /* trap exception */ |
1026 | if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) | 1072 | if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) |
1027 | == NOTIFY_STOP) | 1073 | == NOTIFY_STOP) |
1028 | return; | 1074 | goto bail; |
1029 | 1075 | ||
1030 | if (!(regs->msr & MSR_PR) && /* not user-mode */ | 1076 | if (!(regs->msr & MSR_PR) && /* not user-mode */ |
1031 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { | 1077 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { |
1032 | regs->nip += 4; | 1078 | regs->nip += 4; |
1033 | return; | 1079 | goto bail; |
1034 | } | 1080 | } |
1035 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | 1081 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); |
1036 | return; | 1082 | goto bail; |
1037 | } | 1083 | } |
1038 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1084 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1039 | if (reason & REASON_TM) { | 1085 | if (reason & REASON_TM) { |
@@ -1049,7 +1095,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1049 | if (!user_mode(regs) && | 1095 | if (!user_mode(regs) && |
1050 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { | 1096 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { |
1051 | regs->nip += 4; | 1097 | regs->nip += 4; |
1052 | return; | 1098 | goto bail; |
1053 | } | 1099 | } |
1054 | /* If usermode caused this, it's done something illegal and | 1100 | /* If usermode caused this, it's done something illegal and |
1055 | * gets a SIGILL slap on the wrist. We call it an illegal | 1101 | * gets a SIGILL slap on the wrist. We call it an illegal |
@@ -1059,7 +1105,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1059 | */ | 1105 | */ |
1060 | if (user_mode(regs)) { | 1106 | if (user_mode(regs)) { |
1061 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); | 1107 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); |
1062 | return; | 1108 | goto bail; |
1063 | } else { | 1109 | } else { |
1064 | printk(KERN_EMERG "Unexpected TM Bad Thing exception " | 1110 | printk(KERN_EMERG "Unexpected TM Bad Thing exception " |
1065 | "at %lx (msr 0x%x)\n", regs->nip, reason); | 1111 | "at %lx (msr 0x%x)\n", regs->nip, reason); |
@@ -1083,16 +1129,16 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1083 | switch (do_mathemu(regs)) { | 1129 | switch (do_mathemu(regs)) { |
1084 | case 0: | 1130 | case 0: |
1085 | emulate_single_step(regs); | 1131 | emulate_single_step(regs); |
1086 | return; | 1132 | goto bail; |
1087 | case 1: { | 1133 | case 1: { |
1088 | int code = 0; | 1134 | int code = 0; |
1089 | code = __parse_fpscr(current->thread.fpscr.val); | 1135 | code = __parse_fpscr(current->thread.fpscr.val); |
1090 | _exception(SIGFPE, regs, code, regs->nip); | 1136 | _exception(SIGFPE, regs, code, regs->nip); |
1091 | return; | 1137 | goto bail; |
1092 | } | 1138 | } |
1093 | case -EFAULT: | 1139 | case -EFAULT: |
1094 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | 1140 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); |
1095 | return; | 1141 | goto bail; |
1096 | } | 1142 | } |
1097 | /* fall through on any other errors */ | 1143 | /* fall through on any other errors */ |
1098 | #endif /* CONFIG_MATH_EMULATION */ | 1144 | #endif /* CONFIG_MATH_EMULATION */ |
@@ -1103,10 +1149,10 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1103 | case 0: | 1149 | case 0: |
1104 | regs->nip += 4; | 1150 | regs->nip += 4; |
1105 | emulate_single_step(regs); | 1151 | emulate_single_step(regs); |
1106 | return; | 1152 | goto bail; |
1107 | case -EFAULT: | 1153 | case -EFAULT: |
1108 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | 1154 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); |
1109 | return; | 1155 | goto bail; |
1110 | } | 1156 | } |
1111 | } | 1157 | } |
1112 | 1158 | ||
@@ -1114,16 +1160,33 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
1114 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); | 1160 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); |
1115 | else | 1161 | else |
1116 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1162 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
1163 | |||
1164 | bail: | ||
1165 | exception_exit(prev_state); | ||
1166 | } | ||
1167 | |||
1168 | /* | ||
1169 | * This occurs when running in hypervisor mode on POWER6 or later | ||
1170 | * and an illegal instruction is encountered. | ||
1171 | */ | ||
1172 | void __kprobes emulation_assist_interrupt(struct pt_regs *regs) | ||
1173 | { | ||
1174 | regs->msr |= REASON_ILLEGAL; | ||
1175 | program_check_exception(regs); | ||
1117 | } | 1176 | } |
1118 | 1177 | ||
1119 | void alignment_exception(struct pt_regs *regs) | 1178 | void alignment_exception(struct pt_regs *regs) |
1120 | { | 1179 | { |
1180 | enum ctx_state prev_state = exception_enter(); | ||
1121 | int sig, code, fixed = 0; | 1181 | int sig, code, fixed = 0; |
1122 | 1182 | ||
1123 | /* We restore the interrupt state now */ | 1183 | /* We restore the interrupt state now */ |
1124 | if (!arch_irq_disabled_regs(regs)) | 1184 | if (!arch_irq_disabled_regs(regs)) |
1125 | local_irq_enable(); | 1185 | local_irq_enable(); |
1126 | 1186 | ||
1187 | if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) | ||
1188 | goto bail; | ||
1189 | |||
1127 | /* we don't implement logging of alignment exceptions */ | 1190 | /* we don't implement logging of alignment exceptions */ |
1128 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) | 1191 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) |
1129 | fixed = fix_alignment(regs); | 1192 | fixed = fix_alignment(regs); |
@@ -1131,7 +1194,7 @@ void alignment_exception(struct pt_regs *regs) | |||
1131 | if (fixed == 1) { | 1194 | if (fixed == 1) { |
1132 | regs->nip += 4; /* skip over emulated instruction */ | 1195 | regs->nip += 4; /* skip over emulated instruction */ |
1133 | emulate_single_step(regs); | 1196 | emulate_single_step(regs); |
1134 | return; | 1197 | goto bail; |
1135 | } | 1198 | } |
1136 | 1199 | ||
1137 | /* Operand address was bad */ | 1200 | /* Operand address was bad */ |
@@ -1146,6 +1209,9 @@ void alignment_exception(struct pt_regs *regs) | |||
1146 | _exception(sig, regs, code, regs->dar); | 1209 | _exception(sig, regs, code, regs->dar); |
1147 | else | 1210 | else |
1148 | bad_page_fault(regs, regs->dar, sig); | 1211 | bad_page_fault(regs, regs->dar, sig); |
1212 | |||
1213 | bail: | ||
1214 | exception_exit(prev_state); | ||
1149 | } | 1215 | } |
1150 | 1216 | ||
1151 | void StackOverflow(struct pt_regs *regs) | 1217 | void StackOverflow(struct pt_regs *regs) |
@@ -1174,23 +1240,32 @@ void trace_syscall(struct pt_regs *regs) | |||
1174 | 1240 | ||
1175 | void kernel_fp_unavailable_exception(struct pt_regs *regs) | 1241 | void kernel_fp_unavailable_exception(struct pt_regs *regs) |
1176 | { | 1242 | { |
1243 | enum ctx_state prev_state = exception_enter(); | ||
1244 | |||
1177 | printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " | 1245 | printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " |
1178 | "%lx at %lx\n", regs->trap, regs->nip); | 1246 | "%lx at %lx\n", regs->trap, regs->nip); |
1179 | die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); | 1247 | die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); |
1248 | |||
1249 | exception_exit(prev_state); | ||
1180 | } | 1250 | } |
1181 | 1251 | ||
1182 | void altivec_unavailable_exception(struct pt_regs *regs) | 1252 | void altivec_unavailable_exception(struct pt_regs *regs) |
1183 | { | 1253 | { |
1254 | enum ctx_state prev_state = exception_enter(); | ||
1255 | |||
1184 | if (user_mode(regs)) { | 1256 | if (user_mode(regs)) { |
1185 | /* A user program has executed an altivec instruction, | 1257 | /* A user program has executed an altivec instruction, |
1186 | but this kernel doesn't support altivec. */ | 1258 | but this kernel doesn't support altivec. */ |
1187 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1259 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
1188 | return; | 1260 | goto bail; |
1189 | } | 1261 | } |
1190 | 1262 | ||
1191 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " | 1263 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " |
1192 | "%lx at %lx\n", regs->trap, regs->nip); | 1264 | "%lx at %lx\n", regs->trap, regs->nip); |
1193 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 1265 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |
1266 | |||
1267 | bail: | ||
1268 | exception_exit(prev_state); | ||
1194 | } | 1269 | } |
1195 | 1270 | ||
1196 | void vsx_unavailable_exception(struct pt_regs *regs) | 1271 | void vsx_unavailable_exception(struct pt_regs *regs) |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 13b867093499..9d3fdcd66290 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -64,6 +64,9 @@ void __init udbg_early_init(void) | |||
64 | udbg_init_usbgecko(); | 64 | udbg_init_usbgecko(); |
65 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) | 65 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) |
66 | udbg_init_wsp(); | 66 | udbg_init_wsp(); |
67 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS) | ||
68 | /* In memory console */ | ||
69 | udbg_init_memcons(); | ||
67 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) | 70 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) |
68 | udbg_init_ehv_bc(); | 71 | udbg_init_ehv_bc(); |
69 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) | 72 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) |
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 5dd3ab469976..ed0385448148 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
@@ -441,6 +441,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | |||
441 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | 441 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); |
442 | struct kvmppc_44x_tlbe *tlbe; | 442 | struct kvmppc_44x_tlbe *tlbe; |
443 | unsigned int gtlb_index; | 443 | unsigned int gtlb_index; |
444 | int idx; | ||
444 | 445 | ||
445 | gtlb_index = kvmppc_get_gpr(vcpu, ra); | 446 | gtlb_index = kvmppc_get_gpr(vcpu, ra); |
446 | if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { | 447 | if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { |
@@ -473,6 +474,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | |||
473 | return EMULATE_FAIL; | 474 | return EMULATE_FAIL; |
474 | } | 475 | } |
475 | 476 | ||
477 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
478 | |||
476 | if (tlbe_is_host_safe(vcpu, tlbe)) { | 479 | if (tlbe_is_host_safe(vcpu, tlbe)) { |
477 | gva_t eaddr; | 480 | gva_t eaddr; |
478 | gpa_t gpaddr; | 481 | gpa_t gpaddr; |
@@ -489,6 +492,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | |||
489 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); | 492 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); |
490 | } | 493 | } |
491 | 494 | ||
495 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
496 | |||
492 | trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, | 497 | trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, |
493 | tlbe->word2); | 498 | tlbe->word2); |
494 | 499 | ||
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 9de24f8e03c7..550f5928b394 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -562,6 +562,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
562 | case H_CPPR: | 562 | case H_CPPR: |
563 | case H_EOI: | 563 | case H_EOI: |
564 | case H_IPI: | 564 | case H_IPI: |
565 | case H_IPOLL: | ||
566 | case H_XIRR_X: | ||
565 | if (kvmppc_xics_enabled(vcpu)) { | 567 | if (kvmppc_xics_enabled(vcpu)) { |
566 | ret = kvmppc_xics_hcall(vcpu, req); | 568 | ret = kvmppc_xics_hcall(vcpu, req); |
567 | break; | 569 | break; |
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index b24309c6c2d5..da0e0bc268bd 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c | |||
@@ -257,6 +257,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) | |||
257 | case H_CPPR: | 257 | case H_CPPR: |
258 | case H_EOI: | 258 | case H_EOI: |
259 | case H_IPI: | 259 | case H_IPI: |
260 | case H_IPOLL: | ||
261 | case H_XIRR_X: | ||
260 | if (kvmppc_xics_enabled(vcpu)) | 262 | if (kvmppc_xics_enabled(vcpu)) |
261 | return kvmppc_h_pr_xics_hcall(vcpu, cmd); | 263 | return kvmppc_h_pr_xics_hcall(vcpu, cmd); |
262 | break; | 264 | break; |
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index f7a103756618..94c1dd46b83d 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -650,6 +650,23 @@ static noinline int kvmppc_h_ipi(struct kvm_vcpu *vcpu, unsigned long server, | |||
650 | return H_SUCCESS; | 650 | return H_SUCCESS; |
651 | } | 651 | } |
652 | 652 | ||
653 | static int kvmppc_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server) | ||
654 | { | ||
655 | union kvmppc_icp_state state; | ||
656 | struct kvmppc_icp *icp; | ||
657 | |||
658 | icp = vcpu->arch.icp; | ||
659 | if (icp->server_num != server) { | ||
660 | icp = kvmppc_xics_find_server(vcpu->kvm, server); | ||
661 | if (!icp) | ||
662 | return H_PARAMETER; | ||
663 | } | ||
664 | state = ACCESS_ONCE(icp->state); | ||
665 | kvmppc_set_gpr(vcpu, 4, ((u32)state.cppr << 24) | state.xisr); | ||
666 | kvmppc_set_gpr(vcpu, 5, state.mfrr); | ||
667 | return H_SUCCESS; | ||
668 | } | ||
669 | |||
653 | static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr) | 670 | static noinline void kvmppc_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr) |
654 | { | 671 | { |
655 | union kvmppc_icp_state old_state, new_state; | 672 | union kvmppc_icp_state old_state, new_state; |
@@ -787,6 +804,18 @@ int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req) | |||
787 | if (!xics || !vcpu->arch.icp) | 804 | if (!xics || !vcpu->arch.icp) |
788 | return H_HARDWARE; | 805 | return H_HARDWARE; |
789 | 806 | ||
807 | /* These requests don't have real-mode implementations at present */ | ||
808 | switch (req) { | ||
809 | case H_XIRR_X: | ||
810 | res = kvmppc_h_xirr(vcpu); | ||
811 | kvmppc_set_gpr(vcpu, 4, res); | ||
812 | kvmppc_set_gpr(vcpu, 5, get_tb()); | ||
813 | return rc; | ||
814 | case H_IPOLL: | ||
815 | rc = kvmppc_h_ipoll(vcpu, kvmppc_get_gpr(vcpu, 4)); | ||
816 | return rc; | ||
817 | } | ||
818 | |||
790 | /* Check for real mode returning too hard */ | 819 | /* Check for real mode returning too hard */ |
791 | if (xics->real_mode) | 820 | if (xics->real_mode) |
792 | return kvmppc_xics_rm_complete(vcpu, req); | 821 | return kvmppc_xics_rm_complete(vcpu, req); |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 1020119226db..1a1b51189773 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -673,7 +673,6 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
673 | ret = s; | 673 | ret = s; |
674 | goto out; | 674 | goto out; |
675 | } | 675 | } |
676 | kvmppc_lazy_ee_enable(); | ||
677 | 676 | ||
678 | kvm_guest_enter(); | 677 | kvm_guest_enter(); |
679 | 678 | ||
@@ -699,6 +698,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
699 | kvmppc_load_guest_fp(vcpu); | 698 | kvmppc_load_guest_fp(vcpu); |
700 | #endif | 699 | #endif |
701 | 700 | ||
701 | kvmppc_lazy_ee_enable(); | ||
702 | |||
702 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); | 703 | ret = __kvmppc_vcpu_run(kvm_run, vcpu); |
703 | 704 | ||
704 | /* No need for kvm_guest_exit. It's done in handle_exit. | 705 | /* No need for kvm_guest_exit. It's done in handle_exit. |
@@ -832,6 +833,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
832 | { | 833 | { |
833 | int r = RESUME_HOST; | 834 | int r = RESUME_HOST; |
834 | int s; | 835 | int s; |
836 | int idx; | ||
837 | |||
838 | #ifdef CONFIG_PPC64 | ||
839 | WARN_ON(local_paca->irq_happened != 0); | ||
840 | #endif | ||
841 | |||
842 | /* | ||
843 | * We enter with interrupts disabled in hardware, but | ||
844 | * we need to call hard_irq_disable anyway to ensure that | ||
845 | * the software state is kept in sync. | ||
846 | */ | ||
847 | hard_irq_disable(); | ||
835 | 848 | ||
836 | /* update before a new last_exit_type is rewritten */ | 849 | /* update before a new last_exit_type is rewritten */ |
837 | kvmppc_update_timing_stats(vcpu); | 850 | kvmppc_update_timing_stats(vcpu); |
@@ -1053,6 +1066,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1053 | break; | 1066 | break; |
1054 | } | 1067 | } |
1055 | 1068 | ||
1069 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
1070 | |||
1056 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); | 1071 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); |
1057 | gfn = gpaddr >> PAGE_SHIFT; | 1072 | gfn = gpaddr >> PAGE_SHIFT; |
1058 | 1073 | ||
@@ -1075,6 +1090,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1075 | kvmppc_account_exit(vcpu, MMIO_EXITS); | 1090 | kvmppc_account_exit(vcpu, MMIO_EXITS); |
1076 | } | 1091 | } |
1077 | 1092 | ||
1093 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
1078 | break; | 1094 | break; |
1079 | } | 1095 | } |
1080 | 1096 | ||
@@ -1098,6 +1114,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1098 | 1114 | ||
1099 | kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS); | 1115 | kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS); |
1100 | 1116 | ||
1117 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
1118 | |||
1101 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); | 1119 | gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr); |
1102 | gfn = gpaddr >> PAGE_SHIFT; | 1120 | gfn = gpaddr >> PAGE_SHIFT; |
1103 | 1121 | ||
@@ -1114,6 +1132,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1114 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK); | 1132 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK); |
1115 | } | 1133 | } |
1116 | 1134 | ||
1135 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
1117 | break; | 1136 | break; |
1118 | } | 1137 | } |
1119 | 1138 | ||
diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index c41a5a96b558..6d6f153b6c1d 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c | |||
@@ -396,6 +396,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | |||
396 | struct kvm_book3e_206_tlb_entry *gtlbe; | 396 | struct kvm_book3e_206_tlb_entry *gtlbe; |
397 | int tlbsel, esel; | 397 | int tlbsel, esel; |
398 | int recal = 0; | 398 | int recal = 0; |
399 | int idx; | ||
399 | 400 | ||
400 | tlbsel = get_tlb_tlbsel(vcpu); | 401 | tlbsel = get_tlb_tlbsel(vcpu); |
401 | esel = get_tlb_esel(vcpu, tlbsel); | 402 | esel = get_tlb_esel(vcpu, tlbsel); |
@@ -430,6 +431,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | |||
430 | kvmppc_set_tlb1map_range(vcpu, gtlbe); | 431 | kvmppc_set_tlb1map_range(vcpu, gtlbe); |
431 | } | 432 | } |
432 | 433 | ||
434 | idx = srcu_read_lock(&vcpu->kvm->srcu); | ||
435 | |||
433 | /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ | 436 | /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ |
434 | if (tlbe_is_host_safe(vcpu, gtlbe)) { | 437 | if (tlbe_is_host_safe(vcpu, gtlbe)) { |
435 | u64 eaddr = get_tlb_eaddr(gtlbe); | 438 | u64 eaddr = get_tlb_eaddr(gtlbe); |
@@ -444,6 +447,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | |||
444 | kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel)); | 447 | kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel)); |
445 | } | 448 | } |
446 | 449 | ||
450 | srcu_read_unlock(&vcpu->kvm->srcu, idx); | ||
451 | |||
447 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); | 452 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); |
448 | return EMULATE_DONE; | 453 | return EMULATE_DONE; |
449 | } | 454 | } |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 753cc99eff2b..19c8379575f7 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -177,8 +177,6 @@ int kvmppc_core_check_processor_compat(void) | |||
177 | r = 0; | 177 | r = 0; |
178 | else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0) | 178 | else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0) |
179 | r = 0; | 179 | r = 0; |
180 | else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0) | ||
181 | r = 0; | ||
182 | else | 180 | else |
183 | r = -ENOTSUPP; | 181 | r = -ENOTSUPP; |
184 | 182 | ||
diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index 0ef75bf0695c..395c594722a2 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S | |||
@@ -28,13 +28,14 @@ _GLOBAL(copypage_power7) | |||
28 | * aligned we don't need to clear the bottom 7 bits of either | 28 | * aligned we don't need to clear the bottom 7 bits of either |
29 | * address. | 29 | * address. |
30 | */ | 30 | */ |
31 | ori r9,r3,1 /* stream=1 */ | 31 | ori r9,r3,1 /* stream=1 => to */ |
32 | 32 | ||
33 | #ifdef CONFIG_PPC_64K_PAGES | 33 | #ifdef CONFIG_PPC_64K_PAGES |
34 | lis r7,0x0E01 /* depth=7, units=512 */ | 34 | lis r7,0x0E01 /* depth=7 |
35 | * units/cachelines=512 */ | ||
35 | #else | 36 | #else |
36 | lis r7,0x0E00 /* depth=7 */ | 37 | lis r7,0x0E00 /* depth=7 */ |
37 | ori r7,r7,0x1000 /* units=32 */ | 38 | ori r7,r7,0x1000 /* units/cachelines=32 */ |
38 | #endif | 39 | #endif |
39 | ori r10,r7,1 /* stream=1 */ | 40 | ori r10,r7,1 /* stream=1 */ |
40 | 41 | ||
@@ -43,12 +44,14 @@ _GLOBAL(copypage_power7) | |||
43 | 44 | ||
44 | .machine push | 45 | .machine push |
45 | .machine "power4" | 46 | .machine "power4" |
46 | dcbt r0,r4,0b01000 | 47 | /* setup read stream 0 */ |
47 | dcbt r0,r7,0b01010 | 48 | dcbt r0,r4,0b01000 /* addr from */ |
48 | dcbtst r0,r9,0b01000 | 49 | dcbt r0,r7,0b01010 /* length and depth from */ |
49 | dcbtst r0,r10,0b01010 | 50 | /* setup write stream 1 */ |
51 | dcbtst r0,r9,0b01000 /* addr to */ | ||
52 | dcbtst r0,r10,0b01010 /* length and depth to */ | ||
50 | eieio | 53 | eieio |
51 | dcbt r0,r8,0b01010 /* GO */ | 54 | dcbt r0,r8,0b01010 /* all streams GO */ |
52 | .machine pop | 55 | .machine pop |
53 | 56 | ||
54 | #ifdef CONFIG_ALTIVEC | 57 | #ifdef CONFIG_ALTIVEC |
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index 0d24ff15f5f6..d1f11795a7ad 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S | |||
@@ -318,12 +318,14 @@ err1; stb r0,0(r3) | |||
318 | 318 | ||
319 | .machine push | 319 | .machine push |
320 | .machine "power4" | 320 | .machine "power4" |
321 | dcbt r0,r6,0b01000 | 321 | /* setup read stream 0 */ |
322 | dcbt r0,r7,0b01010 | 322 | dcbt r0,r6,0b01000 /* addr from */ |
323 | dcbtst r0,r9,0b01000 | 323 | dcbt r0,r7,0b01010 /* length and depth from */ |
324 | dcbtst r0,r10,0b01010 | 324 | /* setup write stream 1 */ |
325 | dcbtst r0,r9,0b01000 /* addr to */ | ||
326 | dcbtst r0,r10,0b01010 /* length and depth to */ | ||
325 | eieio | 327 | eieio |
326 | dcbt r0,r8,0b01010 /* GO */ | 328 | dcbt r0,r8,0b01010 /* all streams GO */ |
327 | .machine pop | 329 | .machine pop |
328 | 330 | ||
329 | beq cr1,.Lunwind_stack_nonvmx_copy | 331 | beq cr1,.Lunwind_stack_nonvmx_copy |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 229951ffc351..8726779e1409 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/perf_event.h> | 32 | #include <linux/perf_event.h> |
33 | #include <linux/magic.h> | 33 | #include <linux/magic.h> |
34 | #include <linux/ratelimit.h> | 34 | #include <linux/ratelimit.h> |
35 | #include <linux/context_tracking.h> | ||
35 | 36 | ||
36 | #include <asm/firmware.h> | 37 | #include <asm/firmware.h> |
37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
@@ -196,6 +197,7 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) | |||
196 | int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | 197 | int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, |
197 | unsigned long error_code) | 198 | unsigned long error_code) |
198 | { | 199 | { |
200 | enum ctx_state prev_state = exception_enter(); | ||
199 | struct vm_area_struct * vma; | 201 | struct vm_area_struct * vma; |
200 | struct mm_struct *mm = current->mm; | 202 | struct mm_struct *mm = current->mm; |
201 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 203 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
@@ -204,6 +206,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
204 | int trap = TRAP(regs); | 206 | int trap = TRAP(regs); |
205 | int is_exec = trap == 0x400; | 207 | int is_exec = trap == 0x400; |
206 | int fault; | 208 | int fault; |
209 | int rc = 0; | ||
207 | 210 | ||
208 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) | 211 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) |
209 | /* | 212 | /* |
@@ -230,28 +233,30 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
230 | * look at it | 233 | * look at it |
231 | */ | 234 | */ |
232 | if (error_code & ICSWX_DSI_UCT) { | 235 | if (error_code & ICSWX_DSI_UCT) { |
233 | int rc = acop_handle_fault(regs, address, error_code); | 236 | rc = acop_handle_fault(regs, address, error_code); |
234 | if (rc) | 237 | if (rc) |
235 | return rc; | 238 | goto bail; |
236 | } | 239 | } |
237 | #endif /* CONFIG_PPC_ICSWX */ | 240 | #endif /* CONFIG_PPC_ICSWX */ |
238 | 241 | ||
239 | if (notify_page_fault(regs)) | 242 | if (notify_page_fault(regs)) |
240 | return 0; | 243 | goto bail; |
241 | 244 | ||
242 | if (unlikely(debugger_fault_handler(regs))) | 245 | if (unlikely(debugger_fault_handler(regs))) |
243 | return 0; | 246 | goto bail; |
244 | 247 | ||
245 | /* On a kernel SLB miss we can only check for a valid exception entry */ | 248 | /* On a kernel SLB miss we can only check for a valid exception entry */ |
246 | if (!user_mode(regs) && (address >= TASK_SIZE)) | 249 | if (!user_mode(regs) && (address >= TASK_SIZE)) { |
247 | return SIGSEGV; | 250 | rc = SIGSEGV; |
251 | goto bail; | ||
252 | } | ||
248 | 253 | ||
249 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ | 254 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ |
250 | defined(CONFIG_PPC_BOOK3S_64)) | 255 | defined(CONFIG_PPC_BOOK3S_64)) |
251 | if (error_code & DSISR_DABRMATCH) { | 256 | if (error_code & DSISR_DABRMATCH) { |
252 | /* breakpoint match */ | 257 | /* breakpoint match */ |
253 | do_break(regs, address, error_code); | 258 | do_break(regs, address, error_code); |
254 | return 0; | 259 | goto bail; |
255 | } | 260 | } |
256 | #endif | 261 | #endif |
257 | 262 | ||
@@ -260,8 +265,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
260 | local_irq_enable(); | 265 | local_irq_enable(); |
261 | 266 | ||
262 | if (in_atomic() || mm == NULL) { | 267 | if (in_atomic() || mm == NULL) { |
263 | if (!user_mode(regs)) | 268 | if (!user_mode(regs)) { |
264 | return SIGSEGV; | 269 | rc = SIGSEGV; |
270 | goto bail; | ||
271 | } | ||
265 | /* in_atomic() in user mode is really bad, | 272 | /* in_atomic() in user mode is really bad, |
266 | as is current->mm == NULL. */ | 273 | as is current->mm == NULL. */ |
267 | printk(KERN_EMERG "Page fault in user mode with " | 274 | printk(KERN_EMERG "Page fault in user mode with " |
@@ -417,9 +424,11 @@ good_area: | |||
417 | */ | 424 | */ |
418 | fault = handle_mm_fault(mm, vma, address, flags); | 425 | fault = handle_mm_fault(mm, vma, address, flags); |
419 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { | 426 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { |
420 | int rc = mm_fault_error(regs, address, fault); | 427 | rc = mm_fault_error(regs, address, fault); |
421 | if (rc >= MM_FAULT_RETURN) | 428 | if (rc >= MM_FAULT_RETURN) |
422 | return rc; | 429 | goto bail; |
430 | else | ||
431 | rc = 0; | ||
423 | } | 432 | } |
424 | 433 | ||
425 | /* | 434 | /* |
@@ -454,7 +463,7 @@ good_area: | |||
454 | } | 463 | } |
455 | 464 | ||
456 | up_read(&mm->mmap_sem); | 465 | up_read(&mm->mmap_sem); |
457 | return 0; | 466 | goto bail; |
458 | 467 | ||
459 | bad_area: | 468 | bad_area: |
460 | up_read(&mm->mmap_sem); | 469 | up_read(&mm->mmap_sem); |
@@ -463,7 +472,7 @@ bad_area_nosemaphore: | |||
463 | /* User mode accesses cause a SIGSEGV */ | 472 | /* User mode accesses cause a SIGSEGV */ |
464 | if (user_mode(regs)) { | 473 | if (user_mode(regs)) { |
465 | _exception(SIGSEGV, regs, code, address); | 474 | _exception(SIGSEGV, regs, code, address); |
466 | return 0; | 475 | goto bail; |
467 | } | 476 | } |
468 | 477 | ||
469 | if (is_exec && (error_code & DSISR_PROTFAULT)) | 478 | if (is_exec && (error_code & DSISR_PROTFAULT)) |
@@ -471,7 +480,11 @@ bad_area_nosemaphore: | |||
471 | " page (%lx) - exploit attempt? (uid: %d)\n", | 480 | " page (%lx) - exploit attempt? (uid: %d)\n", |
472 | address, from_kuid(&init_user_ns, current_uid())); | 481 | address, from_kuid(&init_user_ns, current_uid())); |
473 | 482 | ||
474 | return SIGSEGV; | 483 | rc = SIGSEGV; |
484 | |||
485 | bail: | ||
486 | exception_exit(prev_state); | ||
487 | return rc; | ||
475 | 488 | ||
476 | } | 489 | } |
477 | 490 | ||
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 6a2aead5b0e5..4c122c3f1623 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -336,11 +336,18 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
336 | 336 | ||
337 | hpte_v = hptep->v; | 337 | hpte_v = hptep->v; |
338 | actual_psize = hpte_actual_psize(hptep, psize); | 338 | actual_psize = hpte_actual_psize(hptep, psize); |
339 | /* | ||
340 | * We need to invalidate the TLB always because hpte_remove doesn't do | ||
341 | * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less | ||
342 | * random entry from it. When we do that we don't invalidate the TLB | ||
343 | * (hpte_remove) because we assume the old translation is still | ||
344 | * technically "valid". | ||
345 | */ | ||
339 | if (actual_psize < 0) { | 346 | if (actual_psize < 0) { |
340 | native_unlock_hpte(hptep); | 347 | actual_psize = psize; |
341 | return -1; | 348 | ret = -1; |
349 | goto err_out; | ||
342 | } | 350 | } |
343 | /* Even if we miss, we need to invalidate the TLB */ | ||
344 | if (!HPTE_V_COMPARE(hpte_v, want_v)) { | 351 | if (!HPTE_V_COMPARE(hpte_v, want_v)) { |
345 | DBG_LOW(" -> miss\n"); | 352 | DBG_LOW(" -> miss\n"); |
346 | ret = -1; | 353 | ret = -1; |
@@ -350,6 +357,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
350 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | | 357 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | |
351 | (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); | 358 | (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)); |
352 | } | 359 | } |
360 | err_out: | ||
353 | native_unlock_hpte(hptep); | 361 | native_unlock_hpte(hptep); |
354 | 362 | ||
355 | /* Ensure it is out of the tlb too. */ | 363 | /* Ensure it is out of the tlb too. */ |
@@ -409,7 +417,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, | |||
409 | hptep = htab_address + slot; | 417 | hptep = htab_address + slot; |
410 | actual_psize = hpte_actual_psize(hptep, psize); | 418 | actual_psize = hpte_actual_psize(hptep, psize); |
411 | if (actual_psize < 0) | 419 | if (actual_psize < 0) |
412 | return; | 420 | actual_psize = psize; |
413 | 421 | ||
414 | /* Update the HPTE */ | 422 | /* Update the HPTE */ |
415 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | | 423 | hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) | |
@@ -437,21 +445,27 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, | |||
437 | hpte_v = hptep->v; | 445 | hpte_v = hptep->v; |
438 | 446 | ||
439 | actual_psize = hpte_actual_psize(hptep, psize); | 447 | actual_psize = hpte_actual_psize(hptep, psize); |
448 | /* | ||
449 | * We need to invalidate the TLB always because hpte_remove doesn't do | ||
450 | * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less | ||
451 | * random entry from it. When we do that we don't invalidate the TLB | ||
452 | * (hpte_remove) because we assume the old translation is still | ||
453 | * technically "valid". | ||
454 | */ | ||
440 | if (actual_psize < 0) { | 455 | if (actual_psize < 0) { |
456 | actual_psize = psize; | ||
441 | native_unlock_hpte(hptep); | 457 | native_unlock_hpte(hptep); |
442 | local_irq_restore(flags); | 458 | goto err_out; |
443 | return; | ||
444 | } | 459 | } |
445 | /* Even if we miss, we need to invalidate the TLB */ | ||
446 | if (!HPTE_V_COMPARE(hpte_v, want_v)) | 460 | if (!HPTE_V_COMPARE(hpte_v, want_v)) |
447 | native_unlock_hpte(hptep); | 461 | native_unlock_hpte(hptep); |
448 | else | 462 | else |
449 | /* Invalidate the hpte. NOTE: this also unlocks it */ | 463 | /* Invalidate the hpte. NOTE: this also unlocks it */ |
450 | hptep->v = 0; | 464 | hptep->v = 0; |
451 | 465 | ||
466 | err_out: | ||
452 | /* Invalidate the TLB */ | 467 | /* Invalidate the TLB */ |
453 | tlbie(vpn, psize, actual_psize, ssize, local); | 468 | tlbie(vpn, psize, actual_psize, ssize, local); |
454 | |||
455 | local_irq_restore(flags); | 469 | local_irq_restore(flags); |
456 | } | 470 | } |
457 | 471 | ||
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 88ac0eeaadde..e303a6d74e3a 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/signal.h> | 34 | #include <linux/signal.h> |
35 | #include <linux/memblock.h> | 35 | #include <linux/memblock.h> |
36 | #include <linux/context_tracking.h> | ||
36 | 37 | ||
37 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
38 | #include <asm/pgtable.h> | 39 | #include <asm/pgtable.h> |
@@ -954,6 +955,7 @@ void hash_failure_debug(unsigned long ea, unsigned long access, | |||
954 | */ | 955 | */ |
955 | int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | 956 | int hash_page(unsigned long ea, unsigned long access, unsigned long trap) |
956 | { | 957 | { |
958 | enum ctx_state prev_state = exception_enter(); | ||
957 | pgd_t *pgdir; | 959 | pgd_t *pgdir; |
958 | unsigned long vsid; | 960 | unsigned long vsid; |
959 | struct mm_struct *mm; | 961 | struct mm_struct *mm; |
@@ -973,7 +975,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
973 | mm = current->mm; | 975 | mm = current->mm; |
974 | if (! mm) { | 976 | if (! mm) { |
975 | DBG_LOW(" user region with no mm !\n"); | 977 | DBG_LOW(" user region with no mm !\n"); |
976 | return 1; | 978 | rc = 1; |
979 | goto bail; | ||
977 | } | 980 | } |
978 | psize = get_slice_psize(mm, ea); | 981 | psize = get_slice_psize(mm, ea); |
979 | ssize = user_segment_size(ea); | 982 | ssize = user_segment_size(ea); |
@@ -992,19 +995,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
992 | /* Not a valid range | 995 | /* Not a valid range |
993 | * Send the problem up to do_page_fault | 996 | * Send the problem up to do_page_fault |
994 | */ | 997 | */ |
995 | return 1; | 998 | rc = 1; |
999 | goto bail; | ||
996 | } | 1000 | } |
997 | DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); | 1001 | DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); |
998 | 1002 | ||
999 | /* Bad address. */ | 1003 | /* Bad address. */ |
1000 | if (!vsid) { | 1004 | if (!vsid) { |
1001 | DBG_LOW("Bad address!\n"); | 1005 | DBG_LOW("Bad address!\n"); |
1002 | return 1; | 1006 | rc = 1; |
1007 | goto bail; | ||
1003 | } | 1008 | } |
1004 | /* Get pgdir */ | 1009 | /* Get pgdir */ |
1005 | pgdir = mm->pgd; | 1010 | pgdir = mm->pgd; |
1006 | if (pgdir == NULL) | 1011 | if (pgdir == NULL) { |
1007 | return 1; | 1012 | rc = 1; |
1013 | goto bail; | ||
1014 | } | ||
1008 | 1015 | ||
1009 | /* Check CPU locality */ | 1016 | /* Check CPU locality */ |
1010 | tmp = cpumask_of(smp_processor_id()); | 1017 | tmp = cpumask_of(smp_processor_id()); |
@@ -1027,7 +1034,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1027 | ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift); | 1034 | ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift); |
1028 | if (ptep == NULL || !pte_present(*ptep)) { | 1035 | if (ptep == NULL || !pte_present(*ptep)) { |
1029 | DBG_LOW(" no PTE !\n"); | 1036 | DBG_LOW(" no PTE !\n"); |
1030 | return 1; | 1037 | rc = 1; |
1038 | goto bail; | ||
1031 | } | 1039 | } |
1032 | 1040 | ||
1033 | /* Add _PAGE_PRESENT to the required access perm */ | 1041 | /* Add _PAGE_PRESENT to the required access perm */ |
@@ -1038,13 +1046,16 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1038 | */ | 1046 | */ |
1039 | if (access & ~pte_val(*ptep)) { | 1047 | if (access & ~pte_val(*ptep)) { |
1040 | DBG_LOW(" no access !\n"); | 1048 | DBG_LOW(" no access !\n"); |
1041 | return 1; | 1049 | rc = 1; |
1050 | goto bail; | ||
1042 | } | 1051 | } |
1043 | 1052 | ||
1044 | #ifdef CONFIG_HUGETLB_PAGE | 1053 | #ifdef CONFIG_HUGETLB_PAGE |
1045 | if (hugeshift) | 1054 | if (hugeshift) { |
1046 | return __hash_page_huge(ea, access, vsid, ptep, trap, local, | 1055 | rc = __hash_page_huge(ea, access, vsid, ptep, trap, local, |
1047 | ssize, hugeshift, psize); | 1056 | ssize, hugeshift, psize); |
1057 | goto bail; | ||
1058 | } | ||
1048 | #endif /* CONFIG_HUGETLB_PAGE */ | 1059 | #endif /* CONFIG_HUGETLB_PAGE */ |
1049 | 1060 | ||
1050 | #ifndef CONFIG_PPC_64K_PAGES | 1061 | #ifndef CONFIG_PPC_64K_PAGES |
@@ -1124,6 +1135,9 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
1124 | pte_val(*(ptep + PTRS_PER_PTE))); | 1135 | pte_val(*(ptep + PTRS_PER_PTE))); |
1125 | #endif | 1136 | #endif |
1126 | DBG_LOW(" -> rc=%d\n", rc); | 1137 | DBG_LOW(" -> rc=%d\n", rc); |
1138 | |||
1139 | bail: | ||
1140 | exception_exit(prev_state); | ||
1127 | return rc; | 1141 | return rc; |
1128 | } | 1142 | } |
1129 | EXPORT_SYMBOL_GPL(hash_page); | 1143 | EXPORT_SYMBOL_GPL(hash_page); |
@@ -1259,6 +1273,8 @@ void flush_hash_range(unsigned long number, int local) | |||
1259 | */ | 1273 | */ |
1260 | void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) | 1274 | void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) |
1261 | { | 1275 | { |
1276 | enum ctx_state prev_state = exception_enter(); | ||
1277 | |||
1262 | if (user_mode(regs)) { | 1278 | if (user_mode(regs)) { |
1263 | #ifdef CONFIG_PPC_SUBPAGE_PROT | 1279 | #ifdef CONFIG_PPC_SUBPAGE_PROT |
1264 | if (rc == -2) | 1280 | if (rc == -2) |
@@ -1268,6 +1284,8 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) | |||
1268 | _exception(SIGBUS, regs, BUS_ADRERR, address); | 1284 | _exception(SIGBUS, regs, BUS_ADRERR, address); |
1269 | } else | 1285 | } else |
1270 | bad_page_fault(regs, address, SIGBUS); | 1286 | bad_page_fault(regs, address, SIGBUS); |
1287 | |||
1288 | exception_exit(prev_state); | ||
1271 | } | 1289 | } |
1272 | 1290 | ||
1273 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn, | 1291 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn, |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 237c8e5f2640..77fdd2cef33b 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -592,8 +592,14 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, | |||
592 | do { | 592 | do { |
593 | pmd = pmd_offset(pud, addr); | 593 | pmd = pmd_offset(pud, addr); |
594 | next = pmd_addr_end(addr, end); | 594 | next = pmd_addr_end(addr, end); |
595 | if (pmd_none_or_clear_bad(pmd)) | 595 | if (!is_hugepd(pmd)) { |
596 | /* | ||
597 | * if it is not hugepd pointer, we should already find | ||
598 | * it cleared. | ||
599 | */ | ||
600 | WARN_ON(!pmd_none_or_clear_bad(pmd)); | ||
596 | continue; | 601 | continue; |
602 | } | ||
597 | #ifdef CONFIG_PPC_FSL_BOOK3E | 603 | #ifdef CONFIG_PPC_FSL_BOOK3E |
598 | /* | 604 | /* |
599 | * Increment next by the size of the huge mapping since | 605 | * Increment next by the size of the huge mapping since |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index c2787bf779ca..a90b9c458990 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -215,7 +215,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start, | |||
215 | unsigned long phys) | 215 | unsigned long phys) |
216 | { | 216 | { |
217 | int mapped = htab_bolt_mapping(start, start + page_size, phys, | 217 | int mapped = htab_bolt_mapping(start, start + page_size, phys, |
218 | PAGE_KERNEL, mmu_vmemmap_psize, | 218 | pgprot_val(PAGE_KERNEL), |
219 | mmu_vmemmap_psize, | ||
219 | mmu_kernel_ssize); | 220 | mmu_kernel_ssize); |
220 | BUG_ON(mapped < 0); | 221 | BUG_ON(mapped < 0); |
221 | } | 222 | } |
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index c627843c5b2e..29c6482890c8 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -13,11 +13,13 @@ | |||
13 | #include <linux/perf_event.h> | 13 | #include <linux/perf_event.h> |
14 | #include <linux/percpu.h> | 14 | #include <linux/percpu.h> |
15 | #include <linux/hardirq.h> | 15 | #include <linux/hardirq.h> |
16 | #include <linux/uaccess.h> | ||
16 | #include <asm/reg.h> | 17 | #include <asm/reg.h> |
17 | #include <asm/pmc.h> | 18 | #include <asm/pmc.h> |
18 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
19 | #include <asm/firmware.h> | 20 | #include <asm/firmware.h> |
20 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
22 | #include <asm/code-patching.h> | ||
21 | 23 | ||
22 | #define BHRB_MAX_ENTRIES 32 | 24 | #define BHRB_MAX_ENTRIES 32 |
23 | #define BHRB_TARGET 0x0000000000000002 | 25 | #define BHRB_TARGET 0x0000000000000002 |
@@ -100,11 +102,15 @@ static inline int siar_valid(struct pt_regs *regs) | |||
100 | return 1; | 102 | return 1; |
101 | } | 103 | } |
102 | 104 | ||
105 | static inline void power_pmu_bhrb_enable(struct perf_event *event) {} | ||
106 | static inline void power_pmu_bhrb_disable(struct perf_event *event) {} | ||
107 | void power_pmu_flush_branch_stack(void) {} | ||
108 | static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} | ||
103 | #endif /* CONFIG_PPC32 */ | 109 | #endif /* CONFIG_PPC32 */ |
104 | 110 | ||
105 | static bool regs_use_siar(struct pt_regs *regs) | 111 | static bool regs_use_siar(struct pt_regs *regs) |
106 | { | 112 | { |
107 | return !!(regs->result & 1); | 113 | return !!regs->result; |
108 | } | 114 | } |
109 | 115 | ||
110 | /* | 116 | /* |
@@ -130,22 +136,30 @@ static inline unsigned long perf_ip_adjust(struct pt_regs *regs) | |||
130 | * If we're not doing instruction sampling, give them the SDAR | 136 | * If we're not doing instruction sampling, give them the SDAR |
131 | * (sampled data address). If we are doing instruction sampling, then | 137 | * (sampled data address). If we are doing instruction sampling, then |
132 | * only give them the SDAR if it corresponds to the instruction | 138 | * only give them the SDAR if it corresponds to the instruction |
133 | * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC or | 139 | * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC, the |
134 | * the [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA. | 140 | * [POWER7P_]MMCRA_SDAR_VALID bit in MMCRA, or the SDAR_VALID bit in SIER. |
135 | */ | 141 | */ |
136 | static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) | 142 | static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) |
137 | { | 143 | { |
138 | unsigned long mmcra = regs->dsisr; | 144 | unsigned long mmcra = regs->dsisr; |
139 | unsigned long sdsync; | 145 | bool sdar_valid; |
140 | 146 | ||
141 | if (ppmu->flags & PPMU_SIAR_VALID) | 147 | if (ppmu->flags & PPMU_HAS_SIER) |
142 | sdsync = POWER7P_MMCRA_SDAR_VALID; | 148 | sdar_valid = regs->dar & SIER_SDAR_VALID; |
143 | else if (ppmu->flags & PPMU_ALT_SIPR) | 149 | else { |
144 | sdsync = POWER6_MMCRA_SDSYNC; | 150 | unsigned long sdsync; |
145 | else | 151 | |
146 | sdsync = MMCRA_SDSYNC; | 152 | if (ppmu->flags & PPMU_SIAR_VALID) |
153 | sdsync = POWER7P_MMCRA_SDAR_VALID; | ||
154 | else if (ppmu->flags & PPMU_ALT_SIPR) | ||
155 | sdsync = POWER6_MMCRA_SDSYNC; | ||
156 | else | ||
157 | sdsync = MMCRA_SDSYNC; | ||
147 | 158 | ||
148 | if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync)) | 159 | sdar_valid = mmcra & sdsync; |
160 | } | ||
161 | |||
162 | if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid) | ||
149 | *addrp = mfspr(SPRN_SDAR); | 163 | *addrp = mfspr(SPRN_SDAR); |
150 | } | 164 | } |
151 | 165 | ||
@@ -175,11 +189,6 @@ static bool regs_sipr(struct pt_regs *regs) | |||
175 | return !!(regs->dsisr & sipr); | 189 | return !!(regs->dsisr & sipr); |
176 | } | 190 | } |
177 | 191 | ||
178 | static bool regs_no_sipr(struct pt_regs *regs) | ||
179 | { | ||
180 | return !!(regs->result & 2); | ||
181 | } | ||
182 | |||
183 | static inline u32 perf_flags_from_msr(struct pt_regs *regs) | 192 | static inline u32 perf_flags_from_msr(struct pt_regs *regs) |
184 | { | 193 | { |
185 | if (regs->msr & MSR_PR) | 194 | if (regs->msr & MSR_PR) |
@@ -202,7 +211,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs) | |||
202 | * SIAR which should give slightly more reliable | 211 | * SIAR which should give slightly more reliable |
203 | * results | 212 | * results |
204 | */ | 213 | */ |
205 | if (regs_no_sipr(regs)) { | 214 | if (ppmu->flags & PPMU_NO_SIPR) { |
206 | unsigned long siar = mfspr(SPRN_SIAR); | 215 | unsigned long siar = mfspr(SPRN_SIAR); |
207 | if (siar >= PAGE_OFFSET) | 216 | if (siar >= PAGE_OFFSET) |
208 | return PERF_RECORD_MISC_KERNEL; | 217 | return PERF_RECORD_MISC_KERNEL; |
@@ -233,22 +242,9 @@ static inline void perf_read_regs(struct pt_regs *regs) | |||
233 | int use_siar; | 242 | int use_siar; |
234 | 243 | ||
235 | regs->dsisr = mmcra; | 244 | regs->dsisr = mmcra; |
236 | regs->result = 0; | ||
237 | |||
238 | if (ppmu->flags & PPMU_NO_SIPR) | ||
239 | regs->result |= 2; | ||
240 | |||
241 | /* | ||
242 | * On power8 if we're in random sampling mode, the SIER is updated. | ||
243 | * If we're in continuous sampling mode, we don't have SIPR. | ||
244 | */ | ||
245 | if (ppmu->flags & PPMU_HAS_SIER) { | ||
246 | if (marked) | ||
247 | regs->dar = mfspr(SPRN_SIER); | ||
248 | else | ||
249 | regs->result |= 2; | ||
250 | } | ||
251 | 245 | ||
246 | if (ppmu->flags & PPMU_HAS_SIER) | ||
247 | regs->dar = mfspr(SPRN_SIER); | ||
252 | 248 | ||
253 | /* | 249 | /* |
254 | * If this isn't a PMU exception (eg a software event) the SIAR is | 250 | * If this isn't a PMU exception (eg a software event) the SIAR is |
@@ -273,12 +269,12 @@ static inline void perf_read_regs(struct pt_regs *regs) | |||
273 | use_siar = 1; | 269 | use_siar = 1; |
274 | else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) | 270 | else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) |
275 | use_siar = 0; | 271 | use_siar = 0; |
276 | else if (!regs_no_sipr(regs) && regs_sipr(regs)) | 272 | else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs)) |
277 | use_siar = 0; | 273 | use_siar = 0; |
278 | else | 274 | else |
279 | use_siar = 1; | 275 | use_siar = 1; |
280 | 276 | ||
281 | regs->result |= use_siar; | 277 | regs->result = use_siar; |
282 | } | 278 | } |
283 | 279 | ||
284 | /* | 280 | /* |
@@ -302,12 +298,170 @@ static inline int siar_valid(struct pt_regs *regs) | |||
302 | unsigned long mmcra = regs->dsisr; | 298 | unsigned long mmcra = regs->dsisr; |
303 | int marked = mmcra & MMCRA_SAMPLE_ENABLE; | 299 | int marked = mmcra & MMCRA_SAMPLE_ENABLE; |
304 | 300 | ||
305 | if ((ppmu->flags & PPMU_SIAR_VALID) && marked) | 301 | if (marked) { |
306 | return mmcra & POWER7P_MMCRA_SIAR_VALID; | 302 | if (ppmu->flags & PPMU_HAS_SIER) |
303 | return regs->dar & SIER_SIAR_VALID; | ||
304 | |||
305 | if (ppmu->flags & PPMU_SIAR_VALID) | ||
306 | return mmcra & POWER7P_MMCRA_SIAR_VALID; | ||
307 | } | ||
307 | 308 | ||
308 | return 1; | 309 | return 1; |
309 | } | 310 | } |
310 | 311 | ||
312 | |||
313 | /* Reset all possible BHRB entries */ | ||
314 | static void power_pmu_bhrb_reset(void) | ||
315 | { | ||
316 | asm volatile(PPC_CLRBHRB); | ||
317 | } | ||
318 | |||
319 | static void power_pmu_bhrb_enable(struct perf_event *event) | ||
320 | { | ||
321 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
322 | |||
323 | if (!ppmu->bhrb_nr) | ||
324 | return; | ||
325 | |||
326 | /* Clear BHRB if we changed task context to avoid data leaks */ | ||
327 | if (event->ctx->task && cpuhw->bhrb_context != event->ctx) { | ||
328 | power_pmu_bhrb_reset(); | ||
329 | cpuhw->bhrb_context = event->ctx; | ||
330 | } | ||
331 | cpuhw->bhrb_users++; | ||
332 | } | ||
333 | |||
334 | static void power_pmu_bhrb_disable(struct perf_event *event) | ||
335 | { | ||
336 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
337 | |||
338 | if (!ppmu->bhrb_nr) | ||
339 | return; | ||
340 | |||
341 | cpuhw->bhrb_users--; | ||
342 | WARN_ON_ONCE(cpuhw->bhrb_users < 0); | ||
343 | |||
344 | if (!cpuhw->disabled && !cpuhw->bhrb_users) { | ||
345 | /* BHRB cannot be turned off when other | ||
346 | * events are active on the PMU. | ||
347 | */ | ||
348 | |||
349 | /* avoid stale pointer */ | ||
350 | cpuhw->bhrb_context = NULL; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | /* Called from ctxsw to prevent one process's branch entries to | ||
355 | * mingle with the other process's entries during context switch. | ||
356 | */ | ||
357 | void power_pmu_flush_branch_stack(void) | ||
358 | { | ||
359 | if (ppmu->bhrb_nr) | ||
360 | power_pmu_bhrb_reset(); | ||
361 | } | ||
362 | /* Calculate the to address for a branch */ | ||
363 | static __u64 power_pmu_bhrb_to(u64 addr) | ||
364 | { | ||
365 | unsigned int instr; | ||
366 | int ret; | ||
367 | __u64 target; | ||
368 | |||
369 | if (is_kernel_addr(addr)) | ||
370 | return branch_target((unsigned int *)addr); | ||
371 | |||
372 | /* Userspace: need copy instruction here then translate it */ | ||
373 | pagefault_disable(); | ||
374 | ret = __get_user_inatomic(instr, (unsigned int __user *)addr); | ||
375 | if (ret) { | ||
376 | pagefault_enable(); | ||
377 | return 0; | ||
378 | } | ||
379 | pagefault_enable(); | ||
380 | |||
381 | target = branch_target(&instr); | ||
382 | if ((!target) || (instr & BRANCH_ABSOLUTE)) | ||
383 | return target; | ||
384 | |||
385 | /* Translate relative branch target from kernel to user address */ | ||
386 | return target - (unsigned long)&instr + addr; | ||
387 | } | ||
388 | |||
389 | /* Processing BHRB entries */ | ||
390 | void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) | ||
391 | { | ||
392 | u64 val; | ||
393 | u64 addr; | ||
394 | int r_index, u_index, pred; | ||
395 | |||
396 | r_index = 0; | ||
397 | u_index = 0; | ||
398 | while (r_index < ppmu->bhrb_nr) { | ||
399 | /* Assembly read function */ | ||
400 | val = read_bhrb(r_index++); | ||
401 | if (!val) | ||
402 | /* Terminal marker: End of valid BHRB entries */ | ||
403 | break; | ||
404 | else { | ||
405 | addr = val & BHRB_EA; | ||
406 | pred = val & BHRB_PREDICTION; | ||
407 | |||
408 | if (!addr) | ||
409 | /* invalid entry */ | ||
410 | continue; | ||
411 | |||
412 | /* Branches are read most recent first (ie. mfbhrb 0 is | ||
413 | * the most recent branch). | ||
414 | * There are two types of valid entries: | ||
415 | * 1) a target entry which is the to address of a | ||
416 | * computed goto like a blr,bctr,btar. The next | ||
417 | * entry read from the bhrb will be branch | ||
418 | * corresponding to this target (ie. the actual | ||
419 | * blr/bctr/btar instruction). | ||
420 | * 2) a from address which is an actual branch. If a | ||
421 | * target entry proceeds this, then this is the | ||
422 | * matching branch for that target. If this is not | ||
423 | * following a target entry, then this is a branch | ||
424 | * where the target is given as an immediate field | ||
425 | * in the instruction (ie. an i or b form branch). | ||
426 | * In this case we need to read the instruction from | ||
427 | * memory to determine the target/to address. | ||
428 | */ | ||
429 | |||
430 | if (val & BHRB_TARGET) { | ||
431 | /* Target branches use two entries | ||
432 | * (ie. computed gotos/XL form) | ||
433 | */ | ||
434 | cpuhw->bhrb_entries[u_index].to = addr; | ||
435 | cpuhw->bhrb_entries[u_index].mispred = pred; | ||
436 | cpuhw->bhrb_entries[u_index].predicted = ~pred; | ||
437 | |||
438 | /* Get from address in next entry */ | ||
439 | val = read_bhrb(r_index++); | ||
440 | addr = val & BHRB_EA; | ||
441 | if (val & BHRB_TARGET) { | ||
442 | /* Shouldn't have two targets in a | ||
443 | row.. Reset index and try again */ | ||
444 | r_index--; | ||
445 | addr = 0; | ||
446 | } | ||
447 | cpuhw->bhrb_entries[u_index].from = addr; | ||
448 | } else { | ||
449 | /* Branches to immediate field | ||
450 | (ie I or B form) */ | ||
451 | cpuhw->bhrb_entries[u_index].from = addr; | ||
452 | cpuhw->bhrb_entries[u_index].to = | ||
453 | power_pmu_bhrb_to(addr); | ||
454 | cpuhw->bhrb_entries[u_index].mispred = pred; | ||
455 | cpuhw->bhrb_entries[u_index].predicted = ~pred; | ||
456 | } | ||
457 | u_index++; | ||
458 | |||
459 | } | ||
460 | } | ||
461 | cpuhw->bhrb_stack.nr = u_index; | ||
462 | return; | ||
463 | } | ||
464 | |||
311 | #endif /* CONFIG_PPC64 */ | 465 | #endif /* CONFIG_PPC64 */ |
312 | 466 | ||
313 | static void perf_event_interrupt(struct pt_regs *regs); | 467 | static void perf_event_interrupt(struct pt_regs *regs); |
@@ -904,47 +1058,6 @@ static int collect_events(struct perf_event *group, int max_count, | |||
904 | return n; | 1058 | return n; |
905 | } | 1059 | } |
906 | 1060 | ||
907 | /* Reset all possible BHRB entries */ | ||
908 | static void power_pmu_bhrb_reset(void) | ||
909 | { | ||
910 | asm volatile(PPC_CLRBHRB); | ||
911 | } | ||
912 | |||
913 | void power_pmu_bhrb_enable(struct perf_event *event) | ||
914 | { | ||
915 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
916 | |||
917 | if (!ppmu->bhrb_nr) | ||
918 | return; | ||
919 | |||
920 | /* Clear BHRB if we changed task context to avoid data leaks */ | ||
921 | if (event->ctx->task && cpuhw->bhrb_context != event->ctx) { | ||
922 | power_pmu_bhrb_reset(); | ||
923 | cpuhw->bhrb_context = event->ctx; | ||
924 | } | ||
925 | cpuhw->bhrb_users++; | ||
926 | } | ||
927 | |||
928 | void power_pmu_bhrb_disable(struct perf_event *event) | ||
929 | { | ||
930 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | ||
931 | |||
932 | if (!ppmu->bhrb_nr) | ||
933 | return; | ||
934 | |||
935 | cpuhw->bhrb_users--; | ||
936 | WARN_ON_ONCE(cpuhw->bhrb_users < 0); | ||
937 | |||
938 | if (!cpuhw->disabled && !cpuhw->bhrb_users) { | ||
939 | /* BHRB cannot be turned off when other | ||
940 | * events are active on the PMU. | ||
941 | */ | ||
942 | |||
943 | /* avoid stale pointer */ | ||
944 | cpuhw->bhrb_context = NULL; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | /* | 1061 | /* |
949 | * Add a event to the PMU. | 1062 | * Add a event to the PMU. |
950 | * If all events are not already frozen, then we disable and | 1063 | * If all events are not already frozen, then we disable and |
@@ -1180,15 +1293,6 @@ int power_pmu_commit_txn(struct pmu *pmu) | |||
1180 | return 0; | 1293 | return 0; |
1181 | } | 1294 | } |
1182 | 1295 | ||
1183 | /* Called from ctxsw to prevent one process's branch entries to | ||
1184 | * mingle with the other process's entries during context switch. | ||
1185 | */ | ||
1186 | void power_pmu_flush_branch_stack(void) | ||
1187 | { | ||
1188 | if (ppmu->bhrb_nr) | ||
1189 | power_pmu_bhrb_reset(); | ||
1190 | } | ||
1191 | |||
1192 | /* | 1296 | /* |
1193 | * Return 1 if we might be able to put event on a limited PMC, | 1297 | * Return 1 if we might be able to put event on a limited PMC, |
1194 | * or 0 if not. | 1298 | * or 0 if not. |
@@ -1458,77 +1562,6 @@ struct pmu power_pmu = { | |||
1458 | .flush_branch_stack = power_pmu_flush_branch_stack, | 1562 | .flush_branch_stack = power_pmu_flush_branch_stack, |
1459 | }; | 1563 | }; |
1460 | 1564 | ||
1461 | /* Processing BHRB entries */ | ||
1462 | void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) | ||
1463 | { | ||
1464 | u64 val; | ||
1465 | u64 addr; | ||
1466 | int r_index, u_index, target, pred; | ||
1467 | |||
1468 | r_index = 0; | ||
1469 | u_index = 0; | ||
1470 | while (r_index < ppmu->bhrb_nr) { | ||
1471 | /* Assembly read function */ | ||
1472 | val = read_bhrb(r_index); | ||
1473 | |||
1474 | /* Terminal marker: End of valid BHRB entries */ | ||
1475 | if (val == 0) { | ||
1476 | break; | ||
1477 | } else { | ||
1478 | /* BHRB field break up */ | ||
1479 | addr = val & BHRB_EA; | ||
1480 | pred = val & BHRB_PREDICTION; | ||
1481 | target = val & BHRB_TARGET; | ||
1482 | |||
1483 | /* Probable Missed entry: Not applicable for POWER8 */ | ||
1484 | if ((addr == 0) && (target == 0) && (pred == 1)) { | ||
1485 | r_index++; | ||
1486 | continue; | ||
1487 | } | ||
1488 | |||
1489 | /* Real Missed entry: Power8 based missed entry */ | ||
1490 | if ((addr == 0) && (target == 1) && (pred == 1)) { | ||
1491 | r_index++; | ||
1492 | continue; | ||
1493 | } | ||
1494 | |||
1495 | /* Reserved condition: Not a valid entry */ | ||
1496 | if ((addr == 0) && (target == 1) && (pred == 0)) { | ||
1497 | r_index++; | ||
1498 | continue; | ||
1499 | } | ||
1500 | |||
1501 | /* Is a target address */ | ||
1502 | if (val & BHRB_TARGET) { | ||
1503 | /* First address cannot be a target address */ | ||
1504 | if (r_index == 0) { | ||
1505 | r_index++; | ||
1506 | continue; | ||
1507 | } | ||
1508 | |||
1509 | /* Update target address for the previous entry */ | ||
1510 | cpuhw->bhrb_entries[u_index - 1].to = addr; | ||
1511 | cpuhw->bhrb_entries[u_index - 1].mispred = pred; | ||
1512 | cpuhw->bhrb_entries[u_index - 1].predicted = ~pred; | ||
1513 | |||
1514 | /* Dont increment u_index */ | ||
1515 | r_index++; | ||
1516 | } else { | ||
1517 | /* Update address, flags for current entry */ | ||
1518 | cpuhw->bhrb_entries[u_index].from = addr; | ||
1519 | cpuhw->bhrb_entries[u_index].mispred = pred; | ||
1520 | cpuhw->bhrb_entries[u_index].predicted = ~pred; | ||
1521 | |||
1522 | /* Successfully popullated one entry */ | ||
1523 | u_index++; | ||
1524 | r_index++; | ||
1525 | } | ||
1526 | } | ||
1527 | } | ||
1528 | cpuhw->bhrb_stack.nr = u_index; | ||
1529 | return; | ||
1530 | } | ||
1531 | |||
1532 | /* | 1565 | /* |
1533 | * A counter has overflowed; update its count and record | 1566 | * A counter has overflowed; update its count and record |
1534 | * things if requested. Note that interrupts are hard-disabled | 1567 | * things if requested. Note that interrupts are hard-disabled |
@@ -1725,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs) | |||
1725 | } | 1758 | } |
1726 | } | 1759 | } |
1727 | } | 1760 | } |
1728 | if ((!found) && printk_ratelimit()) | 1761 | if (!found && !nmi && printk_ratelimit()) |
1729 | printk(KERN_WARNING "Can't find PMC that caused IRQ\n"); | 1762 | printk(KERN_WARNING "Can't find PMC that caused IRQ\n"); |
1730 | 1763 | ||
1731 | /* | 1764 | /* |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index a881232a3cce..b62aab3e22ec 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -128,7 +128,7 @@ config PPC_RTAS_DAEMON | |||
128 | 128 | ||
129 | config RTAS_PROC | 129 | config RTAS_PROC |
130 | bool "Proc interface to RTAS" | 130 | bool "Proc interface to RTAS" |
131 | depends on PPC_RTAS | 131 | depends on PPC_RTAS && PROC_FS |
132 | default y | 132 | default y |
133 | 133 | ||
134 | config RTAS_FLASH | 134 | config RTAS_FLASH |
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index d3e840d643af..c24684c818ab 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig | |||
@@ -6,6 +6,7 @@ config PPC_POWERNV | |||
6 | select PPC_ICP_NATIVE | 6 | select PPC_ICP_NATIVE |
7 | select PPC_P7_NAP | 7 | select PPC_P7_NAP |
8 | select PPC_PCI_CHOICE if EMBEDDED | 8 | select PPC_PCI_CHOICE if EMBEDDED |
9 | select EPAPR_BOOT | ||
9 | default y | 10 | default y |
10 | 11 | ||
11 | config POWERNV_MSI | 12 | config POWERNV_MSI |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index ade4463226c6..628c564ceadb 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/slab.h> | ||
18 | #include <asm/opal.h> | 19 | #include <asm/opal.h> |
19 | #include <asm/firmware.h> | 20 | #include <asm/firmware.h> |
20 | 21 | ||
@@ -28,6 +29,8 @@ struct opal { | |||
28 | static struct device_node *opal_node; | 29 | static struct device_node *opal_node; |
29 | static DEFINE_SPINLOCK(opal_write_lock); | 30 | static DEFINE_SPINLOCK(opal_write_lock); |
30 | extern u64 opal_mc_secondary_handler[]; | 31 | extern u64 opal_mc_secondary_handler[]; |
32 | static unsigned int *opal_irqs; | ||
33 | static unsigned int opal_irq_count; | ||
31 | 34 | ||
32 | int __init early_init_dt_scan_opal(unsigned long node, | 35 | int __init early_init_dt_scan_opal(unsigned long node, |
33 | const char *uname, int depth, void *data) | 36 | const char *uname, int depth, void *data) |
@@ -53,7 +56,11 @@ int __init early_init_dt_scan_opal(unsigned long node, | |||
53 | opal.entry, entryp, entrysz); | 56 | opal.entry, entryp, entrysz); |
54 | 57 | ||
55 | powerpc_firmware_features |= FW_FEATURE_OPAL; | 58 | powerpc_firmware_features |= FW_FEATURE_OPAL; |
56 | if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { | 59 | if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { |
60 | powerpc_firmware_features |= FW_FEATURE_OPALv2; | ||
61 | powerpc_firmware_features |= FW_FEATURE_OPALv3; | ||
62 | printk("OPAL V3 detected !\n"); | ||
63 | } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { | ||
57 | powerpc_firmware_features |= FW_FEATURE_OPALv2; | 64 | powerpc_firmware_features |= FW_FEATURE_OPALv2; |
58 | printk("OPAL V2 detected !\n"); | 65 | printk("OPAL V2 detected !\n"); |
59 | } else { | 66 | } else { |
@@ -144,6 +151,13 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) | |||
144 | rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { | 151 | rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { |
145 | len = total_len; | 152 | len = total_len; |
146 | rc = opal_console_write(vtermno, &len, data); | 153 | rc = opal_console_write(vtermno, &len, data); |
154 | |||
155 | /* Closed or other error drop */ | ||
156 | if (rc != OPAL_SUCCESS && rc != OPAL_BUSY && | ||
157 | rc != OPAL_BUSY_EVENT) { | ||
158 | written = total_len; | ||
159 | break; | ||
160 | } | ||
147 | if (rc == OPAL_SUCCESS) { | 161 | if (rc == OPAL_SUCCESS) { |
148 | total_len -= len; | 162 | total_len -= len; |
149 | data += len; | 163 | data += len; |
@@ -316,6 +330,8 @@ static int __init opal_init(void) | |||
316 | irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); | 330 | irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); |
317 | pr_debug("opal: Found %d interrupts reserved for OPAL\n", | 331 | pr_debug("opal: Found %d interrupts reserved for OPAL\n", |
318 | irqs ? (irqlen / 4) : 0); | 332 | irqs ? (irqlen / 4) : 0); |
333 | opal_irq_count = irqlen / 4; | ||
334 | opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL); | ||
319 | for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { | 335 | for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { |
320 | unsigned int hwirq = be32_to_cpup(irqs); | 336 | unsigned int hwirq = be32_to_cpup(irqs); |
321 | unsigned int irq = irq_create_mapping(NULL, hwirq); | 337 | unsigned int irq = irq_create_mapping(NULL, hwirq); |
@@ -327,7 +343,19 @@ static int __init opal_init(void) | |||
327 | if (rc) | 343 | if (rc) |
328 | pr_warning("opal: Error %d requesting irq %d" | 344 | pr_warning("opal: Error %d requesting irq %d" |
329 | " (0x%x)\n", rc, irq, hwirq); | 345 | " (0x%x)\n", rc, irq, hwirq); |
346 | opal_irqs[i] = irq; | ||
330 | } | 347 | } |
331 | return 0; | 348 | return 0; |
332 | } | 349 | } |
333 | subsys_initcall(opal_init); | 350 | subsys_initcall(opal_init); |
351 | |||
352 | void opal_shutdown(void) | ||
353 | { | ||
354 | unsigned int i; | ||
355 | |||
356 | for (i = 0; i < opal_irq_count; i++) { | ||
357 | if (opal_irqs[i]) | ||
358 | free_irq(opal_irqs[i], 0); | ||
359 | opal_irqs[i] = 0; | ||
360 | } | ||
361 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 1da578b7c1bf..9c9d15e4cdf2 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -68,16 +68,6 @@ define_pe_printk_level(pe_err, KERN_ERR); | |||
68 | define_pe_printk_level(pe_warn, KERN_WARNING); | 68 | define_pe_printk_level(pe_warn, KERN_WARNING); |
69 | define_pe_printk_level(pe_info, KERN_INFO); | 69 | define_pe_printk_level(pe_info, KERN_INFO); |
70 | 70 | ||
71 | static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) | ||
72 | { | ||
73 | struct device_node *np; | ||
74 | |||
75 | np = pci_device_to_OF_node(dev); | ||
76 | if (!np) | ||
77 | return NULL; | ||
78 | return PCI_DN(np); | ||
79 | } | ||
80 | |||
81 | static int pnv_ioda_alloc_pe(struct pnv_phb *phb) | 71 | static int pnv_ioda_alloc_pe(struct pnv_phb *phb) |
82 | { | 72 | { |
83 | unsigned long pe; | 73 | unsigned long pe; |
@@ -110,7 +100,7 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev) | |||
110 | { | 100 | { |
111 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 101 | struct pci_controller *hose = pci_bus_to_host(dev->bus); |
112 | struct pnv_phb *phb = hose->private_data; | 102 | struct pnv_phb *phb = hose->private_data; |
113 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | 103 | struct pci_dn *pdn = pci_get_pdn(dev); |
114 | 104 | ||
115 | if (!pdn) | 105 | if (!pdn) |
116 | return NULL; | 106 | return NULL; |
@@ -173,7 +163,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) | |||
173 | 163 | ||
174 | /* Add to all parents PELT-V */ | 164 | /* Add to all parents PELT-V */ |
175 | while (parent) { | 165 | while (parent) { |
176 | struct pci_dn *pdn = pnv_ioda_get_pdn(parent); | 166 | struct pci_dn *pdn = pci_get_pdn(parent); |
177 | if (pdn && pdn->pe_number != IODA_INVALID_PE) { | 167 | if (pdn && pdn->pe_number != IODA_INVALID_PE) { |
178 | rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, | 168 | rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, |
179 | pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); | 169 | pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); |
@@ -252,7 +242,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) | |||
252 | { | 242 | { |
253 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | 243 | struct pci_controller *hose = pci_bus_to_host(dev->bus); |
254 | struct pnv_phb *phb = hose->private_data; | 244 | struct pnv_phb *phb = hose->private_data; |
255 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | 245 | struct pci_dn *pdn = pci_get_pdn(dev); |
256 | struct pnv_ioda_pe *pe; | 246 | struct pnv_ioda_pe *pe; |
257 | int pe_num; | 247 | int pe_num; |
258 | 248 | ||
@@ -323,7 +313,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) | |||
323 | struct pci_dev *dev; | 313 | struct pci_dev *dev; |
324 | 314 | ||
325 | list_for_each_entry(dev, &bus->devices, bus_list) { | 315 | list_for_each_entry(dev, &bus->devices, bus_list) { |
326 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | 316 | struct pci_dn *pdn = pci_get_pdn(dev); |
327 | 317 | ||
328 | if (pdn == NULL) { | 318 | if (pdn == NULL) { |
329 | pr_warn("%s: No device node associated with device !\n", | 319 | pr_warn("%s: No device node associated with device !\n", |
@@ -436,7 +426,7 @@ static void pnv_pci_ioda_setup_PEs(void) | |||
436 | 426 | ||
437 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev) | 427 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev) |
438 | { | 428 | { |
439 | struct pci_dn *pdn = pnv_ioda_get_pdn(pdev); | 429 | struct pci_dn *pdn = pci_get_pdn(pdev); |
440 | struct pnv_ioda_pe *pe; | 430 | struct pnv_ioda_pe *pe; |
441 | 431 | ||
442 | /* | 432 | /* |
@@ -768,6 +758,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
768 | unsigned int is_64, struct msi_msg *msg) | 758 | unsigned int is_64, struct msi_msg *msg) |
769 | { | 759 | { |
770 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | 760 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); |
761 | struct pci_dn *pdn = pci_get_pdn(dev); | ||
771 | struct irq_data *idata; | 762 | struct irq_data *idata; |
772 | struct irq_chip *ichip; | 763 | struct irq_chip *ichip; |
773 | unsigned int xive_num = hwirq - phb->msi_base; | 764 | unsigned int xive_num = hwirq - phb->msi_base; |
@@ -783,6 +774,10 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
783 | if (pe->mve_number < 0) | 774 | if (pe->mve_number < 0) |
784 | return -ENXIO; | 775 | return -ENXIO; |
785 | 776 | ||
777 | /* Force 32-bit MSI on some broken devices */ | ||
778 | if (pdn && pdn->force_32bit_msi) | ||
779 | is_64 = 0; | ||
780 | |||
786 | /* Assign XIVE to PE */ | 781 | /* Assign XIVE to PE */ |
787 | rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); | 782 | rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); |
788 | if (rc) { | 783 | if (rc) { |
@@ -1035,7 +1030,7 @@ static int pnv_pci_enable_device_hook(struct pci_dev *dev) | |||
1035 | if (!phb->initialized) | 1030 | if (!phb->initialized) |
1036 | return 0; | 1031 | return 0; |
1037 | 1032 | ||
1038 | pdn = pnv_ioda_get_pdn(dev); | 1033 | pdn = pci_get_pdn(dev); |
1039 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) | 1034 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) |
1040 | return -EINVAL; | 1035 | return -EINVAL; |
1041 | 1036 | ||
@@ -1048,6 +1043,12 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, | |||
1048 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; | 1043 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; |
1049 | } | 1044 | } |
1050 | 1045 | ||
1046 | static void pnv_pci_ioda_shutdown(struct pnv_phb *phb) | ||
1047 | { | ||
1048 | opal_pci_reset(phb->opal_id, OPAL_PCI_IODA_TABLE_RESET, | ||
1049 | OPAL_ASSERT_RESET); | ||
1050 | } | ||
1051 | |||
1051 | void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) | 1052 | void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) |
1052 | { | 1053 | { |
1053 | struct pci_controller *hose; | 1054 | struct pci_controller *hose; |
@@ -1178,6 +1179,9 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) | |||
1178 | /* Setup TCEs */ | 1179 | /* Setup TCEs */ |
1179 | phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; | 1180 | phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; |
1180 | 1181 | ||
1182 | /* Setup shutdown function for kexec */ | ||
1183 | phb->shutdown = pnv_pci_ioda_shutdown; | ||
1184 | |||
1181 | /* Setup MSI support */ | 1185 | /* Setup MSI support */ |
1182 | pnv_pci_init_ioda_msis(phb); | 1186 | pnv_pci_init_ioda_msis(phb); |
1183 | 1187 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 55dfca844ddf..277343cc6a3d 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -47,6 +47,10 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | |||
47 | { | 47 | { |
48 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 48 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
49 | struct pnv_phb *phb = hose->private_data; | 49 | struct pnv_phb *phb = hose->private_data; |
50 | struct pci_dn *pdn = pci_get_pdn(pdev); | ||
51 | |||
52 | if (pdn && pdn->force_32bit_msi && !phb->msi32_support) | ||
53 | return -ENODEV; | ||
50 | 54 | ||
51 | return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; | 55 | return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; |
52 | } | 56 | } |
@@ -367,7 +371,7 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) | |||
367 | while (npages--) | 371 | while (npages--) |
368 | *(tcep++) = 0; | 372 | *(tcep++) = 0; |
369 | 373 | ||
370 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) | 374 | if (tbl->it_type & TCE_PCI_SWINV_FREE) |
371 | pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); | 375 | pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); |
372 | } | 376 | } |
373 | 377 | ||
@@ -450,6 +454,18 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev) | |||
450 | pnv_pci_dma_fallback_setup(hose, pdev); | 454 | pnv_pci_dma_fallback_setup(hose, pdev); |
451 | } | 455 | } |
452 | 456 | ||
457 | void pnv_pci_shutdown(void) | ||
458 | { | ||
459 | struct pci_controller *hose; | ||
460 | |||
461 | list_for_each_entry(hose, &hose_list, list_node) { | ||
462 | struct pnv_phb *phb = hose->private_data; | ||
463 | |||
464 | if (phb && phb->shutdown) | ||
465 | phb->shutdown(phb); | ||
466 | } | ||
467 | } | ||
468 | |||
453 | /* Fixup wrong class code in p7ioc and p8 root complex */ | 469 | /* Fixup wrong class code in p7ioc and p8 root complex */ |
454 | static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) | 470 | static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) |
455 | { | 471 | { |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 48dc4bb856a1..25d76c4df50b 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -86,6 +86,7 @@ struct pnv_phb { | |||
86 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); | 86 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); |
87 | void (*fixup_phb)(struct pci_controller *hose); | 87 | void (*fixup_phb)(struct pci_controller *hose); |
88 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); | 88 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); |
89 | void (*shutdown)(struct pnv_phb *phb); | ||
89 | 90 | ||
90 | union { | 91 | union { |
91 | struct { | 92 | struct { |
@@ -158,4 +159,5 @@ extern void pnv_pci_init_ioda_hub(struct device_node *np); | |||
158 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); | 159 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); |
159 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | 160 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, |
160 | u64 *startp, u64 *endp); | 161 | u64 *startp, u64 *endp); |
162 | |||
161 | #endif /* __POWERNV_PCI_H */ | 163 | #endif /* __POWERNV_PCI_H */ |
diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 8a9df7f9667e..a1c6f83fc391 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h | |||
@@ -9,8 +9,10 @@ static inline void pnv_smp_init(void) { } | |||
9 | 9 | ||
10 | #ifdef CONFIG_PCI | 10 | #ifdef CONFIG_PCI |
11 | extern void pnv_pci_init(void); | 11 | extern void pnv_pci_init(void); |
12 | extern void pnv_pci_shutdown(void); | ||
12 | #else | 13 | #else |
13 | static inline void pnv_pci_init(void) { } | 14 | static inline void pnv_pci_init(void) { } |
15 | static inline void pnv_pci_shutdown(void) { } | ||
14 | #endif | 16 | #endif |
15 | 17 | ||
16 | #endif /* _POWERNV_H */ | 18 | #endif /* _POWERNV_H */ |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index db1ad1c8f68f..d4459bfc92f7 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
@@ -78,7 +78,9 @@ static void pnv_show_cpuinfo(struct seq_file *m) | |||
78 | if (root) | 78 | if (root) |
79 | model = of_get_property(root, "model", NULL); | 79 | model = of_get_property(root, "model", NULL); |
80 | seq_printf(m, "machine\t\t: PowerNV %s\n", model); | 80 | seq_printf(m, "machine\t\t: PowerNV %s\n", model); |
81 | if (firmware_has_feature(FW_FEATURE_OPALv2)) | 81 | if (firmware_has_feature(FW_FEATURE_OPALv3)) |
82 | seq_printf(m, "firmware\t: OPAL v3\n"); | ||
83 | else if (firmware_has_feature(FW_FEATURE_OPALv2)) | ||
82 | seq_printf(m, "firmware\t: OPAL v2\n"); | 84 | seq_printf(m, "firmware\t: OPAL v2\n"); |
83 | else if (firmware_has_feature(FW_FEATURE_OPAL)) | 85 | else if (firmware_has_feature(FW_FEATURE_OPAL)) |
84 | seq_printf(m, "firmware\t: OPAL v1\n"); | 86 | seq_printf(m, "firmware\t: OPAL v1\n"); |
@@ -126,6 +128,17 @@ static void pnv_progress(char *s, unsigned short hex) | |||
126 | { | 128 | { |
127 | } | 129 | } |
128 | 130 | ||
131 | static void pnv_shutdown(void) | ||
132 | { | ||
133 | /* Let the PCI code clear up IODA tables */ | ||
134 | pnv_pci_shutdown(); | ||
135 | |||
136 | /* And unregister all OPAL interrupts so they don't fire | ||
137 | * up while we kexec | ||
138 | */ | ||
139 | opal_shutdown(); | ||
140 | } | ||
141 | |||
129 | #ifdef CONFIG_KEXEC | 142 | #ifdef CONFIG_KEXEC |
130 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) | 143 | static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) |
131 | { | 144 | { |
@@ -187,6 +200,7 @@ define_machine(powernv) { | |||
187 | .init_IRQ = pnv_init_IRQ, | 200 | .init_IRQ = pnv_init_IRQ, |
188 | .show_cpuinfo = pnv_show_cpuinfo, | 201 | .show_cpuinfo = pnv_show_cpuinfo, |
189 | .progress = pnv_progress, | 202 | .progress = pnv_progress, |
203 | .machine_shutdown = pnv_shutdown, | ||
190 | .power_save = power7_idle, | 204 | .power_save = power7_idle, |
191 | .calibrate_decr = generic_calibrate_decr, | 205 | .calibrate_decr = generic_calibrate_decr, |
192 | #ifdef CONFIG_KEXEC | 206 | #ifdef CONFIG_KEXEC |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 6a3ecca5b725..88c9459c3e07 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -71,18 +71,68 @@ int pnv_smp_kick_cpu(int nr) | |||
71 | 71 | ||
72 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 72 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
73 | 73 | ||
74 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, | 74 | /* |
75 | * get them back now | 75 | * If we already started or OPALv2 is not supported, we just |
76 | * kick the CPU via the PACA | ||
76 | */ | 77 | */ |
77 | if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) { | 78 | if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2)) |
78 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); | 79 | goto kick; |
79 | rc = opal_start_cpu(pcpu, start_here); | 80 | |
81 | /* | ||
82 | * At this point, the CPU can either be spinning on the way in | ||
83 | * from kexec or be inside OPAL waiting to be started for the | ||
84 | * first time. OPAL v3 allows us to query OPAL to know if it | ||
85 | * has the CPUs, so we do that | ||
86 | */ | ||
87 | if (firmware_has_feature(FW_FEATURE_OPALv3)) { | ||
88 | uint8_t status; | ||
89 | |||
90 | rc = opal_query_cpu_status(pcpu, &status); | ||
80 | if (rc != OPAL_SUCCESS) { | 91 | if (rc != OPAL_SUCCESS) { |
81 | pr_warn("OPAL Error %ld starting CPU %d\n", | 92 | pr_warn("OPAL Error %ld querying CPU %d state\n", |
82 | rc, nr); | 93 | rc, nr); |
83 | return -ENODEV; | 94 | return -ENODEV; |
84 | } | 95 | } |
96 | |||
97 | /* | ||
98 | * Already started, just kick it, probably coming from | ||
99 | * kexec and spinning | ||
100 | */ | ||
101 | if (status == OPAL_THREAD_STARTED) | ||
102 | goto kick; | ||
103 | |||
104 | /* | ||
105 | * Available/inactive, let's kick it | ||
106 | */ | ||
107 | if (status == OPAL_THREAD_INACTIVE) { | ||
108 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", | ||
109 | nr, pcpu); | ||
110 | rc = opal_start_cpu(pcpu, start_here); | ||
111 | if (rc != OPAL_SUCCESS) { | ||
112 | pr_warn("OPAL Error %ld starting CPU %d\n", | ||
113 | rc, nr); | ||
114 | return -ENODEV; | ||
115 | } | ||
116 | } else { | ||
117 | /* | ||
118 | * An unavailable CPU (or any other unknown status) | ||
119 | * shouldn't be started. It should also | ||
120 | * not be in the possible map but currently it can | ||
121 | * happen | ||
122 | */ | ||
123 | pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" | ||
124 | " (status %d)...\n", nr, pcpu, status); | ||
125 | return -ENODEV; | ||
126 | } | ||
127 | } else { | ||
128 | /* | ||
129 | * On OPAL v2, we just kick it and hope for the best, | ||
130 | * we must not test the error from opal_start_cpu() or | ||
131 | * we would fail to get CPUs from kexec. | ||
132 | */ | ||
133 | opal_start_cpu(pcpu, start_here); | ||
85 | } | 134 | } |
135 | kick: | ||
86 | return smp_generic_kick_cpu(nr); | 136 | return smp_generic_kick_cpu(nr); |
87 | } | 137 | } |
88 | 138 | ||
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 9a0941bc4d31..4459eff7a75a 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -18,6 +18,9 @@ config PPC_PSERIES | |||
18 | select PPC_PCI_CHOICE if EXPERT | 18 | select PPC_PCI_CHOICE if EXPERT |
19 | select ZLIB_DEFLATE | 19 | select ZLIB_DEFLATE |
20 | select PPC_DOORBELL | 20 | select PPC_DOORBELL |
21 | select HAVE_CONTEXT_TRACKING | ||
22 | select HOTPLUG if SMP | ||
23 | select HOTPLUG_CPU if SMP | ||
21 | default y | 24 | default y |
22 | 25 | ||
23 | config PPC_SPLPAR | 26 | config PPC_SPLPAR |
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 19506f935737..b456b157d33d 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c | |||
@@ -83,7 +83,11 @@ static int pseries_eeh_init(void) | |||
83 | ibm_configure_pe = rtas_token("ibm,configure-pe"); | 83 | ibm_configure_pe = rtas_token("ibm,configure-pe"); |
84 | ibm_configure_bridge = rtas_token("ibm,configure-bridge"); | 84 | ibm_configure_bridge = rtas_token("ibm,configure-bridge"); |
85 | 85 | ||
86 | /* necessary sanity check */ | 86 | /* |
87 | * Necessary sanity check. We needn't check "get-config-addr-info" | ||
88 | * and its variant since the old firmware probably support address | ||
89 | * of domain/bus/slot/function for EEH RTAS operations. | ||
90 | */ | ||
87 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { | 91 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { |
88 | pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n", | 92 | pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n", |
89 | __func__); | 93 | __func__); |
@@ -102,12 +106,6 @@ static int pseries_eeh_init(void) | |||
102 | pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n", | 106 | pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n", |
103 | __func__); | 107 | __func__); |
104 | return -EINVAL; | 108 | return -EINVAL; |
105 | } else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE && | ||
106 | ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) { | ||
107 | pr_warning("%s: RTAS service <ibm,get-config-addr-info2> and " | ||
108 | "<ibm,get-config-addr-info> invalid\n", | ||
109 | __func__); | ||
110 | return -EINVAL; | ||
111 | } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && | 109 | } else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && |
112 | ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) { | 110 | ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) { |
113 | pr_warning("%s: RTAS service <ibm,configure-pe> and " | 111 | pr_warning("%s: RTAS service <ibm,configure-pe> and " |
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 420524e6f8c9..6d2f0abce6fa 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
@@ -26,26 +26,6 @@ static int query_token, change_token; | |||
26 | #define RTAS_CHANGE_MSIX_FN 4 | 26 | #define RTAS_CHANGE_MSIX_FN 4 |
27 | #define RTAS_CHANGE_32MSI_FN 5 | 27 | #define RTAS_CHANGE_32MSI_FN 5 |
28 | 28 | ||
29 | static struct pci_dn *get_pdn(struct pci_dev *pdev) | ||
30 | { | ||
31 | struct device_node *dn; | ||
32 | struct pci_dn *pdn; | ||
33 | |||
34 | dn = pci_device_to_OF_node(pdev); | ||
35 | if (!dn) { | ||
36 | dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | pdn = PCI_DN(dn); | ||
41 | if (!pdn) { | ||
42 | dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); | ||
43 | return NULL; | ||
44 | } | ||
45 | |||
46 | return pdn; | ||
47 | } | ||
48 | |||
49 | /* RTAS Helpers */ | 29 | /* RTAS Helpers */ |
50 | 30 | ||
51 | static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) | 31 | static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) |
@@ -91,7 +71,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) | |||
91 | { | 71 | { |
92 | struct pci_dn *pdn; | 72 | struct pci_dn *pdn; |
93 | 73 | ||
94 | pdn = get_pdn(pdev); | 74 | pdn = pci_get_pdn(pdev); |
95 | if (!pdn) | 75 | if (!pdn) |
96 | return; | 76 | return; |
97 | 77 | ||
@@ -152,7 +132,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) | |||
152 | struct pci_dn *pdn; | 132 | struct pci_dn *pdn; |
153 | const u32 *req_msi; | 133 | const u32 *req_msi; |
154 | 134 | ||
155 | pdn = get_pdn(pdev); | 135 | pdn = pci_get_pdn(pdev); |
156 | if (!pdn) | 136 | if (!pdn) |
157 | return -ENODEV; | 137 | return -ENODEV; |
158 | 138 | ||
@@ -394,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev) | |||
394 | return 0; | 374 | return 0; |
395 | } | 375 | } |
396 | 376 | ||
377 | static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) | ||
378 | { | ||
379 | u32 addr_hi, addr_lo; | ||
380 | |||
381 | /* | ||
382 | * We should only get in here for IODA1 configs. This is based on the | ||
383 | * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS | ||
384 | * support, and we are in a PCIe Gen2 slot. | ||
385 | */ | ||
386 | dev_info(&pdev->dev, | ||
387 | "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n"); | ||
388 | pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi); | ||
389 | addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4); | ||
390 | pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo); | ||
391 | pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0); | ||
392 | } | ||
393 | |||
397 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | 394 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) |
398 | { | 395 | { |
399 | struct pci_dn *pdn; | 396 | struct pci_dn *pdn; |
@@ -401,8 +398,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
401 | struct msi_desc *entry; | 398 | struct msi_desc *entry; |
402 | struct msi_msg msg; | 399 | struct msi_msg msg; |
403 | int nvec = nvec_in; | 400 | int nvec = nvec_in; |
401 | int use_32bit_msi_hack = 0; | ||
404 | 402 | ||
405 | pdn = get_pdn(pdev); | 403 | pdn = pci_get_pdn(pdev); |
406 | if (!pdn) | 404 | if (!pdn) |
407 | return -ENODEV; | 405 | return -ENODEV; |
408 | 406 | ||
@@ -428,15 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
428 | */ | 426 | */ |
429 | again: | 427 | again: |
430 | if (type == PCI_CAP_ID_MSI) { | 428 | if (type == PCI_CAP_ID_MSI) { |
431 | if (pdn->force_32bit_msi) | 429 | if (pdn->force_32bit_msi) { |
432 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); | 430 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); |
433 | else | 431 | if (rc < 0) { |
432 | /* | ||
433 | * We only want to run the 32 bit MSI hack below if | ||
434 | * the max bus speed is Gen2 speed | ||
435 | */ | ||
436 | if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) | ||
437 | return rc; | ||
438 | |||
439 | use_32bit_msi_hack = 1; | ||
440 | } | ||
441 | } else | ||
442 | rc = -1; | ||
443 | |||
444 | if (rc < 0) | ||
434 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); | 445 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); |
435 | 446 | ||
436 | if (rc < 0 && !pdn->force_32bit_msi) { | 447 | if (rc < 0) { |
437 | pr_debug("rtas_msi: trying the old firmware call.\n"); | 448 | pr_debug("rtas_msi: trying the old firmware call.\n"); |
438 | rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); | 449 | rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); |
439 | } | 450 | } |
451 | |||
452 | if (use_32bit_msi_hack && rc > 0) | ||
453 | rtas_hack_32bit_msi_gen2(pdev); | ||
440 | } else | 454 | } else |
441 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); | 455 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); |
442 | 456 | ||
@@ -518,12 +532,3 @@ static int rtas_msi_init(void) | |||
518 | } | 532 | } |
519 | arch_initcall(rtas_msi_init); | 533 | arch_initcall(rtas_msi_init); |
520 | 534 | ||
521 | static void quirk_radeon(struct pci_dev *dev) | ||
522 | { | ||
523 | struct pci_dn *pdn = get_pdn(dev); | ||
524 | |||
525 | if (pdn) | ||
526 | pdn->force_32bit_msi = 1; | ||
527 | } | ||
528 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon); | ||
529 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon); | ||
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index 47226e04126d..5f997e79d570 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/cpu.h> | ||
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
20 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
21 | #include <linux/stat.h> | 22 | #include <linux/stat.h> |
@@ -126,11 +127,15 @@ static ssize_t store_hibernate(struct device *dev, | |||
126 | struct device_attribute *attr, | 127 | struct device_attribute *attr, |
127 | const char *buf, size_t count) | 128 | const char *buf, size_t count) |
128 | { | 129 | { |
130 | cpumask_var_t offline_mask; | ||
129 | int rc; | 131 | int rc; |
130 | 132 | ||
131 | if (!capable(CAP_SYS_ADMIN)) | 133 | if (!capable(CAP_SYS_ADMIN)) |
132 | return -EPERM; | 134 | return -EPERM; |
133 | 135 | ||
136 | if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) | ||
137 | return -ENOMEM; | ||
138 | |||
134 | stream_id = simple_strtoul(buf, NULL, 16); | 139 | stream_id = simple_strtoul(buf, NULL, 16); |
135 | 140 | ||
136 | do { | 141 | do { |
@@ -140,15 +145,32 @@ static ssize_t store_hibernate(struct device *dev, | |||
140 | } while (rc == -EAGAIN); | 145 | } while (rc == -EAGAIN); |
141 | 146 | ||
142 | if (!rc) { | 147 | if (!rc) { |
148 | /* All present CPUs must be online */ | ||
149 | cpumask_andnot(offline_mask, cpu_present_mask, | ||
150 | cpu_online_mask); | ||
151 | rc = rtas_online_cpus_mask(offline_mask); | ||
152 | if (rc) { | ||
153 | pr_err("%s: Could not bring present CPUs online.\n", | ||
154 | __func__); | ||
155 | goto out; | ||
156 | } | ||
157 | |||
143 | stop_topology_update(); | 158 | stop_topology_update(); |
144 | rc = pm_suspend(PM_SUSPEND_MEM); | 159 | rc = pm_suspend(PM_SUSPEND_MEM); |
145 | start_topology_update(); | 160 | start_topology_update(); |
161 | |||
162 | /* Take down CPUs not online prior to suspend */ | ||
163 | if (!rtas_offline_cpus_mask(offline_mask)) | ||
164 | pr_warn("%s: Could not restore CPUs to offline " | ||
165 | "state.\n", __func__); | ||
146 | } | 166 | } |
147 | 167 | ||
148 | stream_id = 0; | 168 | stream_id = 0; |
149 | 169 | ||
150 | if (!rc) | 170 | if (!rc) |
151 | rc = count; | 171 | rc = count; |
172 | out: | ||
173 | free_cpumask_var(offline_mask); | ||
152 | return rc; | 174 | return rc; |
153 | } | 175 | } |
154 | 176 | ||
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c index 97fe82ee8633..2d3b1dd9571d 100644 --- a/arch/powerpc/platforms/wsp/ics.c +++ b/arch/powerpc/platforms/wsp/ics.c | |||
@@ -361,7 +361,7 @@ static int wsp_chip_set_affinity(struct irq_data *d, | |||
361 | xive = xive_set_server(xive, get_irq_server(ics, hw_irq)); | 361 | xive = xive_set_server(xive, get_irq_server(ics, hw_irq)); |
362 | wsp_ics_set_xive(ics, hw_irq, xive); | 362 | wsp_ics_set_xive(ics, hw_irq, xive); |
363 | 363 | ||
364 | return 0; | 364 | return IRQ_SET_MASK_OK; |
365 | } | 365 | } |
366 | 366 | ||
367 | static struct irq_chip wsp_irq_chip = { | 367 | static struct irq_chip wsp_irq_chip = { |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index b0a518e97599..99464a7bdb3b 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -64,6 +64,8 @@ endif | |||
64 | 64 | ||
65 | obj-$(CONFIG_PPC_SCOM) += scom.o | 65 | obj-$(CONFIG_PPC_SCOM) += scom.o |
66 | 66 | ||
67 | obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o | ||
68 | |||
67 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | 69 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror |
68 | 70 | ||
69 | obj-$(CONFIG_PPC_XICS) += xics/ | 71 | obj-$(CONFIG_PPC_XICS) += xics/ |
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 6e0e1005227f..9cd0e60716fe 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c | |||
@@ -81,7 +81,7 @@ int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest, | |||
81 | ev_int_set_config(src, config, prio, cpuid); | 81 | ev_int_set_config(src, config, prio, cpuid); |
82 | spin_unlock_irqrestore(&ehv_pic_lock, flags); | 82 | spin_unlock_irqrestore(&ehv_pic_lock, flags); |
83 | 83 | ||
84 | return 0; | 84 | return IRQ_SET_MASK_OK; |
85 | } | 85 | } |
86 | 86 | ||
87 | static unsigned int ehv_pic_type_to_vecpri(unsigned int type) | 87 | static unsigned int ehv_pic_type_to_vecpri(unsigned int type) |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index ee21b5e71aec..3cc2f9159ab1 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -54,7 +54,7 @@ static DEFINE_RAW_SPINLOCK(mpic_lock); | |||
54 | 54 | ||
55 | #ifdef CONFIG_PPC32 /* XXX for now */ | 55 | #ifdef CONFIG_PPC32 /* XXX for now */ |
56 | #ifdef CONFIG_IRQ_ALL_CPUS | 56 | #ifdef CONFIG_IRQ_ALL_CPUS |
57 | #define distribute_irqs (!(mpic->flags & MPIC_SINGLE_DEST_CPU)) | 57 | #define distribute_irqs (1) |
58 | #else | 58 | #else |
59 | #define distribute_irqs (0) | 59 | #define distribute_irqs (0) |
60 | #endif | 60 | #endif |
@@ -836,7 +836,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | |||
836 | mpic_physmask(mask)); | 836 | mpic_physmask(mask)); |
837 | } | 837 | } |
838 | 838 | ||
839 | return 0; | 839 | return IRQ_SET_MASK_OK; |
840 | } | 840 | } |
841 | 841 | ||
842 | static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) | 842 | static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) |
@@ -1703,7 +1703,7 @@ void mpic_setup_this_cpu(void) | |||
1703 | * it differently, then we should make sure we also change the default | 1703 | * it differently, then we should make sure we also change the default |
1704 | * values of irq_desc[].affinity in irq.c. | 1704 | * values of irq_desc[].affinity in irq.c. |
1705 | */ | 1705 | */ |
1706 | if (distribute_irqs) { | 1706 | if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) { |
1707 | for (i = 0; i < mpic->num_sources ; i++) | 1707 | for (i = 0; i < mpic->num_sources ; i++) |
1708 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), | 1708 | mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), |
1709 | mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); | 1709 | mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); |
diff --git a/arch/powerpc/sysdev/udbg_memcons.c b/arch/powerpc/sysdev/udbg_memcons.c new file mode 100644 index 000000000000..ce5a7b489e4b --- /dev/null +++ b/arch/powerpc/sysdev/udbg_memcons.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * A udbg backend which logs messages and reads input from in memory | ||
3 | * buffers. | ||
4 | * | ||
5 | * The console output can be read from memcons_output which is a | ||
6 | * circular buffer whose next write position is stored in memcons.output_pos. | ||
7 | * | ||
8 | * Input may be passed by writing into the memcons_input buffer when it is | ||
9 | * empty. The input buffer is empty when both input_pos == input_start and | ||
10 | * *input_start == '\0'. | ||
11 | * | ||
12 | * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp | ||
13 | * Copyright (C) 2013 Alistair Popple, IBM Corp | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version | ||
18 | * 2 of the License, or (at your option) any later version. | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <asm/barrier.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/processor.h> | ||
26 | #include <asm/udbg.h> | ||
27 | |||
28 | struct memcons { | ||
29 | char *output_start; | ||
30 | char *output_pos; | ||
31 | char *output_end; | ||
32 | char *input_start; | ||
33 | char *input_pos; | ||
34 | char *input_end; | ||
35 | }; | ||
36 | |||
37 | static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE]; | ||
38 | static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE]; | ||
39 | |||
40 | struct memcons memcons = { | ||
41 | .output_start = memcons_output, | ||
42 | .output_pos = memcons_output, | ||
43 | .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE], | ||
44 | .input_start = memcons_input, | ||
45 | .input_pos = memcons_input, | ||
46 | .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE], | ||
47 | }; | ||
48 | |||
49 | void memcons_putc(char c) | ||
50 | { | ||
51 | char *new_output_pos; | ||
52 | |||
53 | *memcons.output_pos = c; | ||
54 | wmb(); | ||
55 | new_output_pos = memcons.output_pos + 1; | ||
56 | if (new_output_pos >= memcons.output_end) | ||
57 | new_output_pos = memcons.output_start; | ||
58 | |||
59 | memcons.output_pos = new_output_pos; | ||
60 | } | ||
61 | |||
62 | int memcons_getc_poll(void) | ||
63 | { | ||
64 | char c; | ||
65 | char *new_input_pos; | ||
66 | |||
67 | if (*memcons.input_pos) { | ||
68 | c = *memcons.input_pos; | ||
69 | |||
70 | new_input_pos = memcons.input_pos + 1; | ||
71 | if (new_input_pos >= memcons.input_end) | ||
72 | new_input_pos = memcons.input_start; | ||
73 | else if (*new_input_pos == '\0') | ||
74 | new_input_pos = memcons.input_start; | ||
75 | |||
76 | *memcons.input_pos = '\0'; | ||
77 | wmb(); | ||
78 | memcons.input_pos = new_input_pos; | ||
79 | return c; | ||
80 | } | ||
81 | |||
82 | return -1; | ||
83 | } | ||
84 | |||
85 | int memcons_getc(void) | ||
86 | { | ||
87 | int c; | ||
88 | |||
89 | while (1) { | ||
90 | c = memcons_getc_poll(); | ||
91 | if (c == -1) | ||
92 | cpu_relax(); | ||
93 | else | ||
94 | break; | ||
95 | } | ||
96 | |||
97 | return c; | ||
98 | } | ||
99 | |||
100 | void udbg_init_memcons(void) | ||
101 | { | ||
102 | udbg_putc = memcons_putc; | ||
103 | udbg_getc = memcons_getc; | ||
104 | udbg_getc_poll = memcons_getc_poll; | ||
105 | } | ||
diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index f7e8609df0d5..39d72212655e 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c | |||
@@ -148,7 +148,7 @@ static int ics_opal_set_affinity(struct irq_data *d, | |||
148 | __func__, d->irq, hw_irq, server, rc); | 148 | __func__, d->irq, hw_irq, server, rc); |
149 | return -1; | 149 | return -1; |
150 | } | 150 | } |
151 | return 0; | 151 | return IRQ_SET_MASK_OK; |
152 | } | 152 | } |
153 | 153 | ||
154 | static struct irq_chip ics_opal_irq_chip = { | 154 | static struct irq_chip ics_opal_irq_chip = { |