[PATCH v2 0/5] kvmppc: Add guest debug support

2009-08-03 Thread Liu Yu
This patchset add guest debug support for BOOKE.

patch 1: fix current e500 broken
patch 2: guest debug definitions
patch 3: switch shadow/host debug register on guest enter/exit path
patch 4: guest debug support
patch 5: exitnr fixup in single step mode

[v2]
1. move code from 2.6.30 to current head
2. move the debug registers updating code to guest enter/exit path
3. some cleanup.


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


[PATCH 1/5] Fix the trace broken for e500 kvm

2009-08-03 Thread Liu Yu
Remove the broken trace.
Will get them cleanup in future.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/e500_tlb.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index fb1e1dc..a344be6 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -225,8 +225,6 @@ static void kvmppc_e500_stlbe_invalidate(struct 
kvmppc_vcpu_e500 *vcpu_e500,
 
kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
stlbe-mas1 = 0;
-   trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe-mas1, stlbe-mas2,
-stlbe-mas3, stlbe-mas7);
 }
 
 static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
-- 
1.5.4

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


[PATCH 2/5] kvmppc guest debug definitions

2009-08-03 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/include/asm/kvm.h  |   20 
 arch/powerpc/include/asm/kvm_host.h |   18 ++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index bb2de6a..804df17 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -22,6 +22,9 @@
 
 #include linux/types.h
 
+/* Select powerpc specific features in linux/kvm.h */
+#define __KVM_HAVE_GUEST_DEBUG
+
 struct kvm_regs {
__u64 pc;
__u64 cr;
@@ -53,10 +56,27 @@ struct kvm_fpu {
 };
 
 struct kvm_debug_exit_arch {
+   __u32 exception;
+   __u32 pc;
+   __u32 status;
 };
 
+#define KVM_INST_GUESTGDB   0x4422
+
+#define KVM_GUESTDBG_USE_SW_BP  0x0001
+#define KVM_GUESTDBG_USE_HW_BP  0x0002
+
+#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)
+
 /* for KVM_SET_GUEST_DEBUG */
 struct kvm_guest_debug_arch {
+   struct {
+   __u32 addr;
+   __u32 type;
+   } bp[6];
 };
 
 #endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index c9c930e..6caabfc 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -109,9 +109,22 @@ struct kvmppc_exit_timing {
 struct kvm_arch {
 };
 
+struct kvmppc_debug_reg {
+   u32 dbcr0;
+   u32 iac[0];
+   u32 iac1;
+   u32 iac2;
+   u32 iac3;
+   u32 iac4;
+   u32 dac[0];
+   u32 dac1;
+   u32 dac2;
+};
+
 struct kvm_vcpu_arch {
u32 host_stack;
u32 host_pid;
+   u32 host_msr;
 
u64 fpr[32];
ulong gpr[32];
@@ -160,6 +173,10 @@ struct kvm_vcpu_arch {
u32 dbcr1;
u32 dbsr;
 
+   struct kvmppc_debug_reg shadow_dbg_reg;
+   struct kvmppc_debug_reg host_dbg_reg;
+   bool has_load_host_dbg;
+
 #ifdef CONFIG_KVM_EXIT_TIMING
struct kvmppc_exit_timing timing_exit;
struct kvmppc_exit_timing timing_last_enter;
@@ -187,6 +204,7 @@ struct kvm_vcpu_arch {
 
struct timer_list dec_timer;
unsigned long pending_exceptions;
+   struct kvm_guest_debug_arch dbg;
 };
 
 #endif /* __POWERPC_KVM_HOST_H__ */
-- 
1.5.4

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


[PATCH 3/5] Switch shadow/host debug registers on guest enter/exit path

2009-08-03 Thread Liu Yu
So that we don't give any chance for host to trigger the debug event.
Also the debug ability in guest can be implemented based on this.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kernel/asm-offsets.c   |3 ++
 arch/powerpc/kvm/booke_interrupts.S |   58 +++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 561b646..643ee15 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -379,6 +379,9 @@ 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_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg));
+   DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg));
+   DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug));
 #endif
 #ifdef CONFIG_44x
DEFINE(PGD_T_LOG2, PGD_T_LOG2);
diff --git a/arch/powerpc/kvm/booke_interrupts.S 
b/arch/powerpc/kvm/booke_interrupts.S
index d0c6f84..52592fe 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -168,6 +168,26 @@ _GLOBAL(kvmppc_resume_host)
stw r9, VCPU_FAULT_ESR(r4)
 ..skip_esr:
 
+   lwz r6, VCPU_GUEST_DEBUG(r4)
+   or. r6, r6, r6
+   beq ..skip_host_debug
+   addir7, r4, VCPU_HOST_DBG - 4
+   lwzur9, 4(r7)
+   mtspr   SPRN_DBCR0, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_IAC1, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_IAC2, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_IAC3, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_IAC4, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_DAC1, r9
+   lwzur9, 4(r7)
+   mtspr   SPRN_DAC2, r9
+..skip_host_debug:
+
/* Save remaining volatile guest register state to vcpu. */
stw r0, VCPU_GPR(r0)(r4)
stw r1, VCPU_GPR(r1)(r4)
@@ -392,6 +412,44 @@ lightweight_exit:
lwz r3, VCPU_SPRG7(r4)
mtspr   SPRN_SPRG7, r3
 
+   lwz r6, VCPU_GUEST_DEBUG(r4)
+   or. r6, r6, r6
+   beq ..skip_guest_debug
+   mfmsr   r7
+   rlwinm  r7, r7, 0, ~MSR_DE
+   mtmsr   r7
+   addir7, r4, VCPU_HOST_DBG - 4
+   mfspr   r8, SPRN_DBCR0
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_IAC1
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_IAC2
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_IAC3
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_IAC4
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_DAC1
+   stwur8, 4(r7)
+   mfspr   r8, SPRN_DAC2
+   stwur8, 4(r7)
+   addir7, r4, VCPU_SHADOW_DBG - 4
+   lwzur8, 4(r7)
+   mtspr   SPRN_DBCR0, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_IAC1, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_IAC2, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_IAC3, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_IAC4, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_DAC1, r8
+   lwzur8, 4(r7)
+   mtspr   SPRN_DAC2, r8
+..skip_guest_debug:
+
 #ifdef CONFIG_KVM_EXIT_TIMING
/* save enter time */
 1:
-- 
1.5.4

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


[PATCH 4/5] kvmppc guest debug support

2009-08-03 Thread Liu Yu
Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/include/asm/kvm_ppc.h |5 ++
 arch/powerpc/kvm/booke.c   |   97 ++--
 arch/powerpc/kvm/e500.c|8 ---
 arch/powerpc/kvm/powerpc.c |2 +-
 4 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 2c6ee34..4f3656b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -89,6 +89,11 @@ extern int kvmppc_core_emulate_op(struct kvm_run *run, 
struct kvm_vcpu *vcpu,
 extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs);
 extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt);
 
+extern void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu);
+extern void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu);
+extern int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu,
+   struct kvm_guest_debug *dbg);
+
 extern int kvmppc_booke_init(void);
 extern void kvmppc_booke_exit(void);
 
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index e7bf4d0..4e7954f 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -16,6 +16,9 @@
  *
  * Authors: Hollis Blanchard holl...@us.ibm.com
  *  Christian Ehrhardt ehrha...@linux.vnet.ibm.com
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *  Yu Liu yu@freescale.com
  */
 
 #include linux/errno.h
@@ -230,6 +233,16 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
break;
}
 
+   if (unlikely(vcpu-guest_debug  KVM_GUESTDBG_ENABLE) 
+(vcpu-arch.last_inst == KVM_INST_GUESTGDB)) {
+   run-exit_reason = KVM_EXIT_DEBUG;
+   run-debug.arch.pc = vcpu-arch.pc;
+   run-debug.arch.exception = exit_nr;
+   kvmppc_account_exit(vcpu, DEBUG_EXITS);
+   r = RESUME_HOST;
+   break;
+   }
+
er = kvmppc_emulate_instruction(run, vcpu);
switch (er) {
case EMULATE_DONE:
@@ -256,6 +269,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
default:
BUG();
}
+
+   if (unlikely(vcpu-guest_debug  KVM_GUESTDBG_ENABLE) 
+   (vcpu-guest_debug  KVM_GUESTDBG_SINGLESTEP)) {
+   run-exit_reason = KVM_EXIT_DEBUG;
+   r = RESUME_HOST;
+   }
break;
 
case BOOKE_INTERRUPT_FP_UNAVAIL:
@@ -386,12 +405,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
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-debug.arch.pc = vcpu-arch.pc;
+   run-debug.arch.status = 0;
+
+   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.pc = 
vcpu-arch.shadow_dbg_reg.dac1;
+   else if (dbsr  (DBSR_DAC2R | DBSR_DAC2W))
+   run-debug.arch.pc = 
vcpu-arch.shadow_dbg_reg.dac2;
+   }
 
+   /* clear events in DBSR register */
+   mtspr(SPRN_DBSR, ~0);
+
+   run-debug.arch.exception = exit_nr;
run-exit_reason = KVM_EXIT_DEBUG;
kvmppc_account_exit(vcpu, DEBUG_EXITS);
r = RESUME_HOST;
@@ -463,6 +497,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, 
struct kvm_regs *regs)
for (i = 0; i  ARRAY_SIZE(regs-gpr); i++)
regs-gpr[i] = vcpu-arch.gpr[i];
 
+
return 0;
 }
 
@@ -520,6 +555,60 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
return kvmppc_core_vcpu_translate(vcpu, tr);
 }
 
+int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu,
+struct kvm_guest_debug *dbg)
+{
+   if (!(dbg-control  KVM_GUESTDBG_ENABLE)) {
+   vcpu-guest_debug = 0;
+   return 0;
+   }
+
+   vcpu-guest_debug = dbg-control;
+   

[PATCH 5/5] kvmppc: exit_nr fixup for guest debug single step

2009-08-03 Thread Liu Yu
As BOOKE doesn't have hardware support for virtualization,
hardware never know guest and host.
So when enable hardware single step for guest,
it cannot be disabled timely if guest want to exit.

Thus, we'll see that an single step interrupt happens at
the beginning of guest exit path.
Then we need to recognize this kind of single step interrupt
and fix the exit_nr to the corret value.

Signed-off-by: Liu Yu yu@freescale.com
---
 arch/powerpc/kvm/booke.c|   82 +++
 arch/powerpc/kvm/booke_interrupts.S |9 ++--
 2 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 4e7954f..d3cfd85 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -27,6 +27,7 @@
 #include linux/module.h
 #include linux/vmalloc.h
 #include linux/fs.h
+#include linux/highmem.h
 
 #include asm/cputable.h
 #include asm/uaccess.h
@@ -37,6 +38,8 @@
 #include booke.h
 
 unsigned long kvmppc_booke_handlers;
+unsigned long kvmppc_booke_handler_addr[16];
+#define handler_vector_num 
(sizeof(kvmppc_booke_handler_addr)/sizeof(kvmppc_booke_handler_addr[0]))
 
 #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
 #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
@@ -179,6 +182,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
}
 }
 
+int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr,
+ void *data, int len)
+{
+   int gtlb_index;
+   gpa_t gpa;
+   gfn_t gfn;
+   struct page *page;
+   void *headdr, *from;
+
+   /* Check the guest TLB. */
+   gtlb_index = kvmppc_mmu_itlb_index(vcpu, geaddr);
+   if (gtlb_index  0)
+   return -EFAULT;
+
+   gpa = kvmppc_mmu_xlate(vcpu, gtlb_index, geaddr);
+   gfn = gpa  PAGE_SHIFT;
+
+   page = gfn_to_page(vcpu-kvm, gfn);
+   if (page == bad_page)
+   return -EFAULT;
+
+   headdr = kmap_atomic(page, KM_USER0);
+   if (!headdr)
+   return -EFAULT;
+   from = headdr + (geaddr  (PAGE_SIZE - 1));
+   memcpy(data, from, len);
+   kunmap_atomic(headdr, KM_USER0);
+
+   return 0;
+}
+
+static unsigned int kvmppc_guest_debug_exit_fixup(struct kvm_vcpu *vcpu,
+  unsigned int exit_nr)
+{
+   unsigned int ret = exit_nr;
+
+   u32 csrr0 = mfspr(SPRN_CSRR0);
+   u32 dbsr = mfspr(SPRN_DBSR);
+
+   if ((dbsr | DBSR_IC) 
+   csrr0 = kvmppc_booke_handlers 
+   csrr0  kvmppc_booke_handlers + (PAGE_SIZE  VCPU_SIZE_ORDER)) {
+   int i = 0;
+
+   for (i = 0; i  handler_vector_num; i++) {
+   if (kvmppc_booke_handler_addr[i] 
+   csrr0 == kvmppc_booke_handler_addr[i] + 4) {
+   mtspr(SPRN_DBSR, ~0);
+   ret = i;
+   break;
+   }
+   }
+
+   }
+
+   switch (ret) {
+   case BOOKE_INTERRUPT_DEBUG:
+   case BOOKE_INTERRUPT_ITLB_MISS:
+   case BOOKE_INTERRUPT_EXTERNAL:
+   case BOOKE_INTERRUPT_DECREMENTER:
+   break;
+
+   case BOOKE_INTERRUPT_PROGRAM:
+   case BOOKE_INTERRUPT_DTLB_MISS:
+   /* Need to save the last instruction */
+   kvmppc_read_guest(vcpu, vcpu-arch.pc, vcpu-arch.last_inst, 
4);
+   break;
+   default:
+   printk(Unhandled debug after interrupt:%d\n, ret);
+   }
+
+   return ret;
+}
+
 /**
  * kvmppc_handle_exit
  *
@@ -198,6 +275,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu 
*vcpu,
run-exit_reason = KVM_EXIT_UNKNOWN;
run-ready_for_interrupt_injection = 1;
 
+   if (exit_nr == BOOKE_INTERRUPT_DEBUG)
+   exit_nr = kvmppc_guest_debug_exit_fixup(vcpu, exit_nr);
+
switch (exit_nr) {
case BOOKE_INTERRUPT_MACHINE_CHECK:
printk(MACHINE CHECK: %lx\n, mfspr(SPRN_MCSR));
@@ -650,6 +730,8 @@ int __init kvmppc_booke_init(void)
memcpy((void *)kvmppc_booke_handlers + ivor[i],
   kvmppc_handlers_start + i * kvmppc_handler_len,
   kvmppc_handler_len);
+   kvmppc_booke_handler_addr[i] =
+   (unsigned long)kvmppc_booke_handlers + ivor[i];
}
flush_icache_range(kvmppc_booke_handlers,
   kvmppc_booke_handlers + max_ivor + 
kvmppc_handler_len);
diff --git a/arch/powerpc/kvm/booke_interrupts.S 
b/arch/powerpc/kvm/booke_interrupts.S
index 52592fe..d7cd37e 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -42,16 +42,17 @@
 #define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */
 
 #define NEED_INST_MASK ((1BOOKE_INTERRUPT_PROGRAM) | \
-(1BOOKE_INTERRUPT_DTLB_MISS) | \
-  

RE: [PATCH 2/5] kvmppc guest debug definitions

2009-08-03 Thread Liu Yu-B13201
 

 -Original Message-
 From: Liu Yu-B13201 
 Sent: Monday, August 03, 2009 7:08 PM
 To: kvm-ppc@vger.kernel.org
 Cc: holl...@us.ibm.com; a...@redhat.com; Liu Yu-B13201
 Subject: [PATCH 2/5] kvmppc guest debug definitions
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
  arch/powerpc/include/asm/kvm.h  |   20 
  arch/powerpc/include/asm/kvm_host.h |   18 ++
  2 files changed, 38 insertions(+), 0 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/kvm_host.h 
 b/arch/powerpc/include/asm/kvm_host.h
 index c9c930e..6caabfc 100644
 --- a/arch/powerpc/include/asm/kvm_host.h
 +++ b/arch/powerpc/include/asm/kvm_host.h
 @@ -160,6 +173,10 @@ struct kvm_vcpu_arch {
   u32 dbcr1;
   u32 dbsr;
  
 + struct kvmppc_debug_reg shadow_dbg_reg;
 + struct kvmppc_debug_reg host_dbg_reg;
 + bool has_load_host_dbg;

Forgot to remove this variable for debug
--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html