[PATCH] [RFC] bookehv: Handle debug exception on guest exit

Bharat Bhushan r65777 at freescale.com
Wed Mar 20 22:29:40 EST 2013


EPCR.DUVD controls whether the debug events can come in
hypervisor mode or not. When KVM guest is using the debug
resource then we do not want debug events to be captured
in guest entry/exit path. So we set EPCR.DUVD when entering
and clears EPCR.DUVD when exiting from guest.

Debug instruction complete is a post-completion debug
exception but debug event gets posted on the basis of MSR
before the instruction is executed. Now if the instruction
switches the context from guest mode (MSR.GS = 1) to hypervisor
mode (MSR.GS = 0) then the xSRR0 points to first instruction of
KVM handler and xSRR1 points that MSR.GS is clear
(hypervisor context). Now as xSRR1.GS is used to decide whether
KVM handler will be invoked to handle the exception or host
host kernel debug handler will be invoked to handle the exception.
This leads to host kernel debug handler handling the exception
which should either be handled by KVM.

This is tested on e500mc in 32 bit mode

Signed-off-by: Bharat Bhushan <bharat.bhushan at freescale.com>
---
 arch/powerpc/kernel/exceptions-64e.S |   54 ++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/head_booke.h     |   35 ++++++++++++++++++++++
 2 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 4684e33..56882a0 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -450,6 +450,33 @@ interrupt_end_book3e:
 	andis.	r15,r14,DBSR_IC at h
 	beq+	1f
 
+#ifdef CONFIG_KVM_BOOKE_HV
+	/*
+	 * EPCR.DUVD controls whether the debug events can come in
+	 * hypervisor mode or not. When KVM guest is using the debug
+	 * resource then we do not want debug events to be captured
+	 * in guest entry/exit path. So we set EPCR.DUVD when entering
+	 * and clears EPCR.DUVD when exiting from guest.
+	 * Debug instruction complete is a post-completion debug
+	 * exception but debug event gets posted on the basis of MSR
+	 * before the instruction is executed. Now if the instruction
+	 * switches the context from guest mode (MSR.GS = 1) to hypervisor
+	 * mode (MSR.GS = 0) then the xSRR0 points to first instruction of
+	 * KVM handler and xSRR1 points that MSR.GS is clear
+	 * (hypervisor context). Now as xSRR1.GS is used to decide whether
+	 * KVM handler will be invoked to handle the exception or host
+	 * host kernel debug handler will be invoked to handle the exception.
+	 * This leads to host kernel debug handler handling the exception
+	 * which should either be handled by KVM.
+	 */
+	mfspr	r10, SPRN_EPCR
+	andis.	r10,r10,SPRN_EPCR_DUVD at h
+	beq+	2f
+
+	andis.	r10,r9,MSR_GS at h
+	beq+	1f
+2:
+#endif
 	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
 	LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
 	cmpld	cr0,r10,r14
@@ -516,6 +543,33 @@ kernel_dbg_exc:
 	andis.	r15,r14,DBSR_IC at h
 	beq+	1f
 
+#ifdef CONFIG_KVM_BOOKE_HV
+	/*
+	 * EPCR.DUVD controls whether the debug events can come in
+	 * hypervisor mode or not. When KVM guest is using the debug
+	 * resource then we do not want debug events to be captured
+	 * in guest entry/exit path. So we set EPCR.DUVD when entering
+	 * and clears EPCR.DUVD when exiting from guest.
+	 * Debug instruction complete is a post-completion debug
+	 * exception but debug event gets posted on the basis of MSR
+	 * before the instruction is executed. Now if the instruction
+	 * switches the context from guest mode (MSR.GS = 1) to hypervisor
+	 * mode (MSR.GS = 0) then the xSRR0 points to first instruction of
+	 * KVM handler and xSRR1 points that MSR.GS is clear
+	 * (hypervisor context). Now as xSRR1.GS is used to decide whether
+	 * KVM handler will be invoked to handle the exception or host
+	 * host kernel debug handler will be invoked to handle the exception.
+	 * This leads to host kernel debug handler handling the exception
+	 * which should either be handled by KVM.
+	 */
+	mfspr	r10, SPRN_EPCR
+	andis.	r10,r10,SPRN_EPCR_DUVD at h
+	beq+	2f
+
+	andis.	r10,r9,MSR_GS at h
+	beq+	1f
+2:
+#endif
 	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
 	LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
 	cmpld	cr0,r10,r14
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 5f051ee..040b0a3 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -285,7 +285,33 @@ label:
 	mfspr	r10,SPRN_DBSR;		/* check single-step/branch taken */  \
 	andis.	r10,r10,(DBSR_IC|DBSR_BT)@h;				      \
 	beq+	2f;							      \
+#ifdef CONFIG_KVM_BOOKE_HV						      \
+	/*								      \
+	 * EPCR.DUVD controls whether the debug events can come in	      \
+	 * hypervisor mode or not. When KVM guest is using the debug	      \
+	 * resource then we do not want debug events to be captured 	      \
+	 * in guest entry/exit path. So we set EPCR.DUVD when entering	      \
+	 * and clears EPCR.DUVD when exiting from guest.		      \
+	 * Debug instruction complete is a post-completion debug	      \
+	 * exception but debug event gets posted on the basis of MSR	      \
+	 * before the instruction is executed. Now if the instruction	      \
+	 * switches the context from guest mode (MSR.GS = 1) to hypervisor    \
+	 * mode (MSR.GS = 0) then the xSRR0 points to first instruction of    \
+	 * KVM handler and xSRR1 points that MSR.GS is clear 		      \
+	 * (hypervisor context). Now as xSRR1.GS is used to decide whether    \
+	 * KVM handler will be invoked to handle the exception or host	      \
+	 * host kernel debug handler will be invoked to handle the exception. \
+	 * This leads to host kernel debug handler handling the exception     \
+	 * which should either be handled by KVM.			      \
+	 */								      \
+	mfspr	r10, SPRN_EPCR;						      \
+	andis.	r10,r10,SPRN_EPCR_DUVD at h;				      \
+	beq+	3f;							      \
 									      \
+	andis.	r10,r9,MSR_GS at h;				    	      \
+	beq+	1f;							      \
+3:									      \
+#endif									      \
 	lis	r10,KERNELBASE at h;	/* check if exception in vectors */   \
 	ori	r10,r10,KERNELBASE at l;					      \
 	cmplw	r12,r10;						      \
@@ -339,6 +365,15 @@ label:
 	andis.	r10,r10,(DBSR_IC|DBSR_BT)@h;				      \
 	beq+	2f;							      \
 									      \
+#ifdef CONFIG_KVM_BOOKE_HV						      \
+	mfspr	r10, SPRN_EPCR;						      \
+	andis.	r10,r10,SPRN_EPCR_DUVD at h;				      \
+	beq+	3f;							      \
+									      \
+	andis.	r10,r9,MSR_GS at h;				    	      \
+	beq+	1f;							      \
+3:									      \
+#endif									      \
 	lis	r10,KERNELBASE at h;	/* check if exception in vectors */   \
 	ori	r10,r10,KERNELBASE at l;					      \
 	cmplw	r12,r10;						      \
-- 
1.7.0.4




More information about the Linuxppc-dev mailing list