From patchwork Thu May 18 09:47:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9733071 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0D36E601A1 for ; Thu, 18 May 2017 09:47:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC7AD285F9 for ; Thu, 18 May 2017 09:47:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E14E72878C; Thu, 18 May 2017 09:47:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4ED51285F9 for ; Thu, 18 May 2017 09:47:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755384AbdERJr4 (ORCPT ); Thu, 18 May 2017 05:47:56 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:34901 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755078AbdERJro (ORCPT ); Thu, 18 May 2017 05:47:44 -0400 Received: by mail-wm0-f49.google.com with SMTP id b84so195118971wmh.0 for ; Thu, 18 May 2017 02:47:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cSUM4s6LtWektfvcez3nGO1N4fGRXlxHBWm1FVN+2Rs=; b=ep0RNG6RF8Lue/NbrQzaAE4SjpJDxh/eAbv8LdY8vlifGr9AqloAwnNbNpabvFvzXw MhCpgI5btrFKda43BNdUVbDKiJWTfQX37SqSBwO4h2gjj8p5E34LYh0MVPf7WffPndqv 2PURCtd5kxTrm1rfdp61rlbLOs4yjTteBKrbE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cSUM4s6LtWektfvcez3nGO1N4fGRXlxHBWm1FVN+2Rs=; b=pBdmyiBzECVs6hpkBct8phdivAHpm38RtkZ9jizMg3TOp1GP90AXdAxePJrIUo8hEh RkAlF5gML03GR4RWqMqpjWHV7ys+adHBsMR3k8vovzH7PMn/M4Tab+5lOBeAa4m3vegx BGl6fFO2ydGuNKkSoWYTlD8zJccH0QU3GY6qmXYnuU4lEvVZ53wOipF1jczwQNOU4LRb eEWX6nvy7GNJYQID0WPSdmNJV4+rcQiTVHnxkmrITEyOJGfjxE6v60Zd6gXNuzMI2UEH adSajZ27fOABFHoSUryUu6NyZrVrdGCEcXtbaXhC+d7G7VP5TTFs+r8ebgl0beK4gYB1 BIIA== X-Gm-Message-State: AODbwcDvotVVNT1k1kn6Sb8cLT72gc6M8GCwgj1W/RRc078aoobcerBd O9CZk2gZlit278PA X-Received: by 10.80.209.200 with SMTP id i8mr2616260edg.65.1495100862807; Thu, 18 May 2017 02:47:42 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id w15sm2377437edw.27.2017.05.18.02.47.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 May 2017 02:47:42 -0700 (PDT) From: Christoffer Dall To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Cc: Marc Zyngier , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Christoffer Dall Subject: [PULL 06/13] KVM: arm/arm64: vgic-v3: Use PREbits to infer the number of ICH_APxRn_EL2 registers Date: Thu, 18 May 2017 11:47:15 +0200 Message-Id: <20170518094722.9926-7-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170518094722.9926-1-cdall@linaro.org> References: <20170518094722.9926-1-cdall@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Marc Zyngier The GICv3 documentation is extremely confusing, as it talks about the number of priorities represented by the ICH_APxRn_EL2 registers, while it should really talk about the number of preemption levels. This leads to a bug where we may access undefined ICH_APxRn_EL2 registers, since PREbits is allowed to be smaller than PRIbits. Thankfully, nobody seem to have taken this path so far... The fix is to use ICH_VTR_EL2.PREbits instead. Signed-off-by: Marc Zyngier Reviewed-by: Christoffer Dall Signed-off-by: Christoffer Dall --- virt/kvm/arm/hyp/vgic-v3-sr.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c index bce6037..32c3295 100644 --- a/virt/kvm/arm/hyp/vgic-v3-sr.c +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c @@ -22,7 +22,7 @@ #include #define vtr_to_max_lr_idx(v) ((v) & 0xf) -#define vtr_to_nr_pri_bits(v) (((u32)(v) >> 29) + 1) +#define vtr_to_nr_pre_bits(v) (((u32)(v) >> 26) + 1) static u64 __hyp_text __gic_v3_get_lr(unsigned int lr) { @@ -135,13 +135,13 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) if (used_lrs) { int i; - u32 nr_pri_bits; + u32 nr_pre_bits; cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2); write_gicreg(0, ICH_HCR_EL2); val = read_gicreg(ICH_VTR_EL2); - nr_pri_bits = vtr_to_nr_pri_bits(val); + nr_pre_bits = vtr_to_nr_pre_bits(val); for (i = 0; i < used_lrs; i++) { if (cpu_if->vgic_elrsr & (1 << i)) @@ -152,7 +152,7 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) __gic_v3_set_lr(0, i); } - switch (nr_pri_bits) { + switch (nr_pre_bits) { case 7: cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2); cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2); @@ -162,7 +162,7 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu) cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2); } - switch (nr_pri_bits) { + switch (nr_pre_bits) { case 7: cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2); cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2); @@ -198,7 +198,7 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs; u64 val; - u32 nr_pri_bits; + u32 nr_pre_bits; int i; /* @@ -217,12 +217,12 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) } val = read_gicreg(ICH_VTR_EL2); - nr_pri_bits = vtr_to_nr_pri_bits(val); + nr_pre_bits = vtr_to_nr_pre_bits(val); if (used_lrs) { write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2); - switch (nr_pri_bits) { + switch (nr_pre_bits) { case 7: write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2); write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2); @@ -232,7 +232,7 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu) write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2); } - switch (nr_pri_bits) { + switch (nr_pre_bits) { case 7: write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2); write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);