From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v9 2/6] target-arm: kvm - implement software breakpoints Date: Thu, 12 Nov 2015 16:20:47 +0000 Message-ID: <1447345251-22625-3-git-send-email-alex.bennee@linaro.org> References: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: kvm@vger.kernel.org, marc.zyngier@arm.com, Paolo Bonzini , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org To: qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, christoffer.dall@linaro.org, zhichao.huang@linaro.org Return-path: In-Reply-To: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kvmarm-bounces@lists.cs.columbia.edu Sender: kvmarm-bounces@lists.cs.columbia.edu List-Id: kvm.vger.kernel.org VGhlc2UgZG9uJ3QgaW52b2x2ZSBtZXNzaW5nIGFyb3VuZCB3aXRoIGRlYnVnIHJlZ2lzdGVycywg anVzdCBzZXR0aW5nCnRoZSBicmVha3BvaW50IGluc3RydWN0aW9uIGluIG1lbW9yeS4gR0RCIHdp bGwgbm90IHVzZSB0aGlzIG1lY2hhbmlzbSBpZgppdCBjYW4ndCBhY2Nlc3MgdGhlIG1lbW9yeSB0 byB3cml0ZSB0aGUgYnJlYWtwb2ludC4KCkFsbCB0aGUga2VybmVsIGhhcyB0byBkbyBpcyBlbnN1 cmUgdGhlIGh5cGVydmlzb3IgdHJhcHMgdGhlIGJyZWFrcG9pbnQKZXhjZXB0aW9ucyBhbmQgcmV0 dXJucyB0byB1c2Vyc3BhY2UuCgpTaWduZWQtb2ZmLWJ5OiBBbGV4IEJlbm7DqWUgPGFsZXguYmVu bmVlQGxpbmFyby5vcmc+CgotLQp2MgogIC0gaGFuZGxlIGRlYnVnIGV4aXQgd2l0aCBuZXcgaHNy IGV4Y2VwdGlvbiBpbmZvCiAgLSBhZGQgdmVyYm9zaXR5IHRvIFVOSU1QIG1lc3NhZ2UKdjMKICAt IHN5bmMgd2l0aCBrdm1fY3B1X3N5bmNocm9uaXplX3N0YXRlKCkgYmVmb3JlIGNoZWNraW5nIFBD LgogIC0gdXNlIGludGVybmFscy5oIGRlZmluZXMKICAtIHVzZSBlbnYtPnBjCiAgLSB1c2UgcHJv cGVyIGZvcm1hdCB0eXBlcwp2OQogIC0gYWRkIGluY2x1ZGUgZm9yIGVycm9yX3JlcG9ydAogIC0g ZGVmaW5lIGEgYnJrX2luc24gY29uc3RhbnQKLS0tCiB0YXJnZXQtYXJtL2t2bS5jIHwgOTAgKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0KIDEg ZmlsZSBjaGFuZ2VkLCA3OCBpbnNlcnRpb25zKCspLCAxMiBkZWxldGlvbnMoLSkKCmRpZmYgLS1n aXQgYS90YXJnZXQtYXJtL2t2bS5jIGIvdGFyZ2V0LWFybS9rdm0uYwppbmRleCA3OWVmNGM2Li41 MGY3MGVmIDEwMDY0NAotLS0gYS90YXJnZXQtYXJtL2t2bS5jCisrKyBiL3RhcmdldC1hcm0va3Zt LmMKQEAgLTE3LDYgKzE3LDcgQEAKIAogI2luY2x1ZGUgInFlbXUtY29tbW9uLmgiCiAjaW5jbHVk ZSAicWVtdS90aW1lci5oIgorI2luY2x1ZGUgInFlbXUvZXJyb3ItcmVwb3J0LmgiCiAjaW5jbHVk ZSAic3lzZW11L3N5c2VtdS5oIgogI2luY2x1ZGUgInN5c2VtdS9rdm0uaCIKICNpbmNsdWRlICJr dm1fYXJtLmgiCkBAIC01MTYsOSArNTE3LDYwIEBAIE1lbVR4QXR0cnMga3ZtX2FyY2hfcG9zdF9y dW4oQ1BVU3RhdGUgKmNzLCBzdHJ1Y3Qga3ZtX3J1biAqcnVuKQogICAgIHJldHVybiBNRU1UWEFU VFJTX1VOU1BFQ0lGSUVEOwogfQogCisvKiBTZWUgdjggQVJNIEFSTSBENy4yLjI3IEVTUl9FTHgs IEV4Y2VwdGlvbiBTeW5kcm9tZSBSZWdpc3RlcgorICoKKyAqIFRvIG1pbmltaXNlIHRyYW5zbGF0 aW5nIGJldHdlZW4ga2VybmVsIGFuZCB1c2VyLXNwYWNlIHRoZSBrZXJuZWwKKyAqIEFCSSBqdXN0 IHByb3ZpZGVzIHVzZXItc3BhY2Ugd2l0aCB0aGUgZnVsbCBleGNlcHRpb24gc3luZHJvbWUKKyAq IHJlZ2lzdGVyIHZhbHVlIHRvIGJlIGRlY29kZWQgaW4gUUVNVS4KKyAqLworCitzdGF0aWMgaW50 IGt2bV9oYW5kbGVfZGVidWcoQ1BVU3RhdGUgKmNzLCBzdHJ1Y3Qga3ZtX3J1biAqcnVuKQorewor ICAgIHN0cnVjdCBrdm1fZGVidWdfZXhpdF9hcmNoICphcmNoX2luZm8gPSAmcnVuLT5kZWJ1Zy5h cmNoOworICAgIGludCBoc3JfZWMgPSBhcmNoX2luZm8tPmhzciA+PiBBUk1fRUxfRUNfU0hJRlQ7 CisgICAgQVJNQ1BVICpjcHUgPSBBUk1fQ1BVKGNzKTsKKyAgICBDUFVBUk1TdGF0ZSAqZW52ID0g JmNwdS0+ZW52OworCisgICAgLyogRW5zdXJlIFBDIGlzIHN5bmNocm9uaXNlZCAqLworICAgIGt2 bV9jcHVfc3luY2hyb25pemVfc3RhdGUoY3MpOworCisgICAgc3dpdGNoIChoc3JfZWMpIHsKKyAg ICBjYXNlIEVDX0FBNjRfQktQVDoKKyAgICAgICAgaWYgKGt2bV9maW5kX3N3X2JyZWFrcG9pbnQo Y3MsIGVudi0+cGMpKSB7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAg ICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBlcnJvcl9yZXBvcnQoIiVzOiB1bmhh bmRsZWQgZGVidWcgZXhpdCAoJSJQUkl4MzIiLCAlIlBSSXg2NCIpXG4iLAorICAgICAgICAgICAg ICAgICAgICAgX19mdW5jX18sIGFyY2hfaW5mby0+aHNyLCBlbnYtPnBjKTsKKyAgICB9CisKKyAg ICAvKiBJZiB3ZSBkb24ndCBoYW5kbGUgdGhpcyBpdCBjb3VsZCBiZSBpdCByZWFsbHkgaXMgZm9y IHRoZQorICAgICAgIGd1ZXN0IHRvIGhhbmRsZSAqLworICAgIHFlbXVfbG9nX21hc2soTE9HX1VO SU1QLAorICAgICAgICAgICAgICAgICAgIiVzOiByZS1pbmplY3RpbmcgZXhjZXB0aW9uIG5vdCB5 ZXQgaW1wbGVtZW50ZWQiCisgICAgICAgICAgICAgICAgICAiICgweCUiUFJJeDMyIiwgJSJQUkl4 NjQiKVxuIiwKKyAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBoc3JfZWMsIGVudi0+cGMpOwor CisgICAgcmV0dXJuIGZhbHNlOworfQorCiBpbnQga3ZtX2FyY2hfaGFuZGxlX2V4aXQoQ1BVU3Rh dGUgKmNzLCBzdHJ1Y3Qga3ZtX3J1biAqcnVuKQogewotICAgIHJldHVybiAwOworICAgIGludCBy ZXQgPSAwOworCisgICAgc3dpdGNoIChydW4tPmV4aXRfcmVhc29uKSB7CisgICAgY2FzZSBLVk1f RVhJVF9ERUJVRzoKKyAgICAgICAgaWYgKGt2bV9oYW5kbGVfZGVidWcoY3MsIHJ1bikpIHsKKyAg ICAgICAgICAgIHJldCA9IEVYQ1BfREVCVUc7CisgICAgICAgIH0gLyogb3RoZXJ3aXNlIHJldHVy biB0byBndWVzdCAqLworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBxZW11 X2xvZ19tYXNrKExPR19VTklNUCwgIiVzOiB1bi1oYW5kbGVkIGV4aXQgcmVhc29uICVkXG4iLAor ICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBydW4tPmV4aXRfcmVhc29uKTsKKyAgICAg ICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiByZXQ7CiB9CiAKIGJvb2wga3ZtX2FyY2hfc3Rv cF9vbl9lbXVsYXRpb25fZXJyb3IoQ1BVU3RhdGUgKmNzKQpAQCAtNTQzLDE0ICs1OTUsMzQgQEAg aW50IGt2bV9hcmNoX29uX3NpZ2J1cyhpbnQgY29kZSwgdm9pZCAqYWRkcikKIAogdm9pZCBrdm1f YXJjaF91cGRhdGVfZ3Vlc3RfZGVidWcoQ1BVU3RhdGUgKmNzLCBzdHJ1Y3Qga3ZtX2d1ZXN0X2Rl YnVnICpkYmcpCiB7Ci0gICAgcWVtdV9sb2dfbWFzayhMT0dfVU5JTVAsICIlczogbm90IGltcGxl bWVudGVkXG4iLCBfX2Z1bmNfXyk7CisgICAgaWYgKGt2bV9zd19icmVha3BvaW50c19hY3RpdmUo Y3MpKSB7CisgICAgICAgIGRiZy0+Y29udHJvbCB8PSBLVk1fR1VFU1REQkdfRU5BQkxFIHwgS1ZN X0dVRVNUREJHX1VTRV9TV19CUDsKKyAgICB9CiB9CiAKLWludCBrdm1fYXJjaF9pbnNlcnRfc3df YnJlYWtwb2ludChDUFVTdGF0ZSAqY3MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc3RydWN0IGt2bV9zd19icmVha3BvaW50ICpicCkKKy8qIEM2LjYuMjkgQlJLIGluc3RydWN0 aW9uICovCitzdGF0aWMgY29uc3QgdWludDMyX3QgYnJrX2luc24gPSAweGQ0MjAwMDAwOworCitp bnQga3ZtX2FyY2hfaW5zZXJ0X3N3X2JyZWFrcG9pbnQoQ1BVU3RhdGUgKmNzLCBzdHJ1Y3Qga3Zt X3N3X2JyZWFrcG9pbnQgKmJwKQogewotICAgIHFlbXVfbG9nX21hc2soTE9HX1VOSU1QLCAiJXM6 IG5vdCBpbXBsZW1lbnRlZFxuIiwgX19mdW5jX18pOwotICAgIHJldHVybiAtRUlOVkFMOworCisg ICAgaWYgKGNwdV9tZW1vcnlfcndfZGVidWcoY3MsIGJwLT5wYywgKHVpbnQ4X3QgKikmYnAtPnNh dmVkX2luc24sIDQsIDApIHx8CisgICAgICAgIGNwdV9tZW1vcnlfcndfZGVidWcoY3MsIGJwLT5w YywgKHVpbnQ4X3QgKikmYnJrX2luc24sIDQsIDEpKSB7CisgICAgICAgIHJldHVybiAtRUlOVkFM OworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworaW50IGt2bV9hcmNoX3JlbW92ZV9zd19icmVh a3BvaW50KENQVVN0YXRlICpjcywgc3RydWN0IGt2bV9zd19icmVha3BvaW50ICpicCkKK3sKKyAg ICBzdGF0aWMgdWludDMyX3QgYnJrOworCisgICAgaWYgKGNwdV9tZW1vcnlfcndfZGVidWcoY3Ms IGJwLT5wYywgKHVpbnQ4X3QgKikmYnJrLCA0LCAwKSB8fAorICAgICAgICBicmsgIT0gYnJrX2lu c24gfHwKKyAgICAgICAgY3B1X21lbW9yeV9yd19kZWJ1ZyhjcywgYnAtPnBjLCAodWludDhfdCAq KSZicC0+c2F2ZWRfaW5zbiwgNCwgMSkpIHsKKyAgICAgICAgcmV0dXJuIC1FSU5WQUw7CisgICAg fQorICAgIHJldHVybiAwOwogfQogCiBpbnQga3ZtX2FyY2hfaW5zZXJ0X2h3X2JyZWFrcG9pbnQo dGFyZ2V0X3Vsb25nIGFkZHIsCkBAIC01NjcsMTIgKzYzOSw2IEBAIGludCBrdm1fYXJjaF9yZW1v dmVfaHdfYnJlYWtwb2ludCh0YXJnZXRfdWxvbmcgYWRkciwKICAgICByZXR1cm4gLUVJTlZBTDsK IH0KIAotaW50IGt2bV9hcmNoX3JlbW92ZV9zd19icmVha3BvaW50KENQVVN0YXRlICpjcywKLSAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qga3ZtX3N3X2JyZWFrcG9pbnQg KmJwKQotewotICAgIHFlbXVfbG9nX21hc2soTE9HX1VOSU1QLCAiJXM6IG5vdCBpbXBsZW1lbnRl ZFxuIiwgX19mdW5jX18pOwotICAgIHJldHVybiAtRUlOVkFMOwotfQogCiB2b2lkIGt2bV9hcmNo X3JlbW92ZV9hbGxfaHdfYnJlYWtwb2ludHModm9pZCkKIHsKLS0gCjIuNi4zCgpfX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwprdm1hcm0gbWFpbGluZyBsaXN0 Cmt2bWFybUBsaXN0cy5jcy5jb2x1bWJpYS5lZHUKaHR0cHM6Ly9saXN0cy5jcy5jb2x1bWJpYS5l ZHUvbWFpbG1hbi9saXN0aW5mby9rdm1hcm0K From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52096) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zwucg-0000T5-6Z for qemu-devel@nongnu.org; Thu, 12 Nov 2015 11:21:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zwucd-0003Kk-Vf for qemu-devel@nongnu.org; Thu, 12 Nov 2015 11:21:18 -0500 Received: from mail-wm0-x22a.google.com ([2a00:1450:400c:c09::22a]:36663) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zwucd-0003KI-NY for qemu-devel@nongnu.org; Thu, 12 Nov 2015 11:21:15 -0500 Received: by wmww144 with SMTP id w144so207574558wmw.1 for ; Thu, 12 Nov 2015 08:21:15 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 12 Nov 2015 16:20:47 +0000 Message-Id: <1447345251-22625-3-git-send-email-alex.bennee@linaro.org> In-Reply-To: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> References: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [PATCH v9 2/6] target-arm: kvm - implement software breakpoints List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, qemu-arm@nongnu.org, peter.maydell@linaro.org, christoffer.dall@linaro.org, zhichao.huang@linaro.org Cc: kvm@vger.kernel.org, marc.zyngier@arm.com, Paolo Bonzini , =?UTF-8?q?Alex=20Benn=C3=A9e?= , kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org These don't involve messing around with debug registers, just setting the breakpoint instruction in memory. GDB will not use this mechanism if it can't access the memory to write the breakpoint. All the kernel has to do is ensure the hypervisor traps the breakpoint exceptions and returns to userspace. Signed-off-by: Alex Bennée -- v2 - handle debug exit with new hsr exception info - add verbosity to UNIMP message v3 - sync with kvm_cpu_synchronize_state() before checking PC. - use internals.h defines - use env->pc - use proper format types v9 - add include for error_report - define a brk_insn constant --- target-arm/kvm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 79ef4c6..50f70ef 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -17,6 +17,7 @@ #include "qemu-common.h" #include "qemu/timer.h" +#include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "kvm_arm.h" @@ -516,9 +517,60 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) return MEMTXATTRS_UNSPECIFIED; } +/* See v8 ARM ARM D7.2.27 ESR_ELx, Exception Syndrome Register + * + * To minimise translating between kernel and user-space the kernel + * ABI just provides user-space with the full exception syndrome + * register value to be decoded in QEMU. + */ + +static int kvm_handle_debug(CPUState *cs, struct kvm_run *run) +{ + struct kvm_debug_exit_arch *arch_info = &run->debug.arch; + int hsr_ec = arch_info->hsr >> ARM_EL_EC_SHIFT; + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + /* Ensure PC is synchronised */ + kvm_cpu_synchronize_state(cs); + + switch (hsr_ec) { + case EC_AA64_BKPT: + if (kvm_find_sw_breakpoint(cs, env->pc)) { + return true; + } + break; + default: + error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")\n", + __func__, arch_info->hsr, env->pc); + } + + /* If we don't handle this it could be it really is for the + guest to handle */ + qemu_log_mask(LOG_UNIMP, + "%s: re-injecting exception not yet implemented" + " (0x%"PRIx32", %"PRIx64")\n", + __func__, hsr_ec, env->pc); + + return false; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { - return 0; + int ret = 0; + + switch (run->exit_reason) { + case KVM_EXIT_DEBUG: + if (kvm_handle_debug(cs, run)) { + ret = EXCP_DEBUG; + } /* otherwise return to guest */ + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", + __func__, run->exit_reason); + break; + } + return ret; } bool kvm_arch_stop_on_emulation_error(CPUState *cs) @@ -543,14 +595,34 @@ int kvm_arch_on_sigbus(int code, void *addr) void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) { - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); + if (kvm_sw_breakpoints_active(cs)) { + dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; + } } -int kvm_arch_insert_sw_breakpoint(CPUState *cs, - struct kvm_sw_breakpoint *bp) +/* C6.6.29 BRK instruction */ +static const uint32_t brk_insn = 0xd4200000; + +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return -EINVAL; + + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { + return -EINVAL; + } + return 0; +} + +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ + static uint32_t brk; + + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || + brk != brk_insn || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { + return -EINVAL; + } + return 0; } int kvm_arch_insert_hw_breakpoint(target_ulong addr, @@ -567,12 +639,6 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr, return -EINVAL; } -int kvm_arch_remove_sw_breakpoint(CPUState *cs, - struct kvm_sw_breakpoint *bp) -{ - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return -EINVAL; -} void kvm_arch_remove_all_hw_breakpoints(void) { -- 2.6.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: alex.bennee@linaro.org (=?UTF-8?q?Alex=20Benn=C3=A9e?=) Date: Thu, 12 Nov 2015 16:20:47 +0000 Subject: [PATCH v9 2/6] target-arm: kvm - implement software breakpoints In-Reply-To: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> References: <1447345251-22625-1-git-send-email-alex.bennee@linaro.org> Message-ID: <1447345251-22625-3-git-send-email-alex.bennee@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org These don't involve messing around with debug registers, just setting the breakpoint instruction in memory. GDB will not use this mechanism if it can't access the memory to write the breakpoint. All the kernel has to do is ensure the hypervisor traps the breakpoint exceptions and returns to userspace. Signed-off-by: Alex Benn?e -- v2 - handle debug exit with new hsr exception info - add verbosity to UNIMP message v3 - sync with kvm_cpu_synchronize_state() before checking PC. - use internals.h defines - use env->pc - use proper format types v9 - add include for error_report - define a brk_insn constant --- target-arm/kvm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 12 deletions(-) diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 79ef4c6..50f70ef 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -17,6 +17,7 @@ #include "qemu-common.h" #include "qemu/timer.h" +#include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "kvm_arm.h" @@ -516,9 +517,60 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) return MEMTXATTRS_UNSPECIFIED; } +/* See v8 ARM ARM D7.2.27 ESR_ELx, Exception Syndrome Register + * + * To minimise translating between kernel and user-space the kernel + * ABI just provides user-space with the full exception syndrome + * register value to be decoded in QEMU. + */ + +static int kvm_handle_debug(CPUState *cs, struct kvm_run *run) +{ + struct kvm_debug_exit_arch *arch_info = &run->debug.arch; + int hsr_ec = arch_info->hsr >> ARM_EL_EC_SHIFT; + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + /* Ensure PC is synchronised */ + kvm_cpu_synchronize_state(cs); + + switch (hsr_ec) { + case EC_AA64_BKPT: + if (kvm_find_sw_breakpoint(cs, env->pc)) { + return true; + } + break; + default: + error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")\n", + __func__, arch_info->hsr, env->pc); + } + + /* If we don't handle this it could be it really is for the + guest to handle */ + qemu_log_mask(LOG_UNIMP, + "%s: re-injecting exception not yet implemented" + " (0x%"PRIx32", %"PRIx64")\n", + __func__, hsr_ec, env->pc); + + return false; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { - return 0; + int ret = 0; + + switch (run->exit_reason) { + case KVM_EXIT_DEBUG: + if (kvm_handle_debug(cs, run)) { + ret = EXCP_DEBUG; + } /* otherwise return to guest */ + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", + __func__, run->exit_reason); + break; + } + return ret; } bool kvm_arch_stop_on_emulation_error(CPUState *cs) @@ -543,14 +595,34 @@ int kvm_arch_on_sigbus(int code, void *addr) void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) { - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); + if (kvm_sw_breakpoints_active(cs)) { + dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; + } } -int kvm_arch_insert_sw_breakpoint(CPUState *cs, - struct kvm_sw_breakpoint *bp) +/* C6.6.29 BRK instruction */ +static const uint32_t brk_insn = 0xd4200000; + +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return -EINVAL; + + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { + return -EINVAL; + } + return 0; +} + +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ + static uint32_t brk; + + if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || + brk != brk_insn || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { + return -EINVAL; + } + return 0; } int kvm_arch_insert_hw_breakpoint(target_ulong addr, @@ -567,12 +639,6 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr, return -EINVAL; } -int kvm_arch_remove_sw_breakpoint(CPUState *cs, - struct kvm_sw_breakpoint *bp) -{ - qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); - return -EINVAL; -} void kvm_arch_remove_all_hw_breakpoints(void) { -- 2.6.3