From patchwork Mon Aug 10 13:25:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhichao Huang X-Patchwork-Id: 52247 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f198.google.com (mail-lb0-f198.google.com [209.85.217.198]) by patches.linaro.org (Postfix) with ESMTPS id A317822919 for ; Mon, 10 Aug 2015 13:30:11 +0000 (UTC) Received: by lbck9 with SMTP id k9sf10337705lbc.0 for ; Mon, 10 Aug 2015 06:30:10 -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=851TIJwp+yAPgSe8buQkZnjFGXsg2bOm81DhmNPu9Ww=; b=l+Up1GHt2VRUESbSPwkENOiS1WaCbBWP0CZEKtjvN9OEC9rX3U5x7gMlPTkBleVbU0 ZTw4bWBn2+zNRVH7k1rMDM3L5b5D/sYjyNX6qe8FWKXhxB64rWEA7tGwyhXzr70YD4+J AOH9KdIeSIGcEVxOU6iTc0IN71KKDr18fWXSKrX9DJmyp2YqhE/pGzKjq5DtgyqWrmYu kuVM9AHs7NKhXuTD6k8SroEmr6YybKD/naDLejHwvdQrd/9I5waOypXWDELrXVUKSDoY Cj9iRRuNYL9rpw+17dDy/hRkyELVHz4oE4QvaIXkZJMfDk9wb6NjUr5FZnCyYKDX5i2G dWkA== X-Gm-Message-State: ALoCoQn5iT5F2mInOx2Guy7NxB/rK/9kW52jj+Nkkpe7UsCODHFnurUkClmxaBwjtKvAGT9Ip85Q X-Received: by 10.152.45.101 with SMTP id l5mr4681851lam.7.1439213410605; Mon, 10 Aug 2015 06:30:10 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.224.129 with SMTP id rc1ls669222lac.25.gmail; Mon, 10 Aug 2015 06:30:10 -0700 (PDT) X-Received: by 10.152.25.228 with SMTP id f4mr20066379lag.25.1439213410455; Mon, 10 Aug 2015 06:30:10 -0700 (PDT) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com. [209.85.215.43]) by mx.google.com with ESMTPS id s6si1088971laj.75.2015.08.10.06.30.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Aug 2015 06:30:10 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by labd1 with SMTP id d1so39966007lab.1 for ; Mon, 10 Aug 2015 06:30:10 -0700 (PDT) X-Received: by 10.152.36.102 with SMTP id p6mr19965519laj.19.1439213410320; Mon, 10 Aug 2015 06:30:10 -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 l6csp1935943lba; Mon, 10 Aug 2015 06:30:08 -0700 (PDT) X-Received: by 10.67.15.67 with SMTP id fm3mr43880669pad.114.1439213408022; Mon, 10 Aug 2015 06:30:08 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id ou7si33012251pbc.219.2015.08.10.06.30.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 10 Aug 2015 06:30:08 -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 1ZOn7x-0007Yw-DA; Mon, 10 Aug 2015 13:28:34 +0000 Received: from mail-pa0-f43.google.com ([209.85.220.43]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZOn6d-00061W-4Y for linux-arm-kernel@lists.infradead.org; Mon, 10 Aug 2015 13:27:29 +0000 Received: by pacgr6 with SMTP id gr6so27274316pac.2 for ; Mon, 10 Aug 2015 06:26:50 -0700 (PDT) X-Received: by 10.66.136.172 with SMTP id qb12mr45254262pab.84.1439213210040; Mon, 10 Aug 2015 06:26:50 -0700 (PDT) Received: from localhost ([199.168.112.128]) by smtp.gmail.com with ESMTPSA id z4sm20023249pdo.88.2015.08.10.06.26.47 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 10 Aug 2015 06:26:49 -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 04/15] KVM: arm: common infrastructure for handling AArch32 CP14/CP15 Date: Mon, 10 Aug 2015 21:25:56 +0800 Message-Id: <1439213167-8988-5-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_062711_747705_6BE40A65 X-CRM114-Status: GOOD ( 18.22 ) 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.220.43 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.220.43 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.215.43 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 As we're about to trap a bunch of CP14 registers, let's rework the CP15 handling so it can be generalized and work with multiple tables. We stop trapping access here, because we haven't finished our trap handlers. We will enable trapping agian until everything is OK. Signed-off-by: Zhichao Huang --- arch/arm/kvm/coproc.c | 168 ++++++++++++++++++++++++++--------------- arch/arm/kvm/interrupts_head.S | 2 +- 2 files changed, 110 insertions(+), 60 deletions(-) diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 4db571d..d23395b 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c @@ -375,6 +375,9 @@ static const struct coproc_reg cp15_regs[] = { { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar}, }; +static const struct coproc_reg cp14_regs[] = { +}; + /* Target specific emulation tables */ static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS]; @@ -424,43 +427,75 @@ static const struct coproc_reg *find_reg(const struct coproc_params *params, return NULL; } -static int emulate_cp15(struct kvm_vcpu *vcpu, - const struct coproc_params *params) +/* + * emulate_cp -- tries to match a cp14/cp15 access in a handling table, + * and call the corresponding trap handler. + * + * @params: pointer to the descriptor of the access + * @table: array of trap descriptors + * @num: size of the trap descriptor array + * + * Return 0 if the access has been handled, and -1 if not. + */ +static int emulate_cp(struct kvm_vcpu *vcpu, + const struct coproc_params *params, + const struct coproc_reg *table, + size_t num) { - size_t num; - const struct coproc_reg *table, *r; - - trace_kvm_emulate_cp15_imp(params->Op1, params->Rt1, params->CRn, - params->CRm, params->Op2, params->is_write); + const struct coproc_reg *r; - table = get_target_table(vcpu->arch.target, &num); + if (!table) + return -1; /* Not handled */ - /* Search target-specific then generic table. */ r = find_reg(params, table, num); - if (!r) - r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs)); - if (likely(r)) { + if (r) { /* If we don't have an accessor, we should never get here! */ BUG_ON(!r->access); if (likely(r->access(vcpu, params, r))) { /* Skip instruction, since it was emulated */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); - return 1; } - /* If access function fails, it should complain. */ - } else { - kvm_err("Unsupported guest CP15 access at: %08lx\n", - *vcpu_pc(vcpu)); - print_cp_instr(params); + + /* Handled */ + return 0; } + + /* Not handled */ + return -1; +} + +static void unhandled_cp_access(struct kvm_vcpu *vcpu, + const struct coproc_params *params) +{ + u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu); + int cp; + + switch (hsr_ec) { + case HSR_EC_CP15_32: + case HSR_EC_CP15_64: + cp = 15; + break; + case HSR_EC_CP14_MR: + case HSR_EC_CP14_64: + cp = 14; + break; + default: + WARN_ON((cp = -1)); + } + + kvm_err("Unsupported guest CP%d access at: %08lx\n", + cp, *vcpu_pc(vcpu)); + print_cp_instr(params); kvm_inject_undefined(vcpu); - return 1; } -static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run, - bool cp15) +int kvm_handle_cp_64(struct kvm_vcpu *vcpu, + const struct coproc_reg *global, + size_t nr_global, + const struct coproc_reg *target_specific, + size_t nr_specific) { struct coproc_params params; @@ -474,37 +509,15 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run, params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; params.CRm = 0; - if (cp15) - return emulate_cp15(vcpu, ¶ms); + if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) + return 1; + if (!emulate_cp(vcpu, ¶ms, global, nr_global)) + return 1; - /* raz_wi cp14 */ - (void)trap_raz_wi(vcpu, ¶ms, NULL); - - /* handled */ - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + unhandled_cp_access(vcpu, ¶ms); return 1; } -/** - * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access - * @vcpu: The VCPU pointer - * @run: The kvm_run struct - */ -int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - return kvm_handle_cp_64(vcpu, run, 1); -} - -/** - * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access - * @vcpu: The VCPU pointer - * @run: The kvm_run struct - */ -int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - return kvm_handle_cp_64(vcpu, run, 0); -} - static void reset_coproc_regs(struct kvm_vcpu *vcpu, const struct coproc_reg *table, size_t num) { @@ -515,8 +528,11 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu, table[i].reset(vcpu, &table[i]); } -static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run, - bool cp15) +int kvm_handle_cp_32(struct kvm_vcpu *vcpu, + const struct coproc_reg *global, + size_t nr_global, + const struct coproc_reg *target_specific, + size_t nr_specific) { struct coproc_params params; @@ -530,25 +546,57 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run, params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7; params.Rt2 = 0; - if (cp15) - return emulate_cp15(vcpu, ¶ms); - - /* raz_wi cp14 */ - (void)trap_raz_wi(vcpu, ¶ms, NULL); + if (!emulate_cp(vcpu, ¶ms, target_specific, nr_specific)) + return 1; + if (!emulate_cp(vcpu, ¶ms, global, nr_global)) + return 1; - /* handled */ - kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); + unhandled_cp_access(vcpu, ¶ms); return 1; } /** + * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access + * @vcpu: The VCPU pointer + * @run: The kvm_run struct + */ +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + const struct coproc_reg *target_specific; + size_t num; + + target_specific = get_target_table(vcpu->arch.target, &num); + return kvm_handle_cp_64(vcpu, + cp15_regs, ARRAY_SIZE(cp15_regs), + target_specific, num); +} + +/** * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { - return kvm_handle_cp_32(vcpu, run, 1); + const struct coproc_reg *target_specific; + size_t num; + + target_specific = get_target_table(vcpu->arch.target, &num); + return kvm_handle_cp_32(vcpu, + cp15_regs, ARRAY_SIZE(cp15_regs), + target_specific, num); +} + +/** + * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access + * @vcpu: The VCPU pointer + * @run: The kvm_run struct + */ +int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + return kvm_handle_cp_64(vcpu, + cp14_regs, ARRAY_SIZE(cp14_regs), + NULL, 0); } /** @@ -558,7 +606,9 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) */ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { - return kvm_handle_cp_32(vcpu, run, 0); + return kvm_handle_cp_32(vcpu, + cp14_regs, ARRAY_SIZE(cp14_regs), + NULL, 0); } /****************************************************************************** diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index 7c4075c..7ac5e51 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S @@ -633,7 +633,7 @@ ARM_BE8(rev r6, r6 ) * (hardware reset value is 0) */ .macro set_hdcr operation mrc p15, 4, r2, c1, c1, 1 - ldr r3, =(HDCR_TPM|HDCR_TPMCR|HDCR_TDRA|HDCR_TDOSA|HDCR_TDA) + ldr r3, =(HDCR_TPM|HDCR_TPMCR) .if \operation == vmentry orr r2, r2, r3 @ Trap some perfmon accesses .else