From patchwork Fri Dec 4 11:42:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Fedin X-Patchwork-Id: 7767231 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 793929F350 for ; Fri, 4 Dec 2015 11:43:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7DF242051C for ; Fri, 4 Dec 2015 11:43:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6D92320549 for ; Fri, 4 Dec 2015 11:43:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752304AbbLDLnJ (ORCPT ); Fri, 4 Dec 2015 06:43:09 -0500 Received: from mailout4.w1.samsung.com ([210.118.77.14]:60066 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751783AbbLDLnH (ORCPT ); Fri, 4 Dec 2015 06:43:07 -0500 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NYU003J60JTCEA0@mailout4.w1.samsung.com> for kvm@vger.kernel.org; Fri, 04 Dec 2015 11:43:05 +0000 (GMT) X-AuditID: cbfec7f4-f79026d00000418a-40-56617c48ec1b Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 5A.66.16778.84C71665; Fri, 4 Dec 2015 11:43:04 +0000 (GMT) Received: from fedinw7x64.rnd.samsung.ru ([106.109.131.169]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NYU006B60JNPB70@eusync1.samsung.com>; Fri, 04 Dec 2015 11:43:04 +0000 (GMT) From: Pavel Fedin To: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Cc: Marc Zyngier Subject: [PATCH v3 1/4] KVM: arm64: Correctly handle zero register during MMIO Date: Fri, 04 Dec 2015 14:42:56 +0300 Message-id: <1158b9cda9dc726342280bd36b0c06631f3d9e88.1449229272.git.p.fedin@samsung.com> X-Mailer: git-send-email 2.4.4 In-reply-to: References: In-reply-to: References: X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuplluLIzCtJLcpLzFFi42I5/e/4ZV2PmsQwg40LtC3mTC20+HjqOLvF 3zv/2ByYPdbMW8PocX7TGmaPz5vkApijuGxSUnMyy1KL9O0SuDK+3znNVNAsW3H0+me2BsZO iS5GTg4JAROJX792sEDYYhIX7q1n62Lk4hASWMoo8ffLFHYIp41Jouf7djaQKjYBdYnTXz+A dYgImEo8//eWFcRmBoo/3j0FzBYW8JPYerGTEcRmEVCV2LHpFTuIzSsQLbFx005GiG1yEleu TwebySlgLtE0ZzsTiC0kYCbxdv86JlziExj5FzAyrGIUTS1NLihOSs811CtOzC0uzUvXS87P 3cQICaQvOxgXH7M6xCjAwajEw8uwKSFMiDWxrLgy9xCjBAezkggvs0ximBBvSmJlVWpRfnxR aU5q8SFGaQ4WJXHeubvehwgJpCeWpGanphakFsFkmTg4pRoYLcSWLYp9m3hFM+mNsKOe2sK+ WznNP/16DMNCFG+zH3fm2Mez6ld7UZx3+HrbR0xzs/51yu8/bZebtpqflzdW7KzG+pMHpiTc SL09+1atsK66R9XF0KC7xz65Pr3EtvPPNe/YM3Pti3hPshysmLw+jM3J1HDJ0cuM03r7PshH nb3yY3LLvbaJSizFGYmGWsxFxYkAI0s8QSACAAA= Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On ARM64 register index of 31 corresponds to both zero register and SP. However, all memory access instructions, use ZR as transfer register. SP is used only as a base register in indirect memory addressing, or by register-register arithmetics, which cannot be trapped here. Correct emulation is achieved by introducing new register accessor functions, which can do special handling for reg_num == 31. These new accessors intentionally do not rely on old vcpu_reg() on ARM64, because it is to be removed. Since the affected code is shared by both ARM flavours, implementations of these accessors are also added to ARM32 code. This patch fixes setting MMIO register to a random value (actually SP) instead of zero by something like: *((volatile int *)reg) = 0; compilers tend to generate "str wzr, [xx]" here Signed-off-by: Pavel Fedin Reviewed-by: Marc Zyngier --- arch/arm/include/asm/kvm_emulate.h | 12 ++++++++++++ arch/arm/kvm/mmio.c | 5 +++-- arch/arm64/include/asm/kvm_emulate.h | 13 +++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index a9c80a2..b7ff32e 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -28,6 +28,18 @@ unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu); +static inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu, + u8 reg_num) +{ + return *vcpu_reg(vcpu, reg_num); +} + +static inline void vcpu_set_reg(const struct kvm_vcpu *vcpu, u8 reg_num, + unsigned long val) +{ + *vcpu_reg(vcpu, reg_num) = val; +} + bool kvm_condition_valid(struct kvm_vcpu *vcpu); void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr); void kvm_inject_undefined(struct kvm_vcpu *vcpu); diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c index 974b1c6..3a10c9f 100644 --- a/arch/arm/kvm/mmio.c +++ b/arch/arm/kvm/mmio.c @@ -115,7 +115,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, data); data = vcpu_data_host_to_guest(vcpu, data, len); - *vcpu_reg(vcpu, vcpu->arch.mmio_decode.rt) = data; + vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data); } return 0; @@ -186,7 +186,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, rt = vcpu->arch.mmio_decode.rt; if (is_write) { - data = vcpu_data_guest_to_host(vcpu, *vcpu_reg(vcpu, rt), len); + data = vcpu_data_guest_to_host(vcpu, vcpu_get_reg(vcpu, rt), + len); trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, len, fault_ipa, data); mmio_write_buf(data_buf, len, data); diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 3ca894e..5a182af 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -109,6 +109,19 @@ static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num) return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.regs[reg_num]; } +static inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu, + u8 reg_num) +{ + return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs.regs[reg_num]; +} + +static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, + unsigned long val) +{ + if (reg_num != 31) + vcpu_gp_regs(vcpu)->regs.regs[reg_num] = val; +} + /* Get vcpu SPSR for current mode */ static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu) {