@@ -221,6 +221,13 @@ kvmppc_primary_no_guest:
221221 li r3, 0 /* Don't wake on privileged (OS) doorbell */
222222 b kvm_do_nap
223223
224+ /*
225+ * kvm_novcpu_wakeup
226+ * Entered from kvm_start_guest if kvm_hstate.napping is set
227+ * to NAPPING_NOVCPU
228+ * r2 = kernel TOC
229+ * r13 = paca
230+ */
224231kvm_novcpu_wakeup:
225232 ld r1, HSTATE_HOST_R1(r13)
226233 ld r5, HSTATE_KVM_VCORE(r13)
@@ -230,6 +237,13 @@ kvm_novcpu_wakeup:
230237 /* check the wake reason */
231238 bl kvmppc_check_wake_reason
232239
240+ /*
241+ * Restore volatile registers since we could have called
242+ * a C routine in kvmppc_check_wake_reason.
243+ * r5 = VCORE
244+ */
245+ ld r5, HSTATE_KVM_VCORE(r13)
246+
233247 /* see if any other thread is already exiting */
234248 lwz r0, VCORE_ENTRY_EXIT(r5)
235249 cmpwi r0, 0x100
@@ -322,6 +336,11 @@ kvm_start_guest:
322336
323337 /* Check the wake reason in SRR1 to see why we got here */
324338 bl kvmppc_check_wake_reason
339+ /*
340+ * kvmppc_check_wake_reason could invoke a C routine, but we
341+ * have no volatile registers to restore when we return.
342+ */
343+
325344 cmpdi r3, 0
326345 bge kvm_no_guest
327346
@@ -881,6 +900,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
881900 cmpwi r3, 512 /* 1 microsecond */
882901 blt hdec_soon
883902
903+ deliver_guest_interrupt:
884904 ld r6, VCPU_CTR(r4)
885905 ld r7, VCPU_XER(r4)
886906
@@ -895,7 +915,6 @@ kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
895915 mtspr SPRN_SRR0, r6
896916 mtspr SPRN_SRR1, r7
897917
898- deliver_guest_interrupt:
899918 /* r11 = vcpu->arch.msr & ~MSR_HV */
900919 rldicl r11, r11, 63 - MSR_HV_LG, 1
901920 rotldi r11, r11, 1 + MSR_HV_LG
@@ -1155,10 +1174,36 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
11551174 * set, we know the host wants us out so let's do it now
11561175 */
11571176 bl kvmppc_read_intr
1177+
1178+ /*
1179+ * Restore the active volatile registers after returning from
1180+ * a C function.
1181+ */
1182+ ld r9, HSTATE_KVM_VCPU(r13)
1183+ li r12, BOOK3S_INTERRUPT_EXTERNAL
1184+
1185+ /*
1186+ * kvmppc_read_intr return codes:
1187+ *
1188+ * Exit to host (r3 > 0)
1189+ * 1 An interrupt is pending that needs to be handled by the host
1190+ * Exit guest and return to host by branching to guest_exit_cont
1191+ *
1192+ * Before returning to guest, we check if any CPU is heading out
1193+ * to the host and if so, we head out also. If no CPUs are heading
1194+ * check return values <= 0.
1195+ *
1196+ * Return to guest (r3 <= 0)
1197+ * 0 No external interrupt is pending
1198+ * -1 A guest wakeup IPI (which has now been cleared)
1199+ * In either case, we return to guest to deliver any pending
1200+ * guest interrupts.
1201+ */
1202+
11581203 cmpdi r3, 0
11591204 bgt guest_exit_cont
11601205
1161- /* Check if any CPU is heading out to the host, if so head out too */
1206+ /* Return code <= 0 */
116212074: ld r5, HSTATE_KVM_VCORE(r13)
11631208 lwz r0, VCORE_ENTRY_EXIT(r5)
11641209 cmpwi r0, 0x100
@@ -2213,10 +2258,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
22132258 ld r29, VCPU_GPR(R29)(r4)
22142259 ld r30, VCPU_GPR(R30)(r4)
22152260 ld r31, VCPU_GPR(R31)(r4)
2216-
2261+
22172262 /* Check the wake reason in SRR1 to see why we got here */
22182263 bl kvmppc_check_wake_reason
22192264
2265+ /*
2266+ * Restore volatile registers since we could have called a
2267+ * C routine in kvmppc_check_wake_reason
2268+ * r4 = VCPU
2269+ * r3 tells us whether we need to return to host or not
2270+ * WARNING: it gets checked further down:
2271+ * should not modify r3 until this check is done.
2272+ */
2273+ ld r4, HSTATE_KVM_VCPU(r13)
2274+
22202275 /* clear our bit in vcore->napping_threads */
2221227634: ld r5,HSTATE_KVM_VCORE(r13)
22222277 lbz r7,HSTATE_PTID(r13)
@@ -2230,7 +2285,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
22302285 li r0,0
22312286 stb r0,HSTATE_NAPPING(r13)
22322287
2233- /* See if the wake reason means we need to exit */
2288+ /* See if the wake reason saved in r3 means we need to exit */
22342289 stw r12, VCPU_TRAP(r4)
22352290 mr r9, r4
22362291 cmpdi r3, 0
@@ -2300,7 +2355,9 @@ machine_check_realmode:
23002355 *
23012356 * Also sets r12 to the interrupt vector for any interrupt that needs
23022357 * to be handled now by the host (0x500 for external interrupt), or zero.
2303- * Modifies r0, r6, r7, r8.
2358+ * Modifies all volatile registers (since it may call a C function).
2359+ * This routine calls kvmppc_read_intr, a C function, if an external
2360+ * interrupt is pending.
23042361 */
23052362kvmppc_check_wake_reason:
23062363 mfspr r6, SPRN_SRR1
@@ -2310,8 +2367,7 @@ FTR_SECTION_ELSE
23102367 rlwinm r6, r6, 45 -31 , 0xe /* P7 wake reason field is 3 bits */
23112368ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)
23122369 cmpwi r6, 8 /* was it an external interrupt? */
2313- li r12, BOOK3S_INTERRUPT_EXTERNAL
2314- beq kvmppc_read_intr /* if so, see what it was */
2370+ beq 7f /* if so, see what it was */
23152371 li r3, 0
23162372 li r12, 0
23172373 cmpwi r6, 6 /* was it the decrementer? */
@@ -2350,83 +2406,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
23502406 li r3, 1
23512407 blr
23522408
2353- /*
2354- * Determine what sort of external interrupt is pending (if any).
2355- * Returns:
2356- * 0 if no interrupt is pending
2357- * 1 if an interrupt is pending that needs to be handled by the host
2358- * -1 if there was a guest wakeup IPI (which has now been cleared)
2359- * Modifies r0, r6, r7, r8, returns value in r3.
2360- */
2361- kvmppc_read_intr:
2362- /* see if a host IPI is pending */
2363- li r3, 1
2364- lbz r0, HSTATE_HOST_IPI(r13)
2365- cmpwi r0, 0
2366- bne 1f
2367-
2368- /* Now read the interrupt from the ICP */
2369- ld r6, HSTATE_XICS_PHYS(r13)
2370- li r7, XICS_XIRR
2371- cmpdi r6, 0
2372- beq- 1f
2373- lwzcix r0, r6, r7
2374- /*
2375- * Save XIRR for later. Since we get in in reverse endian on LE
2376- * systems, save it byte reversed and fetch it back in host endian.
2377- */
2378- li r3, HSTATE_SAVED_XIRR
2379- STWX_BE r0, r3, r13
2380- #ifdef __LITTLE_ENDIAN__
2381- lwz r3, HSTATE_SAVED_XIRR(r13)
2382- #else
2383- mr r3, r0
2384- #endif
2385- rlwinm. r3, r3, 0 , 0xffffff
2386- sync
2387- beq 1f /* if nothing pending in the ICP */
2388-
2389- /* We found something in the ICP...
2390- *
2391- * If it's not an IPI, stash it in the PACA and return to
2392- * the host, we don't (yet) handle directing real external
2393- * interrupts directly to the guest
2394- */
2395- cmpwi r3, XICS_IPI /* if there is, is it an IPI? */
2396- bne 42f
2397-
2398- /* It's an IPI, clear the MFRR and EOI it */
2399- li r3, 0xff
2400- li r8, XICS_MFRR
2401- stbcix r3, r6, r8 /* clear the IPI */
2402- stwcix r0, r6, r7 /* EOI it */
2403- sync
2404-
2405- /* We need to re-check host IPI now in case it got set in the
2406- * meantime. If it's clear, we bounce the interrupt to the
2407- * guest
2408- */
2409- lbz r0, HSTATE_HOST_IPI(r13)
2410- cmpwi r0, 0
2411- bne- 43f
2412-
2413- /* OK, it's an IPI for us */
2414- li r12, 0
2415- li r3, -1
2416- 1: blr
2417-
2418- 42: /* It's not an IPI and it's for the host. We saved a copy of XIRR in
2419- * the PACA earlier, it will be picked up by the host ICP driver
2420- */
2421- li r3, 1
2422- b 1b
2423-
2424- 43: /* We raced with the host, we need to resend that IPI, bummer */
2425- li r0, IPI_PRIORITY
2426- stbcix r0, r6, r8 /* set the IPI */
2427- sync
2428- li r3, 1
2429- b 1b
2409+ /* external interrupt - create a stack frame so we can call C */
2410+ 7: mflr r0
2411+ std r0, PPC_LR_STKOFF(r1)
2412+ stdu r1, -PPC_MIN_STKFRM(r1)
2413+ bl kvmppc_read_intr
2414+ nop
2415+ li r12, BOOK3S_INTERRUPT_EXTERNAL
2416+ ld r0, PPC_MIN_STKFRM+PPC_LR_STKOFF(r1)
2417+ addi r1, r1, PPC_MIN_STKFRM
2418+ mtlr r0
2419+ blr
24302420
24312421/*
24322422 * Save away FP, VMX and VSX registers.
0 commit comments