diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kvm/book3s_segment.S | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 012fc9281213..87cfc1def241 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S | |||
@@ -197,6 +197,7 @@ kvmppc_interrupt: | |||
197 | /* Save guest PC and MSR */ | 197 | /* Save guest PC and MSR */ |
198 | #ifdef CONFIG_PPC64 | 198 | #ifdef CONFIG_PPC64 |
199 | BEGIN_FTR_SECTION | 199 | BEGIN_FTR_SECTION |
200 | mr r10, r12 | ||
200 | andi. r0,r12,0x2 | 201 | andi. r0,r12,0x2 |
201 | beq 1f | 202 | beq 1f |
202 | mfspr r3,SPRN_HSRR0 | 203 | mfspr r3,SPRN_HSRR0 |
@@ -322,23 +323,17 @@ no_dcbz32_off: | |||
322 | * Having set up SRR0/1 with the address where we want | 323 | * Having set up SRR0/1 with the address where we want |
323 | * to continue with relocation on (potentially in module | 324 | * to continue with relocation on (potentially in module |
324 | * space), we either just go straight there with rfi[d], | 325 | * space), we either just go straight there with rfi[d], |
325 | * or we jump to an interrupt handler with bctr if there | 326 | * or we jump to an interrupt handler if there is an |
326 | * is an interrupt to be handled first. In the latter | 327 | * interrupt to be handled first. In the latter case, |
327 | * case, the rfi[d] at the end of the interrupt handler | 328 | * the rfi[d] at the end of the interrupt handler will |
328 | * will get us back to where we want to continue. | 329 | * get us back to where we want to continue. |
329 | */ | 330 | */ |
330 | 331 | ||
331 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL | ||
332 | beq 1f | ||
333 | cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER | ||
334 | beq 1f | ||
335 | cmpwi r12, BOOK3S_INTERRUPT_PERFMON | ||
336 | 1: mtctr r12 | ||
337 | |||
338 | /* Register usage at this point: | 332 | /* Register usage at this point: |
339 | * | 333 | * |
340 | * R1 = host R1 | 334 | * R1 = host R1 |
341 | * R2 = host R2 | 335 | * R2 = host R2 |
336 | * R10 = raw exit handler id | ||
342 | * R12 = exit handler id | 337 | * R12 = exit handler id |
343 | * R13 = shadow vcpu (32-bit) or PACA (64-bit) | 338 | * R13 = shadow vcpu (32-bit) or PACA (64-bit) |
344 | * SVCPU.* = guest * | 339 | * SVCPU.* = guest * |
@@ -348,12 +343,26 @@ no_dcbz32_off: | |||
348 | PPC_LL r6, HSTATE_HOST_MSR(r13) | 343 | PPC_LL r6, HSTATE_HOST_MSR(r13) |
349 | PPC_LL r8, HSTATE_VMHANDLER(r13) | 344 | PPC_LL r8, HSTATE_VMHANDLER(r13) |
350 | 345 | ||
351 | /* Restore host msr -> SRR1 */ | 346 | #ifdef CONFIG_PPC64 |
347 | BEGIN_FTR_SECTION | ||
348 | andi. r0,r10,0x2 | ||
349 | beq 1f | ||
350 | mtspr SPRN_HSRR1, r6 | ||
351 | mtspr SPRN_HSRR0, r8 | ||
352 | END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) | ||
353 | #endif | ||
354 | 1: /* Restore host msr -> SRR1 */ | ||
352 | mtsrr1 r6 | 355 | mtsrr1 r6 |
353 | /* Load highmem handler address */ | 356 | /* Load highmem handler address */ |
354 | mtsrr0 r8 | 357 | mtsrr0 r8 |
355 | 358 | ||
356 | /* RFI into the highmem handler, or jump to interrupt handler */ | 359 | /* RFI into the highmem handler, or jump to interrupt handler */ |
357 | beqctr | 360 | cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL |
361 | beqa BOOK3S_INTERRUPT_EXTERNAL | ||
362 | cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER | ||
363 | beqa BOOK3S_INTERRUPT_DECREMENTER | ||
364 | cmpwi r12, BOOK3S_INTERRUPT_PERFMON | ||
365 | beqa BOOK3S_INTERRUPT_PERFMON | ||
366 | |||
358 | RFI | 367 | RFI |
359 | kvmppc_handler_trampoline_exit_end: | 368 | kvmppc_handler_trampoline_exit_end: |