From patchwork Sun Nov 17 04:30:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 21549 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f198.google.com (mail-ob0-f198.google.com [209.85.214.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9247723FBB for ; Sun, 17 Nov 2013 04:29:16 +0000 (UTC) Received: by mail-ob0-f198.google.com with SMTP id vb8sf2634902obc.1 for ; Sat, 16 Nov 2013 20:29:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=dO1BPVsrXo1qjwthnwjJyjuLBZiJ5q7wTtjI13NlaRk=; b=SvryspZ0yC7/RNRI66NrxhLq6KogvRJ5G+C36RzT3pZ1vL7gKRZhFj+HrzYlPrUuJR Gy1qIHnqUiU7+wpbhoA3MC6Z8DhFzqg3CFpQrwrV7gTsI/esIO0TAjFj4Vb04ADj9wJX 9AJoldAXrfylC74ZkZAa3TjR+yYGx6fEeP8vUxViW9cfNH00lUxca0nmx25VSrCSHXki eJLzE30eq0Gf5rwHJYNA9VXyPXFqcN0P9mo+EVFa6tfLl2E7TPoUf/pt/nMOkgIB0Hdr ThAONet004QFpdtR0jtHoQFAQPYU1ATNNLnhtzyZdUcSuttK4oP9xWwaSb/TBEwBPdLX v9Vg== X-Gm-Message-State: ALoCoQkPVmxsMiZIAxh/Z+FnAMC28R/0ckZOGJae6H9ULPLi7KRiZ6akP+NmAPkxVHIYqKKv5lT/ X-Received: by 10.182.43.137 with SMTP id w9mr5994584obl.24.1384662555872; Sat, 16 Nov 2013 20:29:15 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.3.129 with SMTP id c1ls2202415qec.84.gmail; Sat, 16 Nov 2013 20:29:15 -0800 (PST) X-Received: by 10.58.100.244 with SMTP id fb20mr9198982veb.6.1384662555783; Sat, 16 Nov 2013 20:29:15 -0800 (PST) Received: from mail-ve0-f169.google.com (mail-ve0-f169.google.com [209.85.128.169]) by mx.google.com with ESMTPS id z15si5072278vce.72.2013.11.16.20.29.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 16 Nov 2013 20:29:15 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.169; Received: by mail-ve0-f169.google.com with SMTP id pa12so4240345veb.28 for ; Sat, 16 Nov 2013 20:29:15 -0800 (PST) X-Received: by 10.52.65.136 with SMTP id x8mr7794429vds.23.1384662555689; Sat, 16 Nov 2013 20:29:15 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp126849vcz; Sat, 16 Nov 2013 20:29:15 -0800 (PST) X-Received: by 10.68.130.234 with SMTP id oh10mr14518106pbb.0.1384662554339; Sat, 16 Nov 2013 20:29:14 -0800 (PST) Received: from mail-pd0-f175.google.com (mail-pd0-f175.google.com [209.85.192.175]) by mx.google.com with ESMTPS id v7si6216931pbi.278.2013.11.16.20.29.14 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 16 Nov 2013 20:29:14 -0800 (PST) Received-SPF: neutral (google.com: 209.85.192.175 is neither permitted nor denied by best guess record for domain of christoffer.dall@linaro.org) client-ip=209.85.192.175; Received: by mail-pd0-f175.google.com with SMTP id w10so2991723pde.6 for ; Sat, 16 Nov 2013 20:29:13 -0800 (PST) X-Received: by 10.68.248.33 with SMTP id yj1mr14090831pbc.45.1384662553917; Sat, 16 Nov 2013 20:29:13 -0800 (PST) Received: from localhost.localdomain (c-67-169-181-221.hsd1.ca.comcast.net. [67.169.181.221]) by mx.google.com with ESMTPSA id ho3sm14498530pbb.23.2013.11.16.20.29.12 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 16 Nov 2013 20:29:13 -0800 (PST) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: patches@linaro.org, Christoffer Dall Subject: [PATCH v3 2/9] KVM: arm-vgic: Support KVM_CREATE_DEVICE for VGIC Date: Sat, 16 Nov 2013 20:30:13 -0800 Message-Id: <1384662620-13795-3-git-send-email-christoffer.dall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1384662620-13795-1-git-send-email-christoffer.dall@linaro.org> References: <1384662620-13795-1-git-send-email-christoffer.dall@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: christoffer.dall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Support creating the ARM VGIC device through the KVM_CREATE_DEVICE ioctl, which can then later be leveraged to use the KVM_{GET/SET}_DEVICE_ATTR, which is useful both for setting addresses in a more generic API than the ARM-specific one and is useful for save/restore of VGIC state. Adds KVM_CAP_DEVICE_CTRL to ARM capabilities. Note that we change the check for creating a VGIC from bailing out if any VCPUs were created, to bailing out if any VCPUs were ever run. This is an important distinction that shouldn't break anything, but allows creating the VGIC after the VCPUs have been created. Signed-off-by: Christoffer Dall Changelog[v3]: - Prevent race in kvm_vgic_create by trying to take all the vcpu locks before creating the vgic. Changelog[v2]: - None --- Documentation/virtual/kvm/devices/arm-vgic.txt | 10 ++++ arch/arm/kvm/arm.c | 1 + include/linux/kvm_host.h | 1 + include/uapi/linux/kvm.h | 1 + virt/kvm/arm/vgic.c | 58 +++++++++++++++++++++++- virt/kvm/kvm_main.c | 6 ++- 6 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 Documentation/virtual/kvm/devices/arm-vgic.txt diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt new file mode 100644 index 0000000..38f27f7 --- /dev/null +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt @@ -0,0 +1,10 @@ +ARM Virtual Generic Interrupt Controller (VGIC) +=============================================== + +Device types supported: + KVM_DEV_TYPE_ARM_VGIC_V2 ARM Generic Interrupt Controller v2.0 + +Only one VGIC instance may be instantiated through either this API or the +legacy KVM_CREATE_IRQCHIP api. The created VGIC will act as the VM interrupt +controller, requiring emulated user-space devices to inject interrupts to the +VGIC instead of directly to CPUs. diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index e80b6a1..984908d 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -190,6 +190,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IRQCHIP: r = vgic_present; break; + case KVM_CAP_DEVICE_CTRL: case KVM_CAP_USER_MEMORY: case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9523d2a..e68d9db 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1076,6 +1076,7 @@ struct kvm_device *kvm_device_from_filp(struct file *filp); extern struct kvm_device_ops kvm_mpic_ops; extern struct kvm_device_ops kvm_xics_ops; extern struct kvm_device_ops kvm_vfio_ops; +extern struct kvm_device_ops kvm_arm_vgic_ops; #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 902f124..b647c29 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -853,6 +853,7 @@ struct kvm_device_attr { #define KVM_DEV_VFIO_GROUP 1 #define KVM_DEV_VFIO_GROUP_ADD 1 #define KVM_DEV_VFIO_GROUP_DEL 2 +#define KVM_DEV_TYPE_ARM_VGIC_V2 5 /* * ioctls for VM fds diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 5e9df47..e3fbb5e 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1433,20 +1433,40 @@ out: int kvm_vgic_create(struct kvm *kvm) { - int ret = 0; + int i, vcpu_lock_idx = -1, ret = 0; + struct kvm_vcpu *vcpu; mutex_lock(&kvm->lock); - if (atomic_read(&kvm->online_vcpus) || kvm->arch.vgic.vctrl_base) { + if (kvm->arch.vgic.vctrl_base) { ret = -EEXIST; goto out; } + kvm_for_each_vcpu(i, vcpu, kvm) { + if (!mutex_trylock(&vcpu->mutex)) + goto out_unlock; + vcpu_lock_idx = i; + } + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (vcpu->arch.has_run_once) { + ret = -EBUSY; + goto out_unlock; + } + } + spin_lock_init(&kvm->arch.vgic.lock); kvm->arch.vgic.vctrl_base = vgic_vctrl_base; kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; +out_unlock: + for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) { + vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx); + mutex_unlock(&vcpu->mutex); + } + out: mutex_unlock(&kvm->lock); return ret; @@ -1510,3 +1530,37 @@ int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr) mutex_unlock(&kvm->lock); return r; } + +static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static int vgic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static int vgic_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) +{ + return -ENXIO; +} + +static void vgic_destroy(struct kvm_device *dev) +{ + kfree(dev); +} + +static int vgic_create(struct kvm_device *dev, u32 type) +{ + return kvm_vgic_create(dev->kvm); +} + +struct kvm_device_ops kvm_arm_vgic_ops = { + .name = "kvm-arm-vgic", + .create = vgic_create, + .destroy = vgic_destroy, + .set_attr = vgic_set_attr, + .get_attr = vgic_get_attr, + .has_attr = vgic_has_attr, +}; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 10015d6..fb8bb21 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2278,7 +2278,11 @@ static int kvm_ioctl_create_device(struct kvm *kvm, #ifdef CONFIG_KVM_VFIO case KVM_DEV_TYPE_VFIO: ops = &kvm_vfio_ops; - break; +#endif +#ifdef CONFIG_KVM_ARM_VGIC + case KVM_DEV_TYPE_ARM_VGIC_V2: + ops = &kvm_arm_vgic_ops; + break; #endif default: return -ENODEV;