diff options
-rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index bd739fed26e3..0d8712a835d2 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
@@ -163,12 +163,6 @@ _GLOBAL(pnv_powersave_common) | |||
163 | std r9,_MSR(r1) | 163 | std r9,_MSR(r1) |
164 | std r1,PACAR1(r13) | 164 | std r1,PACAR1(r13) |
165 | 165 | ||
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 | /* | 166 | /* |
173 | * Go to real mode to do the nap, as required by the architecture. | 167 | * 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, | 168 | * Also, we need to be in real mode before setting hwthread_state, |
@@ -185,6 +179,26 @@ _GLOBAL(pnv_powersave_common) | |||
185 | 179 | ||
186 | .globl pnv_enter_arch207_idle_mode | 180 | .globl pnv_enter_arch207_idle_mode |
187 | pnv_enter_arch207_idle_mode: | 181 | pnv_enter_arch207_idle_mode: |
182 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
183 | /* Tell KVM we're entering idle */ | ||
184 | li r4,KVM_HWTHREAD_IN_IDLE | ||
185 | /******************************************************/ | ||
186 | /* N O T E W E L L ! ! ! N O T E W E L L */ | ||
187 | /* The following store to HSTATE_HWTHREAD_STATE(r13) */ | ||
188 | /* MUST occur in real mode, i.e. with the MMU off, */ | ||
189 | /* and the MMU must stay off until we clear this flag */ | ||
190 | /* and test HSTATE_HWTHREAD_REQ(r13) in the system */ | ||
191 | /* reset interrupt vector in exceptions-64s.S. */ | ||
192 | /* The reason is that another thread can switch the */ | ||
193 | /* MMU to a guest context whenever this flag is set */ | ||
194 | /* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on, */ | ||
195 | /* that would potentially cause this thread to start */ | ||
196 | /* executing instructions from guest memory in */ | ||
197 | /* hypervisor mode, leading to a host crash or data */ | ||
198 | /* corruption, or worse. */ | ||
199 | /******************************************************/ | ||
200 | stb r4,HSTATE_HWTHREAD_STATE(r13) | ||
201 | #endif | ||
188 | stb r3,PACA_THREAD_IDLE_STATE(r13) | 202 | stb r3,PACA_THREAD_IDLE_STATE(r13) |
189 | cmpwi cr3,r3,PNV_THREAD_SLEEP | 203 | cmpwi cr3,r3,PNV_THREAD_SLEEP |
190 | bge cr3,2f | 204 | bge cr3,2f |
@@ -250,6 +264,12 @@ enter_winkle: | |||
250 | * r3 - requested stop state | 264 | * r3 - requested stop state |
251 | */ | 265 | */ |
252 | power_enter_stop: | 266 | power_enter_stop: |
267 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
268 | /* Tell KVM we're entering idle */ | ||
269 | li r4,KVM_HWTHREAD_IN_IDLE | ||
270 | /* DO THIS IN REAL MODE! See comment above. */ | ||
271 | stb r4,HSTATE_HWTHREAD_STATE(r13) | ||
272 | #endif | ||
253 | /* | 273 | /* |
254 | * Check if the requested state is a deep idle state. | 274 | * Check if the requested state is a deep idle state. |
255 | */ | 275 | */ |