All of lore.kernel.org
 help / color / mirror / Atom feed
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 --]

  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.