From patchwork Mon Aug 10 13:26:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhichao Huang X-Patchwork-Id: 52260 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by patches.linaro.org (Postfix) with ESMTPS id 5F01D22919 for ; Mon, 10 Aug 2015 13:34:42 +0000 (UTC) Received: by labth1 with SMTP id th1sf61779856lab.2 for ; Mon, 10 Aug 2015 06:34:41 -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:subject:date:message-id :in-reply-to:references:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:cc:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=Qy1+4wqvgtigK5t0XQJz+5y3GKqH/DwVCZcfhZf+xRU=; b=TBg5Nqkb3BrdT8wYQt9XIM3q7PhPmo42NspnI4FoRiOlDvhfgoPylwEw/MHReOHrSt zy4+0ehA9H1N8qg7KtvIBCdpJE5gabCE9MECxVoT8yLUnSvSocPQB7x0WFSZtVZhfNQt CBS7wzQCT505s5tVrKD5CQ/3rS3aATKp3s7lTJe/oX3IuhQ+HcAtpY7+JcBCcU2+cZnn o7EgYK/TVs71i8fJEZ5qG1OUW+rJLuQnLxw6dPo2onuwuTtB2YjPALdgJBq8CEixkGTw a0JhBF+WCGoBT0pWLHD2hbpf76hA1Y0MAGbAdiJ4wqjfU2GGKsfRSP9T5lNp6YwfmpgH GcSQ== X-Gm-Message-State: ALoCoQmXM0Vx6yEiAaXlQkmpQyIaornU1IMBmBa5P4Q1PyFdIDA1psHkQzY6s9U7N1NrvC4kKBQi X-Received: by 10.112.189.105 with SMTP id gh9mr1114384lbc.16.1439213681321; Mon, 10 Aug 2015 06:34:41 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.29.170 with SMTP id l10ls167005lah.82.gmail; Mon, 10 Aug 2015 06:34:41 -0700 (PDT) X-Received: by 10.152.8.234 with SMTP id u10mr20022980laa.8.1439213681040; Mon, 10 Aug 2015 06:34:41 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id l6si14055840lbm.27.2015.08.10.06.34.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Aug 2015 06:34:40 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by lbbtg9 with SMTP id tg9so57329041lbb.1 for ; Mon, 10 Aug 2015 06:34:40 -0700 (PDT) X-Received: by 10.112.129.137 with SMTP id nw9mr13901862lbb.19.1439213680849; Mon, 10 Aug 2015 06:34:40 -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.7.198 with SMTP id l6csp1938418lba; Mon, 10 Aug 2015 06:34:39 -0700 (PDT) X-Received: by 10.70.98.230 with SMTP id el6mr24522867pdb.81.1439213678962; Mon, 10 Aug 2015 06:34:38 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id qx7si33168789pab.134.2015.08.10.06.34.37 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Aug 2015 06:34:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZOnCP-0004uC-UM; Mon, 10 Aug 2015 13:33:09 +0000 Received: from mail-pd0-f178.google.com ([209.85.192.178]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZOn8f-0007xP-Rc for linux-arm-kernel@lists.infradead.org; Mon, 10 Aug 2015 13:29:22 +0000 Received: by pdrh1 with SMTP id h1so53646817pdr.0 for ; Mon, 10 Aug 2015 06:28:56 -0700 (PDT) X-Received: by 10.70.132.228 with SMTP id ox4mr45152520pdb.0.1439213336641; Mon, 10 Aug 2015 06:28:56 -0700 (PDT) Received: from localhost ([199.168.112.128]) by smtp.gmail.com with ESMTPSA id nx1sm20105127pab.6.2015.08.10.06.28.53 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 10 Aug 2015 06:28:55 -0700 (PDT) From: Zhichao Huang To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com, alex.bennee@linaro.org, will.deacon@arm.com Subject: [PATCH v4 13/15] KVM: arm: keep track of guest use of the debug registers Date: Mon, 10 Aug 2015 21:26:05 +0800 Message-Id: <1439213167-8988-14-git-send-email-zhichao.huang@linaro.org> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org> References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150810_062918_448231_34479C95 X-CRM114-Status: GOOD ( 17.95 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.192.178 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.192.178 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Cc: huangzhichao@huawei.com, Zhichao Huang MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: zhichao.huang@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.174 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 We trap debug register accesses from guest all the time, and read the BCR/WCR to indicate whether the guest has enabled any break/watch points or not. Signed-off-by: Zhichao Huang --- arch/arm/include/asm/kvm_asm.h | 2 ++ arch/arm/kvm/coproc.c | 75 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 5b1c3eb..e9e1f0a 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -65,7 +65,9 @@ #define NR_CP14_REGS 66 /* Number of regs (incl. invalid) */ #define KVM_ARM_DEBUG_HOST_INUSE_SHIFT 0 +#define KVM_ARM_DEBUG_GUEST_INUSE_SHIFT 1 #define KVM_ARM_DEBUG_HOST_INUSE (1 << KVM_ARM_DEBUG_HOST_INUSE_SHIFT) +#define KVM_ARM_DEBUG_GUEST_INUSE (1 << KVM_ARM_DEBUG_GUEST_INUSE_SHIFT) #define ARM_EXCEPTION_RESET 0 #define ARM_EXCEPTION_UNDEFINED 1 diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index b37afd6..d9dcd28b 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -220,7 +220,22 @@ bool access_vm_reg(struct kvm_vcpu *vcpu, return true; } -static bool trap_debug32(struct kvm_vcpu *vcpu, +/* Indicate whether the guest has enabled any break/watch points or not. */ +static bool guest_debug_in_use(struct kvm_vcpu *vcpu) +{ + unsigned int i; + + for (i = 0; i < ARM_MAX_BRP; i++) + if (vcpu->arch.cp14[cp14_DBGBCR0 + i] & 0x1) + return true; + for (i = 0; i < ARM_MAX_WRP; i++) + if (vcpu->arch.cp14[cp14_DBGWCR0 + i] & 0x1) + return true; + + return false; +} + +static bool __trap_debug32(struct kvm_vcpu *vcpu, const struct coproc_params *p, const struct coproc_reg *r) { @@ -232,6 +247,56 @@ static bool trap_debug32(struct kvm_vcpu *vcpu, return true; } +/* + * We want to avoid world-switching all the DBG registers all the + * time: + * + * When we are about to run a guest, we have the following cases: + * + * 1) Neither the host nor the guest has configured any [WB]points + * 2) Only the host has configured any [WB]points + * 3) Only the guest has configured any [WB]points + * 4) Both the host and the guest have configured any [WB]points + * + * - In case (1), KVM should enable trapping and swtich the register + * state on guest accesses. + * - In cases (2), (3), and (4) we must switch the register state on each + * entry/exit. + * + * For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set, ARM_DSCR_MDBGEN + * is always set(ARM64 use it to indicate that debug registers are actively + * in use). + * + * - We add a function reading the break/watch control variables directly to + * indicate whether the host has enabled any break/watch points or not. + * We only call the function upon guest entry, after preempt_disable() and + * local_irq_disable(), so there is no race for it. + * + * - We trap debug register accesses from guest all the time, and read the + * BCR/WCR to indicate whether the guest has enabled any break/watch points + * or not. + * + * For this, we can keep track of the host/guest use of debug registers, + * and skip the save/restore dance when neither the host nor the guest has + * configured any [WB]points. + */ +static bool trap_debug32(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + const struct coproc_reg *r) +{ + __trap_debug32(vcpu, p, r); + + if (p->is_write) { + if ((vcpu->arch.cp14[r->reg] & 0x1) || + guest_debug_in_use(vcpu)) + vcpu->arch.debug_flags |= KVM_ARM_DEBUG_GUEST_INUSE; + else + vcpu->arch.debug_flags &= ~KVM_ARM_DEBUG_GUEST_INUSE; + } + + return true; +} + /* DBGIDR (RO) Debug ID */ static bool trap_dbgidr(struct kvm_vcpu *vcpu, const struct coproc_params *p, @@ -419,13 +484,13 @@ static const struct coproc_reg cp15_regs[] = { #define DBG_BCR_BVR_WCR_WVR(n) \ /* DBGBVRn */ \ { CRn( 0), CRm((n)), Op1( 0), Op2( 4), is32, \ - trap_debug32, reset_val, (cp14_DBGBVR0 + (n)), 0 }, \ + __trap_debug32, reset_val, (cp14_DBGBVR0 + (n)), 0 }, \ /* DBGBCRn */ \ { CRn( 0), CRm((n)), Op1( 0), Op2( 5), is32, \ trap_debug32, reset_val, (cp14_DBGBCR0 + (n)), 0 }, \ /* DBGWVRn */ \ { CRn( 0), CRm((n)), Op1( 0), Op2( 6), is32, \ - trap_debug32, reset_val, (cp14_DBGWVR0 + (n)), 0 }, \ + __trap_debug32, reset_val, (cp14_DBGWVR0 + (n)), 0 }, \ /* DBGWCRn */ \ { CRn( 0), CRm((n)), Op1( 0), Op2( 7), is32, \ trap_debug32, reset_val, (cp14_DBGWCR0 + (n)), 0 } @@ -462,7 +527,7 @@ static const struct coproc_reg cp14_regs[] = { /* DBGDSAR (64bit) */ { CRn( 0), CRm( 2), Op1( 0), Op2( 0), is64, trap_raz_wi }, /* DBGDSCRext */ - { CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, trap_debug32, + { CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, __trap_debug32, reset_val, cp14_DBGDSCRext, 0 }, DBG_BCR_BVR_WCR_WVR(2), /* DBGDTRTXext */ @@ -474,7 +539,7 @@ static const struct coproc_reg cp14_regs[] = { DBG_BCR_BVR_WCR_WVR(5), DBG_BCR_BVR_WCR_WVR(6), /* DBGVCR */ - { CRn( 0), CRm( 7), Op1( 0), Op2( 0), is32, trap_debug32 }, + { CRn( 0), CRm( 7), Op1( 0), Op2( 0), is32, __trap_debug32 }, DBG_BCR_BVR_WCR_WVR(7), DBG_BCR_BVR_WCR_WVR(8), DBG_BCR_BVR_WCR_WVR(9),