From patchwork Tue Mar 21 11:05:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9636409 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 34EA2602CC for ; Tue, 21 Mar 2017 11:16:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 36D4426E4C for ; Tue, 21 Mar 2017 11:16:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2BE0227CF9; Tue, 21 Mar 2017 11:16:07 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0A18F2793A for ; Tue, 21 Mar 2017 11:16:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=lNKMWXeE/o2Nshe5lo1Ccf4dXUBuS6feABZdVqa2ew4=; b=td+SM5tmzJ3ViRC7o4XrOZb3/0 /21OgNW+DphHIipkaJavxIf3H2/rrZE5Mi/Jk9N3jSLg9084A90PrQVtVclCx2/k9N0/v9Gthszvm ypuIOF1zHtWpSZfVg6N7tZDRIwpjhihzW2/cGBhyvcnKv7P9UyCc1X2OVP7Ocss9w37KD4ZZasgua 4EUvTgCACU6Xujgpieh25H4a2fgZL6+pRRXDyHfB0l7if4gm/gc1aIKfzQW5J3NS/BYUgk/frDqJR dK0ijGGblSxbh5Qp9/aYc3k52neE6cTt+pdwK49C/0/6mp6zDhciVboqtm9uKt5jB3Xd/+itfiXKr gmEM1UgA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cqHli-0001l9-Ii; Tue, 21 Mar 2017 11:16:02 +0000 Received: from mail-wm0-x234.google.com ([2a00:1450:400c:c09::234]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cqHc2-0004Vr-H0 for linux-arm-kernel@lists.infradead.org; Tue, 21 Mar 2017 11:06:06 +0000 Received: by mail-wm0-x234.google.com with SMTP id n11so9557741wma.0 for ; Tue, 21 Mar 2017 04:05: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=qAIkR/EaLRaPSupBaMZduJ/M/XZ89SYIZ/EumT66aTw=; b=aqXjbwgYosWExAuWIhboHcp/+v+AeINvN4toV6w8wb4aKCoDsHloVdKleIwyRMWq2r Snoh2c4Sii0v2+rsYwqjryfhepDWtNvBar2pqdBTmMaV67sC7O/wo34V0U27L7o96U/e u1AXRulLGPNKPQJ0q0tNW793XfVVZ2woQ9yVE= 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=qAIkR/EaLRaPSupBaMZduJ/M/XZ89SYIZ/EumT66aTw=; b=hafFFTiaMxwULAHfaZuRwOQ+XYGXLzZBuQDH2k4k/uCkC+t4eymWdRILgJn1+iZXgK DT/gryIiNABDARyr1q8fP478gq+40i2e9okzYpARtjYNsW6Kf7V3SAZ90165bWGEz/1q ZbiB6ZPI4MlyjuHDldKaTSe7zJp6/GMpDnSXMVT7TkdPj7XOPx8GSVie032deUjIrNll gJWH1aXsZuFd94AvZ4r968XF+oztpx428qM+24WxGQ1Rqm4xVgfbmWD9TygP31jdBTNU 0e64ihIB57EawdNpOnHgeDdWiLXztX1Lrx/Yv7q4p3MyLAAsiOIfINYG3RcwDfk0PcGB VPdw== X-Gm-Message-State: AFeK/H2eM9WPp4IIVhxLp27KBMH6qMpVD0XXExqoIXLm3+bXzEWlRlJJEwPIxUBWLdt2txR5 X-Received: by 10.28.37.135 with SMTP id l129mr2086600wml.49.1490094342190; Tue, 21 Mar 2017 04:05:42 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id f48sm24358252wrf.17.2017.03.21.04.05.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 Mar 2017 04:05:41 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH 4/5] KVM: arm64: vgic: Get rid of struct vmcr for GICv3 Date: Tue, 21 Mar 2017 12:05:29 +0100 Message-Id: <20170321110530.15857-5-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170321110530.15857-1-cdall@linaro.org> References: <20170321110530.15857-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170321_040603_013269_4BFA214E X-CRM114-Status: GOOD ( 17.49 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Christoffer Dall , kvm@vger.kernel.org, Marc Zyngier , Andre Przywara , Vijaya.Kumar@cavium.com, Eric Auger MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP There is no common code in the VGIC that uses the VMCR, so we have no use of the intermediate architecture-agnostic representation of the VMCR and might as well manipulate the bits specifically using the logic for the version of the GIC that the code supports. For GICv3, this means translating between the ICH_VMCR register format stored in memory and the ICC_X_EL1 registers exported to user space. Signed-off-by: Christoffer Dall --- arch/arm64/kvm/vgic-sys-reg-v3.c | 133 +++++++++++++++------------------------ virt/kvm/arm/vgic/vgic-mmio.c | 4 +- virt/kvm/arm/vgic/vgic-v3.c | 38 ----------- virt/kvm/arm/vgic/vgic.h | 2 - 4 files changed, 53 insertions(+), 124 deletions(-) diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c index 33f111c..cd51433 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c @@ -21,10 +21,9 @@ static bool write_gic_ctlr(struct kvm_vcpu *vcpu, u32 val) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + u32 *vmcr = &vgic_cpu->vgic_v3.vgic_vmcr; u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v; - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); + u32 cbpr, eoimode; /* * Disallow restoring VM state if not supported by this @@ -57,24 +56,26 @@ static bool write_gic_ctlr(struct kvm_vcpu *vcpu, u32 val) if (host_a3v != a3v) return false; - /* - * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. - * The vgic_set_vmcr() will convert to ICH_VMCR layout. - */ - vmcr.ctlr = val & ICC_CTLR_EL1_CBPR_MASK; - vmcr.ctlr |= val & ICC_CTLR_EL1_EOImode_MASK; + /* Mask off any immutable bits from the ICC_CTLR_EL1 layout. */ + eoimode = val & ICC_CTLR_EL1_EOImode_MASK; + cbpr = val & ICC_CTLR_EL1_CBPR_MASK; - vgic_set_vmcr(vcpu, &vmcr); + /* Convert the remaining bits to ICH_VMCR layout. */ + *vmcr &= ~(ICH_VMCR_EOIM_MASK | ICH_VMCR_CBPR_MASK); + *vmcr |= (eoimode >> ICC_CTLR_EL1_EOImode_SHIFT) << + ICH_VMCR_EOIM_SHIFT; + *vmcr |= (cbpr >> ICC_CTLR_EL1_CBPR_SHIFT) << + ICH_VMCR_CBPR_SHIFT; + + *vmcr = val; return true; } static u32 read_gic_ctlr(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + u32 vmcr = vgic_cpu->vgic_v3.vgic_vmcr; u32 val = 0; - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); val |= (vgic_cpu->num_pri_bits - 1) << ICC_CTLR_EL1_PRI_BITS_SHIFT; @@ -85,12 +86,12 @@ static u32 read_gic_ctlr(struct kvm_vcpu *vcpu) val |= ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) << ICC_CTLR_EL1_A3V_SHIFT; - /* - * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. - * Extract it directly using ICC_CTLR_EL1 reg definitions. - */ - val |= vmcr.ctlr & ICC_CTLR_EL1_CBPR_MASK; - val |= vmcr.ctlr & ICC_CTLR_EL1_EOImode_MASK; + + /* Convert the data in the ICH_VMCR_EL1 to the ICC_CTLR_EL1 layout */ + val |= ((vmcr & ICH_VMCR_EOIM_MASK) >> ICH_VMCR_EOIM_SHIFT) << + ICC_CTLR_EL1_EOImode_SHIFT; + val |= ((vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT) << + ICC_CTLR_EL1_CBPR_SHIFT; return val; } @@ -108,99 +109,67 @@ static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return ret; } -static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) +static void access_vmcr_field(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + u32 ich_mask, u32 ich_shift, u32 icc_shift) { - struct vgic_vmcr vmcr; + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + u32 *vmcr = &vgic_cpu->vgic_v3.vgic_vmcr; - vgic_get_vmcr(vcpu, &vmcr); if (p->is_write) { - vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT; - vgic_set_vmcr(vcpu, &vmcr); + *vmcr &= ~ich_mask; + *vmcr |= ((p->regval >> icc_shift) << ich_shift) & ich_mask; } else { - p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK; + p->regval = ((*vmcr & ich_mask) >> ich_shift) << icc_shift; } +} +static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + access_vmcr_field(vcpu, p, + ICH_VMCR_PMR_MASK, + ICH_VMCR_PMR_SHIFT, + ICC_PMR_EL1_SHIFT); return true; } static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); - if (p->is_write) { - vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >> - ICC_BPR0_EL1_SHIFT; - vgic_set_vmcr(vcpu, &vmcr); - } else { - p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) & - ICC_BPR0_EL1_MASK; - } - + access_vmcr_field(vcpu, p, + ICH_VMCR_BPR0_MASK, + ICH_VMCR_BPR0_SHIFT, + ICC_BPR0_EL1_SHIFT); return true; } static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - struct vgic_vmcr vmcr; - - if (!p->is_write) - p->regval = 0; - - vgic_get_vmcr(vcpu, &vmcr); - if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) { - if (p->is_write) { - vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >> - ICC_BPR1_EL1_SHIFT; - vgic_set_vmcr(vcpu, &vmcr); - } else { - p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) & - ICC_BPR1_EL1_MASK; - } - } else { - if (!p->is_write) - p->regval = min((vmcr.bpr + 1), 7U); - } - + access_vmcr_field(vcpu, p, + ICH_VMCR_BPR1_MASK, + ICH_VMCR_BPR1_SHIFT, + ICC_BPR1_EL1_SHIFT); return true; } static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); - if (p->is_write) { - vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >> - ICC_IGRPEN0_EL1_SHIFT; - vgic_set_vmcr(vcpu, &vmcr); - } else { - p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) & - ICC_IGRPEN0_EL1_MASK; - } - + access_vmcr_field(vcpu, p, + ICH_VMCR_ENG0_MASK, + ICH_VMCR_ENG0_SHIFT, + ICC_IGRPEN0_EL1_SHIFT); return true; } static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); - if (p->is_write) { - vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >> - ICC_IGRPEN1_EL1_SHIFT; - vgic_set_vmcr(vcpu, &vmcr); - } else { - p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) & - ICC_IGRPEN1_EL1_MASK; - } - + access_vmcr_field(vcpu, p, + ICH_VMCR_ENG1_MASK, + ICH_VMCR_ENG1_SHIFT, + ICC_IGRPEN1_EL1_SHIFT); return true; } diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c index 3654b4c..b53c66e 100644 --- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -444,7 +444,7 @@ void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_set_vmcr(vcpu, vmcr); else - vgic_v3_set_vmcr(vcpu, vmcr); + BUG(); } void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) @@ -452,7 +452,7 @@ void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_get_vmcr(vcpu, vmcr); else - vgic_v3_get_vmcr(vcpu, vmcr); + BUG(); } /* diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index edc6ee2..4697f5d 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c @@ -171,44 +171,6 @@ void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr) vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[lr] = 0; } -void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) -{ - u32 vmcr; - - /* - * Ignore the FIQen bit, because GIC emulation always implies - * SRE=1 which means the vFIQEn bit is also RES1. - */ - vmcr = ((vmcrp->ctlr >> ICC_CTLR_EL1_EOImode_SHIFT) << - ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK; - vmcr |= (vmcrp->ctlr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_MASK; - vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK; - vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK; - vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK; - vmcr |= (vmcrp->grpen0 << ICH_VMCR_ENG0_SHIFT) & ICH_VMCR_ENG0_MASK; - vmcr |= (vmcrp->grpen1 << ICH_VMCR_ENG1_SHIFT) & ICH_VMCR_ENG1_MASK; - - vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = vmcr; -} - -void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) -{ - u32 vmcr = vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr; - - /* - * Ignore the FIQen bit, because GIC emulation always implies - * SRE=1 which means the vFIQEn bit is also RES1. - */ - vmcrp->ctlr = ((vmcr >> ICH_VMCR_EOIM_SHIFT) << - ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; - vmcrp->ctlr |= (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT; - vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT; - vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT; - vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT; - vmcrp->grpen0 = (vmcr & ICH_VMCR_ENG0_MASK) >> ICH_VMCR_ENG0_SHIFT; - vmcrp->grpen1 = (vmcr & ICH_VMCR_ENG1_MASK) >> ICH_VMCR_ENG1_SHIFT; -} - #define INITIAL_PENDBASER_VALUE \ (GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RaWb) | \ GIC_BASER_CACHEABILITY(GICR_PENDBASER, OUTER, SameAsInner) | \ diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index db28f7c..5652983 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -143,8 +143,6 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu); void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr); void vgic_v3_set_underflow(struct kvm_vcpu *vcpu); -void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); -void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); void vgic_v3_enable(struct kvm_vcpu *vcpu); int vgic_v3_probe(const struct gic_kvm_info *info); int vgic_v3_map_resources(struct kvm *kvm);