RE: [PATCH 3/5] Add guest debug support for kvmppc

2009-07-27 Thread Liu Yu-B13201
 

 -Original Message-
 From: jan.kis...@web.de [mailto:jan.kis...@web.de] 
 Sent: Saturday, July 25, 2009 6:19 PM
 To: Liu Yu-B13201
 Cc: qemu-devel; Hollis Blanchard; kvm-ppc; Nathan Froyd
 Subject: Re: [PATCH 3/5] Add guest debug support for kvmppc
 
 Liu Yu wrote:
  Signed-off-by: Liu Yu 
 yu.liu-kzfg59tc24xl57midrc...@public.gmane.org
  ---
   target-ppc/kvm.c |  197 
 ++
   1 files changed, 197 insertions(+), 0 deletions(-)
  
  diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
  index b53d6e9..d8dbdb4 100644
  --- a/target-ppc/kvm.c
  +++ b/target-ppc/kvm.c
  +
  +int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
  +{
  +int handle = 0;
  +int n;
  +
  +if (cpu_single_env-singlestep_enabled) {
  +handle = 1;
  +
  +} else if (arch_info-status) {
  +if (arch_info-status == KVMPPC_DEBUG_BREAKPOINT) {
  +n = find_hw_breakpoint(arch_info-pc, 
 GDB_BREAKPOINT_HW);
  +if (n = 0)
  +handle = 1;
  +
  +} else if (arch_info-status == 
 KVMPPC_DEBUG_WATCH_ACCESS) {
  +n = find_hw_breakpoint(arch_info-pc, 
 GDB_WATCHPOINT_ACCESS);
  +if (n = 0) {
  +handle = 1;
  +cpu_single_env-watchpoint_hit = hw_watchpoint;
  +hw_watchpoint.vaddr = hw_breakpoint[n].addr;
  +hw_watchpoint.flags = BP_MEM_ACCESS;
  +}
  +
  +} else if (arch_info-status == KVMPPC_DEBUG_WATCH_WRITE) {
  +n = find_hw_breakpoint(arch_info-pc, 
 GDB_WATCHPOINT_WRITE);
  +if (n = 0) {
  +handle = 1;
  +cpu_single_env-watchpoint_hit = hw_watchpoint;
  +hw_watchpoint.vaddr = hw_breakpoint[n].addr;
  +hw_watchpoint.flags = BP_MEM_WRITE;
  +}
  +}
  +
  +} else if (kvm_find_sw_breakpoint(cpu_single_env, 
 arch_info-pc))
  +handle = 1;
  +
  +/* XXX inject guest debug exception */
  +if (!handle)
  +printf(Unhandled debug exception!\n);
 
 Out of curiosity: Not yet implemented here, or is PPC also 
 lacking some
 kernel bits to support it?

Yes, guest has no hardware debug support in booke kvm so far.
It's now useless for a guest to set debug register.

--
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


Re: [PATCH 3/5] Add guest debug support for kvmppc

2009-07-25 Thread Jan Kiszka
Liu Yu wrote:
 Signed-off-by: Liu Yu yu.liu-kzfg59tc24xl57midrc...@public.gmane.org
 ---
  target-ppc/kvm.c |  197 
 ++
  1 files changed, 197 insertions(+), 0 deletions(-)
 
 diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
 index b53d6e9..d8dbdb4 100644
 --- a/target-ppc/kvm.c
 +++ b/target-ppc/kvm.c
 @@ -8,6 +8,9 @@
   *  Christian Ehrhardt 
 ehrhardt-23vcf4htsmix0ybbhkvfkdbpr1lh4...@public.gmane.org
   *  Hollis Blanchard hollisb-r/jw6+rmf7hqt0dzr+a...@public.gmane.org
   *
 + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
 + *  Yu Liu yu.liu-kzfg59tc24xl57midrc...@public.gmane.org
 + *
   * This work is licensed under the terms of the GNU GPL, version 2 or later.
   * See the COPYING file in the top-level directory.
   *
 @@ -18,6 +21,7 @@
  #include sys/mman.h
  
  #include linux/kvm.h
 +#include asm/kvm_asm.h
  
  #include qemu-common.h
  #include qemu-timer.h
 @@ -26,6 +30,7 @@
  #include kvm_ppc.h
  #include cpu.h
  #include device_tree.h
 +#include gdbstub.h
  
  //#define DEBUG_KVM
  
 @@ -216,3 +221,195 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
 *run)
  return ret;
  }
  
 +#ifdef KVM_CAP_SET_GUEST_DEBUG
 +int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint 
 *bp)
 +{
 +uint32_t sc = tswap32(KVM_INST_GUESTGDB);
 +uint32_t tmp;
 +
 +if (cpu_memory_rw_debug(env, bp-pc, (uint8_t *)bp-saved_insn, 4, 0) ||
 +cpu_memory_rw_debug(env, bp-pc, (uint8_t *)sc, 4, 1))
 +return -EINVAL;
 +cpu_memory_rw_debug(env, bp-pc, (uint8_t *)tmp, 4, 0);
 +return 0;
 +}
 +
 +int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint 
 *bp)
 +{
 +uint32_t sc;
 +
 +if (cpu_memory_rw_debug(env, bp-pc, (uint8_t *)sc, 4, 0) ||
 +sc != tswap32(KVM_INST_GUESTGDB) ||
 +cpu_memory_rw_debug(env, bp-pc, (uint8_t *)bp-saved_insn, 4, 1))
 +return -EINVAL;
 +return 0;
 +}
 +
 +static struct {
 +target_ulong addr;
 +int type;
 +} hw_breakpoint[6];
 +
 +static int nb_hw_breakpoint;
 +static int nb_hw_watchpoint;
 +static int max_hw_breakpoint;
 +static int max_hw_watchpoint;
 +
 +void kvmppc_debug_init(int max_hw_bp, int max_hw_wp)
 +{
 +max_hw_breakpoint = max_hw_bp  4? 4 : max_hw_bp;
 +max_hw_watchpoint = max_hw_wp  2? 2 : max_hw_wp;
 +}
 +
 +static int find_hw_breakpoint(target_ulong addr, int type)
 +{
 +int n;
 +
 +for (n = 0; n  nb_hw_breakpoint + nb_hw_watchpoint; n++)
 +if (hw_breakpoint[n].addr == addr  hw_breakpoint[n].type == type)
 +return n;
 +return -1;
 +}
 +
 +int kvm_arch_insert_hw_breakpoint(target_ulong addr,
 +  target_ulong len, int type)
 +{
 +hw_breakpoint[nb_hw_breakpoint + nb_hw_watchpoint].addr = addr;
 +hw_breakpoint[nb_hw_breakpoint + nb_hw_watchpoint].type = type;
 +
 +switch (type) {
 +case GDB_BREAKPOINT_HW:
 +if (nb_hw_breakpoint = max_hw_breakpoint)
 +return -ENOBUFS;
 +
 +if (find_hw_breakpoint(addr, type) = 0)
 +return -EEXIST;
 +
 +nb_hw_breakpoint++;
 +break;
 +
 +case GDB_WATCHPOINT_WRITE:
 +case GDB_WATCHPOINT_ACCESS:
 +if (nb_hw_watchpoint = max_hw_watchpoint)
 +return -ENOBUFS;
 +
 +if (find_hw_breakpoint(addr, type) = 0)
 +return -EEXIST;
 +
 +nb_hw_watchpoint++;
 +break;
 +
 +default:
 +return -ENOSYS;
 +}
 +
 +return 0;
 +}
 +
 +int kvm_arch_remove_hw_breakpoint(target_ulong addr,
 +  target_ulong len, int type)
 +{
 +int n;
 +
 +n = find_hw_breakpoint(addr, type);
 +if (n  0)
 +return -ENOENT;
 +
 +switch (type) {
 +case GDB_BREAKPOINT_HW:
 +nb_hw_breakpoint--;
 +break;
 +
 +case GDB_WATCHPOINT_WRITE:
 +case GDB_WATCHPOINT_ACCESS:
 +nb_hw_watchpoint--;
 +break;
 +
 +default:
 +return -ENOSYS;
 +}
 +hw_breakpoint[n] = hw_breakpoint[nb_hw_breakpoint + nb_hw_watchpoint];
 +
 +return 0;
 +}
 +
 +void kvm_arch_remove_all_hw_breakpoints(void)
 +{
 +nb_hw_breakpoint = nb_hw_watchpoint = 0;
 +}
 +
 +static CPUWatchpoint hw_watchpoint;
 +
 +int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
 +{
 +int handle = 0;
 +int n;
 +
 +if (cpu_single_env-singlestep_enabled) {
 +handle = 1;
 +
 +} else if (arch_info-status) {
 +if (arch_info-status == KVMPPC_DEBUG_BREAKPOINT) {
 +n = find_hw_breakpoint(arch_info-pc, GDB_BREAKPOINT_HW);
 +if (n = 0)
 +handle = 1;
 +
 +} else if (arch_info-status == KVMPPC_DEBUG_WATCH_ACCESS) {
 +n = find_hw_breakpoint(arch_info-pc, GDB_WATCHPOINT_ACCESS);
 +if (n = 0) {
 +handle = 1;
 +cpu_single_env-watchpoint_hit = hw_watchpoint;
 +hw_watchpoint.vaddr =