Re: [PATCH 2/2] KVM: PPC: Book3S HV: Better handling of exceptions that happen in real mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04.10.2013, at 13:45, Paul Mackerras wrote:

> When an interrupt or exception happens in the guest that comes to the
> host, the CPU goes to hypervisor real mode (MMU off) to handle the
> exception but doesn't change the MMU context.  After saving a few
> registers, we then clear the "in guest" flag.  If, for any reason,
> we get an exception in the real-mode code, that then gets handled
> by the normal kernel exception handlers, which turn the MMU on.  This
> is disastrous if the MMU is still set to the guest context, since we
> end up executing instructions from random places in the guest kernel
> with hypervisor privilege.
> 
> In order to catch this situation, we define a new value for the "in guest"
> flag, KVM_GUEST_MODE_HOST_HV, to indicate that we are in hypervisor real
> mode with guest MMU context.  If the "in guest" flag is set to this value,
> we branch off to an emergency handler.  For the moment, this just does
> a branch to self to stop the CPU from doing anything further.

I don't understand how you get there. The only case I can imagine where you'd hit a normal Linux handler while in guest MMU context is a bug in the complex real mode handling code.

So basically what you're doing is you're changing the "guest mode" bit to HOST_NV while you're executing these.

The other change this patch does is it postpones the return to GUEST_MODE_NONE to after fast-path handling of interrupt exits.

What if you simply don't introduce a new mode but instead only postpone the GUEST_MODE_NONE switch to later? Worst case that can happen is that your bug spins the CPU into handling that exit in a tight loop - not much different from your explicit spin, no?


Alex

> 
> While we're here, we define another new flag value to indicate that we
> are in a HV guest, as distinct from a PR guest.  This will be useful
> when we have a kernel that can support both PR and HV guests concurrently.
> 
> Signed-off-by: Paul Mackerras <paulus@xxxxxxxxx>
> ---
> arch/powerpc/include/asm/kvm_asm.h      |  2 ++
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 31 +++++++++++++++++++++++++------
> 2 files changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
> index e2d4d46..1bd92fd 100644
> --- a/arch/powerpc/include/asm/kvm_asm.h
> +++ b/arch/powerpc/include/asm/kvm_asm.h
> @@ -138,6 +138,8 @@
> #define KVM_GUEST_MODE_NONE	0
> #define KVM_GUEST_MODE_GUEST	1
> #define KVM_GUEST_MODE_SKIP	2
> +#define KVM_GUEST_MODE_GUEST_HV	3
> +#define KVM_GUEST_MODE_HOST_HV	4
> 
> #define KVM_INST_FETCH_FAILED	-1
> 
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index 8e0f28f..f1f1bf3 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -383,6 +383,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
> 	mtspr	SPRN_DAR, r5
> 	mtspr	SPRN_DSISR, r6
> 
> +	li	r6, KVM_GUEST_MODE_HOST_HV
> +	stb	r6, HSTATE_IN_GUEST(r13)
> +
> BEGIN_FTR_SECTION
> 	/* Restore AMR and UAMOR, set AMOR to all 1s */
> 	ld	r5,VCPU_AMR(r4)
> @@ -682,7 +685,7 @@ fast_guest_return:
> 	mtspr	SPRN_HSRR1,r11
> 
> 	/* Activate guest mode, so faults get handled by KVM */
> -	li	r9, KVM_GUEST_MODE_GUEST
> +	li	r9, KVM_GUEST_MODE_GUEST_HV
> 	stb	r9, HSTATE_IN_GUEST(r13)
> 
> 	/* Enter guest */
> @@ -742,6 +745,14 @@ kvmppc_interrupt:
> 	 */
> 	/* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */
> 	std	r9, HSTATE_HOST_R2(r13)
> +
> +	lbz	r9, HSTATE_IN_GUEST(r13)
> +	cmpwi	r9, KVM_GUEST_MODE_HOST_HV
> +	beq	kvmppc_bad_host_intr
> +	/* We're now back in the host but in guest MMU context */
> +	li	r9, KVM_GUEST_MODE_HOST_HV
> +	stb	r9, HSTATE_IN_GUEST(r13)
> +
> 	ld	r9, HSTATE_KVM_VCPU(r13)
> 
> 	/* Save registers */
> @@ -793,10 +804,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
> 	std	r3, VCPU_GPR(R13)(r9)
> 	std	r4, VCPU_LR(r9)
> 
> -	/* Unset guest mode */
> -	li	r0, KVM_GUEST_MODE_NONE
> -	stb	r0, HSTATE_IN_GUEST(r13)
> -
> 	stw	r12,VCPU_TRAP(r9)
> 
> 	/* Save HEIR (HV emulation assist reg) in last_inst
> @@ -1186,6 +1193,10 @@ BEGIN_FTR_SECTION
> 	mtspr	SPRN_AMR,r6
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
> 
> +	/* Unset guest mode */
> +	li	r0, KVM_GUEST_MODE_NONE
> +	stb	r0, HSTATE_IN_GUEST(r13)
> +
> 	/* Switch DSCR back to host value */
> BEGIN_FTR_SECTION
> 	mfspr	r8, SPRN_DSCR
> @@ -1388,7 +1399,7 @@ fast_interrupt_c_return:
> 	stw	r8, VCPU_LAST_INST(r9)
> 
> 	/* Unset guest mode. */
> -	li	r0, KVM_GUEST_MODE_NONE
> +	li	r0, KVM_GUEST_MODE_HOST_HV
> 	stb	r0, HSTATE_IN_GUEST(r13)
> 	b	guest_exit_cont
> 
> @@ -1937,3 +1948,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
> 	lwz	r7,VCPU_VRSAVE(r4)
> 	mtspr	SPRN_VRSAVE,r7
> 	blr
> +
> +/*
> + * We come here if we get any exception or interrupt while we are
> + * executing host real mode code while in guest MMU context.
> + * For now just spin, but we should do something better.
> + */
> +kvmppc_bad_host_intr:
> +	b	.
> -- 
> 1.8.4.rc3
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux