Received: by 2002:a05:7412:31a9:b0:e2:908c:2ebd with SMTP id et41csp4945384rdb; Fri, 15 Sep 2023 18:33:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEPg/AlXu7tGyZ09kaGWxz8sgLjLe1/jMZPRwZl+0HehXNRL3ZWlBg8my93j8hmdAkYt0GH X-Received: by 2002:a05:6a20:4285:b0:14c:f16a:2b78 with SMTP id o5-20020a056a20428500b0014cf16a2b78mr4404375pzj.45.1694827991289; Fri, 15 Sep 2023 18:33:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694827991; cv=none; d=google.com; s=arc-20160816; b=gBpPKoCLJBM8Kpom3nbiHXK0gB4LV/65XAA9E+gfqgRXC2bAgUGRh7uJVhxQZ3Lr7Z L1OCqhbyo/fCPfIjVVbMNcfpdsq6eB1cdGtAsqP3nnIEcf4JSsOtIygFkrRFezOqc3Op u0NxFjqzFEAAayHWXmyuTSv2BYb9xbLJZZof5JBbuXyvn+bHsDw0nF84O4SY8fGNrEmP jU7DS83hc69JifZTri7EMTQMGVedztlPZk6cCQ/fQBt4kjWhYHRdOvS0ezcpY+j58qbC Cio7ILQM5JgYvHfQOEKs6xuhD2ZjiY/1tQFHA1kwSKDi87NhlkuKRehF/RFsb0djmqYQ TRlg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:reply-to:dkim-signature; bh=C0sn2AnVcRbsYEvqFgh4BzWbc2uKAyyxP92cnWXv5Gc=; fh=kXSkXFacTVTlVHq0XnHvR0iN61knZqi7sPJIGv3JAWo=; b=S5TYZX0si/6Q/TKaN0V/LetOPBl5TfaZ51tErVFcgSJY5YJOP+7iKtFvdoYiJD79UR /EKHjsg2mQDz8j9k9aiLpQluo9kmV2Ld09ls2di16LnboFwO+zvltJOB7kqh1uguYjAF bIRUcgsXXQ3z7pIlmVzJSSJvvgALKok6As7F4pucLh+nKRXKHK3MPka6Jm14W5a9O9/w IRKgJ9yietQcZlFqC/ojD4iiSwuVlN6mfCs7BVbwIEOzv2HatnWYJpqyPBIVuKReFtDK e/vCzJ3E2CN8r0GPBCCcYYImS4Kx3G0Eou9qrLdvNNLNE4vhy+xBpXP0qJfcgc3noTRa pexw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=jvDBnkFi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id ff11-20020a056a002f4b00b0068fb6e2859dsi4028604pfb.45.2023.09.15.18.33.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 18:33:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=jvDBnkFi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 57D9983C547D; Fri, 15 Sep 2023 17:33:57 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239016AbjIPAdU (ORCPT + 99 others); Fri, 15 Sep 2023 20:33:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238391AbjIPAcT (ORCPT ); Fri, 15 Sep 2023 20:32:19 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A7F3271E for ; Fri, 15 Sep 2023 17:31:31 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id d9443c01a7336-1c0cfc2b995so24151615ad.2 for ; Fri, 15 Sep 2023 17:31:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1694824291; x=1695429091; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=C0sn2AnVcRbsYEvqFgh4BzWbc2uKAyyxP92cnWXv5Gc=; b=jvDBnkFi8COrquzeFvzZe1NGIcw2+MdT3qMRI4S7MM7TtszA/o4dFGVmucHUardQ0N nGh/1bkIjVTOZz4YECMI/AWeidonXnZiVATf/POPsl2fjOLRExjl3/OV0GV3vw5y5BjP 6YYSZ48XUlyCXQuzXpGRve5bffxA0OSzOhkTIJj8ObEZO9M3vcX8ub2TXheKDnfYpGDJ WW9O9i8K/UqxEYpWt+N+D4xO1KLq5GpE5gSkZQbgtA2XIpHKtfv5EX2VrBgQz1Hb2oK6 aDcZuaC1yLFZfkK0plhW0iiZN+cRhrYegjy5+73NURC3ACgUCig5UVuHKxhPx6BM7Ra4 PyYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694824291; x=1695429091; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=C0sn2AnVcRbsYEvqFgh4BzWbc2uKAyyxP92cnWXv5Gc=; b=D1hzDJSd3LenmWyZCkPXBJFfWSoAnbtHy9BN54/PROl0lJv0CrYoHlAmi60CObvDAX /UzkEF5OApD83iRHjjkQcRCl0tmDga8dNfu+6MpXDFUwpgiUFVBt8iKWB36urHjHoRCq mrQzC2wJHhhNs+Ga7LEiQpFNKdCdsVDV0z+2aGV4KR0kXHj853Rt+LToydZm33A9PxO0 sf+pglGh/SqMGu8bF1b8lyCKGiSc39KXMdhnHxRfvqcL+M76WeRaHdJ6k1+uNoQ6nwiZ U0JQtYuGTka1t1O+R+9ROIs6Y7G0UMUszrpbxRZk6rnZ8yBNFd3tcf8mVHPouu34O8Tq wBWA== X-Gm-Message-State: AOJu0Yw+6U2uW+foaEwrSTJJi31PvXrWoj4tirn8w0CfeBuf3CB2h6tN mBH15GIJnXa272E2yEgrwC0/RAPipP8= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a17:903:41c2:b0:1c1:fbec:bc39 with SMTP id u2-20020a17090341c200b001c1fbecbc39mr73146ple.4.1694824290982; Fri, 15 Sep 2023 17:31:30 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 15 Sep 2023 17:30:57 -0700 In-Reply-To: <20230916003118.2540661-1-seanjc@google.com> Mime-Version: 1.0 References: <20230916003118.2540661-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.459.ge4e396fd5e-goog Message-ID: <20230916003118.2540661-6-seanjc@google.com> Subject: [PATCH 05/26] vfio: KVM: Pass get/put helpers from KVM to VFIO, don't do circular lookup From: Sean Christopherson To: Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Huacai Chen , Michael Ellerman , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Peter Zijlstra , Arnaldo Carvalho de Melo , Sean Christopherson , Paolo Bonzini , Tony Krowiak , Halil Pasic , Jason Herne , Harald Freudenberger , Alex Williamson , Andy Lutomirski Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-mips@vger.kernel.org, kvm@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Anish Ghulati , Venkatesh Srinivas , Andrew Thornton Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Fri, 15 Sep 2023 17:33:57 -0700 (PDT) Explicitly pass KVM's get/put helpers to VFIO when attaching a VM to VFIO instead of having VFIO do a symbol lookup back into KVM. Having both KVM and VFIO do symbol lookups increases the overall complexity and places an unnecessary dependency on KVM (from VFIO) without adding any value. Signed-off-by: Sean Christopherson --- drivers/vfio/vfio.h | 2 ++ drivers/vfio/vfio_main.c | 74 +++++++++++++++++++--------------------- include/linux/vfio.h | 4 ++- virt/kvm/vfio.c | 9 +++-- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index a1f741365075..eec51c7ee822 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -19,6 +19,8 @@ struct vfio_container; struct vfio_kvm_reference { struct kvm *kvm; + bool (*get_kvm)(struct kvm *kvm); + void (*put_kvm)(struct kvm *kvm); spinlock_t lock; }; diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index e77e8c6aae2f..1f58ab6dbcd2 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -1306,38 +1305,22 @@ EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent); void vfio_device_get_kvm_safe(struct vfio_device *device, struct vfio_kvm_reference *ref) { - void (*pfn)(struct kvm *kvm); - bool (*fn)(struct kvm *kvm); - bool ret; - lockdep_assert_held(&device->dev_set->lock); + /* + * Note! The "kvm" and "put_kvm" pointers *must* be transferred to the + * device so that the device can put its reference to KVM. KVM can + * invoke vfio_device_set_kvm() to detach from VFIO, i.e. nullify all + * pointers in @ref, even if a device holds a reference to KVM! That + * also means that detaching KVM from VFIO only prevents "new" devices + * from using KVM, it doesn't invalidate KVM references in existing + * devices. + */ spin_lock(&ref->lock); - - if (!ref->kvm) - goto out; - - pfn = symbol_get(kvm_put_kvm); - if (WARN_ON(!pfn)) - goto out; - - fn = symbol_get(kvm_get_kvm_safe); - if (WARN_ON(!fn)) { - symbol_put(kvm_put_kvm); - goto out; + if (ref->kvm && ref->get_kvm(ref->kvm)) { + device->kvm = ref->kvm; + device->put_kvm = ref->put_kvm; } - - ret = fn(ref->kvm); - symbol_put(kvm_get_kvm_safe); - if (!ret) { - symbol_put(kvm_put_kvm); - goto out; - } - - device->put_kvm = pfn; - device->kvm = ref->kvm; - -out: spin_unlock(&ref->lock); } @@ -1353,28 +1336,37 @@ void vfio_device_put_kvm(struct vfio_device *device) device->put_kvm(device->kvm); device->put_kvm = NULL; - symbol_put(kvm_put_kvm); - clear: device->kvm = NULL; } static void vfio_device_set_kvm(struct vfio_kvm_reference *ref, - struct kvm *kvm) + struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)) { + if (WARN_ON_ONCE(kvm && (!get_kvm || !put_kvm))) + return; + spin_lock(&ref->lock); ref->kvm = kvm; + ref->get_kvm = get_kvm; + ref->put_kvm = put_kvm; spin_unlock(&ref->lock); } -static void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm) +static void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)) { #if IS_ENABLED(CONFIG_VFIO_GROUP) - vfio_device_set_kvm(&group->kvm_ref, kvm); + vfio_device_set_kvm(&group->kvm_ref, kvm, get_kvm, put_kvm); #endif } -static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm) +static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)) { struct vfio_device_file *df = file->private_data; @@ -1383,27 +1375,31 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm) * be propagated to vfio_device::kvm when the file is bound to * iommufd successfully in the vfio device cdev path. */ - vfio_device_set_kvm(&df->kvm_ref, kvm); + vfio_device_set_kvm(&df->kvm_ref, kvm, get_kvm, put_kvm); } /** * vfio_file_set_kvm - Link a kvm with VFIO drivers * @file: VFIO group file or VFIO device file * @kvm: KVM to link + * @get_kvm: Callback to get a reference to @kvm + * @put_kvm: Callback to put a reference to @kvm * * When a VFIO device is first opened the KVM will be available in * device->kvm if one was associated with the file. */ -void vfio_file_set_kvm(struct file *file, struct kvm *kvm) +void vfio_file_set_kvm(struct file *file, struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)) { struct vfio_group *group; group = vfio_group_from_file(file); if (group) - vfio_group_set_kvm(group, kvm); + vfio_group_set_kvm(group, kvm, get_kvm, put_kvm); if (vfio_device_from_file(file)) - vfio_device_file_set_kvm(file, kvm); + vfio_device_file_set_kvm(file, kvm, get_kvm, put_kvm); } EXPORT_SYMBOL_GPL(vfio_file_set_kvm); #endif diff --git a/include/linux/vfio.h b/include/linux/vfio.h index e80955de266c..35e970e3d3fb 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -312,7 +312,9 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi bool vfio_file_is_valid(struct file *file); bool vfio_file_enforced_coherent(struct file *file); #if IS_ENABLED(CONFIG_KVM) -void vfio_file_set_kvm(struct file *file, struct kvm *kvm); +void vfio_file_set_kvm(struct file *file, struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)); #endif #define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long)) diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c index ca24ce120906..f14fcbb34bc6 100644 --- a/virt/kvm/vfio.c +++ b/virt/kvm/vfio.c @@ -37,13 +37,18 @@ struct kvm_vfio { static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm) { - void (*fn)(struct file *file, struct kvm *kvm); + void (*fn)(struct file *file, struct kvm *kvm, + bool (*get_kvm)(struct kvm *kvm), + void (*put_kvm)(struct kvm *kvm)); fn = symbol_get(vfio_file_set_kvm); if (!fn) return; - fn(file, kvm); + if (kvm) + fn(file, kvm, kvm_get_kvm_safe, kvm_put_kvm); + else + fn(file, kvm, NULL, NULL); symbol_put(vfio_file_set_kvm); } -- 2.42.0.459.ge4e396fd5e-goog