linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6 v5] KVM :PPC: Userspace Debug support
@ 2013-06-26  5:42 Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 1/6 v5] powerpc: remove unnecessary line continuations Bharat Bhushan
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

From: Bharat Bhushan <bharat.bhushan@freescale.com>

Note: These patches are based on http://github.com/agraf/linux-2.6.git queue

This patchset adds the userspace debug support for booke/bookehv.
this is tested on powerpc e500v2/e500mc devices.

We are now assuming that debug resource will not be used by kernel for
its own debugging. It will be used for only kernel user process debugging.
So the kernel debug load interface during context_to is used to load
debug conext for that selected process.

v4->v5
 - Some comments reworded and other cleanup (like change of function name etc)
 - Added a function for setting MSRP rather than inline

v3->v4
 - 4 out of 7 patches of initial patchset were applied.
   This patchset is on and above those 4 patches
 - KVM local "struct kvmppc_booke_debug_reg" is replaced by
   powerpc global "struct debug_reg"
 - use switch_booke_debug_regs() for debug register context switch.
 - Save DBSR before kernel pre-emption is enabled.
 - Some more cleanup

v2->v3
 - We are now assuming that debug resource will not be used by
   kernel for its own debugging.
   It will be used for only kernel user process debugging.
   So the kernel debug load interface during context_to is
   used to load debug conext for that selected process.

v1->v2
 - Debug registers are save/restore in vcpu_put/vcpu_get.
   Earlier the debug registers are saved/restored in guest entry/exit

Bharat Bhushan (6):
  powerpc: remove unnecessary line continuations
  powerpc: move debug registers in a structure
  powerpc: export debug registers save function for KVM
  KVM: PPC: exit to user space on "ehpriv" instruction
  KVM: PPC: Using "struct debug_reg"
  KVM: PPC: Add userspace debug stub support

 arch/powerpc/include/asm/disassemble.h |    4 +
 arch/powerpc/include/asm/kvm_host.h    |   16 +--
 arch/powerpc/include/asm/processor.h   |   38 +++--
 arch/powerpc/include/asm/reg_booke.h   |    8 +-
 arch/powerpc/include/asm/switch_to.h   |    4 +
 arch/powerpc/include/uapi/asm/kvm.h    |   22 ++-
 arch/powerpc/kernel/asm-offsets.c      |    2 +-
 arch/powerpc/kernel/process.c          |   45 +++---
 arch/powerpc/kernel/ptrace.c           |  154 +++++++++---------
 arch/powerpc/kernel/signal_32.c        |    6 +-
 arch/powerpc/kernel/traps.c            |   35 ++--
 arch/powerpc/kvm/booke.c               |  273 ++++++++++++++++++++++++++++----
 arch/powerpc/kvm/booke.h               |    5 +
 arch/powerpc/kvm/e500_emulate.c        |   27 +++
 14 files changed, 455 insertions(+), 184 deletions(-)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/6 v5] powerpc: remove unnecessary line continuations
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 2/6 v5] powerpc: move debug registers in a structure Bharat Bhushan
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/kernel/process.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ceb4e7b..639a8de 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -325,7 +325,7 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
 	/*
 	 * Force User/Supervisor bits to b11 (user-only MSR[PR]=1)
 	 */
-	thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |	\
+	thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
 			DBCR1_IAC3US | DBCR1_IAC4US;
 	/*
 	 * Force Data Address Compare User/Supervisor bits to be User-only
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/6 v5] powerpc: move debug registers in a structure
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 1/6 v5] powerpc: remove unnecessary line continuations Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 3/6 v5] powerpc: export debug registers save function for KVM Bharat Bhushan
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

This way we can use same data type struct with KVM and
also help in using other debug related function.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/processor.h |   38 +++++----
 arch/powerpc/include/asm/reg_booke.h |    8 +-
 arch/powerpc/kernel/asm-offsets.c    |    2 +-
 arch/powerpc/kernel/process.c        |   42 +++++-----
 arch/powerpc/kernel/ptrace.c         |  154 +++++++++++++++++-----------------
 arch/powerpc/kernel/signal_32.c      |    6 +-
 arch/powerpc/kernel/traps.c          |   35 ++++----
 7 files changed, 146 insertions(+), 139 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index d7e67ca..5b8a7f1 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -147,22 +147,7 @@ typedef struct {
 #define TS_FPR(i) fpr[i][TS_FPROFFSET]
 #define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET]
 
-struct thread_struct {
-	unsigned long	ksp;		/* Kernel stack pointer */
-	unsigned long	ksp_limit;	/* if ksp <= ksp_limit stack overflow */
-
-#ifdef CONFIG_PPC64
-	unsigned long	ksp_vsid;
-#endif
-	struct pt_regs	*regs;		/* Pointer to saved register state */
-	mm_segment_t	fs;		/* for get_fs() validation */
-#ifdef CONFIG_BOOKE
-	/* BookE base exception scratch space; align on cacheline */
-	unsigned long	normsave[8] ____cacheline_aligned;
-#endif
-#ifdef CONFIG_PPC32
-	void		*pgdir;		/* root of page-table tree */
-#endif
+struct debug_reg {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	/*
 	 * The following help to manage the use of Debug Control Registers
@@ -199,6 +184,27 @@ struct thread_struct {
 	unsigned long	dvc2;
 #endif
 #endif
+};
+
+struct thread_struct {
+	unsigned long	ksp;		/* Kernel stack pointer */
+	unsigned long	ksp_limit;	/* if ksp <= ksp_limit stack overflow */
+
+#ifdef CONFIG_PPC64
+	unsigned long	ksp_vsid;
+#endif
+	struct pt_regs	*regs;		/* Pointer to saved register state */
+	mm_segment_t	fs;		/* for get_fs() validation */
+#ifdef CONFIG_BOOKE
+	/* BookE base exception scratch space; align on cacheline */
+	unsigned long	normsave[8] ____cacheline_aligned;
+#endif
+#ifdef CONFIG_PPC32
+	void		*pgdir;		/* root of page-table tree */
+#endif
+	/* Debug Registers */
+	struct debug_reg debug;
+
 	/* FP and VSX 0-31 register set */
 	double		fpr[32][TS_FPRWIDTH];
 	struct {
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index b417de3..455dc89 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -381,7 +381,7 @@
 #define DBCR0_IA34T	0x00004000	/* Instr Addr 3-4 range Toggle */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
 
-#define dbcr_iac_range(task)	((task)->thread.dbcr0)
+#define dbcr_iac_range(task)	((task)->thread.debug.dbcr0)
 #define DBCR_IAC12I	DBCR0_IA12			/* Range Inclusive */
 #define DBCR_IAC12X	(DBCR0_IA12 | DBCR0_IA12X)	/* Range Exclusive */
 #define DBCR_IAC12MODE	(DBCR0_IA12 | DBCR0_IA12X)	/* IAC 1-2 Mode Bits */
@@ -395,7 +395,7 @@
 #define DBCR1_DAC1W	0x20000000	/* DAC1 Write Debug Event */
 #define DBCR1_DAC2W	0x10000000	/* DAC2 Write Debug Event */
 
-#define dbcr_dac(task)	((task)->thread.dbcr1)
+#define dbcr_dac(task)	((task)->thread.debug.dbcr1)
 #define DBCR_DAC1R	DBCR1_DAC1R
 #define DBCR_DAC1W	DBCR1_DAC1W
 #define DBCR_DAC2R	DBCR1_DAC2R
@@ -441,7 +441,7 @@
 #define DBCR0_CRET	0x00000020	/* Critical Return Debug Event */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
 
-#define dbcr_dac(task)	((task)->thread.dbcr0)
+#define dbcr_dac(task)	((task)->thread.debug.dbcr0)
 #define DBCR_DAC1R	DBCR0_DAC1R
 #define DBCR_DAC1W	DBCR0_DAC1W
 #define DBCR_DAC2R	DBCR0_DAC2R
@@ -475,7 +475,7 @@
 #define DBCR1_IAC34MX	0x000000C0	/* Instr Addr 3-4 range eXclusive */
 #define DBCR1_IAC34AT	0x00000001	/* Instr Addr 3-4 range Toggle */
 
-#define dbcr_iac_range(task)	((task)->thread.dbcr1)
+#define dbcr_iac_range(task)	((task)->thread.debug.dbcr1)
 #define DBCR_IAC12I	DBCR1_IAC12M	/* Range Inclusive */
 #define DBCR_IAC12X	DBCR1_IAC12MX	/* Range Exclusive */
 #define DBCR_IAC12MODE	DBCR1_IAC12MX	/* IAC 1-2 Mode Bits */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index b51a97c..c241c60 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -106,7 +106,7 @@ int main(void)
 #else /* CONFIG_PPC64 */
 	DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, debug.dbcr0));
 #endif
 #ifdef CONFIG_SPE
 	DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 639a8de..01ff496 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -312,49 +312,49 @@ static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk);
  */
 static void set_debug_reg_defaults(struct thread_struct *thread)
 {
-	thread->iac1 = thread->iac2 = 0;
+	thread->debug.iac1 = thread->debug.iac2 = 0;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
-	thread->iac3 = thread->iac4 = 0;
+	thread->debug.iac3 = thread->debug.iac4 = 0;
 #endif
-	thread->dac1 = thread->dac2 = 0;
+	thread->debug.dac1 = thread->debug.dac2 = 0;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-	thread->dvc1 = thread->dvc2 = 0;
+	thread->debug.dvc1 = thread->debug.dvc2 = 0;
 #endif
-	thread->dbcr0 = 0;
+	thread->debug.dbcr0 = 0;
 #ifdef CONFIG_BOOKE
 	/*
 	 * Force User/Supervisor bits to b11 (user-only MSR[PR]=1)
 	 */
-	thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
+	thread->debug.dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
 			DBCR1_IAC3US | DBCR1_IAC4US;
 	/*
 	 * Force Data Address Compare User/Supervisor bits to be User-only
 	 * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0.
 	 */
-	thread->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+	thread->debug.dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
 #else
-	thread->dbcr1 = 0;
+	thread->debug.dbcr1 = 0;
 #endif
 }
 
 static void prime_debug_regs(struct thread_struct *thread)
 {
-	mtspr(SPRN_IAC1, thread->iac1);
-	mtspr(SPRN_IAC2, thread->iac2);
+	mtspr(SPRN_IAC1, thread->debug.iac1);
+	mtspr(SPRN_IAC2, thread->debug.iac2);
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
-	mtspr(SPRN_IAC3, thread->iac3);
-	mtspr(SPRN_IAC4, thread->iac4);
+	mtspr(SPRN_IAC3, thread->debug.iac3);
+	mtspr(SPRN_IAC4, thread->debug.iac4);
 #endif
-	mtspr(SPRN_DAC1, thread->dac1);
-	mtspr(SPRN_DAC2, thread->dac2);
+	mtspr(SPRN_DAC1, thread->debug.dac1);
+	mtspr(SPRN_DAC2, thread->debug.dac2);
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-	mtspr(SPRN_DVC1, thread->dvc1);
-	mtspr(SPRN_DVC2, thread->dvc2);
+	mtspr(SPRN_DVC1, thread->debug.dvc1);
+	mtspr(SPRN_DVC2, thread->debug.dvc2);
 #endif
-	mtspr(SPRN_DBCR0, thread->dbcr0);
-	mtspr(SPRN_DBCR1, thread->dbcr1);
+	mtspr(SPRN_DBCR0, thread->debug.dbcr0);
+	mtspr(SPRN_DBCR1, thread->debug.dbcr1);
 #ifdef CONFIG_BOOKE
-	mtspr(SPRN_DBCR2, thread->dbcr2);
+	mtspr(SPRN_DBCR2, thread->debug.dbcr2);
 #endif
 }
 /*
@@ -364,8 +364,8 @@ static void prime_debug_regs(struct thread_struct *thread)
  */
 static void switch_booke_debug_regs(struct thread_struct *new_thread)
 {
-	if ((current->thread.dbcr0 & DBCR0_IDM)
-		|| (new_thread->dbcr0 & DBCR0_IDM))
+	if ((current->thread.debug.dbcr0 & DBCR0_IDM)
+		|| (new_thread->debug.dbcr0 & DBCR0_IDM))
 			prime_debug_regs(new_thread);
 }
 #else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3b14d32..80b902f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -853,8 +853,8 @@ void user_enable_single_step(struct task_struct *task)
 
 	if (regs != NULL) {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-		task->thread.dbcr0 &= ~DBCR0_BT;
-		task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+		task->thread.debug.dbcr0 &= ~DBCR0_BT;
+		task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC;
 		regs->msr |= MSR_DE;
 #else
 		regs->msr &= ~MSR_BE;
@@ -870,8 +870,8 @@ void user_enable_block_step(struct task_struct *task)
 
 	if (regs != NULL) {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-		task->thread.dbcr0 &= ~DBCR0_IC;
-		task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
+		task->thread.debug.dbcr0 &= ~DBCR0_IC;
+		task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT;
 		regs->msr |= MSR_DE;
 #else
 		regs->msr &= ~MSR_SE;
@@ -893,16 +893,16 @@ void user_disable_single_step(struct task_struct *task)
 		 * And, after doing so, if all debug flags are off, turn
 		 * off DBCR0(IDM) and MSR(DE) .... Torez
 		 */
-		task->thread.dbcr0 &= ~DBCR0_IC;
+		task->thread.debug.dbcr0 &= ~DBCR0_IC;
 		/*
 		 * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set.
 		 */
-		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
-					task->thread.dbcr1)) {
+		if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
+					task->thread.debug.dbcr1)) {
 			/*
 			 * All debug events were off.....
 			 */
-			task->thread.dbcr0 &= ~DBCR0_IDM;
+			task->thread.debug.dbcr0 &= ~DBCR0_IDM;
 			regs->msr &= ~MSR_DE;
 		}
 #else
@@ -1030,14 +1030,14 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 	 */
 
 	/* DAC's hold the whole address without any mode flags */
-	task->thread.dac1 = data & ~0x3UL;
+	task->thread.debug.dac1 = data & ~0x3UL;
 
-	if (task->thread.dac1 == 0) {
+	if (task->thread.debug.dac1 == 0) {
 		dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
-		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
-					task->thread.dbcr1)) {
+		if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
+					task->thread.debug.dbcr1)) {
 			task->thread.regs->msr &= ~MSR_DE;
-			task->thread.dbcr0 &= ~DBCR0_IDM;
+			task->thread.debug.dbcr0 &= ~DBCR0_IDM;
 		}
 		return 0;
 	}
@@ -1049,7 +1049,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 
 	/* Set the Internal Debugging flag (IDM bit 1) for the DBCR0
 	   register */
-	task->thread.dbcr0 |= DBCR0_IDM;
+	task->thread.debug.dbcr0 |= DBCR0_IDM;
 
 	/* Check for write and read flags and set DBCR0
 	   accordingly */
@@ -1079,10 +1079,10 @@ static long set_instruction_bp(struct task_struct *child,
 			      struct ppc_hw_breakpoint *bp_info)
 {
 	int slot;
-	int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0);
-	int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0);
-	int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0);
-	int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0);
+	int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0);
+	int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0);
+	int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0);
+	int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0);
 
 	if (dbcr_iac_range(child) & DBCR_IAC12MODE)
 		slot2_in_use = 1;
@@ -1101,9 +1101,9 @@ static long set_instruction_bp(struct task_struct *child,
 		/* We need a pair of IAC regsisters */
 		if ((!slot1_in_use) && (!slot2_in_use)) {
 			slot = 1;
-			child->thread.iac1 = bp_info->addr;
-			child->thread.iac2 = bp_info->addr2;
-			child->thread.dbcr0 |= DBCR0_IAC1;
+			child->thread.debug.iac1 = bp_info->addr;
+			child->thread.debug.iac2 = bp_info->addr2;
+			child->thread.debug.dbcr0 |= DBCR0_IAC1;
 			if (bp_info->addr_mode ==
 					PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
 				dbcr_iac_range(child) |= DBCR_IAC12X;
@@ -1112,9 +1112,9 @@ static long set_instruction_bp(struct task_struct *child,
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 		} else if ((!slot3_in_use) && (!slot4_in_use)) {
 			slot = 3;
-			child->thread.iac3 = bp_info->addr;
-			child->thread.iac4 = bp_info->addr2;
-			child->thread.dbcr0 |= DBCR0_IAC3;
+			child->thread.debug.iac3 = bp_info->addr;
+			child->thread.debug.iac4 = bp_info->addr2;
+			child->thread.debug.dbcr0 |= DBCR0_IAC3;
 			if (bp_info->addr_mode ==
 					PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
 				dbcr_iac_range(child) |= DBCR_IAC34X;
@@ -1134,30 +1134,30 @@ static long set_instruction_bp(struct task_struct *child,
 			 */
 			if (slot2_in_use || (slot3_in_use == slot4_in_use)) {
 				slot = 1;
-				child->thread.iac1 = bp_info->addr;
-				child->thread.dbcr0 |= DBCR0_IAC1;
+				child->thread.debug.iac1 = bp_info->addr;
+				child->thread.debug.dbcr0 |= DBCR0_IAC1;
 				goto out;
 			}
 		}
 		if (!slot2_in_use) {
 			slot = 2;
-			child->thread.iac2 = bp_info->addr;
-			child->thread.dbcr0 |= DBCR0_IAC2;
+			child->thread.debug.iac2 = bp_info->addr;
+			child->thread.debug.dbcr0 |= DBCR0_IAC2;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 		} else if (!slot3_in_use) {
 			slot = 3;
-			child->thread.iac3 = bp_info->addr;
-			child->thread.dbcr0 |= DBCR0_IAC3;
+			child->thread.debug.iac3 = bp_info->addr;
+			child->thread.debug.dbcr0 |= DBCR0_IAC3;
 		} else if (!slot4_in_use) {
 			slot = 4;
-			child->thread.iac4 = bp_info->addr;
-			child->thread.dbcr0 |= DBCR0_IAC4;
+			child->thread.debug.iac4 = bp_info->addr;
+			child->thread.debug.dbcr0 |= DBCR0_IAC4;
 #endif
 		} else
 			return -ENOSPC;
 	}
 out:
-	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.debug.dbcr0 |= DBCR0_IDM;
 	child->thread.regs->msr |= MSR_DE;
 
 	return slot;
@@ -1167,49 +1167,49 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 {
 	switch (slot) {
 	case 1:
-		if ((child->thread.dbcr0 & DBCR0_IAC1) == 0)
+		if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
 			/* address range - clear slots 1 & 2 */
-			child->thread.iac2 = 0;
+			child->thread.debug.iac2 = 0;
 			dbcr_iac_range(child) &= ~DBCR_IAC12MODE;
 		}
-		child->thread.iac1 = 0;
-		child->thread.dbcr0 &= ~DBCR0_IAC1;
+		child->thread.debug.iac1 = 0;
+		child->thread.debug.dbcr0 &= ~DBCR0_IAC1;
 		break;
 	case 2:
-		if ((child->thread.dbcr0 & DBCR0_IAC2) == 0)
+		if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC12MODE)
 			/* used in a range */
 			return -EINVAL;
-		child->thread.iac2 = 0;
-		child->thread.dbcr0 &= ~DBCR0_IAC2;
+		child->thread.debug.iac2 = 0;
+		child->thread.debug.dbcr0 &= ~DBCR0_IAC2;
 		break;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case 3:
-		if ((child->thread.dbcr0 & DBCR0_IAC3) == 0)
+		if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
 			/* address range - clear slots 3 & 4 */
-			child->thread.iac4 = 0;
+			child->thread.debug.iac4 = 0;
 			dbcr_iac_range(child) &= ~DBCR_IAC34MODE;
 		}
-		child->thread.iac3 = 0;
-		child->thread.dbcr0 &= ~DBCR0_IAC3;
+		child->thread.debug.iac3 = 0;
+		child->thread.debug.dbcr0 &= ~DBCR0_IAC3;
 		break;
 	case 4:
-		if ((child->thread.dbcr0 & DBCR0_IAC4) == 0)
+		if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0)
 			return -ENOENT;
 
 		if (dbcr_iac_range(child) & DBCR_IAC34MODE)
 			/* Used in a range */
 			return -EINVAL;
-		child->thread.iac4 = 0;
-		child->thread.dbcr0 &= ~DBCR0_IAC4;
+		child->thread.debug.iac4 = 0;
+		child->thread.debug.dbcr0 &= ~DBCR0_IAC4;
 		break;
 #endif
 	default:
@@ -1239,18 +1239,18 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
 			dbcr_dac(child) |= DBCR_DAC1R;
 		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
 			dbcr_dac(child) |= DBCR_DAC1W;
-		child->thread.dac1 = (unsigned long)bp_info->addr;
+		child->thread.debug.dac1 = (unsigned long)bp_info->addr;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
 		if (byte_enable) {
-			child->thread.dvc1 =
+			child->thread.debug.dvc1 =
 				(unsigned long)bp_info->condition_value;
-			child->thread.dbcr2 |=
+			child->thread.debug.dbcr2 |=
 				((byte_enable << DBCR2_DVC1BE_SHIFT) |
 				 (condition_mode << DBCR2_DVC1M_SHIFT));
 		}
 #endif
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-	} else if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+	} else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
 		/* Both dac1 and dac2 are part of a range */
 		return -ENOSPC;
 #endif
@@ -1260,19 +1260,19 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
 			dbcr_dac(child) |= DBCR_DAC2R;
 		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
 			dbcr_dac(child) |= DBCR_DAC2W;
-		child->thread.dac2 = (unsigned long)bp_info->addr;
+		child->thread.debug.dac2 = (unsigned long)bp_info->addr;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
 		if (byte_enable) {
-			child->thread.dvc2 =
+			child->thread.debug.dvc2 =
 				(unsigned long)bp_info->condition_value;
-			child->thread.dbcr2 |=
+			child->thread.debug.dbcr2 |=
 				((byte_enable << DBCR2_DVC2BE_SHIFT) |
 				 (condition_mode << DBCR2_DVC2M_SHIFT));
 		}
 #endif
 	} else
 		return -ENOSPC;
-	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.debug.dbcr0 |= DBCR0_IDM;
 	child->thread.regs->msr |= MSR_DE;
 
 	return slot + 4;
@@ -1284,32 +1284,32 @@ static int del_dac(struct task_struct *child, int slot)
 		if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
 			return -ENOENT;
 
-		child->thread.dac1 = 0;
+		child->thread.debug.dac1 = 0;
 		dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-		if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
-			child->thread.dac2 = 0;
-			child->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+		if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
+			child->thread.debug.dac2 = 0;
+			child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE;
 		}
-		child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
+		child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
 #endif
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-		child->thread.dvc1 = 0;
+		child->thread.debug.dvc1 = 0;
 #endif
 	} else if (slot == 2) {
 		if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
 			return -ENOENT;
 
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-		if (child->thread.dbcr2 & DBCR2_DAC12MODE)
+		if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE)
 			/* Part of a range */
 			return -EINVAL;
-		child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
+		child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
 #endif
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-		child->thread.dvc2 = 0;
+		child->thread.debug.dvc2 = 0;
 #endif
-		child->thread.dac2 = 0;
+		child->thread.debug.dac2 = 0;
 		dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
 	} else
 		return -EINVAL;
@@ -1351,22 +1351,22 @@ static int set_dac_range(struct task_struct *child,
 			return -EIO;
 	}
 
-	if (child->thread.dbcr0 &
+	if (child->thread.debug.dbcr0 &
 	    (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
 		return -ENOSPC;
 
 	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
-		child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
+		child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
 	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
-		child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
-	child->thread.dac1 = bp_info->addr;
-	child->thread.dac2 = bp_info->addr2;
+		child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
+	child->thread.debug.dac1 = bp_info->addr;
+	child->thread.debug.dac2 = bp_info->addr2;
 	if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
-		child->thread.dbcr2  |= DBCR2_DAC12M;
+		child->thread.debug.dbcr2  |= DBCR2_DAC12M;
 	else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
-		child->thread.dbcr2  |= DBCR2_DAC12MX;
+		child->thread.debug.dbcr2  |= DBCR2_DAC12MX;
 	else	/* PPC_BREAKPOINT_MODE_MASK */
-		child->thread.dbcr2  |= DBCR2_DAC12MM;
+		child->thread.debug.dbcr2  |= DBCR2_DAC12MM;
 	child->thread.regs->msr |= MSR_DE;
 
 	return 5;
@@ -1504,9 +1504,9 @@ static long ppc_del_hwdebug(struct task_struct *child, long data)
 		rc = del_dac(child, (int)data - 4);
 
 	if (!rc) {
-		if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0,
-					child->thread.dbcr1)) {
-			child->thread.dbcr0 &= ~DBCR0_IDM;
+		if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0,
+					child->thread.debug.dbcr1)) {
+			child->thread.debug.dbcr0 &= ~DBCR0_IDM;
 			child->thread.regs->msr &= ~MSR_DE;
 		}
 	}
@@ -1688,7 +1688,7 @@ long arch_ptrace(struct task_struct *child, long request,
 		if (addr > 0)
 			break;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-		ret = put_user(child->thread.dac1, datalp);
+		ret = put_user(child->thread.debug.dac1, datalp);
 #else
 		dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
 			     (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 95068bf..3e46b2c 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1294,7 +1294,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 	unsigned char tmp;
 	unsigned long new_msr = regs->msr;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-	unsigned long new_dbcr0 = current->thread.dbcr0;
+	unsigned long new_dbcr0 = current->thread.debug.dbcr0;
 #endif
 
 	for (i=0; i<ndbg; i++) {
@@ -1309,7 +1309,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 			} else {
 				new_dbcr0 &= ~DBCR0_IC;
 				if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
-						current->thread.dbcr1)) {
+						current->thread.debug.dbcr1)) {
 					new_msr &= ~MSR_DE;
 					new_dbcr0 &= ~DBCR0_IDM;
 				}
@@ -1344,7 +1344,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 	   the user is really doing something wrong. */
 	regs->msr = new_msr;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-	current->thread.dbcr0 = new_dbcr0;
+	current->thread.debug.dbcr0 = new_dbcr0;
 #endif
 
 	if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 83efa2f..86d5bd8 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -350,8 +350,8 @@ static inline int check_io_access(struct pt_regs *regs)
 #define REASON_TRAP		ESR_PTR
 
 /* single-step stuff */
-#define single_stepping(regs)	(current->thread.dbcr0 & DBCR0_IC)
-#define clear_single_step(regs)	(current->thread.dbcr0 &= ~DBCR0_IC)
+#define single_stepping(regs)	(current->thread.debug.dbcr0 & DBCR0_IC)
+#define clear_single_step(regs)	(current->thread.debug.dbcr0 &= ~DBCR0_IC)
 
 #else
 /* On non-4xx, the reason for the machine check or program
@@ -1389,7 +1389,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
 	if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
 		dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-		current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+		current->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE;
 #endif
 		do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
 			     5);
@@ -1400,24 +1400,24 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
 			     6);
 		changed |= 0x01;
 	}  else if (debug_status & DBSR_IAC1) {
-		current->thread.dbcr0 &= ~DBCR0_IAC1;
+		current->thread.debug.dbcr0 &= ~DBCR0_IAC1;
 		dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
 		do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
 			     1);
 		changed |= 0x01;
 	}  else if (debug_status & DBSR_IAC2) {
-		current->thread.dbcr0 &= ~DBCR0_IAC2;
+		current->thread.debug.dbcr0 &= ~DBCR0_IAC2;
 		do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
 			     2);
 		changed |= 0x01;
 	}  else if (debug_status & DBSR_IAC3) {
-		current->thread.dbcr0 &= ~DBCR0_IAC3;
+		current->thread.debug.dbcr0 &= ~DBCR0_IAC3;
 		dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
 		do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
 			     3);
 		changed |= 0x01;
 	}  else if (debug_status & DBSR_IAC4) {
-		current->thread.dbcr0 &= ~DBCR0_IAC4;
+		current->thread.debug.dbcr0 &= ~DBCR0_IAC4;
 		do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
 			     4);
 		changed |= 0x01;
@@ -1427,19 +1427,20 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
 	 * Check all other debug flags and see if that bit needs to be turned
 	 * back on or not.
 	 */
-	if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
+	if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0,
+			       current->thread.debug.dbcr1))
 		regs->msr |= MSR_DE;
 	else
 		/* Make sure the IDM flag is off */
-		current->thread.dbcr0 &= ~DBCR0_IDM;
+		current->thread.debug.dbcr0 &= ~DBCR0_IDM;
 
 	if (changed & 0x01)
-		mtspr(SPRN_DBCR0, current->thread.dbcr0);
+		mtspr(SPRN_DBCR0, current->thread.debug.dbcr0);
 }
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
-	current->thread.dbsr = debug_status;
+	current->thread.debug.dbsr = debug_status;
 
 	/* Hack alert: On BookE, Branch Taken stops on the branch itself, while
 	 * on server, it stops on the target of the branch. In order to simulate
@@ -1456,8 +1457,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 
 		/* Do the single step trick only when coming from userspace */
 		if (user_mode(regs)) {
-			current->thread.dbcr0 &= ~DBCR0_BT;
-			current->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+			current->thread.debug.dbcr0 &= ~DBCR0_BT;
+			current->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC;
 			regs->msr |= MSR_DE;
 			return;
 		}
@@ -1485,13 +1486,13 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 			return;
 
 		if (user_mode(regs)) {
-			current->thread.dbcr0 &= ~DBCR0_IC;
-			if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
-					       current->thread.dbcr1))
+			current->thread.debug.dbcr0 &= ~DBCR0_IC;
+			if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0,
+					       current->thread.debug.dbcr1))
 				regs->msr |= MSR_DE;
 			else
 				/* Make sure the IDM bit is off */
-				current->thread.dbcr0 &= ~DBCR0_IDM;
+				current->thread.debug.dbcr0 &= ~DBCR0_IDM;
 		}
 
 		_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/6 v5] powerpc: export debug registers save function for KVM
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 1/6 v5] powerpc: remove unnecessary line continuations Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 2/6 v5] powerpc: move debug registers in a structure Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  2013-06-27  4:47   ` Stephen Rothwell
  2013-06-26  5:42 ` [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction Bharat Bhushan
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

KVM need this function when switching from vcpu to user-space
thread. My subsequent patch will use this function.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/switch_to.h |    4 ++++
 arch/powerpc/kernel/process.c        |    3 ++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 200d763..50b357f 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -30,6 +30,10 @@ extern void enable_kernel_spe(void);
 extern void giveup_spe(struct task_struct *);
 extern void load_up_spe(struct task_struct *);
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+extern void switch_booke_debug_regs(struct thread_struct *new_thread);
+#endif
+
 #ifndef CONFIG_SMP
 extern void discard_lazy_cpu_state(void);
 #else
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 01ff496..da586aa 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -362,12 +362,13 @@ static void prime_debug_regs(struct thread_struct *thread)
  * debug registers, set the debug registers from the values
  * stored in the new thread.
  */
-static void switch_booke_debug_regs(struct thread_struct *new_thread)
+void switch_booke_debug_regs(struct thread_struct *new_thread)
 {
 	if ((current->thread.debug.dbcr0 & DBCR0_IDM)
 		|| (new_thread->debug.dbcr0 & DBCR0_IDM))
 			prime_debug_regs(new_thread);
 }
+EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
 #else	/* !CONFIG_PPC_ADV_DEBUG_REGS */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
 static void set_debug_reg_defaults(struct thread_struct *thread)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
                   ` (2 preceding siblings ...)
  2013-06-26  5:42 ` [PATCH 3/6 v5] powerpc: export debug registers save function for KVM Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  2013-06-26  6:54   ` tiejun.chen
  2013-06-26  5:42 ` [PATCH 5/6 v5] KVM: PPC: Using "struct debug_reg" Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 6/6 v5] KVM: PPC: Add userspace debug stub support Bharat Bhushan
  5 siblings, 1 reply; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

"ehpriv" instruction is used for setting software breakpoints
by user space. This patch adds support to exit to user space
with "run->debug" have relevant information.

As this is the first point we are using run->debug, also defined
the run->debug structure.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/disassemble.h |    4 ++++
 arch/powerpc/include/uapi/asm/kvm.h    |   21 +++++++++++++++++----
 arch/powerpc/kvm/e500_emulate.c        |   27 +++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/disassemble.h b/arch/powerpc/include/asm/disassemble.h
index 9b198d1..856f8de 100644
--- a/arch/powerpc/include/asm/disassemble.h
+++ b/arch/powerpc/include/asm/disassemble.h
@@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst)
 	return inst & 0xffff;
 }
 
+static inline unsigned int get_oc(u32 inst)
+{
+	return (inst >> 11) & 0x7fff;
+}
 #endif /* __ASM_PPC_DISASSEMBLE_H__ */
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 0fb1a6e..ded0607 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -269,7 +269,24 @@ struct kvm_fpu {
 	__u64 fpr[32];
 };
 
+/*
+ * Defines for h/w breakpoint, watchpoint (read, write or both) and
+ * software breakpoint.
+ * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
+ * for KVM_DEBUG_EXIT.
+ */
+#define KVMPPC_DEBUG_NONE		0x0
+#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
+#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
+#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
 struct kvm_debug_exit_arch {
+	__u64 address;
+	/*
+	 * exiting to userspace because of h/w breakpoint, watchpoint
+	 * (read, write or both) and software breakpoint.
+	 */
+	__u32 status;
+	__u32 reserved;
 };
 
 /* for KVM_SET_GUEST_DEBUG */
@@ -281,10 +298,6 @@ struct kvm_guest_debug_arch {
 		 * Type denotes h/w breakpoint, read watchpoint, write
 		 * watchpoint or watchpoint (both read and write).
 		 */
-#define KVMPPC_DEBUG_NONE		0x0
-#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
-#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
-#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
 		__u32 type;
 		__u32 reserved;
 	} bp[16];
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index b10a012..dab9d07 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -26,6 +26,8 @@
 #define XOP_TLBRE   946
 #define XOP_TLBWE   978
 #define XOP_TLBILX  18
+#define XOP_EHPRIV  270
+#define EHPRIV_OC_DEBUG 0
 
 #ifdef CONFIG_KVM_E500MC
 static int dbell2prio(ulong param)
@@ -82,6 +84,26 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
 }
 #endif
 
+static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
+				   unsigned int inst, int *advance)
+{
+	int emulated = EMULATE_DONE;
+
+	switch (get_oc(inst)) {
+	case EHPRIV_OC_DEBUG:
+		run->exit_reason = KVM_EXIT_DEBUG;
+		run->debug.arch.address = vcpu->arch.pc;
+		run->debug.arch.status = 0;
+		kvmppc_account_exit(vcpu, DEBUG_EXITS);
+		emulated = EMULATE_EXIT_USER;
+		*advance = 0;
+		break;
+	default:
+		emulated = EMULATE_FAIL;
+	}
+	return emulated;
+}
+
 int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                            unsigned int inst, int *advance)
 {
@@ -130,6 +152,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
 			emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
 			break;
 
+		case XOP_EHPRIV:
+			emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
+							   advance);
+			break;
+
 		default:
 			emulated = EMULATE_FAIL;
 		}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/6 v5] KVM: PPC: Using "struct debug_reg"
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
                   ` (3 preceding siblings ...)
  2013-06-26  5:42 ` [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  2013-06-26  5:42 ` [PATCH 6/6 v5] KVM: PPC: Add userspace debug stub support Bharat Bhushan
  5 siblings, 0 replies; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

For KVM also use the "struct debug_reg" defined in asm/processor.h

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h |   13 +------------
 arch/powerpc/kvm/booke.c            |   34 ++++++++++++++++++++++++----------
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index af326cd..838a577 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -381,17 +381,6 @@ struct kvmppc_slb {
 #define KVMPPC_EPR_USER		1 /* exit to userspace to fill EPR */
 #define KVMPPC_EPR_KERNEL	2 /* in-kernel irqchip */
 
-struct kvmppc_booke_debug_reg {
-	u32 dbcr0;
-	u32 dbcr1;
-	u32 dbcr2;
-#ifdef CONFIG_KVM_E500MC
-	u32 dbcr4;
-#endif
-	u64 iac[KVMPPC_BOOKE_MAX_IAC];
-	u64 dac[KVMPPC_BOOKE_MAX_DAC];
-};
-
 #define KVMPPC_IRQ_DEFAULT	0
 #define KVMPPC_IRQ_MPIC		1
 #define KVMPPC_IRQ_XICS		2
@@ -535,7 +524,7 @@ struct kvm_vcpu_arch {
 	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
-	struct kvmppc_booke_debug_reg dbg_reg;
+	struct debug_reg dbg_reg;
 #endif
 	gpa_t paddr_accessed;
 	gva_t vaddr_accessed;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 62d4ece..3e9fc1d 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1424,7 +1424,6 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	int r = 0;
 	union kvmppc_one_reg val;
 	int size;
-	long int i;
 
 	size = one_reg_size(reg->id);
 	if (size > sizeof(val))
@@ -1432,16 +1431,24 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac1);
+		break;
 	case KVM_REG_PPC_IAC2:
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac2);
+		break;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case KVM_REG_PPC_IAC3:
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac3);
+		break;
 	case KVM_REG_PPC_IAC4:
-		i = reg->id - KVM_REG_PPC_IAC1;
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac[i]);
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.iac4);
 		break;
+#endif
 	case KVM_REG_PPC_DAC1:
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac1);
+		break;
 	case KVM_REG_PPC_DAC2:
-		i = reg->id - KVM_REG_PPC_DAC1;
-		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac[i]);
+		val = get_reg_val(reg->id, vcpu->arch.dbg_reg.dac2);
 		break;
 	case KVM_REG_PPC_EPR: {
 		u32 epr = get_guest_epr(vcpu);
@@ -1481,7 +1488,6 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	int r = 0;
 	union kvmppc_one_reg val;
 	int size;
-	long int i;
 
 	size = one_reg_size(reg->id);
 	if (size > sizeof(val))
@@ -1492,16 +1498,24 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 
 	switch (reg->id) {
 	case KVM_REG_PPC_IAC1:
+		vcpu->arch.dbg_reg.iac1 = set_reg_val(reg->id, val);
+		break;
 	case KVM_REG_PPC_IAC2:
+		vcpu->arch.dbg_reg.iac2 = set_reg_val(reg->id, val);
+		break;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
 	case KVM_REG_PPC_IAC3:
+		vcpu->arch.dbg_reg.iac3 = set_reg_val(reg->id, val);
+		break;
 	case KVM_REG_PPC_IAC4:
-		i = reg->id - KVM_REG_PPC_IAC1;
-		vcpu->arch.dbg_reg.iac[i] = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.iac4 = set_reg_val(reg->id, val);
 		break;
+#endif
 	case KVM_REG_PPC_DAC1:
+		vcpu->arch.dbg_reg.dac1 = set_reg_val(reg->id, val);
+		break;
 	case KVM_REG_PPC_DAC2:
-		i = reg->id - KVM_REG_PPC_DAC1;
-		vcpu->arch.dbg_reg.dac[i] = set_reg_val(reg->id, val);
+		vcpu->arch.dbg_reg.dac2 = set_reg_val(reg->id, val);
 		break;
 	case KVM_REG_PPC_EPR: {
 		u32 new_epr = set_reg_val(reg->id, val);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/6 v5] KVM: PPC: Add userspace debug stub support
  2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
                   ` (4 preceding siblings ...)
  2013-06-26  5:42 ` [PATCH 5/6 v5] KVM: PPC: Using "struct debug_reg" Bharat Bhushan
@ 2013-06-26  5:42 ` Bharat Bhushan
  5 siblings, 0 replies; 13+ messages in thread
From: Bharat Bhushan @ 2013-06-26  5:42 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf, scottwood, tiejun.chen, benh, linuxppc-dev,
	linux-kernel, mikey
  Cc: Bharat Bhushan

This patch adds the debug stub support on booke/bookehv.
Now QEMU debug stub can use hw breakpoint, watchpoint and
software breakpoint to debug guest.

This is how we save/restore debug register context when switching
between guest, userspace and kernel user-process:

When QEMU is running
 -> thread->debug_reg == QEMU debug register context.
 -> Kernel will handle switching the debug register on context switch.
 -> no vcpu_load() called

QEMU makes ioctls (except RUN)
 -> This will call vcpu_load()
 -> should not change context.
 -> Some ioctls can change vcpu debug register, context saved in vcpu->debug_regs

QEMU Makes RUN ioctl
 -> Save thread->debug_reg on STACK
 -> Store thread->debug_reg == vcpu->debug_reg
 -> load thread->debug_reg
 -> RUN VCPU ( So thread points to vcpu context )

Context switch happens When VCPU running
 -> makes vcpu_load() should not load any context
 -> kernel loads the vcpu context as thread->debug_regs points to vcpu context.

On heavyweight_exit
 -> Load the context saved on stack in thread->debug_reg

Currently we do not support debug resource emulation to guest,
On debug exception, always exit to user space irrespective of
user space is expecting the debug exception or not. If this is
unexpected exception (breakpoint/watchpoint event not set by
userspace) then let us leave the action on user space. This
is similar to what it was before, only thing is that now we
have proper exit state available to user space.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h |    3 +
 arch/powerpc/include/uapi/asm/kvm.h |    1 +
 arch/powerpc/kvm/booke.c            |  239 ++++++++++++++++++++++++++++++++---
 arch/powerpc/kvm/booke.h            |    5 +
 4 files changed, 230 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 838a577..aeb490d 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -524,7 +524,10 @@ struct kvm_vcpu_arch {
 	u32 eptcfg;
 	u32 epr;
 	u32 crit_save;
+	/* guest debug registers*/
 	struct debug_reg dbg_reg;
+	/* hardware visible debug registers when in guest state */
+	struct debug_reg shadow_dbg_reg;
 #endif
 	gpa_t paddr_accessed;
 	gva_t vaddr_accessed;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ded0607..f5077c2 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -27,6 +27,7 @@
 #define __KVM_HAVE_PPC_SMT
 #define __KVM_HAVE_IRQCHIP
 #define __KVM_HAVE_IRQ_LINE
+#define __KVM_HAVE_GUEST_DEBUG
 
 struct kvm_regs {
 	__u64 pc;
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 3e9fc1d..8cd8d41 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -133,6 +133,29 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 #endif
 }
 
+static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
+{
+	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
+#ifndef CONFIG_KVM_BOOKE_HV
+	vcpu->arch.shadow_msr &= ~MSR_DE;
+	vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_DE;
+#endif
+
+	/* Force enable debug interrupts when user space wants to debug */
+	if (vcpu->guest_debug) {
+#ifdef CONFIG_KVM_BOOKE_HV
+		/*
+		 * Since there is no shadow MSR, sync MSR_DE into the guest
+		 * visible MSR.
+		 */
+		vcpu->arch.shared->msr |= MSR_DE;
+#else
+		vcpu->arch.shadow_msr |= MSR_DE;
+		vcpu->arch.shared->msr &= ~MSR_DE;
+#endif
+	}
+}
+
 /*
  * Helper function for "full" MSR writes.  No need to call this if only
  * EE/CE/ME/DE/RI are changing.
@@ -150,6 +173,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
 	kvmppc_mmu_msr_notify(vcpu, old_msr);
 	kvmppc_vcpu_sync_spe(vcpu);
 	kvmppc_vcpu_sync_fpu(vcpu);
+	kvmppc_vcpu_sync_debug(vcpu);
 }
 
 static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
@@ -655,6 +679,7 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
 int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
 	int ret, s;
+	struct thread_struct thread;
 #ifdef CONFIG_PPC_FPU
 	unsigned int fpscr;
 	int fpexc_mode;
@@ -698,12 +723,21 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
 	kvmppc_load_guest_fp(vcpu);
 #endif
+	/* Switch to guest debug context */
+	thread.debug = vcpu->arch.shadow_dbg_reg;
+	switch_booke_debug_regs(&thread);
+	thread.debug = current->thread.debug;
+	current->thread.debug = vcpu->arch.shadow_dbg_reg;
 
 	ret = __kvmppc_vcpu_run(kvm_run, vcpu);
 
 	/* No need for kvm_guest_exit. It's done in handle_exit.
 	   We also get here with interrupts enabled. */
 
+	/* Switch back to user space debug context */
+	switch_booke_debug_regs(&thread);
+	current->thread.debug = thread.debug;
+
 #ifdef CONFIG_PPC_FPU
 	kvmppc_save_guest_fp(vcpu);
 
@@ -759,6 +793,30 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 	}
 }
 
+static int kvmppc_handle_debug(struct kvm_run *run, struct kvm_vcpu *vcpu)
+{
+	struct debug_reg *dbg_reg = &(vcpu->arch.shadow_dbg_reg);
+	u32 dbsr = vcpu->arch.dbsr;
+
+	run->debug.arch.status = 0;
+	run->debug.arch.address = vcpu->arch.pc;
+
+	if (dbsr & (DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4)) {
+		run->debug.arch.status |= KVMPPC_DEBUG_BREAKPOINT;
+	} else {
+		if (dbsr & (DBSR_DAC1W | DBSR_DAC2W))
+			run->debug.arch.status |= KVMPPC_DEBUG_WATCH_WRITE;
+		else if (dbsr & (DBSR_DAC1R | DBSR_DAC2R))
+			run->debug.arch.status |= KVMPPC_DEBUG_WATCH_READ;
+		if (dbsr & (DBSR_DAC1R | DBSR_DAC1W))
+			run->debug.arch.address = dbg_reg->dac1;
+		else if (dbsr & (DBSR_DAC2R | DBSR_DAC2W))
+			run->debug.arch.address = dbg_reg->dac2;
+	}
+
+	return RESUME_HOST;
+}
+
 static void kvmppc_fill_pt_regs(struct pt_regs *regs)
 {
 	ulong r1, ip, msr, lr;
@@ -819,6 +877,11 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
 	case BOOKE_INTERRUPT_CRITICAL:
 		unknown_exception(&regs);
 		break;
+	case BOOKE_INTERRUPT_DEBUG:
+		/* Save DBSR before preemption is enabled */
+		vcpu->arch.dbsr = mfspr(SPRN_DBSR);
+		kvmppc_clear_dbsr();
+		break;
 	}
 }
 
@@ -1118,18 +1181,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	}
 
 	case BOOKE_INTERRUPT_DEBUG: {
-		u32 dbsr;
-
-		vcpu->arch.pc = mfspr(SPRN_CSRR0);
-
-		/* clear IAC events in DBSR register */
-		dbsr = mfspr(SPRN_DBSR);
-		dbsr &= DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4;
-		mtspr(SPRN_DBSR, dbsr);
-
-		run->exit_reason = KVM_EXIT_DEBUG;
+		r = kvmppc_handle_debug(run, vcpu);
+		if (r == RESUME_HOST)
+			run->exit_reason = KVM_EXIT_DEBUG;
 		kvmppc_account_exit(vcpu, DEBUG_EXITS);
-		r = RESUME_HOST;
 		break;
 	}
 
@@ -1180,7 +1235,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 	kvmppc_set_msr(vcpu, 0);
 
 #ifndef CONFIG_KVM_BOOKE_HV
-	vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
+	vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
 	vcpu->arch.shadow_pid = 1;
 	vcpu->arch.shared->msr = 0;
 #endif
@@ -1557,12 +1612,6 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	return r;
 }
 
-int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
-					 struct kvm_guest_debug *dbg)
-{
-	return -EINVAL;
-}
-
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
 	return -ENOTSUPP;
@@ -1668,6 +1717,157 @@ void kvmppc_decrementer_func(unsigned long data)
 	kvmppc_set_tsr_bits(vcpu, TSR_DIS);
 }
 
+static int kvmppc_booke_add_breakpoint(struct debug_reg *dbg_reg,
+				       uint64_t addr, int index)
+{
+	switch (index) {
+	case 0:
+		dbg_reg->dbcr0 |= DBCR0_IAC1;
+		dbg_reg->iac1 = addr;
+		break;
+	case 1:
+		dbg_reg->dbcr0 |= DBCR0_IAC2;
+		dbg_reg->iac2 = addr;
+		break;
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	case 2:
+		dbg_reg->dbcr0 |= DBCR0_IAC3;
+		dbg_reg->iac3 = addr;
+		break;
+	case 3:
+		dbg_reg->dbcr0 |= DBCR0_IAC4;
+		dbg_reg->iac4 = addr;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	dbg_reg->dbcr0 |= DBCR0_IDM;
+	return 0;
+}
+
+static int kvmppc_booke_add_watchpoint(struct debug_reg *dbg_reg, uint64_t addr,
+				       int type, int index)
+{
+	switch (index) {
+	case 0:
+		if (type & KVMPPC_DEBUG_WATCH_READ)
+			dbg_reg->dbcr0 |= DBCR0_DAC1R;
+		if (type & KVMPPC_DEBUG_WATCH_WRITE)
+			dbg_reg->dbcr0 |= DBCR0_DAC1W;
+		dbg_reg->dac1 = addr;
+		break;
+	case 1:
+		if (type & KVMPPC_DEBUG_WATCH_READ)
+			dbg_reg->dbcr0 |= DBCR0_DAC2R;
+		if (type & KVMPPC_DEBUG_WATCH_WRITE)
+			dbg_reg->dbcr0 |= DBCR0_DAC2W;
+		dbg_reg->dac2 = addr;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dbg_reg->dbcr0 |= DBCR0_IDM;
+	return 0;
+}
+void kvm_guest_protect_msr(struct kvm_vcpu *vcpu, ulong prot_bitmap, bool set)
+{
+	/* XXX: Add similar MSR protection for BookE-PR */
+#ifdef CONFIG_KVM_BOOKE_HV
+	BUG_ON(prot_bitmap & ~(MSRP_UCLEP | MSRP_DEP | MSRP_PMMP));
+	if (set) {
+		if (prot_bitmap & MSR_UCLE)
+			vcpu->arch.shadow_msrp |= MSRP_UCLEP;
+		if (prot_bitmap & MSR_DE)
+			vcpu->arch.shadow_msrp |= MSRP_DEP;
+		if (prot_bitmap & MSR_PMM)
+			vcpu->arch.shadow_msrp |= MSRP_PMMP;
+	} else {
+		if (prot_bitmap & MSR_UCLE)
+			vcpu->arch.shadow_msrp &= ~MSRP_UCLEP;
+		if (prot_bitmap & MSR_DE)
+			vcpu->arch.shadow_msrp &= ~MSRP_DEP;
+		if (prot_bitmap & MSR_PMM)
+			vcpu->arch.shadow_msrp &= ~MSRP_PMMP;
+	}
+#endif
+}
+
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					 struct kvm_guest_debug *dbg)
+{
+	struct debug_reg *dbg_reg;
+	int n, b = 0, w = 0;
+
+	if (!(dbg->control & KVM_GUESTDBG_ENABLE)) {
+		vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
+		vcpu->guest_debug = 0;
+		kvm_guest_protect_msr(vcpu, MSR_DE, false);
+		return 0;
+	}
+
+	kvm_guest_protect_msr(vcpu, MSR_DE, true);
+	vcpu->guest_debug = dbg->control;
+	vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
+	/* Set DBCR0_EDM in guest visible DBCR0 register. */
+	vcpu->arch.dbg_reg.dbcr0 = DBCR0_EDM;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+
+	/* Code below handles only HW breakpoints */
+	dbg_reg = &(vcpu->arch.shadow_dbg_reg);
+
+#ifdef CONFIG_KVM_BOOKE_HV
+	/*
+	 * On BookE-HV (e500mc) the guest is always executed with MSR.GS=1
+	 * DBCR1 and DBCR2 are set to trigger debug events when MSR.PR is 0
+	 */
+	dbg_reg->dbcr1 = 0;
+	dbg_reg->dbcr2 = 0;
+#else
+	/*
+	 * On BookE-PR (e500v2) the guest is always executed with MSR.PR=1
+	 * We set DBCR1 and DBCR2 to only trigger debug events when MSR.PR
+	 * is set.
+	 */
+	dbg_reg->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US | DBCR1_IAC3US |
+			  DBCR1_IAC4US;
+	dbg_reg->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+#endif
+
+	if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+		return 0;
+
+	for (n = 0; n < (KVMPPC_BOOKE_IAC_NUM + KVMPPC_BOOKE_DAC_NUM); n++) {
+		uint64_t addr = dbg->arch.bp[n].addr;
+		uint32_t type = dbg->arch.bp[n].type;
+
+		if (type == KVMPPC_DEBUG_NONE)
+			continue;
+
+		if (type & !(KVMPPC_DEBUG_WATCH_READ |
+			     KVMPPC_DEBUG_WATCH_WRITE |
+			     KVMPPC_DEBUG_BREAKPOINT))
+			return -EINVAL;
+
+		if (type & KVMPPC_DEBUG_BREAKPOINT) {
+			/* Setting H/W breakpoint */
+			if (kvmppc_booke_add_breakpoint(dbg_reg, addr, b++))
+				return -EINVAL;
+		} else {
+			/* Setting H/W watchpoint */
+			if (kvmppc_booke_add_watchpoint(dbg_reg, addr,
+							type, w++))
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	vcpu->cpu = smp_processor_id();
@@ -1678,6 +1878,9 @@ void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu)
 {
 	current->thread.kvm_vcpu = NULL;
 	vcpu->cpu = -1;
+
+	/* Clear pending debug event in DBSR */
+	kvmppc_clear_dbsr();
 }
 
 int __init kvmppc_booke_init(void)
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index 5fd1ba6..a1ff67d 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -129,4 +129,9 @@ static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu)
 		giveup_fpu(current);
 #endif
 }
+
+static inline void kvmppc_clear_dbsr(void)
+{
+	mtspr(SPRN_DBSR, mfspr(SPRN_DBSR));
+}
 #endif /* __KVM_BOOKE_H__ */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  5:42 ` [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction Bharat Bhushan
@ 2013-06-26  6:54   ` tiejun.chen
  2013-06-26  8:44     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 13+ messages in thread
From: tiejun.chen @ 2013-06-26  6:54 UTC (permalink / raw)
  To: Bharat Bhushan
  Cc: mikey, kvm, agraf, kvm-ppc, linux-kernel, Bharat Bhushan,
	scottwood, linuxppc-dev

On 06/26/2013 01:42 PM, Bharat Bhushan wrote:
> "ehpriv" instruction is used for setting software breakpoints
> by user space. This patch adds support to exit to user space
> with "run->debug" have relevant information.
>
> As this is the first point we are using run->debug, also defined
> the run->debug structure.
>
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
>   arch/powerpc/include/asm/disassemble.h |    4 ++++
>   arch/powerpc/include/uapi/asm/kvm.h    |   21 +++++++++++++++++----
>   arch/powerpc/kvm/e500_emulate.c        |   27 +++++++++++++++++++++++++++
>   3 files changed, 48 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/disassemble.h b/arch/powerpc/include/asm/disassemble.h
> index 9b198d1..856f8de 100644
> --- a/arch/powerpc/include/asm/disassemble.h
> +++ b/arch/powerpc/include/asm/disassemble.h
> @@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst)
>   	return inst & 0xffff;
>   }
>
> +static inline unsigned int get_oc(u32 inst)
> +{
> +	return (inst >> 11) & 0x7fff;
> +}
>   #endif /* __ASM_PPC_DISASSEMBLE_H__ */
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index 0fb1a6e..ded0607 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -269,7 +269,24 @@ struct kvm_fpu {
>   	__u64 fpr[32];
>   };
>
> +/*
> + * Defines for h/w breakpoint, watchpoint (read, write or both) and
> + * software breakpoint.
> + * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
> + * for KVM_DEBUG_EXIT.
> + */
> +#define KVMPPC_DEBUG_NONE		0x0
> +#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
> +#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
> +#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>   struct kvm_debug_exit_arch {
> +	__u64 address;
> +	/*
> +	 * exiting to userspace because of h/w breakpoint, watchpoint
> +	 * (read, write or both) and software breakpoint.
> +	 */
> +	__u32 status;
> +	__u32 reserved;
>   };
>
>   /* for KVM_SET_GUEST_DEBUG */
> @@ -281,10 +298,6 @@ struct kvm_guest_debug_arch {
>   		 * Type denotes h/w breakpoint, read watchpoint, write
>   		 * watchpoint or watchpoint (both read and write).
>   		 */
> -#define KVMPPC_DEBUG_NONE		0x0
> -#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
> -#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
> -#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>   		__u32 type;
>   		__u32 reserved;
>   	} bp[16];
> diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
> index b10a012..dab9d07 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -26,6 +26,8 @@
>   #define XOP_TLBRE   946
>   #define XOP_TLBWE   978
>   #define XOP_TLBILX  18
> +#define XOP_EHPRIV  270
> +#define EHPRIV_OC_DEBUG 0

As I think the case, "OC = 0", is a bit specific since IIRC, if the OC
operand is omitted, its equal 0 by default. So I think we should start this OC 
value from 1 or other magic number.

And if possible, we'd better add some comments to describe this to make the OC 
definition readable.

Tiejun

>
>   #ifdef CONFIG_KVM_E500MC
>   static int dbell2prio(ulong param)
> @@ -82,6 +84,26 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
>   }
>   #endif
>
> +static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
> +				   unsigned int inst, int *advance)
> +{
> +	int emulated = EMULATE_DONE;
> +
> +	switch (get_oc(inst)) {
> +	case EHPRIV_OC_DEBUG:
> +		run->exit_reason = KVM_EXIT_DEBUG;
> +		run->debug.arch.address = vcpu->arch.pc;
> +		run->debug.arch.status = 0;
> +		kvmppc_account_exit(vcpu, DEBUG_EXITS);
> +		emulated = EMULATE_EXIT_USER;
> +		*advance = 0;
> +		break;
> +	default:
> +		emulated = EMULATE_FAIL;
> +	}
> +	return emulated;
> +}
> +
>   int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
>                              unsigned int inst, int *advance)
>   {
> @@ -130,6 +152,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
>   			emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
>   			break;
>
> +		case XOP_EHPRIV:
> +			emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
> +							   advance);
> +			break;
> +
>   		default:
>   			emulated = EMULATE_FAIL;
>   		}
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  6:54   ` tiejun.chen
@ 2013-06-26  8:44     ` Bhushan Bharat-R65777
  2013-06-26  9:17       ` tiejun.chen
  0 siblings, 1 reply; 13+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-06-26  8:44 UTC (permalink / raw)
  To: tiejun.chen
  Cc: Wood Scott-B07421, mikey, kvm, agraf, kvm-ppc, linux-kernel,
	linuxppc-dev

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogdGllanVuLmNoZW4gW21h
aWx0bzp0aWVqdW4uY2hlbkB3aW5kcml2ZXIuY29tXQ0KPiBTZW50OiBXZWRuZXNkYXksIEp1bmUg
MjYsIDIwMTMgMTI6MjUgUE0NCj4gVG86IEJodXNoYW4gQmhhcmF0LVI2NTc3Nw0KPiBDYzoga3Zt
LXBwY0B2Z2VyLmtlcm5lbC5vcmc7IGt2bUB2Z2VyLmtlcm5lbC5vcmc7IGFncmFmQHN1c2UuZGU7
IFdvb2QgU2NvdHQtDQo+IEIwNzQyMTsgYmVuaEBrZXJuZWwuY3Jhc2hpbmcub3JnOyBsaW51eHBw
Yy1kZXZAbGlzdHMub3psYWJzLm9yZzsgbGludXgtDQo+IGtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7
IG1pa2V5QG5ldWxpbmcub3JnOyBCaHVzaGFuIEJoYXJhdC1SNjU3NzcNCj4gU3ViamVjdDogUmU6
IFtQQVRDSCA0LzYgdjVdIEtWTTogUFBDOiBleGl0IHRvIHVzZXIgc3BhY2Ugb24gImVocHJpdiIg
aW5zdHJ1Y3Rpb24NCj4gDQo+IE9uIDA2LzI2LzIwMTMgMDE6NDIgUE0sIEJoYXJhdCBCaHVzaGFu
IHdyb3RlOg0KPiA+ICJlaHByaXYiIGluc3RydWN0aW9uIGlzIHVzZWQgZm9yIHNldHRpbmcgc29m
dHdhcmUgYnJlYWtwb2ludHMNCj4gPiBieSB1c2VyIHNwYWNlLiBUaGlzIHBhdGNoIGFkZHMgc3Vw
cG9ydCB0byBleGl0IHRvIHVzZXIgc3BhY2UNCj4gPiB3aXRoICJydW4tPmRlYnVnIiBoYXZlIHJl
bGV2YW50IGluZm9ybWF0aW9uLg0KPiA+DQo+ID4gQXMgdGhpcyBpcyB0aGUgZmlyc3QgcG9pbnQg
d2UgYXJlIHVzaW5nIHJ1bi0+ZGVidWcsIGFsc28gZGVmaW5lZA0KPiA+IHRoZSBydW4tPmRlYnVn
IHN0cnVjdHVyZS4NCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IEJoYXJhdCBCaHVzaGFuIDxiaGFy
YXQuYmh1c2hhbkBmcmVlc2NhbGUuY29tPg0KPiA+IC0tLQ0KPiA+ICAgYXJjaC9wb3dlcnBjL2lu
Y2x1ZGUvYXNtL2Rpc2Fzc2VtYmxlLmggfCAgICA0ICsrKysNCj4gPiAgIGFyY2gvcG93ZXJwYy9p
bmNsdWRlL3VhcGkvYXNtL2t2bS5oICAgIHwgICAyMSArKysrKysrKysrKysrKysrKy0tLS0NCj4g
PiAgIGFyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVsYXRlLmMgICAgICAgIHwgICAyNyArKysrKysr
KysrKysrKysrKysrKysrKysrKysNCj4gPiAgIDMgZmlsZXMgY2hhbmdlZCwgNDggaW5zZXJ0aW9u
cygrKSwgNCBkZWxldGlvbnMoLSkNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMv
aW5jbHVkZS9hc20vZGlzYXNzZW1ibGUuaA0KPiBiL2FyY2gvcG93ZXJwYy9pbmNsdWRlL2FzbS9k
aXNhc3NlbWJsZS5oDQo+ID4gaW5kZXggOWIxOThkMS4uODU2ZjhkZSAxMDA2NDQNCj4gPiAtLS0g
YS9hcmNoL3Bvd2VycGMvaW5jbHVkZS9hc20vZGlzYXNzZW1ibGUuaA0KPiA+ICsrKyBiL2FyY2gv
cG93ZXJwYy9pbmNsdWRlL2FzbS9kaXNhc3NlbWJsZS5oDQo+ID4gQEAgLTc3LDQgKzc3LDggQEAg
c3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgZ2V0X2QodTMyIGluc3QpDQo+ID4gICAJcmV0dXJu
IGluc3QgJiAweGZmZmY7DQo+ID4gICB9DQo+ID4NCj4gPiArc3RhdGljIGlubGluZSB1bnNpZ25l
ZCBpbnQgZ2V0X29jKHUzMiBpbnN0KQ0KPiA+ICt7DQo+ID4gKwlyZXR1cm4gKGluc3QgPj4gMTEp
ICYgMHg3ZmZmOw0KPiA+ICt9DQo+ID4gICAjZW5kaWYgLyogX19BU01fUFBDX0RJU0FTU0VNQkxF
X0hfXyAqLw0KPiA+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMvaW5jbHVkZS91YXBpL2FzbS9r
dm0uaA0KPiBiL2FyY2gvcG93ZXJwYy9pbmNsdWRlL3VhcGkvYXNtL2t2bS5oDQo+ID4gaW5kZXgg
MGZiMWE2ZS4uZGVkMDYwNyAxMDA2NDQNCj4gPiAtLS0gYS9hcmNoL3Bvd2VycGMvaW5jbHVkZS91
YXBpL2FzbS9rdm0uaA0KPiA+ICsrKyBiL2FyY2gvcG93ZXJwYy9pbmNsdWRlL3VhcGkvYXNtL2t2
bS5oDQo+ID4gQEAgLTI2OSw3ICsyNjksMjQgQEAgc3RydWN0IGt2bV9mcHUgew0KPiA+ICAgCV9f
dTY0IGZwclszMl07DQo+ID4gICB9Ow0KPiA+DQo+ID4gKy8qDQo+ID4gKyAqIERlZmluZXMgZm9y
IGgvdyBicmVha3BvaW50LCB3YXRjaHBvaW50IChyZWFkLCB3cml0ZSBvciBib3RoKSBhbmQNCj4g
PiArICogc29mdHdhcmUgYnJlYWtwb2ludC4NCj4gPiArICogVGhlc2UgYXJlIHVzZWQgYXMgInR5
cGUiIGluIEtWTV9TRVRfR1VFU1RfREVCVUcgaW9jdGwgYW5kICJzdGF0dXMiDQo+ID4gKyAqIGZv
ciBLVk1fREVCVUdfRVhJVC4NCj4gPiArICovDQo+ID4gKyNkZWZpbmUgS1ZNUFBDX0RFQlVHX05P
TkUJCTB4MA0KPiA+ICsjZGVmaW5lIEtWTVBQQ19ERUJVR19CUkVBS1BPSU5UCQkoMVVMIDw8IDEp
DQo+ID4gKyNkZWZpbmUgS1ZNUFBDX0RFQlVHX1dBVENIX1dSSVRFCSgxVUwgPDwgMikNCj4gPiAr
I2RlZmluZSBLVk1QUENfREVCVUdfV0FUQ0hfUkVBRAkJKDFVTCA8PCAzKQ0KPiA+ICAgc3RydWN0
IGt2bV9kZWJ1Z19leGl0X2FyY2ggew0KPiA+ICsJX191NjQgYWRkcmVzczsNCj4gPiArCS8qDQo+
ID4gKwkgKiBleGl0aW5nIHRvIHVzZXJzcGFjZSBiZWNhdXNlIG9mIGgvdyBicmVha3BvaW50LCB3
YXRjaHBvaW50DQo+ID4gKwkgKiAocmVhZCwgd3JpdGUgb3IgYm90aCkgYW5kIHNvZnR3YXJlIGJy
ZWFrcG9pbnQuDQo+ID4gKwkgKi8NCj4gPiArCV9fdTMyIHN0YXR1czsNCj4gPiArCV9fdTMyIHJl
c2VydmVkOw0KPiA+ICAgfTsNCj4gPg0KPiA+ICAgLyogZm9yIEtWTV9TRVRfR1VFU1RfREVCVUcg
Ki8NCj4gPiBAQCAtMjgxLDEwICsyOTgsNiBAQCBzdHJ1Y3Qga3ZtX2d1ZXN0X2RlYnVnX2FyY2gg
ew0KPiA+ICAgCQkgKiBUeXBlIGRlbm90ZXMgaC93IGJyZWFrcG9pbnQsIHJlYWQgd2F0Y2hwb2lu
dCwgd3JpdGUNCj4gPiAgIAkJICogd2F0Y2hwb2ludCBvciB3YXRjaHBvaW50IChib3RoIHJlYWQg
YW5kIHdyaXRlKS4NCj4gPiAgIAkJICovDQo+ID4gLSNkZWZpbmUgS1ZNUFBDX0RFQlVHX05PTkUJ
CTB4MA0KPiA+IC0jZGVmaW5lIEtWTVBQQ19ERUJVR19CUkVBS1BPSU5UCQkoMVVMIDw8IDEpDQo+
ID4gLSNkZWZpbmUgS1ZNUFBDX0RFQlVHX1dBVENIX1dSSVRFCSgxVUwgPDwgMikNCj4gPiAtI2Rl
ZmluZSBLVk1QUENfREVCVUdfV0FUQ0hfUkVBRAkJKDFVTCA8PCAzKQ0KPiA+ICAgCQlfX3UzMiB0
eXBlOw0KPiA+ICAgCQlfX3UzMiByZXNlcnZlZDsNCj4gPiAgIAl9IGJwWzE2XTsNCj4gPiBkaWZm
IC0tZ2l0IGEvYXJjaC9wb3dlcnBjL2t2bS9lNTAwX2VtdWxhdGUuYyBiL2FyY2gvcG93ZXJwYy9r
dm0vZTUwMF9lbXVsYXRlLmMNCj4gPiBpbmRleCBiMTBhMDEyLi5kYWI5ZDA3IDEwMDY0NA0KPiA+
IC0tLSBhL2FyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVsYXRlLmMNCj4gPiArKysgYi9hcmNoL3Bv
d2VycGMva3ZtL2U1MDBfZW11bGF0ZS5jDQo+ID4gQEAgLTI2LDYgKzI2LDggQEANCj4gPiAgICNk
ZWZpbmUgWE9QX1RMQlJFICAgOTQ2DQo+ID4gICAjZGVmaW5lIFhPUF9UTEJXRSAgIDk3OA0KPiA+
ICAgI2RlZmluZSBYT1BfVExCSUxYICAxOA0KPiA+ICsjZGVmaW5lIFhPUF9FSFBSSVYgIDI3MA0K
PiA+ICsjZGVmaW5lIEVIUFJJVl9PQ19ERUJVRyAwDQo+IA0KPiBBcyBJIHRoaW5rIHRoZSBjYXNl
LCAiT0MgPSAwIiwgaXMgYSBiaXQgc3BlY2lmaWMgc2luY2UgSUlSQywgaWYgdGhlIE9DDQo+IG9w
ZXJhbmQgaXMgb21pdHRlZCwgaXRzIGVxdWFsIDAgYnkgZGVmYXVsdC4gU28gSSB0aGluayB3ZSBz
aG91bGQgc3RhcnQgdGhpcyBPQw0KPiB2YWx1ZSBmcm9tIDEgb3Igb3RoZXIgbWFnaWMgbnVtYmVy
Lg0KDQplaHByaXYgaW5zdHJ1Y3Rpb24gaXMgZGVmaW5lZCB0byBiZSB1c2VkIGFzOg0KCWVocHJp
diBPQyAvLyB3aGVyZSBPQyBjYW4gYmUgMCwxLCAuLi4gbg0KYW5kIGluIGV4dGVuZGVkIGZvciBp
dCBjYW4gYmUgdXNlZCBhcw0KCWVocHJpdiAvLyBXaXRoIG5vIE9DLCBhbmQgaGVyZSBpdCBhc3N1
bWVzIE9DID0gMA0KU28gT0MgPSAwIGlzIG5vdCBzcGVjaWZpYyBidXQgImVocHJpdiIgaXMgc2Ft
ZSBhcyAiZWhwcml2IDAiLg0KDQpJIGRvIG5vdCB0aGluayBvZiBhbnkgc3BlY2lhbCByZWFzb24g
dG8gcmVzZXJ2ZSAiZWhwcml2IiBhbmQgImVocHJpdiAwIi4NCg0KVGhhbmtzDQotQmhhcmF0DQoN
Cj4gDQo+IEFuZCBpZiBwb3NzaWJsZSwgd2UnZCBiZXR0ZXIgYWRkIHNvbWUgY29tbWVudHMgdG8g
ZGVzY3JpYmUgdGhpcyB0byBtYWtlIHRoZSBPQw0KPiBkZWZpbml0aW9uIHJlYWRhYmxlLg0KPiAN
Cj4gVGllanVuDQo+IA0KPiA+DQo+ID4gICAjaWZkZWYgQ09ORklHX0tWTV9FNTAwTUMNCj4gPiAg
IHN0YXRpYyBpbnQgZGJlbGwycHJpbyh1bG9uZyBwYXJhbSkNCj4gPiBAQCAtODIsNiArODQsMjYg
QEAgc3RhdGljIGludCBrdm1wcGNfZTUwMF9lbXVsX21zZ3NuZChzdHJ1Y3Qga3ZtX3ZjcHUgKnZj
cHUsDQo+IGludCByYikNCj4gPiAgIH0NCj4gPiAgICNlbmRpZg0KPiA+DQo+ID4gK3N0YXRpYyBp
bnQga3ZtcHBjX2U1MDBfZW11bF9laHByaXYoc3RydWN0IGt2bV9ydW4gKnJ1biwgc3RydWN0IGt2
bV92Y3B1DQo+ICp2Y3B1LA0KPiA+ICsJCQkJICAgdW5zaWduZWQgaW50IGluc3QsIGludCAqYWR2
YW5jZSkNCj4gPiArew0KPiA+ICsJaW50IGVtdWxhdGVkID0gRU1VTEFURV9ET05FOw0KPiA+ICsN
Cj4gPiArCXN3aXRjaCAoZ2V0X29jKGluc3QpKSB7DQo+ID4gKwljYXNlIEVIUFJJVl9PQ19ERUJV
RzoNCj4gPiArCQlydW4tPmV4aXRfcmVhc29uID0gS1ZNX0VYSVRfREVCVUc7DQo+ID4gKwkJcnVu
LT5kZWJ1Zy5hcmNoLmFkZHJlc3MgPSB2Y3B1LT5hcmNoLnBjOw0KPiA+ICsJCXJ1bi0+ZGVidWcu
YXJjaC5zdGF0dXMgPSAwOw0KPiA+ICsJCWt2bXBwY19hY2NvdW50X2V4aXQodmNwdSwgREVCVUdf
RVhJVFMpOw0KPiA+ICsJCWVtdWxhdGVkID0gRU1VTEFURV9FWElUX1VTRVI7DQo+ID4gKwkJKmFk
dmFuY2UgPSAwOw0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJZGVmYXVsdDoNCj4gPiArCQllbXVsYXRl
ZCA9IEVNVUxBVEVfRkFJTDsNCj4gPiArCX0NCj4gPiArCXJldHVybiBlbXVsYXRlZDsNCj4gPiAr
fQ0KPiA+ICsNCj4gPiAgIGludCBrdm1wcGNfY29yZV9lbXVsYXRlX29wKHN0cnVjdCBrdm1fcnVu
ICpydW4sIHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwNCj4gPiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIHVuc2lnbmVkIGludCBpbnN0LCBpbnQgKmFkdmFuY2UpDQo+ID4gICB7DQo+ID4gQEAg
LTEzMCw2ICsxNTIsMTEgQEAgaW50IGt2bXBwY19jb3JlX2VtdWxhdGVfb3Aoc3RydWN0IGt2bV9y
dW4gKnJ1biwgc3RydWN0DQo+IGt2bV92Y3B1ICp2Y3B1LA0KPiA+ICAgCQkJZW11bGF0ZWQgPSBr
dm1wcGNfZTUwMF9lbXVsX3RsYml2YXgodmNwdSwgZWEpOw0KPiA+ICAgCQkJYnJlYWs7DQo+ID4N
Cj4gPiArCQljYXNlIFhPUF9FSFBSSVY6DQo+ID4gKwkJCWVtdWxhdGVkID0ga3ZtcHBjX2U1MDBf
ZW11bF9laHByaXYocnVuLCB2Y3B1LCBpbnN0LA0KPiA+ICsJCQkJCQkJICAgYWR2YW5jZSk7DQo+
ID4gKwkJCWJyZWFrOw0KPiA+ICsNCj4gPiAgIAkJZGVmYXVsdDoNCj4gPiAgIAkJCWVtdWxhdGVk
ID0gRU1VTEFURV9GQUlMOw0KPiA+ICAgCQl9DQo+ID4NCj4gDQoNCg==

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  8:44     ` Bhushan Bharat-R65777
@ 2013-06-26  9:17       ` tiejun.chen
  2013-06-26  9:27         ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 13+ messages in thread
From: tiejun.chen @ 2013-06-26  9:17 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, mikey, kvm, agraf, kvm-ppc, linux-kernel,
	linuxppc-dev

On 06/26/2013 04:44 PM, Bhushan Bharat-R65777 wrote:
>
>
>> -----Original Message-----
>> From: tiejun.chen [mailto:tiejun.chen@windriver.com]
>> Sent: Wednesday, June 26, 2013 12:25 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de; Wood Scott-
>> B07421; benh@kernel.crashing.org; linuxppc-dev@lists.ozlabs.org; linux-
>> kernel@vger.kernel.org; mikey@neuling.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
>>
>> On 06/26/2013 01:42 PM, Bharat Bhushan wrote:
>>> "ehpriv" instruction is used for setting software breakpoints
>>> by user space. This patch adds support to exit to user space
>>> with "run->debug" have relevant information.
>>>
>>> As this is the first point we are using run->debug, also defined
>>> the run->debug structure.
>>>
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>>    arch/powerpc/include/asm/disassemble.h |    4 ++++
>>>    arch/powerpc/include/uapi/asm/kvm.h    |   21 +++++++++++++++++----
>>>    arch/powerpc/kvm/e500_emulate.c        |   27 +++++++++++++++++++++++++++
>>>    3 files changed, 48 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/powerpc/include/asm/disassemble.h
>> b/arch/powerpc/include/asm/disassemble.h
>>> index 9b198d1..856f8de 100644
>>> --- a/arch/powerpc/include/asm/disassemble.h
>>> +++ b/arch/powerpc/include/asm/disassemble.h
>>> @@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst)
>>>    	return inst & 0xffff;
>>>    }
>>>
>>> +static inline unsigned int get_oc(u32 inst)
>>> +{
>>> +	return (inst >> 11) & 0x7fff;
>>> +}
>>>    #endif /* __ASM_PPC_DISASSEMBLE_H__ */
>>> diff --git a/arch/powerpc/include/uapi/asm/kvm.h
>> b/arch/powerpc/include/uapi/asm/kvm.h
>>> index 0fb1a6e..ded0607 100644
>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>> @@ -269,7 +269,24 @@ struct kvm_fpu {
>>>    	__u64 fpr[32];
>>>    };
>>>
>>> +/*
>>> + * Defines for h/w breakpoint, watchpoint (read, write or both) and
>>> + * software breakpoint.
>>> + * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
>>> + * for KVM_DEBUG_EXIT.
>>> + */
>>> +#define KVMPPC_DEBUG_NONE		0x0
>>> +#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
>>> +#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
>>> +#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>>>    struct kvm_debug_exit_arch {
>>> +	__u64 address;
>>> +	/*
>>> +	 * exiting to userspace because of h/w breakpoint, watchpoint
>>> +	 * (read, write or both) and software breakpoint.
>>> +	 */
>>> +	__u32 status;
>>> +	__u32 reserved;
>>>    };
>>>
>>>    /* for KVM_SET_GUEST_DEBUG */
>>> @@ -281,10 +298,6 @@ struct kvm_guest_debug_arch {
>>>    		 * Type denotes h/w breakpoint, read watchpoint, write
>>>    		 * watchpoint or watchpoint (both read and write).
>>>    		 */
>>> -#define KVMPPC_DEBUG_NONE		0x0
>>> -#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
>>> -#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
>>> -#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>>>    		__u32 type;
>>>    		__u32 reserved;
>>>    	} bp[16];
>>> diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
>>> index b10a012..dab9d07 100644
>>> --- a/arch/powerpc/kvm/e500_emulate.c
>>> +++ b/arch/powerpc/kvm/e500_emulate.c
>>> @@ -26,6 +26,8 @@
>>>    #define XOP_TLBRE   946
>>>    #define XOP_TLBWE   978
>>>    #define XOP_TLBILX  18
>>> +#define XOP_EHPRIV  270
>>> +#define EHPRIV_OC_DEBUG 0
>>
>> As I think the case, "OC = 0", is a bit specific since IIRC, if the OC
>> operand is omitted, its equal 0 by default. So I think we should start this OC
>> value from 1 or other magic number.
>
> ehpriv instruction is defined to be used as:
> 	ehpriv OC // where OC can be 0,1, ... n
> and in extended for it can be used as
> 	ehpriv // With no OC, and here it assumes OC = 0
> So OC = 0 is not specific but "ehpriv" is same as "ehpriv 0".

Yes, this is just what I mean.

>
> I do not think of any special reason to reserve "ehpriv" and "ehpriv 0".

So I still prefer we can reserve the 'ehpriv' without OC operand as one simple 
approach to test or develop something for KVM quickly because its really 
convenient to trap into the hypervisor only with one 'ehpriv' instruction easily.

But I have no further objection if you guys are fine to this ;-)

Tiejun

>
> Thanks
> -Bharat
>
>>
>> And if possible, we'd better add some comments to describe this to make the OC
>> definition readable.
>>
>> Tiejun
>>
>>>
>>>    #ifdef CONFIG_KVM_E500MC
>>>    static int dbell2prio(ulong param)
>>> @@ -82,6 +84,26 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu,
>> int rb)
>>>    }
>>>    #endif
>>>
>>> +static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu
>> *vcpu,
>>> +				   unsigned int inst, int *advance)
>>> +{
>>> +	int emulated = EMULATE_DONE;
>>> +
>>> +	switch (get_oc(inst)) {
>>> +	case EHPRIV_OC_DEBUG:
>>> +		run->exit_reason = KVM_EXIT_DEBUG;
>>> +		run->debug.arch.address = vcpu->arch.pc;
>>> +		run->debug.arch.status = 0;
>>> +		kvmppc_account_exit(vcpu, DEBUG_EXITS);
>>> +		emulated = EMULATE_EXIT_USER;
>>> +		*advance = 0;
>>> +		break;
>>> +	default:
>>> +		emulated = EMULATE_FAIL;
>>> +	}
>>> +	return emulated;
>>> +}
>>> +
>>>    int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
>>>                               unsigned int inst, int *advance)
>>>    {
>>> @@ -130,6 +152,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct
>> kvm_vcpu *vcpu,
>>>    			emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
>>>    			break;
>>>
>>> +		case XOP_EHPRIV:
>>> +			emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
>>> +							   advance);
>>> +			break;
>>> +
>>>    		default:
>>>    			emulated = EMULATE_FAIL;
>>>    		}
>>>
>>
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  9:17       ` tiejun.chen
@ 2013-06-26  9:27         ` Bhushan Bharat-R65777
  2013-06-26 10:33           ` Alexander Graf
  0 siblings, 1 reply; 13+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-06-26  9:27 UTC (permalink / raw)
  To: tiejun.chen
  Cc: Wood Scott-B07421, mikey, kvm, agraf, kvm-ppc, linux-kernel,
	linuxppc-dev

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogdGllanVuLmNoZW4gW21h
aWx0bzp0aWVqdW4uY2hlbkB3aW5kcml2ZXIuY29tXQ0KPiBTZW50OiBXZWRuZXNkYXksIEp1bmUg
MjYsIDIwMTMgMjo0NyBQTQ0KPiBUbzogQmh1c2hhbiBCaGFyYXQtUjY1Nzc3DQo+IENjOiBrdm0t
cHBjQHZnZXIua2VybmVsLm9yZzsga3ZtQHZnZXIua2VybmVsLm9yZzsgYWdyYWZAc3VzZS5kZTsg
V29vZCBTY290dC0NCj4gQjA3NDIxOyBiZW5oQGtlcm5lbC5jcmFzaGluZy5vcmc7IGxpbnV4cHBj
LWRldkBsaXN0cy5vemxhYnMub3JnOyBsaW51eC0NCj4ga2VybmVsQHZnZXIua2VybmVsLm9yZzsg
bWlrZXlAbmV1bGluZy5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRDSCA0LzYgdjVdIEtWTTogUFBD
OiBleGl0IHRvIHVzZXIgc3BhY2Ugb24gImVocHJpdiIgaW5zdHJ1Y3Rpb24NCj4gDQo+IE9uIDA2
LzI2LzIwMTMgMDQ6NDQgUE0sIEJodXNoYW4gQmhhcmF0LVI2NTc3NyB3cm90ZToNCj4gPg0KPiA+
DQo+ID4+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4+IEZyb206IHRpZWp1bi5jaGVu
IFttYWlsdG86dGllanVuLmNoZW5Ad2luZHJpdmVyLmNvbV0NCj4gPj4gU2VudDogV2VkbmVzZGF5
LCBKdW5lIDI2LCAyMDEzIDEyOjI1IFBNDQo+ID4+IFRvOiBCaHVzaGFuIEJoYXJhdC1SNjU3NzcN
Cj4gPj4gQ2M6IGt2bS1wcGNAdmdlci5rZXJuZWwub3JnOyBrdm1Admdlci5rZXJuZWwub3JnOyBh
Z3JhZkBzdXNlLmRlOyBXb29kDQo+ID4+IFNjb3R0LSBCMDc0MjE7IGJlbmhAa2VybmVsLmNyYXNo
aW5nLm9yZzsNCj4gPj4gbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IGxpbnV4LSBrZXJu
ZWxAdmdlci5rZXJuZWwub3JnOw0KPiA+PiBtaWtleUBuZXVsaW5nLm9yZzsgQmh1c2hhbiBCaGFy
YXQtUjY1Nzc3DQo+ID4+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggNC82IHY1XSBLVk06IFBQQzogZXhp
dCB0byB1c2VyIHNwYWNlIG9uICJlaHByaXYiDQo+ID4+IGluc3RydWN0aW9uDQo+ID4+DQo+ID4+
IE9uIDA2LzI2LzIwMTMgMDE6NDIgUE0sIEJoYXJhdCBCaHVzaGFuIHdyb3RlOg0KPiA+Pj4gImVo
cHJpdiIgaW5zdHJ1Y3Rpb24gaXMgdXNlZCBmb3Igc2V0dGluZyBzb2Z0d2FyZSBicmVha3BvaW50
cyBieQ0KPiA+Pj4gdXNlciBzcGFjZS4gVGhpcyBwYXRjaCBhZGRzIHN1cHBvcnQgdG8gZXhpdCB0
byB1c2VyIHNwYWNlIHdpdGgNCj4gPj4+ICJydW4tPmRlYnVnIiBoYXZlIHJlbGV2YW50IGluZm9y
bWF0aW9uLg0KPiA+Pj4NCj4gPj4+IEFzIHRoaXMgaXMgdGhlIGZpcnN0IHBvaW50IHdlIGFyZSB1
c2luZyBydW4tPmRlYnVnLCBhbHNvIGRlZmluZWQgdGhlDQo+ID4+PiBydW4tPmRlYnVnIHN0cnVj
dHVyZS4NCj4gPj4+DQo+ID4+PiBTaWduZWQtb2ZmLWJ5OiBCaGFyYXQgQmh1c2hhbiA8YmhhcmF0
LmJodXNoYW5AZnJlZXNjYWxlLmNvbT4NCj4gPj4+IC0tLQ0KPiA+Pj4gICAgYXJjaC9wb3dlcnBj
L2luY2x1ZGUvYXNtL2Rpc2Fzc2VtYmxlLmggfCAgICA0ICsrKysNCj4gPj4+ICAgIGFyY2gvcG93
ZXJwYy9pbmNsdWRlL3VhcGkvYXNtL2t2bS5oICAgIHwgICAyMSArKysrKysrKysrKysrKysrKy0t
LS0NCj4gPj4+ICAgIGFyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVsYXRlLmMgICAgICAgIHwgICAy
NyArKysrKysrKysrKysrKysrKysrKysrKysrKysNCj4gPj4+ICAgIDMgZmlsZXMgY2hhbmdlZCwg
NDggaW5zZXJ0aW9ucygrKSwgNCBkZWxldGlvbnMoLSkNCj4gPj4+DQo+ID4+PiBkaWZmIC0tZ2l0
IGEvYXJjaC9wb3dlcnBjL2luY2x1ZGUvYXNtL2Rpc2Fzc2VtYmxlLmgNCj4gPj4gYi9hcmNoL3Bv
d2VycGMvaW5jbHVkZS9hc20vZGlzYXNzZW1ibGUuaA0KPiA+Pj4gaW5kZXggOWIxOThkMS4uODU2
ZjhkZSAxMDA2NDQNCj4gPj4+IC0tLSBhL2FyY2gvcG93ZXJwYy9pbmNsdWRlL2FzbS9kaXNhc3Nl
bWJsZS5oDQo+ID4+PiArKysgYi9hcmNoL3Bvd2VycGMvaW5jbHVkZS9hc20vZGlzYXNzZW1ibGUu
aA0KPiA+Pj4gQEAgLTc3LDQgKzc3LDggQEAgc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgZ2V0
X2QodTMyIGluc3QpDQo+ID4+PiAgICAJcmV0dXJuIGluc3QgJiAweGZmZmY7DQo+ID4+PiAgICB9
DQo+ID4+Pg0KPiA+Pj4gK3N0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IGdldF9vYyh1MzIgaW5z
dCkgew0KPiA+Pj4gKwlyZXR1cm4gKGluc3QgPj4gMTEpICYgMHg3ZmZmOw0KPiA+Pj4gK30NCj4g
Pj4+ICAgICNlbmRpZiAvKiBfX0FTTV9QUENfRElTQVNTRU1CTEVfSF9fICovIGRpZmYgLS1naXQN
Cj4gPj4+IGEvYXJjaC9wb3dlcnBjL2luY2x1ZGUvdWFwaS9hc20va3ZtLmgNCj4gPj4gYi9hcmNo
L3Bvd2VycGMvaW5jbHVkZS91YXBpL2FzbS9rdm0uaA0KPiA+Pj4gaW5kZXggMGZiMWE2ZS4uZGVk
MDYwNyAxMDA2NDQNCj4gPj4+IC0tLSBhL2FyY2gvcG93ZXJwYy9pbmNsdWRlL3VhcGkvYXNtL2t2
bS5oDQo+ID4+PiArKysgYi9hcmNoL3Bvd2VycGMvaW5jbHVkZS91YXBpL2FzbS9rdm0uaA0KPiA+
Pj4gQEAgLTI2OSw3ICsyNjksMjQgQEAgc3RydWN0IGt2bV9mcHUgew0KPiA+Pj4gICAgCV9fdTY0
IGZwclszMl07DQo+ID4+PiAgICB9Ow0KPiA+Pj4NCj4gPj4+ICsvKg0KPiA+Pj4gKyAqIERlZmlu
ZXMgZm9yIGgvdyBicmVha3BvaW50LCB3YXRjaHBvaW50IChyZWFkLCB3cml0ZSBvciBib3RoKSBh
bmQNCj4gPj4+ICsgKiBzb2Z0d2FyZSBicmVha3BvaW50Lg0KPiA+Pj4gKyAqIFRoZXNlIGFyZSB1
c2VkIGFzICJ0eXBlIiBpbiBLVk1fU0VUX0dVRVNUX0RFQlVHIGlvY3RsIGFuZCAic3RhdHVzIg0K
PiA+Pj4gKyAqIGZvciBLVk1fREVCVUdfRVhJVC4NCj4gPj4+ICsgKi8NCj4gPj4+ICsjZGVmaW5l
IEtWTVBQQ19ERUJVR19OT05FCQkweDANCj4gPj4+ICsjZGVmaW5lIEtWTVBQQ19ERUJVR19CUkVB
S1BPSU5UCQkoMVVMIDw8IDEpDQo+ID4+PiArI2RlZmluZSBLVk1QUENfREVCVUdfV0FUQ0hfV1JJ
VEUJKDFVTCA8PCAyKQ0KPiA+Pj4gKyNkZWZpbmUgS1ZNUFBDX0RFQlVHX1dBVENIX1JFQUQJCSgx
VUwgPDwgMykNCj4gPj4+ICAgIHN0cnVjdCBrdm1fZGVidWdfZXhpdF9hcmNoIHsNCj4gPj4+ICsJ
X191NjQgYWRkcmVzczsNCj4gPj4+ICsJLyoNCj4gPj4+ICsJICogZXhpdGluZyB0byB1c2Vyc3Bh
Y2UgYmVjYXVzZSBvZiBoL3cgYnJlYWtwb2ludCwgd2F0Y2hwb2ludA0KPiA+Pj4gKwkgKiAocmVh
ZCwgd3JpdGUgb3IgYm90aCkgYW5kIHNvZnR3YXJlIGJyZWFrcG9pbnQuDQo+ID4+PiArCSAqLw0K
PiA+Pj4gKwlfX3UzMiBzdGF0dXM7DQo+ID4+PiArCV9fdTMyIHJlc2VydmVkOw0KPiA+Pj4gICAg
fTsNCj4gPj4+DQo+ID4+PiAgICAvKiBmb3IgS1ZNX1NFVF9HVUVTVF9ERUJVRyAqLw0KPiA+Pj4g
QEAgLTI4MSwxMCArMjk4LDYgQEAgc3RydWN0IGt2bV9ndWVzdF9kZWJ1Z19hcmNoIHsNCj4gPj4+
ICAgIAkJICogVHlwZSBkZW5vdGVzIGgvdyBicmVha3BvaW50LCByZWFkIHdhdGNocG9pbnQsIHdy
aXRlDQo+ID4+PiAgICAJCSAqIHdhdGNocG9pbnQgb3Igd2F0Y2hwb2ludCAoYm90aCByZWFkIGFu
ZCB3cml0ZSkuDQo+ID4+PiAgICAJCSAqLw0KPiA+Pj4gLSNkZWZpbmUgS1ZNUFBDX0RFQlVHX05P
TkUJCTB4MA0KPiA+Pj4gLSNkZWZpbmUgS1ZNUFBDX0RFQlVHX0JSRUFLUE9JTlQJCSgxVUwgPDwg
MSkNCj4gPj4+IC0jZGVmaW5lIEtWTVBQQ19ERUJVR19XQVRDSF9XUklURQkoMVVMIDw8IDIpDQo+
ID4+PiAtI2RlZmluZSBLVk1QUENfREVCVUdfV0FUQ0hfUkVBRAkJKDFVTCA8PCAzKQ0KPiA+Pj4g
ICAgCQlfX3UzMiB0eXBlOw0KPiA+Pj4gICAgCQlfX3UzMiByZXNlcnZlZDsNCj4gPj4+ICAgIAl9
IGJwWzE2XTsNCj4gPj4+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMva3ZtL2U1MDBfZW11bGF0
ZS5jDQo+ID4+PiBiL2FyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVsYXRlLmMgaW5kZXggYjEwYTAx
Mi4uZGFiOWQwNyAxMDA2NDQNCj4gPj4+IC0tLSBhL2FyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVs
YXRlLmMNCj4gPj4+ICsrKyBiL2FyY2gvcG93ZXJwYy9rdm0vZTUwMF9lbXVsYXRlLmMNCj4gPj4+
IEBAIC0yNiw2ICsyNiw4IEBADQo+ID4+PiAgICAjZGVmaW5lIFhPUF9UTEJSRSAgIDk0Ng0KPiA+
Pj4gICAgI2RlZmluZSBYT1BfVExCV0UgICA5NzgNCj4gPj4+ICAgICNkZWZpbmUgWE9QX1RMQklM
WCAgMTgNCj4gPj4+ICsjZGVmaW5lIFhPUF9FSFBSSVYgIDI3MA0KPiA+Pj4gKyNkZWZpbmUgRUhQ
UklWX09DX0RFQlVHIDANCj4gPj4NCj4gPj4gQXMgSSB0aGluayB0aGUgY2FzZSwgIk9DID0gMCIs
IGlzIGEgYml0IHNwZWNpZmljIHNpbmNlIElJUkMsIGlmIHRoZQ0KPiA+PiBPQyBvcGVyYW5kIGlz
IG9taXR0ZWQsIGl0cyBlcXVhbCAwIGJ5IGRlZmF1bHQuIFNvIEkgdGhpbmsgd2Ugc2hvdWxkDQo+
ID4+IHN0YXJ0IHRoaXMgT0MgdmFsdWUgZnJvbSAxIG9yIG90aGVyIG1hZ2ljIG51bWJlci4NCj4g
Pg0KPiA+IGVocHJpdiBpbnN0cnVjdGlvbiBpcyBkZWZpbmVkIHRvIGJlIHVzZWQgYXM6DQo+ID4g
CWVocHJpdiBPQyAvLyB3aGVyZSBPQyBjYW4gYmUgMCwxLCAuLi4gbiBhbmQgaW4gZXh0ZW5kZWQg
Zm9yIGl0IGNhbiBiZQ0KPiA+IHVzZWQgYXMNCj4gPiAJZWhwcml2IC8vIFdpdGggbm8gT0MsIGFu
ZCBoZXJlIGl0IGFzc3VtZXMgT0MgPSAwIFNvIE9DID0gMCBpcyBub3QNCj4gPiBzcGVjaWZpYyBi
dXQgImVocHJpdiIgaXMgc2FtZSBhcyAiZWhwcml2IDAiLg0KPiANCj4gWWVzLCB0aGlzIGlzIGp1
c3Qgd2hhdCBJIG1lYW4uDQo+IA0KPiA+DQo+ID4gSSBkbyBub3QgdGhpbmsgb2YgYW55IHNwZWNp
YWwgcmVhc29uIHRvIHJlc2VydmUgImVocHJpdiIgYW5kICJlaHByaXYgMCIuDQo+IA0KPiBTbyBJ
IHN0aWxsIHByZWZlciB3ZSBjYW4gcmVzZXJ2ZSB0aGUgJ2VocHJpdicgd2l0aG91dCBPQyBvcGVy
YW5kIGFzIG9uZSBzaW1wbGUNCj4gYXBwcm9hY2ggdG8gdGVzdCBvciBkZXZlbG9wIHNvbWV0aGlu
ZyBmb3IgS1ZNIHF1aWNrbHkgYmVjYXVzZSBpdHMgcmVhbGx5DQo+IGNvbnZlbmllbnQgdG8gdHJh
cCBpbnRvIHRoZSBoeXBlcnZpc29yIG9ubHkgd2l0aCBvbmUgJ2VocHJpdicgaW5zdHJ1Y3Rpb24N
Cj4gZWFzaWx5Lg0KPiANCj4gQnV0IEkgaGF2ZSBubyBmdXJ0aGVyIG9iamVjdGlvbiBpZiB5b3Ug
Z3V5cyBhcmUgZmluZSB0byB0aGlzIDstKQ0KDQpJIGNhbiBzZWUgdGhlIHVzaW5nICJlaHByaXYi
IGNhbiBiZSBhIGRlZmF1bHQgY2hvaWNlLiBCdXQgYWxsIGVodnByaXYgdHJhcCBpcyBoYW5kbGVk
IGF0IG9uZSBwbGFjZSAoaW4gYSBzaW5nbGUgZnVuY3Rpb24pIHNvIHRoZSBhY2NpZGVudGx5IG92
ZXJsYXAgd2l0aCBkZWJ1ZyBzaG91bGQgbm90IGJlIGFuIGlzc3VlLg0KDQpJIHRvbyBkbyBub3Qg
aGF2ZSBhbnkgc3Ryb25nIG9waW5pb24gdG8ga2VlcCBlaXRoZXIgd2F5LCBzbyB3YW50IHRvIGxl
YXZlIGFzIGlzIDstKS4NCg0KLUJoYXJhdA0KDQo+IA0KPiBUaWVqdW4NCj4gDQo+ID4NCj4gPiBU
aGFua3MNCj4gPiAtQmhhcmF0DQo+ID4NCj4gPj4NCj4gPj4gQW5kIGlmIHBvc3NpYmxlLCB3ZSdk
IGJldHRlciBhZGQgc29tZSBjb21tZW50cyB0byBkZXNjcmliZSB0aGlzIHRvDQo+ID4+IG1ha2Ug
dGhlIE9DIGRlZmluaXRpb24gcmVhZGFibGUuDQo+ID4+DQo+ID4+IFRpZWp1bg0KPiA+Pg0KPiA+
Pj4NCj4gPj4+ICAgICNpZmRlZiBDT05GSUdfS1ZNX0U1MDBNQw0KPiA+Pj4gICAgc3RhdGljIGlu
dCBkYmVsbDJwcmlvKHVsb25nIHBhcmFtKSBAQCAtODIsNiArODQsMjYgQEAgc3RhdGljIGludA0K
PiA+Pj4ga3ZtcHBjX2U1MDBfZW11bF9tc2dzbmQoc3RydWN0IGt2bV92Y3B1ICp2Y3B1LA0KPiA+
PiBpbnQgcmIpDQo+ID4+PiAgICB9DQo+ID4+PiAgICAjZW5kaWYNCj4gPj4+DQo+ID4+PiArc3Rh
dGljIGludCBrdm1wcGNfZTUwMF9lbXVsX2VocHJpdihzdHJ1Y3Qga3ZtX3J1biAqcnVuLCBzdHJ1
Y3QNCj4gPj4+ICtrdm1fdmNwdQ0KPiA+PiAqdmNwdSwNCj4gPj4+ICsJCQkJICAgdW5zaWduZWQg
aW50IGluc3QsIGludCAqYWR2YW5jZSkgew0KPiA+Pj4gKwlpbnQgZW11bGF0ZWQgPSBFTVVMQVRF
X0RPTkU7DQo+ID4+PiArDQo+ID4+PiArCXN3aXRjaCAoZ2V0X29jKGluc3QpKSB7DQo+ID4+PiAr
CWNhc2UgRUhQUklWX09DX0RFQlVHOg0KPiA+Pj4gKwkJcnVuLT5leGl0X3JlYXNvbiA9IEtWTV9F
WElUX0RFQlVHOw0KPiA+Pj4gKwkJcnVuLT5kZWJ1Zy5hcmNoLmFkZHJlc3MgPSB2Y3B1LT5hcmNo
LnBjOw0KPiA+Pj4gKwkJcnVuLT5kZWJ1Zy5hcmNoLnN0YXR1cyA9IDA7DQo+ID4+PiArCQlrdm1w
cGNfYWNjb3VudF9leGl0KHZjcHUsIERFQlVHX0VYSVRTKTsNCj4gPj4+ICsJCWVtdWxhdGVkID0g
RU1VTEFURV9FWElUX1VTRVI7DQo+ID4+PiArCQkqYWR2YW5jZSA9IDA7DQo+ID4+PiArCQlicmVh
azsNCj4gPj4+ICsJZGVmYXVsdDoNCj4gPj4+ICsJCWVtdWxhdGVkID0gRU1VTEFURV9GQUlMOw0K
PiA+Pj4gKwl9DQo+ID4+PiArCXJldHVybiBlbXVsYXRlZDsNCj4gPj4+ICt9DQo+ID4+PiArDQo+
ID4+PiAgICBpbnQga3ZtcHBjX2NvcmVfZW11bGF0ZV9vcChzdHJ1Y3Qga3ZtX3J1biAqcnVuLCBz
dHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUsDQo+ID4+PiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICB1bnNpZ25lZCBpbnQgaW5zdCwgaW50ICphZHZhbmNlKQ0KPiA+Pj4gICAgew0KPiA+Pj4gQEAg
LTEzMCw2ICsxNTIsMTEgQEAgaW50IGt2bXBwY19jb3JlX2VtdWxhdGVfb3Aoc3RydWN0IGt2bV9y
dW4gKnJ1biwNCj4gPj4+IHN0cnVjdA0KPiA+PiBrdm1fdmNwdSAqdmNwdSwNCj4gPj4+ICAgIAkJ
CWVtdWxhdGVkID0ga3ZtcHBjX2U1MDBfZW11bF90bGJpdmF4KHZjcHUsIGVhKTsNCj4gPj4+ICAg
IAkJCWJyZWFrOw0KPiA+Pj4NCj4gPj4+ICsJCWNhc2UgWE9QX0VIUFJJVjoNCj4gPj4+ICsJCQll
bXVsYXRlZCA9IGt2bXBwY19lNTAwX2VtdWxfZWhwcml2KHJ1biwgdmNwdSwgaW5zdCwNCj4gPj4+
ICsJCQkJCQkJICAgYWR2YW5jZSk7DQo+ID4+PiArCQkJYnJlYWs7DQo+ID4+PiArDQo+ID4+PiAg
ICAJCWRlZmF1bHQ6DQo+ID4+PiAgICAJCQllbXVsYXRlZCA9IEVNVUxBVEVfRkFJTDsNCj4gPj4+
ICAgIAkJfQ0KPiA+Pj4NCj4gPj4NCj4gPg0KPiANCg0K

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction
  2013-06-26  9:27         ` Bhushan Bharat-R65777
@ 2013-06-26 10:33           ` Alexander Graf
  0 siblings, 0 replies; 13+ messages in thread
From: Alexander Graf @ 2013-06-26 10:33 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, mikey, kvm, linux-kernel, kvm-ppc,
	tiejun.chen, linuxppc-dev


On 26.06.2013, at 11:27, Bhushan Bharat-R65777 wrote:

>=20
>=20
>> -----Original Message-----
>> From: tiejun.chen [mailto:tiejun.chen@windriver.com]
>> Sent: Wednesday, June 26, 2013 2:47 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de; Wood =
Scott-
>> B07421; benh@kernel.crashing.org; linuxppc-dev@lists.ozlabs.org; =
linux-
>> kernel@vger.kernel.org; mikey@neuling.org
>> Subject: Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" =
instruction
>>=20
>> On 06/26/2013 04:44 PM, Bhushan Bharat-R65777 wrote:
>>>=20
>>>=20
>>>> -----Original Message-----
>>>> From: tiejun.chen [mailto:tiejun.chen@windriver.com]
>>>> Sent: Wednesday, June 26, 2013 12:25 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de; =
Wood
>>>> Scott- B07421; benh@kernel.crashing.org;
>>>> linuxppc-dev@lists.ozlabs.org; linux- kernel@vger.kernel.org;
>>>> mikey@neuling.org; Bhushan Bharat-R65777
>>>> Subject: Re: [PATCH 4/6 v5] KVM: PPC: exit to user space on =
"ehpriv"
>>>> instruction
>>>>=20
>>>> On 06/26/2013 01:42 PM, Bharat Bhushan wrote:
>>>>> "ehpriv" instruction is used for setting software breakpoints by
>>>>> user space. This patch adds support to exit to user space with
>>>>> "run->debug" have relevant information.
>>>>>=20
>>>>> As this is the first point we are using run->debug, also defined =
the
>>>>> run->debug structure.
>>>>>=20
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>>   arch/powerpc/include/asm/disassemble.h |    4 ++++
>>>>>   arch/powerpc/include/uapi/asm/kvm.h    |   21 =
+++++++++++++++++----
>>>>>   arch/powerpc/kvm/e500_emulate.c        |   27 =
+++++++++++++++++++++++++++
>>>>>   3 files changed, 48 insertions(+), 4 deletions(-)
>>>>>=20
>>>>> diff --git a/arch/powerpc/include/asm/disassemble.h
>>>> b/arch/powerpc/include/asm/disassemble.h
>>>>> index 9b198d1..856f8de 100644
>>>>> --- a/arch/powerpc/include/asm/disassemble.h
>>>>> +++ b/arch/powerpc/include/asm/disassemble.h
>>>>> @@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst)
>>>>>   	return inst & 0xffff;
>>>>>   }
>>>>>=20
>>>>> +static inline unsigned int get_oc(u32 inst) {
>>>>> +	return (inst >> 11) & 0x7fff;
>>>>> +}
>>>>>   #endif /* __ASM_PPC_DISASSEMBLE_H__ */ diff --git
>>>>> a/arch/powerpc/include/uapi/asm/kvm.h
>>>> b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> index 0fb1a6e..ded0607 100644
>>>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> @@ -269,7 +269,24 @@ struct kvm_fpu {
>>>>>   	__u64 fpr[32];
>>>>>   };
>>>>>=20
>>>>> +/*
>>>>> + * Defines for h/w breakpoint, watchpoint (read, write or both) =
and
>>>>> + * software breakpoint.
>>>>> + * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and =
"status"
>>>>> + * for KVM_DEBUG_EXIT.
>>>>> + */
>>>>> +#define KVMPPC_DEBUG_NONE		0x0
>>>>> +#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
>>>>> +#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
>>>>> +#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>>>>>   struct kvm_debug_exit_arch {
>>>>> +	__u64 address;
>>>>> +	/*
>>>>> +	 * exiting to userspace because of h/w breakpoint, watchpoint
>>>>> +	 * (read, write or both) and software breakpoint.
>>>>> +	 */
>>>>> +	__u32 status;
>>>>> +	__u32 reserved;
>>>>>   };
>>>>>=20
>>>>>   /* for KVM_SET_GUEST_DEBUG */
>>>>> @@ -281,10 +298,6 @@ struct kvm_guest_debug_arch {
>>>>>   		 * Type denotes h/w breakpoint, read watchpoint, =
write
>>>>>   		 * watchpoint or watchpoint (both read and =
write).
>>>>>   		 */
>>>>> -#define KVMPPC_DEBUG_NONE		0x0
>>>>> -#define KVMPPC_DEBUG_BREAKPOINT		(1UL << 1)
>>>>> -#define KVMPPC_DEBUG_WATCH_WRITE	(1UL << 2)
>>>>> -#define KVMPPC_DEBUG_WATCH_READ		(1UL << 3)
>>>>>   		__u32 type;
>>>>>   		__u32 reserved;
>>>>>   	} bp[16];
>>>>> diff --git a/arch/powerpc/kvm/e500_emulate.c
>>>>> b/arch/powerpc/kvm/e500_emulate.c index b10a012..dab9d07 100644
>>>>> --- a/arch/powerpc/kvm/e500_emulate.c
>>>>> +++ b/arch/powerpc/kvm/e500_emulate.c
>>>>> @@ -26,6 +26,8 @@
>>>>>   #define XOP_TLBRE   946
>>>>>   #define XOP_TLBWE   978
>>>>>   #define XOP_TLBILX  18
>>>>> +#define XOP_EHPRIV  270
>>>>> +#define EHPRIV_OC_DEBUG 0
>>>>=20
>>>> As I think the case, "OC =3D 0", is a bit specific since IIRC, if =
the
>>>> OC operand is omitted, its equal 0 by default. So I think we should
>>>> start this OC value from 1 or other magic number.
>>>=20
>>> ehpriv instruction is defined to be used as:
>>> 	ehpriv OC // where OC can be 0,1, ... n and in extended for it =
can be
>>> used as
>>> 	ehpriv // With no OC, and here it assumes OC =3D 0 So OC =3D 0 =
is not
>>> specific but "ehpriv" is same as "ehpriv 0".
>>=20
>> Yes, this is just what I mean.
>>=20
>>>=20
>>> I do not think of any special reason to reserve "ehpriv" and "ehpriv =
0".
>>=20
>> So I still prefer we can reserve the 'ehpriv' without OC operand as =
one simple
>> approach to test or develop something for KVM quickly because its =
really
>> convenient to trap into the hypervisor only with one 'ehpriv' =
instruction
>> easily.
>>=20
>> But I have no further objection if you guys are fine to this ;-)
>=20
> I can see the using "ehpriv" can be a default choice. But all ehvpriv =
trap is handled at one place (in a single function) so the accidently =
overlap with debug should not be an issue.
>=20
> I too do not have any strong opinion to keep either way, so want to =
leave as is ;-).

Seconded. On x86 we also just use int3 for soft breakpoints IIRC.


Alex

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/6 v5] powerpc: export debug registers save function for KVM
  2013-06-26  5:42 ` [PATCH 3/6 v5] powerpc: export debug registers save function for KVM Bharat Bhushan
@ 2013-06-27  4:47   ` Stephen Rothwell
  0 siblings, 0 replies; 13+ messages in thread
From: Stephen Rothwell @ 2013-06-27  4:47 UTC (permalink / raw)
  To: Bharat Bhushan
  Cc: mikey, kvm, agraf, kvm-ppc, linux-kernel, Bharat Bhushan,
	tiejun.chen, scottwood, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 729 bytes --]

Hi,

On Wed, 26 Jun 2013 11:12:23 +0530 Bharat Bhushan <r65777@freescale.com> wrote:
>
> diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
> index 200d763..50b357f 100644
> --- a/arch/powerpc/include/asm/switch_to.h
> +++ b/arch/powerpc/include/asm/switch_to.h
> @@ -30,6 +30,10 @@ extern void enable_kernel_spe(void);
>  extern void giveup_spe(struct task_struct *);
>  extern void load_up_spe(struct task_struct *);
>  
> +#ifdef CONFIG_PPC_ADV_DEBUG_REGS
> +extern void switch_booke_debug_regs(struct thread_struct *new_thread);
> +#endif

We usually don't bother guarding function declarations.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-06-27  4:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-26  5:42 [PATCH 0/6 v5] KVM :PPC: Userspace Debug support Bharat Bhushan
2013-06-26  5:42 ` [PATCH 1/6 v5] powerpc: remove unnecessary line continuations Bharat Bhushan
2013-06-26  5:42 ` [PATCH 2/6 v5] powerpc: move debug registers in a structure Bharat Bhushan
2013-06-26  5:42 ` [PATCH 3/6 v5] powerpc: export debug registers save function for KVM Bharat Bhushan
2013-06-27  4:47   ` Stephen Rothwell
2013-06-26  5:42 ` [PATCH 4/6 v5] KVM: PPC: exit to user space on "ehpriv" instruction Bharat Bhushan
2013-06-26  6:54   ` tiejun.chen
2013-06-26  8:44     ` Bhushan Bharat-R65777
2013-06-26  9:17       ` tiejun.chen
2013-06-26  9:27         ` Bhushan Bharat-R65777
2013-06-26 10:33           ` Alexander Graf
2013-06-26  5:42 ` [PATCH 5/6 v5] KVM: PPC: Using "struct debug_reg" Bharat Bhushan
2013-06-26  5:42 ` [PATCH 6/6 v5] KVM: PPC: Add userspace debug stub support Bharat Bhushan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).