From patchwork Thu Jun 19 09:21:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 32192 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f72.google.com (mail-pb0-f72.google.com [209.85.160.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id EEFF2206A0 for ; Thu, 19 Jun 2014 09:35:58 +0000 (UTC) Received: by mail-pb0-f72.google.com with SMTP id ma3sf7070756pbc.11 for ; Thu, 19 Jun 2014 02:35:58 -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:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:content-type:content-transfer-encoding; bh=XZEIRwcjdTo6d0s+VcHWEyce+hgOqN56/+T3jKgn6GQ=; b=UUSvt6a+9Tl6niH1HSJFC0gJwykRftGFgZVfY+JXVm95IHSX5bSotb/sYIiMsuc83X V2e6CxdASJXOzGeCf8mWC2AppftIcEHvtYJoLvx+PxOLiWx3LLOvNHxQaIm+bANKU1yV x4C2M2vinWD/J/kjz4cv/Yt2n6tGKS8oA/9Go+hUzmezOG5weRMxmyzyXhk2HLWIjgGd vXpRnGzWfiFrx+zRD901D4edqgLL2Mb0bSTZkLrPzSklTeI5xwaZJ54gbvKsNTTmakSr aeTKyYeHnpSpu50ULUwRCRhiIa26E7+oDPw3In58nUlWwAtdYOhdKS8U/900VCPvk0zi nafA== X-Gm-Message-State: ALoCoQnF4tngsqABqt8Ne2e3BDAyGnBIAGj9aJeEOJ1bQojjbfQnipF3ifEZ8ltLfExKV0r3E41Q X-Received: by 10.66.217.170 with SMTP id oz10mr1977837pac.9.1403170558204; Thu, 19 Jun 2014 02:35:58 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.106.203 with SMTP id e69ls502285qgf.29.gmail; Thu, 19 Jun 2014 02:35:58 -0700 (PDT) X-Received: by 10.220.94.146 with SMTP id z18mr120041vcm.40.1403170558093; Thu, 19 Jun 2014 02:35:58 -0700 (PDT) Received: from mail-ve0-f178.google.com (mail-ve0-f178.google.com [209.85.128.178]) by mx.google.com with ESMTPS id na9si2108798vcb.64.2014.06.19.02.35.58 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 19 Jun 2014 02:35:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.178 as permitted sender) client-ip=209.85.128.178; Received: by mail-ve0-f178.google.com with SMTP id oy12so2029140veb.23 for ; Thu, 19 Jun 2014 02:35:58 -0700 (PDT) X-Received: by 10.58.132.41 with SMTP id or9mr3045220veb.5.1403170558003; Thu, 19 Jun 2014 02:35:58 -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.221.54.6 with SMTP id vs6csp348912vcb; Thu, 19 Jun 2014 02:35:57 -0700 (PDT) X-Received: by 10.224.63.194 with SMTP id c2mr4904866qai.21.1403170557595; Thu, 19 Jun 2014 02:35:57 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id s49si5596955qgs.97.2014.06.19.02.35.57 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Jun 2014 02:35:57 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) 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 1WxYjR-0006WR-AF; Thu, 19 Jun 2014 09:34:09 +0000 Received: from fw-tnat.austin.arm.com ([217.140.110.23] helo=collaborate-mta1.arm.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WxYXz-0001Ms-FD for linux-arm-kernel@lists.infradead.org; Thu, 19 Jun 2014 09:22:21 +0000 Received: from e102391-lin.cambridge.arm.com (e102391-lin.cambridge.arm.com [10.1.209.143]) by collaborate-mta1.arm.com (Postfix) with ESMTP id B471A13FB3D; Thu, 19 Jun 2014 04:21:40 -0500 (CDT) From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Subject: [PATCH v2 7/9] arm/arm64: KVM: vgic: delay vgic allocation until init time Date: Thu, 19 Jun 2014 10:21:31 +0100 Message-Id: <1403169693-13982-8-git-send-email-marc.zyngier@arm.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1403169693-13982-1-git-send-email-marc.zyngier@arm.com> References: <1403169693-13982-1-git-send-email-marc.zyngier@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140619_022219_633275_A77CC997 X-CRM114-Status: GOOD ( 19.50 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain Cc: Christoffer Dall X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , 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: marc.zyngier@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.178 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 It is now quite easy to delay the allocation of the vgic tables until we actually require it to be up and running (when the first starting to kick around). This allow us to allocate memory for the exact number of CPUs we have. As nobody configures the number of interrupts just yet, use a fallback to VGIC_NR_IRQS_LEGACY. Signed-off-by: Marc Zyngier --- arch/arm/kvm/arm.c | 9 +------- include/kvm/arm_vgic.h | 3 +-- virt/kvm/arm/vgic.c | 56 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 66c14ef..9b3957d 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -308,16 +308,9 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) { - int ret; - /* Force users to call KVM_ARM_VCPU_INIT */ vcpu->arch.target = -1; - /* Set up VGIC */ - ret = kvm_vgic_vcpu_init(vcpu); - if (ret) - return ret; - /* Set up the timer */ kvm_timer_vcpu_init(vcpu); @@ -811,7 +804,7 @@ long kvm_arch_vm_ioctl(struct file *filp, switch (ioctl) { case KVM_CREATE_IRQCHIP: { if (vgic_present) - return kvm_vgic_create(kvm, KVM_MAX_VCPUS, VGIC_NR_IRQS_LEGACY); + return kvm_vgic_create(kvm); else return -ENXIO; } diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index cf17b68..f5788cf 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -231,9 +231,8 @@ struct kvm_exit_mmio; int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); int kvm_vgic_hyp_init(void); int kvm_vgic_init(struct kvm *kvm); -int kvm_vgic_create(struct kvm *kvm, int nr_cpus, int nr_irqs); +int kvm_vgic_create(struct kvm *kvm); void kvm_vgic_destroy(struct kvm *kvm); -int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 17ceb8a..6e13ff9 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1589,7 +1589,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) * Initialize the vgic_cpu struct and vgic_dist struct fields pertaining to * this vcpu and enable the VGIC for this VCPU */ -int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) +static int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_dist *dist = &vcpu->kvm->arch.vgic; @@ -1599,9 +1599,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) if (ret) return ret; - if (vcpu->vcpu_id >= dist->nr_cpus) - return -EBUSY; - for (i = 0; i < dist->nr_irqs; i++) { if (i < VGIC_NR_PPIS) vgic_bitmap_set_irq_val(&dist->irq_enabled, @@ -1723,9 +1720,6 @@ static int vgic_init_maps(struct vgic_dist *dist, int nr_cpus, int nr_irqs) { int ret, i; - dist->nr_cpus = nr_cpus; - dist->nr_irqs = nr_irqs; - ret = vgic_init_bitmap(&dist->irq_enabled, nr_cpus, nr_irqs); ret |= vgic_init_bitmap(&dist->irq_state, nr_cpus, nr_irqs); ret |= vgic_init_bitmap(&dist->irq_active, nr_cpus, nr_irqs); @@ -1775,7 +1769,9 @@ void kvm_vgic_destroy(struct kvm *kvm) */ int kvm_vgic_init(struct kvm *kvm) { - int ret = 0, i; + struct vgic_dist *dist = &kvm->arch.vgic; + struct kvm_vcpu *vcpu; + int ret = 0, i, v; if (!irqchip_in_kernel(kvm)) return 0; @@ -1785,30 +1781,58 @@ int kvm_vgic_init(struct kvm *kvm) if (vgic_initialized(kvm)) goto out; - if (IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_dist_base) || - IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_cpu_base)) { + dist->nr_cpus = atomic_read(&kvm->online_vcpus); + + /* + * If nobody configured the number of interrupts, use the + * legacy one. + */ + if (!dist->nr_irqs) + dist->nr_irqs = VGIC_NR_IRQS_LEGACY; + + if (IS_VGIC_ADDR_UNDEF(dist->vgic_dist_base) || + IS_VGIC_ADDR_UNDEF(dist->vgic_cpu_base)) { kvm_err("Need to set vgic cpu and dist addresses first\n"); ret = -ENXIO; goto out; } - ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, + ret = vgic_init_maps(dist, dist->nr_cpus, dist->nr_irqs); + if (ret) { + kvm_err("Unable to allocate maps\n"); + goto out; + } + + ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base, vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE); if (ret) { kvm_err("Unable to remap VGIC CPU to VCPU\n"); goto out; } - for (i = VGIC_NR_PRIVATE_IRQS; i < kvm->arch.vgic.nr_irqs; i += 4) + for (i = VGIC_NR_PRIVATE_IRQS; i < dist->nr_irqs; i += 4) vgic_set_target_reg(kvm, 0, i); + kvm_for_each_vcpu(v, vcpu, kvm) { + ret = kvm_vgic_vcpu_init(vcpu); + if (ret) { + kvm_err("Failed to allocate vcpu memory\n"); + break; + } + } + kvm->arch.vgic.ready = true; out: + if (ret) { + kvm_for_each_vcpu(v, vcpu, kvm) + kvm_vgic_vcpu_destroy(vcpu); + vgic_free_maps(dist); + } mutex_unlock(&kvm->lock); return ret; } -int kvm_vgic_create(struct kvm *kvm, int nr_cpus, int nr_irqs) +int kvm_vgic_create(struct kvm *kvm) { int i, vcpu_lock_idx = -1, ret = 0; struct kvm_vcpu *vcpu; @@ -1844,10 +1868,6 @@ int kvm_vgic_create(struct kvm *kvm, int nr_cpus, int nr_irqs) kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; - ret = vgic_init_maps(&kvm->arch.vgic, nr_cpus, nr_irqs); - if (ret) - kvm_err("Unable to allocate maps\n"); - out_unlock: for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) { vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx); @@ -2228,7 +2248,7 @@ static void vgic_destroy(struct kvm_device *dev) static int vgic_create(struct kvm_device *dev, u32 type) { - return kvm_vgic_create(dev->kvm, KVM_MAX_VCPUS, VGIC_NR_IRQS_LEGACY); + return kvm_vgic_create(dev->kvm); } struct kvm_device_ops kvm_arm_vgic_v2_ops = {