From patchwork Tue Mar 21 11:05:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9636397 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 B77CE602D6 for ; Tue, 21 Mar 2017 11:06:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B848226E4F for ; Tue, 21 Mar 2017 11:06:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD35327D8D; Tue, 21 Mar 2017 11:06:09 +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 E9C8F28305 for ; Tue, 21 Mar 2017 11:06:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757001AbdCULFq (ORCPT ); Tue, 21 Mar 2017 07:05:46 -0400 Received: from mail-wr0-f173.google.com ([209.85.128.173]:34468 "EHLO mail-wr0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756981AbdCULFp (ORCPT ); Tue, 21 Mar 2017 07:05:45 -0400 Received: by mail-wr0-f173.google.com with SMTP id l37so109733464wrc.1 for ; Tue, 21 Mar 2017 04:05:44 -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=Q01o4NLsV8u8H44I/Vk3OvKFCRYThgInOKsFU7fKAD4=; b=cq76tmOwGUn1QtZUvtdFViLkKyAeAUrrexhJ26GZbbmLN/cFbkRL0ndmbFmD02uRf7 K83V4PKVHkZ4oR8SeIBjK1GKBkJm4UevQC177cA9ms4z3nkwzStMHcovEer9V0eWUrfE NBqnavwMtXOikN22wdcCGcY3fTKUldjhu+caU= 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=Q01o4NLsV8u8H44I/Vk3OvKFCRYThgInOKsFU7fKAD4=; b=kMdo/Axtga5SzBCIAdTcqAK8kF4YsJoS4Cx7HT+VvliSAMQcszCxfisBVYM+mphbr7 XFCRby3fNGxEyrUth8GYC5Iq0ZLCaLKUEJMZqBInuFML9gA184jEfkaBxhRIlg4ow6RV NkBrnhJATTNCblNY9V0An5hPf32TIa9hmaYUCrMNM7gZARzQ4TaWEC1uWmRZpbfRIO34 ZCo6Cwt1FDUq9w8a7ibF1L12wI0puw+oA/GstdL3A52876auA0CLdswZi+52x31PtbFk AkAf91V1C3wyG8TI2Ey7Wi3qyxMoJ97rV+rMfRT05aRPCAf1ftWPj7iqLwZO8/xHaalz nosA== X-Gm-Message-State: AFeK/H0dCgheRNUKv9EYIDovtukmQxCWgxfDMTjDsjIEk+MZzBRf0f9mTHsBPLJuR39ezpBs X-Received: by 10.223.138.134 with SMTP id y6mr29796081wry.118.1490094343239; Tue, 21 Mar 2017 04:05:43 -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.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 Mar 2017 04:05:42 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Cc: kvm@vger.kernel.org, Marc Zyngier , Andre Przywara , Eric Auger , Vijaya.Kumar@cavium.com, Christoffer Dall Subject: [PATCH 5/5] KVM: arm/arm64: vgic: Get rid of struct vmcr for GICv2 Date: Tue, 21 Mar 2017 12:05:30 +0100 Message-Id: <20170321110530.15857-6-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> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.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 GICv2, this means translating between the GICH_VMCR register format stored in memory and the GICC_X registers exported to user space, with the annoying quirk around the format of the GICC_PMR, where we export the 8 bit prority field using the lower 5 bits and always assuming bits[2:0] are clear. This now lets us get completely rid of struct vmcr and its common accessor functions. Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic/vgic-mmio-v2.c | 51 +++++++++++++++++++++++++++++----------- virt/kvm/arm/vgic/vgic-mmio.c | 16 ------------- virt/kvm/arm/vgic/vgic-v2.c | 29 ----------------------- virt/kvm/arm/vgic/vgic.h | 14 ----------- 4 files changed, 37 insertions(+), 73 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c index a3ad7ff..1bdb990 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c @@ -219,23 +219,33 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu, static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len) { - struct vgic_vmcr vmcr; + u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr; u32 val; - vgic_get_vmcr(vcpu, &vmcr); switch (addr & 0xff) { case GIC_CPU_CTRL: - val = vmcr.ctlr; + val = (vmcr & GICH_VMCR_CTRL_MASK) >> + GICH_VMCR_CTRL_SHIFT; break; case GIC_CPU_PRIMASK: - val = vmcr.pmr; + /* + * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the + * the PMR field as GICH_VMCR.VMPriMask rather than + * GICC_PMR.Priority, so we expose the upper five bits of + * priority mask to userspace using the lower bits in the + * 32-bit word provided by userspace. + */ + val = (vmcr & GICH_VMCR_PRIMASK_MASK) >> + GICH_VMCR_PRIMASK_SHIFT; break; case GIC_CPU_BINPOINT: - val = vmcr.bpr; + val = (vmcr & GICH_VMCR_BINPOINT_MASK) >> + GICH_VMCR_BINPOINT_SHIFT; break; case GIC_CPU_ALIAS_BINPOINT: - val = vmcr.abpr; + val = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> + GICH_VMCR_ALIAS_BINPOINT_SHIFT; break; case GIC_CPU_IDENT: val = ((PRODUCT_ID_KVM << 20) | @@ -253,26 +263,39 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len, unsigned long val) { - struct vgic_vmcr vmcr; - - vgic_get_vmcr(vcpu, &vmcr); + u32 *vmcr = &vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr; + u32 mask, field; switch (addr & 0xff) { case GIC_CPU_CTRL: - vmcr.ctlr = val; + mask = GICH_VMCR_CTRL_MASK; + field = val << GICH_VMCR_CTRL_SHIFT; break; case GIC_CPU_PRIMASK: - vmcr.pmr = val; + /* + * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the + * the PMR field as GICH_VMCR.VMPriMask rather than + * GICC_PMR.Priority, so we obtain the upper five bits of + * priority mask from userspace using the lower bits in the + * 32-bit word provided by userspace. + */ + mask = GICH_VMCR_PRIMASK_MASK; + field = val << GICH_VMCR_PRIMASK_SHIFT; break; case GIC_CPU_BINPOINT: - vmcr.bpr = val; + mask = GICH_VMCR_BINPOINT_MASK; + field = val << GICH_VMCR_BINPOINT_SHIFT; break; case GIC_CPU_ALIAS_BINPOINT: - vmcr.abpr = val; + mask = GICH_VMCR_ALIAS_BINPOINT_MASK; + field = val << GICH_VMCR_ALIAS_BINPOINT_SHIFT; break; + default: + return; } - vgic_set_vmcr(vcpu, &vmcr); + *vmcr &= ~mask; + *vmcr |= (field & mask); } static const struct vgic_register_region vgic_v2_dist_registers[] = { diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c index b53c66e..07635d4 100644 --- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -439,22 +439,6 @@ vgic_find_mmio_region(const struct vgic_register_region *region, int nr_regions, sizeof(region[0]), match_region); } -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 - BUG(); -} - -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 - BUG(); -} - /* * kvm_mmio_read_buf() returns a value in a format where it can be converted * to a byte array and be directly observed as the guest wanted it to appear diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c index b834ecd..bfd1da0 100644 --- a/virt/kvm/arm/vgic/vgic-v2.c +++ b/virt/kvm/arm/vgic/vgic-v2.c @@ -182,35 +182,6 @@ void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr) vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = 0; } -void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) -{ - u32 vmcr; - - vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK; - vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & - GICH_VMCR_ALIAS_BINPOINT_MASK; - vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & - GICH_VMCR_BINPOINT_MASK; - vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & - GICH_VMCR_PRIMASK_MASK; - - vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr; -} - -void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) -{ - u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr; - - vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> - GICH_VMCR_CTRL_SHIFT; - vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> - GICH_VMCR_ALIAS_BINPOINT_SHIFT; - vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> - GICH_VMCR_BINPOINT_SHIFT; - vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> - GICH_VMCR_PRIMASK_SHIFT; -} - void vgic_v2_enable(struct kvm_vcpu *vcpu) { /* diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 5652983..9ffc4d4 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -81,16 +81,6 @@ static inline bool irq_is_pending(struct vgic_irq *irq) return irq->pending_latch || irq->line_level; } -struct vgic_vmcr { - u32 ctlr; - u32 abpr; - u32 bpr; - u32 pmr; - /* Below member variable are valid only for GICv3 */ - u32 grpen0; - u32 grpen1; -}; - struct vgic_reg_attr { struct kvm_vcpu *vcpu; gpa_t addr; @@ -122,8 +112,6 @@ int vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, int offset, u32 *val); int vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write, int offset, u32 *val); -void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); -void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); void vgic_v2_enable(struct kvm_vcpu *vcpu); int vgic_v2_probe(const struct gic_kvm_info *info); int vgic_v2_map_resources(struct kvm *kvm); @@ -165,8 +153,6 @@ int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write, u32 intid, u64 *val); int kvm_register_vgic_device(unsigned long type); -void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); -void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); int vgic_lazy_init(struct kvm *kvm); int vgic_init(struct kvm *kvm);