public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types
@ 2013-01-16  8:24 Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 3/8] KVM: PPC: booke: Added debug handler Bharat Bhushan
                   ` (5 more replies)
  0 siblings, 6 replies; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan, Bharat Bhushan

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

Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and
all handlers are considered to be the same size. This will not be
the case if we want to use different macros for different handlers.

This patch improves the kvmppc_booke_handler so that it can
support different macros for different handlers.

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_ppc.h  |    2 -
 arch/powerpc/kvm/booke.c            |   14 ++++++++----
 arch/powerpc/kvm/booke.h            |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   37 ++++++++++++++++++++++++++++++++--
 arch/powerpc/kvm/e500.c             |   16 +++++++++-----
 5 files changed, 54 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 493630e..44a657a 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -49,8 +49,6 @@ enum emulation_result {
 
 extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
 extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
-extern char kvmppc_handlers_start[];
-extern unsigned long kvmppc_handler_len;
 extern void kvmppc_handler_highmem(void);
 
 extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 8779cd4..d2f502d 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1594,7 +1594,9 @@ int __init kvmppc_booke_init(void)
 {
 #ifndef CONFIG_KVM_BOOKE_HV
 	unsigned long ivor[16];
+	unsigned long *handler = kvmppc_booke_handler_addr;
 	unsigned long max_ivor = 0;
+	unsigned long handler_len;
 	int i;
 
 	/* We install our own exception handlers by hijacking IVPR. IVPR must
@@ -1627,14 +1629,16 @@ int __init kvmppc_booke_init(void)
 
 	for (i = 0; i < 16; i++) {
 		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+			max_ivor = i;
 
+		handler_len = handler[i + 1] - handler[i];
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + i * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler_len);
 	}
-	flush_icache_range(kvmppc_booke_handlers,
-	                   kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+
+	handler_len = handler[max_ivor + 1] - handler[max_ivor];
+	flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers +
+			   ivor[max_ivor] + handler_len);
 #endif /* !BOOKE_HV */
 	return 0;
 }
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index e9b88e4..5fd1ba6 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -65,6 +65,7 @@
 			  (1 << BOOKE_IRQPRIO_CRITICAL))
 
 extern unsigned long kvmppc_booke_handlers;
+extern unsigned long kvmppc_booke_handler_addr[];
 
 void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr);
 void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr);
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index ca16d57..eae8483 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -74,6 +74,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_HANDLER_ADDR ivor_nr
+	.long	kvmppc_handler_\ivor_nr
+.endm
+
+.macro KVM_HANDLER_END
+	.long	kvmppc_handlers_end
+.endm
+
 _GLOBAL(kvmppc_handlers_start)
 KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
@@ -94,9 +102,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
-
-_GLOBAL(kvmppc_handler_len)
-	.long kvmppc_handler_1 - kvmppc_handler_0
+_GLOBAL(kvmppc_handlers_end)
 
 /* Registers:
  *  SPRG_SCRATCH0: guest r4
@@ -461,6 +467,31 @@ lightweight_exit:
 	lwz	r4, VCPU_GPR(R4)(r4)
 	rfi
 
+	.data
+	.align	4
+	.globl	kvmppc_booke_handler_addr
+kvmppc_booke_handler_addr:
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
+KVM_HANDLER_END /*Always keep this in end*/
+
 #ifdef CONFIG_SPE
 _GLOBAL(kvmppc_save_guest_spe)
 	cmpi	0,r3,0
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index b479ed7..6dd4de7 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -491,6 +491,9 @@ static int __init kvmppc_e500_init(void)
 {
 	int r, i;
 	unsigned long ivor[3];
+	/* Process remaining handlers above the generic first 16 */
+	unsigned long *handler = &kvmppc_booke_handler_addr[16];
+	unsigned long handler_len;
 	unsigned long max_ivor = 0;
 
 	r = kvmppc_core_check_processor_compat();
@@ -506,15 +509,16 @@ static int __init kvmppc_e500_init(void)
 	ivor[1] = mfspr(SPRN_IVOR33);
 	ivor[2] = mfspr(SPRN_IVOR34);
 	for (i = 0; i < 3; i++) {
-		if (ivor[i] > max_ivor)
-			max_ivor = ivor[i];
+		if (ivor[i] > ivor[max_ivor])
+			max_ivor = i;
 
+		handler_len = handler[i + 1] - handler[i];
 		memcpy((void *)kvmppc_booke_handlers + ivor[i],
-		       kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
-		       kvmppc_handler_len);
+		       (void *)handler[i], handler_len);
 	}
-	flush_icache_range(kvmppc_booke_handlers,
-			kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+	handler_len = handler[max_ivor + 1] - handler[max_ivor];
+	flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers +
+			   ivor[max_ivor] + handler_len);
 
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
 }
-- 
1.7.0.4

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

* [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-25 11:42   ` Alexander Graf
  2013-01-16  8:24 ` [PATCH 4/8] Added ONE_REG interface for debug instruction Bharat Bhushan
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan, Bharat Bhushan

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

Installed debug handler will be used for guest debug support
and debug facility emulation features (patches for these
features will follow this patch).

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[bharat.bhushan@freescale.com: Substantial changes]
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h |    1 +
 arch/powerpc/kernel/asm-offsets.c   |    1 +
 arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-----
 3 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 8a72d59..f4ba881 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
 	u32 tlbcfg[4];
 	u32 mmucfg;
 	u32 epr;
+	u32 crit_save;
 	struct kvmppc_booke_debug_reg dbg_reg;
 #endif
 	gpa_t paddr_accessed;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 46f6afd..02048f3 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -562,6 +562,7 @@ int main(void)
 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
+	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
 #endif /* CONFIG_PPC_BOOK3S */
 #endif /* CONFIG_KVM */
 
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index eae8483..dd9c5d4 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -52,12 +52,7 @@
                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
 
-.macro KVM_HANDLER ivor_nr scratch srr0
-_GLOBAL(kvmppc_handler_\ivor_nr)
-	/* Get pointer to vcpu and record exit number. */
-	mtspr	\scratch , r4
-	mfspr   r4, SPRN_SPRG_THREAD
-	lwz     r4, THREAD_KVM_VCPU(r4)
+.macro __KVM_HANDLER ivor_nr scratch srr0
 	stw	r3, VCPU_GPR(R3)(r4)
 	stw	r5, VCPU_GPR(R5)(r4)
 	stw	r6, VCPU_GPR(R6)(r4)
@@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
 	bctr
 .endm
 
+.macro KVM_HANDLER ivor_nr scratch srr0
+_GLOBAL(kvmppc_handler_\ivor_nr)
+	/* Get pointer to vcpu and record exit number. */
+	mtspr	\scratch , r4
+	mfspr   r4, SPRN_SPRG_THREAD
+	lwz     r4, THREAD_KVM_VCPU(r4)
+	__KVM_HANDLER \ivor_nr \scratch \srr0
+.endm
+
+.macro KVM_DBG_HANDLER ivor_nr scratch srr0
+_GLOBAL(kvmppc_handler_\ivor_nr)
+	mtspr   \scratch, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	stw	r3, VCPU_CRIT_SAVE(r4)
+	mfcr	r3
+	mfspr	r4, SPRN_CSRR1
+	andi.	r4, r4, MSR_PR
+	bne	1f
+	/* debug interrupt happened in enter/exit path */
+	mfspr   r4, SPRN_CSRR1
+	rlwinm  r4, r4, 0, ~MSR_DE
+	mtspr   SPRN_CSRR1, r4
+	lis	r4, 0xffff
+	ori	r4, r4, 0xffff
+	mtspr	SPRN_DBSR, r4
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	mtcr	r3
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	mfspr   r4, \scratch
+	rfci
+1:	/* debug interrupt happened in guest */
+	mtcr	r3
+	mfspr	r4, SPRN_SPRG_THREAD
+	lwz	r4, THREAD_KVM_VCPU(r4)
+	lwz     r3, VCPU_CRIT_SAVE(r4)
+	__KVM_HANDLER \ivor_nr \scratch \srr0
+.endm
+
 .macro KVM_HANDLER_ADDR ivor_nr
 	.long	kvmppc_handler_\ivor_nr
 .endm
@@ -98,7 +133,7 @@ KVM_HANDLER BOOKE_INTERRUPT_FIT SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
-KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
+KVM_DBG_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
-- 
1.7.0.4

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

* [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 3/8] KVM: PPC: booke: Added debug handler Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-25 11:48   ` Alexander Graf
  2013-02-04  0:41   ` Paul Mackerras
  2013-01-16  8:24 ` [PATCH 5/8] KVM: PPC: debug stub interface parameter defined Bharat Bhushan
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

This patch adds the one_reg interface to get the special instruction
to be used for setting software breakpoint from userspace.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 Documentation/virtual/kvm/api.txt   |    1 +
 arch/powerpc/include/asm/kvm_ppc.h  |    1 +
 arch/powerpc/include/uapi/asm/kvm.h |    3 +++
 arch/powerpc/kvm/44x.c              |    5 +++++
 arch/powerpc/kvm/booke.c            |   10 ++++++++++
 arch/powerpc/kvm/e500.c             |    5 +++++
 arch/powerpc/kvm/e500.h             |    9 +++++++++
 arch/powerpc/kvm/e500mc.c           |    5 +++++
 8 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 09905cb..7e8be9e 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1775,6 +1775,7 @@ registers, find a list below:
   PPC   | KVM_REG_PPC_VPA_DTL   | 128
   PPC   | KVM_REG_PPC_EPCR	| 32
   PPC   | KVM_REG_PPC_EPR	| 32
+  PPC   | KVM_REG_PPC_DEBUG_INST| 32
 
 4.69 KVM_GET_ONE_REG
 
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 44a657a..b3c481e 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -235,6 +235,7 @@ union kvmppc_one_reg {
 
 void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
+u32 kvmppc_core_debug_inst_op(void);
 
 void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 16064d0..e81ae5b 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -417,4 +417,7 @@ struct kvm_get_htab_header {
 #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
 #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
 
+/* Debugging: Special instruction for software breakpoint */
+#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
+
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 3d7fd21..41501be 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+u32 kvmppc_core_debug_inst_op(void)
+{
+	return -1;
+}
+
 void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
 	kvmppc_get_sregs_ivor(vcpu, sregs);
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index d2f502d..453a10f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1424,6 +1424,12 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
 		break;
 #endif
+	case KVM_REG_PPC_DEBUG_INST: {
+		u32 opcode = kvmppc_core_debug_inst_op();
+		r = copy_to_user((u32 __user *)(long)reg->addr,
+				 &opcode, sizeof(u32));
+		break;
+	}
 	default:
 		break;
 	}
@@ -1467,6 +1473,10 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 		break;
 	}
 #endif
+	case KVM_REG_PPC_DEBUG_INST:
+		/* This is read only, so write to this is nop*/
+		r = 0;
+		break;
 	default:
 		break;
 	}
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 6dd4de7..d8a5e8e 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -367,6 +367,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+u32 kvmppc_core_debug_inst_op(void)
+{
+	return KVMPPC_INST_GUEST_GDB;
+}
+
 void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
index c70d37e..17942d2 100644
--- a/arch/powerpc/kvm/e500.h
+++ b/arch/powerpc/kvm/e500.h
@@ -302,4 +302,13 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
 #define get_tlb_sts(gtlbe)              (MAS1_TS)
 #endif /* !BOOKE_HV */
 
+/* When setting software breakpoint, Change the software breakpoint
+ * instruction to special trap/invalid instruction and set
+ * KVM_GUESTDBG_USE_SW_BP flag in kvm_guest_debug->control. KVM does
+ * keep track of software breakpoints. So when KVM_GUESTDBG_USE_SW_BP
+ * flag is set and special trap instruction is executed by guest then
+ * exit to userspace.
+ */
+#define KVMPPC_INST_GUEST_GDB		0x7C00021C	/* ehpriv OC=0 */
+
 #endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..dead142 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -199,6 +199,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+u32 kvmppc_core_debug_inst_op(void)
+{
+	return KVMPPC_INST_GUEST_GDB;
+}
+
 void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
-- 
1.7.0.4



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

* [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 3/8] KVM: PPC: booke: Added debug handler Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 4/8] Added ONE_REG interface for debug instruction Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-17  7:22   ` Paul Mackerras
  2013-01-16  8:24 ` [PATCH 6/8] booke: Added DBCR4 SPR number Bharat Bhushan
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
ioctl support. Follow up patches will use this for setting up
hardware breakpoints, watchpoints and software breakpoints.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/uapi/asm/kvm.h |   23 +++++++++++++++++++++++
 arch/powerpc/kvm/booke.c            |    6 ++++++
 arch/powerpc/kvm/powerpc.c          |    6 ------
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index e81ae5b..e8842ed 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -272,8 +272,31 @@ struct kvm_debug_exit_arch {
 
 /* for KVM_SET_GUEST_DEBUG */
 struct kvm_guest_debug_arch {
+	struct {
+		/* H/W breakpoint/watchpoint address */
+		__u64 addr;
+		/*
+		 * Type denotes h/w breakpoint, read watchpoint, write
+		 * watchpoint or watchpoint (both read and write).
+		 */
+#define KVMPPC_DEBUG_NOTYPE		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];
 };
 
+/* Debug related defines */
+/*
+ * kvm_guest_debug->control is a 32 bit field. The lower 16 bits are generic
+ * and upper 16 bits are architecture specific. Architecture specific defines
+ * that ioctl is for setting hardware breakpoint or software breakpoint.
+ */
+#define KVM_GUESTDBG_USE_SW_BP		0x00010000
+#define KVM_GUESTDBG_USE_HW_BP		0x00020000
+
 /* definition of registers in kvm_run */
 struct kvm_sync_regs {
 };
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 453a10f..7d5a51c 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1483,6 +1483,12 @@ 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;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 934413c..4c94ca9 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 #endif
 }
 
-int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
-                                        struct kvm_guest_debug *dbg)
-{
-	return -EINVAL;
-}
-
 static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
                                      struct kvm_run *run)
 {
-- 
1.7.0.4

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

* [PATCH 6/8] booke: Added DBCR4 SPR number
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
                   ` (2 preceding siblings ...)
  2013-01-16  8:24 ` [PATCH 5/8] KVM: PPC: debug stub interface parameter defined Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support Bharat Bhushan
  2013-01-16  8:24 ` [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest Bharat Bhushan
  5 siblings, 0 replies; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan, Bharat Bhushan

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

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/reg_booke.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index e07e6af..b417de3 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -56,6 +56,7 @@
 #define SPRN_SPRG7W	0x117	/* Special Purpose Register General 7 Write */
 #define SPRN_EPCR	0x133	/* Embedded Processor Control Register */
 #define SPRN_DBCR2	0x136	/* Debug Control Register 2 */
+#define SPRN_DBCR4	0x233	/* Debug Control Register 4 */
 #define SPRN_MSRP	0x137	/* MSR Protect Register */
 #define SPRN_IAC3	0x13A	/* Instruction Address Compare 3 */
 #define SPRN_IAC4	0x13B	/* Instruction Address Compare 4 */
-- 
1.7.0.4



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

* [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
                   ` (3 preceding siblings ...)
  2013-01-16  8:24 ` [PATCH 6/8] booke: Added DBCR4 SPR number Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-25 12:07   ` Alexander Graf
  2013-01-16  8:24 ` [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest Bharat Bhushan
  5 siblings, 1 reply; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +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.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/include/asm/kvm_host.h   |    5 +
 arch/powerpc/include/asm/kvm_ppc.h    |    2 +
 arch/powerpc/include/uapi/asm/kvm.h   |   22 ++++-
 arch/powerpc/kernel/asm-offsets.c     |   26 ++++++
 arch/powerpc/kvm/booke.c              |  124 +++++++++++++++++++++++++----
 arch/powerpc/kvm/booke_interrupts.S   |  114 ++++++++++++++++++++++++++
 arch/powerpc/kvm/bookehv_interrupts.S |  145 ++++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/e500_emulate.c       |    6 ++
 arch/powerpc/kvm/e500mc.c             |    3 +-
 9 files changed, 422 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index f4ba881..a9feeb0 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -504,7 +504,12 @@ struct kvm_vcpu_arch {
 	u32 mmucfg;
 	u32 epr;
 	u32 crit_save;
+	/* guest debug registers*/
 	struct kvmppc_booke_debug_reg dbg_reg;
+	/* shadow debug registers */
+	struct kvmppc_booke_debug_reg shadow_dbg_reg;
+	/* host debug registers*/
+	struct kvmppc_booke_debug_reg host_dbg_reg;
 #endif
 	gpa_t paddr_accessed;
 	gva_t vaddr_accessed;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index b3c481e..e4b3398 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -45,6 +45,8 @@ enum emulation_result {
 	EMULATE_FAIL,         /* can't emulate this instruction */
 	EMULATE_AGAIN,        /* something went wrong. go again */
 	EMULATE_DO_PAPR,      /* kvm_run filled with PAPR request */
+	EMULATE_DEBUG_INST,   /* debug instruction for software
+				 breakpoint, exit to userspace */
 };
 
 extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index e8842ed..a81ab29 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -25,6 +25,7 @@
 /* Select powerpc specific features in <linux/kvm.h> */
 #define __KVM_HAVE_SPAPR_TCE
 #define __KVM_HAVE_PPC_SMT
+#define __KVM_HAVE_GUEST_DEBUG
 
 struct kvm_regs {
 	__u64 pc;
@@ -267,7 +268,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 */
@@ -279,10 +297,6 @@ struct kvm_guest_debug_arch {
 		 * Type denotes h/w breakpoint, read watchpoint, write
 		 * watchpoint or watchpoint (both read and write).
 		 */
-#define KVMPPC_DEBUG_NOTYPE		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/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 02048f3..22deda7 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -563,6 +563,32 @@ int main(void)
 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
 	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
+	DEFINE(VCPU_DBSR, offsetof(struct kvm_vcpu, arch.dbsr));
+	DEFINE(VCPU_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg));
+	DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg));
+	DEFINE(KVMPPC_DBG_DBCR0, offsetof(struct kvmppc_booke_debug_reg,
+					  dbcr0));
+	DEFINE(KVMPPC_DBG_DBCR1, offsetof(struct kvmppc_booke_debug_reg,
+					  dbcr1));
+	DEFINE(KVMPPC_DBG_DBCR2, offsetof(struct kvmppc_booke_debug_reg,
+					  dbcr2));
+#ifdef CONFIG_KVM_E500MC
+	DEFINE(KVMPPC_DBG_DBCR4, offsetof(struct kvmppc_booke_debug_reg,
+					  dbcr4));
+#endif
+	DEFINE(KVMPPC_DBG_IAC1, offsetof(struct kvmppc_booke_debug_reg,
+					 iac[0]));
+	DEFINE(KVMPPC_DBG_IAC2, offsetof(struct kvmppc_booke_debug_reg,
+					 iac[1]));
+	DEFINE(KVMPPC_DBG_IAC3, offsetof(struct kvmppc_booke_debug_reg,
+					 iac[2]));
+	DEFINE(KVMPPC_DBG_IAC4, offsetof(struct kvmppc_booke_debug_reg,
+					 iac[3]));
+	DEFINE(KVMPPC_DBG_DAC1, offsetof(struct kvmppc_booke_debug_reg,
+					 dac[0]));
+	DEFINE(KVMPPC_DBG_DAC2, offsetof(struct kvmppc_booke_debug_reg,
+					 dac[1]));
+	DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug));
 #endif /* CONFIG_PPC_BOOK3S */
 #endif /* CONFIG_KVM */
 
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 7d5a51c..faa0a0b 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -143,6 +143,9 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
 
 #ifdef CONFIG_KVM_BOOKE_HV
 	new_msr |= MSR_GS;
+
+	if (vcpu->guest_debug)
+		new_msr |= MSR_DE;
 #endif
 
 	vcpu->arch.shared->msr = new_msr;
@@ -711,7 +714,8 @@ out:
 	return ret;
 }
 
-static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
+static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
+			  int exit_nr)
 {
 	enum emulation_result er;
 
@@ -728,6 +732,13 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		run->exit_reason = KVM_EXIT_DCR;
 		return RESUME_HOST;
 
+	case EMULATE_DEBUG_INST:
+		run->exit_reason = KVM_EXIT_DEBUG;
+		run->debug.arch.address = vcpu->arch.pc;
+		run->debug.arch.status = 0;
+		kvmppc_account_exit(vcpu, DEBUG_EXITS);
+		return RESUME_HOST;
+
 	case EMULATE_FAIL:
 		printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
 		       __func__, vcpu->arch.pc, vcpu->arch.last_inst);
@@ -743,6 +754,28 @@ 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)
+{
+	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 = vcpu->arch.shadow_dbg_reg.dac[0];
+		else if (dbsr & (DBSR_DAC2R | DBSR_DAC2W))
+			run->debug.arch.address = vcpu->arch.shadow_dbg_reg.dac[1];
+	}
+
+	return RESUME_HOST;
+}
+
 static void kvmppc_fill_pt_regs(struct pt_regs *regs)
 {
 	ulong r1, ip, msr, lr;
@@ -887,7 +920,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 		break;
 
 	case BOOKE_INTERRUPT_HV_PRIV:
-		r = emulation_exit(run, vcpu);
+		r = emulation_exit(run, vcpu, exit_nr);
 		break;
 
 	case BOOKE_INTERRUPT_PROGRAM:
@@ -906,7 +939,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
 			break;
 		}
 
-		r = emulation_exit(run, vcpu);
+		r = emulation_exit(run, vcpu, exit_nr);
 		break;
 
 	case BOOKE_INTERRUPT_FP_UNAVAIL:
@@ -1096,18 +1129,11 @@ 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;
 	}
 
@@ -1483,10 +1509,78 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
 	return r;
 }
 
+#define BP_NUM	KVMPPC_BOOKE_IAC_NUM
+#define WP_NUM	KVMPPC_BOOKE_DAC_NUM
+
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 					 struct kvm_guest_debug *dbg)
 {
-	return -EINVAL;
+
+	if (!(dbg->control & KVM_GUESTDBG_ENABLE)) {
+		/* Clear All debug events */
+		vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
+		vcpu->guest_debug = 0;
+		return 0;
+	}
+
+	vcpu->guest_debug = dbg->control;
+	vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+		struct kvmppc_booke_debug_reg *gdbgr =
+				&(vcpu->arch.shadow_dbg_reg);
+		int n, b = 0, w = 0;
+		const u32 bp_code[] = {
+			DBCR0_IAC1 | DBCR0_IDM,
+			DBCR0_IAC2 | DBCR0_IDM,
+			DBCR0_IAC3 | DBCR0_IDM,
+			DBCR0_IAC4 | DBCR0_IDM
+		};
+		const u32 wp_code[] = {
+			DBCR0_DAC1W | DBCR0_IDM,
+			DBCR0_DAC2W | DBCR0_IDM,
+			DBCR0_DAC1R | DBCR0_IDM,
+			DBCR0_DAC2R | DBCR0_IDM
+		};
+
+#ifndef CONFIG_KVM_BOOKE_HV
+		gdbgr->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
+				DBCR1_IAC3US | DBCR1_IAC4US;
+		gdbgr->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+#else
+		gdbgr->dbcr1 = 0;
+		gdbgr->dbcr2 = 0;
+#endif
+
+		for (n = 0; n < (BP_NUM + WP_NUM); n++) {
+			u32 type = dbg->arch.bp[n].type;
+
+			if (!type)
+				break;
+
+			if (type & (KVMPPC_DEBUG_WATCH_READ |
+				    KVMPPC_DEBUG_WATCH_WRITE)) {
+				if (w < WP_NUM) {
+					if (type & KVMPPC_DEBUG_WATCH_READ)
+						gdbgr->dbcr0 |= wp_code[w + 2];
+					if (type & KVMPPC_DEBUG_WATCH_WRITE)
+						gdbgr->dbcr0 |= wp_code[w];
+					gdbgr->dac[w] = dbg->arch.bp[n].addr;
+					w++;
+				}
+			} else if (type & KVMPPC_DEBUG_BREAKPOINT) {
+				if (b < BP_NUM) {
+					gdbgr->dbcr0 |= bp_code[b];
+					gdbgr->iac[b] = dbg->arch.bp[n].addr;
+					b++;
+				}
+			}
+		}
+	}
+	return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index dd9c5d4..734c549 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -39,6 +39,8 @@
 #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4)
 #define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
 #define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */
+#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
+			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
 
 #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
                         (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
@@ -52,6 +54,8 @@
                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
 
+#define NEED_DEBUG_SAVE (1<<BOOKE_INTERRUPT_DEBUG)
+
 .macro __KVM_HANDLER ivor_nr scratch srr0
 	stw	r3, VCPU_GPR(R3)(r4)
 	stw	r5, VCPU_GPR(R5)(r4)
@@ -212,6 +216,59 @@ _GLOBAL(kvmppc_resume_host)
 	stw	r9, VCPU_FAULT_ESR(r4)
 ..skip_esr:
 
+	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
+	rlwinm.	r8, r9, 0, ~DBCR0_IDM
+	beq	skip_load_host_debug
+	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
+	andis.	r9, r9, DBCR0_AC_BITS@h
+	li	r9, 0
+	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
+	beq	skip_load_hw_bkpts
+	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
+	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
+	mtspr	SPRN_DBCR1, r7
+	mtspr	SPRN_DBCR2, r9
+	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
+	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
+	mtspr	SPRN_IAC1, r7
+	mtspr	SPRN_IAC2, r9
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
+	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
+	mtspr	SPRN_IAC3, r3
+	mtspr	SPRN_IAC4, r4
+#endif
+	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
+	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
+	mtspr	SPRN_DAC1, r7
+	mtspr	SPRN_DAC2, r9
+skip_load_hw_bkpts:
+	/* Clear h/w DBSR and save current(guest) DBSR */
+	mfspr	r9, SPRN_DBSR
+	mtspr	SPRN_DBSR, r9
+	isync
+	andi.	r7, r6, NEED_DEBUG_SAVE
+	beq	skip_dbsr_save
+	/*
+	 * If vcpu->guest_debug flag is set then do not check for
+	 * shared->msr.DE as this debugging (say by QEMU) does not
+	 * depends on shared->msr.de. In these scanerios MSR.DE is
+	 * always set using shared_msr and should be handled always.
+	 */
+	lwz	r7, VCPU_GUEST_DEBUG(r4)
+	cmpwi	r7, 0
+	bne	skip_save_trap_event
+	PPC_LL	r3, VCPU_SHARED(r4)
+	PPC_LD(r3, VCPU_SHARED_MSR, r3)
+	andi.	r3, r3, MSR_DE
+	bne	skip_save_trap_event
+	andis.	r9, r9, DBSR_TIE@h
+skip_save_trap_event:
+	stw	r9, VCPU_DBSR(r4)
+skip_dbsr_save:
+	mtspr	SPRN_DBCR0, r8
+skip_load_host_debug:
+
 	/* Save remaining volatile guest register state to vcpu. */
 	stw	r0, VCPU_GPR(R0)(r4)
 	stw	r1, VCPU_GPR(R1)(r4)
@@ -465,6 +522,63 @@ lightweight_exit:
 	PPC_LD(r3, VCPU_SHARED_SPRG7, r5)
 	mtspr	SPRN_SPRG7W, r3
 
+	mfmsr	r7
+	rlwinm	r7, r7, 0, ~MSR_DE
+	mtmsr	r7
+	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
+	rlwinm.	r7, r6, 0, ~DBCR0_IDM
+	beq	skip_load_guest_debug
+	mfspr	r8, SPRN_DBCR0
+	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
+	andis.	r3, r6, DBCR0_AC_BITS@h
+	beq	skip_hw_bkpts
+	mfspr	r7, SPRN_DBCR1
+	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
+	mfspr	r8, SPRN_DBCR2
+	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
+	mfspr	r7, SPRN_IAC1
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
+	mfspr	r8, SPRN_IAC2
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	mfspr	r7, SPRN_IAC3
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
+	mfspr	r8, SPRN_IAC4
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
+#endif
+	mfspr	r7, SPRN_DAC1
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
+	mfspr	r8, SPRN_DAC2
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
+	li	r8, 0
+	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2, r4)
+	mtspr	SPRN_DBCR1, r7
+	mtspr	SPRN_DBCR2, r8
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
+	mtspr	SPRN_IAC1, r7
+	mtspr	SPRN_IAC2, r8
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
+	mtspr	SPRN_IAC3, r7
+	mtspr	SPRN_IAC4, r8
+#endif
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
+	mtspr	SPRN_DAC1, r7
+	mtspr	SPRN_DAC2, r8
+skip_hw_bkpts:
+	/* Clear if any deferred debug event */
+	mfspr	r8, SPRN_DBSR
+	mtspr	SPRN_DBSR, r8
+	isync
+	/* Restore guest DBCR */
+	mtspr	SPRN_DBCR0, r6
+skip_load_guest_debug:
+
 #ifdef CONFIG_KVM_EXIT_TIMING
 	/* save enter time */
 1:
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
index e8ed7d6..0d830cc 100644
--- a/arch/powerpc/kvm/bookehv_interrupts.S
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -62,6 +62,10 @@
 #define NEED_EMU		0x00000001 /* emulation -- save nv regs */
 #define NEED_DEAR		0x00000002 /* save faulting DEAR */
 #define NEED_ESR		0x00000004 /* save faulting ESR */
+#define NEED_DBSR		0x00000008 /* save DBSR */
+
+#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
+			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
 
 /*
  * On entry:
@@ -201,6 +205,11 @@
 	PPC_STL	r9, VCPU_FAULT_DEAR(r4)
 	.endif
 
+	.if	\flags & NEED_DBSR
+	mfspr	r9, SPRN_DBSR
+	stw	r9, VCPU_DBSR(r4)
+	.endif
+
 	b	kvmppc_resume_host
 .endm
 
@@ -316,9 +325,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, EX_PARAMS(GDBELL), \
 kvm_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, EX_PARAMS(CRIT), \
 	SPRN_CSRR0, SPRN_CSRR1, 0
 kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \
-	SPRN_DSRR0, SPRN_DSRR1, 0
+	SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
 kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \
-	SPRN_CSRR0, SPRN_CSRR1, 0
+	SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
 #else
 /*
  * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
@@ -411,9 +420,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0
 kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
 	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
 kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
-	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
+	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
 kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
-	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
+	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
 #endif
 
 /* Registers:
@@ -423,6 +432,56 @@ kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
  *  r14: KVM exit number
  */
 _GLOBAL(kvmppc_resume_host)
+	/*
+	 * If guest not used debug facility then hw debug registers
+	 * already have proper host values. If guest used debug
+	 * facility then restore host debug registers.
+	 * No Need to save guest debug registers as they are already intact
+	 * in guest/shadow registers.
+	 */
+	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
+	rlwinm.	r8, r9, 0, ~DBCR0_IDM
+	beq	skip_load_host_debug
+	lwz	r3, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
+	andis.	r9, r9, DBCR0_AC_BITS@h
+	li	r9, 0
+	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
+	beq	skip_load_hw_bkpts
+	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
+	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
+	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
+	mtspr	SPRN_DBCR1, r7
+	PPC_LD(r6, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
+	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
+	mtspr	SPRN_DBCR2, r8
+	mtspr	SPRN_DBCR4, r9
+	mtspr	SPRN_IAC1, r6
+	mtspr	SPRN_IAC2, r7
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
+	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
+	mtspr	SPRN_IAC3, r7
+	mtspr	SPRN_IAC4, r8
+#endif
+	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
+	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
+	mtspr	SPRN_DAC1, r8
+	mtspr	SPRN_DAC2, r9
+skip_load_hw_bkpts:
+	isync
+	/* Clear h/w DBSR */
+	mfspr	r8, SPRN_DBSR
+	mtspr	SPRN_DBSR, r8
+	isync
+	/* Clear EPCR.DUVD and set host DBCR0 */
+	mfspr	r8, SPRN_EPCR
+	rlwinm	r8, r8, 0, ~SPRN_EPCR_DUVD
+	mtspr	SPRN_EPCR, r8
+	isync
+	mtspr	SPRN_DBCR0, r3
+	isync
+skip_load_host_debug:
+
 	/* Save remaining volatile guest register state to vcpu. */
 	mfspr	r3, SPRN_VRSAVE
 	PPC_STL	r0, VCPU_GPR(R0)(r4)
@@ -662,6 +721,84 @@ lightweight_exit:
 	mtspr	SPRN_SPRG6W, r7
 	mtspr	SPRN_SPRG7W, r8
 
+	mfmsr	r7
+	rlwinm	r7, r7, 0, ~MSR_DE
+	mtmsr	r7
+	/*
+	 * Load hw debug registers with guest(shadow) debug registers
+	 * if guest is using the debug facility and also set EPCR.DUVD
+	 * to not allow debug events in HV mode. Do not change the
+	 * debug registers if guest is not using the debug facility.
+	 */
+	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
+	rlwinm.	r7, r6, 0, ~DBCR0_IDM
+	beq	skip_load_guest_debug
+	/* Save host DBCR0 */
+	mfspr	r8, SPRN_DBCR0
+	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
+	/*
+	 * Save host DBCR1/2, IACx and DACx and load guest DBCR1/2,
+	 * IACx and DACx if guest using hw breakpoint/watchpoints.
+	 */
+	andis.	r3, r6, DBCR0_AC_BITS@h
+	beq	skip_hw_bkpts
+	mfspr	r7, SPRN_DBCR1
+	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
+	mfspr	r8, SPRN_DBCR2
+	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
+	mfspr	r7, SPRN_DBCR4
+	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
+	mfspr	r8, SPRN_IAC1
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
+	mfspr	r7, SPRN_IAC2
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	mfspr	r8, SPRN_IAC3
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
+	mfspr	r7, SPRN_IAC4
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
+#endif
+	mfspr	r8, SPRN_DAC1
+	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
+	mfspr	r7, SPRN_DAC2
+	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
+	li	r8, 0
+	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
+	lwz	r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1(r4)
+	lwz	r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2(r4)
+	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR4(r4)
+	mtspr	SPRN_DBCR1, r7
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
+	PPC_LD(r3, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
+	mtspr	SPRN_DBCR2, r8
+	mtspr	SPRN_DBCR4, r9
+	mtspr	SPRN_IAC1, r7
+	mtspr	SPRN_IAC2, r3
+#if CONFIG_PPC_ADV_DEBUG_IACS > 2
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
+	mtspr	SPRN_IAC3, r7
+	mtspr	SPRN_IAC4, r8
+#endif
+	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
+	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
+	mtspr	SPRN_DAC1, r7
+	mtspr	SPRN_DAC2, r8
+skip_hw_bkpts:
+	/* Set EPCR.DUVD and guest DBCR0 */
+	mfspr	r7, SPRN_EPCR
+	oris	r7, r7, SPRN_EPCR_DUVD@h
+	mtspr	SPRN_EPCR, r7
+	isync
+	/* Clear if any deferred debug event */
+	mfspr	r8, SPRN_DBSR
+	mtspr	SPRN_DBSR, r8
+	isync
+	/* Restore guest DBCR */
+	mtspr	SPRN_DBCR0, r6
+	isync
+skip_load_guest_debug:
+
 	/* Load some guest volatiles. */
 	PPC_LL	r3, VCPU_LR(r4)
 	PPC_LL	r5, VCPU_XER(r4)
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index e78f353..ddb903e 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -26,6 +26,7 @@
 #define XOP_TLBRE   946
 #define XOP_TLBWE   978
 #define XOP_TLBILX  18
+#define XOP_EHPRIV  270
 
 #ifdef CONFIG_KVM_E500MC
 static int dbell2prio(ulong param)
@@ -130,6 +131,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 = EMULATE_DEBUG_INST;
+			*advance = 0;
+			break;
+
 		default:
 			emulated = EMULATE_FAIL;
 		}
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index dead142..81abe92 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -182,8 +182,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 
-	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
-				 SPRN_EPCR_DUVD;
+	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI;
 #ifdef CONFIG_64BIT
 	vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM;
 #endif
-- 
1.7.0.4

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

* [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
                   ` (4 preceding siblings ...)
  2013-01-16  8:24 ` [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support Bharat Bhushan
@ 2013-01-16  8:24 ` Bharat Bhushan
  2013-01-25 12:13   ` Alexander Graf
  5 siblings, 1 reply; 59+ messages in thread
From: Bharat Bhushan @ 2013-01-16  8:24 UTC (permalink / raw)
  To: kvm-ppc, kvm, agraf; +Cc: Bharat Bhushan

Allow userspace to inject debug interrupt to guest. QEMU can
inject the debug interrupt to guest if it is not able to handle
the debug interrupt.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/e500mc.c |   10 +++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index faa0a0b..547797f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 #endif
 }
 
+#ifdef CONFIG_KVM_BOOKE_HV
+static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu)
+{
+	return test_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions);
+}
+#endif
+
 /*
  * Helper function for "full" MSR writes.  No need to call this if only
  * EE/CE/ME/DE/RI are changing.
@@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
 #ifdef CONFIG_KVM_BOOKE_HV
 	new_msr |= MSR_GS;
 
-	if (vcpu->guest_debug)
+	/*
+	 * Set MSR_DE if the hardware debug resources are owned by user-space
+	 * and there is no debug interrupt pending for guest to handle.
+	 */
+	if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu))
 		new_msr |= MSR_DE;
 #endif
 
@@ -234,6 +245,16 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu *vcpu)
 	clear_bit(BOOKE_IRQPRIO_WATCHDOG, &vcpu->arch.pending_exceptions);
 }
 
+static void kvmppc_core_queue_debug(struct kvm_vcpu *vcpu)
+{
+	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DEBUG);
+}
+
+static void kvmppc_core_dequeue_debug(struct kvm_vcpu *vcpu)
+{
+	clear_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions);
+}
+
 static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
 {
 #ifdef CONFIG_KVM_BOOKE_HV
@@ -1278,6 +1299,7 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
 	sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
 	sregs->u.e.tb = tb;
 	sregs->u.e.vrsave = vcpu->arch.vrsave;
+	sregs->u.e.dbsr = vcpu->arch.dbsr;
 }
 
 static int set_sregs_base(struct kvm_vcpu *vcpu,
@@ -1310,6 +1332,14 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
 		update_timer_ints(vcpu);
 	}
 
+	if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DBSR) {
+		vcpu->arch.dbsr = sregs->u.e.dbsr;
+		if (vcpu->arch.dbsr)
+			kvmppc_core_queue_debug(vcpu);
+		else
+			kvmppc_core_dequeue_debug(vcpu);
+	}
+
 	return 0;
 }
 
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 81abe92..7d90622 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -208,7 +208,7 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
 
 	sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
-			       KVM_SREGS_E_PC;
+			       KVM_SREGS_E_PC | KVM_SREGS_E_ED;
 	sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
 
 	sregs->u.e.impl.fsl.features = 0;
@@ -216,6 +216,9 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 	sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
 	sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
 
+	sregs->u.e.dsrr0 = vcpu->arch.dsrr0;
+	sregs->u.e.dsrr1 = vcpu->arch.dsrr1;
+
 	kvmppc_get_sregs_e500_tlb(vcpu, sregs);
 
 	sregs->u.e.ivor_high[3] =
@@ -256,6 +259,11 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 			sregs->u.e.ivor_high[5];
 	}
 
+	if (sregs->u.e.features & KVM_SREGS_E_ED) {
+		vcpu->arch.dsrr0 = sregs->u.e.dsrr0;
+		vcpu->arch.dsrr1 = sregs->u.e.dsrr1;
+	}
+
 	return kvmppc_set_sregs_ivor(vcpu, sregs);
 }
 
-- 
1.7.0.4

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

* Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-16  8:24 ` [PATCH 5/8] KVM: PPC: debug stub interface parameter defined Bharat Bhushan
@ 2013-01-17  7:22   ` Paul Mackerras
  2013-01-17 11:11     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Paul Mackerras @ 2013-01-17  7:22 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, agraf, Bharat Bhushan

On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
> ioctl support. Follow up patches will use this for setting up
> hardware breakpoints, watchpoints and software breakpoints.

[snip]

> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 453a10f..7d5a51c 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -1483,6 +1483,12 @@ 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;
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 934413c..4c94ca9 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  #endif
>  }
>  
> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> -                                        struct kvm_guest_debug *dbg)
> -{
> -	return -EINVAL;
> -}
> -

This will break the build for non-book E machines, since
kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
You need to add it to arch/powerpc/kvm/book3s.c as well.

Paul.

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

* RE: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-17  7:22   ` Paul Mackerras
@ 2013-01-17 11:11     ` Bhushan Bharat-R65777
  2013-01-25 11:53       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-17 11:11 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org, agraf@suse.de



> -----Original Message-----
> From: Paul Mackerras [mailto:paulus@samba.org]
> Sent: Thursday, January 17, 2013 12:53 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de; Bhushan Bharat-
> R65777
> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
> 
> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
> > This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
> > ioctl support. Follow up patches will use this for setting up hardware
> > breakpoints, watchpoints and software breakpoints.
> 
> [snip]
> 
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 453a10f..7d5a51c 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -1483,6 +1483,12 @@ 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;
> > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> > index 934413c..4c94ca9 100644
> > --- a/arch/powerpc/kvm/powerpc.c
> > +++ b/arch/powerpc/kvm/powerpc.c
> > @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> > #endif  }
> >
> > -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> > -                                        struct kvm_guest_debug *dbg)
> > -{
> > -	return -EINVAL;
> > -}
> > -
> 
> This will break the build for non-book E machines, since
> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
> You need to add it to arch/powerpc/kvm/book3s.c as well.

right,  I will correct this.

Thanks
-Bharat

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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-16  8:24 ` [PATCH 3/8] KVM: PPC: booke: Added debug handler Bharat Bhushan
@ 2013-01-25 11:42   ` Alexander Graf
  2013-01-30 11:30     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-25 11:42 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 16.01.2013, at 09:24, Bharat Bhushan wrote:

> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> 
> Installed debug handler will be used for guest debug support
> and debug facility emulation features (patches for these
> features will follow this patch).
> 
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> [bharat.bhushan@freescale.com: Substantial changes]
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_host.h |    1 +
> arch/powerpc/kernel/asm-offsets.c   |    1 +
> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-----
> 3 files changed, 44 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index 8a72d59..f4ba881 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> 	u32 tlbcfg[4];
> 	u32 mmucfg;
> 	u32 epr;
> +	u32 crit_save;
> 	struct kvmppc_booke_debug_reg dbg_reg;
> #endif
> 	gpa_t paddr_accessed;
> diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 46f6afd..02048f3 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -562,6 +562,7 @@ int main(void)
> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> #endif /* CONFIG_PPC_BOOK3S */
> #endif /* CONFIG_KVM */
> 
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index eae8483..dd9c5d4 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -52,12 +52,7 @@
>                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
>                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
> 
> -.macro KVM_HANDLER ivor_nr scratch srr0
> -_GLOBAL(kvmppc_handler_\ivor_nr)
> -	/* Get pointer to vcpu and record exit number. */
> -	mtspr	\scratch , r4
> -	mfspr   r4, SPRN_SPRG_THREAD
> -	lwz     r4, THREAD_KVM_VCPU(r4)
> +.macro __KVM_HANDLER ivor_nr scratch srr0
> 	stw	r3, VCPU_GPR(R3)(r4)
> 	stw	r5, VCPU_GPR(R5)(r4)
> 	stw	r6, VCPU_GPR(R6)(r4)
> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> 	bctr
> .endm
> 
> +.macro KVM_HANDLER ivor_nr scratch srr0
> +_GLOBAL(kvmppc_handler_\ivor_nr)
> +	/* Get pointer to vcpu and record exit number. */
> +	mtspr	\scratch , r4
> +	mfspr   r4, SPRN_SPRG_THREAD
> +	lwz     r4, THREAD_KVM_VCPU(r4)
> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> +.endm
> +
> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> +_GLOBAL(kvmppc_handler_\ivor_nr)
> +	mtspr   \scratch, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	stw	r3, VCPU_CRIT_SAVE(r4)
> +	mfcr	r3
> +	mfspr	r4, SPRN_CSRR1
> +	andi.	r4, r4, MSR_PR
> +	bne	1f


> +	/* debug interrupt happened in enter/exit path */
> +	mfspr   r4, SPRN_CSRR1
> +	rlwinm  r4, r4, 0, ~MSR_DE
> +	mtspr   SPRN_CSRR1, r4
> +	lis	r4, 0xffff
> +	ori	r4, r4, 0xffff
> +	mtspr	SPRN_DBSR, r4
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	mtcr	r3
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	mfspr   r4, \scratch
> +	rfci

What is this part doing? Try to ignore the debug exit? Why would we have MSR_DE enabled in the first place when we can't handle it?

> +1:	/* debug interrupt happened in guest */
> +	mtcr	r3
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	__KVM_HANDLER \ivor_nr \scratch \srr0

I don't think you need the __KVM_HANDLER split. This should be quite easily refactorable into a simple DBG prolog.


Alex

> +.endm
> +
> .macro KVM_HANDLER_ADDR ivor_nr
> 	.long	kvmppc_handler_\ivor_nr
> .endm
> @@ -98,7 +133,7 @@ KVM_HANDLER BOOKE_INTERRUPT_FIT SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> -KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> +KVM_DBG_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> -- 
> 1.7.0.4
> 
> 

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-16  8:24 ` [PATCH 4/8] Added ONE_REG interface for debug instruction Bharat Bhushan
@ 2013-01-25 11:48   ` Alexander Graf
  2013-01-31 17:44     ` Bhushan Bharat-R65777
  2013-02-04  0:41   ` Paul Mackerras
  1 sibling, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-25 11:48 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 16.01.2013, at 09:24, Bharat Bhushan wrote:

> This patch adds the one_reg interface to get the special instruction
> to be used for setting software breakpoint from userspace.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> Documentation/virtual/kvm/api.txt   |    1 +
> arch/powerpc/include/asm/kvm_ppc.h  |    1 +
> arch/powerpc/include/uapi/asm/kvm.h |    3 +++
> arch/powerpc/kvm/44x.c              |    5 +++++
> arch/powerpc/kvm/booke.c            |   10 ++++++++++
> arch/powerpc/kvm/e500.c             |    5 +++++
> arch/powerpc/kvm/e500.h             |    9 +++++++++
> arch/powerpc/kvm/e500mc.c           |    5 +++++
> 8 files changed, 39 insertions(+), 0 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 09905cb..7e8be9e 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -1775,6 +1775,7 @@ registers, find a list below:
>   PPC   | KVM_REG_PPC_VPA_DTL   | 128
>   PPC   | KVM_REG_PPC_EPCR	| 32
>   PPC   | KVM_REG_PPC_EPR	| 32
> +  PPC   | KVM_REG_PPC_DEBUG_INST| 32
> 
> 4.69 KVM_GET_ONE_REG
> 
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index 44a657a..b3c481e 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -235,6 +235,7 @@ union kvmppc_one_reg {
> 
> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> +u32 kvmppc_core_debug_inst_op(void);
> 
> void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index 16064d0..e81ae5b 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -417,4 +417,7 @@ struct kvm_get_htab_header {
> #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
> #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
> 
> +/* Debugging: Special instruction for software breakpoint */
> +#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
> +
> #endif /* __LINUX_KVM_POWERPC_H */
> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
> index 3d7fd21..41501be 100644
> --- a/arch/powerpc/kvm/44x.c
> +++ b/arch/powerpc/kvm/44x.c
> @@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
> 	return 0;
> }
> 
> +u32 kvmppc_core_debug_inst_op(void)
> +{
> +	return -1;
> +}
> +
> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> {
> 	kvmppc_get_sregs_ivor(vcpu, sregs);
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index d2f502d..453a10f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c

Please provide the DEBUG_INST on a more global level - across all ppc subarchs.

> @@ -1424,6 +1424,12 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> 		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
> 		break;
> #endif
> +	case KVM_REG_PPC_DEBUG_INST: {
> +		u32 opcode = kvmppc_core_debug_inst_op();
> +		r = copy_to_user((u32 __user *)(long)reg->addr,
> +				 &opcode, sizeof(u32));
> +		break;
> +	}
> 	default:
> 		break;
> 	}
> @@ -1467,6 +1473,10 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> 		break;
> 	}
> #endif
> +	case KVM_REG_PPC_DEBUG_INST:
> +		/* This is read only, so write to this is nop*/
> +		r = 0;
> +		break;

Just don't support set_one_reg on this reg.

> 	default:
> 		break;
> 	}
> diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
> index 6dd4de7..d8a5e8e 100644
> --- a/arch/powerpc/kvm/e500.c
> +++ b/arch/powerpc/kvm/e500.c
> @@ -367,6 +367,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> 	return 0;
> }
> 
> +u32 kvmppc_core_debug_inst_op(void)
> +{
> +	return KVMPPC_INST_GUEST_GDB;
> +}
> +
> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index c70d37e..17942d2 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -302,4 +302,13 @@ static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
> #define get_tlb_sts(gtlbe)              (MAS1_TS)
> #endif /* !BOOKE_HV */
> 
> +/* When setting software breakpoint, Change the software breakpoint
> + * instruction to special trap/invalid instruction and set
> + * KVM_GUESTDBG_USE_SW_BP flag in kvm_guest_debug->control. KVM does
> + * keep track of software breakpoints. So when KVM_GUESTDBG_USE_SW_BP
> + * flag is set and special trap instruction is executed by guest then
> + * exit to userspace.

This comment chunk no apply to define. Also please fix English ;).


Alex

> + */
> +#define KVMPPC_INST_GUEST_GDB		0x7C00021C	/* ehpriv OC=0 */
> +
> #endif /* KVM_E500_H */
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..dead142 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -199,6 +199,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> 	return 0;
> }
> 
> +u32 kvmppc_core_debug_inst_op(void)
> +{
> +	return KVMPPC_INST_GUEST_GDB;
> +}
> +
> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> -- 
> 1.7.0.4
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-17 11:11     ` Bhushan Bharat-R65777
@ 2013-01-25 11:53       ` Alexander Graf
  2013-01-30 14:15         ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-25 11:53 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Paul Mackerras [mailto:paulus@samba.org]
>> Sent: Thursday, January 17, 2013 12:53 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de; Bhushan Bharat-
>> R65777
>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
>> 
>> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
>>> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
>>> ioctl support. Follow up patches will use this for setting up hardware
>>> breakpoints, watchpoints and software breakpoints.
>> 
>> [snip]
>> 
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>> 453a10f..7d5a51c 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>>> @@ -1483,6 +1483,12 @@ 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;
>>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
>>> index 934413c..4c94ca9 100644
>>> --- a/arch/powerpc/kvm/powerpc.c
>>> +++ b/arch/powerpc/kvm/powerpc.c
>>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>> #endif  }
>>> 
>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>> -                                        struct kvm_guest_debug *dbg)
>>> -{
>>> -	return -EINVAL;
>>> -}
>>> -
>> 
>> This will break the build for non-book E machines, since
>> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
>> You need to add it to arch/powerpc/kvm/book3s.c as well.
> 
> right,  I will correct this.

Would the implementation actually be different on booke vs book3s? My feeling is that powerpc.c is actually the right place for this.


Alex

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

* Re: [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
  2013-01-16  8:24 ` [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support Bharat Bhushan
@ 2013-01-25 12:07   ` Alexander Graf
  2013-02-01  6:31     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-25 12:07 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 16.01.2013, at 09:24, Bharat Bhushan wrote:

> 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.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_host.h   |    5 +
> arch/powerpc/include/asm/kvm_ppc.h    |    2 +
> arch/powerpc/include/uapi/asm/kvm.h   |   22 ++++-
> arch/powerpc/kernel/asm-offsets.c     |   26 ++++++
> arch/powerpc/kvm/booke.c              |  124 +++++++++++++++++++++++++----
> arch/powerpc/kvm/booke_interrupts.S   |  114 ++++++++++++++++++++++++++
> arch/powerpc/kvm/bookehv_interrupts.S |  145 ++++++++++++++++++++++++++++++++-
> arch/powerpc/kvm/e500_emulate.c       |    6 ++
> arch/powerpc/kvm/e500mc.c             |    3 +-
> 9 files changed, 422 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index f4ba881..a9feeb0 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -504,7 +504,12 @@ struct kvm_vcpu_arch {
> 	u32 mmucfg;
> 	u32 epr;
> 	u32 crit_save;
> +	/* guest debug registers*/
> 	struct kvmppc_booke_debug_reg dbg_reg;
> +	/* shadow debug registers */
> +	struct kvmppc_booke_debug_reg shadow_dbg_reg;
> +	/* host debug registers*/
> +	struct kvmppc_booke_debug_reg host_dbg_reg;
> #endif
> 	gpa_t paddr_accessed;
> 	gva_t vaddr_accessed;
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index b3c481e..e4b3398 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -45,6 +45,8 @@ enum emulation_result {
> 	EMULATE_FAIL,         /* can't emulate this instruction */
> 	EMULATE_AGAIN,        /* something went wrong. go again */
> 	EMULATE_DO_PAPR,      /* kvm_run filled with PAPR request */
> +	EMULATE_DEBUG_INST,   /* debug instruction for software
> +				 breakpoint, exit to userspace */

Does this do something different from DO_PAPR? Maybe it makes sense to have an exit code EMULATE_EXIT_USER?

> };
> 
> extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index e8842ed..a81ab29 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -25,6 +25,7 @@
> /* Select powerpc specific features in <linux/kvm.h> */
> #define __KVM_HAVE_SPAPR_TCE
> #define __KVM_HAVE_PPC_SMT
> +#define __KVM_HAVE_GUEST_DEBUG
> 
> struct kvm_regs {
> 	__u64 pc;
> @@ -267,7 +268,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 */
> @@ -279,10 +297,6 @@ struct kvm_guest_debug_arch {
> 		 * Type denotes h/w breakpoint, read watchpoint, write
> 		 * watchpoint or watchpoint (both read and write).
> 		 */
> -#define KVMPPC_DEBUG_NOTYPE		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/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
> index 02048f3..22deda7 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -563,6 +563,32 @@ int main(void)
> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> 	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> +	DEFINE(VCPU_DBSR, offsetof(struct kvm_vcpu, arch.dbsr));
> +	DEFINE(VCPU_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg));
> +	DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg));
> +	DEFINE(KVMPPC_DBG_DBCR0, offsetof(struct kvmppc_booke_debug_reg,
> +					  dbcr0));
> +	DEFINE(KVMPPC_DBG_DBCR1, offsetof(struct kvmppc_booke_debug_reg,
> +					  dbcr1));
> +	DEFINE(KVMPPC_DBG_DBCR2, offsetof(struct kvmppc_booke_debug_reg,
> +					  dbcr2));
> +#ifdef CONFIG_KVM_E500MC
> +	DEFINE(KVMPPC_DBG_DBCR4, offsetof(struct kvmppc_booke_debug_reg,
> +					  dbcr4));
> +#endif
> +	DEFINE(KVMPPC_DBG_IAC1, offsetof(struct kvmppc_booke_debug_reg,
> +					 iac[0]));
> +	DEFINE(KVMPPC_DBG_IAC2, offsetof(struct kvmppc_booke_debug_reg,
> +					 iac[1]));
> +	DEFINE(KVMPPC_DBG_IAC3, offsetof(struct kvmppc_booke_debug_reg,
> +					 iac[2]));
> +	DEFINE(KVMPPC_DBG_IAC4, offsetof(struct kvmppc_booke_debug_reg,
> +					 iac[3]));
> +	DEFINE(KVMPPC_DBG_DAC1, offsetof(struct kvmppc_booke_debug_reg,
> +					 dac[0]));
> +	DEFINE(KVMPPC_DBG_DAC2, offsetof(struct kvmppc_booke_debug_reg,
> +					 dac[1]));
> +	DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug));
> #endif /* CONFIG_PPC_BOOK3S */
> #endif /* CONFIG_KVM */
> 
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 7d5a51c..faa0a0b 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -143,6 +143,9 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
> 
> #ifdef CONFIG_KVM_BOOKE_HV
> 	new_msr |= MSR_GS;
> +
> +	if (vcpu->guest_debug)
> +		new_msr |= MSR_DE;
> #endif
> 
> 	vcpu->arch.shared->msr = new_msr;
> @@ -711,7 +714,8 @@ out:
> 	return ret;
> }
> 
> -static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
> +static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
> +			  int exit_nr)

Why pass in exit_nr?

> {
> 	enum emulation_result er;
> 
> @@ -728,6 +732,13 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
> 		run->exit_reason = KVM_EXIT_DCR;
> 		return RESUME_HOST;
> 
> +	case EMULATE_DEBUG_INST:
> +		run->exit_reason = KVM_EXIT_DEBUG;
> +		run->debug.arch.address = vcpu->arch.pc;
> +		run->debug.arch.status = 0;
> +		kvmppc_account_exit(vcpu, DEBUG_EXITS);
> +		return RESUME_HOST;
> +
> 	case EMULATE_FAIL:
> 		printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
> 		       __func__, vcpu->arch.pc, vcpu->arch.last_inst);
> @@ -743,6 +754,28 @@ 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)
> +{
> +	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 = vcpu->arch.shadow_dbg_reg.dac[0];
> +		else if (dbsr & (DBSR_DAC2R | DBSR_DAC2W))
> +			run->debug.arch.address = vcpu->arch.shadow_dbg_reg.dac[1];
> +	}
> +
> +	return RESUME_HOST;
> +}
> +
> static void kvmppc_fill_pt_regs(struct pt_regs *regs)
> {
> 	ulong r1, ip, msr, lr;
> @@ -887,7 +920,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
> 		break;
> 
> 	case BOOKE_INTERRUPT_HV_PRIV:
> -		r = emulation_exit(run, vcpu);
> +		r = emulation_exit(run, vcpu, exit_nr);
> 		break;
> 
> 	case BOOKE_INTERRUPT_PROGRAM:
> @@ -906,7 +939,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
> 			break;
> 		}
> 
> -		r = emulation_exit(run, vcpu);
> +		r = emulation_exit(run, vcpu, exit_nr);
> 		break;
> 
> 	case BOOKE_INTERRUPT_FP_UNAVAIL:
> @@ -1096,18 +1129,11 @@ 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;
> 	}
> 
> @@ -1483,10 +1509,78 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
> 	return r;
> }
> 
> +#define BP_NUM	KVMPPC_BOOKE_IAC_NUM
> +#define WP_NUM	KVMPPC_BOOKE_DAC_NUM
> +
> int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> 					 struct kvm_guest_debug *dbg)
> {
> -	return -EINVAL;
> +
> +	if (!(dbg->control & KVM_GUESTDBG_ENABLE)) {
> +		/* Clear All debug events */
> +		vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
> +		vcpu->guest_debug = 0;
> +		return 0;
> +	}
> +
> +	vcpu->guest_debug = dbg->control;
> +	vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
> +
> +	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
> +		vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC;
> +
> +	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
> +		struct kvmppc_booke_debug_reg *gdbgr =
> +				&(vcpu->arch.shadow_dbg_reg);
> +		int n, b = 0, w = 0;
> +		const u32 bp_code[] = {
> +			DBCR0_IAC1 | DBCR0_IDM,
> +			DBCR0_IAC2 | DBCR0_IDM,
> +			DBCR0_IAC3 | DBCR0_IDM,
> +			DBCR0_IAC4 | DBCR0_IDM
> +		};
> +		const u32 wp_code[] = {
> +			DBCR0_DAC1W | DBCR0_IDM,
> +			DBCR0_DAC2W | DBCR0_IDM,
> +			DBCR0_DAC1R | DBCR0_IDM,
> +			DBCR0_DAC2R | DBCR0_IDM
> +		};
> +
> +#ifndef CONFIG_KVM_BOOKE_HV

Please reverse the logic here. #ifndef ... #else is always a bad idea.

> +		gdbgr->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
> +				DBCR1_IAC3US | DBCR1_IAC4US;
> +		gdbgr->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
> +#else
> +		gdbgr->dbcr1 = 0;
> +		gdbgr->dbcr2 = 0;
> +#endif
> +
> +		for (n = 0; n < (BP_NUM + WP_NUM); n++) {
> +			u32 type = dbg->arch.bp[n].type;
> +
> +			if (!type)
> +				break;
> +
> +			if (type & (KVMPPC_DEBUG_WATCH_READ |
> +				    KVMPPC_DEBUG_WATCH_WRITE)) {
> +				if (w < WP_NUM) {
> +					if (type & KVMPPC_DEBUG_WATCH_READ)
> +						gdbgr->dbcr0 |= wp_code[w + 2];
> +					if (type & KVMPPC_DEBUG_WATCH_WRITE)
> +						gdbgr->dbcr0 |= wp_code[w];
> +					gdbgr->dac[w] = dbg->arch.bp[n].addr;
> +					w++;
> +				}
> +			} else if (type & KVMPPC_DEBUG_BREAKPOINT) {
> +				if (b < BP_NUM) {
> +					gdbgr->dbcr0 |= bp_code[b];
> +					gdbgr->iac[b] = dbg->arch.bp[n].addr;
> +					b++;
> +				}
> +			}
> +		}
> +	}
> +	return 0;
> }

I'll stop reviewing here. This patch is way too big. Please split it up in smaller, understandable bits.


Alex

> 
> int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
> diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
> index dd9c5d4..734c549 100644
> --- a/arch/powerpc/kvm/booke_interrupts.S
> +++ b/arch/powerpc/kvm/booke_interrupts.S
> @@ -39,6 +39,8 @@
> #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4)
> #define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
> #define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */
> +#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
> +			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
> 
> #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
>                         (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
> @@ -52,6 +54,8 @@
>                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
>                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
> 
> +#define NEED_DEBUG_SAVE (1<<BOOKE_INTERRUPT_DEBUG)
> +
> .macro __KVM_HANDLER ivor_nr scratch srr0
> 	stw	r3, VCPU_GPR(R3)(r4)
> 	stw	r5, VCPU_GPR(R5)(r4)
> @@ -212,6 +216,59 @@ _GLOBAL(kvmppc_resume_host)
> 	stw	r9, VCPU_FAULT_ESR(r4)
> ..skip_esr:
> 
> +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> +	rlwinm.	r8, r9, 0, ~DBCR0_IDM
> +	beq	skip_load_host_debug
> +	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> +	andis.	r9, r9, DBCR0_AC_BITS@h
> +	li	r9, 0
> +	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
> +	beq	skip_load_hw_bkpts
> +	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> +	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> +	mtspr	SPRN_DBCR1, r7
> +	mtspr	SPRN_DBCR2, r9
> +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> +	mtspr	SPRN_IAC1, r7
> +	mtspr	SPRN_IAC2, r9
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> +	mtspr	SPRN_IAC3, r3
> +	mtspr	SPRN_IAC4, r4
> +#endif
> +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> +	mtspr	SPRN_DAC1, r7
> +	mtspr	SPRN_DAC2, r9
> +skip_load_hw_bkpts:
> +	/* Clear h/w DBSR and save current(guest) DBSR */
> +	mfspr	r9, SPRN_DBSR
> +	mtspr	SPRN_DBSR, r9
> +	isync
> +	andi.	r7, r6, NEED_DEBUG_SAVE
> +	beq	skip_dbsr_save
> +	/*
> +	 * If vcpu->guest_debug flag is set then do not check for
> +	 * shared->msr.DE as this debugging (say by QEMU) does not
> +	 * depends on shared->msr.de. In these scanerios MSR.DE is
> +	 * always set using shared_msr and should be handled always.
> +	 */
> +	lwz	r7, VCPU_GUEST_DEBUG(r4)
> +	cmpwi	r7, 0
> +	bne	skip_save_trap_event
> +	PPC_LL	r3, VCPU_SHARED(r4)
> +	PPC_LD(r3, VCPU_SHARED_MSR, r3)
> +	andi.	r3, r3, MSR_DE
> +	bne	skip_save_trap_event
> +	andis.	r9, r9, DBSR_TIE@h
> +skip_save_trap_event:
> +	stw	r9, VCPU_DBSR(r4)
> +skip_dbsr_save:
> +	mtspr	SPRN_DBCR0, r8
> +skip_load_host_debug:
> +
> 	/* Save remaining volatile guest register state to vcpu. */
> 	stw	r0, VCPU_GPR(R0)(r4)
> 	stw	r1, VCPU_GPR(R1)(r4)
> @@ -465,6 +522,63 @@ lightweight_exit:
> 	PPC_LD(r3, VCPU_SHARED_SPRG7, r5)
> 	mtspr	SPRN_SPRG7W, r3
> 
> +	mfmsr	r7
> +	rlwinm	r7, r7, 0, ~MSR_DE
> +	mtmsr	r7
> +	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> +	rlwinm.	r7, r6, 0, ~DBCR0_IDM
> +	beq	skip_load_guest_debug
> +	mfspr	r8, SPRN_DBCR0
> +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> +	andis.	r3, r6, DBCR0_AC_BITS@h
> +	beq	skip_hw_bkpts
> +	mfspr	r7, SPRN_DBCR1
> +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> +	mfspr	r8, SPRN_DBCR2
> +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> +	mfspr	r7, SPRN_IAC1
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> +	mfspr	r8, SPRN_IAC2
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	mfspr	r7, SPRN_IAC3
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> +	mfspr	r8, SPRN_IAC4
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> +#endif
> +	mfspr	r7, SPRN_DAC1
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> +	mfspr	r8, SPRN_DAC2
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> +	li	r8, 0
> +	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2, r4)
> +	mtspr	SPRN_DBCR1, r7
> +	mtspr	SPRN_DBCR2, r8
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
> +	mtspr	SPRN_IAC1, r7
> +	mtspr	SPRN_IAC2, r8
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
> +	mtspr	SPRN_IAC3, r7
> +	mtspr	SPRN_IAC4, r8
> +#endif
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
> +	mtspr	SPRN_DAC1, r7
> +	mtspr	SPRN_DAC2, r8
> +skip_hw_bkpts:
> +	/* Clear if any deferred debug event */
> +	mfspr	r8, SPRN_DBSR
> +	mtspr	SPRN_DBSR, r8
> +	isync
> +	/* Restore guest DBCR */
> +	mtspr	SPRN_DBCR0, r6
> +skip_load_guest_debug:
> +
> #ifdef CONFIG_KVM_EXIT_TIMING
> 	/* save enter time */
> 1:
> diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
> index e8ed7d6..0d830cc 100644
> --- a/arch/powerpc/kvm/bookehv_interrupts.S
> +++ b/arch/powerpc/kvm/bookehv_interrupts.S
> @@ -62,6 +62,10 @@
> #define NEED_EMU		0x00000001 /* emulation -- save nv regs */
> #define NEED_DEAR		0x00000002 /* save faulting DEAR */
> #define NEED_ESR		0x00000004 /* save faulting ESR */
> +#define NEED_DBSR		0x00000008 /* save DBSR */
> +
> +#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
> +			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
> 
> /*
>  * On entry:
> @@ -201,6 +205,11 @@
> 	PPC_STL	r9, VCPU_FAULT_DEAR(r4)
> 	.endif
> 
> +	.if	\flags & NEED_DBSR
> +	mfspr	r9, SPRN_DBSR
> +	stw	r9, VCPU_DBSR(r4)
> +	.endif
> +
> 	b	kvmppc_resume_host
> .endm
> 
> @@ -316,9 +325,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, EX_PARAMS(GDBELL), \
> kvm_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, EX_PARAMS(CRIT), \
> 	SPRN_CSRR0, SPRN_CSRR1, 0
> kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \
> -	SPRN_DSRR0, SPRN_DSRR1, 0
> +	SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
> kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \
> -	SPRN_CSRR0, SPRN_CSRR1, 0
> +	SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
> #else
> /*
>  * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
> @@ -411,9 +420,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0
> kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
> 	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> -	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
> kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> -	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
> +	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
> #endif
> 
> /* Registers:
> @@ -423,6 +432,56 @@ kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
>  *  r14: KVM exit number
>  */
> _GLOBAL(kvmppc_resume_host)
> +	/*
> +	 * If guest not used debug facility then hw debug registers
> +	 * already have proper host values. If guest used debug
> +	 * facility then restore host debug registers.
> +	 * No Need to save guest debug registers as they are already intact
> +	 * in guest/shadow registers.
> +	 */
> +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> +	rlwinm.	r8, r9, 0, ~DBCR0_IDM
> +	beq	skip_load_host_debug
> +	lwz	r3, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> +	andis.	r9, r9, DBCR0_AC_BITS@h
> +	li	r9, 0
> +	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
> +	beq	skip_load_hw_bkpts
> +	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> +	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> +	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
> +	mtspr	SPRN_DBCR1, r7
> +	PPC_LD(r6, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> +	mtspr	SPRN_DBCR2, r8
> +	mtspr	SPRN_DBCR4, r9
> +	mtspr	SPRN_IAC1, r6
> +	mtspr	SPRN_IAC2, r7
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> +	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> +	mtspr	SPRN_IAC3, r7
> +	mtspr	SPRN_IAC4, r8
> +#endif
> +	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> +	mtspr	SPRN_DAC1, r8
> +	mtspr	SPRN_DAC2, r9
> +skip_load_hw_bkpts:
> +	isync
> +	/* Clear h/w DBSR */
> +	mfspr	r8, SPRN_DBSR
> +	mtspr	SPRN_DBSR, r8
> +	isync
> +	/* Clear EPCR.DUVD and set host DBCR0 */
> +	mfspr	r8, SPRN_EPCR
> +	rlwinm	r8, r8, 0, ~SPRN_EPCR_DUVD
> +	mtspr	SPRN_EPCR, r8
> +	isync
> +	mtspr	SPRN_DBCR0, r3
> +	isync
> +skip_load_host_debug:
> +
> 	/* Save remaining volatile guest register state to vcpu. */
> 	mfspr	r3, SPRN_VRSAVE
> 	PPC_STL	r0, VCPU_GPR(R0)(r4)
> @@ -662,6 +721,84 @@ lightweight_exit:
> 	mtspr	SPRN_SPRG6W, r7
> 	mtspr	SPRN_SPRG7W, r8
> 
> +	mfmsr	r7
> +	rlwinm	r7, r7, 0, ~MSR_DE
> +	mtmsr	r7
> +	/*
> +	 * Load hw debug registers with guest(shadow) debug registers
> +	 * if guest is using the debug facility and also set EPCR.DUVD
> +	 * to not allow debug events in HV mode. Do not change the
> +	 * debug registers if guest is not using the debug facility.
> +	 */
> +	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> +	rlwinm.	r7, r6, 0, ~DBCR0_IDM
> +	beq	skip_load_guest_debug
> +	/* Save host DBCR0 */
> +	mfspr	r8, SPRN_DBCR0
> +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> +	/*
> +	 * Save host DBCR1/2, IACx and DACx and load guest DBCR1/2,
> +	 * IACx and DACx if guest using hw breakpoint/watchpoints.
> +	 */
> +	andis.	r3, r6, DBCR0_AC_BITS@h
> +	beq	skip_hw_bkpts
> +	mfspr	r7, SPRN_DBCR1
> +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> +	mfspr	r8, SPRN_DBCR2
> +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> +	mfspr	r7, SPRN_DBCR4
> +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
> +	mfspr	r8, SPRN_IAC1
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> +	mfspr	r7, SPRN_IAC2
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	mfspr	r8, SPRN_IAC3
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> +	mfspr	r7, SPRN_IAC4
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> +#endif
> +	mfspr	r8, SPRN_DAC1
> +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> +	mfspr	r7, SPRN_DAC2
> +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> +	li	r8, 0
> +	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
> +	lwz	r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1(r4)
> +	lwz	r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2(r4)
> +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR4(r4)
> +	mtspr	SPRN_DBCR1, r7
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
> +	PPC_LD(r3, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
> +	mtspr	SPRN_DBCR2, r8
> +	mtspr	SPRN_DBCR4, r9
> +	mtspr	SPRN_IAC1, r7
> +	mtspr	SPRN_IAC2, r3
> +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
> +	mtspr	SPRN_IAC3, r7
> +	mtspr	SPRN_IAC4, r8
> +#endif
> +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
> +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
> +	mtspr	SPRN_DAC1, r7
> +	mtspr	SPRN_DAC2, r8
> +skip_hw_bkpts:
> +	/* Set EPCR.DUVD and guest DBCR0 */
> +	mfspr	r7, SPRN_EPCR
> +	oris	r7, r7, SPRN_EPCR_DUVD@h
> +	mtspr	SPRN_EPCR, r7
> +	isync
> +	/* Clear if any deferred debug event */
> +	mfspr	r8, SPRN_DBSR
> +	mtspr	SPRN_DBSR, r8
> +	isync
> +	/* Restore guest DBCR */
> +	mtspr	SPRN_DBCR0, r6
> +	isync
> +skip_load_guest_debug:
> +
> 	/* Load some guest volatiles. */
> 	PPC_LL	r3, VCPU_LR(r4)
> 	PPC_LL	r5, VCPU_XER(r4)
> diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
> index e78f353..ddb903e 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -26,6 +26,7 @@
> #define XOP_TLBRE   946
> #define XOP_TLBWE   978
> #define XOP_TLBILX  18
> +#define XOP_EHPRIV  270
> 
> #ifdef CONFIG_KVM_E500MC
> static int dbell2prio(ulong param)
> @@ -130,6 +131,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 = EMULATE_DEBUG_INST;
> +			*advance = 0;
> +			break;
> +
> 		default:
> 			emulated = EMULATE_FAIL;
> 		}
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index dead142..81abe92 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -182,8 +182,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> 
> -	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
> -				 SPRN_EPCR_DUVD;
> +	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI;
> #ifdef CONFIG_64BIT
> 	vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM;
> #endif
> -- 
> 1.7.0.4
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-16  8:24 ` [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest Bharat Bhushan
@ 2013-01-25 12:13   ` Alexander Graf
  2013-01-30 11:12     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-25 12:13 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, Bharat Bhushan


On 16.01.2013, at 09:24, Bharat Bhushan wrote:

> Allow userspace to inject debug interrupt to guest. QEMU can

s/QEMU/user space.

> inject the debug interrupt to guest if it is not able to handle
> the debug interrupt.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> ---
> arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
> arch/powerpc/kvm/e500mc.c |   10 +++++++++-
> 2 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index faa0a0b..547797f 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
> #endif
> }
> 
> +#ifdef CONFIG_KVM_BOOKE_HV
> +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu)
> +{
> +	return test_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions);
> +}
> +#endif
> +
> /*
>  * Helper function for "full" MSR writes.  No need to call this if only
>  * EE/CE/ME/DE/RI are changing.
> @@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
> #ifdef CONFIG_KVM_BOOKE_HV
> 	new_msr |= MSR_GS;
> 
> -	if (vcpu->guest_debug)
> +	/*
> +	 * Set MSR_DE if the hardware debug resources are owned by user-space
> +	 * and there is no debug interrupt pending for guest to handle.

Why? And why is this whole thing only executed on HV?


Alex

> +	 */
> +	if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu))
> 		new_msr |= MSR_DE;
> #endif
> 
> @@ -234,6 +245,16 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu *vcpu)
> 	clear_bit(BOOKE_IRQPRIO_WATCHDOG, &vcpu->arch.pending_exceptions);
> }
> 
> +static void kvmppc_core_queue_debug(struct kvm_vcpu *vcpu)
> +{
> +	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DEBUG);
> +}
> +
> +static void kvmppc_core_dequeue_debug(struct kvm_vcpu *vcpu)
> +{
> +	clear_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions);
> +}
> +
> static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
> {
> #ifdef CONFIG_KVM_BOOKE_HV
> @@ -1278,6 +1299,7 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
> 	sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
> 	sregs->u.e.tb = tb;
> 	sregs->u.e.vrsave = vcpu->arch.vrsave;
> +	sregs->u.e.dbsr = vcpu->arch.dbsr;
> }
> 
> static int set_sregs_base(struct kvm_vcpu *vcpu,
> @@ -1310,6 +1332,14 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
> 		update_timer_ints(vcpu);
> 	}
> 
> +	if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DBSR) {
> +		vcpu->arch.dbsr = sregs->u.e.dbsr;
> +		if (vcpu->arch.dbsr)
> +			kvmppc_core_queue_debug(vcpu);
> +		else
> +			kvmppc_core_dequeue_debug(vcpu);
> +	}
> +
> 	return 0;
> }
> 
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 81abe92..7d90622 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -208,7 +208,7 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> 
> 	sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
> -			       KVM_SREGS_E_PC;
> +			       KVM_SREGS_E_PC | KVM_SREGS_E_ED;
> 	sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
> 
> 	sregs->u.e.impl.fsl.features = 0;
> @@ -216,6 +216,9 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 	sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
> 	sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
> 
> +	sregs->u.e.dsrr0 = vcpu->arch.dsrr0;
> +	sregs->u.e.dsrr1 = vcpu->arch.dsrr1;
> +
> 	kvmppc_get_sregs_e500_tlb(vcpu, sregs);
> 
> 	sregs->u.e.ivor_high[3] =
> @@ -256,6 +259,11 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
> 			sregs->u.e.ivor_high[5];
> 	}
> 
> +	if (sregs->u.e.features & KVM_SREGS_E_ED) {
> +		vcpu->arch.dsrr0 = sregs->u.e.dsrr0;
> +		vcpu->arch.dsrr1 = sregs->u.e.dsrr1;
> +	}
> +
> 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> }
> 
> -- 
> 1.7.0.4
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-25 12:13   ` Alexander Graf
@ 2013-01-30 11:12     ` Bhushan Bharat-R65777
  2013-01-31 12:04       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-30 11:12 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Friday, January 25, 2013 5:44 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
> 
> 
> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> 
> > Allow userspace to inject debug interrupt to guest. QEMU can
> 
> s/QEMU/user space.
> 
> > inject the debug interrupt to guest if it is not able to handle the
> > debug interrupt.
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
> > arch/powerpc/kvm/e500mc.c |   10 +++++++++-
> > 2 files changed, 40 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > faa0a0b..547797f 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
> > *vcpu) #endif }
> >
> > +#ifdef CONFIG_KVM_BOOKE_HV
> > +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu) {
> > +	return test_bit(BOOKE_IRQPRIO_DEBUG,
> > +&vcpu->arch.pending_exceptions); } #endif
> > +
> > /*
> >  * Helper function for "full" MSR writes.  No need to call this if only
> >  * EE/CE/ME/DE/RI are changing.
> > @@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
> > #ifdef CONFIG_KVM_BOOKE_HV
> > 	new_msr |= MSR_GS;
> >
> > -	if (vcpu->guest_debug)
> > +	/*
> > +	 * Set MSR_DE if the hardware debug resources are owned by user-space
> > +	 * and there is no debug interrupt pending for guest to handle.
> 
> Why?

QEMU is using the IAC/DAC registers to set hardware breakpoint/watchpoints via debug ioctls. As debug events are enabled/gated by MSR_DE so somehow we need to set MSR_DE on hardware MSR when guest is running in this case.

On bookehv this is how I am controlling the MSR_DE in hardware MSR.  

> And why is this whole thing only executed on HV?

On e500v2 we always enable MSR_DE using vcpu->arch.shadow_msr in e500.c
#ifndef CONFIG_KVM_BOOKE_HV
-       vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
+       vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
        vcpu->arch.shadow_pid = 1;
        vcpu->arch.shared->msr = 0;
#endif

Thanks
-Bharat

> 
> 
> Alex
> 
> > +	 */
> > +	if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu))
> > 		new_msr |= MSR_DE;
> > #endif
> >
> > @@ -234,6 +245,16 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu
> *vcpu)
> > 	clear_bit(BOOKE_IRQPRIO_WATCHDOG, &vcpu->arch.pending_exceptions);
> > }
> >
> > +static void kvmppc_core_queue_debug(struct kvm_vcpu *vcpu)
> > +{
> > +	kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DEBUG);
> > +}
> > +
> > +static void kvmppc_core_dequeue_debug(struct kvm_vcpu *vcpu)
> > +{
> > +	clear_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions);
> > +}
> > +
> > static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
> > {
> > #ifdef CONFIG_KVM_BOOKE_HV
> > @@ -1278,6 +1299,7 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
> > 	sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
> > 	sregs->u.e.tb = tb;
> > 	sregs->u.e.vrsave = vcpu->arch.vrsave;
> > +	sregs->u.e.dbsr = vcpu->arch.dbsr;
> > }
> >
> > static int set_sregs_base(struct kvm_vcpu *vcpu,
> > @@ -1310,6 +1332,14 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
> > 		update_timer_ints(vcpu);
> > 	}
> >
> > +	if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DBSR) {
> > +		vcpu->arch.dbsr = sregs->u.e.dbsr;
> > +		if (vcpu->arch.dbsr)
> > +			kvmppc_core_queue_debug(vcpu);
> > +		else
> > +			kvmppc_core_dequeue_debug(vcpu);
> > +	}
> > +
> > 	return 0;
> > }
> >
> > diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> > index 81abe92..7d90622 100644
> > --- a/arch/powerpc/kvm/e500mc.c
> > +++ b/arch/powerpc/kvm/e500mc.c
> > @@ -208,7 +208,7 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct
> kvm_sregs *sregs)
> > 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> >
> > 	sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
> > -			       KVM_SREGS_E_PC;
> > +			       KVM_SREGS_E_PC | KVM_SREGS_E_ED;
> > 	sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
> >
> > 	sregs->u.e.impl.fsl.features = 0;
> > @@ -216,6 +216,9 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct
> kvm_sregs *sregs)
> > 	sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
> > 	sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
> >
> > +	sregs->u.e.dsrr0 = vcpu->arch.dsrr0;
> > +	sregs->u.e.dsrr1 = vcpu->arch.dsrr1;
> > +
> > 	kvmppc_get_sregs_e500_tlb(vcpu, sregs);
> >
> > 	sregs->u.e.ivor_high[3] =
> > @@ -256,6 +259,11 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct
> kvm_sregs *sregs)
> > 			sregs->u.e.ivor_high[5];
> > 	}
> >
> > +	if (sregs->u.e.features & KVM_SREGS_E_ED) {
> > +		vcpu->arch.dsrr0 = sregs->u.e.dsrr0;
> > +		vcpu->arch.dsrr1 = sregs->u.e.dsrr1;
> > +	}
> > +
> > 	return kvmppc_set_sregs_ivor(vcpu, sregs);
> > }
> >
> > --
> > 1.7.0.4
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-25 11:42   ` Alexander Graf
@ 2013-01-30 11:30     ` Bhushan Bharat-R65777
  2013-01-31 12:17       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-30 11:30 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, January 25, 2013 5:13 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> 
> 
> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> 
> > From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> >
> > Installed debug handler will be used for guest debug support and debug
> > facility emulation features (patches for these features will follow
> > this patch).
> >
> > Signed-off-by: Liu Yu <yu.liu@freescale.com>
> > [bharat.bhushan@freescale.com: Substantial changes]
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/include/asm/kvm_host.h |    1 +
> > arch/powerpc/kernel/asm-offsets.c   |    1 +
> > arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-----
> > 3 files changed, 44 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_host.h
> > b/arch/powerpc/include/asm/kvm_host.h
> > index 8a72d59..f4ba881 100644
> > --- a/arch/powerpc/include/asm/kvm_host.h
> > +++ b/arch/powerpc/include/asm/kvm_host.h
> > @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> > 	u32 tlbcfg[4];
> > 	u32 mmucfg;
> > 	u32 epr;
> > +	u32 crit_save;
> > 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> > 	gpa_t paddr_accessed;
> > diff --git a/arch/powerpc/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index 46f6afd..02048f3 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -562,6 +562,7 @@ int main(void)
> > 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> > 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> > 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> > +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> > #endif /* CONFIG_PPC_BOOK3S */
> > #endif /* CONFIG_KVM */
> >
> > diff --git a/arch/powerpc/kvm/booke_interrupts.S
> > b/arch/powerpc/kvm/booke_interrupts.S
> > index eae8483..dd9c5d4 100644
> > --- a/arch/powerpc/kvm/booke_interrupts.S
> > +++ b/arch/powerpc/kvm/booke_interrupts.S
> > @@ -52,12 +52,7 @@
> >                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >
> > -.macro KVM_HANDLER ivor_nr scratch srr0
> > -_GLOBAL(kvmppc_handler_\ivor_nr)
> > -	/* Get pointer to vcpu and record exit number. */
> > -	mtspr	\scratch , r4
> > -	mfspr   r4, SPRN_SPRG_THREAD
> > -	lwz     r4, THREAD_KVM_VCPU(r4)
> > +.macro __KVM_HANDLER ivor_nr scratch srr0
> > 	stw	r3, VCPU_GPR(R3)(r4)
> > 	stw	r5, VCPU_GPR(R5)(r4)
> > 	stw	r6, VCPU_GPR(R6)(r4)
> > @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> > 	bctr
> > .endm
> >
> > +.macro KVM_HANDLER ivor_nr scratch srr0
> > +_GLOBAL(kvmppc_handler_\ivor_nr)
> > +	/* Get pointer to vcpu and record exit number. */
> > +	mtspr	\scratch , r4
> > +	mfspr   r4, SPRN_SPRG_THREAD
> > +	lwz     r4, THREAD_KVM_VCPU(r4)
> > +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> > +
> > +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> > +_GLOBAL(kvmppc_handler_\ivor_nr)
> > +	mtspr   \scratch, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	stw	r3, VCPU_CRIT_SAVE(r4)
> > +	mfcr	r3
> > +	mfspr	r4, SPRN_CSRR1
> > +	andi.	r4, r4, MSR_PR
> > +	bne	1f
> 
> 
> > +	/* debug interrupt happened in enter/exit path */
> > +	mfspr   r4, SPRN_CSRR1
> > +	rlwinm  r4, r4, 0, ~MSR_DE
> > +	mtspr   SPRN_CSRR1, r4
> > +	lis	r4, 0xffff
> > +	ori	r4, r4, 0xffff
> > +	mtspr	SPRN_DBSR, r4
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	mtcr	r3
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	mfspr   r4, \scratch
> > +	rfci
> 
> What is this part doing? Try to ignore the debug exit?

As BOOKE doesn't have hardware support for virtualization, hardware never know current pc is in guest or in host.
So when enable hardware single step for guest, it cannot be disabled at the time guest exit. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path.

With the above code we recognize this kind of single step interrupt disable single step and rfci.

> Why would we have MSR_DE
> enabled in the first place when we can't handle it?

When QEMU is using hardware debug resource then we always set MSR_DE during guest is running.

> 
> > +1:	/* debug interrupt happened in guest */
> > +	mtcr	r3
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	__KVM_HANDLER \ivor_nr \scratch \srr0
> 
> I don't think you need the __KVM_HANDLER split. This should be quite easily
> refactorable into a simple DBG prolog.

Can you please elaborate how you are envisioning this?

Thanks
-Bharat

> 
> 
> Alex
> 
> > +.endm
> > +
> > .macro KVM_HANDLER_ADDR ivor_nr
> > 	.long	kvmppc_handler_\ivor_nr
> > .endm
> > @@ -98,7 +133,7 @@ KVM_HANDLER BOOKE_INTERRUPT_FIT SPRN_SPRG_RSCRATCH0
> > SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG SPRN_SPRG_RSCRATCH_CRIT
> > SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS SPRN_SPRG_RSCRATCH0
> > SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS SPRN_SPRG_RSCRATCH0
> > SPRN_SRR0 -KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> > SPRN_CSRR0
> > +KVM_DBG_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT
> > +SPRN_CSRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
> > --
> > 1.7.0.4
> >
> >
> 



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

* RE: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-25 11:53       ` Alexander Graf
@ 2013-01-30 14:15         ` Bhushan Bharat-R65777
  2013-01-31 13:01           ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-30 14:15 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, January 25, 2013 5:24 PM
> To: Bhushan Bharat-R65777
> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
> 
> 
> On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Paul Mackerras [mailto:paulus@samba.org]
> >> Sent: Thursday, January 17, 2013 12:53 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de;
> >> Bhushan Bharat-
> >> R65777
> >> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >> defined
> >>
> >> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
> >>> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
> >>> ioctl support. Follow up patches will use this for setting up
> >>> hardware breakpoints, watchpoints and software breakpoints.
> >>
> >> [snip]
> >>
> >>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >>> index 453a10f..7d5a51c 100644
> >>> --- a/arch/powerpc/kvm/booke.c
> >>> +++ b/arch/powerpc/kvm/booke.c
> >>> @@ -1483,6 +1483,12 @@ 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;
> >>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> >>> index 934413c..4c94ca9 100644
> >>> --- a/arch/powerpc/kvm/powerpc.c
> >>> +++ b/arch/powerpc/kvm/powerpc.c
> >>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >>> #endif  }
> >>>
> >>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> >>> -                                        struct kvm_guest_debug *dbg)
> >>> -{
> >>> -	return -EINVAL;
> >>> -}
> >>> -
> >>
> >> This will break the build for non-book E machines, since
> >> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
> >> You need to add it to arch/powerpc/kvm/book3s.c as well.
> >
> > right,  I will correct this.
> 
> Would the implementation actually be different on booke vs book3s? My feeling is
> that powerpc.c is actually the right place for this.
> 

I am not sure there will be anything common between book3s and booke. Should we define the cpu specific function something like kvm_ppc_vcpu_ioctl_set_guest_debug() for booke and book3s and call this new defined function from kvm_arch_vcpu_ioctl_set_guest_debug() in powerpc.c ?

Thanks
-Bharat

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-30 11:12     ` Bhushan Bharat-R65777
@ 2013-01-31 12:04       ` Alexander Graf
  2013-01-31 17:59         ` Bhushan Bharat-R65777
  2013-01-31 18:03         ` Scott Wood
  0 siblings, 2 replies; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 12:04 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 30.01.2013, at 12:12, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Friday, January 25, 2013 5:44 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
>> 
>> 
>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>> 
>>> Allow userspace to inject debug interrupt to guest. QEMU can
>> 
>> s/QEMU/user space.
>> 
>>> inject the debug interrupt to guest if it is not able to handle the
>>> debug interrupt.
>>> 
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
>>> arch/powerpc/kvm/e500mc.c |   10 +++++++++-
>>> 2 files changed, 40 insertions(+), 2 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>> faa0a0b..547797f 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>>> @@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
>>> *vcpu) #endif }
>>> 
>>> +#ifdef CONFIG_KVM_BOOKE_HV
>>> +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu) {
>>> +	return test_bit(BOOKE_IRQPRIO_DEBUG,
>>> +&vcpu->arch.pending_exceptions); } #endif
>>> +
>>> /*
>>> * Helper function for "full" MSR writes.  No need to call this if only
>>> * EE/CE/ME/DE/RI are changing.
>>> @@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
>>> #ifdef CONFIG_KVM_BOOKE_HV
>>> 	new_msr |= MSR_GS;
>>> 
>>> -	if (vcpu->guest_debug)
>>> +	/*
>>> +	 * Set MSR_DE if the hardware debug resources are owned by user-space
>>> +	 * and there is no debug interrupt pending for guest to handle.
>> 
>> Why?
> 
> QEMU is using the IAC/DAC registers to set hardware breakpoint/watchpoints via debug ioctls. As debug events are enabled/gated by MSR_DE so somehow we need to set MSR_DE on hardware MSR when guest is running in this case.

Reading this 5 times I still have no idea what you're really checking for here. Maybe the naming for kvmppc_core_pending_debug is just unnatural? What does that function do really?

> 
> On bookehv this is how I am controlling the MSR_DE in hardware MSR.  
> 
>> And why is this whole thing only executed on HV?
> 
> On e500v2 we always enable MSR_DE using vcpu->arch.shadow_msr in e500.c
> #ifndef CONFIG_KVM_BOOKE_HV
> -       vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
> +       vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;

Why? How is e500v2 any different wrt debug? And why wouldn't that work for e500mc?


Alex

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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-30 11:30     ` Bhushan Bharat-R65777
@ 2013-01-31 12:17       ` Alexander Graf
  2013-01-31 16:58         ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 12:17 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, January 25, 2013 5:13 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>> 
>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>> 
>>> Installed debug handler will be used for guest debug support and debug
>>> facility emulation features (patches for these features will follow
>>> this patch).
>>> 
>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>> [bharat.bhushan@freescale.com: Substantial changes]
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-----
>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>> b/arch/powerpc/include/asm/kvm_host.h
>>> index 8a72d59..f4ba881 100644
>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>> 	u32 tlbcfg[4];
>>> 	u32 mmucfg;
>>> 	u32 epr;
>>> +	u32 crit_save;
>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>> 	gpa_t paddr_accessed;
>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>> b/arch/powerpc/kernel/asm-offsets.c
>>> index 46f6afd..02048f3 100644
>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>> @@ -562,6 +562,7 @@ int main(void)
>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
>>> #endif /* CONFIG_PPC_BOOK3S */
>>> #endif /* CONFIG_KVM */
>>> 
>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>> b/arch/powerpc/kvm/booke_interrupts.S
>>> index eae8483..dd9c5d4 100644
>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>> @@ -52,12 +52,7 @@
>>>                       (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>                       (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>> 
>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>> -	/* Get pointer to vcpu and record exit number. */
>>> -	mtspr	\scratch , r4
>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>> 	bctr
>>> .endm
>>> 
>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>> +	/* Get pointer to vcpu and record exit number. */
>>> +	mtspr	\scratch , r4
>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>> +
>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>> +	mtspr   \scratch, r4
>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>> +	mfcr	r3
>>> +	mfspr	r4, SPRN_CSRR1
>>> +	andi.	r4, r4, MSR_PR
>>> +	bne	1f
>> 
>> 
>>> +	/* debug interrupt happened in enter/exit path */
>>> +	mfspr   r4, SPRN_CSRR1
>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>> +	mtspr   SPRN_CSRR1, r4
>>> +	lis	r4, 0xffff
>>> +	ori	r4, r4, 0xffff
>>> +	mtspr	SPRN_DBSR, r4
>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>> +	mtcr	r3
>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>> +	mfspr   r4, \scratch
>>> +	rfci
>> 
>> What is this part doing? Try to ignore the debug exit?
> 
> As BOOKE doesn't have hardware support for virtualization, hardware never know current pc is in guest or in host.
> So when enable hardware single step for guest, it cannot be disabled at the time guest exit. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path.
> 
> With the above code we recognize this kind of single step interrupt disable single step and rfci.
> 
>> Why would we have MSR_DE
>> enabled in the first place when we can't handle it?
> 
> When QEMU is using hardware debug resource then we always set MSR_DE during guest is running.

Right, but why is MSR_DE enabled during the exit path? If MSR_DE wasn't set, you wouldn't get a single step exit. During the exit code path, you could then swap DBSR back to what the host expects (which means no single step). Only after that enable MSR_DE again.

> 
>> 
>>> +1:	/* debug interrupt happened in guest */
>>> +	mtcr	r3
>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
>> 
>> I don't think you need the __KVM_HANDLER split. This should be quite easily
>> refactorable into a simple DBG prolog.
> 
> Can you please elaborate how you are envisioning this?

With this patch, you have

KVM_HANLDER:

  <code>
  __KVM_HANDLER

KVM_DBG_HANDLER:

  <code>
  __KVM_HANDLER

Right?

In KVM_HANDLER, you get:

> .macro KVM_HANDLER ivor_nr scratch srr0
> _GLOBAL(kvmppc_handler_\ivor_nr)
> 	/* Get pointer to vcpu and record exit number. */
> 	mtspr	\scratch , r4
> 	mfspr   r4, SPRN_SPRG_THREAD
> 	lwz     r4, THREAD_KVM_VCPU(r4)
> 	__KVM_HANDLER \ivor_nr \scratch \srr0
> .endm


while KVM_DBG_HANDLER is:

> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> +_GLOBAL(kvmppc_handler_\ivor_nr)
>  <debug specific handling>
> +1:	/* debug interrupt happened in guest */
> +	mtcr	r3
> +	mfspr	r4, SPRN_SPRG_THREAD
> +	lwz	r4, THREAD_KVM_VCPU(r4)
> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> +.endm


So if you write this as

KVM_DBG_HANDLER:
	<debug specific handling>
	1:
	mtcr		r3
	mfspr	r4, SPRN_SPRG_THREAD
	lwz		r4, THREAD_KVM_VCPU(r4)
	lwz		r3, VCPU_CRIT_SAVE(r4)
	lwz		r4, \scratch
	<KVM_HANDLER>

then you get code that is slower :) but it should be easier to read, since the interface between the individual pieces is always the same. Debug shouldn't be a fast path anyway, right?


Alex

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

* Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-30 14:15         ` Bhushan Bharat-R65777
@ 2013-01-31 13:01           ` Alexander Graf
  2013-01-31 14:05             ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 13:01 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 30.01.2013, at 15:15, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, January 25, 2013 5:24 PM
>> To: Bhushan Bharat-R65777
>> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
>> 
>> 
>> On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Paul Mackerras [mailto:paulus@samba.org]
>>>> Sent: Thursday, January 17, 2013 12:53 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de;
>>>> Bhushan Bharat-
>>>> R65777
>>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
>>>> defined
>>>> 
>>>> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
>>>>> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
>>>>> ioctl support. Follow up patches will use this for setting up
>>>>> hardware breakpoints, watchpoints and software breakpoints.
>>>> 
>>>> [snip]
>>>> 
>>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>>>> index 453a10f..7d5a51c 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>> @@ -1483,6 +1483,12 @@ 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;
>>>>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
>>>>> index 934413c..4c94ca9 100644
>>>>> --- a/arch/powerpc/kvm/powerpc.c
>>>>> +++ b/arch/powerpc/kvm/powerpc.c
>>>>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>>>> #endif  }
>>>>> 
>>>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>>>> -                                        struct kvm_guest_debug *dbg)
>>>>> -{
>>>>> -	return -EINVAL;
>>>>> -}
>>>>> -
>>>> 
>>>> This will break the build for non-book E machines, since
>>>> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
>>>> You need to add it to arch/powerpc/kvm/book3s.c as well.
>>> 
>>> right,  I will correct this.
>> 
>> Would the implementation actually be different on booke vs book3s? My feeling is
>> that powerpc.c is actually the right place for this.
>> 
> 
> I am not sure there will be anything common between book3s and booke. Should we define the cpu specific function something like kvm_ppc_vcpu_ioctl_set_guest_debug() for booke and book3s and call this new defined function from kvm_arch_vcpu_ioctl_set_guest_debug() in powerpc.c ?

No, just put it into the subarch directories then :). No need to overengineer anything for now.


Alex

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

* RE: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-31 13:01           ` Alexander Graf
@ 2013-01-31 14:05             ` Bhushan Bharat-R65777
  2013-01-31 14:27               ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 14:05 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Thursday, January 31, 2013 6:31 PM
> To: Bhushan Bharat-R65777
> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
> 
> 
> On 30.01.2013, at 15:15, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Alexander Graf [mailto:agraf@suse.de]
> >> Sent: Friday, January 25, 2013 5:24 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >> defined
> >>
> >>
> >> On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Paul Mackerras [mailto:paulus@samba.org]
> >>>> Sent: Thursday, January 17, 2013 12:53 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de;
> >>>> Bhushan Bharat-
> >>>> R65777
> >>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >>>> defined
> >>>>
> >>>> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
> >>>>> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
> >>>>> ioctl support. Follow up patches will use this for setting up
> >>>>> hardware breakpoints, watchpoints and software breakpoints.
> >>>>
> >>>> [snip]
> >>>>
> >>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >>>>> index 453a10f..7d5a51c 100644
> >>>>> --- a/arch/powerpc/kvm/booke.c
> >>>>> +++ b/arch/powerpc/kvm/booke.c
> >>>>> @@ -1483,6 +1483,12 @@ 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;
> >>>>> diff --git a/arch/powerpc/kvm/powerpc.c
> >>>>> b/arch/powerpc/kvm/powerpc.c index 934413c..4c94ca9 100644
> >>>>> --- a/arch/powerpc/kvm/powerpc.c
> >>>>> +++ b/arch/powerpc/kvm/powerpc.c
> >>>>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >>>>> #endif  }
> >>>>>
> >>>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> >>>>> -                                        struct kvm_guest_debug *dbg)
> >>>>> -{
> >>>>> -	return -EINVAL;
> >>>>> -}
> >>>>> -
> >>>>
> >>>> This will break the build for non-book E machines, since
> >>>> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
> >>>> You need to add it to arch/powerpc/kvm/book3s.c as well.
> >>>
> >>> right,  I will correct this.
> >>
> >> Would the implementation actually be different on booke vs book3s? My
> >> feeling is that powerpc.c is actually the right place for this.
> >>
> >
> > I am not sure there will be anything common between book3s and booke. Should
> we define the cpu specific function something like
> kvm_ppc_vcpu_ioctl_set_guest_debug() for booke and book3s and call this new
> defined function from kvm_arch_vcpu_ioctl_set_guest_debug() in powerpc.c ?
> 
> No, just put it into the subarch directories then :). No need to overengineer
> anything for now.

What you mean by subarch?  Above you mentioned that powerpc.c is right place? 
Is not this patch is doing partially :)

Thanks
-Bharat

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

* Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-31 14:05             ` Bhushan Bharat-R65777
@ 2013-01-31 14:27               ` Alexander Graf
  2013-01-31 14:44                 ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 14:27 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 15:05, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Thursday, January 31, 2013 6:31 PM
>> To: Bhushan Bharat-R65777
>> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
>> 
>> 
>> On 30.01.2013, at 15:15, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>> Sent: Friday, January 25, 2013 5:24 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
>>>> defined
>>>> 
>>>> 
>>>> On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:
>>>> 
>>>>> 
>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Paul Mackerras [mailto:paulus@samba.org]
>>>>>> Sent: Thursday, January 17, 2013 12:53 PM
>>>>>> To: Bhushan Bharat-R65777
>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de;
>>>>>> Bhushan Bharat-
>>>>>> R65777
>>>>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
>>>>>> defined
>>>>>> 
>>>>>> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
>>>>>>> This patch defines the interface parameter for KVM_SET_GUEST_DEBUG
>>>>>>> ioctl support. Follow up patches will use this for setting up
>>>>>>> hardware breakpoints, watchpoints and software breakpoints.
>>>>>> 
>>>>>> [snip]
>>>>>> 
>>>>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>>>>>> index 453a10f..7d5a51c 100644
>>>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>>>> @@ -1483,6 +1483,12 @@ 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;
>>>>>>> diff --git a/arch/powerpc/kvm/powerpc.c
>>>>>>> b/arch/powerpc/kvm/powerpc.c index 934413c..4c94ca9 100644
>>>>>>> --- a/arch/powerpc/kvm/powerpc.c
>>>>>>> +++ b/arch/powerpc/kvm/powerpc.c
>>>>>>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>>>>>> #endif  }
>>>>>>> 
>>>>>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>>>>>> -                                        struct kvm_guest_debug *dbg)
>>>>>>> -{
>>>>>>> -	return -EINVAL;
>>>>>>> -}
>>>>>>> -
>>>>>> 
>>>>>> This will break the build for non-book E machines, since
>>>>>> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
>>>>>> You need to add it to arch/powerpc/kvm/book3s.c as well.
>>>>> 
>>>>> right,  I will correct this.
>>>> 
>>>> Would the implementation actually be different on booke vs book3s? My
>>>> feeling is that powerpc.c is actually the right place for this.
>>>> 
>>> 
>>> I am not sure there will be anything common between book3s and booke. Should
>> we define the cpu specific function something like
>> kvm_ppc_vcpu_ioctl_set_guest_debug() for booke and book3s and call this new
>> defined function from kvm_arch_vcpu_ioctl_set_guest_debug() in powerpc.c ?
>> 
>> No, just put it into the subarch directories then :). No need to overengineer
>> anything for now.
> 
> What you mean by subarch?  Above you mentioned that powerpc.c is right place? 
> Is not this patch is doing partially :)

If the code in powerpc.c only says

void kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) {
    kvmppc_core_set_guest_debug(vcpu, dbg);
}

then doing it in powerpc.c is obviously moot. Since there is no other debug implementation, it's ok if we try and find (and create) commonalities later. So yes, it's ok if you put it into booke.c or even e500.c. Just make sure to not break any other archs (440, book3s_pr, book3s_hv).


Alex

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

* RE: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
  2013-01-31 14:27               ` Alexander Graf
@ 2013-01-31 14:44                 ` Bhushan Bharat-R65777
  0 siblings, 0 replies; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 14:44 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Paul Mackerras, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
> Alexander Graf
> Sent: Thursday, January 31, 2013 7:58 PM
> To: Bhushan Bharat-R65777
> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter defined
> 
> 
> On 31.01.2013, at 15:05, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-ppc-owner@vger.kernel.org
> >> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >> Sent: Thursday, January 31, 2013 6:31 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >> defined
> >>
> >>
> >> On 30.01.2013, at 15:15, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Alexander Graf [mailto:agraf@suse.de]
> >>>> Sent: Friday, January 25, 2013 5:24 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: Paul Mackerras; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >>>> defined
> >>>>
> >>>>
> >>>> On 17.01.2013, at 12:11, Bhushan Bharat-R65777 wrote:
> >>>>
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Paul Mackerras [mailto:paulus@samba.org]
> >>>>>> Sent: Thursday, January 17, 2013 12:53 PM
> >>>>>> To: Bhushan Bharat-R65777
> >>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; agraf@suse.de;
> >>>>>> Bhushan Bharat-
> >>>>>> R65777
> >>>>>> Subject: Re: [PATCH 5/8] KVM: PPC: debug stub interface parameter
> >>>>>> defined
> >>>>>>
> >>>>>> On Wed, Jan 16, 2013 at 01:54:42PM +0530, Bharat Bhushan wrote:
> >>>>>>> This patch defines the interface parameter for
> >>>>>>> KVM_SET_GUEST_DEBUG ioctl support. Follow up patches will use
> >>>>>>> this for setting up hardware breakpoints, watchpoints and software
> breakpoints.
> >>>>>>
> >>>>>> [snip]
> >>>>>>
> >>>>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >>>>>>> index 453a10f..7d5a51c 100644
> >>>>>>> --- a/arch/powerpc/kvm/booke.c
> >>>>>>> +++ b/arch/powerpc/kvm/booke.c
> >>>>>>> @@ -1483,6 +1483,12 @@ 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;
> >>>>>>> diff --git a/arch/powerpc/kvm/powerpc.c
> >>>>>>> b/arch/powerpc/kvm/powerpc.c index 934413c..4c94ca9 100644
> >>>>>>> --- a/arch/powerpc/kvm/powerpc.c
> >>>>>>> +++ b/arch/powerpc/kvm/powerpc.c
> >>>>>>> @@ -532,12 +532,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu
> >>>>>>> *vcpu) #endif  }
> >>>>>>>
> >>>>>>> -int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> >>>>>>> -                                        struct kvm_guest_debug *dbg)
> >>>>>>> -{
> >>>>>>> -	return -EINVAL;
> >>>>>>> -}
> >>>>>>> -
> >>>>>>
> >>>>>> This will break the build for non-book E machines, since
> >>>>>> kvm_arch_vcpu_ioctl_set_guest_debug() is referenced from generic code.
> >>>>>> You need to add it to arch/powerpc/kvm/book3s.c as well.
> >>>>>
> >>>>> right,  I will correct this.
> >>>>
> >>>> Would the implementation actually be different on booke vs book3s?
> >>>> My feeling is that powerpc.c is actually the right place for this.
> >>>>
> >>>
> >>> I am not sure there will be anything common between book3s and
> >>> booke. Should
> >> we define the cpu specific function something like
> >> kvm_ppc_vcpu_ioctl_set_guest_debug() for booke and book3s and call
> >> this new defined function from kvm_arch_vcpu_ioctl_set_guest_debug() in
> powerpc.c ?
> >>
> >> No, just put it into the subarch directories then :). No need to
> >> overengineer anything for now.
> >
> > What you mean by subarch?  Above you mentioned that powerpc.c is right place?
> > Is not this patch is doing partially :)
> 
> If the code in powerpc.c only says
> 
> void kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, struct
> kvm_guest_debug *dbg) {
>     kvmppc_core_set_guest_debug(vcpu, dbg); }
> 
> then doing it in powerpc.c is obviously moot. Since there is no other debug
> implementation, it's ok if we try and find (and create) commonalities later.
> So
> yes, it's ok if you put it into booke.c or even e500.c. Just make sure to not
> break any other archs (440, book3s_pr, book3s_hv).

Right, yes I will correct that it compiles for all archs.

Thanks.
-Bharat

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

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

* RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-31 12:17       ` Alexander Graf
@ 2013-01-31 16:58         ` Bhushan Bharat-R65777
  2013-01-31 17:08           ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 16:58 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Thursday, January 31, 2013 5:47 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> 
> 
> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Alexander Graf [mailto:agraf@suse.de]
> >> Sent: Friday, January 25, 2013 5:13 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >> Bharat-R65777
> >> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>
> >>
> >> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>
> >>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> >>>
> >>> Installed debug handler will be used for guest debug support and
> >>> debug facility emulation features (patches for these features will
> >>> follow this patch).
> >>>
> >>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>> [bharat.bhushan@freescale.com: Substantial changes]
> >>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>> ---
> >>> arch/powerpc/include/asm/kvm_host.h |    1 +
> >>> arch/powerpc/kernel/asm-offsets.c   |    1 +
> >>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++---
> --
> >>> 3 files changed, 44 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/arch/powerpc/include/asm/kvm_host.h
> >>> b/arch/powerpc/include/asm/kvm_host.h
> >>> index 8a72d59..f4ba881 100644
> >>> --- a/arch/powerpc/include/asm/kvm_host.h
> >>> +++ b/arch/powerpc/include/asm/kvm_host.h
> >>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> >>> 	u32 tlbcfg[4];
> >>> 	u32 mmucfg;
> >>> 	u32 epr;
> >>> +	u32 crit_save;
> >>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> >>> 	gpa_t paddr_accessed;
> >>> diff --git a/arch/powerpc/kernel/asm-offsets.c
> >>> b/arch/powerpc/kernel/asm-offsets.c
> >>> index 46f6afd..02048f3 100644
> >>> --- a/arch/powerpc/kernel/asm-offsets.c
> >>> +++ b/arch/powerpc/kernel/asm-offsets.c
> >>> @@ -562,6 +562,7 @@ int main(void)
> >>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> >>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> >>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> >>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> >>> #endif /* CONFIG_PPC_BOOK3S */
> >>> #endif /* CONFIG_KVM */
> >>>
> >>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>> b/arch/powerpc/kvm/booke_interrupts.S
> >>> index eae8483..dd9c5d4 100644
> >>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>> @@ -52,12 +52,7 @@
> >>>                       (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >>>                       (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >>>
> >>> -.macro KVM_HANDLER ivor_nr scratch srr0
> >>> -_GLOBAL(kvmppc_handler_\ivor_nr)
> >>> -	/* Get pointer to vcpu and record exit number. */
> >>> -	mtspr	\scratch , r4
> >>> -	mfspr   r4, SPRN_SPRG_THREAD
> >>> -	lwz     r4, THREAD_KVM_VCPU(r4)
> >>> +.macro __KVM_HANDLER ivor_nr scratch srr0
> >>> 	stw	r3, VCPU_GPR(R3)(r4)
> >>> 	stw	r5, VCPU_GPR(R5)(r4)
> >>> 	stw	r6, VCPU_GPR(R6)(r4)
> >>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>> 	bctr
> >>> .endm
> >>>
> >>> +.macro KVM_HANDLER ivor_nr scratch srr0
> >>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>> +	/* Get pointer to vcpu and record exit number. */
> >>> +	mtspr	\scratch , r4
> >>> +	mfspr   r4, SPRN_SPRG_THREAD
> >>> +	lwz     r4, THREAD_KVM_VCPU(r4)
> >>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>> +
> >>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>> +	mtspr   \scratch, r4
> >>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>> +	stw	r3, VCPU_CRIT_SAVE(r4)
> >>> +	mfcr	r3
> >>> +	mfspr	r4, SPRN_CSRR1
> >>> +	andi.	r4, r4, MSR_PR
> >>> +	bne	1f
> >>
> >>
> >>> +	/* debug interrupt happened in enter/exit path */
> >>> +	mfspr   r4, SPRN_CSRR1
> >>> +	rlwinm  r4, r4, 0, ~MSR_DE
> >>> +	mtspr   SPRN_CSRR1, r4
> >>> +	lis	r4, 0xffff
> >>> +	ori	r4, r4, 0xffff
> >>> +	mtspr	SPRN_DBSR, r4
> >>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>> +	mtcr	r3
> >>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>> +	mfspr   r4, \scratch
> >>> +	rfci
> >>
> >> What is this part doing? Try to ignore the debug exit?
> >
> > As BOOKE doesn't have hardware support for virtualization, hardware never know
> current pc is in guest or in host.
> > So when enable hardware single step for guest, it cannot be disabled at the
> time guest exit. Thus, we'll see that an single step interrupt happens at the
> beginning of guest exit path.
> >
> > With the above code we recognize this kind of single step interrupt disable
> single step and rfci.
> >
> >> Why would we have MSR_DE
> >> enabled in the first place when we can't handle it?
> >
> > When QEMU is using hardware debug resource then we always set MSR_DE during
> guest is running.
> 
> Right, but why is MSR_DE enabled during the exit path? If MSR_DE wasn't set, you
> wouldn't get a single step exit.

We always set MSR_DE in hw MSR when qemu using the debug resource.

> During the exit code path, you could then swap
> DBSR back to what the host expects (which means no single step). Only after that
> enable MSR_DE again.

We do not support deferred debug interrupt, so we do save restore dbsr.

> 
> >
> >>
> >>> +1:	/* debug interrupt happened in guest */
> >>> +	mtcr	r3
> >>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> >>
> >> I don't think you need the __KVM_HANDLER split. This should be quite
> >> easily refactorable into a simple DBG prolog.
> >
> > Can you please elaborate how you are envisioning this?
> 
> With this patch, you have
> 
> KVM_HANLDER:
> 
>   <code>
>   __KVM_HANDLER
> 
> KVM_DBG_HANDLER:
> 
>   <code>
>   __KVM_HANDLER
> 
> Right?
> 
> In KVM_HANDLER, you get:
> 
> > .macro KVM_HANDLER ivor_nr scratch srr0
> > _GLOBAL(kvmppc_handler_\ivor_nr)
> > 	/* Get pointer to vcpu and record exit number. */
> > 	mtspr	\scratch , r4
> > 	mfspr   r4, SPRN_SPRG_THREAD
> > 	lwz     r4, THREAD_KVM_VCPU(r4)
> > 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> 
> 
> while KVM_DBG_HANDLER is:
> 
> > +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> > +_GLOBAL(kvmppc_handler_\ivor_nr)
> >  <debug specific handling>
> > +1:	/* debug interrupt happened in guest */
> > +	mtcr	r3
> > +	mfspr	r4, SPRN_SPRG_THREAD
> > +	lwz	r4, THREAD_KVM_VCPU(r4)
> > +	lwz     r3, VCPU_CRIT_SAVE(r4)
> > +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> 
> 
> So if you write this as
> 
> KVM_DBG_HANDLER:
> 	<debug specific handling>
> 	1:
> 	mtcr		r3
> 	mfspr	r4, SPRN_SPRG_THREAD
> 	lwz		r4, THREAD_KVM_VCPU(r4)
> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> 	lwz		r4, \scratch
> 	<KVM_HANDLER>
> 
> then you get code that is slower :) but it should be easier to read, since the
> interface between the individual pieces is always the same. Debug shouldn't be a
> fast path anyway, right?

Frankly speaking I do not see much difference :).

If we have to do as you mentioned then I think we can just do

KVM_DBG_HANDLER:
 	<debug specific handling>
 	1:
 	mtcr		r3
 	lwz		r3, VCPU_CRIT_SAVE(r4)
 	lwz		r4, \scratch
 	<KVM_HANDLER>

Thanks
-Bharat

> 
> 
> Alex
> 



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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-31 16:58         ` Bhushan Bharat-R65777
@ 2013-01-31 17:08           ` Alexander Graf
  2013-01-31 17:11             ` Alexander Graf
  2013-02-01  5:04             ` Bhushan Bharat-R65777
  0 siblings, 2 replies; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 17:08 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Thursday, January 31, 2013 5:47 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>> Sent: Friday, January 25, 2013 5:13 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>> 
>>>> 
>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>> 
>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>>>> 
>>>>> Installed debug handler will be used for guest debug support and
>>>>> debug facility emulation features (patches for these features will
>>>>> follow this patch).
>>>>> 
>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>>>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++---
>> --
>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>>>> 
>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>> index 8a72d59..f4ba881 100644
>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>>>> 	u32 tlbcfg[4];
>>>>> 	u32 mmucfg;
>>>>> 	u32 epr;
>>>>> +	u32 crit_save;
>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>>>> 	gpa_t paddr_accessed;
>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>>>> b/arch/powerpc/kernel/asm-offsets.c
>>>>> index 46f6afd..02048f3 100644
>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>>>> @@ -562,6 +562,7 @@ int main(void)
>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
>>>>> #endif /* CONFIG_PPC_BOOK3S */
>>>>> #endif /* CONFIG_KVM */
>>>>> 
>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>> index eae8483..dd9c5d4 100644
>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>> @@ -52,12 +52,7 @@
>>>>>                      (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>>>                      (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>>>> 
>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> -	/* Get pointer to vcpu and record exit number. */
>>>>> -	mtspr	\scratch , r4
>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> 	bctr
>>>>> .endm
>>>>> 
>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> +	/* Get pointer to vcpu and record exit number. */
>>>>> +	mtspr	\scratch , r4
>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>> +
>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> +	mtspr   \scratch, r4
>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>>>> +	mfcr	r3
>>>>> +	mfspr	r4, SPRN_CSRR1
>>>>> +	andi.	r4, r4, MSR_PR
>>>>> +	bne	1f
>>>> 
>>>> 
>>>>> +	/* debug interrupt happened in enter/exit path */
>>>>> +	mfspr   r4, SPRN_CSRR1
>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>>>> +	mtspr   SPRN_CSRR1, r4
>>>>> +	lis	r4, 0xffff
>>>>> +	ori	r4, r4, 0xffff
>>>>> +	mtspr	SPRN_DBSR, r4
>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>> +	mtcr	r3
>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>> +	mfspr   r4, \scratch
>>>>> +	rfci
>>>> 
>>>> What is this part doing? Try to ignore the debug exit?
>>> 
>>> As BOOKE doesn't have hardware support for virtualization, hardware never know
>> current pc is in guest or in host.
>>> So when enable hardware single step for guest, it cannot be disabled at the
>> time guest exit. Thus, we'll see that an single step interrupt happens at the
>> beginning of guest exit path.
>>> 
>>> With the above code we recognize this kind of single step interrupt disable
>> single step and rfci.
>>> 
>>>> Why would we have MSR_DE
>>>> enabled in the first place when we can't handle it?
>>> 
>>> When QEMU is using hardware debug resource then we always set MSR_DE during
>> guest is running.
>> 
>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE wasn't set, you
>> wouldn't get a single step exit.
> 
> We always set MSR_DE in hw MSR when qemu using the debug resource.

In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be set anymore, because we're in an interrupt handler, no? Or is MSR_DE kept alive on interrupts?

> 
>> During the exit code path, you could then swap
>> DBSR back to what the host expects (which means no single step). Only after that
>> enable MSR_DE again.
> 
> We do not support deferred debug interrupt, so we do save restore dbsr.
> 
>> 
>>> 
>>>> 
>>>>> +1:	/* debug interrupt happened in guest */
>>>>> +	mtcr	r3
>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
>>>> 
>>>> I don't think you need the __KVM_HANDLER split. This should be quite
>>>> easily refactorable into a simple DBG prolog.
>>> 
>>> Can you please elaborate how you are envisioning this?
>> 
>> With this patch, you have
>> 
>> KVM_HANLDER:
>> 
>>  <code>
>>  __KVM_HANDLER
>> 
>> KVM_DBG_HANDLER:
>> 
>>  <code>
>>  __KVM_HANDLER
>> 
>> Right?
>> 
>> In KVM_HANDLER, you get:
>> 
>>> .macro KVM_HANDLER ivor_nr scratch srr0
>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>> 	/* Get pointer to vcpu and record exit number. */
>>> 	mtspr	\scratch , r4
>>> 	mfspr   r4, SPRN_SPRG_THREAD
>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>> 
>> 
>> while KVM_DBG_HANDLER is:
>> 
>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>> <debug specific handling>
>>> +1:	/* debug interrupt happened in guest */
>>> +	mtcr	r3
>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>> 
>> 
>> So if you write this as
>> 
>> KVM_DBG_HANDLER:
>> 	<debug specific handling>
>> 	1:
>> 	mtcr		r3
>> 	mfspr	r4, SPRN_SPRG_THREAD
>> 	lwz		r4, THREAD_KVM_VCPU(r4)
>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>> 	lwz		r4, \scratch
>> 	<KVM_HANDLER>
>> 
>> then you get code that is slower :) but it should be easier to read, since the
>> interface between the individual pieces is always the same. Debug shouldn't be a
>> fast path anyway, right?
> 
> Frankly speaking I do not see much difference :).
> 
> If we have to do as you mentioned then I think we can just do
> 
> KVM_DBG_HANDLER:
> 	<debug specific handling>
> 	1:
> 	mtcr		r3
> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> 	lwz		r4, \scratch
> 	<KVM_HANDLER>

Whatever it takes to keep the oddball (debug) an oddball and keep the normal case easy :).


Alex

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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-31 17:08           ` Alexander Graf
@ 2013-01-31 17:11             ` Alexander Graf
  2013-02-01  5:04             ` Bhushan Bharat-R65777
  1 sibling, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 17:11 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 18:08, Alexander Graf wrote:

> 
> On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:
> 
>> 
>> 
>>> -----Original Message-----
>>> From: Alexander Graf [mailto:agraf@suse.de]
>>> Sent: Thursday, January 31, 2013 5:47 PM
>>> To: Bhushan Bharat-R65777
>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>> 
>>> 
>>> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
>>> 
>>>> 
>>>> 
>>>>> -----Original Message-----
>>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>>> Sent: Friday, January 25, 2013 5:13 PM
>>>>> To: Bhushan Bharat-R65777
>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>>> Bharat-R65777
>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>>> 
>>>>> 
>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>>> 
>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>>>>> 
>>>>>> Installed debug handler will be used for guest debug support and
>>>>>> debug facility emulation features (patches for these features will
>>>>>> follow this patch).
>>>>>> 
>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>>> ---
>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++---
>>> --
>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>>>>> 
>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>>> index 8a72d59..f4ba881 100644
>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>>>>> 	u32 tlbcfg[4];
>>>>>> 	u32 mmucfg;
>>>>>> 	u32 epr;
>>>>>> +	u32 crit_save;
>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>>>>> 	gpa_t paddr_accessed;
>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>>>>> b/arch/powerpc/kernel/asm-offsets.c
>>>>>> index 46f6afd..02048f3 100644
>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>>>>> @@ -562,6 +562,7 @@ int main(void)
>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
>>>>>> #endif /* CONFIG_PPC_BOOK3S */
>>>>>> #endif /* CONFIG_KVM */
>>>>>> 
>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> index eae8483..dd9c5d4 100644
>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>> @@ -52,12 +52,7 @@
>>>>>>                     (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>>>>                     (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>>>>> 
>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> -	/* Get pointer to vcpu and record exit number. */
>>>>>> -	mtspr	\scratch , r4
>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> 	bctr
>>>>>> .endm
>>>>>> 
>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> +	/* Get pointer to vcpu and record exit number. */
>>>>>> +	mtspr	\scratch , r4
>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>> +
>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>> +	mtspr   \scratch, r4
>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>>>>> +	mfcr	r3
>>>>>> +	mfspr	r4, SPRN_CSRR1
>>>>>> +	andi.	r4, r4, MSR_PR
>>>>>> +	bne	1f
>>>>> 
>>>>> 
>>>>>> +	/* debug interrupt happened in enter/exit path */
>>>>>> +	mfspr   r4, SPRN_CSRR1
>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>>>>> +	mtspr   SPRN_CSRR1, r4
>>>>>> +	lis	r4, 0xffff
>>>>>> +	ori	r4, r4, 0xffff
>>>>>> +	mtspr	SPRN_DBSR, r4
>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>> +	mtcr	r3
>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>> +	mfspr   r4, \scratch
>>>>>> +	rfci
>>>>> 
>>>>> What is this part doing? Try to ignore the debug exit?
>>>> 
>>>> As BOOKE doesn't have hardware support for virtualization, hardware never know
>>> current pc is in guest or in host.
>>>> So when enable hardware single step for guest, it cannot be disabled at the
>>> time guest exit. Thus, we'll see that an single step interrupt happens at the
>>> beginning of guest exit path.
>>>> 
>>>> With the above code we recognize this kind of single step interrupt disable
>>> single step and rfci.
>>>> 
>>>>> Why would we have MSR_DE
>>>>> enabled in the first place when we can't handle it?
>>>> 
>>>> When QEMU is using hardware debug resource then we always set MSR_DE during
>>> guest is running.
>>> 
>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE wasn't set, you
>>> wouldn't get a single step exit.
>> 
>> We always set MSR_DE in hw MSR when qemu using the debug resource.
> 
> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be set anymore, because we're in an interrupt handler, no? Or is MSR_DE kept alive on interrupts?

Ah, it's kept for non-debug interrupts. That explains things.


Alex

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

* RE: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-25 11:48   ` Alexander Graf
@ 2013-01-31 17:44     ` Bhushan Bharat-R65777
  2013-01-31 17:52       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 17:44 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, January 25, 2013 5:18 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
> 
> 
> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> 
> > This patch adds the one_reg interface to get the special instruction
> > to be used for setting software breakpoint from userspace.
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > Documentation/virtual/kvm/api.txt   |    1 +
> > arch/powerpc/include/asm/kvm_ppc.h  |    1 +
> > arch/powerpc/include/uapi/asm/kvm.h |    3 +++
> > arch/powerpc/kvm/44x.c              |    5 +++++
> > arch/powerpc/kvm/booke.c            |   10 ++++++++++
> > arch/powerpc/kvm/e500.c             |    5 +++++
> > arch/powerpc/kvm/e500.h             |    9 +++++++++
> > arch/powerpc/kvm/e500mc.c           |    5 +++++
> > 8 files changed, 39 insertions(+), 0 deletions(-)
> >
> > diff --git a/Documentation/virtual/kvm/api.txt
> > b/Documentation/virtual/kvm/api.txt
> > index 09905cb..7e8be9e 100644
> > --- a/Documentation/virtual/kvm/api.txt
> > +++ b/Documentation/virtual/kvm/api.txt
> > @@ -1775,6 +1775,7 @@ registers, find a list below:
> >   PPC   | KVM_REG_PPC_VPA_DTL   | 128
> >   PPC   | KVM_REG_PPC_EPCR	| 32
> >   PPC   | KVM_REG_PPC_EPR	| 32
> > +  PPC   | KVM_REG_PPC_DEBUG_INST| 32
> >
> > 4.69 KVM_GET_ONE_REG
> >
> > diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> > b/arch/powerpc/include/asm/kvm_ppc.h
> > index 44a657a..b3c481e 100644
> > --- a/arch/powerpc/include/asm/kvm_ppc.h
> > +++ b/arch/powerpc/include/asm/kvm_ppc.h
> > @@ -235,6 +235,7 @@ union kvmppc_one_reg {
> >
> > void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> > *sregs); int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct
> > kvm_sregs *sregs);
> > +u32 kvmppc_core_debug_inst_op(void);
> >
> > void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs
> > *sregs); int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct
> > kvm_sregs *sregs); diff --git a/arch/powerpc/include/uapi/asm/kvm.h
> > b/arch/powerpc/include/uapi/asm/kvm.h
> > index 16064d0..e81ae5b 100644
> > --- a/arch/powerpc/include/uapi/asm/kvm.h
> > +++ b/arch/powerpc/include/uapi/asm/kvm.h
> > @@ -417,4 +417,7 @@ struct kvm_get_htab_header {
> > #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
> > #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
> >
> > +/* Debugging: Special instruction for software breakpoint */ #define
> > +KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
> > +
> > #endif /* __LINUX_KVM_POWERPC_H */
> > diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index
> > 3d7fd21..41501be 100644
> > --- a/arch/powerpc/kvm/44x.c
> > +++ b/arch/powerpc/kvm/44x.c
> > @@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
> > 	return 0;
> > }
> >
> > +u32 kvmppc_core_debug_inst_op(void)
> > +{
> > +	return -1;
> > +}
> > +
> > void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> > *sregs) {
> > 	kvmppc_get_sregs_ivor(vcpu, sregs);
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > d2f502d..453a10f 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> 
> Please provide the DEBUG_INST on a more global level - across all ppc subarchs.

Do you mean defining in powerpc.c ?

We are using one_reg for DEBUG_INST and one_reg_ioctl and defined in respective subarchs (booke and books have their separate handler). So how you want this to be defined in more common way for all subarchs?

Thanks
-Bharat

> 
> > @@ -1424,6 +1424,12 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
> struct kvm_one_reg *reg)
> > 		r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
> > 		break;
> > #endif
> > +	case KVM_REG_PPC_DEBUG_INST: {
> > +		u32 opcode = kvmppc_core_debug_inst_op();
> > +		r = copy_to_user((u32 __user *)(long)reg->addr,
> > +				 &opcode, sizeof(u32));
> > +		break;
> > +	}
> > 	default:
> > 		break;
> > 	}
> > @@ -1467,6 +1473,10 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
> struct kvm_one_reg *reg)
> > 		break;
> > 	}
> > #endif
> > +	case KVM_REG_PPC_DEBUG_INST:
> > +		/* This is read only, so write to this is nop*/
> > +		r = 0;
> > +		break;
> 
> Just don't support set_one_reg on this reg.
> 
> > 	default:
> > 		break;
> > 	}
> > diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index
> > 6dd4de7..d8a5e8e 100644
> > --- a/arch/powerpc/kvm/e500.c
> > +++ b/arch/powerpc/kvm/e500.c
> > @@ -367,6 +367,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> > 	return 0;
> > }
> >
> > +u32 kvmppc_core_debug_inst_op(void)
> > +{
> > +	return KVMPPC_INST_GUEST_GDB;
> > +}
> > +
> > void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> > *sregs) {
> > 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); diff --git
> > a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index
> > c70d37e..17942d2 100644
> > --- a/arch/powerpc/kvm/e500.h
> > +++ b/arch/powerpc/kvm/e500.h
> > @@ -302,4 +302,13 @@ static inline unsigned int get_tlbmiss_tid(struct
> kvm_vcpu *vcpu)
> > #define get_tlb_sts(gtlbe)              (MAS1_TS)
> > #endif /* !BOOKE_HV */
> >
> > +/* When setting software breakpoint, Change the software breakpoint
> > + * instruction to special trap/invalid instruction and set
> > + * KVM_GUESTDBG_USE_SW_BP flag in kvm_guest_debug->control. KVM does
> > + * keep track of software breakpoints. So when KVM_GUESTDBG_USE_SW_BP
> > + * flag is set and special trap instruction is executed by guest then
> > + * exit to userspace.
> 
> This comment chunk no apply to define. Also please fix English ;).
> 
> 
> Alex
> 
> > + */
> > +#define KVMPPC_INST_GUEST_GDB		0x7C00021C	/* ehpriv OC=0 */
> > +
> > #endif /* KVM_E500_H */
> > diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> > index 1f89d26..dead142 100644
> > --- a/arch/powerpc/kvm/e500mc.c
> > +++ b/arch/powerpc/kvm/e500mc.c
> > @@ -199,6 +199,11 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> > 	return 0;
> > }
> >
> > +u32 kvmppc_core_debug_inst_op(void)
> > +{
> > +	return KVMPPC_INST_GUEST_GDB;
> > +}
> > +
> > void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> > *sregs) {
> > 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> > --
> > 1.7.0.4
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> > the body of a message to majordomo@vger.kernel.org More majordomo info
> > at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-31 17:44     ` Bhushan Bharat-R65777
@ 2013-01-31 17:52       ` Alexander Graf
  2013-01-31 17:58         ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 17:52 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 18:44, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, January 25, 2013 5:18 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
>> 
>> 
>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>> 
>>> This patch adds the one_reg interface to get the special instruction
>>> to be used for setting software breakpoint from userspace.
>>> 
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> Documentation/virtual/kvm/api.txt   |    1 +
>>> arch/powerpc/include/asm/kvm_ppc.h  |    1 +
>>> arch/powerpc/include/uapi/asm/kvm.h |    3 +++
>>> arch/powerpc/kvm/44x.c              |    5 +++++
>>> arch/powerpc/kvm/booke.c            |   10 ++++++++++
>>> arch/powerpc/kvm/e500.c             |    5 +++++
>>> arch/powerpc/kvm/e500.h             |    9 +++++++++
>>> arch/powerpc/kvm/e500mc.c           |    5 +++++
>>> 8 files changed, 39 insertions(+), 0 deletions(-)
>>> 
>>> diff --git a/Documentation/virtual/kvm/api.txt
>>> b/Documentation/virtual/kvm/api.txt
>>> index 09905cb..7e8be9e 100644
>>> --- a/Documentation/virtual/kvm/api.txt
>>> +++ b/Documentation/virtual/kvm/api.txt
>>> @@ -1775,6 +1775,7 @@ registers, find a list below:
>>>  PPC   | KVM_REG_PPC_VPA_DTL   | 128
>>>  PPC   | KVM_REG_PPC_EPCR	| 32
>>>  PPC   | KVM_REG_PPC_EPR	| 32
>>> +  PPC   | KVM_REG_PPC_DEBUG_INST| 32
>>> 
>>> 4.69 KVM_GET_ONE_REG
>>> 
>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>>> b/arch/powerpc/include/asm/kvm_ppc.h
>>> index 44a657a..b3c481e 100644
>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>> @@ -235,6 +235,7 @@ union kvmppc_one_reg {
>>> 
>>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
>>> *sregs); int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct
>>> kvm_sregs *sregs);
>>> +u32 kvmppc_core_debug_inst_op(void);
>>> 
>>> void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs
>>> *sregs); int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct
>>> kvm_sregs *sregs); diff --git a/arch/powerpc/include/uapi/asm/kvm.h
>>> b/arch/powerpc/include/uapi/asm/kvm.h
>>> index 16064d0..e81ae5b 100644
>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>> @@ -417,4 +417,7 @@ struct kvm_get_htab_header {
>>> #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
>>> #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
>>> 
>>> +/* Debugging: Special instruction for software breakpoint */ #define
>>> +KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x87)
>>> +
>>> #endif /* __LINUX_KVM_POWERPC_H */
>>> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index
>>> 3d7fd21..41501be 100644
>>> --- a/arch/powerpc/kvm/44x.c
>>> +++ b/arch/powerpc/kvm/44x.c
>>> @@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
>>> 	return 0;
>>> }
>>> 
>>> +u32 kvmppc_core_debug_inst_op(void)
>>> +{
>>> +	return -1;

The way you handle it here this needs to be an  int kvmppc_core_debug_inst_op(u32 *inst) so you can return an error for 440. I don't think it's worth to worry about a case where we don't know about the inst though. Just return the same as what we use on e500v2 here.

>>> +}
>>> +
>>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
>>> *sregs) {
>>> 	kvmppc_get_sregs_ivor(vcpu, sregs);
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>> d2f502d..453a10f 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>> 
>> Please provide the DEBUG_INST on a more global level - across all ppc subarchs.
> 
> Do you mean defining in powerpc.c ?
> 
> We are using one_reg for DEBUG_INST and one_reg_ioctl and defined in respective subarchs (booke and books have their separate handler). So how you want this to be defined in more common way for all subarchs?

Just add it to all subarch's one_reg handlers.


Alex

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

* RE: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-31 17:52       ` Alexander Graf
@ 2013-01-31 17:58         ` Bhushan Bharat-R65777
  2013-01-31 18:22           ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 17:58 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Thursday, January 31, 2013 11:23 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
> 
> 
> On 31.01.2013, at 18:44, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Alexander Graf [mailto:agraf@suse.de]
> >> Sent: Friday, January 25, 2013 5:18 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >> Bharat-R65777
> >> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug
> >> instruction
> >>
> >>
> >> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>
> >>> This patch adds the one_reg interface to get the special instruction
> >>> to be used for setting software breakpoint from userspace.
> >>>
> >>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>> ---
> >>> Documentation/virtual/kvm/api.txt   |    1 +
> >>> arch/powerpc/include/asm/kvm_ppc.h  |    1 +
> >>> arch/powerpc/include/uapi/asm/kvm.h |    3 +++
> >>> arch/powerpc/kvm/44x.c              |    5 +++++
> >>> arch/powerpc/kvm/booke.c            |   10 ++++++++++
> >>> arch/powerpc/kvm/e500.c             |    5 +++++
> >>> arch/powerpc/kvm/e500.h             |    9 +++++++++
> >>> arch/powerpc/kvm/e500mc.c           |    5 +++++
> >>> 8 files changed, 39 insertions(+), 0 deletions(-)
> >>>
> >>> diff --git a/Documentation/virtual/kvm/api.txt
> >>> b/Documentation/virtual/kvm/api.txt
> >>> index 09905cb..7e8be9e 100644
> >>> --- a/Documentation/virtual/kvm/api.txt
> >>> +++ b/Documentation/virtual/kvm/api.txt
> >>> @@ -1775,6 +1775,7 @@ registers, find a list below:
> >>>  PPC   | KVM_REG_PPC_VPA_DTL   | 128
> >>>  PPC   | KVM_REG_PPC_EPCR	| 32
> >>>  PPC   | KVM_REG_PPC_EPR	| 32
> >>> +  PPC   | KVM_REG_PPC_DEBUG_INST| 32
> >>>
> >>> 4.69 KVM_GET_ONE_REG
> >>>
> >>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> >>> b/arch/powerpc/include/asm/kvm_ppc.h
> >>> index 44a657a..b3c481e 100644
> >>> --- a/arch/powerpc/include/asm/kvm_ppc.h
> >>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> >>> @@ -235,6 +235,7 @@ union kvmppc_one_reg {
> >>>
> >>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> >>> *sregs); int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct
> >>> kvm_sregs *sregs);
> >>> +u32 kvmppc_core_debug_inst_op(void);
> >>>
> >>> void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs
> >>> *sregs); int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct
> >>> kvm_sregs *sregs); diff --git a/arch/powerpc/include/uapi/asm/kvm.h
> >>> b/arch/powerpc/include/uapi/asm/kvm.h
> >>> index 16064d0..e81ae5b 100644
> >>> --- a/arch/powerpc/include/uapi/asm/kvm.h
> >>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> >>> @@ -417,4 +417,7 @@ struct kvm_get_htab_header {
> >>> #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
> >>> #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
> >>>
> >>> +/* Debugging: Special instruction for software breakpoint */
> >>> +#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 |
> >>> +0x87)
> >>> +
> >>> #endif /* __LINUX_KVM_POWERPC_H */
> >>> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index
> >>> 3d7fd21..41501be 100644
> >>> --- a/arch/powerpc/kvm/44x.c
> >>> +++ b/arch/powerpc/kvm/44x.c
> >>> @@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
> >>> 	return 0;
> >>> }
> >>>
> >>> +u32 kvmppc_core_debug_inst_op(void) {
> >>> +	return -1;
> 
> The way you handle it here this needs to be an  int
> kvmppc_core_debug_inst_op(u32 *inst) so you can return an error for 440. I don't
> think it's worth to worry about a case where we don't know about the inst
> though. Just return the same as what we use on e500v2 here.
> 
> >>> +}
> >>> +
> >>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
> >>> *sregs) {
> >>> 	kvmppc_get_sregs_ivor(vcpu, sregs); diff --git
> >>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> >>> d2f502d..453a10f 100644
> >>> --- a/arch/powerpc/kvm/booke.c
> >>> +++ b/arch/powerpc/kvm/booke.c
> >>
> >> Please provide the DEBUG_INST on a more global level - across all ppc
> subarchs.
> >
> > Do you mean defining in powerpc.c ?
> >
> > We are using one_reg for DEBUG_INST and one_reg_ioctl and defined in
> respective subarchs (booke and books have their separate handler). So how you
> want this to be defined in more common way for all subarchs?
> 
> Just add it to all subarch's one_reg handlers.

And what book3s etc should return?

-1 ? 

Thanks
-Bharat

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

* RE: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 12:04       ` Alexander Graf
@ 2013-01-31 17:59         ` Bhushan Bharat-R65777
  2013-01-31 18:21           ` Alexander Graf
  2013-01-31 18:03         ` Scott Wood
  1 sibling, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-01-31 17:59 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
> Alexander Graf
> Sent: Thursday, January 31, 2013 5:34 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
> 
> 
> On 30.01.2013, at 12:12, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-ppc-owner@vger.kernel.org
> >> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >> Sent: Friday, January 25, 2013 5:44 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >> Bharat-R65777
> >> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt
> >> injection to guest
> >>
> >>
> >> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>
> >>> Allow userspace to inject debug interrupt to guest. QEMU can
> >>
> >> s/QEMU/user space.
> >>
> >>> inject the debug interrupt to guest if it is not able to handle the
> >>> debug interrupt.
> >>>
> >>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>> ---
> >>> arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
> >>> arch/powerpc/kvm/e500mc.c |   10 +++++++++-
> >>> 2 files changed, 40 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >>> index faa0a0b..547797f 100644
> >>> --- a/arch/powerpc/kvm/booke.c
> >>> +++ b/arch/powerpc/kvm/booke.c
> >>> @@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct
> >>> kvm_vcpu
> >>> *vcpu) #endif }
> >>>
> >>> +#ifdef CONFIG_KVM_BOOKE_HV
> >>> +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu) {
> >>> +	return test_bit(BOOKE_IRQPRIO_DEBUG,
> >>> +&vcpu->arch.pending_exceptions); } #endif
> >>> +
> >>> /*
> >>> * Helper function for "full" MSR writes.  No need to call this if
> >>> only
> >>> * EE/CE/ME/DE/RI are changing.
> >>> @@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32
> >>> new_msr) #ifdef CONFIG_KVM_BOOKE_HV
> >>> 	new_msr |= MSR_GS;
> >>>
> >>> -	if (vcpu->guest_debug)
> >>> +	/*
> >>> +	 * Set MSR_DE if the hardware debug resources are owned by user-space
> >>> +	 * and there is no debug interrupt pending for guest to handle.
> >>
> >> Why?
> >
> > QEMU is using the IAC/DAC registers to set hardware breakpoint/watchpoints via
> debug ioctls. As debug events are enabled/gated by MSR_DE so somehow we need to
> set MSR_DE on hardware MSR when guest is running in this case.
> 
> Reading this 5 times I still have no idea what you're really checking for here.
> Maybe the naming for kvmppc_core_pending_debug is just unnatural? What does that
> function do really?
> 
> >
> > On bookehv this is how I am controlling the MSR_DE in hardware MSR.
> >
> >> And why is this whole thing only executed on HV?
> >
> > On e500v2 we always enable MSR_DE using vcpu->arch.shadow_msr in
> > e500.c #ifndef CONFIG_KVM_BOOKE_HV
> > -       vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
> > +       vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;


diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index b340a62..1e2d663 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -151,10 +151,14 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)

        /*
         * Set MSR_DE if the hardware debug resources are owned by user-space
-        * and there is no debug interrupt pending for guest to handle.
         */
-       if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu))
+       if (vcpu->guest_debug)
                new_msr |= MSR_DE;
+#else
+       if (vcpu->guest_debug)
+               vcpu->arch.shadow_msr |= MSR_DE;
#endif

But do not when I should clear?

> 
> Why? How is e500v2 any different wrt debug? And why wouldn't that work for
> e500mc?
> 
> 
> Alex
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a
> message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 12:04       ` Alexander Graf
  2013-01-31 17:59         ` Bhushan Bharat-R65777
@ 2013-01-31 18:03         ` Scott Wood
  1 sibling, 0 replies; 59+ messages in thread
From: Scott Wood @ 2013-01-31 18:03 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 01/31/2013 06:04:29 AM, Alexander Graf wrote:
> 
> On 30.01.2013, at 12:12, Bhushan Bharat-R65777 wrote:
> 
> > On bookehv this is how I am controlling the MSR_DE in hardware MSR.
> >
> >> And why is this whole thing only executed on HV?
> >
> > On e500v2 we always enable MSR_DE using vcpu->arch.shadow_msr in  
> e500.c
> > #ifndef CONFIG_KVM_BOOKE_HV
> > -       vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
> > +       vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
> 
> Why? How is e500v2 any different wrt debug? And why wouldn't that  
> work for e500mc?

shadow_msr isn't used at all on bookehv.

-Scott

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 17:59         ` Bhushan Bharat-R65777
@ 2013-01-31 18:21           ` Alexander Graf
  2013-01-31 18:43             ` Scott Wood
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 18:21 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 18:59, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Behalf Of
>> Alexander Graf
>> Sent: Thursday, January 31, 2013 5:34 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
>> 
>> 
>> On 30.01.2013, at 12:12, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: kvm-ppc-owner@vger.kernel.org
>>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
>>>> Sent: Friday, January 25, 2013 5:44 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt
>>>> injection to guest
>>>> 
>>>> 
>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>> 
>>>>> Allow userspace to inject debug interrupt to guest. QEMU can
>>>> 
>>>> s/QEMU/user space.
>>>> 
>>>>> inject the debug interrupt to guest if it is not able to handle the
>>>>> debug interrupt.
>>>>> 
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>> arch/powerpc/kvm/booke.c  |   32 +++++++++++++++++++++++++++++++-
>>>>> arch/powerpc/kvm/e500mc.c |   10 +++++++++-
>>>>> 2 files changed, 40 insertions(+), 2 deletions(-)
>>>>> 
>>>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>>>>> index faa0a0b..547797f 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>>> @@ -133,6 +133,13 @@ static void kvmppc_vcpu_sync_fpu(struct
>>>>> kvm_vcpu
>>>>> *vcpu) #endif }
>>>>> 
>>>>> +#ifdef CONFIG_KVM_BOOKE_HV
>>>>> +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu) {
>>>>> +	return test_bit(BOOKE_IRQPRIO_DEBUG,
>>>>> +&vcpu->arch.pending_exceptions); } #endif
>>>>> +
>>>>> /*
>>>>> * Helper function for "full" MSR writes.  No need to call this if
>>>>> only
>>>>> * EE/CE/ME/DE/RI are changing.
>>>>> @@ -144,7 +151,11 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32
>>>>> new_msr) #ifdef CONFIG_KVM_BOOKE_HV
>>>>> 	new_msr |= MSR_GS;
>>>>> 
>>>>> -	if (vcpu->guest_debug)
>>>>> +	/*
>>>>> +	 * Set MSR_DE if the hardware debug resources are owned by user-space
>>>>> +	 * and there is no debug interrupt pending for guest to handle.
>>>> 
>>>> Why?
>>> 
>>> QEMU is using the IAC/DAC registers to set hardware breakpoint/watchpoints via
>> debug ioctls. As debug events are enabled/gated by MSR_DE so somehow we need to
>> set MSR_DE on hardware MSR when guest is running in this case.
>> 
>> Reading this 5 times I still have no idea what you're really checking for here.
>> Maybe the naming for kvmppc_core_pending_debug is just unnatural? What does that
>> function do really?
>> 
>>> 
>>> On bookehv this is how I am controlling the MSR_DE in hardware MSR.
>>> 
>>>> And why is this whole thing only executed on HV?
>>> 
>>> On e500v2 we always enable MSR_DE using vcpu->arch.shadow_msr in
>>> e500.c #ifndef CONFIG_KVM_BOOKE_HV
>>> -       vcpu->arch.shadow_msr = MSR_USER | MSR_IS | MSR_DS;
>>> +       vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
> 
> 
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index b340a62..1e2d663 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -151,10 +151,14 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
> 
>        /*
>         * Set MSR_DE if the hardware debug resources are owned by user-space
> -        * and there is no debug interrupt pending for guest to handle.
>         */
> -       if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu))
> +       if (vcpu->guest_debug)
>                new_msr |= MSR_DE;
> +#else
> +       if (vcpu->guest_debug)
> +               vcpu->arch.shadow_msr |= MSR_DE;
> #endif
> 
> But do not when I should clear?

How about something like this? Then both targets at least suck as much :).

Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.

So I would assume it's for the best to just treat both the same: always expose MSR_DE into guest visibility.

This will break when the guest disables MSR_DE. But I have no good idea on how to solve this properly - except for hypercalls to tell us that MSR_DE is set or not.

Scott, do you have an idea?


Alex


diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 38a62ef..3f8cbbd 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -133,6 +133,19 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 #endif
 }
 
+static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
+{
+	/* Force debug to on in guest space when user space wants to debug */
+	if (vcpu->guest_debug)
+		vcpu->arch.shared->msr |= MSR_DE;
+
+#if !defined(CONFIG_KVM_BOOKE_HV)
+	/* Synchronize MSR_DE into shadow MSR */
+	vcpu->arch.shadow_msr &= ~MSR_DE;
+	vcpu->arch.shadow_msr |= 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 +163,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,

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-31 17:58         ` Bhushan Bharat-R65777
@ 2013-01-31 18:22           ` Alexander Graf
  0 siblings, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 18:22 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 31.01.2013, at 18:58, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Thursday, January 31, 2013 11:23 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
>> 
>> 
>> On 31.01.2013, at 18:44, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>> Sent: Friday, January 25, 2013 5:18 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>> Bharat-R65777
>>>> Subject: Re: [PATCH 4/8] Added ONE_REG interface for debug
>>>> instruction
>>>> 
>>>> 
>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>> 
>>>>> This patch adds the one_reg interface to get the special instruction
>>>>> to be used for setting software breakpoint from userspace.
>>>>> 
>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>> ---
>>>>> Documentation/virtual/kvm/api.txt   |    1 +
>>>>> arch/powerpc/include/asm/kvm_ppc.h  |    1 +
>>>>> arch/powerpc/include/uapi/asm/kvm.h |    3 +++
>>>>> arch/powerpc/kvm/44x.c              |    5 +++++
>>>>> arch/powerpc/kvm/booke.c            |   10 ++++++++++
>>>>> arch/powerpc/kvm/e500.c             |    5 +++++
>>>>> arch/powerpc/kvm/e500.h             |    9 +++++++++
>>>>> arch/powerpc/kvm/e500mc.c           |    5 +++++
>>>>> 8 files changed, 39 insertions(+), 0 deletions(-)
>>>>> 
>>>>> diff --git a/Documentation/virtual/kvm/api.txt
>>>>> b/Documentation/virtual/kvm/api.txt
>>>>> index 09905cb..7e8be9e 100644
>>>>> --- a/Documentation/virtual/kvm/api.txt
>>>>> +++ b/Documentation/virtual/kvm/api.txt
>>>>> @@ -1775,6 +1775,7 @@ registers, find a list below:
>>>>> PPC   | KVM_REG_PPC_VPA_DTL   | 128
>>>>> PPC   | KVM_REG_PPC_EPCR	| 32
>>>>> PPC   | KVM_REG_PPC_EPR	| 32
>>>>> +  PPC   | KVM_REG_PPC_DEBUG_INST| 32
>>>>> 
>>>>> 4.69 KVM_GET_ONE_REG
>>>>> 
>>>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>>>>> b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> index 44a657a..b3c481e 100644
>>>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>>>> @@ -235,6 +235,7 @@ union kvmppc_one_reg {
>>>>> 
>>>>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
>>>>> *sregs); int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct
>>>>> kvm_sregs *sregs);
>>>>> +u32 kvmppc_core_debug_inst_op(void);
>>>>> 
>>>>> void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs
>>>>> *sregs); int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct
>>>>> kvm_sregs *sregs); diff --git a/arch/powerpc/include/uapi/asm/kvm.h
>>>>> b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> index 16064d0..e81ae5b 100644
>>>>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>>>>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>>>>> @@ -417,4 +417,7 @@ struct kvm_get_htab_header {
>>>>> #define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
>>>>> #define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
>>>>> 
>>>>> +/* Debugging: Special instruction for software breakpoint */
>>>>> +#define KVM_REG_PPC_DEBUG_INST (KVM_REG_PPC | KVM_REG_SIZE_U32 |
>>>>> +0x87)
>>>>> +
>>>>> #endif /* __LINUX_KVM_POWERPC_H */
>>>>> diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index
>>>>> 3d7fd21..41501be 100644
>>>>> --- a/arch/powerpc/kvm/44x.c
>>>>> +++ b/arch/powerpc/kvm/44x.c
>>>>> @@ -114,6 +114,11 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
>>>>> 	return 0;
>>>>> }
>>>>> 
>>>>> +u32 kvmppc_core_debug_inst_op(void) {
>>>>> +	return -1;
>> 
>> The way you handle it here this needs to be an  int
>> kvmppc_core_debug_inst_op(u32 *inst) so you can return an error for 440. I don't
>> think it's worth to worry about a case where we don't know about the inst
>> though. Just return the same as what we use on e500v2 here.
>> 
>>>>> +}
>>>>> +
>>>>> void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs
>>>>> *sregs) {
>>>>> 	kvmppc_get_sregs_ivor(vcpu, sregs); diff --git
>>>>> a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>>>> d2f502d..453a10f 100644
>>>>> --- a/arch/powerpc/kvm/booke.c
>>>>> +++ b/arch/powerpc/kvm/booke.c
>>>> 
>>>> Please provide the DEBUG_INST on a more global level - across all ppc
>> subarchs.
>>> 
>>> Do you mean defining in powerpc.c ?
>>> 
>>> We are using one_reg for DEBUG_INST and one_reg_ioctl and defined in
>> respective subarchs (booke and books have their separate handler). So how you
>> want this to be defined in more common way for all subarchs?
>> 
>> Just add it to all subarch's one_reg handlers.
> 
> And what book3s etc should return?
> 
> -1 ? 

trap maybe?


Alex

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 18:21           ` Alexander Graf
@ 2013-01-31 18:43             ` Scott Wood
  2013-01-31 18:52               ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Scott Wood @ 2013-01-31 18:43 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> How about something like this? Then both targets at least suck as  
> much :).

I'm not sure that should be the goal...

> Thanks to e500mc's awful hardware design, we don't know who sets the  
> MSR_DE bit. Once we forced it onto the guest, we have no change to  
> know whether the guest also set it or not. We could only guess.

MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still  
need to set it in the first place.

According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let  
the guest know that the debug resources are not available, and that  
"the value of MSR[DE] is not specified and not modifiable".

-Scott

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 18:43             ` Scott Wood
@ 2013-01-31 18:52               ` Alexander Graf
  2013-01-31 18:54                 ` Scott Wood
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 18:52 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org


On 31.01.2013, at 19:43, Scott Wood wrote:

> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>> How about something like this? Then both targets at least suck as much :).
> 
> I'm not sure that should be the goal...
> 
>> Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.
> 
> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still need to set it in the first place.
> 
> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let the guest know that the debug resources are not available, and that "the value of MSR[DE] is not specified and not modifiable".

So what would the guest do then to tell the hypervisor that it actually wants to know about debug events?


Alex


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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 18:52               ` Alexander Graf
@ 2013-01-31 18:54                 ` Scott Wood
  2013-01-31 19:05                   ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Scott Wood @ 2013-01-31 18:54 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> 
> On 31.01.2013, at 19:43, Scott Wood wrote:
> 
> > On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> >> How about something like this? Then both targets at least suck as  
> much :).
> >
> > I'm not sure that should be the goal...
> >
> >> Thanks to e500mc's awful hardware design, we don't know who sets  
> the MSR_DE bit. Once we forced it onto the guest, we have no change  
> to know whether the guest also set it or not. We could only guess.
> >
> > MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we  
> still need to set it in the first place.
> >
> > According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to  
> let the guest know that the debug resources are not available, and  
> that "the value of MSR[DE] is not specified and not modifiable".
> 
> So what would the guest do then to tell the hypervisor that it  
> actually wants to know about debug events?

The guest is out of luck, just as if a JTAG were in use.

-Scott

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 18:54                 ` Scott Wood
@ 2013-01-31 19:05                   ` Alexander Graf
  2013-01-31 19:20                     ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 19:05 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org


On 31.01.2013, at 19:54, Scott Wood wrote:

> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>> On 31.01.2013, at 19:43, Scott Wood wrote:
>> > On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>> >> How about something like this? Then both targets at least suck as much :).
>> >
>> > I'm not sure that should be the goal...
>> >
>> >> Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.
>> >
>> > MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still need to set it in the first place.
>> >
>> > According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let the guest know that the debug resources are not available, and that "the value of MSR[DE] is not specified and not modifiable".
>> So what would the guest do then to tell the hypervisor that it actually wants to know about debug events?
> 
> The guest is out of luck, just as if a JTAG were in use.

Hrm.

Can we somehow generalize this "out of luck" behavior?

Every time we would set or clear an MSR bit in shadow_msr on e500v2, we would instead set or clear it in the real MSR. That way only e500mc is out of luck, but the code would still be shared.


Alex

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 19:05                   ` Alexander Graf
@ 2013-01-31 19:20                     ` Alexander Graf
  2013-01-31 22:40                       ` Scott Wood
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-01-31 19:20 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org


On 31.01.2013, at 20:05, Alexander Graf wrote:

> 
> On 31.01.2013, at 19:54, Scott Wood wrote:
> 
>> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>>> On 31.01.2013, at 19:43, Scott Wood wrote:
>>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>>>>> How about something like this? Then both targets at least suck as much :).
>>>> 
>>>> I'm not sure that should be the goal...
>>>> 
>>>>> Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.
>>>> 
>>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still need to set it in the first place.
>>>> 
>>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let the guest know that the debug resources are not available, and that "the value of MSR[DE] is not specified and not modifiable".
>>> So what would the guest do then to tell the hypervisor that it actually wants to know about debug events?
>> 
>> The guest is out of luck, just as if a JTAG were in use.
> 
> Hrm.
> 
> Can we somehow generalize this "out of luck" behavior?
> 
> Every time we would set or clear an MSR bit in shadow_msr on e500v2, we would instead set or clear it in the real MSR. That way only e500mc is out of luck, but the code would still be shared.


Something like this. We could also define a SHADOW_MSR(vcpu) macro to hide the glorious details, but I think this way it's easier to understand what's going on.


Alex

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 38a62ef..9bdb845 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)
+{
+	u32 is_debug = vcpu->arch.shared->msr & MSR_DE;
+
+	/* Force debug to on in guest space when user space wants to debug */
+	if (vcpu->guest_debug)
+		is_debug = MSR_DE;
+
+#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;
+	vcpu->arch.shared->msr |= is_debug;
+#endif
+
+#ifndef CONFIG_KVM_BOOKE_HV
+	vcpu->arch.shadow_msr &= ~MSR_DE;
+	vcpu->arch.shadow_msr |= is_debug;
+#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,

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 19:20                     ` Alexander Graf
@ 2013-01-31 22:40                       ` Scott Wood
  2013-02-01  0:11                         ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Scott Wood @ 2013-01-31 22:40 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
> 
> On 31.01.2013, at 20:05, Alexander Graf wrote:
> 
> >
> > On 31.01.2013, at 19:54, Scott Wood wrote:
> >
> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> >>>>> How about something like this? Then both targets at least suck  
> as much :).
> >>>>
> >>>> I'm not sure that should be the goal...
> >>>>
> >>>>> Thanks to e500mc's awful hardware design, we don't know who  
> sets the MSR_DE bit. Once we forced it onto the guest, we have no  
> change to know whether the guest also set it or not. We could only  
> guess.
> >>>>
> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we  
> still need to set it in the first place.
> >>>>
> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to  
> let the guest know that the debug resources are not available, and  
> that "the value of MSR[DE] is not specified and not modifiable".
> >>> So what would the guest do then to tell the hypervisor that it  
> actually wants to know about debug events?
> >>
> >> The guest is out of luck, just as if a JTAG were in use.
> >
> > Hrm.
> >
> > Can we somehow generalize this "out of luck" behavior?
> >
> > Every time we would set or clear an MSR bit in shadow_msr on  
> e500v2, we would instead set or clear it in the real MSR. That way  
> only e500mc is out of luck, but the code would still be shared.

I don't follow.  e500v2 is just as out-of-luck.  The mechanism simply  
does not support sharing debug resources.

What do you mean by "the real MSR"?  The real MSR is shadow_msr, and  
MSR_DE must always be set there if the host is debugging the guest.  As  
for reflecting it into the guest MSR, we could, but I don't really see  
the point.  We're never going to actually send a debug exception to the  
guest when the host owns the debug resources.

Speaking of naming issues, "guest_debug" is very ambiguous...

> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 38a62ef..9bdb845 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)
> +{
> +	u32 is_debug = vcpu->arch.shared->msr & MSR_DE;
> +
> +	/* Force debug to on in guest space when user space wants to  
> debug */
> +	if (vcpu->guest_debug)
> +		is_debug = MSR_DE;
> +
> +#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;
> +	vcpu->arch.shared->msr |= is_debug;
> +#endif
> +
> +#ifndef CONFIG_KVM_BOOKE_HV
> +	vcpu->arch.shadow_msr &= ~MSR_DE;
> +	vcpu->arch.shadow_msr |= is_debug;
> +#endif
> +}

The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder to  
read.  I had to stare at it a while before noticing that you initially  
set is_debug from the guest MSR and that you'd never really clear  
MSR_DE here on bookehv.

-Scott

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-01-31 22:40                       ` Scott Wood
@ 2013-02-01  0:11                         ` Alexander Graf
  2013-02-01 22:38                           ` Scott Wood
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-02-01  0:11 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org


On 31.01.2013, at 23:40, Scott Wood wrote:

> On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
>> On 31.01.2013, at 20:05, Alexander Graf wrote:
>> >
>> > On 31.01.2013, at 19:54, Scott Wood wrote:
>> >
>> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
>> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>> >>>>> How about something like this? Then both targets at least suck as much :).
>> >>>>
>> >>>> I'm not sure that should be the goal...
>> >>>>
>> >>>>> Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.
>> >>>>
>> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still need to set it in the first place.
>> >>>>
>> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let the guest know that the debug resources are not available, and that "the value of MSR[DE] is not specified and not modifiable".
>> >>> So what would the guest do then to tell the hypervisor that it actually wants to know about debug events?
>> >>
>> >> The guest is out of luck, just as if a JTAG were in use.
>> >
>> > Hrm.
>> >
>> > Can we somehow generalize this "out of luck" behavior?
>> >
>> > Every time we would set or clear an MSR bit in shadow_msr on e500v2, we would instead set or clear it in the real MSR. That way only e500mc is out of luck, but the code would still be shared.
> 
> I don't follow.  e500v2 is just as out-of-luck.  The mechanism simply does not support sharing debug resources.

For e500v2 we have 2 fields

  * MSR as the guest sees it
  * MSR as we execute when the guest runs

Since we know the MSR when the guest sees it, we can decide what to do when we get an unhandled debug interrupt. We can simulate what hardware would do depending on the guest's MSR_DE setting.

For e500mc we only have

  * MSR as the guest sees it and as we execute when the guest runs

Because there is only one field, as soon as we OR MSR_DE into there, we can no longer distinguish whether the guest wanted to have MSR_DE enabled or not.

> What do you mean by "the real MSR"?  The real MSR is shadow_msr, and MSR_DE must always be set there if the host is debugging the guest.  As for reflecting it into the guest MSR, we could, but I don't really see the point.  We're never going to actually send a debug exception to the guest when the host owns the debug resources.

Why not? That's the whole point of jumping through user space.

  1) guest exits with debug interrupt
  2) QEMU gets a debug exit
  3) QEMU checks in its list whether it belongs to its own debug points
  4) if not, it reinjects the interrupt into the guest

Step 4 is pretty difficult to do when we don't know whether the guest is actually capable of handling debug interrupts at that moment.

> Speaking of naming issues, "guest_debug" is very ambiguous...

I agree.

> 
>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>> index 38a62ef..9bdb845 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)
>> +{
>> +	u32 is_debug = vcpu->arch.shared->msr & MSR_DE;
>> +
>> +	/* Force debug to on in guest space when user space wants to debug */
>> +	if (vcpu->guest_debug)
>> +		is_debug = MSR_DE;
>> +
>> +#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;
>> +	vcpu->arch.shared->msr |= is_debug;
>> +#endif
>> +
>> +#ifndef CONFIG_KVM_BOOKE_HV
>> +	vcpu->arch.shadow_msr &= ~MSR_DE;
>> +	vcpu->arch.shadow_msr |= is_debug;
>> +#endif
>> +}
> 
> The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder to read.  I had to stare at it a while before noticing that you initially set is_debug from the guest MSR and that you'd never really clear MSR_DE here on bookehv.

Well, I'm mostly bouncing ideas here to find a way to express what we're trying to say in a way that someone who hasn't read this email thread would still understand what's going on :).

How about this version?


diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 38a62ef..9929c41 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
 #endif
 }
 
+static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
+{
+#ifndef CONFIG_KVM_BOOKE_HV
+	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
+	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;
+#endif
+	}
+}
+
 /*
  * Helper function for "full" MSR writes.  No need to call this if only
  * EE/CE/ME/DE/RI are changing.
@@ -150,6 +172,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,


My main concern here is that we don't know when to remove MSR_DE again from the (shadow) MSR. So how about this one instead?


diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 38a62ef..2676703 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
 	u32 old_msr = vcpu->arch.shared->msr;
 
 #ifdef CONFIG_KVM_BOOKE_HV
-	new_msr |= MSR_GS;
+	new_msr |= MSR_GS | MSR_DE;
 #endif
 
 	vcpu->arch.shared->msr = new_msr;


That would semantically move e500mc to the same logic as e500v2. With the main difference that we have no idea what MSR_DE value the guest really wanted to have set.

If I read the spec correctly, rfci traps. So we know the time frame from [inject debug interrupt ... rfci]. During that time we know for sure that the guest thinks MSR_DE is 0. Outside of that context, we just have to assume the guest can always receive debug interrupts if it configured them.

So I think setting it always is even the better idea.


Alex

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

* RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-01-31 17:08           ` Alexander Graf
  2013-01-31 17:11             ` Alexander Graf
@ 2013-02-01  5:04             ` Bhushan Bharat-R65777
  2013-02-01  8:06               ` Alexander Graf
  1 sibling, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-01  5:04 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Thursday, January 31, 2013 10:38 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> 
> 
> On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: Alexander Graf [mailto:agraf@suse.de]
> >> Sent: Thursday, January 31, 2013 5:47 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>
> >>
> >> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Alexander Graf [mailto:agraf@suse.de]
> >>>> Sent: Friday, January 25, 2013 5:13 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >>>> Bharat-R65777
> >>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>>>
> >>>>
> >>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>>>
> >>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> >>>>>
> >>>>> Installed debug handler will be used for guest debug support and
> >>>>> debug facility emulation features (patches for these features will
> >>>>> follow this patch).
> >>>>>
> >>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>>>> [bharat.bhushan@freescale.com: Substantial changes]
> >>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>>>> ---
> >>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
> >>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
> >>>>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-
> --
> >> --
> >>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
> >>>>>
> >>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
> >>>>> b/arch/powerpc/include/asm/kvm_host.h
> >>>>> index 8a72d59..f4ba881 100644
> >>>>> --- a/arch/powerpc/include/asm/kvm_host.h
> >>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
> >>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> >>>>> 	u32 tlbcfg[4];
> >>>>> 	u32 mmucfg;
> >>>>> 	u32 epr;
> >>>>> +	u32 crit_save;
> >>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> >>>>> 	gpa_t paddr_accessed;
> >>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
> >>>>> b/arch/powerpc/kernel/asm-offsets.c
> >>>>> index 46f6afd..02048f3 100644
> >>>>> --- a/arch/powerpc/kernel/asm-offsets.c
> >>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
> >>>>> @@ -562,6 +562,7 @@ int main(void)
> >>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> >>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> >>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
> >>>>> arch.fault_esr));
> >>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
> >>>>> +arch.crit_save));
> >>>>> #endif /* CONFIG_PPC_BOOK3S */
> >>>>> #endif /* CONFIG_KVM */
> >>>>>
> >>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> index eae8483..dd9c5d4 100644
> >>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>> @@ -52,12 +52,7 @@
> >>>>>                      (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >>>>>                      (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >>>>>
> >>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> -	/* Get pointer to vcpu and record exit number. */
> >>>>> -	mtspr	\scratch , r4
> >>>>> -	mfspr   r4, SPRN_SPRG_THREAD
> >>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
> >>>>> 	stw	r3, VCPU_GPR(R3)(r4)
> >>>>> 	stw	r5, VCPU_GPR(R5)(r4)
> >>>>> 	stw	r6, VCPU_GPR(R6)(r4)
> >>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> 	bctr
> >>>>> .endm
> >>>>>
> >>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> +	/* Get pointer to vcpu and record exit number. */
> >>>>> +	mtspr	\scratch , r4
> >>>>> +	mfspr   r4, SPRN_SPRG_THREAD
> >>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>> +
> >>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> +	mtspr   \scratch, r4
> >>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
> >>>>> +	mfcr	r3
> >>>>> +	mfspr	r4, SPRN_CSRR1
> >>>>> +	andi.	r4, r4, MSR_PR
> >>>>> +	bne	1f
> >>>>
> >>>>
> >>>>> +	/* debug interrupt happened in enter/exit path */
> >>>>> +	mfspr   r4, SPRN_CSRR1
> >>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
> >>>>> +	mtspr   SPRN_CSRR1, r4
> >>>>> +	lis	r4, 0xffff
> >>>>> +	ori	r4, r4, 0xffff
> >>>>> +	mtspr	SPRN_DBSR, r4
> >>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>> +	mtcr	r3
> >>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>> +	mfspr   r4, \scratch
> >>>>> +	rfci
> >>>>
> >>>> What is this part doing? Try to ignore the debug exit?
> >>>
> >>> As BOOKE doesn't have hardware support for virtualization, hardware
> >>> never know
> >> current pc is in guest or in host.
> >>> So when enable hardware single step for guest, it cannot be disabled
> >>> at the
> >> time guest exit. Thus, we'll see that an single step interrupt
> >> happens at the beginning of guest exit path.
> >>>
> >>> With the above code we recognize this kind of single step interrupt
> >>> disable
> >> single step and rfci.
> >>>
> >>>> Why would we have MSR_DE
> >>>> enabled in the first place when we can't handle it?
> >>>
> >>> When QEMU is using hardware debug resource then we always set MSR_DE
> >>> during
> >> guest is running.
> >>
> >> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
> >> wasn't set, you wouldn't get a single step exit.
> >
> > We always set MSR_DE in hw MSR when qemu using the debug resource.
> 
> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be set
> anymore, because we're in an interrupt handler, no? Or is MSR_DE kept alive on
> interrupts?
> 
> >
> >> During the exit code path, you could then swap DBSR back to what the
> >> host expects (which means no single step). Only after that enable
> >> MSR_DE again.
> >
> > We do not support deferred debug interrupt, so we do save restore dbsr.
> >
> >>
> >>>
> >>>>
> >>>>> +1:	/* debug interrupt happened in guest */
> >>>>> +	mtcr	r3
> >>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> >>>>
> >>>> I don't think you need the __KVM_HANDLER split. This should be
> >>>> quite easily refactorable into a simple DBG prolog.
> >>>
> >>> Can you please elaborate how you are envisioning this?
> >>
> >> With this patch, you have
> >>
> >> KVM_HANLDER:
> >>
> >>  <code>
> >>  __KVM_HANDLER
> >>
> >> KVM_DBG_HANDLER:
> >>
> >>  <code>
> >>  __KVM_HANDLER
> >>
> >> Right?
> >>
> >> In KVM_HANDLER, you get:
> >>
> >>> .macro KVM_HANDLER ivor_nr scratch srr0
> >>> _GLOBAL(kvmppc_handler_\ivor_nr)
> >>> 	/* Get pointer to vcpu and record exit number. */
> >>> 	mtspr	\scratch , r4
> >>> 	mfspr   r4, SPRN_SPRG_THREAD
> >>> 	lwz     r4, THREAD_KVM_VCPU(r4)
> >>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>
> >>
> >> while KVM_DBG_HANDLER is:
> >>
> >>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>> <debug specific handling>
> >>> +1:	/* debug interrupt happened in guest */
> >>> +	mtcr	r3
> >>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>
> >>
> >> So if you write this as
> >>
> >> KVM_DBG_HANDLER:
> >> 	<debug specific handling>
> >> 	1:
> >> 	mtcr		r3
> >> 	mfspr	r4, SPRN_SPRG_THREAD
> >> 	lwz		r4, THREAD_KVM_VCPU(r4)
> >> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >> 	lwz		r4, \scratch
> >> 	<KVM_HANDLER>
> >>
> >> then you get code that is slower :) but it should be easier to read,
> >> since the interface between the individual pieces is always the same.
> >> Debug shouldn't be a fast path anyway, right?
> >
> > Frankly speaking I do not see much difference :).
> >
> > If we have to do as you mentioned then I think we can just do
> >
> > KVM_DBG_HANDLER:
> > 	<debug specific handling>
> > 	1:
> > 	mtcr		r3
> > 	lwz		r3, VCPU_CRIT_SAVE(r4)
> > 	lwz		r4, \scratch
> > 	<KVM_HANDLER>
> 
> Whatever it takes to keep the oddball (debug) an oddball and keep the normal
> case easy :).

I think there will be another problem as  the kvmppc_handler_\ivor_nr will not be the starting address which is required as per our ivor/ivpr usages for booke architecture.

I am thinking of keeping as is :).

Thanks
-Bharat

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

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

* RE: [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
  2013-01-25 12:07   ` Alexander Graf
@ 2013-02-01  6:31     ` Bhushan Bharat-R65777
  2013-02-01  8:21       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-01  6:31 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, January 25, 2013 5:37 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
> Subject: Re: [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
> 
> 
> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> 
> > 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.
> >
> > Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> > ---
> > arch/powerpc/include/asm/kvm_host.h   |    5 +
> > arch/powerpc/include/asm/kvm_ppc.h    |    2 +
> > arch/powerpc/include/uapi/asm/kvm.h   |   22 ++++-
> > arch/powerpc/kernel/asm-offsets.c     |   26 ++++++
> > arch/powerpc/kvm/booke.c              |  124 +++++++++++++++++++++++++----
> > arch/powerpc/kvm/booke_interrupts.S   |  114 ++++++++++++++++++++++++++
> > arch/powerpc/kvm/bookehv_interrupts.S |  145 ++++++++++++++++++++++++++++++++-
> > arch/powerpc/kvm/e500_emulate.c       |    6 ++
> > arch/powerpc/kvm/e500mc.c             |    3 +-
> > 9 files changed, 422 insertions(+), 25 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/kvm_host.h
> > b/arch/powerpc/include/asm/kvm_host.h
> > index f4ba881..a9feeb0 100644
> > --- a/arch/powerpc/include/asm/kvm_host.h
> > +++ b/arch/powerpc/include/asm/kvm_host.h
> > @@ -504,7 +504,12 @@ struct kvm_vcpu_arch {
> > 	u32 mmucfg;
> > 	u32 epr;
> > 	u32 crit_save;
> > +	/* guest debug registers*/
> > 	struct kvmppc_booke_debug_reg dbg_reg;
> > +	/* shadow debug registers */
> > +	struct kvmppc_booke_debug_reg shadow_dbg_reg;
> > +	/* host debug registers*/
> > +	struct kvmppc_booke_debug_reg host_dbg_reg;
> > #endif
> > 	gpa_t paddr_accessed;
> > 	gva_t vaddr_accessed;
> > diff --git a/arch/powerpc/include/asm/kvm_ppc.h
> > b/arch/powerpc/include/asm/kvm_ppc.h
> > index b3c481e..e4b3398 100644
> > --- a/arch/powerpc/include/asm/kvm_ppc.h
> > +++ b/arch/powerpc/include/asm/kvm_ppc.h
> > @@ -45,6 +45,8 @@ enum emulation_result {
> > 	EMULATE_FAIL,         /* can't emulate this instruction */
> > 	EMULATE_AGAIN,        /* something went wrong. go again */
> > 	EMULATE_DO_PAPR,      /* kvm_run filled with PAPR request */
> > +	EMULATE_DEBUG_INST,   /* debug instruction for software
> > +				 breakpoint, exit to userspace */
> 
> Does this do something different from DO_PAPR? Maybe it makes sense to have an
> exit code EMULATE_EXIT_USER?

I think EMULATE_DO_PAPR does something similar but the name is confusing. May be we can rename EMULATE_DO_PAPR to 
EMULATE_EXIT_USER.

Thanks
-Bharat
> 
> > };
> >
> > extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu
> > *vcpu); diff --git a/arch/powerpc/include/uapi/asm/kvm.h
> > b/arch/powerpc/include/uapi/asm/kvm.h
> > index e8842ed..a81ab29 100644
> > --- a/arch/powerpc/include/uapi/asm/kvm.h
> > +++ b/arch/powerpc/include/uapi/asm/kvm.h
> > @@ -25,6 +25,7 @@
> > /* Select powerpc specific features in <linux/kvm.h> */ #define
> > __KVM_HAVE_SPAPR_TCE #define __KVM_HAVE_PPC_SMT
> > +#define __KVM_HAVE_GUEST_DEBUG
> >
> > struct kvm_regs {
> > 	__u64 pc;
> > @@ -267,7 +268,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 */
> > @@ -279,10 +297,6 @@ struct kvm_guest_debug_arch {
> > 		 * Type denotes h/w breakpoint, read watchpoint, write
> > 		 * watchpoint or watchpoint (both read and write).
> > 		 */
> > -#define KVMPPC_DEBUG_NOTYPE		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/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index 02048f3..22deda7 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -563,6 +563,32 @@ int main(void)
> > 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
> > 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr));
> > 	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu, arch.crit_save));
> > +	DEFINE(VCPU_DBSR, offsetof(struct kvm_vcpu, arch.dbsr));
> > +	DEFINE(VCPU_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg));
> > +	DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg));
> > +	DEFINE(KVMPPC_DBG_DBCR0, offsetof(struct kvmppc_booke_debug_reg,
> > +					  dbcr0));
> > +	DEFINE(KVMPPC_DBG_DBCR1, offsetof(struct kvmppc_booke_debug_reg,
> > +					  dbcr1));
> > +	DEFINE(KVMPPC_DBG_DBCR2, offsetof(struct kvmppc_booke_debug_reg,
> > +					  dbcr2));
> > +#ifdef CONFIG_KVM_E500MC
> > +	DEFINE(KVMPPC_DBG_DBCR4, offsetof(struct kvmppc_booke_debug_reg,
> > +					  dbcr4));
> > +#endif
> > +	DEFINE(KVMPPC_DBG_IAC1, offsetof(struct kvmppc_booke_debug_reg,
> > +					 iac[0]));
> > +	DEFINE(KVMPPC_DBG_IAC2, offsetof(struct kvmppc_booke_debug_reg,
> > +					 iac[1]));
> > +	DEFINE(KVMPPC_DBG_IAC3, offsetof(struct kvmppc_booke_debug_reg,
> > +					 iac[2]));
> > +	DEFINE(KVMPPC_DBG_IAC4, offsetof(struct kvmppc_booke_debug_reg,
> > +					 iac[3]));
> > +	DEFINE(KVMPPC_DBG_DAC1, offsetof(struct kvmppc_booke_debug_reg,
> > +					 dac[0]));
> > +	DEFINE(KVMPPC_DBG_DAC2, offsetof(struct kvmppc_booke_debug_reg,
> > +					 dac[1]));
> > +	DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug));
> > #endif /* CONFIG_PPC_BOOK3S */
> > #endif /* CONFIG_KVM */
> >
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 7d5a51c..faa0a0b 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -143,6 +143,9 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32
> > new_msr)
> >
> > #ifdef CONFIG_KVM_BOOKE_HV
> > 	new_msr |= MSR_GS;
> > +
> > +	if (vcpu->guest_debug)
> > +		new_msr |= MSR_DE;
> > #endif
> >
> > 	vcpu->arch.shared->msr = new_msr;
> > @@ -711,7 +714,8 @@ out:
> > 	return ret;
> > }
> >
> > -static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
> > +static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
> > +			  int exit_nr)
> 
> Why pass in exit_nr?
> 
> > {
> > 	enum emulation_result er;
> >
> > @@ -728,6 +732,13 @@ static int emulation_exit(struct kvm_run *run, struct
> kvm_vcpu *vcpu)
> > 		run->exit_reason = KVM_EXIT_DCR;
> > 		return RESUME_HOST;
> >
> > +	case EMULATE_DEBUG_INST:
> > +		run->exit_reason = KVM_EXIT_DEBUG;
> > +		run->debug.arch.address = vcpu->arch.pc;
> > +		run->debug.arch.status = 0;
> > +		kvmppc_account_exit(vcpu, DEBUG_EXITS);
> > +		return RESUME_HOST;
> > +
> > 	case EMULATE_FAIL:
> > 		printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
> > 		       __func__, vcpu->arch.pc, vcpu->arch.last_inst); @@ -743,6
> > +754,28 @@ 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) {
> > +	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 = vcpu->arch.shadow_dbg_reg.dac[0];
> > +		else if (dbsr & (DBSR_DAC2R | DBSR_DAC2W))
> > +			run->debug.arch.address = vcpu->arch.shadow_dbg_reg.dac[1];
> > +	}
> > +
> > +	return RESUME_HOST;
> > +}
> > +
> > static void kvmppc_fill_pt_regs(struct pt_regs *regs) {
> > 	ulong r1, ip, msr, lr;
> > @@ -887,7 +920,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct
> kvm_vcpu *vcpu,
> > 		break;
> >
> > 	case BOOKE_INTERRUPT_HV_PRIV:
> > -		r = emulation_exit(run, vcpu);
> > +		r = emulation_exit(run, vcpu, exit_nr);
> > 		break;
> >
> > 	case BOOKE_INTERRUPT_PROGRAM:
> > @@ -906,7 +939,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct
> kvm_vcpu *vcpu,
> > 			break;
> > 		}
> >
> > -		r = emulation_exit(run, vcpu);
> > +		r = emulation_exit(run, vcpu, exit_nr);
> > 		break;
> >
> > 	case BOOKE_INTERRUPT_FP_UNAVAIL:
> > @@ -1096,18 +1129,11 @@ 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;
> > 	}
> >
> > @@ -1483,10 +1509,78 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
> struct kvm_one_reg *reg)
> > 	return r;
> > }
> >
> > +#define BP_NUM	KVMPPC_BOOKE_IAC_NUM
> > +#define WP_NUM	KVMPPC_BOOKE_DAC_NUM
> > +
> > int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
> > 					 struct kvm_guest_debug *dbg)
> > {
> > -	return -EINVAL;
> > +
> > +	if (!(dbg->control & KVM_GUESTDBG_ENABLE)) {
> > +		/* Clear All debug events */
> > +		vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
> > +		vcpu->guest_debug = 0;
> > +		return 0;
> > +	}
> > +
> > +	vcpu->guest_debug = dbg->control;
> > +	vcpu->arch.shadow_dbg_reg.dbcr0 = 0;
> > +
> > +	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
> > +		vcpu->arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC;
> > +
> > +	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
> > +		struct kvmppc_booke_debug_reg *gdbgr =
> > +				&(vcpu->arch.shadow_dbg_reg);
> > +		int n, b = 0, w = 0;
> > +		const u32 bp_code[] = {
> > +			DBCR0_IAC1 | DBCR0_IDM,
> > +			DBCR0_IAC2 | DBCR0_IDM,
> > +			DBCR0_IAC3 | DBCR0_IDM,
> > +			DBCR0_IAC4 | DBCR0_IDM
> > +		};
> > +		const u32 wp_code[] = {
> > +			DBCR0_DAC1W | DBCR0_IDM,
> > +			DBCR0_DAC2W | DBCR0_IDM,
> > +			DBCR0_DAC1R | DBCR0_IDM,
> > +			DBCR0_DAC2R | DBCR0_IDM
> > +		};
> > +
> > +#ifndef CONFIG_KVM_BOOKE_HV
> 
> Please reverse the logic here. #ifndef ... #else is always a bad idea.
> 
> > +		gdbgr->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
> > +				DBCR1_IAC3US | DBCR1_IAC4US;
> > +		gdbgr->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US; #else
> > +		gdbgr->dbcr1 = 0;
> > +		gdbgr->dbcr2 = 0;
> > +#endif
> > +
> > +		for (n = 0; n < (BP_NUM + WP_NUM); n++) {
> > +			u32 type = dbg->arch.bp[n].type;
> > +
> > +			if (!type)
> > +				break;
> > +
> > +			if (type & (KVMPPC_DEBUG_WATCH_READ |
> > +				    KVMPPC_DEBUG_WATCH_WRITE)) {
> > +				if (w < WP_NUM) {
> > +					if (type & KVMPPC_DEBUG_WATCH_READ)
> > +						gdbgr->dbcr0 |= wp_code[w + 2];
> > +					if (type & KVMPPC_DEBUG_WATCH_WRITE)
> > +						gdbgr->dbcr0 |= wp_code[w];
> > +					gdbgr->dac[w] = dbg->arch.bp[n].addr;
> > +					w++;
> > +				}
> > +			} else if (type & KVMPPC_DEBUG_BREAKPOINT) {
> > +				if (b < BP_NUM) {
> > +					gdbgr->dbcr0 |= bp_code[b];
> > +					gdbgr->iac[b] = dbg->arch.bp[n].addr;
> > +					b++;
> > +				}
> > +			}
> > +		}
> > +	}
> > +	return 0;
> > }
> 
> I'll stop reviewing here. This patch is way too big. Please split it up in
> smaller, understandable bits.
> 
> 
> Alex
> 
> >
> > int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu
> > *fpu) diff --git a/arch/powerpc/kvm/booke_interrupts.S
> > b/arch/powerpc/kvm/booke_interrupts.S
> > index dd9c5d4..734c549 100644
> > --- a/arch/powerpc/kvm/booke_interrupts.S
> > +++ b/arch/powerpc/kvm/booke_interrupts.S
> > @@ -39,6 +39,8 @@
> > #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4) #define
> > HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
> > #define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */
> > +#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
> > +			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
> >
> > #define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
> >                         (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ @@ -52,6
> > +54,8 @@
> >                        (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >                        (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >
> > +#define NEED_DEBUG_SAVE (1<<BOOKE_INTERRUPT_DEBUG)
> > +
> > .macro __KVM_HANDLER ivor_nr scratch srr0
> > 	stw	r3, VCPU_GPR(R3)(r4)
> > 	stw	r5, VCPU_GPR(R5)(r4)
> > @@ -212,6 +216,59 @@ _GLOBAL(kvmppc_resume_host)
> > 	stw	r9, VCPU_FAULT_ESR(r4)
> > ..skip_esr:
> >
> > +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	rlwinm.	r8, r9, 0, ~DBCR0_IDM
> > +	beq	skip_load_host_debug
> > +	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	andis.	r9, r9, DBCR0_AC_BITS@h
> > +	li	r9, 0
> > +	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
> > +	beq	skip_load_hw_bkpts
> > +	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> > +	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> > +	mtspr	SPRN_DBCR1, r7
> > +	mtspr	SPRN_DBCR2, r9
> > +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> > +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> > +	mtspr	SPRN_IAC1, r7
> > +	mtspr	SPRN_IAC2, r9
> > +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> > +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> > +	mtspr	SPRN_IAC3, r3
> > +	mtspr	SPRN_IAC4, r4
> > +#endif
> > +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> > +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> > +	mtspr	SPRN_DAC1, r7
> > +	mtspr	SPRN_DAC2, r9
> > +skip_load_hw_bkpts:
> > +	/* Clear h/w DBSR and save current(guest) DBSR */
> > +	mfspr	r9, SPRN_DBSR
> > +	mtspr	SPRN_DBSR, r9
> > +	isync
> > +	andi.	r7, r6, NEED_DEBUG_SAVE
> > +	beq	skip_dbsr_save
> > +	/*
> > +	 * If vcpu->guest_debug flag is set then do not check for
> > +	 * shared->msr.DE as this debugging (say by QEMU) does not
> > +	 * depends on shared->msr.de. In these scanerios MSR.DE is
> > +	 * always set using shared_msr and should be handled always.
> > +	 */
> > +	lwz	r7, VCPU_GUEST_DEBUG(r4)
> > +	cmpwi	r7, 0
> > +	bne	skip_save_trap_event
> > +	PPC_LL	r3, VCPU_SHARED(r4)
> > +	PPC_LD(r3, VCPU_SHARED_MSR, r3)
> > +	andi.	r3, r3, MSR_DE
> > +	bne	skip_save_trap_event
> > +	andis.	r9, r9, DBSR_TIE@h
> > +skip_save_trap_event:
> > +	stw	r9, VCPU_DBSR(r4)
> > +skip_dbsr_save:
> > +	mtspr	SPRN_DBCR0, r8
> > +skip_load_host_debug:
> > +
> > 	/* Save remaining volatile guest register state to vcpu. */
> > 	stw	r0, VCPU_GPR(R0)(r4)
> > 	stw	r1, VCPU_GPR(R1)(r4)
> > @@ -465,6 +522,63 @@ lightweight_exit:
> > 	PPC_LD(r3, VCPU_SHARED_SPRG7, r5)
> > 	mtspr	SPRN_SPRG7W, r3
> >
> > +	mfmsr	r7
> > +	rlwinm	r7, r7, 0, ~MSR_DE
> > +	mtmsr	r7
> > +	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	rlwinm.	r7, r6, 0, ~DBCR0_IDM
> > +	beq	skip_load_guest_debug
> > +	mfspr	r8, SPRN_DBCR0
> > +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	andis.	r3, r6, DBCR0_AC_BITS@h
> > +	beq	skip_hw_bkpts
> > +	mfspr	r7, SPRN_DBCR1
> > +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> > +	mfspr	r8, SPRN_DBCR2
> > +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> > +	mfspr	r7, SPRN_IAC1
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> > +	mfspr	r8, SPRN_IAC2
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4) #if
> > +CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	mfspr	r7, SPRN_IAC3
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> > +	mfspr	r8, SPRN_IAC4
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4) #endif
> > +	mfspr	r7, SPRN_DAC1
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> > +	mfspr	r8, SPRN_DAC2
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> > +	li	r8, 0
> > +	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2, r4)
> > +	mtspr	SPRN_DBCR1, r7
> > +	mtspr	SPRN_DBCR2, r8
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
> > +	mtspr	SPRN_IAC1, r7
> > +	mtspr	SPRN_IAC2, r8
> > +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
> > +	mtspr	SPRN_IAC3, r7
> > +	mtspr	SPRN_IAC4, r8
> > +#endif
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
> > +	mtspr	SPRN_DAC1, r7
> > +	mtspr	SPRN_DAC2, r8
> > +skip_hw_bkpts:
> > +	/* Clear if any deferred debug event */
> > +	mfspr	r8, SPRN_DBSR
> > +	mtspr	SPRN_DBSR, r8
> > +	isync
> > +	/* Restore guest DBCR */
> > +	mtspr	SPRN_DBCR0, r6
> > +skip_load_guest_debug:
> > +
> > #ifdef CONFIG_KVM_EXIT_TIMING
> > 	/* save enter time */
> > 1:
> > diff --git a/arch/powerpc/kvm/bookehv_interrupts.S
> > b/arch/powerpc/kvm/bookehv_interrupts.S
> > index e8ed7d6..0d830cc 100644
> > --- a/arch/powerpc/kvm/bookehv_interrupts.S
> > +++ b/arch/powerpc/kvm/bookehv_interrupts.S
> > @@ -62,6 +62,10 @@
> > #define NEED_EMU		0x00000001 /* emulation -- save nv regs */
> > #define NEED_DEAR		0x00000002 /* save faulting DEAR */
> > #define NEED_ESR		0x00000004 /* save faulting ESR */
> > +#define NEED_DBSR		0x00000008 /* save DBSR */
> > +
> > +#define DBCR0_AC_BITS	(DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
> > +			 DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W)
> >
> > /*
> >  * On entry:
> > @@ -201,6 +205,11 @@
> > 	PPC_STL	r9, VCPU_FAULT_DEAR(r4)
> > 	.endif
> >
> > +	.if	\flags & NEED_DBSR
> > +	mfspr	r9, SPRN_DBSR
> > +	stw	r9, VCPU_DBSR(r4)
> > +	.endif
> > +
> > 	b	kvmppc_resume_host
> > .endm
> >
> > @@ -316,9 +325,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL,
> > EX_PARAMS(GDBELL), \ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
> EX_PARAMS(CRIT), \
> > 	SPRN_CSRR0, SPRN_CSRR1, 0
> > kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \
> > -	SPRN_DSRR0, SPRN_DSRR1, 0
> > +	SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
> > kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \
> > -	SPRN_CSRR0, SPRN_CSRR1, 0
> > +	SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
> > #else
> > /*
> >  * For input register values, see
> > arch/powerpc/include/asm/kvm_booke_hv_asm.h
> > @@ -411,9 +420,9 @@ kvm_handler BOOKE_INTERRUPT_GUEST_DBELL,
> > SPRN_GSRR0, SPRN_GSRR1, 0 kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
> > 	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0 kvm_lvl_handler
> > BOOKE_INTERRUPT_DEBUG, \
> > -	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> > +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, NEED_DBSR
> > kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> > -	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
> > +	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, NEED_DBSR
> > #endif
> >
> > /* Registers:
> > @@ -423,6 +432,56 @@ kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> >  *  r14: KVM exit number
> >  */
> > _GLOBAL(kvmppc_resume_host)
> > +	/*
> > +	 * If guest not used debug facility then hw debug registers
> > +	 * already have proper host values. If guest used debug
> > +	 * facility then restore host debug registers.
> > +	 * No Need to save guest debug registers as they are already intact
> > +	 * in guest/shadow registers.
> > +	 */
> > +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	rlwinm.	r8, r9, 0, ~DBCR0_IDM
> > +	beq	skip_load_host_debug
> > +	lwz	r3, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	andis.	r9, r9, DBCR0_AC_BITS@h
> > +	li	r9, 0
> > +	mtspr	SPRN_DBCR0, r9		/* disable all debug event */
> > +	beq	skip_load_hw_bkpts
> > +	lwz	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> > +	lwz	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> > +	lwz	r9, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
> > +	mtspr	SPRN_DBCR1, r7
> > +	PPC_LD(r6, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> > +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4)
> > +	mtspr	SPRN_DBCR2, r8
> > +	mtspr	SPRN_DBCR4, r9
> > +	mtspr	SPRN_IAC1, r6
> > +	mtspr	SPRN_IAC2, r7
> > +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	PPC_LD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> > +	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4)
> > +	mtspr	SPRN_IAC3, r7
> > +	mtspr	SPRN_IAC4, r8
> > +#endif
> > +	PPC_LD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> > +	PPC_LD(r9, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> > +	mtspr	SPRN_DAC1, r8
> > +	mtspr	SPRN_DAC2, r9
> > +skip_load_hw_bkpts:
> > +	isync
> > +	/* Clear h/w DBSR */
> > +	mfspr	r8, SPRN_DBSR
> > +	mtspr	SPRN_DBSR, r8
> > +	isync
> > +	/* Clear EPCR.DUVD and set host DBCR0 */
> > +	mfspr	r8, SPRN_EPCR
> > +	rlwinm	r8, r8, 0, ~SPRN_EPCR_DUVD
> > +	mtspr	SPRN_EPCR, r8
> > +	isync
> > +	mtspr	SPRN_DBCR0, r3
> > +	isync
> > +skip_load_host_debug:
> > +
> > 	/* Save remaining volatile guest register state to vcpu. */
> > 	mfspr	r3, SPRN_VRSAVE
> > 	PPC_STL	r0, VCPU_GPR(R0)(r4)
> > @@ -662,6 +721,84 @@ lightweight_exit:
> > 	mtspr	SPRN_SPRG6W, r7
> > 	mtspr	SPRN_SPRG7W, r8
> >
> > +	mfmsr	r7
> > +	rlwinm	r7, r7, 0, ~MSR_DE
> > +	mtmsr	r7
> > +	/*
> > +	 * Load hw debug registers with guest(shadow) debug registers
> > +	 * if guest is using the debug facility and also set EPCR.DUVD
> > +	 * to not allow debug events in HV mode. Do not change the
> > +	 * debug registers if guest is not using the debug facility.
> > +	 */
> > +	lwz	r6, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	rlwinm.	r7, r6, 0, ~DBCR0_IDM
> > +	beq	skip_load_guest_debug
> > +	/* Save host DBCR0 */
> > +	mfspr	r8, SPRN_DBCR0
> > +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR0(r4)
> > +	/*
> > +	 * Save host DBCR1/2, IACx and DACx and load guest DBCR1/2,
> > +	 * IACx and DACx if guest using hw breakpoint/watchpoints.
> > +	 */
> > +	andis.	r3, r6, DBCR0_AC_BITS@h
> > +	beq	skip_hw_bkpts
> > +	mfspr	r7, SPRN_DBCR1
> > +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR1(r4)
> > +	mfspr	r8, SPRN_DBCR2
> > +	stw	r8, VCPU_HOST_DBG+KVMPPC_DBG_DBCR2(r4)
> > +	mfspr	r7, SPRN_DBCR4
> > +	stw	r7, VCPU_HOST_DBG+KVMPPC_DBG_DBCR4(r4)
> > +	mfspr	r8, SPRN_IAC1
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC1, r4)
> > +	mfspr	r7, SPRN_IAC2
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC2, r4) #if
> > +CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	mfspr	r8, SPRN_IAC3
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_IAC3, r4)
> > +	mfspr	r7, SPRN_IAC4
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_IAC4, r4) #endif
> > +	mfspr	r8, SPRN_DAC1
> > +	PPC_STD(r8, VCPU_HOST_DBG+KVMPPC_DBG_DAC1, r4)
> > +	mfspr	r7, SPRN_DAC2
> > +	PPC_STD(r7, VCPU_HOST_DBG+KVMPPC_DBG_DAC2, r4)
> > +	li	r8, 0
> > +	mtspr	SPRN_DBCR0, r8		/* disable all debug event */
> > +	lwz	r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR1(r4)
> > +	lwz	r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR2(r4)
> > +	lwz	r9, VCPU_SHADOW_DBG+KVMPPC_DBG_DBCR4(r4)
> > +	mtspr	SPRN_DBCR1, r7
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC1, r4)
> > +	PPC_LD(r3, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC2, r4)
> > +	mtspr	SPRN_DBCR2, r8
> > +	mtspr	SPRN_DBCR4, r9
> > +	mtspr	SPRN_IAC1, r7
> > +	mtspr	SPRN_IAC2, r3
> > +#if CONFIG_PPC_ADV_DEBUG_IACS > 2
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC3, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_IAC4, r4)
> > +	mtspr	SPRN_IAC3, r7
> > +	mtspr	SPRN_IAC4, r8
> > +#endif
> > +	PPC_LD(r7, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC1, r4)
> > +	PPC_LD(r8, VCPU_SHADOW_DBG+KVMPPC_DBG_DAC2, r4)
> > +	mtspr	SPRN_DAC1, r7
> > +	mtspr	SPRN_DAC2, r8
> > +skip_hw_bkpts:
> > +	/* Set EPCR.DUVD and guest DBCR0 */
> > +	mfspr	r7, SPRN_EPCR
> > +	oris	r7, r7, SPRN_EPCR_DUVD@h
> > +	mtspr	SPRN_EPCR, r7
> > +	isync
> > +	/* Clear if any deferred debug event */
> > +	mfspr	r8, SPRN_DBSR
> > +	mtspr	SPRN_DBSR, r8
> > +	isync
> > +	/* Restore guest DBCR */
> > +	mtspr	SPRN_DBCR0, r6
> > +	isync
> > +skip_load_guest_debug:
> > +
> > 	/* Load some guest volatiles. */
> > 	PPC_LL	r3, VCPU_LR(r4)
> > 	PPC_LL	r5, VCPU_XER(r4)
> > diff --git a/arch/powerpc/kvm/e500_emulate.c
> > b/arch/powerpc/kvm/e500_emulate.c index e78f353..ddb903e 100644
> > --- a/arch/powerpc/kvm/e500_emulate.c
> > +++ b/arch/powerpc/kvm/e500_emulate.c
> > @@ -26,6 +26,7 @@
> > #define XOP_TLBRE   946
> > #define XOP_TLBWE   978
> > #define XOP_TLBILX  18
> > +#define XOP_EHPRIV  270
> >
> > #ifdef CONFIG_KVM_E500MC
> > static int dbell2prio(ulong param)
> > @@ -130,6 +131,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 = EMULATE_DEBUG_INST;
> > +			*advance = 0;
> > +			break;
> > +
> > 		default:
> > 			emulated = EMULATE_FAIL;
> > 		}
> > diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> > index dead142..81abe92 100644
> > --- a/arch/powerpc/kvm/e500mc.c
> > +++ b/arch/powerpc/kvm/e500mc.c
> > @@ -182,8 +182,7 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
> > {
> > 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> >
> > -	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
> > -				 SPRN_EPCR_DUVD;
> > +	vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI;
> > #ifdef CONFIG_64BIT
> > 	vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM; #endif
> > --
> > 1.7.0.4
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-02-01  5:04             ` Bhushan Bharat-R65777
@ 2013-02-01  8:06               ` Alexander Graf
  2013-02-01  9:07                 ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-02-01  8:06 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 01.02.2013, at 06:04, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Thursday, January 31, 2013 10:38 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>> Sent: Thursday, January 31, 2013 5:47 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>> 
>>>> 
>>>> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
>>>> 
>>>>> 
>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>>>> Sent: Friday, January 25, 2013 5:13 PM
>>>>>> To: Bhushan Bharat-R65777
>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>>>> Bharat-R65777
>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>>>> 
>>>>>> 
>>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>>>> 
>>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>>>>>> 
>>>>>>> Installed debug handler will be used for guest debug support and
>>>>>>> debug facility emulation features (patches for these features will
>>>>>>> follow this patch).
>>>>>>> 
>>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>>>> ---
>>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49 ++++++++++++++++++++++++++++++-
>> --
>>>> --
>>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>>>>>> 
>>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>>>> index 8a72d59..f4ba881 100644
>>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>>>>>> 	u32 tlbcfg[4];
>>>>>>> 	u32 mmucfg;
>>>>>>> 	u32 epr;
>>>>>>> +	u32 crit_save;
>>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>>>>>> 	gpa_t paddr_accessed;
>>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>>>>>> b/arch/powerpc/kernel/asm-offsets.c
>>>>>>> index 46f6afd..02048f3 100644
>>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>>>>>> @@ -562,6 +562,7 @@ int main(void)
>>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
>>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
>>>>>>> arch.fault_esr));
>>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
>>>>>>> +arch.crit_save));
>>>>>>> #endif /* CONFIG_PPC_BOOK3S */
>>>>>>> #endif /* CONFIG_KVM */
>>>>>>> 
>>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>> index eae8483..dd9c5d4 100644
>>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>> @@ -52,12 +52,7 @@
>>>>>>>                     (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>>>>>                     (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>>>>>> 
>>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> -	/* Get pointer to vcpu and record exit number. */
>>>>>>> -	mtspr	\scratch , r4
>>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> 	bctr
>>>>>>> .endm
>>>>>>> 
>>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> +	/* Get pointer to vcpu and record exit number. */
>>>>>>> +	mtspr	\scratch , r4
>>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>>> +
>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> +	mtspr   \scratch, r4
>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>>>>>> +	mfcr	r3
>>>>>>> +	mfspr	r4, SPRN_CSRR1
>>>>>>> +	andi.	r4, r4, MSR_PR
>>>>>>> +	bne	1f
>>>>>> 
>>>>>> 
>>>>>>> +	/* debug interrupt happened in enter/exit path */
>>>>>>> +	mfspr   r4, SPRN_CSRR1
>>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>>>>>> +	mtspr   SPRN_CSRR1, r4
>>>>>>> +	lis	r4, 0xffff
>>>>>>> +	ori	r4, r4, 0xffff
>>>>>>> +	mtspr	SPRN_DBSR, r4
>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>> +	mtcr	r3
>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>> +	mfspr   r4, \scratch
>>>>>>> +	rfci
>>>>>> 
>>>>>> What is this part doing? Try to ignore the debug exit?
>>>>> 
>>>>> As BOOKE doesn't have hardware support for virtualization, hardware
>>>>> never know
>>>> current pc is in guest or in host.
>>>>> So when enable hardware single step for guest, it cannot be disabled
>>>>> at the
>>>> time guest exit. Thus, we'll see that an single step interrupt
>>>> happens at the beginning of guest exit path.
>>>>> 
>>>>> With the above code we recognize this kind of single step interrupt
>>>>> disable
>>>> single step and rfci.
>>>>> 
>>>>>> Why would we have MSR_DE
>>>>>> enabled in the first place when we can't handle it?
>>>>> 
>>>>> When QEMU is using hardware debug resource then we always set MSR_DE
>>>>> during
>>>> guest is running.
>>>> 
>>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
>>>> wasn't set, you wouldn't get a single step exit.
>>> 
>>> We always set MSR_DE in hw MSR when qemu using the debug resource.
>> 
>> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be set
>> anymore, because we're in an interrupt handler, no? Or is MSR_DE kept alive on
>> interrupts?
>> 
>>> 
>>>> During the exit code path, you could then swap DBSR back to what the
>>>> host expects (which means no single step). Only after that enable
>>>> MSR_DE again.
>>> 
>>> We do not support deferred debug interrupt, so we do save restore dbsr.
>>> 
>>>> 
>>>>> 
>>>>>> 
>>>>>>> +1:	/* debug interrupt happened in guest */
>>>>>>> +	mtcr	r3
>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
>>>>>> 
>>>>>> I don't think you need the __KVM_HANDLER split. This should be
>>>>>> quite easily refactorable into a simple DBG prolog.
>>>>> 
>>>>> Can you please elaborate how you are envisioning this?
>>>> 
>>>> With this patch, you have
>>>> 
>>>> KVM_HANLDER:
>>>> 
>>>> <code>
>>>> __KVM_HANDLER
>>>> 
>>>> KVM_DBG_HANDLER:
>>>> 
>>>> <code>
>>>> __KVM_HANDLER
>>>> 
>>>> Right?
>>>> 
>>>> In KVM_HANDLER, you get:
>>>> 
>>>>> .macro KVM_HANDLER ivor_nr scratch srr0
>>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> 	/* Get pointer to vcpu and record exit number. */
>>>>> 	mtspr	\scratch , r4
>>>>> 	mfspr   r4, SPRN_SPRG_THREAD
>>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>> 
>>>> 
>>>> while KVM_DBG_HANDLER is:
>>>> 
>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>> <debug specific handling>
>>>>> +1:	/* debug interrupt happened in guest */
>>>>> +	mtcr	r3
>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>> 
>>>> 
>>>> So if you write this as
>>>> 
>>>> KVM_DBG_HANDLER:
>>>> 	<debug specific handling>
>>>> 	1:
>>>> 	mtcr		r3
>>>> 	mfspr	r4, SPRN_SPRG_THREAD
>>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>>> 	lwz		r4, \scratch
>>>> 	<KVM_HANDLER>
>>>> 
>>>> then you get code that is slower :) but it should be easier to read,
>>>> since the interface between the individual pieces is always the same.
>>>> Debug shouldn't be a fast path anyway, right?
>>> 
>>> Frankly speaking I do not see much difference :).
>>> 
>>> If we have to do as you mentioned then I think we can just do
>>> 
>>> KVM_DBG_HANDLER:
>>> 	<debug specific handling>
>>> 	1:
>>> 	mtcr		r3
>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>> 	lwz		r4, \scratch
>>> 	<KVM_HANDLER>
>> 
>> Whatever it takes to keep the oddball (debug) an oddball and keep the normal
>> case easy :).
> 
> I think there will be another problem as  the kvmppc_handler_\ivor_nr will not be the starting address which is required as per our ivor/ivpr usages for booke architecture.
> 
> I am thinking of keeping as is :).

How about we take a hybrid approach? You write the code as I described above, but call __KVM_HANDLER at the end. The normal KVM_HANDLER would look like:

KVM_HANDLER:
	kvmppc_handler_\ivor_nr:
	__KVM_HANDLER ...

That way the code should still be more understandable :)


Alex

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

* Re: [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
  2013-02-01  6:31     ` Bhushan Bharat-R65777
@ 2013-02-01  8:21       ` Alexander Graf
  0 siblings, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-02-01  8:21 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 01.02.2013, at 07:31, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, January 25, 2013 5:37 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan Bharat-R65777
>> Subject: Re: [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support
>> 
>> 
>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>> 
>>> 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.
>>> 
>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>> ---
>>> arch/powerpc/include/asm/kvm_host.h   |    5 +
>>> arch/powerpc/include/asm/kvm_ppc.h    |    2 +
>>> arch/powerpc/include/uapi/asm/kvm.h   |   22 ++++-
>>> arch/powerpc/kernel/asm-offsets.c     |   26 ++++++
>>> arch/powerpc/kvm/booke.c              |  124 +++++++++++++++++++++++++----
>>> arch/powerpc/kvm/booke_interrupts.S   |  114 ++++++++++++++++++++++++++
>>> arch/powerpc/kvm/bookehv_interrupts.S |  145 ++++++++++++++++++++++++++++++++-
>>> arch/powerpc/kvm/e500_emulate.c       |    6 ++
>>> arch/powerpc/kvm/e500mc.c             |    3 +-
>>> 9 files changed, 422 insertions(+), 25 deletions(-)
>>> 
>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>> b/arch/powerpc/include/asm/kvm_host.h
>>> index f4ba881..a9feeb0 100644
>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>> @@ -504,7 +504,12 @@ struct kvm_vcpu_arch {
>>> 	u32 mmucfg;
>>> 	u32 epr;
>>> 	u32 crit_save;
>>> +	/* guest debug registers*/
>>> 	struct kvmppc_booke_debug_reg dbg_reg;
>>> +	/* shadow debug registers */
>>> +	struct kvmppc_booke_debug_reg shadow_dbg_reg;
>>> +	/* host debug registers*/
>>> +	struct kvmppc_booke_debug_reg host_dbg_reg;
>>> #endif
>>> 	gpa_t paddr_accessed;
>>> 	gva_t vaddr_accessed;
>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>>> b/arch/powerpc/include/asm/kvm_ppc.h
>>> index b3c481e..e4b3398 100644
>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>> @@ -45,6 +45,8 @@ enum emulation_result {
>>> 	EMULATE_FAIL,         /* can't emulate this instruction */
>>> 	EMULATE_AGAIN,        /* something went wrong. go again */
>>> 	EMULATE_DO_PAPR,      /* kvm_run filled with PAPR request */
>>> +	EMULATE_DEBUG_INST,   /* debug instruction for software
>>> +				 breakpoint, exit to userspace */
>> 
>> Does this do something different from DO_PAPR? Maybe it makes sense to have an
>> exit code EMULATE_EXIT_USER?
> 
> I think EMULATE_DO_PAPR does something similar but the name is confusing. May be we can rename EMULATE_DO_PAPR to 
> EMULATE_EXIT_USER.

Yeah, please check that it actually does the right thing still for PAPR exits then :).


Alex

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

* RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-02-01  8:06               ` Alexander Graf
@ 2013-02-01  9:07                 ` Bhushan Bharat-R65777
  2013-02-07 14:21                   ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-01  9:07 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Alexander Graf [mailto:agraf@suse.de]
> Sent: Friday, February 01, 2013 1:36 PM
> To: Bhushan Bharat-R65777
> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> 
> 
> On 01.02.2013, at 06:04, Bhushan Bharat-R65777 wrote:
> 
> >
> >
> >> -----Original Message-----
> >> From: kvm-ppc-owner@vger.kernel.org
> >> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
> >> Sent: Thursday, January 31, 2013 10:38 PM
> >> To: Bhushan Bharat-R65777
> >> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>
> >>
> >> On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:
> >>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Alexander Graf [mailto:agraf@suse.de]
> >>>> Sent: Thursday, January 31, 2013 5:47 PM
> >>>> To: Bhushan Bharat-R65777
> >>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> >>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>>>
> >>>>
> >>>> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
> >>>>
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Alexander Graf [mailto:agraf@suse.de]
> >>>>>> Sent: Friday, January 25, 2013 5:13 PM
> >>>>>> To: Bhushan Bharat-R65777
> >>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >>>>>> Bharat-R65777
> >>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>>>>>
> >>>>>>
> >>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>>>>>
> >>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> >>>>>>>
> >>>>>>> Installed debug handler will be used for guest debug support and
> >>>>>>> debug facility emulation features (patches for these features
> >>>>>>> will follow this patch).
> >>>>>>>
> >>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
> >>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>>>>>> ---
> >>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
> >>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
> >>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49
> ++++++++++++++++++++++++++++++-
> >> --
> >>>> --
> >>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>> b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>> index 8a72d59..f4ba881 100644
> >>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> >>>>>>> 	u32 tlbcfg[4];
> >>>>>>> 	u32 mmucfg;
> >>>>>>> 	u32 epr;
> >>>>>>> +	u32 crit_save;
> >>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> >>>>>>> 	gpa_t paddr_accessed;
> >>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>> b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>> index 46f6afd..02048f3 100644
> >>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>> @@ -562,6 +562,7 @@ int main(void)
> >>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> >>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu,
> arch.fault_dear));
> >>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
> >>>>>>> arch.fault_esr));
> >>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
> >>>>>>> +arch.crit_save));
> >>>>>>> #endif /* CONFIG_PPC_BOOK3S */
> >>>>>>> #endif /* CONFIG_KVM */
> >>>>>>>
> >>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>> index eae8483..dd9c5d4 100644
> >>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>> @@ -52,12 +52,7 @@
> >>>>>>>                     (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >>>>>>>                     (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >>>>>>>
> >>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> -	/* Get pointer to vcpu and record exit number. */
> >>>>>>> -	mtspr	\scratch , r4
> >>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
> >>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
> >>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
> >>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
> >>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> 	bctr
> >>>>>>> .endm
> >>>>>>>
> >>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> +	/* Get pointer to vcpu and record exit number. */
> >>>>>>> +	mtspr	\scratch , r4
> >>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>> +
> >>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> +	mtspr   \scratch, r4
> >>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
> >>>>>>> +	mfcr	r3
> >>>>>>> +	mfspr	r4, SPRN_CSRR1
> >>>>>>> +	andi.	r4, r4, MSR_PR
> >>>>>>> +	bne	1f
> >>>>>>
> >>>>>>
> >>>>>>> +	/* debug interrupt happened in enter/exit path */
> >>>>>>> +	mfspr   r4, SPRN_CSRR1
> >>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
> >>>>>>> +	mtspr   SPRN_CSRR1, r4
> >>>>>>> +	lis	r4, 0xffff
> >>>>>>> +	ori	r4, r4, 0xffff
> >>>>>>> +	mtspr	SPRN_DBSR, r4
> >>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	mtcr	r3
> >>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>> +	mfspr   r4, \scratch
> >>>>>>> +	rfci
> >>>>>>
> >>>>>> What is this part doing? Try to ignore the debug exit?
> >>>>>
> >>>>> As BOOKE doesn't have hardware support for virtualization,
> >>>>> hardware never know
> >>>> current pc is in guest or in host.
> >>>>> So when enable hardware single step for guest, it cannot be
> >>>>> disabled at the
> >>>> time guest exit. Thus, we'll see that an single step interrupt
> >>>> happens at the beginning of guest exit path.
> >>>>>
> >>>>> With the above code we recognize this kind of single step
> >>>>> interrupt disable
> >>>> single step and rfci.
> >>>>>
> >>>>>> Why would we have MSR_DE
> >>>>>> enabled in the first place when we can't handle it?
> >>>>>
> >>>>> When QEMU is using hardware debug resource then we always set
> >>>>> MSR_DE during
> >>>> guest is running.
> >>>>
> >>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
> >>>> wasn't set, you wouldn't get a single step exit.
> >>>
> >>> We always set MSR_DE in hw MSR when qemu using the debug resource.
> >>
> >> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be
> >> set anymore, because we're in an interrupt handler, no? Or is MSR_DE
> >> kept alive on interrupts?
> >>
> >>>
> >>>> During the exit code path, you could then swap DBSR back to what
> >>>> the host expects (which means no single step). Only after that
> >>>> enable MSR_DE again.
> >>>
> >>> We do not support deferred debug interrupt, so we do save restore dbsr.
> >>>
> >>>>
> >>>>>
> >>>>>>
> >>>>>>> +1:	/* debug interrupt happened in guest */
> >>>>>>> +	mtcr	r3
> >>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> >>>>>>
> >>>>>> I don't think you need the __KVM_HANDLER split. This should be
> >>>>>> quite easily refactorable into a simple DBG prolog.
> >>>>>
> >>>>> Can you please elaborate how you are envisioning this?
> >>>>
> >>>> With this patch, you have
> >>>>
> >>>> KVM_HANLDER:
> >>>>
> >>>> <code>
> >>>> __KVM_HANDLER
> >>>>
> >>>> KVM_DBG_HANDLER:
> >>>>
> >>>> <code>
> >>>> __KVM_HANDLER
> >>>>
> >>>> Right?
> >>>>
> >>>> In KVM_HANDLER, you get:
> >>>>
> >>>>> .macro KVM_HANDLER ivor_nr scratch srr0
> >>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> 	/* Get pointer to vcpu and record exit number. */
> >>>>> 	mtspr	\scratch , r4
> >>>>> 	mfspr   r4, SPRN_SPRG_THREAD
> >>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>
> >>>>
> >>>> while KVM_DBG_HANDLER is:
> >>>>
> >>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>> <debug specific handling>
> >>>>> +1:	/* debug interrupt happened in guest */
> >>>>> +	mtcr	r3
> >>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>
> >>>>
> >>>> So if you write this as
> >>>>
> >>>> KVM_DBG_HANDLER:
> >>>> 	<debug specific handling>
> >>>> 	1:
> >>>> 	mtcr		r3
> >>>> 	mfspr	r4, SPRN_SPRG_THREAD
> >>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
> >>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>>> 	lwz		r4, \scratch
> >>>> 	<KVM_HANDLER>
> >>>>
> >>>> then you get code that is slower :) but it should be easier to
> >>>> read, since the interface between the individual pieces is always the same.
> >>>> Debug shouldn't be a fast path anyway, right?
> >>>
> >>> Frankly speaking I do not see much difference :).
> >>>
> >>> If we have to do as you mentioned then I think we can just do
> >>>
> >>> KVM_DBG_HANDLER:
> >>> 	<debug specific handling>
> >>> 	1:
> >>> 	mtcr		r3
> >>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>> 	lwz		r4, \scratch
> >>> 	<KVM_HANDLER>
> >>
> >> Whatever it takes to keep the oddball (debug) an oddball and keep the
> >> normal case easy :).
> >
> > I think there will be another problem as  the kvmppc_handler_\ivor_nr will not
> be the starting address which is required as per our ivor/ivpr usages for booke
> architecture.
> >
> > I am thinking of keeping as is :).
> 
> How about we take a hybrid approach? You write the code as I described above,
> but call __KVM_HANDLER at the end. The normal KVM_HANDLER would look like:
> 
> KVM_HANDLER:
> 	kvmppc_handler_\ivor_nr:
> 	__KVM_HANDLER ...
> 
> That way the code should still be more understandable :)
> 

With my current Patch it is defined as:

.macro KVM_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)
        /* Get pointer to vcpu and record exit number. */
        mtspr   \scratch , r4
        mfspr   r4, SPRN_SPRG_THREAD
        lwz     r4, THREAD_KVM_VCPU(r4)
        __KVM_HANDLER \ivor_nr \scratch \srr0
.endm

.macro KVM_DBG_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)

<<<<<<Debug related handling>>>>>

1:      /* debug interrupt happened in guest */
        mtcr    r3
        mfspr   r4, SPRN_SPRG_THREAD
        lwz     r4, THREAD_KVM_VCPU(r4)
        lwz     r3, VCPU_CRIT_SAVE(r4)
        __KVM_HANDLER \ivor_nr \scratch \srr0
.endm

So the kvmppc_handler_\ivor_nr is defined and should always be at the start of exception handling?

So if KVM_DBG_HANDLER need to call KVM_HANDLER then there will be issue of 2 definition for DBG interrupt.

I am sorry but I did not understood how you want this to define. Can you please describe ?

Thanks
-Bharat



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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-01  0:11                         ` Alexander Graf
@ 2013-02-01 22:38                           ` Scott Wood
  2013-02-04  4:48                             ` Bhushan Bharat-R65777
                                               ` (2 more replies)
  0 siblings, 3 replies; 59+ messages in thread
From: Scott Wood @ 2013-02-01 22:38 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
> 
> On 31.01.2013, at 23:40, Scott Wood wrote:
> 
> > On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
> >> On 31.01.2013, at 20:05, Alexander Graf wrote:
> >> >
> >> > On 31.01.2013, at 19:54, Scott Wood wrote:
> >> >
> >> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> >> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
> >> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> >> >>>>> How about something like this? Then both targets at least  
> suck as much :).
> >> >>>>
> >> >>>> I'm not sure that should be the goal...
> >> >>>>
> >> >>>>> Thanks to e500mc's awful hardware design, we don't know who  
> sets the MSR_DE bit. Once we forced it onto the guest, we have no  
> change to know whether the guest also set it or not. We could only  
> guess.
> >> >>>>
> >> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but  
> we still need to set it in the first place.
> >> >>>>
> >> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM]  
> to let the guest know that the debug resources are not available, and  
> that "the value of MSR[DE] is not specified and not modifiable".
> >> >>> So what would the guest do then to tell the hypervisor that it  
> actually wants to know about debug events?
> >> >>
> >> >> The guest is out of luck, just as if a JTAG were in use.
> >> >
> >> > Hrm.
> >> >
> >> > Can we somehow generalize this "out of luck" behavior?
> >> >
> >> > Every time we would set or clear an MSR bit in shadow_msr on  
> e500v2, we would instead set or clear it in the real MSR. That way  
> only e500mc is out of luck, but the code would still be shared.
> >
> > I don't follow.  e500v2 is just as out-of-luck.  The mechanism  
> simply does not support sharing debug resources.
> 
> For e500v2 we have 2 fields
> 
>   * MSR as the guest sees it
>   * MSR as we execute when the guest runs
> 
> Since we know the MSR when the guest sees it, we can decide what to  
> do when we get an unhandled debug interrupt.

That's not the same thing as making the real MSR[DE] show up in the  
guest MSR[DE].

There are other problems with sharing -- what happens when both host  
and guest try to write to a particular IAC or DAC?

Also, performance would be pretty awful if the guest has e.g. single  
stepping in DBCR0 enabled but MSR[DE]=0, and the host doesn't care  
about single stepping (but does want debugging enabled in general).

> > What do you mean by "the real MSR"?  The real MSR is shadow_msr,  
> and MSR_DE must always be set there if the host is debugging the  
> guest.  As for reflecting it into the guest MSR, we could, but I  
> don't really see the point.  We're never going to actually send a  
> debug exception to the guest when the host owns the debug resources.
> 
> Why not? That's the whole point of jumping through user space.

That's still needed for software breakpoints, which don't rely on the  
debug resources.

>   1) guest exits with debug interrupt
>   2) QEMU gets a debug exit
>   3) QEMU checks in its list whether it belongs to its own debug  
> points
>   4) if not, it reinjects the interrupt into the guest
> 
> Step 4 is pretty difficult to do when we don't know whether the guest  
> is actually capable of handling debug interrupts at that moment.

Software breakpoints take a Program interrupt rather than a Debug  
interrupt, unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not  
own debug resources we should always send it to the Program interrupt,  
so MSR[DE] doesn't matter.

> > The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder  
> to read.  I had to stare at it a while before noticing that you  
> initially set is_debug from the guest MSR and that you'd never really  
> clear MSR_DE here on bookehv.
> 
> Well, I'm mostly bouncing ideas here to find a way to express what  
> we're trying to say in a way that someone who hasn't read this email  
> thread would still understand what's going on :).

I think it's already straightforward enough if you accept that shared  
debug resources aren't supported, and that we are either in a mode  
where the real MSR[DE] reflects the guest MSR[DE], or a mode where the  
real MSR[DE] is always on in guest mode and the guest MSR[DE] is  
irrelevant.

> How about this version?
> 
> 
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 38a62ef..9929c41 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu  
> *vcpu)
>  #endif
>  }
> 
> +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
> +{
> +#ifndef CONFIG_KVM_BOOKE_HV
> +	/* Synchronize guest's desire to get debug interrupts into  
> shadow MSR */
> +	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;
> +#endif
> +	}
> +}

This shows "guest's desire to get debug interrupts" in a context that  
is not specifically for !vcpu->guest_debug, which is misleading.

> +
>  /*
>   * Helper function for "full" MSR writes.  No need to call this if  
> only
>   * EE/CE/ME/DE/RI are changing.
> @@ -150,6 +172,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,
> 
> 
> My main concern here is that we don't know when to remove MSR_DE  
> again from the (shadow) MSR. So how about this one instead?

Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove  
it } else { just copy whatever's in guest MSR }

> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 38a62ef..2676703 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32  
> new_msr)
>  	u32 old_msr = vcpu->arch.shared->msr;
> 
>  #ifdef CONFIG_KVM_BOOKE_HV
> -	new_msr |= MSR_GS;
> +	new_msr |= MSR_GS | MSR_DE;
>  #endif
> 
>  	vcpu->arch.shared->msr = new_msr;
> 
> 
> That would semantically move e500mc to the same logic as e500v2. With  
> the main difference that we have no idea what MSR_DE value the guest  
> really wanted to have set.

This would break the case where the guest owns the debug resources.

> If I read the spec correctly, rfci traps.

rfdi is the relevant one for e500mc, but yes.

> So we know the time frame from [inject debug interrupt ... rfci].  
> During that time we know for sure that the guest thinks MSR_DE is 0.

No, we don't.  The guest could have tried to use mtmsr or rfi to enable  
MSR[DE].  It could have seen the context it came from was userspace,  
and scheduled to another process, etc.

> Outside of that context, we just have to assume the guest can always  
> receive debug interrupts if it configured them.

No.

-Scott

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-01-16  8:24 ` [PATCH 4/8] Added ONE_REG interface for debug instruction Bharat Bhushan
  2013-01-25 11:48   ` Alexander Graf
@ 2013-02-04  0:41   ` Paul Mackerras
  2013-02-07 14:29     ` Alexander Graf
  1 sibling, 1 reply; 59+ messages in thread
From: Paul Mackerras @ 2013-02-04  0:41 UTC (permalink / raw)
  To: Bharat Bhushan; +Cc: kvm-ppc, kvm, agraf, Bharat Bhushan

On Wed, Jan 16, 2013 at 01:54:41PM +0530, Bharat Bhushan wrote:
> This patch adds the one_reg interface to get the special instruction
> to be used for setting software breakpoint from userspace.

Since this presumably is constant for any given platform, wouldn't
a capability be more appropriate?

Paul.

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

* RE: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-01 22:38                           ` Scott Wood
@ 2013-02-04  4:48                             ` Bhushan Bharat-R65777
  2013-02-04 19:47                               ` Scott Wood
  2013-02-07 14:58                             ` Alexander Graf
  2013-02-07 15:00                             ` Bhushan Bharat-R65777
  2 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-04  4:48 UTC (permalink / raw)
  To: Wood Scott-B07421, Alexander Graf
  Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Saturday, February 02, 2013 4:09 AM
> To: Alexander Graf
> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
> 
> On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
> >
> > On 31.01.2013, at 23:40, Scott Wood wrote:
> >
> > > On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
> > >> On 31.01.2013, at 20:05, Alexander Graf wrote:
> > >> >
> > >> > On 31.01.2013, at 19:54, Scott Wood wrote:
> > >> >
> > >> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> > >> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
> > >> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> > >> >>>>> How about something like this? Then both targets at least
> > suck as much :).
> > >> >>>>
> > >> >>>> I'm not sure that should be the goal...
> > >> >>>>
> > >> >>>>> Thanks to e500mc's awful hardware design, we don't know who
> > sets the MSR_DE bit. Once we forced it onto the guest, we have no
> > change to know whether the guest also set it or not. We could only
> > guess.
> > >> >>>>
> > >> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but
> > we still need to set it in the first place.
> > >> >>>>
> > >> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM]
> > to let the guest know that the debug resources are not available, and
> > that "the value of MSR[DE] is not specified and not modifiable".
> > >> >>> So what would the guest do then to tell the hypervisor that it
> > actually wants to know about debug events?
> > >> >>
> > >> >> The guest is out of luck, just as if a JTAG were in use.
> > >> >
> > >> > Hrm.
> > >> >
> > >> > Can we somehow generalize this "out of luck" behavior?
> > >> >
> > >> > Every time we would set or clear an MSR bit in shadow_msr on
> > e500v2, we would instead set or clear it in the real MSR. That way
> > only e500mc is out of luck, but the code would still be shared.
> > >
> > > I don't follow.  e500v2 is just as out-of-luck.  The mechanism
> > simply does not support sharing debug resources.
> >
> > For e500v2 we have 2 fields
> >
> >   * MSR as the guest sees it
> >   * MSR as we execute when the guest runs
> >
> > Since we know the MSR when the guest sees it, we can decide what to do
> > when we get an unhandled debug interrupt.
> 
> That's not the same thing as making the real MSR[DE] show up in the guest
> MSR[DE].
> 
> There are other problems with sharing -- what happens when both host and guest
> try to write to a particular IAC or DAC?
> 
> Also, performance would be pretty awful if the guest has e.g. single stepping in
> DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping
> (but does want debugging enabled in general).
> 
> > > What do you mean by "the real MSR"?  The real MSR is shadow_msr,
> > and MSR_DE must always be set there if the host is debugging the
> > guest.  As for reflecting it into the guest MSR, we could, but I don't
> > really see the point.  We're never going to actually send a debug
> > exception to the guest when the host owns the debug resources.
> >
> > Why not? That's the whole point of jumping through user space.
> 
> That's still needed for software breakpoints, which don't rely on the debug
> resources.
> 
> >   1) guest exits with debug interrupt
> >   2) QEMU gets a debug exit
> >   3) QEMU checks in its list whether it belongs to its own debug
> > points
> >   4) if not, it reinjects the interrupt into the guest
> >
> > Step 4 is pretty difficult to do when we don't know whether the guest
> > is actually capable of handling debug interrupts at that moment.
> 
> Software breakpoints take a Program interrupt rather than a Debug interrupt,
> unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources
> we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
> 
> > > The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder
> > to read.  I had to stare at it a while before noticing that you
> > initially set is_debug from the guest MSR and that you'd never really
> > clear MSR_DE here on bookehv.
> >
> > Well, I'm mostly bouncing ideas here to find a way to express what
> > we're trying to say in a way that someone who hasn't read this email
> > thread would still understand what's going on :).
> 
> I think it's already straightforward enough if you accept that shared debug
> resources aren't supported, and that we are either in a mode where the real
> MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always
> on in guest mode and the guest MSR[DE] is irrelevant.
> 
> > How about this version?
> >
> >
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 38a62ef..9929c41 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
> > *vcpu)
> >  #endif
> >  }
> >
> > +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { #ifndef
> > +CONFIG_KVM_BOOKE_HV
> > +	/* Synchronize guest's desire to get debug interrupts into
> > shadow MSR */
> > +	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;
> > +#endif
> > +	}
> > +}
> 
> This shows "guest's desire to get debug interrupts" in a context that is not
> specifically for !vcpu->guest_debug, which is misleading.
> 
> > +
> >  /*
> >   * Helper function for "full" MSR writes.  No need to call this if
> > only
> >   * EE/CE/ME/DE/RI are changing.
> > @@ -150,6 +172,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,
> >
> >
> > My main concern here is that we don't know when to remove MSR_DE again
> > from the (shadow) MSR. So how about this one instead?
> 
> Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove it } else
> { just copy whatever's in guest MSR }

I think we are ok with shadow_msr on e500v2 but we can have problem on bookehv where we do not know when to clear MSR_DE in shared->msr.

How it works on e500mc:
	(1) User-space makes ioctl to use debug resource, we set vcpu->guest_debug.
	(2) Before entering into the guest we check vcpu->guest_debug flag and if set we set MSR_DE in shared->msr.
	(3) Sometime later user-space releases the debug resource then in ioctl handling will clear vcpu->guest_debug.
	(4) Now when entering to guest we do not know what to do with MSR_DE in shared->msr as we do now know if guest might have tried to set/clear MSR_DE in between step (2) and step(3). What should be safe thing to do? Can we leave MSR_DE set or clear MSR_DE. If we want to clear MSR_DE then will it be good idea to clear this in step (3) above (in ioctl where we clear vcpu->guest_debug).


On e500v2 we have separate shadow_msr and shared->msr so the flow can be:
	(1) User-space makes ioctl to use debug resource, we set vcpu->guest_debug.
	(2) Before entering into the guest we check vcpu->guest_debug flag and we set MSR_DE in vcpu->arch.shadow_msr. And if vcpu->guest_debug flag is not set then use vcpu->arch.shared->msr for MSR_DE in shadow_msr.
	(3) User-space releases the debug resource then in ioctl handling will clear vcpu->guest_debug.
	(4) Now when entering to guest set shadow_msr as per vcpu->arch.shared->msr. 

Thanks
-Bharat


> 
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 38a62ef..2676703 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32
> > new_msr)
> >  	u32 old_msr = vcpu->arch.shared->msr;
> >
> >  #ifdef CONFIG_KVM_BOOKE_HV
> > -	new_msr |= MSR_GS;
> > +	new_msr |= MSR_GS | MSR_DE;
> >  #endif
> >
> >  	vcpu->arch.shared->msr = new_msr;
> >
> >
> > That would semantically move e500mc to the same logic as e500v2. With
> > the main difference that we have no idea what MSR_DE value the guest
> > really wanted to have set.
> 
> This would break the case where the guest owns the debug resources.
> 
> > If I read the spec correctly, rfci traps.
> 
> rfdi is the relevant one for e500mc, but yes.
> 
> > So we know the time frame from [inject debug interrupt ... rfci].
> > During that time we know for sure that the guest thinks MSR_DE is 0.
> 
> No, we don't.  The guest could have tried to use mtmsr or rfi to enable MSR[DE].
> It could have seen the context it came from was userspace, and scheduled to
> another process, etc.
> 
> > Outside of that context, we just have to assume the guest can always
> > receive debug interrupts if it configured them.
> 
> No.
> 
> -Scott

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-04  4:48                             ` Bhushan Bharat-R65777
@ 2013-02-04 19:47                               ` Scott Wood
  0 siblings, 0 replies; 59+ messages in thread
From: Scott Wood @ 2013-02-04 19:47 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, Alexander Graf, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org

On 02/03/2013 10:48:29 PM, Bhushan Bharat-R65777 wrote:
> 
> 
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Saturday, February 02, 2013 4:09 AM
> > To: Alexander Graf
> > Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org;  
> kvm@vger.kernel.org
> > Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt  
> injection to guest
> >
> > On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
> > > My main concern here is that we don't know when to remove MSR_DE  
> again
> > > from the (shadow) MSR. So how about this one instead?
> >
> > Why wouldn't you know this?  if (vcpu->guest_debug) { you never  
> remove it } else
> > { just copy whatever's in guest MSR }
> 
> I think we are ok with shadow_msr on e500v2 but we can have problem  
> on bookehv where we do not know when to clear MSR_DE in shared->msr.
> 
> How it works on e500mc:
> 	(1) User-space makes ioctl to use debug resource, we set  
> vcpu->guest_debug.
> 	(2) Before entering into the guest we check vcpu->guest_debug  
> flag and if set we set MSR_DE in shared->msr.
> 	(3) Sometime later user-space releases the debug resource then  
> in ioctl handling will clear vcpu->guest_debug.
> 	(4) Now when entering to guest we do not know what to do with  
> MSR_DE in shared->msr as we do now know if guest might have tried to  
> set/clear MSR_DE in between step (2) and step(3). What should be safe  
> thing to do? Can we leave MSR_DE set or clear MSR_DE. If we want to  
> clear MSR_DE then will it be good idea to clear this in step (3)  
> above (in ioctl where we clear vcpu->guest_debug).

Oh, you want to support dynamically changing the debug mode?  The  
hardware can't really deal with that, unless you paravirt MSR[DE],  
which doesn't seem worth it.  There's also the issue of confusing the  
guest if it checks EDM before you give debug to the host (this one  
applies to e500v2 as well).

-Scott

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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-02-01  9:07                 ` Bhushan Bharat-R65777
@ 2013-02-07 14:21                   ` Alexander Graf
  2013-02-07 14:48                     ` Bhushan Bharat-R65777
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 14:21 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 01.02.2013, at 10:07, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, February 01, 2013 1:36 PM
>> To: Bhushan Bharat-R65777
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>> 
>> 
>> On 01.02.2013, at 06:04, Bhushan Bharat-R65777 wrote:
>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: kvm-ppc-owner@vger.kernel.org
>>>> [mailto:kvm-ppc-owner@vger.kernel.org] On Behalf Of Alexander Graf
>>>> Sent: Thursday, January 31, 2013 10:38 PM
>>>> To: Bhushan Bharat-R65777
>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>> 
>>>> 
>>>> On 31.01.2013, at 17:58, Bhushan Bharat-R65777 wrote:
>>>> 
>>>>> 
>>>>> 
>>>>>> -----Original Message-----
>>>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>>>> Sent: Thursday, January 31, 2013 5:47 PM
>>>>>> To: Bhushan Bharat-R65777
>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>>>> 
>>>>>> 
>>>>>> On 30.01.2013, at 12:30, Bhushan Bharat-R65777 wrote:
>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>>> -----Original Message-----
>>>>>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>>>>>> Sent: Friday, January 25, 2013 5:13 PM
>>>>>>>> To: Bhushan Bharat-R65777
>>>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>>>>>> Bharat-R65777
>>>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>>>>>> 
>>>>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>>>>>>>> 
>>>>>>>>> Installed debug handler will be used for guest debug support and
>>>>>>>>> debug facility emulation features (patches for these features
>>>>>>>>> will follow this patch).
>>>>>>>>> 
>>>>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>>>>>> ---
>>>>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>>>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>>>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49
>> ++++++++++++++++++++++++++++++-
>>>> --
>>>>>> --
>>>>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>>>>>>>> 
>>>>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>> index 8a72d59..f4ba881 100644
>>>>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>>>>>>>> 	u32 tlbcfg[4];
>>>>>>>>> 	u32 mmucfg;
>>>>>>>>> 	u32 epr;
>>>>>>>>> +	u32 crit_save;
>>>>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>>>>>>>> 	gpa_t paddr_accessed;
>>>>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>> b/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>> index 46f6afd..02048f3 100644
>>>>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>> @@ -562,6 +562,7 @@ int main(void)
>>>>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>>>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu,
>> arch.fault_dear));
>>>>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
>>>>>>>>> arch.fault_esr));
>>>>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
>>>>>>>>> +arch.crit_save));
>>>>>>>>> #endif /* CONFIG_PPC_BOOK3S */
>>>>>>>>> #endif /* CONFIG_KVM */
>>>>>>>>> 
>>>>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>> index eae8483..dd9c5d4 100644
>>>>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>> @@ -52,12 +52,7 @@
>>>>>>>>>                    (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>>>>>>>                    (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>>>>>>>> 
>>>>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> -	/* Get pointer to vcpu and record exit number. */
>>>>>>>>> -	mtspr	\scratch , r4
>>>>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>>>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>>>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>>>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> 	bctr
>>>>>>>>> .endm
>>>>>>>>> 
>>>>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> +	/* Get pointer to vcpu and record exit number. */
>>>>>>>>> +	mtspr	\scratch , r4
>>>>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>>>>> +
>>>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> +	mtspr   \scratch, r4
>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>> +	mfcr	r3
>>>>>>>>> +	mfspr	r4, SPRN_CSRR1
>>>>>>>>> +	andi.	r4, r4, MSR_PR
>>>>>>>>> +	bne	1f
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> +	/* debug interrupt happened in enter/exit path */
>>>>>>>>> +	mfspr   r4, SPRN_CSRR1
>>>>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>>>>>>>> +	mtspr   SPRN_CSRR1, r4
>>>>>>>>> +	lis	r4, 0xffff
>>>>>>>>> +	ori	r4, r4, 0xffff
>>>>>>>>> +	mtspr	SPRN_DBSR, r4
>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +	mtcr	r3
>>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>> +	mfspr   r4, \scratch
>>>>>>>>> +	rfci
>>>>>>>> 
>>>>>>>> What is this part doing? Try to ignore the debug exit?
>>>>>>> 
>>>>>>> As BOOKE doesn't have hardware support for virtualization,
>>>>>>> hardware never know
>>>>>> current pc is in guest or in host.
>>>>>>> So when enable hardware single step for guest, it cannot be
>>>>>>> disabled at the
>>>>>> time guest exit. Thus, we'll see that an single step interrupt
>>>>>> happens at the beginning of guest exit path.
>>>>>>> 
>>>>>>> With the above code we recognize this kind of single step
>>>>>>> interrupt disable
>>>>>> single step and rfci.
>>>>>>> 
>>>>>>>> Why would we have MSR_DE
>>>>>>>> enabled in the first place when we can't handle it?
>>>>>>> 
>>>>>>> When QEMU is using hardware debug resource then we always set
>>>>>>> MSR_DE during
>>>>>> guest is running.
>>>>>> 
>>>>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
>>>>>> wasn't set, you wouldn't get a single step exit.
>>>>> 
>>>>> We always set MSR_DE in hw MSR when qemu using the debug resource.
>>>> 
>>>> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't be
>>>> set anymore, because we're in an interrupt handler, no? Or is MSR_DE
>>>> kept alive on interrupts?
>>>> 
>>>>> 
>>>>>> During the exit code path, you could then swap DBSR back to what
>>>>>> the host expects (which means no single step). Only after that
>>>>>> enable MSR_DE again.
>>>>> 
>>>>> We do not support deferred debug interrupt, so we do save restore dbsr.
>>>>> 
>>>>>> 
>>>>>>> 
>>>>>>>> 
>>>>>>>>> +1:	/* debug interrupt happened in guest */
>>>>>>>>> +	mtcr	r3
>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
>>>>>>>> 
>>>>>>>> I don't think you need the __KVM_HANDLER split. This should be
>>>>>>>> quite easily refactorable into a simple DBG prolog.
>>>>>>> 
>>>>>>> Can you please elaborate how you are envisioning this?
>>>>>> 
>>>>>> With this patch, you have
>>>>>> 
>>>>>> KVM_HANLDER:
>>>>>> 
>>>>>> <code>
>>>>>> __KVM_HANDLER
>>>>>> 
>>>>>> KVM_DBG_HANDLER:
>>>>>> 
>>>>>> <code>
>>>>>> __KVM_HANDLER
>>>>>> 
>>>>>> Right?
>>>>>> 
>>>>>> In KVM_HANDLER, you get:
>>>>>> 
>>>>>>> .macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> 	/* Get pointer to vcpu and record exit number. */
>>>>>>> 	mtspr	\scratch , r4
>>>>>>> 	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>> 
>>>>>> 
>>>>>> while KVM_DBG_HANDLER is:
>>>>>> 
>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>> <debug specific handling>
>>>>>>> +1:	/* debug interrupt happened in guest */
>>>>>>> +	mtcr	r3
>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>> 
>>>>>> 
>>>>>> So if you write this as
>>>>>> 
>>>>>> KVM_DBG_HANDLER:
>>>>>> 	<debug specific handling>
>>>>>> 	1:
>>>>>> 	mtcr		r3
>>>>>> 	mfspr	r4, SPRN_SPRG_THREAD
>>>>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
>>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>>>>> 	lwz		r4, \scratch
>>>>>> 	<KVM_HANDLER>
>>>>>> 
>>>>>> then you get code that is slower :) but it should be easier to
>>>>>> read, since the interface between the individual pieces is always the same.
>>>>>> Debug shouldn't be a fast path anyway, right?
>>>>> 
>>>>> Frankly speaking I do not see much difference :).
>>>>> 
>>>>> If we have to do as you mentioned then I think we can just do
>>>>> 
>>>>> KVM_DBG_HANDLER:
>>>>> 	<debug specific handling>
>>>>> 	1:
>>>>> 	mtcr		r3
>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>>>> 	lwz		r4, \scratch
>>>>> 	<KVM_HANDLER>
>>>> 
>>>> Whatever it takes to keep the oddball (debug) an oddball and keep the
>>>> normal case easy :).
>>> 
>>> I think there will be another problem as  the kvmppc_handler_\ivor_nr will not
>> be the starting address which is required as per our ivor/ivpr usages for booke
>> architecture.
>>> 
>>> I am thinking of keeping as is :).
>> 
>> How about we take a hybrid approach? You write the code as I described above,
>> but call __KVM_HANDLER at the end. The normal KVM_HANDLER would look like:
>> 
>> KVM_HANDLER:
>> 	kvmppc_handler_\ivor_nr:
>> 	__KVM_HANDLER ...
>> 
>> That way the code should still be more understandable :)
>> 
> 
> With my current Patch it is defined as:
> 
> .macro KVM_HANDLER ivor_nr scratch srr0
> _GLOBAL(kvmppc_handler_\ivor_nr)
>        /* Get pointer to vcpu and record exit number. */
>        mtspr   \scratch , r4
>        mfspr   r4, SPRN_SPRG_THREAD
>        lwz     r4, THREAD_KVM_VCPU(r4)

Move these into __KVM_HANDLER (aka: keep the code in there the same as KVM_HANDLER today)

>        __KVM_HANDLER \ivor_nr \scratch \srr0
> .endm
> 
> .macro KVM_DBG_HANDLER ivor_nr scratch srr0
> _GLOBAL(kvmppc_handler_\ivor_nr)
> 
> <<<<<<Debug related handling>>>>>
> 
> 1:      /* debug interrupt happened in guest */
>        mtcr    r3
>        mfspr   r4, SPRN_SPRG_THREAD
>        lwz     r4, THREAD_KVM_VCPU(r4)
>        lwz     r3, VCPU_CRIT_SAVE(r4)

Restore the state here as if a non-debug interrupt occurred. __KVM_HANDLER will fetch r4 itself from SPRG_THREAD.

I'm basically advocating to not optimize the debug case at all. Instead, I would prefer to have the exception ABI be identical to the fallback case ABI. That way we don't have to worry about 4 code paths, but only about 3, keeping the complexity of the code low.


Alex

>        __KVM_HANDLER \ivor_nr \scratch \srr0
> .endm
> 
> So the kvmppc_handler_\ivor_nr is defined and should always be at the start of exception handling?
> 
> So if KVM_DBG_HANDLER need to call KVM_HANDLER then there will be issue of 2 definition for DBG interrupt.
> 
> I am sorry but I did not understood how you want this to define. Can you please describe ?
> 
> Thanks
> -Bharat
> 
> 

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-02-04  0:41   ` Paul Mackerras
@ 2013-02-07 14:29     ` Alexander Graf
  2013-02-11  0:22       ` Paul Mackerras
  0 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 14:29 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Bharat Bhushan, kvm-ppc, kvm, Bharat Bhushan


On 04.02.2013, at 01:41, Paul Mackerras wrote:

> On Wed, Jan 16, 2013 at 01:54:41PM +0530, Bharat Bhushan wrote:
>> This patch adds the one_reg interface to get the special instruction
>> to be used for setting software breakpoint from userspace.
> 
> Since this presumably is constant for any given platform, wouldn't
> a capability be more appropriate?

How so? A capability only tells you "I can do debug". Or "I can do debug on e500". I don't want to reteach QEMU how to do debug for every core we implement.


Alex

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

* RE: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-02-07 14:21                   ` Alexander Graf
@ 2013-02-07 14:48                     ` Bhushan Bharat-R65777
  2013-02-07 15:01                       ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-07 14:48 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org

> >>>>>>>> -----Original Message-----
> >>>>>>>> From: Alexander Graf [mailto:agraf@suse.de]
> >>>>>>>> Sent: Friday, January 25, 2013 5:13 PM
> >>>>>>>> To: Bhushan Bharat-R65777
> >>>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
> >>>>>>>> Bharat-R65777
> >>>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
> >>>>>>>>
> >>>>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
> >>>>>>>>>
> >>>>>>>>> Installed debug handler will be used for guest debug support
> >>>>>>>>> and debug facility emulation features (patches for these
> >>>>>>>>> features will follow this patch).
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> >>>>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
> >>>>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
> >>>>>>>>> ---
> >>>>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
> >>>>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
> >>>>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49
> >> ++++++++++++++++++++++++++++++-
> >>>> --
> >>>>>> --
> >>>>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> index 8a72d59..f4ba881 100644
> >>>>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
> >>>>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
> >>>>>>>>> 	u32 tlbcfg[4];
> >>>>>>>>> 	u32 mmucfg;
> >>>>>>>>> 	u32 epr;
> >>>>>>>>> +	u32 crit_save;
> >>>>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
> >>>>>>>>> 	gpa_t paddr_accessed;
> >>>>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> index 46f6afd..02048f3 100644
> >>>>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
> >>>>>>>>> @@ -562,6 +562,7 @@ int main(void)
> >>>>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
> >>>>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu,
> >> arch.fault_dear));
> >>>>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
> >>>>>>>>> arch.fault_esr));
> >>>>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
> >>>>>>>>> +arch.crit_save));
> >>>>>>>>> #endif /* CONFIG_PPC_BOOK3S */ #endif /* CONFIG_KVM */
> >>>>>>>>>
> >>>>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> index eae8483..dd9c5d4 100644
> >>>>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
> >>>>>>>>> @@ -52,12 +52,7 @@
> >>>>>>>>>                    (1<<BOOKE_INTERRUPT_PROGRAM) | \
> >>>>>>>>>                    (1<<BOOKE_INTERRUPT_DTLB_MISS))
> >>>>>>>>>
> >>>>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> -	/* Get pointer to vcpu and record exit number. */
> >>>>>>>>> -	mtspr	\scratch , r4
> >>>>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
> >>>>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
> >>>>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
> >>>>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> 	bctr
> >>>>>>>>> .endm
> >>>>>>>>>
> >>>>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> +	/* Get pointer to vcpu and record exit number. */
> >>>>>>>>> +	mtspr	\scratch , r4
> >>>>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>>>> +
> >>>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>>>> +	mtspr   \scratch, r4
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	mfcr	r3
> >>>>>>>>> +	mfspr	r4, SPRN_CSRR1
> >>>>>>>>> +	andi.	r4, r4, MSR_PR
> >>>>>>>>> +	bne	1f
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> +	/* debug interrupt happened in enter/exit path */
> >>>>>>>>> +	mfspr   r4, SPRN_CSRR1
> >>>>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
> >>>>>>>>> +	mtspr   SPRN_CSRR1, r4
> >>>>>>>>> +	lis	r4, 0xffff
> >>>>>>>>> +	ori	r4, r4, 0xffff
> >>>>>>>>> +	mtspr	SPRN_DBSR, r4
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	mtcr	r3
> >>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	mfspr   r4, \scratch
> >>>>>>>>> +	rfci
> >>>>>>>>
> >>>>>>>> What is this part doing? Try to ignore the debug exit?
> >>>>>>>
> >>>>>>> As BOOKE doesn't have hardware support for virtualization,
> >>>>>>> hardware never know
> >>>>>> current pc is in guest or in host.
> >>>>>>> So when enable hardware single step for guest, it cannot be
> >>>>>>> disabled at the
> >>>>>> time guest exit. Thus, we'll see that an single step interrupt
> >>>>>> happens at the beginning of guest exit path.
> >>>>>>>
> >>>>>>> With the above code we recognize this kind of single step
> >>>>>>> interrupt disable
> >>>>>> single step and rfci.
> >>>>>>>
> >>>>>>>> Why would we have MSR_DE
> >>>>>>>> enabled in the first place when we can't handle it?
> >>>>>>>
> >>>>>>> When QEMU is using hardware debug resource then we always set
> >>>>>>> MSR_DE during
> >>>>>> guest is running.
> >>>>>>
> >>>>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
> >>>>>> wasn't set, you wouldn't get a single step exit.
> >>>>>
> >>>>> We always set MSR_DE in hw MSR when qemu using the debug resource.
> >>>>
> >>>> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't
> >>>> be set anymore, because we're in an interrupt handler, no? Or is
> >>>> MSR_DE kept alive on interrupts?
> >>>>
> >>>>>
> >>>>>> During the exit code path, you could then swap DBSR back to what
> >>>>>> the host expects (which means no single step). Only after that
> >>>>>> enable MSR_DE again.
> >>>>>
> >>>>> We do not support deferred debug interrupt, so we do save restore dbsr.
> >>>>>
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>>> +1:	/* debug interrupt happened in guest */
> >>>>>>>>> +	mtcr	r3
> >>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
> >>>>>>>>
> >>>>>>>> I don't think you need the __KVM_HANDLER split. This should be
> >>>>>>>> quite easily refactorable into a simple DBG prolog.
> >>>>>>>
> >>>>>>> Can you please elaborate how you are envisioning this?
> >>>>>>
> >>>>>> With this patch, you have
> >>>>>>
> >>>>>> KVM_HANLDER:
> >>>>>>
> >>>>>> <code>
> >>>>>> __KVM_HANDLER
> >>>>>>
> >>>>>> KVM_DBG_HANDLER:
> >>>>>>
> >>>>>> <code>
> >>>>>> __KVM_HANDLER
> >>>>>>
> >>>>>> Right?
> >>>>>>
> >>>>>> In KVM_HANDLER, you get:
> >>>>>>
> >>>>>>> .macro KVM_HANDLER ivor_nr scratch srr0
> >>>>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> 	/* Get pointer to vcpu and record exit number. */
> >>>>>>> 	mtspr	\scratch , r4
> >>>>>>> 	mfspr   r4, SPRN_SPRG_THREAD
> >>>>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
> >>>>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>
> >>>>>>
> >>>>>> while KVM_DBG_HANDLER is:
> >>>>>>
> >>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
> >>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
> >>>>>>> <debug specific handling>
> >>>>>>> +1:	/* debug interrupt happened in guest */
> >>>>>>> +	mtcr	r3
> >>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
> >>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
> >>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >>>>>>
> >>>>>>
> >>>>>> So if you write this as
> >>>>>>
> >>>>>> KVM_DBG_HANDLER:
> >>>>>> 	<debug specific handling>
> >>>>>> 	1:
> >>>>>> 	mtcr		r3
> >>>>>> 	mfspr	r4, SPRN_SPRG_THREAD
> >>>>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
> >>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>>>>> 	lwz		r4, \scratch
> >>>>>> 	<KVM_HANDLER>
> >>>>>>
> >>>>>> then you get code that is slower :) but it should be easier to
> >>>>>> read, since the interface between the individual pieces is always the
> same.
> >>>>>> Debug shouldn't be a fast path anyway, right?
> >>>>>
> >>>>> Frankly speaking I do not see much difference :).
> >>>>>
> >>>>> If we have to do as you mentioned then I think we can just do
> >>>>>
> >>>>> KVM_DBG_HANDLER:
> >>>>> 	<debug specific handling>
> >>>>> 	1:
> >>>>> 	mtcr		r3
> >>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
> >>>>> 	lwz		r4, \scratch
> >>>>> 	<KVM_HANDLER>
> >>>>
> >>>> Whatever it takes to keep the oddball (debug) an oddball and keep
> >>>> the normal case easy :).
> >>>
> >>> I think there will be another problem as  the
> >>> kvmppc_handler_\ivor_nr will not
> >> be the starting address which is required as per our ivor/ivpr usages
> >> for booke architecture.
> >>>
> >>> I am thinking of keeping as is :).
> >>
> >> How about we take a hybrid approach? You write the code as I
> >> described above, but call __KVM_HANDLER at the end. The normal KVM_HANDLER
> would look like:
> >>
> >> KVM_HANDLER:
> >> 	kvmppc_handler_\ivor_nr:
> >> 	__KVM_HANDLER ...
> >>
> >> That way the code should still be more understandable :)
> >>
> >
> > With my current Patch it is defined as:
> >
> > .macro KVM_HANDLER ivor_nr scratch srr0
> > _GLOBAL(kvmppc_handler_\ivor_nr)
> >        /* Get pointer to vcpu and record exit number. */
> >        mtspr   \scratch , r4
> >        mfspr   r4, SPRN_SPRG_THREAD
> >        lwz     r4, THREAD_KVM_VCPU(r4)
> 
> Move these into __KVM_HANDLER (aka: keep the code in there the same as
> KVM_HANDLER today)
> 
> >        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >
> > .macro KVM_DBG_HANDLER ivor_nr scratch srr0
> > _GLOBAL(kvmppc_handler_\ivor_nr)
> >
> > <<<<<<Debug related handling>>>>>
> >
> > 1:      /* debug interrupt happened in guest */
> >        mtcr    r3
> >        mfspr   r4, SPRN_SPRG_THREAD
> >        lwz     r4, THREAD_KVM_VCPU(r4)
> >        lwz     r3, VCPU_CRIT_SAVE(r4)
> 
> Restore the state here as if a non-debug interrupt occurred. __KVM_HANDLER will
> fetch r4 itself from SPRG_THREAD.
> 
> I'm basically advocating to not optimize the debug case at all. Instead, I would
> prefer to have the exception ABI be identical to the fallback case ABI. That way
> we don't have to worry about 4 code paths, but only about 3, keeping the
> complexity of the code low.
> 
> 
> Alex
> 
> >        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> >

Do you mean something like this ?

.macro __KVM_HANDLER
+        /* Get pointer to vcpu and record exit number. */
+        mtspr   \scratch , r4
+        mfspr   r4, SPRN_SPRG_THREAD
+        lwz     r4, THREAD_KVM_VCPU(r4)
 << Existing code >>


.macro KVM_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)
	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm




.macro KVM_DBG_HANDLER ivor_nr scratch srr0
_GLOBAL(kvmppc_handler_\ivor_nr)
<<<<<<Debug related handling>>>>>
1:      /* debug interrupt happened in guest */
        mtcr    r3
        mfspr   r4, SPRN_SPRG_THREAD
        lwz     r4, THREAD_KVM_VCPU(r4)
        lwz     r3, VCPU_CRIT_SAVE(r4)
	 lwz		r4, \scratch 
        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm


Thanks
-Bharat

> > So the kvmppc_handler_\ivor_nr is defined and should always be at the start of
> exception handling?
> >
> > So if KVM_DBG_HANDLER need to call KVM_HANDLER then there will be issue of 2
> definition for DBG interrupt.
> >
> > I am sorry but I did not understood how you want this to define. Can you
> please describe ?
> >
> > Thanks
> > -Bharat
> >
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body
> of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-01 22:38                           ` Scott Wood
  2013-02-04  4:48                             ` Bhushan Bharat-R65777
@ 2013-02-07 14:58                             ` Alexander Graf
  2013-02-07 15:25                               ` Bhushan Bharat-R65777
  2013-02-07 15:00                             ` Bhushan Bharat-R65777
  2 siblings, 1 reply; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 14:58 UTC (permalink / raw)
  To: Scott Wood
  Cc: Bhushan Bharat-R65777, kvm-ppc@vger.kernel.org,
	kvm@vger.kernel.org


On 01.02.2013, at 23:38, Scott Wood wrote:

> On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
>> On 31.01.2013, at 23:40, Scott Wood wrote:
>> > On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
>> >> On 31.01.2013, at 20:05, Alexander Graf wrote:
>> >> >
>> >> > On 31.01.2013, at 19:54, Scott Wood wrote:
>> >> >
>> >> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>> >> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
>> >> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>> >> >>>>> How about something like this? Then both targets at least suck as much :).
>> >> >>>>
>> >> >>>> I'm not sure that should be the goal...
>> >> >>>>
>> >> >>>>> Thanks to e500mc's awful hardware design, we don't know who sets the MSR_DE bit. Once we forced it onto the guest, we have no change to know whether the guest also set it or not. We could only guess.
>> >> >>>>
>> >> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we still need to set it in the first place.
>> >> >>>>
>> >> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let the guest know that the debug resources are not available, and that "the value of MSR[DE] is not specified and not modifiable".
>> >> >>> So what would the guest do then to tell the hypervisor that it actually wants to know about debug events?
>> >> >>
>> >> >> The guest is out of luck, just as if a JTAG were in use.
>> >> >
>> >> > Hrm.
>> >> >
>> >> > Can we somehow generalize this "out of luck" behavior?
>> >> >
>> >> > Every time we would set or clear an MSR bit in shadow_msr on e500v2, we would instead set or clear it in the real MSR. That way only e500mc is out of luck, but the code would still be shared.
>> >
>> > I don't follow.  e500v2 is just as out-of-luck.  The mechanism simply does not support sharing debug resources.
>> For e500v2 we have 2 fields
>>  * MSR as the guest sees it
>>  * MSR as we execute when the guest runs
>> Since we know the MSR when the guest sees it, we can decide what to do when we get an unhandled debug interrupt.
> 
> That's not the same thing as making the real MSR[DE] show up in the guest MSR[DE].
> 
> There are other problems with sharing -- what happens when both host and guest try to write to a particular IAC or DAC?
> 
> Also, performance would be pretty awful if the guest has e.g. single stepping in DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping (but does want debugging enabled in general).
> 
>> > What do you mean by "the real MSR"?  The real MSR is shadow_msr, and MSR_DE must always be set there if the host is debugging the guest.  As for reflecting it into the guest MSR, we could, but I don't really see the point.  We're never going to actually send a debug exception to the guest when the host owns the debug resources.
>> Why not? That's the whole point of jumping through user space.
> 
> That's still needed for software breakpoints, which don't rely on the debug resources.
> 
>>  1) guest exits with debug interrupt
>>  2) QEMU gets a debug exit
>>  3) QEMU checks in its list whether it belongs to its own debug points
>>  4) if not, it reinjects the interrupt into the guest
>> Step 4 is pretty difficult to do when we don't know whether the guest is actually capable of handling debug interrupts at that moment.
> 
> Software breakpoints take a Program interrupt rather than a Debug interrupt, unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
> 
>> > The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder to read.  I had to stare at it a while before noticing that you initially set is_debug from the guest MSR and that you'd never really clear MSR_DE here on bookehv.
>> Well, I'm mostly bouncing ideas here to find a way to express what we're trying to say in a way that someone who hasn't read this email thread would still understand what's going on :).
> 
> I think it's already straightforward enough if you accept that shared debug resources aren't supported, and that we are either in a mode where the real MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always on in guest mode and the guest MSR[DE] is irrelevant.

I think I'm starting to grasp what you're suggesting:

On e500mc, have 2 modes

  1) guest owns debug

  This is the normal operation. Here the guest defines the value of MSR_DE. The guest gets debug interrupts directly.

  2) host owns debug

  In this case, take away any debug capabilities from the guest. Everything debug related goes straight to QEMU.


On e500v2, have 2 modes

  1) guest owns debug

  This is the normal operation. Here the guest defines the value of MSR_DE. The guest gets debug interrupts directly.

  2) host and guest share debug

  We want to enable debug always. Guest and host debug desire DBCR, IAC, DAC registers are merged by QEMU. All debug events go to QEMU, QEMU reinjects interrupts when they really were meant for the guest.


The reason that the e500v2 approach doesn't work on e500mc is that e500mc doesn't support trapping MSR_DE writes.

Is there any foreseeable way in future hardware that the e500v2 way would work on HV capable chips as well? If not, we should probably just ditch that approach, make e500v2 as limited as e500mc and keep the code simple.

>From a kvm <-> user space interface point of view, we want to keep the door open for the e500v2 approach though, even though we wouldn't implement it for now.


Alex

> 
>> How about this version?
>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>> index 38a62ef..9929c41 100644
>> --- a/arch/powerpc/kvm/booke.c
>> +++ b/arch/powerpc/kvm/booke.c
>> @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu)
>> #endif
>> }
>> +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu)
>> +{
>> +#ifndef CONFIG_KVM_BOOKE_HV
>> +	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
>> +	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;
>> +#endif
>> +	}
>> +}
> 
> This shows "guest's desire to get debug interrupts" in a context that is not specifically for !vcpu->guest_debug, which is misleading.
> 
>> +
>> /*
>>  * Helper function for "full" MSR writes.  No need to call this if only
>>  * EE/CE/ME/DE/RI are changing.
>> @@ -150,6 +172,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,
>> My main concern here is that we don't know when to remove MSR_DE again from the (shadow) MSR. So how about this one instead?
> 
> Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove it } else { just copy whatever's in guest MSR }
> 
>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
>> index 38a62ef..2676703 100644
>> --- a/arch/powerpc/kvm/booke.c
>> +++ b/arch/powerpc/kvm/booke.c
>> @@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
>> 	u32 old_msr = vcpu->arch.shared->msr;
>> #ifdef CONFIG_KVM_BOOKE_HV
>> -	new_msr |= MSR_GS;
>> +	new_msr |= MSR_GS | MSR_DE;
>> #endif
>> 	vcpu->arch.shared->msr = new_msr;
>> That would semantically move e500mc to the same logic as e500v2. With the main difference that we have no idea what MSR_DE value the guest really wanted to have set.
> 
> This would break the case where the guest owns the debug resources.
> 
>> If I read the spec correctly, rfci traps.
> 
> rfdi is the relevant one for e500mc, but yes.
> 
>> So we know the time frame from [inject debug interrupt ... rfci]. During that time we know for sure that the guest thinks MSR_DE is 0.
> 
> No, we don't.  The guest could have tried to use mtmsr or rfi to enable MSR[DE].  It could have seen the context it came from was userspace, and scheduled to another process, etc.
> 
>> Outside of that context, we just have to assume the guest can always receive debug interrupts if it configured them.
> 
> No.
> 
> -Scott
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* RE: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-01 22:38                           ` Scott Wood
  2013-02-04  4:48                             ` Bhushan Bharat-R65777
  2013-02-07 14:58                             ` Alexander Graf
@ 2013-02-07 15:00                             ` Bhushan Bharat-R65777
  2013-02-07 15:08                               ` Alexander Graf
  2 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-07 15:00 UTC (permalink / raw)
  To: Wood Scott-B07421, Alexander Graf
  Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: Wood Scott-B07421
> Sent: Saturday, February 02, 2013 4:09 AM
> To: Alexander Graf
> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
> 
> On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
> >
> > On 31.01.2013, at 23:40, Scott Wood wrote:
> >
> > > On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
> > >> On 31.01.2013, at 20:05, Alexander Graf wrote:
> > >> >
> > >> > On 31.01.2013, at 19:54, Scott Wood wrote:
> > >> >
> > >> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> > >> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
> > >> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> > >> >>>>> How about something like this? Then both targets at least
> > suck as much :).
> > >> >>>>
> > >> >>>> I'm not sure that should be the goal...
> > >> >>>>
> > >> >>>>> Thanks to e500mc's awful hardware design, we don't know who
> > sets the MSR_DE bit. Once we forced it onto the guest, we have no
> > change to know whether the guest also set it or not. We could only
> > guess.
> > >> >>>>
> > >> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but
> > we still need to set it in the first place.
> > >> >>>>
> > >> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM]
> > to let the guest know that the debug resources are not available, and
> > that "the value of MSR[DE] is not specified and not modifiable".
> > >> >>> So what would the guest do then to tell the hypervisor that it
> > actually wants to know about debug events?
> > >> >>
> > >> >> The guest is out of luck, just as if a JTAG were in use.
> > >> >
> > >> > Hrm.
> > >> >
> > >> > Can we somehow generalize this "out of luck" behavior?
> > >> >
> > >> > Every time we would set or clear an MSR bit in shadow_msr on
> > e500v2, we would instead set or clear it in the real MSR. That way
> > only e500mc is out of luck, but the code would still be shared.
> > >
> > > I don't follow.  e500v2 is just as out-of-luck.  The mechanism
> > simply does not support sharing debug resources.
> >
> > For e500v2 we have 2 fields
> >
> >   * MSR as the guest sees it
> >   * MSR as we execute when the guest runs
> >
> > Since we know the MSR when the guest sees it, we can decide what to do
> > when we get an unhandled debug interrupt.
> 
> That's not the same thing as making the real MSR[DE] show up in the guest
> MSR[DE].
> 
> There are other problems with sharing -- what happens when both host and guest
> try to write to a particular IAC or DAC?
> 
> Also, performance would be pretty awful if the guest has e.g. single stepping in
> DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping
> (but does want debugging enabled in general).
> 
> > > What do you mean by "the real MSR"?  The real MSR is shadow_msr,
> > and MSR_DE must always be set there if the host is debugging the
> > guest.  As for reflecting it into the guest MSR, we could, but I don't
> > really see the point.  We're never going to actually send a debug
> > exception to the guest when the host owns the debug resources.
> >
> > Why not? That's the whole point of jumping through user space.
> 
> That's still needed for software breakpoints, which don't rely on the debug
> resources.
> 
> >   1) guest exits with debug interrupt
> >   2) QEMU gets a debug exit
> >   3) QEMU checks in its list whether it belongs to its own debug
> > points
> >   4) if not, it reinjects the interrupt into the guest
> >
> > Step 4 is pretty difficult to do when we don't know whether the guest
> > is actually capable of handling debug interrupts at that moment.
> 
> Software breakpoints take a Program interrupt rather than a Debug interrupt,
> unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources
> we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
> 
> > > The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder
> > to read.  I had to stare at it a while before noticing that you
> > initially set is_debug from the guest MSR and that you'd never really
> > clear MSR_DE here on bookehv.
> >
> > Well, I'm mostly bouncing ideas here to find a way to express what
> > we're trying to say in a way that someone who hasn't read this email
> > thread would still understand what's going on :).
> 
> I think it's already straightforward enough if you accept that shared debug
> resources aren't supported, and that we are either in a mode where the real
> MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always
> on in guest mode and the guest MSR[DE] is irrelevant.
> 
> > How about this version?
> >
> >
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 38a62ef..9929c41 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
> > *vcpu)
> >  #endif
> >  }
> >
> > +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { #ifndef
> > +CONFIG_KVM_BOOKE_HV
> > +	/* Synchronize guest's desire to get debug interrupts into
> > shadow MSR */
> > +	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;
> > +#endif
> > +	}
> > +}
> 
> This shows "guest's desire to get debug interrupts" in a context that is not
> specifically for !vcpu->guest_debug, which is misleading.
> 
> > +
> >  /*
> >   * Helper function for "full" MSR writes.  No need to call this if
> > only
> >   * EE/CE/ME/DE/RI are changing.
> > @@ -150,6 +172,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,
> >
> >
> > My main concern here is that we don't know when to remove MSR_DE again
> > from the (shadow) MSR. So how about this one instead?
> 
> Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove it } else
> { just copy whatever's in guest MSR }

Once MSR_DE set because of vcpu->guest_debug, it will remains set even if vcpu->guest_debug is not set, until guest clears msr_de itself. And guest may not clear MSR_DE because it have never set it.

Thanks
-Bharat

> 
> > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
> > 38a62ef..2676703 100644
> > --- a/arch/powerpc/kvm/booke.c
> > +++ b/arch/powerpc/kvm/booke.c
> > @@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32
> > new_msr)
> >  	u32 old_msr = vcpu->arch.shared->msr;
> >
> >  #ifdef CONFIG_KVM_BOOKE_HV
> > -	new_msr |= MSR_GS;
> > +	new_msr |= MSR_GS | MSR_DE;
> >  #endif
> >
> >  	vcpu->arch.shared->msr = new_msr;
> >
> >
> > That would semantically move e500mc to the same logic as e500v2. With
> > the main difference that we have no idea what MSR_DE value the guest
> > really wanted to have set.
> 
> This would break the case where the guest owns the debug resources.
> 
> > If I read the spec correctly, rfci traps.
> 
> rfdi is the relevant one for e500mc, but yes.
> 
> > So we know the time frame from [inject debug interrupt ... rfci].
> > During that time we know for sure that the guest thinks MSR_DE is 0.
> 
> No, we don't.  The guest could have tried to use mtmsr or rfi to enable MSR[DE].
> It could have seen the context it came from was userspace, and scheduled to
> another process, etc.
> 
> > Outside of that context, we just have to assume the guest can always
> > receive debug interrupts if it configured them.
> 
> No.
> 
> -Scott


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

* Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
  2013-02-07 14:48                     ` Bhushan Bharat-R65777
@ 2013-02-07 15:01                       ` Alexander Graf
  0 siblings, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 15:01 UTC (permalink / raw)
  To: Bhushan Bharat-R65777; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 07.02.2013, at 15:48, Bhushan Bharat-R65777 wrote:

>>>>>>>>>> -----Original Message-----
>>>>>>>>>> From: Alexander Graf [mailto:agraf@suse.de]
>>>>>>>>>> Sent: Friday, January 25, 2013 5:13 PM
>>>>>>>>>> To: Bhushan Bharat-R65777
>>>>>>>>>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; Bhushan
>>>>>>>>>> Bharat-R65777
>>>>>>>>>> Subject: Re: [PATCH 3/8] KVM: PPC: booke: Added debug handler
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On 16.01.2013, at 09:24, Bharat Bhushan wrote:
>>>>>>>>>> 
>>>>>>>>>>> From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
>>>>>>>>>>> 
>>>>>>>>>>> Installed debug handler will be used for guest debug support
>>>>>>>>>>> and debug facility emulation features (patches for these
>>>>>>>>>>> features will follow this patch).
>>>>>>>>>>> 
>>>>>>>>>>> Signed-off-by: Liu Yu <yu.liu@freescale.com>
>>>>>>>>>>> [bharat.bhushan@freescale.com: Substantial changes]
>>>>>>>>>>> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
>>>>>>>>>>> ---
>>>>>>>>>>> arch/powerpc/include/asm/kvm_host.h |    1 +
>>>>>>>>>>> arch/powerpc/kernel/asm-offsets.c   |    1 +
>>>>>>>>>>> arch/powerpc/kvm/booke_interrupts.S |   49
>>>> ++++++++++++++++++++++++++++++-
>>>>>> --
>>>>>>>> --
>>>>>>>>>>> 3 files changed, 44 insertions(+), 7 deletions(-)
>>>>>>>>>>> 
>>>>>>>>>>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>>>> b/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>>>> index 8a72d59..f4ba881 100644
>>>>>>>>>>> --- a/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>>>> +++ b/arch/powerpc/include/asm/kvm_host.h
>>>>>>>>>>> @@ -503,6 +503,7 @@ struct kvm_vcpu_arch {
>>>>>>>>>>> 	u32 tlbcfg[4];
>>>>>>>>>>> 	u32 mmucfg;
>>>>>>>>>>> 	u32 epr;
>>>>>>>>>>> +	u32 crit_save;
>>>>>>>>>>> 	struct kvmppc_booke_debug_reg dbg_reg; #endif
>>>>>>>>>>> 	gpa_t paddr_accessed;
>>>>>>>>>>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>>>> b/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>>>> index 46f6afd..02048f3 100644
>>>>>>>>>>> --- a/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>>>> +++ b/arch/powerpc/kernel/asm-offsets.c
>>>>>>>>>>> @@ -562,6 +562,7 @@ int main(void)
>>>>>>>>>>> 	DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
>>>>>>>>>>> 	DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu,
>>>> arch.fault_dear));
>>>>>>>>>>> 	DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu,
>>>>>>>>>>> arch.fault_esr));
>>>>>>>>>>> +	DEFINE(VCPU_CRIT_SAVE, offsetof(struct kvm_vcpu,
>>>>>>>>>>> +arch.crit_save));
>>>>>>>>>>> #endif /* CONFIG_PPC_BOOK3S */ #endif /* CONFIG_KVM */
>>>>>>>>>>> 
>>>>>>>>>>> diff --git a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>>>> b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>>>> index eae8483..dd9c5d4 100644
>>>>>>>>>>> --- a/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>>>> +++ b/arch/powerpc/kvm/booke_interrupts.S
>>>>>>>>>>> @@ -52,12 +52,7 @@
>>>>>>>>>>>                   (1<<BOOKE_INTERRUPT_PROGRAM) | \
>>>>>>>>>>>                   (1<<BOOKE_INTERRUPT_DTLB_MISS))
>>>>>>>>>>> 
>>>>>>>>>>> -.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>>>> -_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>>>> -	/* Get pointer to vcpu and record exit number. */
>>>>>>>>>>> -	mtspr	\scratch , r4
>>>>>>>>>>> -	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>>>>>> -	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>>>>>> +.macro __KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>>>> 	stw	r3, VCPU_GPR(R3)(r4)
>>>>>>>>>>> 	stw	r5, VCPU_GPR(R5)(r4)
>>>>>>>>>>> 	stw	r6, VCPU_GPR(R6)(r4)
>>>>>>>>>>> @@ -74,6 +69,46 @@ _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>>>> 	bctr
>>>>>>>>>>> .endm
>>>>>>>>>>> 
>>>>>>>>>>> +.macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>>>> +	/* Get pointer to vcpu and record exit number. */
>>>>>>>>>>> +	mtspr	\scratch , r4
>>>>>>>>>>> +	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>>>>>> +	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>>>>>>> +
>>>>>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>>>> +	mtspr   \scratch, r4
>>>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>>>> +	stw	r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>>>> +	mfcr	r3
>>>>>>>>>>> +	mfspr	r4, SPRN_CSRR1
>>>>>>>>>>> +	andi.	r4, r4, MSR_PR
>>>>>>>>>>> +	bne	1f
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> +	/* debug interrupt happened in enter/exit path */
>>>>>>>>>>> +	mfspr   r4, SPRN_CSRR1
>>>>>>>>>>> +	rlwinm  r4, r4, 0, ~MSR_DE
>>>>>>>>>>> +	mtspr   SPRN_CSRR1, r4
>>>>>>>>>>> +	lis	r4, 0xffff
>>>>>>>>>>> +	ori	r4, r4, 0xffff
>>>>>>>>>>> +	mtspr	SPRN_DBSR, r4
>>>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>>>> +	mtcr	r3
>>>>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>>>> +	mfspr   r4, \scratch
>>>>>>>>>>> +	rfci
>>>>>>>>>> 
>>>>>>>>>> What is this part doing? Try to ignore the debug exit?
>>>>>>>>> 
>>>>>>>>> As BOOKE doesn't have hardware support for virtualization,
>>>>>>>>> hardware never know
>>>>>>>> current pc is in guest or in host.
>>>>>>>>> So when enable hardware single step for guest, it cannot be
>>>>>>>>> disabled at the
>>>>>>>> time guest exit. Thus, we'll see that an single step interrupt
>>>>>>>> happens at the beginning of guest exit path.
>>>>>>>>> 
>>>>>>>>> With the above code we recognize this kind of single step
>>>>>>>>> interrupt disable
>>>>>>>> single step and rfci.
>>>>>>>>> 
>>>>>>>>>> Why would we have MSR_DE
>>>>>>>>>> enabled in the first place when we can't handle it?
>>>>>>>>> 
>>>>>>>>> When QEMU is using hardware debug resource then we always set
>>>>>>>>> MSR_DE during
>>>>>>>> guest is running.
>>>>>>>> 
>>>>>>>> Right, but why is MSR_DE enabled during the exit path? If MSR_DE
>>>>>>>> wasn't set, you wouldn't get a single step exit.
>>>>>>> 
>>>>>>> We always set MSR_DE in hw MSR when qemu using the debug resource.
>>>>>> 
>>>>>> In the _guest_ MSR, yes. But once we exit the guest, it shouldn't
>>>>>> be set anymore, because we're in an interrupt handler, no? Or is
>>>>>> MSR_DE kept alive on interrupts?
>>>>>> 
>>>>>>> 
>>>>>>>> During the exit code path, you could then swap DBSR back to what
>>>>>>>> the host expects (which means no single step). Only after that
>>>>>>>> enable MSR_DE again.
>>>>>>> 
>>>>>>> We do not support deferred debug interrupt, so we do save restore dbsr.
>>>>>>> 
>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>> +1:	/* debug interrupt happened in guest */
>>>>>>>>>>> +	mtcr	r3
>>>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0
>>>>>>>>>> 
>>>>>>>>>> I don't think you need the __KVM_HANDLER split. This should be
>>>>>>>>>> quite easily refactorable into a simple DBG prolog.
>>>>>>>>> 
>>>>>>>>> Can you please elaborate how you are envisioning this?
>>>>>>>> 
>>>>>>>> With this patch, you have
>>>>>>>> 
>>>>>>>> KVM_HANLDER:
>>>>>>>> 
>>>>>>>> <code>
>>>>>>>> __KVM_HANDLER
>>>>>>>> 
>>>>>>>> KVM_DBG_HANDLER:
>>>>>>>> 
>>>>>>>> <code>
>>>>>>>> __KVM_HANDLER
>>>>>>>> 
>>>>>>>> Right?
>>>>>>>> 
>>>>>>>> In KVM_HANDLER, you get:
>>>>>>>> 
>>>>>>>>> .macro KVM_HANDLER ivor_nr scratch srr0
>>>>>>>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> 	/* Get pointer to vcpu and record exit number. */
>>>>>>>>> 	mtspr	\scratch , r4
>>>>>>>>> 	mfspr   r4, SPRN_SPRG_THREAD
>>>>>>>>> 	lwz     r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>>>> 
>>>>>>>> 
>>>>>>>> while KVM_DBG_HANDLER is:
>>>>>>>> 
>>>>>>>>> +.macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>>>>>>>> +_GLOBAL(kvmppc_handler_\ivor_nr)
>>>>>>>>> <debug specific handling>
>>>>>>>>> +1:	/* debug interrupt happened in guest */
>>>>>>>>> +	mtcr	r3
>>>>>>>>> +	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>>> +	lwz	r4, THREAD_KVM_VCPU(r4)
>>>>>>>>> +	lwz     r3, VCPU_CRIT_SAVE(r4)
>>>>>>>>> +	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>>>>>>> 
>>>>>>>> 
>>>>>>>> So if you write this as
>>>>>>>> 
>>>>>>>> KVM_DBG_HANDLER:
>>>>>>>> 	<debug specific handling>
>>>>>>>> 	1:
>>>>>>>> 	mtcr		r3
>>>>>>>> 	mfspr	r4, SPRN_SPRG_THREAD
>>>>>>>> 	lwz		r4, THREAD_KVM_VCPU(r4)
>>>>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>>>>>>> 	lwz		r4, \scratch
>>>>>>>> 	<KVM_HANDLER>
>>>>>>>> 
>>>>>>>> then you get code that is slower :) but it should be easier to
>>>>>>>> read, since the interface between the individual pieces is always the
>> same.
>>>>>>>> Debug shouldn't be a fast path anyway, right?
>>>>>>> 
>>>>>>> Frankly speaking I do not see much difference :).
>>>>>>> 
>>>>>>> If we have to do as you mentioned then I think we can just do
>>>>>>> 
>>>>>>> KVM_DBG_HANDLER:
>>>>>>> 	<debug specific handling>
>>>>>>> 	1:
>>>>>>> 	mtcr		r3
>>>>>>> 	lwz		r3, VCPU_CRIT_SAVE(r4)
>>>>>>> 	lwz		r4, \scratch
>>>>>>> 	<KVM_HANDLER>
>>>>>> 
>>>>>> Whatever it takes to keep the oddball (debug) an oddball and keep
>>>>>> the normal case easy :).
>>>>> 
>>>>> I think there will be another problem as  the
>>>>> kvmppc_handler_\ivor_nr will not
>>>> be the starting address which is required as per our ivor/ivpr usages
>>>> for booke architecture.
>>>>> 
>>>>> I am thinking of keeping as is :).
>>>> 
>>>> How about we take a hybrid approach? You write the code as I
>>>> described above, but call __KVM_HANDLER at the end. The normal KVM_HANDLER
>> would look like:
>>>> 
>>>> KVM_HANDLER:
>>>> 	kvmppc_handler_\ivor_nr:
>>>> 	__KVM_HANDLER ...
>>>> 
>>>> That way the code should still be more understandable :)
>>>> 
>>> 
>>> With my current Patch it is defined as:
>>> 
>>> .macro KVM_HANDLER ivor_nr scratch srr0
>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>>       /* Get pointer to vcpu and record exit number. */
>>>       mtspr   \scratch , r4
>>>       mfspr   r4, SPRN_SPRG_THREAD
>>>       lwz     r4, THREAD_KVM_VCPU(r4)
>> 
>> Move these into __KVM_HANDLER (aka: keep the code in there the same as
>> KVM_HANDLER today)
>> 
>>>       __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>> 
>>> .macro KVM_DBG_HANDLER ivor_nr scratch srr0
>>> _GLOBAL(kvmppc_handler_\ivor_nr)
>>> 
>>> <<<<<<Debug related handling>>>>>
>>> 
>>> 1:      /* debug interrupt happened in guest */
>>>       mtcr    r3
>>>       mfspr   r4, SPRN_SPRG_THREAD
>>>       lwz     r4, THREAD_KVM_VCPU(r4)
>>>       lwz     r3, VCPU_CRIT_SAVE(r4)
>> 
>> Restore the state here as if a non-debug interrupt occurred. __KVM_HANDLER will
>> fetch r4 itself from SPRG_THREAD.
>> 
>> I'm basically advocating to not optimize the debug case at all. Instead, I would
>> prefer to have the exception ABI be identical to the fallback case ABI. That way
>> we don't have to worry about 4 code paths, but only about 3, keeping the
>> complexity of the code low.
>> 
>> 
>> Alex
>> 
>>>       __KVM_HANDLER \ivor_nr \scratch \srr0 .endm
>>> 
> 
> Do you mean something like this ?
> 
> .macro __KVM_HANDLER
> +        /* Get pointer to vcpu and record exit number. */
> +        mtspr   \scratch , r4
> +        mfspr   r4, SPRN_SPRG_THREAD
> +        lwz     r4, THREAD_KVM_VCPU(r4)

This wouldn't be a +, but rather just stay the exact same code as it is, right? :)

> << Existing code >>
> 
> 
> .macro KVM_HANDLER ivor_nr scratch srr0
> _GLOBAL(kvmppc_handler_\ivor_nr)
> 	__KVM_HANDLER \ivor_nr \scratch \srr0 .endm
> 
> 
> 
> 
> .macro KVM_DBG_HANDLER ivor_nr scratch srr0
> _GLOBAL(kvmppc_handler_\ivor_nr)
> <<<<<<Debug related handling>>>>>
> 1:      /* debug interrupt happened in guest */
>        mtcr    r3
>        mfspr   r4, SPRN_SPRG_THREAD
>        lwz     r4, THREAD_KVM_VCPU(r4)
>        lwz     r3, VCPU_CRIT_SAVE(r4)

You need to swap the above 2 operations.

> 	 lwz		r4, \scratch 

s/lwz/mfspr/

>        __KVM_HANDLER \ivor_nr \scratch \srr0 .endm

Otherwise, pretty much, yeah :)


Alex

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-07 15:00                             ` Bhushan Bharat-R65777
@ 2013-02-07 15:08                               ` Alexander Graf
  0 siblings, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 15:08 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 07.02.2013, at 16:00, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: Wood Scott-B07421
>> Sent: Saturday, February 02, 2013 4:09 AM
>> To: Alexander Graf
>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
>> 
>> On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
>>> 
>>> On 31.01.2013, at 23:40, Scott Wood wrote:
>>> 
>>>> On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
>>>>> On 31.01.2013, at 20:05, Alexander Graf wrote:
>>>>>> 
>>>>>> On 31.01.2013, at 19:54, Scott Wood wrote:
>>>>>> 
>>>>>>> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>>>>>>>> On 31.01.2013, at 19:43, Scott Wood wrote:
>>>>>>>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>>>>>>>>>> How about something like this? Then both targets at least
>>> suck as much :).
>>>>>>>>> 
>>>>>>>>> I'm not sure that should be the goal...
>>>>>>>>> 
>>>>>>>>>> Thanks to e500mc's awful hardware design, we don't know who
>>> sets the MSR_DE bit. Once we forced it onto the guest, we have no
>>> change to know whether the guest also set it or not. We could only
>>> guess.
>>>>>>>>> 
>>>>>>>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but
>>> we still need to set it in the first place.
>>>>>>>>> 
>>>>>>>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM]
>>> to let the guest know that the debug resources are not available, and
>>> that "the value of MSR[DE] is not specified and not modifiable".
>>>>>>>> So what would the guest do then to tell the hypervisor that it
>>> actually wants to know about debug events?
>>>>>>> 
>>>>>>> The guest is out of luck, just as if a JTAG were in use.
>>>>>> 
>>>>>> Hrm.
>>>>>> 
>>>>>> Can we somehow generalize this "out of luck" behavior?
>>>>>> 
>>>>>> Every time we would set or clear an MSR bit in shadow_msr on
>>> e500v2, we would instead set or clear it in the real MSR. That way
>>> only e500mc is out of luck, but the code would still be shared.
>>>> 
>>>> I don't follow.  e500v2 is just as out-of-luck.  The mechanism
>>> simply does not support sharing debug resources.
>>> 
>>> For e500v2 we have 2 fields
>>> 
>>>  * MSR as the guest sees it
>>>  * MSR as we execute when the guest runs
>>> 
>>> Since we know the MSR when the guest sees it, we can decide what to do
>>> when we get an unhandled debug interrupt.
>> 
>> That's not the same thing as making the real MSR[DE] show up in the guest
>> MSR[DE].
>> 
>> There are other problems with sharing -- what happens when both host and guest
>> try to write to a particular IAC or DAC?
>> 
>> Also, performance would be pretty awful if the guest has e.g. single stepping in
>> DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping
>> (but does want debugging enabled in general).
>> 
>>>> What do you mean by "the real MSR"?  The real MSR is shadow_msr,
>>> and MSR_DE must always be set there if the host is debugging the
>>> guest.  As for reflecting it into the guest MSR, we could, but I don't
>>> really see the point.  We're never going to actually send a debug
>>> exception to the guest when the host owns the debug resources.
>>> 
>>> Why not? That's the whole point of jumping through user space.
>> 
>> That's still needed for software breakpoints, which don't rely on the debug
>> resources.
>> 
>>>  1) guest exits with debug interrupt
>>>  2) QEMU gets a debug exit
>>>  3) QEMU checks in its list whether it belongs to its own debug
>>> points
>>>  4) if not, it reinjects the interrupt into the guest
>>> 
>>> Step 4 is pretty difficult to do when we don't know whether the guest
>>> is actually capable of handling debug interrupts at that moment.
>> 
>> Software breakpoints take a Program interrupt rather than a Debug interrupt,
>> unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources
>> we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
>> 
>>>> The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder
>>> to read.  I had to stare at it a while before noticing that you
>>> initially set is_debug from the guest MSR and that you'd never really
>>> clear MSR_DE here on bookehv.
>>> 
>>> Well, I'm mostly bouncing ideas here to find a way to express what
>>> we're trying to say in a way that someone who hasn't read this email
>>> thread would still understand what's going on :).
>> 
>> I think it's already straightforward enough if you accept that shared debug
>> resources aren't supported, and that we are either in a mode where the real
>> MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always
>> on in guest mode and the guest MSR[DE] is irrelevant.
>> 
>>> How about this version?
>>> 
>>> 
>>> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index
>>> 38a62ef..9929c41 100644
>>> --- a/arch/powerpc/kvm/booke.c
>>> +++ b/arch/powerpc/kvm/booke.c
>>> @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
>>> *vcpu)
>>> #endif
>>> }
>>> 
>>> +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { #ifndef
>>> +CONFIG_KVM_BOOKE_HV
>>> +	/* Synchronize guest's desire to get debug interrupts into
>>> shadow MSR */
>>> +	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;
>>> +#endif
>>> +	}
>>> +}
>> 
>> This shows "guest's desire to get debug interrupts" in a context that is not
>> specifically for !vcpu->guest_debug, which is misleading.
>> 
>>> +
>>> /*
>>>  * Helper function for "full" MSR writes.  No need to call this if
>>> only
>>>  * EE/CE/ME/DE/RI are changing.
>>> @@ -150,6 +172,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,
>>> 
>>> 
>>> My main concern here is that we don't know when to remove MSR_DE again
>>> from the (shadow) MSR. So how about this one instead?
>> 
>> Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove it } else
>> { just copy whatever's in guest MSR }
> 
> Once MSR_DE set because of vcpu->guest_debug, it will remains set even if vcpu->guest_debug is not set, until guest clears msr_de itself. And guest may not clear MSR_DE because it have never set it.

That would create a time frame where the guest maybe doesn't want debug interrupts, but would get them. I'm not sure how bad that would be though.


Alex


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

* RE: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-07 14:58                             ` Alexander Graf
@ 2013-02-07 15:25                               ` Bhushan Bharat-R65777
  2013-02-07 15:53                                 ` Alexander Graf
  0 siblings, 1 reply; 59+ messages in thread
From: Bhushan Bharat-R65777 @ 2013-02-07 15:25 UTC (permalink / raw)
  To: Alexander Graf, Wood Scott-B07421
  Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org



> -----Original Message-----
> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
> Behalf Of Alexander Graf
> Sent: Thursday, February 07, 2013 8:29 PM
> To: Wood Scott-B07421
> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
> 
> 
> On 01.02.2013, at 23:38, Scott Wood wrote:
> 
> > On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
> >> On 31.01.2013, at 23:40, Scott Wood wrote:
> >> > On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
> >> >> On 31.01.2013, at 20:05, Alexander Graf wrote:
> >> >> >
> >> >> > On 31.01.2013, at 19:54, Scott Wood wrote:
> >> >> >
> >> >> >> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
> >> >> >>> On 31.01.2013, at 19:43, Scott Wood wrote:
> >> >> >>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
> >> >> >>>>> How about something like this? Then both targets at least suck as
> much :).
> >> >> >>>>
> >> >> >>>> I'm not sure that should be the goal...
> >> >> >>>>
> >> >> >>>>> Thanks to e500mc's awful hardware design, we don't know who sets the
> MSR_DE bit. Once we forced it onto the guest, we have no change to know whether
> the guest also set it or not. We could only guess.
> >> >> >>>>
> >> >> >>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we
> still need to set it in the first place.
> >> >> >>>>
> >> >> >>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let
> the guest know that the debug resources are not available, and that "the value
> of MSR[DE] is not specified and not modifiable".
> >> >> >>> So what would the guest do then to tell the hypervisor that it
> actually wants to know about debug events?
> >> >> >>
> >> >> >> The guest is out of luck, just as if a JTAG were in use.
> >> >> >
> >> >> > Hrm.
> >> >> >
> >> >> > Can we somehow generalize this "out of luck" behavior?
> >> >> >
> >> >> > Every time we would set or clear an MSR bit in shadow_msr on e500v2, we
> would instead set or clear it in the real MSR. That way only e500mc is out of
> luck, but the code would still be shared.
> >> >
> >> > I don't follow.  e500v2 is just as out-of-luck.  The mechanism simply does
> not support sharing debug resources.
> >> For e500v2 we have 2 fields
> >>  * MSR as the guest sees it
> >>  * MSR as we execute when the guest runs Since we know the MSR when
> >> the guest sees it, we can decide what to do when we get an unhandled debug
> interrupt.
> >
> > That's not the same thing as making the real MSR[DE] show up in the guest
> MSR[DE].
> >
> > There are other problems with sharing -- what happens when both host and guest
> try to write to a particular IAC or DAC?
> >
> > Also, performance would be pretty awful if the guest has e.g. single stepping
> in DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping
> (but does want debugging enabled in general).
> >
> >> > What do you mean by "the real MSR"?  The real MSR is shadow_msr, and MSR_DE
> must always be set there if the host is debugging the guest.  As for reflecting
> it into the guest MSR, we could, but I don't really see the point.  We're never
> going to actually send a debug exception to the guest when the host owns the
> debug resources.
> >> Why not? That's the whole point of jumping through user space.
> >
> > That's still needed for software breakpoints, which don't rely on the debug
> resources.
> >
> >>  1) guest exits with debug interrupt
> >>  2) QEMU gets a debug exit
> >>  3) QEMU checks in its list whether it belongs to its own debug
> >> points
> >>  4) if not, it reinjects the interrupt into the guest Step 4 is
> >> pretty difficult to do when we don't know whether the guest is actually
> capable of handling debug interrupts at that moment.
> >
> > Software breakpoints take a Program interrupt rather than a Debug interrupt,
> unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources
> we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
> >
> >> > The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder to read.
> I had to stare at it a while before noticing that you initially set is_debug
> from the guest MSR and that you'd never really clear MSR_DE here on bookehv.
> >> Well, I'm mostly bouncing ideas here to find a way to express what we're
> trying to say in a way that someone who hasn't read this email thread would
> still understand what's going on :).
> >
> > I think it's already straightforward enough if you accept that shared debug
> resources aren't supported, and that we are either in a mode where the real
> MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always
> on in guest mode and the guest MSR[DE] is irrelevant.
> 
> I think I'm starting to grasp what you're suggesting:
> 
> On e500mc, have 2 modes
> 
>   1) guest owns debug
> 
>   This is the normal operation. Here the guest defines the value of MSR_DE. The
> guest gets debug interrupts directly.
> 
>   2) host owns debug
> 
>   In this case, take away any debug capabilities from the guest. Everything
> debug related goes straight to QEMU.
> 
> 
> On e500v2, have 2 modes
> 
>   1) guest owns debug
> 
>   This is the normal operation. Here the guest defines the value of MSR_DE. The
> guest gets debug interrupts directly.
> 
>   2) host and guest share debug

We are not allowing the sharing, it is same as (2) in e500mc.

Thanks
-Bharat

> 
>   We want to enable debug always. Guest and host debug desire DBCR, IAC, DAC
> registers are merged by QEMU. All debug events go to QEMU, QEMU reinjects
> interrupts when they really were meant for the guest.
> 
> 
> The reason that the e500v2 approach doesn't work on e500mc is that e500mc
> doesn't support trapping MSR_DE writes.
> 
> Is there any foreseeable way in future hardware that the e500v2 way would work
> on HV capable chips as well? If not, we should probably just ditch that
> approach, make e500v2 as limited as e500mc and keep the code simple.
> 
> From a kvm <-> user space interface point of view, we want to keep the door open
> for the e500v2 approach though, even though we wouldn't implement it for now.
> 
> 
> Alex
> 
> >
> >> How about this version?
> >> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >> index 38a62ef..9929c41 100644
> >> --- a/arch/powerpc/kvm/booke.c
> >> +++ b/arch/powerpc/kvm/booke.c
> >> @@ -133,6 +133,28 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu
> >> *vcpu) #endif }
> >> +static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { #ifndef
> >> +CONFIG_KVM_BOOKE_HV
> >> +	/* Synchronize guest's desire to get debug interrupts into shadow MSR */
> >> +	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;
> >> +#endif
> >> +	}
> >> +}
> >
> > This shows "guest's desire to get debug interrupts" in a context that is not
> specifically for !vcpu->guest_debug, which is misleading.
> >
> >> +
> >> /*
> >>  * Helper function for "full" MSR writes.  No need to call this if
> >> only
> >>  * EE/CE/ME/DE/RI are changing.
> >> @@ -150,6 +172,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, My main
> >> concern here is that we don't know when to remove MSR_DE again from the
> (shadow) MSR. So how about this one instead?
> >
> > Why wouldn't you know this?  if (vcpu->guest_debug) { you never remove
> > it } else { just copy whatever's in guest MSR }
> >
> >> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> >> index 38a62ef..2676703 100644
> >> --- a/arch/powerpc/kvm/booke.c
> >> +++ b/arch/powerpc/kvm/booke.c
> >> @@ -142,7 +142,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
> >> 	u32 old_msr = vcpu->arch.shared->msr; #ifdef CONFIG_KVM_BOOKE_HV
> >> -	new_msr |= MSR_GS;
> >> +	new_msr |= MSR_GS | MSR_DE;
> >> #endif
> >> 	vcpu->arch.shared->msr = new_msr;
> >> That would semantically move e500mc to the same logic as e500v2. With the
> main difference that we have no idea what MSR_DE value the guest really wanted
> to have set.
> >
> > This would break the case where the guest owns the debug resources.
> >
> >> If I read the spec correctly, rfci traps.
> >
> > rfdi is the relevant one for e500mc, but yes.
> >
> >> So we know the time frame from [inject debug interrupt ... rfci]. During that
> time we know for sure that the guest thinks MSR_DE is 0.
> >
> > No, we don't.  The guest could have tried to use mtmsr or rfi to enable
> MSR[DE].  It could have seen the context it came from was userspace, and
> scheduled to another process, etc.
> >
> >> Outside of that context, we just have to assume the guest can always receive
> debug interrupts if it configured them.
> >
> > No.
> >
> > -Scott
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> > the body of a message to majordomo@vger.kernel.org More majordomo info
> > at  http://vger.kernel.org/majordomo-info.html
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body
> of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
  2013-02-07 15:25                               ` Bhushan Bharat-R65777
@ 2013-02-07 15:53                                 ` Alexander Graf
  0 siblings, 0 replies; 59+ messages in thread
From: Alexander Graf @ 2013-02-07 15:53 UTC (permalink / raw)
  To: Bhushan Bharat-R65777
  Cc: Wood Scott-B07421, kvm-ppc@vger.kernel.org, kvm@vger.kernel.org


On 07.02.2013, at 16:25, Bhushan Bharat-R65777 wrote:

> 
> 
>> -----Original Message-----
>> From: kvm-ppc-owner@vger.kernel.org [mailto:kvm-ppc-owner@vger.kernel.org] On
>> Behalf Of Alexander Graf
>> Sent: Thursday, February 07, 2013 8:29 PM
>> To: Wood Scott-B07421
>> Cc: Bhushan Bharat-R65777; kvm-ppc@vger.kernel.org; kvm@vger.kernel.org
>> Subject: Re: [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest
>> 
>> 
>> On 01.02.2013, at 23:38, Scott Wood wrote:
>> 
>>> On 01/31/2013 06:11:32 PM, Alexander Graf wrote:
>>>> On 31.01.2013, at 23:40, Scott Wood wrote:
>>>>> On 01/31/2013 01:20:39 PM, Alexander Graf wrote:
>>>>>> On 31.01.2013, at 20:05, Alexander Graf wrote:
>>>>>>> 
>>>>>>> On 31.01.2013, at 19:54, Scott Wood wrote:
>>>>>>> 
>>>>>>>> On 01/31/2013 12:52:41 PM, Alexander Graf wrote:
>>>>>>>>> On 31.01.2013, at 19:43, Scott Wood wrote:
>>>>>>>>>> On 01/31/2013 12:21:07 PM, Alexander Graf wrote:
>>>>>>>>>>> How about something like this? Then both targets at least suck as
>> much :).
>>>>>>>>>> 
>>>>>>>>>> I'm not sure that should be the goal...
>>>>>>>>>> 
>>>>>>>>>>> Thanks to e500mc's awful hardware design, we don't know who sets the
>> MSR_DE bit. Once we forced it onto the guest, we have no change to know whether
>> the guest also set it or not. We could only guess.
>>>>>>>>>> 
>>>>>>>>>> MSRP[DEP] can prevent the guest from modifying MSR[DE] -- but we
>> still need to set it in the first place.
>>>>>>>>>> 
>>>>>>>>>> According to ISA V2.06B, the hypervisor should set DBCR0[EDM] to let
>> the guest know that the debug resources are not available, and that "the value
>> of MSR[DE] is not specified and not modifiable".
>>>>>>>>> So what would the guest do then to tell the hypervisor that it
>> actually wants to know about debug events?
>>>>>>>> 
>>>>>>>> The guest is out of luck, just as if a JTAG were in use.
>>>>>>> 
>>>>>>> Hrm.
>>>>>>> 
>>>>>>> Can we somehow generalize this "out of luck" behavior?
>>>>>>> 
>>>>>>> Every time we would set or clear an MSR bit in shadow_msr on e500v2, we
>> would instead set or clear it in the real MSR. That way only e500mc is out of
>> luck, but the code would still be shared.
>>>>> 
>>>>> I don't follow.  e500v2 is just as out-of-luck.  The mechanism simply does
>> not support sharing debug resources.
>>>> For e500v2 we have 2 fields
>>>> * MSR as the guest sees it
>>>> * MSR as we execute when the guest runs Since we know the MSR when
>>>> the guest sees it, we can decide what to do when we get an unhandled debug
>> interrupt.
>>> 
>>> That's not the same thing as making the real MSR[DE] show up in the guest
>> MSR[DE].
>>> 
>>> There are other problems with sharing -- what happens when both host and guest
>> try to write to a particular IAC or DAC?
>>> 
>>> Also, performance would be pretty awful if the guest has e.g. single stepping
>> in DBCR0 enabled but MSR[DE]=0, and the host doesn't care about single stepping
>> (but does want debugging enabled in general).
>>> 
>>>>> What do you mean by "the real MSR"?  The real MSR is shadow_msr, and MSR_DE
>> must always be set there if the host is debugging the guest.  As for reflecting
>> it into the guest MSR, we could, but I don't really see the point.  We're never
>> going to actually send a debug exception to the guest when the host owns the
>> debug resources.
>>>> Why not? That's the whole point of jumping through user space.
>>> 
>>> That's still needed for software breakpoints, which don't rely on the debug
>> resources.
>>> 
>>>> 1) guest exits with debug interrupt
>>>> 2) QEMU gets a debug exit
>>>> 3) QEMU checks in its list whether it belongs to its own debug
>>>> points
>>>> 4) if not, it reinjects the interrupt into the guest Step 4 is
>>>> pretty difficult to do when we don't know whether the guest is actually
>> capable of handling debug interrupts at that moment.
>>> 
>>> Software breakpoints take a Program interrupt rather than a Debug interrupt,
>> unless MSR[DE]=1 and DBCR0[TRAP]=1.  If the guest does not own debug resources
>> we should always send it to the Program interrupt, so MSR[DE] doesn't matter.
>>> 
>>>>> The "&= ~MSR_DE" line is pointless on bookehv, and makes it harder to read.
>> I had to stare at it a while before noticing that you initially set is_debug
>> from the guest MSR and that you'd never really clear MSR_DE here on bookehv.
>>>> Well, I'm mostly bouncing ideas here to find a way to express what we're
>> trying to say in a way that someone who hasn't read this email thread would
>> still understand what's going on :).
>>> 
>>> I think it's already straightforward enough if you accept that shared debug
>> resources aren't supported, and that we are either in a mode where the real
>> MSR[DE] reflects the guest MSR[DE], or a mode where the real MSR[DE] is always
>> on in guest mode and the guest MSR[DE] is irrelevant.
>> 
>> I think I'm starting to grasp what you're suggesting:
>> 
>> On e500mc, have 2 modes
>> 
>>  1) guest owns debug
>> 
>>  This is the normal operation. Here the guest defines the value of MSR_DE. The
>> guest gets debug interrupts directly.
>> 
>>  2) host owns debug
>> 
>>  In this case, take away any debug capabilities from the guest. Everything
>> debug related goes straight to QEMU.
>> 
>> 
>> On e500v2, have 2 modes
>> 
>>  1) guest owns debug
>> 
>>  This is the normal operation. Here the guest defines the value of MSR_DE. The
>> guest gets debug interrupts directly.
>> 
>>  2) host and guest share debug
> 
> We are not allowing the sharing, it is same as (2) in e500mc.

I don't grasp why we would set MSR_DE in shadow_msr always then :).


Alex

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

* Re: [PATCH 4/8] Added ONE_REG interface for debug instruction
  2013-02-07 14:29     ` Alexander Graf
@ 2013-02-11  0:22       ` Paul Mackerras
  0 siblings, 0 replies; 59+ messages in thread
From: Paul Mackerras @ 2013-02-11  0:22 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Bharat Bhushan, kvm-ppc, kvm, Bharat Bhushan

On Thu, Feb 07, 2013 at 03:29:50PM +0100, Alexander Graf wrote:
> 
> On 04.02.2013, at 01:41, Paul Mackerras wrote:
> 
> > On Wed, Jan 16, 2013 at 01:54:41PM +0530, Bharat Bhushan wrote:
> >> This patch adds the one_reg interface to get the special instruction
> >> to be used for setting software breakpoint from userspace.
> > 
> > Since this presumably is constant for any given platform, wouldn't
> > a capability be more appropriate?
> 
> How so? A capability only tells you "I can do debug". Or "I can do debug on e500". I don't want to reteach QEMU how to do debug for every core we implement.

Capabilities aren't just binary - the get-capability (check_extension)
ioctl returns a 32-bit value, and we already have some that return
values other than 0 or 1.  So I was thinking that we could add a
capability which when queried returns the special instruction.  It's
up to you whether you want to do it that way or not.

Paul.

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

end of thread, other threads:[~2013-02-11  0:22 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-16  8:24 [PATCH 2/8] KVM: PPC: booke: Allow multiple exception types Bharat Bhushan
2013-01-16  8:24 ` [PATCH 3/8] KVM: PPC: booke: Added debug handler Bharat Bhushan
2013-01-25 11:42   ` Alexander Graf
2013-01-30 11:30     ` Bhushan Bharat-R65777
2013-01-31 12:17       ` Alexander Graf
2013-01-31 16:58         ` Bhushan Bharat-R65777
2013-01-31 17:08           ` Alexander Graf
2013-01-31 17:11             ` Alexander Graf
2013-02-01  5:04             ` Bhushan Bharat-R65777
2013-02-01  8:06               ` Alexander Graf
2013-02-01  9:07                 ` Bhushan Bharat-R65777
2013-02-07 14:21                   ` Alexander Graf
2013-02-07 14:48                     ` Bhushan Bharat-R65777
2013-02-07 15:01                       ` Alexander Graf
2013-01-16  8:24 ` [PATCH 4/8] Added ONE_REG interface for debug instruction Bharat Bhushan
2013-01-25 11:48   ` Alexander Graf
2013-01-31 17:44     ` Bhushan Bharat-R65777
2013-01-31 17:52       ` Alexander Graf
2013-01-31 17:58         ` Bhushan Bharat-R65777
2013-01-31 18:22           ` Alexander Graf
2013-02-04  0:41   ` Paul Mackerras
2013-02-07 14:29     ` Alexander Graf
2013-02-11  0:22       ` Paul Mackerras
2013-01-16  8:24 ` [PATCH 5/8] KVM: PPC: debug stub interface parameter defined Bharat Bhushan
2013-01-17  7:22   ` Paul Mackerras
2013-01-17 11:11     ` Bhushan Bharat-R65777
2013-01-25 11:53       ` Alexander Graf
2013-01-30 14:15         ` Bhushan Bharat-R65777
2013-01-31 13:01           ` Alexander Graf
2013-01-31 14:05             ` Bhushan Bharat-R65777
2013-01-31 14:27               ` Alexander Graf
2013-01-31 14:44                 ` Bhushan Bharat-R65777
2013-01-16  8:24 ` [PATCH 6/8] booke: Added DBCR4 SPR number Bharat Bhushan
2013-01-16  8:24 ` [PATCH 7/8] KVM: PPC: booke/bookehv: Add debug stub support Bharat Bhushan
2013-01-25 12:07   ` Alexander Graf
2013-02-01  6:31     ` Bhushan Bharat-R65777
2013-02-01  8:21       ` Alexander Graf
2013-01-16  8:24 ` [PATCH 8/8] KVM:PPC:booke: Allow debug interrupt injection to guest Bharat Bhushan
2013-01-25 12:13   ` Alexander Graf
2013-01-30 11:12     ` Bhushan Bharat-R65777
2013-01-31 12:04       ` Alexander Graf
2013-01-31 17:59         ` Bhushan Bharat-R65777
2013-01-31 18:21           ` Alexander Graf
2013-01-31 18:43             ` Scott Wood
2013-01-31 18:52               ` Alexander Graf
2013-01-31 18:54                 ` Scott Wood
2013-01-31 19:05                   ` Alexander Graf
2013-01-31 19:20                     ` Alexander Graf
2013-01-31 22:40                       ` Scott Wood
2013-02-01  0:11                         ` Alexander Graf
2013-02-01 22:38                           ` Scott Wood
2013-02-04  4:48                             ` Bhushan Bharat-R65777
2013-02-04 19:47                               ` Scott Wood
2013-02-07 14:58                             ` Alexander Graf
2013-02-07 15:25                               ` Bhushan Bharat-R65777
2013-02-07 15:53                                 ` Alexander Graf
2013-02-07 15:00                             ` Bhushan Bharat-R65777
2013-02-07 15:08                               ` Alexander Graf
2013-01-31 18:03         ` Scott Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox