From nobody Sun Dec 14 11:36:45 2025 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 312CD221FD0 for ; Thu, 16 Oct 2025 17:56:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760637408; cv=none; b=eCRaxIV4pnCXvH9KMKlWwd4ppG0O+NIPiYypXiDtzvGnRuUgM7FyCNvzIA+1K8/dTyRvRcB9dL6E46CirHY3bucTgmD41J7U8TXLrLOpGZh4U2ed/l1tpC/DkYl+DhsfX4LNsee57+NmzpJOMX/u5rsGtYQ1YDR580WMYagF0jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760637408; c=relaxed/simple; bh=/KrH4Ah18U4AfQ63aZ1XwopQVYXVo8+xTvxAT3paEf0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SQP1xEJNX0ooBBurckhS8oy6eXltnTAZTiD1bs1qO2gNaGXX31zQOiHfJBYNeXJGEgwllnPEdgFQIeOSa37iJxB7BDsfUhqMTu2hSWsZHVPqcK16iz2ebeeYUlZNP86S7qzpiDYfjLOZcPeOONvtOQxdLNEDjOOA2txDZMaCxcI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DMNhPru/; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DMNhPru/" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-42557c5cedcso640121f8f.0 for ; Thu, 16 Oct 2025 10:56:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1760637404; x=1761242204; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KKP1Ta3BfHb/8wlxAanz9De+XRrWGVKj4Da9wjd+w5A=; b=DMNhPru/VEwuFO1gFyjekRLtpTmFnweG95iD9D14pv4Je3nVpveWYzxO7h9udIexHT xuRhu7WRmhFAKXP+W33jrmsdFv8MutpoPEl37qCiF4GXApfV56uctiavzRhJSwamL5Rd Cci1yDrV3xVgu/wSPiR8biMDUirT3NFx1N2CX6nRftATMuIFyprk5GRokiVvzalvMk74 p5ceg7yVexguQH6aPGo1r0LxGSMxD4qxG1hX2FHGWUS2OU1Z6dTLJQWh3loRsZbRc2Tl Kew8W3JTA29uLgDPTid63+XgsEoEkbZWyoVFxx8bGzr1H6KYjTBwqoLJq3Ag51Q895Z5 SgGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760637404; x=1761242204; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KKP1Ta3BfHb/8wlxAanz9De+XRrWGVKj4Da9wjd+w5A=; b=XCHOTWIcZBWuzGLNC5CB43JYY48mXIIKOL4zobQSf+cCthwYYU4UOWCfCfWa1Ar3Og d8ShyOe+/j1DnGlnx1zILg+e574B0QTKVs7J1oOu4OOHARjvDaIMedxgJXiYCD6U3X/I /Ui0krpUQsRmc3tiAc1mHh/FLnHaH7UoPcHznFcMLkWfhGrPJJDOBRoOc0kCaIWS9zWR op2EJB8hTajqwJ3wR+e15zdmO7EDWvHGbuIMEO5pxruZHqfNjmDO7cBTqUm0DMEg+CS+ oxHxH6KplnrePbCa1W6bg5ZJ4NKoMbFbTFHveJWcWJb75iKHfhMFKeNpKakBi/rjm20a vCZw== X-Forwarded-Encrypted: i=1; AJvYcCUlk6qPnx9NwVI3I6b+oUe+K+yHolIsQczmjCemrL2l0d+9lGFFy7wlFvs+JGZrMIk/5HwptWY4Xf5FsGU=@vger.kernel.org X-Gm-Message-State: AOJu0YxerHtGExU9Zg2yvaR8g5XqxI4rhJqMeqJay3zBoUe0g6Vy0uNl GB/bI81EWbyhHej/0SDTAnOkxJOJAh7DKdtSjl7TMjAvhblFu0XW7gEx X-Gm-Gg: ASbGncs9SMeK3ZPmxEJvr06D29zFQJFT8hPurwiBRVWKPp/8ydjdjSDWeE2apUfboJC fQK0FwE7xg0UH2GXeQlw07rTK1ouCnLJLuCCD2+G5RhRZNusF+5ONfSTnrPrs4vOfeOA5IdLIzY biyF22Z0EfqZFb1HlMkZZX6GZACgojrGZEEcolSqwApksGHUaP++A0M7cK+kb/FS5WQfQNo6CGI PXSSxx5V6diBIIHfqD4C9cU3hkomhQiSPqMSVsUUNEPWX2VbTrzlt6KayzimE3B99vqXIjOkWb6 SFZA7H1GdGDjDddNRYyuE4M1lD6P18Qj0nmWsMqKfSeqqdWr90M/+0zeN25sfJRPtbLDmg5b0EC UjfQuyeMjZVrWS5EsLGbU5BOJzCuSBR/Qf4SMo38DbVNsLBY4pEPI/IIA3to9/4AsM9pkRKR4sA 8s3cNEzwynqg== X-Google-Smtp-Source: AGHT+IFblAy5GAIp1r8QzuJtiDYDa0ypR0JAOuaVZe/d+x+4Bl8CWH2kZcRnkZPVR8FiiPrGRmKQEw== X-Received: by 2002:a5d:5f82:0:b0:3ec:db87:e8fa with SMTP id ffacd0b85a97d-42704d768b6mr761730f8f.26.1760637404162; Thu, 16 Oct 2025 10:56:44 -0700 (PDT) Received: from fedora ([94.73.33.104]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-426ce5cfe74sm35344023f8f.35.2025.10.16.10.56.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Oct 2025 10:56:43 -0700 (PDT) From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= To: louis.chauvet@bootlin.com Cc: hamohammed.sa@gmail.com, simona@ffwll.ch, melissa.srw@gmail.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, sebastian.wick@redhat.com, xaver.hugl@kde.org, victoria@system76.com, a.hindborg@kernel.org, leitao@debian.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Mark Yacoub , Harry Wentland , Luca Ceresoli , =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Subject: [PATCH v7 02/16] drm/vkms: Add and remove VKMS instances via configfs Date: Thu, 16 Oct 2025 19:56:04 +0200 Message-ID: <20251016175618.10051-3-jose.exposito89@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251016175618.10051-1-jose.exposito89@gmail.com> References: <20251016175618.10051-1-jose.exposito89@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Louis Chauvet Allow to create, enable, disable and destroy VKMS instances using configfs. For the moment, it is not possible to add pipeline items, so trying to enable the device will fail printing an informative error to the log. Tested-by: Mark Yacoub Reviewed-by: Louis Chauvet Reviewed-by: Harry Wentland Reviewed-by: Luca Ceresoli Signed-off-by: Louis Chauvet Co-developed-by: Jos=C3=A9 Exp=C3=B3sito Signed-off-by: Jos=C3=A9 Exp=C3=B3sito --- Documentation/gpu/vkms.rst | 32 +++++ drivers/gpu/drm/vkms/Kconfig | 1 + drivers/gpu/drm/vkms/Makefile | 3 +- drivers/gpu/drm/vkms/vkms_configfs.c | 172 +++++++++++++++++++++++++++ drivers/gpu/drm/vkms/vkms_configfs.h | 8 ++ drivers/gpu/drm/vkms/vkms_drv.c | 7 ++ 6 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/vkms/vkms_configfs.c create mode 100644 drivers/gpu/drm/vkms/vkms_configfs.h diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst index 8a8b1002931f..73521b9ff0c3 100644 --- a/Documentation/gpu/vkms.rst +++ b/Documentation/gpu/vkms.rst @@ -51,6 +51,38 @@ To disable the driver, use :: =20 sudo modprobe -r vkms =20 +Configuring With Configfs +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +It is possible to create and configure multiple VKMS instances via configf= s. + +Start by mounting configfs and loading VKMS:: + + sudo mount -t configfs none /config + sudo modprobe vkms + +Once VKMS is loaded, ``/config/vkms`` is created automatically. Each direc= tory +under ``/config/vkms`` represents a VKMS instance, create a new one:: + + sudo mkdir /config/vkms/my-vkms + +By default, the instance is disabled:: + + cat /config/vkms/my-vkms/enabled + 0 + +Once you are done configuring the VKMS instance, enable it:: + + echo "1" | sudo tee /config/vkms/my-vkms/enabled + +Finally, you can remove the VKMS instance disabling it:: + + echo "0" | sudo tee /config/vkms/my-vkms/enabled + +And removing the top level directory:: + + sudo rmdir /config/vkms/my-vkms + Testing With IGT =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/drivers/gpu/drm/vkms/Kconfig b/drivers/gpu/drm/vkms/Kconfig index 3c02f928ffe6..3977bbb99f7d 100644 --- a/drivers/gpu/drm/vkms/Kconfig +++ b/drivers/gpu/drm/vkms/Kconfig @@ -7,6 +7,7 @@ config DRM_VKMS select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select CRC32 + select CONFIGFS_FS default n help Virtual Kernel Mode-Setting (VKMS) is used for testing or for diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile index d657865e573f..939991fc8233 100644 --- a/drivers/gpu/drm/vkms/Makefile +++ b/drivers/gpu/drm/vkms/Makefile @@ -8,7 +8,8 @@ vkms-y :=3D \ vkms_composer.o \ vkms_writeback.o \ vkms_connector.o \ - vkms_config.o + vkms_config.o \ + vkms_configfs.o =20 obj-$(CONFIG_DRM_VKMS) +=3D vkms.o obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) +=3D tests/ diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vk= ms_configfs.c new file mode 100644 index 000000000000..ee186952971b --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_configfs.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include +#include + +#include "vkms_drv.h" +#include "vkms_config.h" +#include "vkms_configfs.h" + +/* To avoid registering configfs more than once or unregistering on error = */ +static bool is_configfs_registered; + +/** + * struct vkms_configfs_device - Configfs representation of a VKMS device + * + * @group: Top level configuration group that represents a VKMS device. + * Initialized when a new directory is created under "/config/vkms/" + * @lock: Lock used to project concurrent access to the configuration attr= ibutes + * @config: Protected by @lock. Configuration of the VKMS device + * @enabled: Protected by @lock. The device is created or destroyed when t= his + * option changes + */ +struct vkms_configfs_device { + struct config_group group; + + struct mutex lock; + struct vkms_config *config; + bool enabled; +}; + +#define device_item_to_vkms_configfs_device(item) \ + container_of(to_config_group((item)), struct vkms_configfs_device, \ + group) + +static ssize_t device_enabled_show(struct config_item *item, char *page) +{ + struct vkms_configfs_device *dev; + bool enabled; + + dev =3D device_item_to_vkms_configfs_device(item); + + scoped_guard(mutex, &dev->lock) + enabled =3D dev->enabled; + + return sprintf(page, "%d\n", enabled); +} + +static ssize_t device_enabled_store(struct config_item *item, const char *= page, + size_t count) +{ + struct vkms_configfs_device *dev; + bool enabled; + int ret =3D 0; + + dev =3D device_item_to_vkms_configfs_device(item); + + if (kstrtobool(page, &enabled)) + return -EINVAL; + + scoped_guard(mutex, &dev->lock) { + if (!dev->enabled && enabled) { + if (!vkms_config_is_valid(dev->config)) + return -EINVAL; + + ret =3D vkms_create(dev->config); + if (ret) + return ret; + } else if (dev->enabled && !enabled) { + vkms_destroy(dev->config); + } + + dev->enabled =3D enabled; + } + + return (ssize_t)count; +} + +CONFIGFS_ATTR(device_, enabled); + +static struct configfs_attribute *device_item_attrs[] =3D { + &device_attr_enabled, + NULL, +}; + +static void device_release(struct config_item *item) +{ + struct vkms_configfs_device *dev; + + dev =3D device_item_to_vkms_configfs_device(item); + + if (dev->enabled) + vkms_destroy(dev->config); + + mutex_destroy(&dev->lock); + vkms_config_destroy(dev->config); + kfree(dev); +} + +static struct configfs_item_operations device_item_operations =3D { + .release =3D &device_release, +}; + +static const struct config_item_type device_item_type =3D { + .ct_attrs =3D device_item_attrs, + .ct_item_ops =3D &device_item_operations, + .ct_owner =3D THIS_MODULE, +}; + +static struct config_group *make_device_group(struct config_group *group, + const char *name) +{ + struct vkms_configfs_device *dev; + + if (strcmp(name, DEFAULT_DEVICE_NAME) =3D=3D 0) + return ERR_PTR(-EINVAL); + + dev =3D kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->config =3D vkms_config_create(name); + if (IS_ERR(dev->config)) { + kfree(dev); + return ERR_CAST(dev->config); + } + + config_group_init_type_name(&dev->group, name, &device_item_type); + mutex_init(&dev->lock); + + return &dev->group; +} + +static struct configfs_group_operations device_group_ops =3D { + .make_group =3D &make_device_group, +}; + +static const struct config_item_type device_group_type =3D { + .ct_group_ops =3D &device_group_ops, + .ct_owner =3D THIS_MODULE, +}; + +static struct configfs_subsystem vkms_subsys =3D { + .su_group =3D { + .cg_item =3D { + .ci_name =3D "vkms", + .ci_type =3D &device_group_type, + }, + }, + .su_mutex =3D __MUTEX_INITIALIZER(vkms_subsys.su_mutex), +}; + +int vkms_configfs_register(void) +{ + int ret; + + if (is_configfs_registered) + return 0; + + config_group_init(&vkms_subsys.su_group); + ret =3D configfs_register_subsystem(&vkms_subsys); + + is_configfs_registered =3D ret =3D=3D 0; + + return ret; +} + +void vkms_configfs_unregister(void) +{ + if (is_configfs_registered) + configfs_unregister_subsystem(&vkms_subsys); +} diff --git a/drivers/gpu/drm/vkms/vkms_configfs.h b/drivers/gpu/drm/vkms/vk= ms_configfs.h new file mode 100644 index 000000000000..e9020b0043db --- /dev/null +++ b/drivers/gpu/drm/vkms/vkms_configfs.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef _VKMS_CONFIGFS_H_ +#define _VKMS_CONFIGFS_H_ + +int vkms_configfs_register(void); +void vkms_configfs_unregister(void); + +#endif /* _VKMS_CONFIGFS_H_ */ diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_dr= v.c index 78af37c7bd83..c1f23e6a4b07 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -28,6 +28,7 @@ #include =20 #include "vkms_config.h" +#include "vkms_configfs.h" #include "vkms_drv.h" =20 #define DRIVER_NAME "vkms" @@ -214,6 +215,10 @@ static int __init vkms_init(void) int ret; struct vkms_config *config; =20 + ret =3D vkms_configfs_register(); + if (ret) + return ret; + config =3D vkms_config_default_create(enable_cursor, enable_writeback, en= able_overlay); if (IS_ERR(config)) return PTR_ERR(config); @@ -250,6 +255,8 @@ void vkms_destroy(struct vkms_config *config) =20 static void __exit vkms_exit(void) { + vkms_configfs_unregister(); + if (!default_config) return; =20 --=20 2.51.0