688
#ifdef KVM_CAP_SET_GUEST_DEBUG
689
static int kvm_patch_opcode_byte(CPUState *env, target_ulong addr, uint8_t val)
691
target_phys_addr_t phys_page_addr;
695
phys_page_addr = cpu_get_phys_page_debug(env, addr & TARGET_PAGE_MASK);
696
if (phys_page_addr == -1)
699
pd = cpu_get_physical_page_desc(phys_page_addr);
700
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
701
(pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM && !(pd & IO_MEM_ROMD))
704
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK)
705
+ (addr & ~TARGET_PAGE_MASK);
710
int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
712
if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
713
kvm_patch_opcode_byte(env, bp->pc, 0xcc))
718
int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
722
if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
723
kvm_patch_opcode_byte(env, bp->pc, bp->saved_insn))
734
static int nb_hw_breakpoint;
736
static int find_hw_breakpoint(target_ulong addr, int len, int type)
740
for (n = 0; n < nb_hw_breakpoint; n++)
741
if (hw_breakpoint[n].addr == addr && hw_breakpoint[n].type == type &&
742
(hw_breakpoint[n].len == len || len == -1))
747
int kvm_arch_insert_hw_breakpoint(target_ulong addr,
748
target_ulong len, int type)
751
case GDB_BREAKPOINT_HW:
754
case GDB_WATCHPOINT_WRITE:
755
case GDB_WATCHPOINT_ACCESS:
762
if (addr & (len - 1))
773
if (nb_hw_breakpoint == 4)
776
if (find_hw_breakpoint(addr, len, type) >= 0)
779
hw_breakpoint[nb_hw_breakpoint].addr = addr;
780
hw_breakpoint[nb_hw_breakpoint].len = len;
781
hw_breakpoint[nb_hw_breakpoint].type = type;
787
int kvm_arch_remove_hw_breakpoint(target_ulong addr,
788
target_ulong len, int type)
792
n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type);
797
hw_breakpoint[n] = hw_breakpoint[nb_hw_breakpoint];
802
void kvm_arch_remove_all_hw_breakpoints(void)
804
nb_hw_breakpoint = 0;
807
static CPUWatchpoint hw_watchpoint;
809
int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
814
if (arch_info->exception == 1) {
815
if (arch_info->dr6 & (1 << 14)) {
816
if (cpu_single_env->singlestep_enabled)
819
for (n = 0; n < 4; n++)
820
if (arch_info->dr6 & (1 << n))
821
switch ((arch_info->dr7 >> (16 + n*4)) & 0x3) {
827
cpu_single_env->watchpoint_hit = &hw_watchpoint;
828
hw_watchpoint.vaddr = hw_breakpoint[n].addr;
829
hw_watchpoint.flags = BP_MEM_WRITE;
833
cpu_single_env->watchpoint_hit = &hw_watchpoint;
834
hw_watchpoint.vaddr = hw_breakpoint[n].addr;
835
hw_watchpoint.flags = BP_MEM_ACCESS;
839
} else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc))
843
kvm_update_guest_debug(cpu_single_env,
844
(arch_info->exception == 1) ?
845
KVM_GUESTDBG_INJECT_DB : KVM_GUESTDBG_INJECT_BP);
850
void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
852
const uint8_t type_code[] = {
853
[GDB_BREAKPOINT_HW] = 0x0,
854
[GDB_WATCHPOINT_WRITE] = 0x1,
855
[GDB_WATCHPOINT_ACCESS] = 0x3
857
const uint8_t len_code[] = {
858
[1] = 0x0, [2] = 0x1, [4] = 0x3, [8] = 0x2
862
if (kvm_sw_breakpoints_active(env))
863
dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
865
if (nb_hw_breakpoint > 0) {
866
dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
867
dbg->arch.debugreg[7] = 0x0600;
868
for (n = 0; n < nb_hw_breakpoint; n++) {
869
dbg->arch.debugreg[n] = hw_breakpoint[n].addr;
870
dbg->arch.debugreg[7] |= (2 << (n * 2)) |
871
(type_code[hw_breakpoint[n].type] << (16 + n*4)) |
872
(len_code[hw_breakpoint[n].len] << (18 + n*4));
876
#endif /* KVM_CAP_SET_GUEST_DEBUG */