From patchwork Tue Mar 31 15:40:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 46599 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CECAD2159A for ; Tue, 31 Mar 2015 15:42:16 +0000 (UTC) Received: by wibgr10 with SMTP id gr10sf5357824wib.2 for ; Tue, 31 Mar 2015 08:42:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding:cc :subject:precedence:list-id:list-unsubscribe:list-archive:list-post :list-help:list-subscribe:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=utK5zO2spvG3/qqH1OWfDcnPYyTc/wjr7UW/zjLhAJ0=; b=VIHIlLjTaEP7m/IyDjPnjPyHfauMpb7BeEtK+CIqIO5LVL2LDZMdwZ9RwBN57wkw3N 6cHWy5BFI8Zo2p8MubzZPab6eC8ZhFNzRpt6s/Gkgq8TjjzJhq3cp4+4Qt+dPtmcOgsk 1lyr+i8WJhkvFmnpjc6EqvxwmfpOZGHB9E2+z/h85qc/084CfhONK6u/JFmCNJiNOTzX BK0e7vuhv2TYcmMtQjqrWVU9YdnOdk73e42PjUHI2BFje+q46FkZLq8qt9nEjEBpKa+d y0L2ib4q8XFVert8SXZtlP1uLz8cT57AQXOHOQVAxtGWHxkEetOAl+F9LW1q7+dDK+du Y+Fg== X-Gm-Message-State: ALoCoQmvMRVU1MRTO1gkTOICZqpDBCbLSYChPmnqJS0byNTf9107gYAshOlMIxv2QUty/m5u8osi X-Received: by 10.112.151.232 with SMTP id ut8mr982561lbb.9.1427816536027; Tue, 31 Mar 2015 08:42:16 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.45.6 with SMTP id i6ls703433lam.10.gmail; Tue, 31 Mar 2015 08:42:15 -0700 (PDT) X-Received: by 10.152.10.180 with SMTP id j20mr4939096lab.54.1427816535883; Tue, 31 Mar 2015 08:42:15 -0700 (PDT) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id d5si9416244lag.58.2015.03.31.08.42.15 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Mar 2015 08:42:15 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by lboc7 with SMTP id c7so15534737lbo.1 for ; Tue, 31 Mar 2015 08:42:15 -0700 (PDT) X-Received: by 10.152.26.34 with SMTP id i2mr10106396lag.117.1427816535783; Tue, 31 Mar 2015 08:42:15 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.57.201 with SMTP id k9csp65591lbq; Tue, 31 Mar 2015 08:42:15 -0700 (PDT) X-Received: by 10.140.46.7 with SMTP id j7mr47441158qga.12.1427816534529; Tue, 31 Mar 2015 08:42:14 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [208.118.235.17]) by mx.google.com with ESMTPS id s8si14030351qce.45.2015.03.31.08.42.13 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 31 Mar 2015 08:42:14 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; Received: from localhost ([::1]:39266 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YcyIv-0000oR-P2 for patch@linaro.org; Tue, 31 Mar 2015 11:42:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42382) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YcyHo-0006Ks-E5 for qemu-devel@nongnu.org; Tue, 31 Mar 2015 11:41:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YcyHj-0004AO-Ae for qemu-devel@nongnu.org; Tue, 31 Mar 2015 11:41:04 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:54264 helo=socrates.bennee.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YcyHj-00049s-5O for qemu-devel@nongnu.org; Tue, 31 Mar 2015 11:40:59 -0400 Received: from localhost ([127.0.0.1] helo=zen.linaroharston) by socrates.bennee.com with esmtp (Exim 4.80) (envelope-from ) id 1YczNu-0005y0-2P; Tue, 31 Mar 2015 18:51:26 +0200 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org, peter.maydell@linaro.org, christoffer.dall@linaro.org, zhichao.huang@linaro.org Date: Tue, 31 Mar 2015 16:40:44 +0100 Message-Id: <1427816446-31586-3-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.3.4 In-Reply-To: <1427816446-31586-1-git-send-email-alex.bennee@linaro.org> References: <1427816446-31586-1-git-send-email-alex.bennee@linaro.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 127.0.0.1 X-SA-Exim-Mail-From: alex.bennee@linaro.org X-SA-Exim-Scanned: No (on socrates.bennee.com); SAEximRunCond expanded to false X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 88.198.71.155 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 Subject: [Qemu-devel] [PATCH v2 2/4] target-arm: kvm - implement software breakpoints X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: alex.bennee@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 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 diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 72c1fa1..290c1fe 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -25,6 +25,7 @@ #include "hw/arm/arm.h" const KVMCapabilityInfo kvm_arch_required_capabilities[] = { + KVM_CAP_INFO(SET_GUEST_DEBUG), KVM_CAP_LAST_INFO }; @@ -466,9 +467,57 @@ void kvm_arch_post_run(CPUState *cs, struct kvm_run *run) { } +/* See 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. +*/ + +#define HSR_EC_SHIFT 26 +#define HSR_EC_SW_BKPT 0x3c + +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 >> HSR_EC_SHIFT; + + switch (hsr_ec) { + case HSR_EC_SW_BKPT: + if (kvm_find_sw_breakpoint(cs, arch_info->pc)) { + return true; + } + break; + default: + error_report("%s: unhandled debug exit (%x, %llx)\n", + __func__, arch_info->hsr, arch_info->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%x, %llx)\n", + __func__, hsr_ec, arch_info->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) @@ -493,14 +542,33 @@ 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 */ +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; + static const uint32_t brk = 0xd4200000; + + 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, 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 != 0xd4200000 || + 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, @@ -517,12 +585,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) {