From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70C47CA9EB9 for ; Wed, 23 Oct 2019 09:58:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C55E2064A for ; Wed, 23 Oct 2019 09:58:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Sy9od2Uh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404252AbfJWJ6W (ORCPT ); Wed, 23 Oct 2019 05:58:22 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:24691 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2404230AbfJWJ6U (ORCPT ); Wed, 23 Oct 2019 05:58:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571824699; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pW2MBcIeb4HhWF7f5i2r0xN4U4b01dzx9T+DIG/qEEY=; b=Sy9od2Uhq2f9xUQ0Pc5SdboFqP9NUkingtKKxGn5npD6Ha9yre9ONaifQOu30Jgq/1veDE L/Q/XhGGAeH6rBIeAtzvwRkGCIR+2ymeQsG3501sGhv9Q0B+ZPgQdaNfIYSCb/n3fx/CdH yJyVPEUr782c0ek716eEJDG9NJG00/s= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-184-YUvYPDDhMi6aoOxdt4PVog-1; Wed, 23 Oct 2019 05:58:17 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 079E4107AD31; Wed, 23 Oct 2019 09:58:16 +0000 (UTC) Received: from steredhat.redhat.com (unknown [10.36.118.164]) by smtp.corp.redhat.com (Postfix) with ESMTP id 969305C1B2; Wed, 23 Oct 2019 09:58:12 +0000 (UTC) From: Stefano Garzarella To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , kvm@vger.kernel.org, Greg Kroah-Hartman , Jason Wang , "David S. Miller" , Dexuan Cui , Haiyang Zhang , Jorgen Hansen , Sasha Levin , linux-kernel@vger.kernel.org, Arnd Bergmann , Stefan Hajnoczi , linux-hyperv@vger.kernel.org, "K. Y. Srinivasan" , Stephen Hemminger , virtualization@lists.linux-foundation.org Subject: [PATCH net-next 12/14] vsock/vmci: register vmci_transport only when VMCI guest/host are active Date: Wed, 23 Oct 2019 11:55:52 +0200 Message-Id: <20191023095554.11340-13-sgarzare@redhat.com> In-Reply-To: <20191023095554.11340-1-sgarzare@redhat.com> References: <20191023095554.11340-1-sgarzare@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-MC-Unique: YUvYPDDhMi6aoOxdt4PVog-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To allow other transports to be loaded with vmci_transport, we register the vmci_transport as G2H or H2G only when a VMCI guest or host is active. To do that, this patch adds a callback registered in the vmci driver that will be called when a new host or guest become active. This callback will register the vmci_transport in the VSOCK core. If the transport is already registered, we ignore the error coming from vsock_core_register(). Cc: Jorgen Hansen Signed-off-by: Stefano Garzarella --- drivers/misc/vmw_vmci/vmci_driver.c | 50 +++++++++++++++++++++++++++++ drivers/misc/vmw_vmci/vmci_driver.h | 2 ++ drivers/misc/vmw_vmci/vmci_guest.c | 2 ++ drivers/misc/vmw_vmci/vmci_host.c | 7 ++++ include/linux/vmw_vmci_api.h | 2 ++ net/vmw_vsock/vmci_transport.c | 29 +++++++++++------ 6 files changed, 82 insertions(+), 10 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vm= ci_driver.c index 819e35995d32..195afbd7edc1 100644 --- a/drivers/misc/vmw_vmci/vmci_driver.c +++ b/drivers/misc/vmw_vmci/vmci_driver.c @@ -28,6 +28,9 @@ MODULE_PARM_DESC(disable_guest, static bool vmci_guest_personality_initialized; static bool vmci_host_personality_initialized; =20 +static DEFINE_MUTEX(vmci_vsock_mutex); /* protects vmci_vsock_transport_cb= */ +static vmci_vsock_cb vmci_vsock_transport_cb; + /* * vmci_get_context_id() - Gets the current context ID. * @@ -45,6 +48,53 @@ u32 vmci_get_context_id(void) } EXPORT_SYMBOL_GPL(vmci_get_context_id); =20 +/* + * vmci_register_vsock_callback() - Register the VSOCK vmci_transport call= back. + * + * The callback will be called every time a new host or guest become activ= e, + * or if they are already active when this function is called. + * To unregister the callback, call this function with NULL parameter. + * + * Returns 0 on success. -EBUSY if a callback is already registered. + */ +int vmci_register_vsock_callback(vmci_vsock_cb callback) +{ +=09int err =3D 0; + +=09mutex_lock(&vmci_vsock_mutex); + +=09if (vmci_vsock_transport_cb && callback) { +=09=09err =3D -EBUSY; +=09=09goto out; +=09} + +=09vmci_vsock_transport_cb =3D callback; + +=09if (!vmci_vsock_transport_cb) +=09=09goto out; + +=09if (vmci_guest_code_active()) +=09=09vmci_vsock_transport_cb(false); + +=09if (vmci_host_users() > 0) +=09=09vmci_vsock_transport_cb(true); + +out: +=09mutex_unlock(&vmci_vsock_mutex); +=09return err; +} +EXPORT_SYMBOL_GPL(vmci_register_vsock_callback); + +void vmci_call_vsock_callback(bool is_host) +{ +=09mutex_lock(&vmci_vsock_mutex); + +=09if (vmci_vsock_transport_cb) +=09=09vmci_vsock_transport_cb(is_host); + +=09mutex_unlock(&vmci_vsock_mutex); +} + static int __init vmci_drv_init(void) { =09int vmci_err; diff --git a/drivers/misc/vmw_vmci/vmci_driver.h b/drivers/misc/vmw_vmci/vm= ci_driver.h index aab81b67670c..990682480bf6 100644 --- a/drivers/misc/vmw_vmci/vmci_driver.h +++ b/drivers/misc/vmw_vmci/vmci_driver.h @@ -36,10 +36,12 @@ extern struct pci_dev *vmci_pdev; =20 u32 vmci_get_context_id(void); int vmci_send_datagram(struct vmci_datagram *dg); +void vmci_call_vsock_callback(bool is_host); =20 int vmci_host_init(void); void vmci_host_exit(void); bool vmci_host_code_active(void); +int vmci_host_users(void); =20 int vmci_guest_init(void); void vmci_guest_exit(void); diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmc= i_guest.c index 7a84a48c75da..cc8eeb361fcd 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -637,6 +637,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev= , =09=09 vmci_dev->iobase + VMCI_CONTROL_ADDR); =20 =09pci_set_drvdata(pdev, vmci_dev); + +=09vmci_call_vsock_callback(false); =09return 0; =20 err_free_irq: diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci= _host.c index 833e2bd248a5..ff3c396146ff 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -108,6 +108,11 @@ bool vmci_host_code_active(void) =09 atomic_read(&vmci_host_active_users) > 0); } =20 +int vmci_host_users(void) +{ +=09return atomic_read(&vmci_host_active_users); +} + /* * Called on open of /dev/vmci. */ @@ -338,6 +343,8 @@ static int vmci_host_do_init_context(struct vmci_host_d= ev *vmci_host_dev, =09vmci_host_dev->ct_type =3D VMCIOBJ_CONTEXT; =09atomic_inc(&vmci_host_active_users); =20 +=09vmci_call_vsock_callback(true); + =09retval =3D 0; =20 out: diff --git a/include/linux/vmw_vmci_api.h b/include/linux/vmw_vmci_api.h index acd9fafe4fc6..f28907345c80 100644 --- a/include/linux/vmw_vmci_api.h +++ b/include/linux/vmw_vmci_api.h @@ -19,6 +19,7 @@ struct msghdr; typedef void (vmci_device_shutdown_fn) (void *device_registration, =09=09=09=09=09void *user_data); +typedef void (*vmci_vsock_cb) (bool is_host); =20 int vmci_datagram_create_handle(u32 resource_id, u32 flags, =09=09=09=09vmci_datagram_recv_cb recv_cb, @@ -37,6 +38,7 @@ int vmci_doorbell_destroy(struct vmci_handle handle); int vmci_doorbell_notify(struct vmci_handle handle, u32 priv_flags); u32 vmci_get_context_id(void); bool vmci_is_context_owner(u32 context_id, kuid_t uid); +int vmci_register_vsock_callback(vmci_vsock_cb callback); =20 int vmci_event_subscribe(u32 event, =09=09=09 vmci_event_cb callback, void *callback_data, diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.= c index 2eb3f16d53e7..04437f822d82 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -2053,19 +2053,22 @@ static bool vmci_check_transport(struct vsock_sock = *vsk) =09return vsk->transport =3D=3D &vmci_transport; } =20 -static int __init vmci_transport_init(void) +void vmci_vsock_transport_cb(bool is_host) { -=09int features =3D VSOCK_TRANSPORT_F_DGRAM | VSOCK_TRANSPORT_F_H2G; -=09int cid; -=09int err; +=09int features; =20 -=09cid =3D vmci_get_context_id(); +=09if (is_host) +=09=09features =3D VSOCK_TRANSPORT_F_H2G; +=09else +=09=09features =3D VSOCK_TRANSPORT_F_G2H; =20 -=09if (cid =3D=3D VMCI_INVALID_ID) -=09=09return -EINVAL; +=09vsock_core_register(&vmci_transport, features); +} =20 -=09if (cid !=3D VMCI_HOST_CONTEXT_ID) -=09=09features |=3D VSOCK_TRANSPORT_F_G2H; +static int __init vmci_transport_init(void) +{ +=09int features =3D VSOCK_TRANSPORT_F_DGRAM; +=09int err; =20 =09/* Create the datagram handle that we will use to send and receive all =09 * VSocket control messages for this context. @@ -2079,7 +2082,6 @@ static int __init vmci_transport_init(void) =09=09pr_err("Unable to create datagram handle. (%d)\n", err); =09=09return vmci_transport_error_to_vsock_error(err); =09} - =09err =3D vmci_event_subscribe(VMCI_EVENT_QP_RESUMED, =09=09=09=09 vmci_transport_qp_resumed_cb, =09=09=09=09 NULL, &vmci_transport_qp_resumed_sub_id); @@ -2094,8 +2096,14 @@ static int __init vmci_transport_init(void) =09if (err < 0) =09=09goto err_unsubscribe; =20 +=09err =3D vmci_register_vsock_callback(vmci_vsock_transport_cb); +=09if (err < 0) +=09=09goto err_unregister; + =09return 0; =20 +err_unregister: +=09vsock_core_unregister(&vmci_transport); err_unsubscribe: =09vmci_event_unsubscribe(vmci_transport_qp_resumed_sub_id); err_destroy_stream_handle: @@ -2121,6 +2129,7 @@ static void __exit vmci_transport_exit(void) =09=09vmci_transport_qp_resumed_sub_id =3D VMCI_INVALID_ID; =09} =20 +=09vmci_register_vsock_callback(NULL); =09vsock_core_unregister(&vmci_transport); } module_exit(vmci_transport_exit); --=20 2.21.0