diff options
Diffstat (limited to 'arch/powerpc/kernel')
| -rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 50 | ||||
| -rw-r--r-- | arch/powerpc/kernel/hw_breakpoint.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 35 | ||||
| -rw-r--r-- | arch/powerpc/kernel/process.c | 2 |
4 files changed, 60 insertions, 29 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index f129408c6022..08ba447a4b3d 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -95,19 +95,35 @@ __start_interrupts: | |||
| 95 | /* No virt vectors corresponding with 0x0..0x100 */ | 95 | /* No virt vectors corresponding with 0x0..0x100 */ |
| 96 | EXC_VIRT_NONE(0x4000, 0x4100) | 96 | EXC_VIRT_NONE(0x4000, 0x4100) |
| 97 | 97 | ||
| 98 | EXC_REAL_BEGIN(system_reset, 0x100, 0x200) | 98 | |
| 99 | SET_SCRATCH0(r13) | ||
| 100 | #ifdef CONFIG_PPC_P7_NAP | 99 | #ifdef CONFIG_PPC_P7_NAP |
| 101 | BEGIN_FTR_SECTION | 100 | /* |
| 102 | /* Running native on arch 2.06 or later, check if we are | 101 | * If running native on arch 2.06 or later, check if we are waking up |
| 103 | * waking up from nap/sleep/winkle. | 102 | * from nap/sleep/winkle, and branch to idle handler. |
| 104 | */ | 103 | */ |
| 105 | mfspr r13,SPRN_SRR1 | 104 | #define IDLETEST(n) \ |
| 106 | rlwinm. r13,r13,47-31,30,31 | 105 | BEGIN_FTR_SECTION ; \ |
| 107 | beq 9f | 106 | mfspr r10,SPRN_SRR1 ; \ |
| 107 | rlwinm. r10,r10,47-31,30,31 ; \ | ||
| 108 | beq- 1f ; \ | ||
| 109 | cmpwi cr3,r10,2 ; \ | ||
| 110 | BRANCH_TO_COMMON(r10, system_reset_idle_common) ; \ | ||
| 111 | 1: \ | ||
| 112 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) | ||
| 113 | #else | ||
| 114 | #define IDLETEST NOTEST | ||
| 115 | #endif | ||
| 108 | 116 | ||
| 109 | cmpwi cr3,r13,2 | 117 | EXC_REAL_BEGIN(system_reset, 0x100, 0x200) |
| 110 | GET_PACA(r13) | 118 | SET_SCRATCH0(r13) |
| 119 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, | ||
| 120 | IDLETEST, 0x100) | ||
| 121 | |||
| 122 | EXC_REAL_END(system_reset, 0x100, 0x200) | ||
| 123 | EXC_VIRT_NONE(0x4100, 0x4200) | ||
| 124 | |||
| 125 | #ifdef CONFIG_PPC_P7_NAP | ||
| 126 | EXC_COMMON_BEGIN(system_reset_idle_common) | ||
| 111 | bl pnv_restore_hyp_resource | 127 | bl pnv_restore_hyp_resource |
| 112 | 128 | ||
| 113 | li r0,PNV_THREAD_RUNNING | 129 | li r0,PNV_THREAD_RUNNING |
| @@ -130,14 +146,8 @@ BEGIN_FTR_SECTION | |||
| 130 | blt cr3,2f | 146 | blt cr3,2f |
| 131 | b pnv_wakeup_loss | 147 | b pnv_wakeup_loss |
| 132 | 2: b pnv_wakeup_noloss | 148 | 2: b pnv_wakeup_noloss |
| 149 | #endif | ||
| 133 | 150 | ||
| 134 | 9: | ||
| 135 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) | ||
| 136 | #endif /* CONFIG_PPC_P7_NAP */ | ||
| 137 | EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, | ||
| 138 | NOTEST, 0x100) | ||
| 139 | EXC_REAL_END(system_reset, 0x100, 0x200) | ||
| 140 | EXC_VIRT_NONE(0x4100, 0x4200) | ||
| 141 | EXC_COMMON(system_reset_common, 0x100, system_reset_exception) | 151 | EXC_COMMON(system_reset_common, 0x100, system_reset_exception) |
| 142 | 152 | ||
| 143 | #ifdef CONFIG_PPC_PSERIES | 153 | #ifdef CONFIG_PPC_PSERIES |
| @@ -817,10 +827,8 @@ EXC_VIRT(trap_0b, 0x4b00, 0x4c00, 0xb00) | |||
| 817 | TRAMP_KVM(PACA_EXGEN, 0xb00) | 827 | TRAMP_KVM(PACA_EXGEN, 0xb00) |
| 818 | EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) | 828 | EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) |
| 819 | 829 | ||
| 820 | 830 | #define LOAD_SYSCALL_HANDLER(reg) \ | |
| 821 | #define LOAD_SYSCALL_HANDLER(reg) \ | 831 | __LOAD_HANDLER(reg, system_call_common) |
| 822 | ld reg,PACAKBASE(r13); \ | ||
| 823 | ori reg,reg,(ABS_ADDR(system_call_common))@l; | ||
| 824 | 832 | ||
| 825 | /* Syscall routine is used twice, in reloc-off and reloc-on paths */ | 833 | /* Syscall routine is used twice, in reloc-off and reloc-on paths */ |
| 826 | #define SYSCALL_PSERIES_1 \ | 834 | #define SYSCALL_PSERIES_1 \ |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 9781c69eae57..03d089b3ed72 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
| @@ -275,7 +275,7 @@ int hw_breakpoint_handler(struct die_args *args) | |||
| 275 | if (!stepped) { | 275 | if (!stepped) { |
| 276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " | 276 | WARN(1, "Unable to handle hardware breakpoint. Breakpoint at " |
| 277 | "0x%lx will be disabled.", info->address); | 277 | "0x%lx will be disabled.", info->address); |
| 278 | perf_event_disable(bp); | 278 | perf_event_disable_inatomic(bp); |
| 279 | goto out; | 279 | goto out; |
| 280 | } | 280 | } |
| 281 | /* | 281 | /* |
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index bd739fed26e3..72dac0b58061 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
| @@ -90,6 +90,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) | |||
| 90 | * Threads will spin in HMT_LOW until the lock bit is cleared. | 90 | * Threads will spin in HMT_LOW until the lock bit is cleared. |
| 91 | * r14 - pointer to core_idle_state | 91 | * r14 - pointer to core_idle_state |
| 92 | * r15 - used to load contents of core_idle_state | 92 | * r15 - used to load contents of core_idle_state |
| 93 | * r9 - used as a temporary variable | ||
| 93 | */ | 94 | */ |
| 94 | 95 | ||
| 95 | core_idle_lock_held: | 96 | core_idle_lock_held: |
| @@ -99,6 +100,8 @@ core_idle_lock_held: | |||
| 99 | bne 3b | 100 | bne 3b |
| 100 | HMT_MEDIUM | 101 | HMT_MEDIUM |
| 101 | lwarx r15,0,r14 | 102 | lwarx r15,0,r14 |
| 103 | andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT | ||
| 104 | bne core_idle_lock_held | ||
| 102 | blr | 105 | blr |
| 103 | 106 | ||
| 104 | /* | 107 | /* |
| @@ -163,12 +166,6 @@ _GLOBAL(pnv_powersave_common) | |||
| 163 | std r9,_MSR(r1) | 166 | std r9,_MSR(r1) |
| 164 | std r1,PACAR1(r13) | 167 | std r1,PACAR1(r13) |
| 165 | 168 | ||
| 166 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
| 167 | /* Tell KVM we're entering idle */ | ||
| 168 | li r4,KVM_HWTHREAD_IN_IDLE | ||
| 169 | stb r4,HSTATE_HWTHREAD_STATE(r13) | ||
| 170 | #endif | ||
| 171 | |||
| 172 | /* | 169 | /* |
| 173 | * Go to real mode to do the nap, as required by the architecture. | 170 | * Go to real mode to do the nap, as required by the architecture. |
| 174 | * Also, we need to be in real mode before setting hwthread_state, | 171 | * Also, we need to be in real mode before setting hwthread_state, |
| @@ -185,6 +182,26 @@ _GLOBAL(pnv_powersave_common) | |||
| 185 | 182 | ||
| 186 | .globl pnv_enter_arch207_idle_mode | 183 | .globl pnv_enter_arch207_idle_mode |
| 187 | pnv_enter_arch207_idle_mode: | 184 | pnv_enter_arch207_idle_mode: |
| 185 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
| 186 | /* Tell KVM we're entering idle */ | ||
| 187 | li r4,KVM_HWTHREAD_IN_IDLE | ||
| 188 | /******************************************************/ | ||
| 189 | /* N O T E W E L L ! ! ! N O T E W E L L */ | ||
| 190 | /* The following store to HSTATE_HWTHREAD_STATE(r13) */ | ||
| 191 | /* MUST occur in real mode, i.e. with the MMU off, */ | ||
| 192 | /* and the MMU must stay off until we clear this flag */ | ||
| 193 | /* and test HSTATE_HWTHREAD_REQ(r13) in the system */ | ||
| 194 | /* reset interrupt vector in exceptions-64s.S. */ | ||
| 195 | /* The reason is that another thread can switch the */ | ||
| 196 | /* MMU to a guest context whenever this flag is set */ | ||
| 197 | /* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on, */ | ||
| 198 | /* that would potentially cause this thread to start */ | ||
| 199 | /* executing instructions from guest memory in */ | ||
| 200 | /* hypervisor mode, leading to a host crash or data */ | ||
| 201 | /* corruption, or worse. */ | ||
| 202 | /******************************************************/ | ||
| 203 | stb r4,HSTATE_HWTHREAD_STATE(r13) | ||
| 204 | #endif | ||
| 188 | stb r3,PACA_THREAD_IDLE_STATE(r13) | 205 | stb r3,PACA_THREAD_IDLE_STATE(r13) |
| 189 | cmpwi cr3,r3,PNV_THREAD_SLEEP | 206 | cmpwi cr3,r3,PNV_THREAD_SLEEP |
| 190 | bge cr3,2f | 207 | bge cr3,2f |
| @@ -250,6 +267,12 @@ enter_winkle: | |||
| 250 | * r3 - requested stop state | 267 | * r3 - requested stop state |
| 251 | */ | 268 | */ |
| 252 | power_enter_stop: | 269 | power_enter_stop: |
| 270 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
| 271 | /* Tell KVM we're entering idle */ | ||
| 272 | li r4,KVM_HWTHREAD_IN_IDLE | ||
| 273 | /* DO THIS IN REAL MODE! See comment above. */ | ||
| 274 | stb r4,HSTATE_HWTHREAD_STATE(r13) | ||
| 275 | #endif | ||
| 253 | /* | 276 | /* |
| 254 | * Check if the requested state is a deep idle state. | 277 | * Check if the requested state is a deep idle state. |
| 255 | */ | 278 | */ |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9e7c10fe205f..ce6dc61b15b2 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -1012,7 +1012,7 @@ void restore_tm_state(struct pt_regs *regs) | |||
| 1012 | /* Ensure that restore_math() will restore */ | 1012 | /* Ensure that restore_math() will restore */ |
| 1013 | if (msr_diff & MSR_FP) | 1013 | if (msr_diff & MSR_FP) |
| 1014 | current->thread.load_fp = 1; | 1014 | current->thread.load_fp = 1; |
| 1015 | #ifdef CONFIG_ALIVEC | 1015 | #ifdef CONFIG_ALTIVEC |
| 1016 | if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC) | 1016 | if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC) |
| 1017 | current->thread.load_vec = 1; | 1017 | current->thread.load_vec = 1; |
| 1018 | #endif | 1018 | #endif |
