diff options
| -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: |
