From: David Gibson <david@gibson.dropbear.id.au>
To: Paul Mackerras <paulus@ozlabs.org>
Cc: linuxppc-dev@ozlabs.org, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v5 06/33] KVM: PPC: Book3S HV: Simplify real-mode interrupt handling
Date: Tue, 09 Oct 2018 00:05:44 +0000 [thread overview]
Message-ID: <20181009000544.GE7004@umbus.fritz.box> (raw)
In-Reply-To: <1538976679-1363-7-git-send-email-paulus@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 12008 bytes --]
On Mon, Oct 08, 2018 at 04:30:52PM +1100, Paul Mackerras wrote:
> This streamlines the first part of the code that handles a hypervisor
> interrupt that occurred in the guest. With this, all of the real-mode
> handling that occurs is done before the "guest_exit_cont" label; once
> we get to that label we are committed to exiting to host virtual mode.
> Thus the machine check and HMI real-mode handling is moved before that
> label.
>
> Also, the code to handle external interrupts is moved out of line, as
> is the code that calls kvmppc_realmode_hmi_handler().
>
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> arch/powerpc/kvm/book3s_hv_ras.c | 8 ++
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 220 ++++++++++++++++----------------
> 2 files changed, 119 insertions(+), 109 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c
> index b11043b..ee564b6 100644
> --- a/arch/powerpc/kvm/book3s_hv_ras.c
> +++ b/arch/powerpc/kvm/book3s_hv_ras.c
> @@ -331,5 +331,13 @@ long kvmppc_realmode_hmi_handler(void)
> } else {
> wait_for_tb_resync();
> }
> +
> + /*
> + * Reset tb_offset_applied so the guest exit code won't try
> + * to subtract the previous timebase offset from the timebase.
> + */
> + if (local_paca->kvm_hstate.kvm_vcore)
> + local_paca->kvm_hstate.kvm_vcore->tb_offset_applied = 0;
> +
> return 0;
> }
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index 5b2ae34..fc360b5 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -1018,8 +1018,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
> no_xive:
> #endif /* CONFIG_KVM_XICS */
>
> -deliver_guest_interrupt:
> -kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
> +deliver_guest_interrupt: /* r4 = vcpu, r13 = paca */
> /* Check if we can deliver an external or decrementer interrupt now */
> ld r0, VCPU_PENDING_EXC(r4)
> BEGIN_FTR_SECTION
> @@ -1269,18 +1268,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
> std r3, VCPU_CTR(r9)
> std r4, VCPU_XER(r9)
>
> -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> - /* For softpatch interrupt, go off and do TM instruction emulation */
> - cmpwi r12, BOOK3S_INTERRUPT_HV_SOFTPATCH
> - beq kvmppc_tm_emul
> -#endif
> + /* Save more register state */
> + mfdar r3
> + mfdsisr r4
> + std r3, VCPU_DAR(r9)
> + stw r4, VCPU_DSISR(r9)
>
> /* If this is a page table miss then see if it's theirs or ours */
> cmpwi r12, BOOK3S_INTERRUPT_H_DATA_STORAGE
> beq kvmppc_hdsi
> + std r3, VCPU_FAULT_DAR(r9)
> + stw r4, VCPU_FAULT_DSISR(r9)
> cmpwi r12, BOOK3S_INTERRUPT_H_INST_STORAGE
> beq kvmppc_hisi
>
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + /* For softpatch interrupt, go off and do TM instruction emulation */
> + cmpwi r12, BOOK3S_INTERRUPT_HV_SOFTPATCH
> + beq kvmppc_tm_emul
> +#endif
> +
> /* See if this is a leftover HDEC interrupt */
> cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER
> bne 2f
> @@ -1303,7 +1310,7 @@ BEGIN_FTR_SECTION
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> lbz r0, HSTATE_HOST_IPI(r13)
> cmpwi r0, 0
> - beq 4f
> + beq maybe_reenter_guest
> b guest_exit_cont
> 3:
> /* If it's a hypervisor facility unavailable interrupt, save HFSCR */
> @@ -1315,82 +1322,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> 14:
> /* External interrupt ? */
> cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
> - bne+ guest_exit_cont
> -
> - /* External interrupt, first check for host_ipi. If this is
> - * set, we know the host wants us out so let's do it now
> - */
> - bl kvmppc_read_intr
> -
> - /*
> - * Restore the active volatile registers after returning from
> - * a C function.
> - */
> - ld r9, HSTATE_KVM_VCPU(r13)
> - li r12, BOOK3S_INTERRUPT_EXTERNAL
> -
> - /*
> - * kvmppc_read_intr return codes:
> - *
> - * Exit to host (r3 > 0)
> - * 1 An interrupt is pending that needs to be handled by the host
> - * Exit guest and return to host by branching to guest_exit_cont
> - *
> - * 2 Passthrough that needs completion in the host
> - * Exit guest and return to host by branching to guest_exit_cont
> - * However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD
> - * to indicate to the host to complete handling the interrupt
> - *
> - * Before returning to guest, we check if any CPU is heading out
> - * to the host and if so, we head out also. If no CPUs are heading
> - * check return values <= 0.
> - *
> - * Return to guest (r3 <= 0)
> - * 0 No external interrupt is pending
> - * -1 A guest wakeup IPI (which has now been cleared)
> - * In either case, we return to guest to deliver any pending
> - * guest interrupts.
> - *
> - * -2 A PCI passthrough external interrupt was handled
> - * (interrupt was delivered directly to guest)
> - * Return to guest to deliver any pending guest interrupts.
> - */
> -
> - cmpdi r3, 1
> - ble 1f
> -
> - /* Return code = 2 */
> - li r12, BOOK3S_INTERRUPT_HV_RM_HARD
> - stw r12, VCPU_TRAP(r9)
> - b guest_exit_cont
> -
> -1: /* Return code <= 1 */
> - cmpdi r3, 0
> - bgt guest_exit_cont
> -
> - /* Return code <= 0 */
> -4: ld r5, HSTATE_KVM_VCORE(r13)
> - lwz r0, VCORE_ENTRY_EXIT(r5)
> - cmpwi r0, 0x100
> - mr r4, r9
> - blt deliver_guest_interrupt
> -
> -guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
> - /* Save more register state */
> - mfdar r6
> - mfdsisr r7
> - std r6, VCPU_DAR(r9)
> - stw r7, VCPU_DSISR(r9)
> - /* don't overwrite fault_dar/fault_dsisr if HDSI */
> - cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE
> - beq mc_cont
> - std r6, VCPU_FAULT_DAR(r9)
> - stw r7, VCPU_FAULT_DSISR(r9)
> -
> + beq kvmppc_guest_external
> /* See if it is a machine check */
> cmpwi r12, BOOK3S_INTERRUPT_MACHINE_CHECK
> beq machine_check_realmode
> -mc_cont:
> + /* Or a hypervisor maintenance interrupt */
> + cmpwi r12, BOOK3S_INTERRUPT_HMI
> + beq hmi_realmode
> +
> +guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
> +
> #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
> addi r3, r9, VCPU_TB_RMEXIT
> mr r4, r9
> @@ -1821,24 +1762,6 @@ BEGIN_FTR_SECTION
> mtspr SPRN_DPDES, r8
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> - /* If HMI, call kvmppc_realmode_hmi_handler() */
> - lwz r12, STACK_SLOT_TRAP(r1)
> - cmpwi r12, BOOK3S_INTERRUPT_HMI
> - bne 27f
> - bl kvmppc_realmode_hmi_handler
> - nop
> - cmpdi r3, 0
> - /*
> - * At this point kvmppc_realmode_hmi_handler may have resync-ed
> - * the TB, and if it has, we must not subtract the guest timebase
> - * offset from the timebase. So, skip it.
> - *
> - * Also, do not call kvmppc_subcore_exit_guest() because it has
> - * been invoked as part of kvmppc_realmode_hmi_handler().
> - */
> - beq 30f
> -
> -27:
> /* Subtract timebase offset from timebase */
> ld r8, VCORE_TB_OFFSET_APPL(r5)
> cmpdi r8,0
> @@ -1856,7 +1779,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> addis r8,r8,0x100 /* if so, increment upper 40 bits */
> mtspr SPRN_TBU40,r8
>
> -17: bl kvmppc_subcore_exit_guest
> +17:
> + /*
> + * If this is an HMI, we called kvmppc_realmode_hmi_handler
> + * above, which may or may not have already called
> + * kvmppc_subcore_exit_guest. Fortunately, all that
> + * kvmppc_subcore_exit_guest does is clear a flag, so calling
> + * it again here is benign even if kvmppc_realmode_hmi_handler
> + * has already called it.
> + */
> + bl kvmppc_subcore_exit_guest
> nop
> 30: ld r5,HSTATE_KVM_VCORE(r13)
> ld r4,VCORE_KVM(r5) /* pointer to struct kvm */
> @@ -1910,6 +1842,67 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> mtlr r0
> blr
>
> +kvmppc_guest_external:
> + /* External interrupt, first check for host_ipi. If this is
> + * set, we know the host wants us out so let's do it now
> + */
> + bl kvmppc_read_intr
> +
> + /*
> + * Restore the active volatile registers after returning from
> + * a C function.
> + */
> + ld r9, HSTATE_KVM_VCPU(r13)
> + li r12, BOOK3S_INTERRUPT_EXTERNAL
> +
> + /*
> + * kvmppc_read_intr return codes:
> + *
> + * Exit to host (r3 > 0)
> + * 1 An interrupt is pending that needs to be handled by the host
> + * Exit guest and return to host by branching to guest_exit_cont
> + *
> + * 2 Passthrough that needs completion in the host
> + * Exit guest and return to host by branching to guest_exit_cont
> + * However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD
> + * to indicate to the host to complete handling the interrupt
> + *
> + * Before returning to guest, we check if any CPU is heading out
> + * to the host and if so, we head out also. If no CPUs are heading
> + * check return values <= 0.
> + *
> + * Return to guest (r3 <= 0)
> + * 0 No external interrupt is pending
> + * -1 A guest wakeup IPI (which has now been cleared)
> + * In either case, we return to guest to deliver any pending
> + * guest interrupts.
> + *
> + * -2 A PCI passthrough external interrupt was handled
> + * (interrupt was delivered directly to guest)
> + * Return to guest to deliver any pending guest interrupts.
> + */
> +
> + cmpdi r3, 1
> + ble 1f
> +
> + /* Return code = 2 */
> + li r12, BOOK3S_INTERRUPT_HV_RM_HARD
> + stw r12, VCPU_TRAP(r9)
> + b guest_exit_cont
> +
> +1: /* Return code <= 1 */
> + cmpdi r3, 0
> + bgt guest_exit_cont
> +
> + /* Return code <= 0 */
> +maybe_reenter_guest:
> + ld r5, HSTATE_KVM_VCORE(r13)
> + lwz r0, VCORE_ENTRY_EXIT(r5)
> + cmpwi r0, 0x100
> + mr r4, r9
> + blt deliver_guest_interrupt
> + b guest_exit_cont
> +
> #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> /*
> * Softpatch interrupt for transactional memory emulation cases
> @@ -2685,13 +2678,7 @@ END_FTR_SECTION(CPU_FTR_TM | CPU_FTR_P9_TM_HV_ASSIST, 0)
> mr r9, r4
> cmpdi r3, 0
> bgt guest_exit_cont
> -
> - /* see if any other thread is already exiting */
> - lwz r0,VCORE_ENTRY_EXIT(r5)
> - cmpwi r0,0x100
> - bge guest_exit_cont
> -
> - b kvmppc_cede_reentry /* if not go back to guest */
> + b maybe_reenter_guest
>
> /* cede when already previously prodded case */
> kvm_cede_prodded:
> @@ -2758,12 +2745,12 @@ machine_check_realmode:
> */
> ld r11, VCPU_MSR(r9)
> rldicl. r0, r11, 64-MSR_HV_LG, 63 /* check if it happened in HV mode */
> - bne mc_cont /* if so, exit to host */
> + bne guest_exit_cont /* if so, exit to host */
> /* Check if guest is capable of handling NMI exit */
> ld r10, VCPU_KVM(r9)
> lbz r10, KVM_FWNMI(r10)
> cmpdi r10, 1 /* FWNMI capable? */
> - beq mc_cont /* if so, exit with KVM_EXIT_NMI. */
> + beq guest_exit_cont /* if so, exit with KVM_EXIT_NMI. */
>
> /* if not, fall through for backward compatibility. */
> andi. r10, r11, MSR_RI /* check for unrecoverable exception */
> @@ -2777,6 +2764,21 @@ machine_check_realmode:
> 2: b fast_interrupt_c_return
>
> /*
> + * Call C code to handle a HMI in real mode.
> + * Only the primary thread does the call, secondary threads are handled
> + * by calling hmi_exception_realmode() after kvmppc_hv_entry returns.
> + * r9 points to the vcpu on entry
> + */
> +hmi_realmode:
> + lbz r0, HSTATE_PTID(r13)
> + cmpwi r0, 0
> + bne guest_exit_cont
> + bl kvmppc_realmode_hmi_handler
> + ld r9, HSTATE_KVM_VCPU(r13)
> + li r12, BOOK3S_INTERRUPT_HMI
> + b guest_exit_cont
> +
> +/*
> * Check the reason we woke from nap, and take appropriate action.
> * Returns (in r3):
> * 0 if nothing needs to be done
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: David Gibson <david@gibson.dropbear.id.au>
To: Paul Mackerras <paulus@ozlabs.org>
Cc: linuxppc-dev@ozlabs.org, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v5 06/33] KVM: PPC: Book3S HV: Simplify real-mode interrupt handling
Date: Tue, 9 Oct 2018 11:05:44 +1100 [thread overview]
Message-ID: <20181009000544.GE7004@umbus.fritz.box> (raw)
In-Reply-To: <1538976679-1363-7-git-send-email-paulus@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 12008 bytes --]
On Mon, Oct 08, 2018 at 04:30:52PM +1100, Paul Mackerras wrote:
> This streamlines the first part of the code that handles a hypervisor
> interrupt that occurred in the guest. With this, all of the real-mode
> handling that occurs is done before the "guest_exit_cont" label; once
> we get to that label we are committed to exiting to host virtual mode.
> Thus the machine check and HMI real-mode handling is moved before that
> label.
>
> Also, the code to handle external interrupts is moved out of line, as
> is the code that calls kvmppc_realmode_hmi_handler().
>
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> arch/powerpc/kvm/book3s_hv_ras.c | 8 ++
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 220 ++++++++++++++++----------------
> 2 files changed, 119 insertions(+), 109 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv_ras.c b/arch/powerpc/kvm/book3s_hv_ras.c
> index b11043b..ee564b6 100644
> --- a/arch/powerpc/kvm/book3s_hv_ras.c
> +++ b/arch/powerpc/kvm/book3s_hv_ras.c
> @@ -331,5 +331,13 @@ long kvmppc_realmode_hmi_handler(void)
> } else {
> wait_for_tb_resync();
> }
> +
> + /*
> + * Reset tb_offset_applied so the guest exit code won't try
> + * to subtract the previous timebase offset from the timebase.
> + */
> + if (local_paca->kvm_hstate.kvm_vcore)
> + local_paca->kvm_hstate.kvm_vcore->tb_offset_applied = 0;
> +
> return 0;
> }
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index 5b2ae34..fc360b5 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -1018,8 +1018,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
> no_xive:
> #endif /* CONFIG_KVM_XICS */
>
> -deliver_guest_interrupt:
> -kvmppc_cede_reentry: /* r4 = vcpu, r13 = paca */
> +deliver_guest_interrupt: /* r4 = vcpu, r13 = paca */
> /* Check if we can deliver an external or decrementer interrupt now */
> ld r0, VCPU_PENDING_EXC(r4)
> BEGIN_FTR_SECTION
> @@ -1269,18 +1268,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
> std r3, VCPU_CTR(r9)
> std r4, VCPU_XER(r9)
>
> -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> - /* For softpatch interrupt, go off and do TM instruction emulation */
> - cmpwi r12, BOOK3S_INTERRUPT_HV_SOFTPATCH
> - beq kvmppc_tm_emul
> -#endif
> + /* Save more register state */
> + mfdar r3
> + mfdsisr r4
> + std r3, VCPU_DAR(r9)
> + stw r4, VCPU_DSISR(r9)
>
> /* If this is a page table miss then see if it's theirs or ours */
> cmpwi r12, BOOK3S_INTERRUPT_H_DATA_STORAGE
> beq kvmppc_hdsi
> + std r3, VCPU_FAULT_DAR(r9)
> + stw r4, VCPU_FAULT_DSISR(r9)
> cmpwi r12, BOOK3S_INTERRUPT_H_INST_STORAGE
> beq kvmppc_hisi
>
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + /* For softpatch interrupt, go off and do TM instruction emulation */
> + cmpwi r12, BOOK3S_INTERRUPT_HV_SOFTPATCH
> + beq kvmppc_tm_emul
> +#endif
> +
> /* See if this is a leftover HDEC interrupt */
> cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER
> bne 2f
> @@ -1303,7 +1310,7 @@ BEGIN_FTR_SECTION
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> lbz r0, HSTATE_HOST_IPI(r13)
> cmpwi r0, 0
> - beq 4f
> + beq maybe_reenter_guest
> b guest_exit_cont
> 3:
> /* If it's a hypervisor facility unavailable interrupt, save HFSCR */
> @@ -1315,82 +1322,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> 14:
> /* External interrupt ? */
> cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
> - bne+ guest_exit_cont
> -
> - /* External interrupt, first check for host_ipi. If this is
> - * set, we know the host wants us out so let's do it now
> - */
> - bl kvmppc_read_intr
> -
> - /*
> - * Restore the active volatile registers after returning from
> - * a C function.
> - */
> - ld r9, HSTATE_KVM_VCPU(r13)
> - li r12, BOOK3S_INTERRUPT_EXTERNAL
> -
> - /*
> - * kvmppc_read_intr return codes:
> - *
> - * Exit to host (r3 > 0)
> - * 1 An interrupt is pending that needs to be handled by the host
> - * Exit guest and return to host by branching to guest_exit_cont
> - *
> - * 2 Passthrough that needs completion in the host
> - * Exit guest and return to host by branching to guest_exit_cont
> - * However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD
> - * to indicate to the host to complete handling the interrupt
> - *
> - * Before returning to guest, we check if any CPU is heading out
> - * to the host and if so, we head out also. If no CPUs are heading
> - * check return values <= 0.
> - *
> - * Return to guest (r3 <= 0)
> - * 0 No external interrupt is pending
> - * -1 A guest wakeup IPI (which has now been cleared)
> - * In either case, we return to guest to deliver any pending
> - * guest interrupts.
> - *
> - * -2 A PCI passthrough external interrupt was handled
> - * (interrupt was delivered directly to guest)
> - * Return to guest to deliver any pending guest interrupts.
> - */
> -
> - cmpdi r3, 1
> - ble 1f
> -
> - /* Return code = 2 */
> - li r12, BOOK3S_INTERRUPT_HV_RM_HARD
> - stw r12, VCPU_TRAP(r9)
> - b guest_exit_cont
> -
> -1: /* Return code <= 1 */
> - cmpdi r3, 0
> - bgt guest_exit_cont
> -
> - /* Return code <= 0 */
> -4: ld r5, HSTATE_KVM_VCORE(r13)
> - lwz r0, VCORE_ENTRY_EXIT(r5)
> - cmpwi r0, 0x100
> - mr r4, r9
> - blt deliver_guest_interrupt
> -
> -guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
> - /* Save more register state */
> - mfdar r6
> - mfdsisr r7
> - std r6, VCPU_DAR(r9)
> - stw r7, VCPU_DSISR(r9)
> - /* don't overwrite fault_dar/fault_dsisr if HDSI */
> - cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE
> - beq mc_cont
> - std r6, VCPU_FAULT_DAR(r9)
> - stw r7, VCPU_FAULT_DSISR(r9)
> -
> + beq kvmppc_guest_external
> /* See if it is a machine check */
> cmpwi r12, BOOK3S_INTERRUPT_MACHINE_CHECK
> beq machine_check_realmode
> -mc_cont:
> + /* Or a hypervisor maintenance interrupt */
> + cmpwi r12, BOOK3S_INTERRUPT_HMI
> + beq hmi_realmode
> +
> +guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
> +
> #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
> addi r3, r9, VCPU_TB_RMEXIT
> mr r4, r9
> @@ -1821,24 +1762,6 @@ BEGIN_FTR_SECTION
> mtspr SPRN_DPDES, r8
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> - /* If HMI, call kvmppc_realmode_hmi_handler() */
> - lwz r12, STACK_SLOT_TRAP(r1)
> - cmpwi r12, BOOK3S_INTERRUPT_HMI
> - bne 27f
> - bl kvmppc_realmode_hmi_handler
> - nop
> - cmpdi r3, 0
> - /*
> - * At this point kvmppc_realmode_hmi_handler may have resync-ed
> - * the TB, and if it has, we must not subtract the guest timebase
> - * offset from the timebase. So, skip it.
> - *
> - * Also, do not call kvmppc_subcore_exit_guest() because it has
> - * been invoked as part of kvmppc_realmode_hmi_handler().
> - */
> - beq 30f
> -
> -27:
> /* Subtract timebase offset from timebase */
> ld r8, VCORE_TB_OFFSET_APPL(r5)
> cmpdi r8,0
> @@ -1856,7 +1779,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> addis r8,r8,0x100 /* if so, increment upper 40 bits */
> mtspr SPRN_TBU40,r8
>
> -17: bl kvmppc_subcore_exit_guest
> +17:
> + /*
> + * If this is an HMI, we called kvmppc_realmode_hmi_handler
> + * above, which may or may not have already called
> + * kvmppc_subcore_exit_guest. Fortunately, all that
> + * kvmppc_subcore_exit_guest does is clear a flag, so calling
> + * it again here is benign even if kvmppc_realmode_hmi_handler
> + * has already called it.
> + */
> + bl kvmppc_subcore_exit_guest
> nop
> 30: ld r5,HSTATE_KVM_VCORE(r13)
> ld r4,VCORE_KVM(r5) /* pointer to struct kvm */
> @@ -1910,6 +1842,67 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> mtlr r0
> blr
>
> +kvmppc_guest_external:
> + /* External interrupt, first check for host_ipi. If this is
> + * set, we know the host wants us out so let's do it now
> + */
> + bl kvmppc_read_intr
> +
> + /*
> + * Restore the active volatile registers after returning from
> + * a C function.
> + */
> + ld r9, HSTATE_KVM_VCPU(r13)
> + li r12, BOOK3S_INTERRUPT_EXTERNAL
> +
> + /*
> + * kvmppc_read_intr return codes:
> + *
> + * Exit to host (r3 > 0)
> + * 1 An interrupt is pending that needs to be handled by the host
> + * Exit guest and return to host by branching to guest_exit_cont
> + *
> + * 2 Passthrough that needs completion in the host
> + * Exit guest and return to host by branching to guest_exit_cont
> + * However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD
> + * to indicate to the host to complete handling the interrupt
> + *
> + * Before returning to guest, we check if any CPU is heading out
> + * to the host and if so, we head out also. If no CPUs are heading
> + * check return values <= 0.
> + *
> + * Return to guest (r3 <= 0)
> + * 0 No external interrupt is pending
> + * -1 A guest wakeup IPI (which has now been cleared)
> + * In either case, we return to guest to deliver any pending
> + * guest interrupts.
> + *
> + * -2 A PCI passthrough external interrupt was handled
> + * (interrupt was delivered directly to guest)
> + * Return to guest to deliver any pending guest interrupts.
> + */
> +
> + cmpdi r3, 1
> + ble 1f
> +
> + /* Return code = 2 */
> + li r12, BOOK3S_INTERRUPT_HV_RM_HARD
> + stw r12, VCPU_TRAP(r9)
> + b guest_exit_cont
> +
> +1: /* Return code <= 1 */
> + cmpdi r3, 0
> + bgt guest_exit_cont
> +
> + /* Return code <= 0 */
> +maybe_reenter_guest:
> + ld r5, HSTATE_KVM_VCORE(r13)
> + lwz r0, VCORE_ENTRY_EXIT(r5)
> + cmpwi r0, 0x100
> + mr r4, r9
> + blt deliver_guest_interrupt
> + b guest_exit_cont
> +
> #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> /*
> * Softpatch interrupt for transactional memory emulation cases
> @@ -2685,13 +2678,7 @@ END_FTR_SECTION(CPU_FTR_TM | CPU_FTR_P9_TM_HV_ASSIST, 0)
> mr r9, r4
> cmpdi r3, 0
> bgt guest_exit_cont
> -
> - /* see if any other thread is already exiting */
> - lwz r0,VCORE_ENTRY_EXIT(r5)
> - cmpwi r0,0x100
> - bge guest_exit_cont
> -
> - b kvmppc_cede_reentry /* if not go back to guest */
> + b maybe_reenter_guest
>
> /* cede when already previously prodded case */
> kvm_cede_prodded:
> @@ -2758,12 +2745,12 @@ machine_check_realmode:
> */
> ld r11, VCPU_MSR(r9)
> rldicl. r0, r11, 64-MSR_HV_LG, 63 /* check if it happened in HV mode */
> - bne mc_cont /* if so, exit to host */
> + bne guest_exit_cont /* if so, exit to host */
> /* Check if guest is capable of handling NMI exit */
> ld r10, VCPU_KVM(r9)
> lbz r10, KVM_FWNMI(r10)
> cmpdi r10, 1 /* FWNMI capable? */
> - beq mc_cont /* if so, exit with KVM_EXIT_NMI. */
> + beq guest_exit_cont /* if so, exit with KVM_EXIT_NMI. */
>
> /* if not, fall through for backward compatibility. */
> andi. r10, r11, MSR_RI /* check for unrecoverable exception */
> @@ -2777,6 +2764,21 @@ machine_check_realmode:
> 2: b fast_interrupt_c_return
>
> /*
> + * Call C code to handle a HMI in real mode.
> + * Only the primary thread does the call, secondary threads are handled
> + * by calling hmi_exception_realmode() after kvmppc_hv_entry returns.
> + * r9 points to the vcpu on entry
> + */
> +hmi_realmode:
> + lbz r0, HSTATE_PTID(r13)
> + cmpwi r0, 0
> + bne guest_exit_cont
> + bl kvmppc_realmode_hmi_handler
> + ld r9, HSTATE_KVM_VCPU(r13)
> + li r12, BOOK3S_INTERRUPT_HMI
> + b guest_exit_cont
> +
> +/*
> * Check the reason we woke from nap, and take appropriate action.
> * Returns (in r3):
> * 0 if nothing needs to be done
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2018-10-09 0:05 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-08 5:30 [PATCH v5 00/33] KVM: PPC: Book3S HV: Nested HV virtualization Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 01/33] powerpc: Turn off CPU_FTR_P9_TM_HV_ASSIST in non-hypervisor mode Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 02/33] KVM: PPC: Book3S: Simplify external interrupt handling Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 03/33] KVM: PPC: Book3S HV: Remove left-over code in XICS-on-XIVE emulation Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 04/33] KVM: PPC: Book3S HV: Move interrupt delivery on guest entry to C code Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 05/33] KVM: PPC: Book3S HV: Extract PMU save/restore operations as C-callable functions Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 8:16 ` Madhavan Srinivasan
2018-10-08 5:30 ` [PATCH v5 06/33] KVM: PPC: Book3S HV: Simplify real-mode interrupt handling Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-09 0:05 ` David Gibson [this message]
2018-10-09 0:05 ` David Gibson
2018-10-08 5:30 ` [PATCH v5 07/33] KVM: PPC: Book3S: Rework TM save/restore code and make it C-callable Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 08/33] KVM: PPC: Book3S HV: Call kvmppc_handle_exit_hv() with vcore unlocked Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 09/33] KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-09 0:20 ` David Gibson
2018-10-09 0:20 ` David Gibson
2018-10-08 5:30 ` [PATCH v5 10/33] KVM: PPC: Book3S HV: Handle hypervisor instruction faults better Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 11/33] KVM: PPC: Book3S HV: Add a debugfs file to dump radix mappings Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 12/33] KVM: PPC: Use ccr field in pt_regs struct embedded in vcpu struct Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:30 ` [PATCH v5 13/33] KVM: PPC: Book3S HV: Clear partition table entry on vm teardown Paul Mackerras
2018-10-08 5:30 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 14/33] KVM: PPC: Book3S HV: Make kvmppc_mmu_radix_xlate process/partition table agnostic Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 15/33] KVM: PPC: Book3S HV: Refactor radix page fault handler Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 16/33] KVM: PPC: Book3S HV: Use kvmppc_unmap_pte() in kvm_unmap_radix() Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 17/33] KVM: PPC: Book3S HV: Framework and hcall stubs for nested virtualization Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 23:30 ` David Gibson
2018-10-08 23:30 ` David Gibson
2018-10-08 5:31 ` [PATCH v5 18/33] KVM: PPC: Book3S HV: Nested guest entry via hypercall Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 19/33] KVM: PPC: Book3S HV: Use XICS hypercalls when running as a nested hypervisor Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 20/33] KVM: PPC: Book3S HV: Handle hypercalls correctly when nested Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 21/33] KVM: PPC: Book3S HV: Handle page fault for a nested guest Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 22/33] KVM: PPC: Book3S HV: Introduce rmap to track nested guest mappings Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-09 0:26 ` David Gibson
2018-10-09 0:26 ` David Gibson
2018-10-08 5:31 ` [PATCH v5 23/33] KVM: PPC: Book3S HV: Implement H_TLB_INVALIDATE hcall Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 24/33] KVM: PPC: Book3S HV: Use hypercalls for TLB invalidation when nested Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 25/33] KVM: PPC: Book3S HV: Invalidate TLB when nested vcpu moves physical cpu Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 26/33] KVM: PPC: Book3S HV: Don't access HFSCR, LPIDR or LPCR when running nested Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 27/33] KVM: PPC: Book3S HV: Add one-reg interface to virtual PTCR register Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 28/33] KVM: PPC: Book3S HV: Sanitise hv_regs on nested guest entry Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 29/33] KVM: PPC: Book3S HV: Handle differing endianness for H_ENTER_NESTED Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 30/33] KVM: PPC: Book3S HV: Allow HV module to load without hypervisor mode Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 23:31 ` David Gibson
2018-10-08 23:31 ` David Gibson
2018-10-08 5:31 ` [PATCH v5 31/33] KVM: PPC: Book3S HV: Add nested shadow page tables to debugfs Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 5:31 ` [PATCH v5 32/33] KVM: PPC: Book3S HV: Add a VM capability to enable nested virtualization Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 23:34 ` David Gibson
2018-10-08 23:34 ` David Gibson
2018-10-08 5:31 ` [PATCH v5 33/33] KVM: PPC: Book3S HV: Add NO_HASH flag to GET_SMMU_INFO ioctl result Paul Mackerras
2018-10-08 5:31 ` Paul Mackerras
2018-10-08 23:34 ` David Gibson
2018-10-08 23:34 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181009000544.GE7004@umbus.fritz.box \
--to=david@gibson.dropbear.id.au \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=paulus@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.