Align qemu-kvm-x86 with upstream kvm support /wrt software breakpoint support in ROM code. Signed-off-by: Jan Kiszka <jan.kiszka@xxxxxxxxxxx> --- qemu/qemu-kvm-x86.c | 29 ++++++++++++++++++++++++----- 1 files changed, 24 insertions(+), 5 deletions(-) diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c index 06ef775..05a9c4c 100644 --- a/qemu/qemu-kvm-x86.c +++ b/qemu/qemu-kvm-x86.c @@ -680,12 +680,32 @@ void kvm_arch_cpu_reset(CPUState *env) } } -int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) +#ifdef KVM_CAP_SET_GUEST_DEBUG +static int kvm_patch_opcode_byte(CPUState *env, target_ulong addr, uint8_t val) { - uint8_t int3 = 0xcc; + target_phys_addr_t phys_page_addr; + unsigned long pd; + uint8_t *ptr; + + phys_page_addr = cpu_get_phys_page_debug(env, addr & TARGET_PAGE_MASK); + if (phys_page_addr == -1) + return -EINVAL; + + pd = cpu_get_physical_page_desc(phys_page_addr); + if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM && + (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM && !(pd & IO_MEM_ROMD)) + return -EINVAL; + ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + + (addr & ~TARGET_PAGE_MASK); + *ptr = val; + return 0; +} + +int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) +{ if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || - cpu_memory_rw_debug(env, bp->pc, &int3, 1, 1)) + kvm_patch_opcode_byte(env, bp->pc, 0xcc)) return -EINVAL; return 0; } @@ -695,12 +715,11 @@ int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) uint8_t int3; if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc || - cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) + kvm_patch_opcode_byte(env, bp->pc, bp->saved_insn)) return -EINVAL; return 0; } -#ifdef KVM_CAP_SET_GUEST_DEBUG static struct { target_ulong addr; int len; -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html