From patchwork Tue Mar 31 15:08:05 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: 46594 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id F0504216E5 for ; Tue, 31 Mar 2015 15:14:00 +0000 (UTC) Received: by wiaa2 with SMTP id a2sf5166781wia.1 for ; Tue, 31 Mar 2015 08:14:00 -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:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type :content-transfer-encoding:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=l+gSIh5DS9jzgBxw0KQ2Ve5U8h+bQ4E+L+Y54DNLwWw=; b=TH4VsDnadO2UcGXP4KYBPF8V9uMFTN/FoFvDq4L3UwI06GJ+hX/9Ho43xCN+aQ3bnt FBaapBbH+elTLipMt00n5WCvUNifZRXvY0StS+hvrYUY7+Et01EvfOqr8/w1N6sdLCIV UxP2TNQQrTzRSCb12U7RItDE/zGc/HdyyZBq3CKY78HqmUyBFBfnvZRSgyp0JA48pTU8 4jSyPTbHvz2G8Zs8PF0qte/DXDxeMgwaMVXRqGTpZBqFjAnTAZc50RNY5UfZDMvwokyv suPxrg535UFRhHtneJUUCPvUwUiImbsvAr23kH4tep2aPdjYXGYZqOvOpLdIkrGkaHBF ulgQ== X-Gm-Message-State: ALoCoQlNPAcG6CL2iEUIHHfdOFAl2ge7c7WJsl8mH8sQrR58dTANTlr3/kVQ70m9WZ6G3sQlsF69 X-Received: by 10.112.201.232 with SMTP id kd8mr648902lbc.16.1427814840161; Tue, 31 Mar 2015 08:14:00 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.178.225 with SMTP id db1ls591568lac.78.gmail; Tue, 31 Mar 2015 08:13:59 -0700 (PDT) X-Received: by 10.112.202.6 with SMTP id ke6mr4172962lbc.46.1427814839953; Tue, 31 Mar 2015 08:13:59 -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 g4si9365990lbs.114.2015.03.31.08.13.59 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Mar 2015 08:13:59 -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 lbbug6 with SMTP id ug6so14858406lbb.3 for ; Tue, 31 Mar 2015 08:13:59 -0700 (PDT) X-Received: by 10.152.19.199 with SMTP id h7mr32269474lae.32.1427814839424; Tue, 31 Mar 2015 08:13:59 -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 k9csp47978lbq; Tue, 31 Mar 2015 08:13:58 -0700 (PDT) X-Received: by 10.66.167.232 with SMTP id zr8mr68594665pab.23.1427814830255; Tue, 31 Mar 2015 08:13:50 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ac10si19804452pac.147.2015.03.31.08.13.49; Tue, 31 Mar 2015 08:13:50 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754743AbbCaPMB (ORCPT + 27 others); Tue, 31 Mar 2015 11:12:01 -0400 Received: from static.88-198-71-155.clients.your-server.de ([88.198.71.155]:48127 "EHLO socrates.bennee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754582AbbCaPJB (ORCPT ); Tue, 31 Mar 2015 11:09:01 -0400 Received: from localhost ([127.0.0.1] helo=zen.linaroharston) by socrates.bennee.com with esmtp (Exim 4.80) (envelope-from ) id 1YcysW-0005gI-Iz; Tue, 31 Mar 2015 18:19:00 +0200 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com, peter.maydell@linaro.org, agraf@suse.de, drjones@redhat.com, pbonzini@redhat.com, zhichao.huang@linaro.org Cc: jan.kiszka@siemens.com, dahi@linux.vnet.ibm.com, r65777@freescale.com, bp@suse.de, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Gleb Natapov , Russell King , Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v2 07/10] KVM: arm64: guest debug, add support for single-step Date: Tue, 31 Mar 2015 16:08:05 +0100 Message-Id: <1427814488-28467-8-git-send-email-alex.bennee@linaro.org> X-Mailer: git-send-email 2.3.4 In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org> References: <1427814488-28467-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 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.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 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This adds support for single-stepping the guest. As userspace can and will manipulate guest registers before restarting any tweaking of the registers has to occur just before control is passed back to the guest. Furthermore while guest debugging is in effect we need to squash the ability of the guest to single-step itself as we have no easy way of re-entering the guest after the exception has been delivered to the hypervisor. Signed-off-by: Alex Bennée --- v2 - Move pstate/mdscr manipulation into C - don't export guest_debug to assembly - add accessor for saved_debug regs - tweak save/restore of mdscr_el1 diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index d3bc8dc..c1ed8cb 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -304,7 +304,21 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) kvm_arm_set_running_vcpu(NULL); } -#define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE|KVM_GUESTDBG_USE_SW_BP) +#define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE | \ + KVM_GUESTDBG_USE_SW_BP | \ + KVM_GUESTDBG_SINGLESTEP) + +/** + * kvm_arch_vcpu_ioctl_set_guest_debug - Setup guest debugging + * @kvm: pointer to the KVM struct + * @kvm_guest_debug: the ioctl data buffer + * + * This sets up the VM for guest debugging. Care has to be taken when + * manipulating guest registers as these will be set/cleared by the + * hyper-visor controller, typically before each kvm_run event. As a + * result modification of the guest registers needs to take place + * after they have been restored in the hyp.S trampoline code. + */ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 0631840..6a33647 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -121,6 +121,13 @@ struct kvm_vcpu_arch { * here. */ + /* Registers pre any guest debug manipulations */ + struct { + u32 pstate_ss_bit; + u32 mdscr_el1_bits; + + } debug_saved_regs; + /* Don't run the guest */ bool pause; @@ -143,6 +150,7 @@ struct kvm_vcpu_arch { #define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs) #define vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)]) +#define vcpu_debug_saved_reg(v, r) ((v)->arch.debug_saved_regs.r) /* * CP14 and CP15 live in the same array, as they are backed by the * same system registers. diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index cff0475..b32362c 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -19,8 +19,16 @@ #include +#include +#include #include #include +#include + +/* These are the bits of MDSCR_EL1 we may mess with */ +#define MDSCR_EL1_DEBUG_BITS (DBG_MDSCR_SS | \ + DBG_MDSCR_KDE | \ + DBG_MDSCR_MDE) /** * kvm_arch_setup_debug - set-up debug related stuff @@ -51,15 +59,46 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu) else vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA; - /* Trap breakpoints? */ - if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) + /* Is Guest debugging in effect? */ + if (vcpu->guest_debug) { vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; - else - vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE; + /* Save pstate/mdscr */ + vcpu_debug_saved_reg(vcpu, pstate_ss_bit) = + *vcpu_cpsr(vcpu) & DBG_SPSR_SS; + vcpu_debug_saved_reg(vcpu, mdscr_el1_bits) = + vcpu_sys_reg(vcpu, MDSCR_EL1) & MDSCR_EL1_DEBUG_BITS; + /* + * Single Step (ARM ARM D2.12.3 The software step state + * machine) + * + * If we are doing Single Step we need to manipulate + * MDSCR_EL1.SS and PSTATE.SS. If not we need to + * suppress the guest from messing with it. + */ + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { + *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; + vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS; + } else { + *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; + vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS; + } + + } else { + /* Debug operations can go straight to the guest */ + vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE; + } } void kvm_arch_clear_debug(struct kvm_vcpu *vcpu) { - /* Nothing to do yet */ + if (vcpu->guest_debug) { + /* Restore pstate/mdscr bits we may have messed with */ + *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; + *vcpu_cpsr(vcpu) |= vcpu_debug_saved_reg(vcpu, pstate_ss_bit); + + vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS; + vcpu_sys_reg(vcpu, MDSCR_EL1) |= + vcpu_debug_saved_reg(vcpu, mdscr_el1_bits); + } } diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index ed1bbb4..16accae 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -101,6 +101,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run) run->debug.arch.hsr = hsr; switch (hsr >> ESR_ELx_EC_SHIFT) { + case ESR_ELx_EC_SOFTSTP_LOW: case ESR_ELx_EC_BKPT32: case ESR_ELx_EC_BRK64: run->debug.arch.pc = *vcpu_pc(vcpu); @@ -127,6 +128,7 @@ static exit_handle_fn arm_exit_handlers[] = { [ESR_ELx_EC_SYS64] = kvm_handle_sys_reg, [ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort, [ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort, + [ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug, [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug, [ESR_ELx_EC_BRK64] = kvm_handle_guest_debug, };