* [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes
@ 2025-10-29 14:36 Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
` (31 more replies)
0 siblings, 32 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS have a wide range of options. The aim of this series is to introduce
many configfs attribute so VKMS can be used to test a wide range of
configurations.
PATCH 1,7,10,13,23 are to expose human readable strings from drm core
PATCH 2-4 are to expose human readable plane type in debugfs
PATCH 5,6 plane attribute
PATCH 8,9 plane rotation
PATCH 11,12 plane color encoding
PATCH 14,15 plane color range
PATCH 16,17 plane format
PATCH 18 properly use zpos
PATCH 19,20 plane zpos
PATCH 21,22 connector type
PATCH 24,25 connector supported colorspace
PATCH 26,27 connector EDID
PATCH 28,29 preparatory work for dynamic connectors
PATCH 30,31 dynamic connectors
PS: Each pair of config/configfs patch are independant. I could
technically create ≈10 different series, but there will be a lot of
(trivial) conflicts between them. I will be happy to reordoer, split and
partially apply this series to help the review process.
PPS: Resend because it was rejected by dri-devel
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Changes in v2:
- PATCH 1: reorder includes (José)
- PATCH 2: use name property instead of folder name (José)
- PATCH 3: Fix default rotations (José)
- PATCH 3,5,7,12: Add tests and extract validation for planes (José)
- PATCH 3,5: Do not create color range/encoding properties if not set
- PATCH 5,6,7,8: Set plural form for vkms_config_plane fields (José)
- PATCH 4,6,8,13: Remove checking for default in supported (José)
- PATCH 9: Add break in vkms_config_plane_add_format (José)
- PATCH 12: fix zpos_enabled typo (José)
- PATCH 13: fix documentation (José)
- Add debug display (José)
- PATCH 20: use drmm_kzalloc instead of kzalloc (José)
- PATCH 22: simplify the code (José)
- Link to v1: https://lore.kernel.org/r/20251018-vkms-all-config-v1-0-a7760755d92d@bootlin.com
---
Louis Chauvet (32):
drm/drm_mode_config: Add helper to get plane type name
drm/vkms: Explicitly display plane type
drm/vkms: Use enabled/disabled instead of 1/0 for debug
drm/vkms: Explicitly display connector status
drm/vkms: Introduce config for plane name
drm/vkms: Introduce configfs for plane name
drm/blend: Get a rotation name from it's bitfield
drm/vkms: Introduce config for plane rotation
drm/vkms: Introduce configfs for plane rotation
drm/drm_color_mgmt: Expose drm_get_color_encoding_name
drm/vkms: Introduce config for plane color encoding
drm/vkms: Introduce configfs for plane color encoding
drm/drm_color_mgmt: Expose drm_get_color_range_name
drm/vkms: Introduce config for plane color range
drm/vkms: Introduce configfs for plane color range
drm/vkms: Introduce config for plane format
drm/vkms: Introduce configfs for plane format
drm/vkms: Properly render plane using their zpos
drm/vkms: Introduce config for plane zpos property
drm/vkms: Introduce configfs for plane zpos property
drm/vkms: Introduce config for connector type
drm/vkms: Introduce configfs for connector type
drm/connector: Export drm_get_colorspace_name
drm/vkms: Introduce config for connector supported colorspace
drm/vkms: Introduce configfs for connector supported colorspace
drm/vkms: Introduce config for connector EDID
drm/vkms: Introduce configfs for connector EDID
drm/vkms: Store the enabled/disabled status for connector
drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
drm/vkms: Extract common code for connector initialization
drm/vkms: Allow to hot-add connectors
drm/vkms: Introduce configfs for dynamic connector creation
Documentation/gpu/vkms.rst | 45 +-
drivers/gpu/drm/drm_blend.c | 35 +-
drivers/gpu/drm/drm_color_mgmt.c | 4 +-
drivers/gpu/drm/drm_connector.c | 1 +
drivers/gpu/drm/drm_crtc_internal.h | 6 -
drivers/gpu/drm/drm_mode_config.c | 13 +
drivers/gpu/drm/vkms/tests/Makefile | 1 +
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 247 +++++++
drivers/gpu/drm/vkms/tests/vkms_configfs_test.c | 102 +++
drivers/gpu/drm/vkms/vkms_config.c | 333 ++++++++-
drivers/gpu/drm/vkms/vkms_config.h | 577 +++++++++++++++
drivers/gpu/drm/vkms/vkms_configfs.c | 939 +++++++++++++++++++++++-
drivers/gpu/drm/vkms/vkms_configfs.h | 6 +
drivers/gpu/drm/vkms/vkms_connector.c | 168 ++++-
drivers/gpu/drm/vkms/vkms_connector.h | 38 +-
drivers/gpu/drm/vkms/vkms_crtc.c | 11 +-
drivers/gpu/drm/vkms/vkms_drv.h | 5 +-
drivers/gpu/drm/vkms/vkms_output.c | 19 +-
drivers/gpu/drm/vkms/vkms_plane.c | 79 +-
include/drm/drm_blend.h | 2 +
include/drm/drm_color_mgmt.h | 3 +
include/drm/drm_mode_config.h | 3 +
22 files changed, 2534 insertions(+), 103 deletions(-)
---
base-commit: 57fe8285dc4764171fa9eb1f153cae3bb313d6fc
change-id: 20251017-vkms-all-config-bd0c2a01846f
Best regards,
--
Louis Chauvet <louis.chauvet@bootlin.com>
^ permalink raw reply [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:06 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type Louis Chauvet
` (30 subsequent siblings)
31 siblings, 2 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Create and export an helper to display plane type using the
property string. This could be used to display debug
information in VKMS.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_mode_config.c | 13 +++++++++++++
include/drm/drm_mode_config.h | 3 +++
2 files changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 25f376869b3a..1a1a3f43db4d 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -226,6 +226,19 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
{ DRM_PLANE_TYPE_CURSOR, "Cursor" },
};
+/**
+ * drm_get_plane_type_name - return a string for plane name
+ * @type: plane type to compute name of
+ */
+const char *drm_get_plane_type_name(enum drm_plane_type type)
+{
+ if (type < ARRAY_SIZE(drm_plane_type_enum_list))
+ return drm_plane_type_enum_list[type].name;
+ else
+ return "(unknown)";
+}
+EXPORT_SYMBOL(drm_get_plane_type_name);
+
static int drm_mode_create_standard_properties(struct drm_device *dev)
{
struct drm_property *prop;
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 2e848b816218..89f3dd46178d 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -30,6 +30,7 @@
#include <linux/llist.h>
#include <drm/drm_modeset_lock.h>
+#include <drm/drm_plane.h>
struct drm_file;
struct drm_device;
@@ -983,4 +984,6 @@ static inline int drm_mode_config_init(struct drm_device *dev)
void drm_mode_config_reset(struct drm_device *dev);
void drm_mode_config_cleanup(struct drm_device *dev);
+const char *drm_get_plane_type_name(enum drm_plane_type type);
+
#endif
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:07 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug Louis Chauvet
` (29 subsequent siblings)
31 siblings, 2 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Debug information are mainly read by human, so use full name instead
of values.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index f8394a063ecf..cfdd5f32f234 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -348,8 +348,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
seq_puts(m, "plane:\n");
- seq_printf(m, "\ttype=%d\n",
- vkms_config_plane_get_type(plane_cfg));
+ seq_printf(m, "\ttype=%s\n",
+ drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:09 ` José Expósito
2025-10-29 14:36 ` [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status Louis Chauvet
` (28 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Debug information are mainly read by human, so display human
readable values.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index cfdd5f32f234..391794d391c5 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
@@ -354,8 +355,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
seq_puts(m, "crtc:\n");
- seq_printf(m, "\twriteback=%d\n",
- vkms_config_crtc_get_writeback(crtc_cfg));
+ seq_printf(m, "\twriteback=%s\n",
+ str_enabled_disabled(vkms_config_crtc_get_writeback(crtc_cfg)));
}
vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg)
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (2 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:11 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name Louis Chauvet
` (27 subsequent siblings)
31 siblings, 2 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Debug information are mainly read by human, so use full name instead
of raw values for connector status.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 391794d391c5..858bec2d1312 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -3,6 +3,7 @@
#include <linux/slab.h>
#include <linux/string_choices.h>
+#include <drm/drm_connector.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
#include <kunit/visibility.h>
@@ -364,8 +365,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
seq_puts(m, "connector:\n");
- seq_printf(m, "\tstatus=%d\n",
- vkms_config_connector_get_status(connector_cfg));
+ seq_printf(m, "\tstatus=%s\n",
+ drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
}
return 0;
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (3 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:17 ` José Expósito
2025-10-29 14:36 ` [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs " Louis Chauvet
` (26 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
As planes can have a name in DRM, prepare VKMS to configure it using
ConfigFS.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 4 ++++
drivers/gpu/drm/vkms/vkms_config.h | 26 ++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_drv.h | 5 +++--
drivers/gpu/drm/vkms/vkms_output.c | 6 +-----
drivers/gpu/drm/vkms/vkms_plane.c | 6 ++++--
5 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 858bec2d1312..bfafb5d2504d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -352,6 +352,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "plane:\n");
seq_printf(m, "\ttype=%s\n",
drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
+ seq_printf(m, "\tname=%s\n",
+ vkms_config_plane_get_name(plane_cfg));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -392,6 +394,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
plane_cfg->config = config;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
+ vkms_config_plane_set_name(plane_cfg, NULL);
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
list_add_tail(&plane_cfg->link, &config->planes);
@@ -404,6 +407,7 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg)
{
xa_destroy(&plane_cfg->possible_crtcs);
list_del(&plane_cfg->link);
+ kfree_const(plane_cfg->name);
kfree(plane_cfg);
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 4c8d668e7ef8..57342db5795a 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -35,6 +35,7 @@ struct vkms_config {
*
* @link: Link to the others planes in vkms_config
* @config: The vkms_config this plane belongs to
+ * @name: Name of the plane
* @type: Type of the plane. The creator of configuration needs to ensures that
* at least one primary plane is present.
* @possible_crtcs: Array of CRTCs that can be used with this plane
@@ -47,6 +48,7 @@ struct vkms_config_plane {
struct list_head link;
struct vkms_config *config;
+ const char *name;
enum drm_plane_type type;
struct xarray possible_crtcs;
@@ -288,6 +290,30 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
plane_cfg->type = type;
}
+/**
+ * vkms_config_plane_set_name() - Set the plane name
+ * @plane_cfg: Plane to set the name to
+ * @name: New plane name. The name is copied.
+ */
+static inline void
+vkms_config_plane_set_name(struct vkms_config_plane *plane_cfg,
+ const char *name)
+{
+ if (plane_cfg->name)
+ kfree_const(plane_cfg->name);
+ plane_cfg->name = kstrdup_const(name, GFP_KERNEL);
+}
+
+/**
+ * vkms_config_plane_get_name - Get the plane name
+ * @plane_cfg: Plane to get the name from
+ */
+static inline const char *
+vkms_config_plane_get_name(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->name;
+}
+
/**
* vkms_config_plane_attach_crtc - Attach a plane to a CRTC
* @plane_cfg: Plane to attach
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index db260df1d4f6..9ad286f043b5 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -225,6 +225,7 @@ struct vkms_output {
};
struct vkms_config;
+struct vkms_config_plane;
/**
* struct vkms_device - Description of a VKMS device
@@ -298,10 +299,10 @@ int vkms_output_init(struct vkms_device *vkmsdev);
* vkms_plane_init() - Initialize a plane
*
* @vkmsdev: VKMS device containing the plane
- * @type: type of plane to initialize
+ * @config: plane configuration
*/
struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
- enum drm_plane_type type);
+ struct vkms_config_plane *config);
/* CRC Support */
const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 2ee3749e2b28..22208d02afa4 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -19,11 +19,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
return -EINVAL;
vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
- enum drm_plane_type type;
-
- type = vkms_config_plane_get_type(plane_cfg);
-
- plane_cfg->plane = vkms_plane_init(vkmsdev, type);
+ plane_cfg->plane = vkms_plane_init(vkmsdev, plane_cfg);
if (IS_ERR(plane_cfg->plane)) {
DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n");
return PTR_ERR(plane_cfg->plane);
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index e592e47a5736..73180cbb78b1 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -9,6 +9,7 @@
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include "vkms_config.h"
#include "vkms_drv.h"
#include "vkms_formats.h"
@@ -217,7 +218,7 @@ static const struct drm_plane_helper_funcs vkms_plane_helper_funcs = {
};
struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
- enum drm_plane_type type)
+ struct vkms_config_plane *config)
{
struct drm_device *dev = &vkmsdev->drm;
struct vkms_plane *plane;
@@ -225,7 +226,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
vkms_formats, ARRAY_SIZE(vkms_formats),
- NULL, type, NULL);
+ NULL, vkms_config_plane_get_type(config),
+ vkms_config_plane_get_name(config));
if (IS_ERR(plane))
return plane;
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs for plane name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (4 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:21 ` José Expósito
2025-10-29 14:36 ` [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield Louis Chauvet
` (25 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Planes can have name, create a plane attribute to configure it. Currently
plane name is mainly used in logs.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 3 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 3574e01b928d..1fe6e420c963 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,10 +87,11 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 1 configurable attribute:
+Planes have 2 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
+- name: Name of the plane
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 07ab794e1052..be6c3ba998b9 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -322,10 +322,42 @@ static ssize_t plane_type_store(struct config_item *item, const char *page,
return (ssize_t)count;
}
+static ssize_t plane_name_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ const char *name;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ name = vkms_config_plane_get_name(plane->config);
+
+ return sprintf(page, "%s\n", name);
+}
+
+static ssize_t plane_name_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_name(plane->config, page);
+ }
+
+ return (ssize_t)count;
+}
+
CONFIGFS_ATTR(plane_, type);
+CONFIGFS_ATTR(plane_, name);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
+ &plane_attr_name,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (5 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-11-13 14:23 ` José Expósito
2025-12-18 17:58 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation Louis Chauvet
` (24 subsequent siblings)
31 siblings, 2 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Having the rotation/reflection name from its value can be useful for
debugging purpose. Extract the rotation property table and implement
drm_get_rotation_name.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_blend.c | 35 ++++++++++++++++++++++++++---------
include/drm/drm_blend.h | 2 ++
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 6852d73c931c..bc7c05e20242 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -241,6 +241,31 @@ int drm_plane_create_alpha_property(struct drm_plane *plane)
}
EXPORT_SYMBOL(drm_plane_create_alpha_property);
+static const struct drm_prop_enum_list rotation_props[] = {
+ { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
+ { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
+ { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
+ { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
+ { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
+ { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
+};
+
+/**
+ * drm_get_rotation_name - Return the name of a rotation
+ * @rotation: The rotation mask (DRM_MODE_ROTATE_* | DRM_MODE_REFLECT_*)
+ *
+ * Returns: the name of the rotation type (unknown) if rotation is not
+ * a known rotation/reflection
+ */
+const char *drm_get_rotation_name(unsigned int rotation)
+{
+ if (rotation < ARRAY_SIZE(rotation_props))
+ return rotation_props[rotation].name;
+
+ return "(unknown)";
+}
+EXPORT_SYMBOL(drm_get_rotation_name);
+
/**
* drm_plane_create_rotation_property - create a new rotation property
* @plane: drm plane
@@ -279,14 +304,6 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation,
unsigned int supported_rotations)
{
- static const struct drm_prop_enum_list props[] = {
- { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
- { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
- { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
- { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
- { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
- { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
- };
struct drm_property *prop;
WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
@@ -294,7 +311,7 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
WARN_ON(rotation & ~supported_rotations);
prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
- props, ARRAY_SIZE(props),
+ rotation_props, ARRAY_SIZE(rotation_props),
supported_rotations);
if (!prop)
return -ENOMEM;
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 88bdfec3bd88..381d1f8d815b 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -42,6 +42,8 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
#define DRM_BLEND_ALPHA_OPAQUE 0xffff
+const char *drm_get_rotation_name(unsigned int rotation);
+
int drm_plane_create_alpha_property(struct drm_plane *plane);
int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation,
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (6 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs " Louis Chauvet
` (23 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS driver supports all the rotation on planes, but for testing it can be
useful to only advertise few of them. This new configuration interface
will allow configuring the rotation per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 46 +++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 63 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 59 +++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 6 ++-
4 files changed, 172 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index d75a6252e4d2..8d805084ad96 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
+#include <drm/drm_mode.h>
#include <kunit/test.h>
#include "../vkms_config.h"
@@ -172,6 +173,12 @@ static void vkms_config_test_default_config(struct kunit *test)
n_possible_crtcs++;
}
KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_supported_rotations(plane_cfg),
+ DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_default_rotation(plane_cfg),
+ DRM_MODE_ROTATE_0);
}
/* Encoders */
@@ -468,6 +475,44 @@ static void vkms_config_test_valid_plane_type(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_rotations(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, no rotation, no reflection */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default rotation is not supported */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_90);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Invalid, supported rotations must contains at least one rotation */
+ vkms_config_plane_set_supported_rotations(plane_cfg, DRM_MODE_REFLECT_MASK);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default rotation must contains at least one rotation */
+ vkms_config_plane_set_supported_rotations(plane_cfg,
+ DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_REFLECT_X);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_rotation(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -990,6 +1035,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_get_connectors),
KUNIT_CASE(vkms_config_test_invalid_plane_number),
KUNIT_CASE(vkms_config_test_valid_plane_type),
+ KUNIT_CASE(vkms_config_test_valid_plane_rotations),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index bfafb5d2504d..dd951db88888 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -3,7 +3,9 @@
#include <linux/slab.h>
#include <linux/string_choices.h>
+#include <drm/drm_blend.h>
#include <drm/drm_connector.h>
+#include <drm/drm_mode.h>
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
#include <kunit/visibility.h>
@@ -146,6 +148,33 @@ static bool valid_plane_number(const struct vkms_config *config)
return true;
}
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if ((vkms_config_plane_get_default_rotation(plane_cfg) &
+ vkms_config_plane_get_supported_rotations(plane_cfg)) !=
+ vkms_config_plane_get_default_rotation(plane_cfg)) {
+ drm_info(dev, "Configured default rotation is not supported by the plane\n");
+ return false;
+ }
+
+ if ((vkms_config_plane_get_default_rotation(plane_cfg) & DRM_MODE_ROTATE_MASK) == 0) {
+ drm_info(dev, "Configured default rotation must contains at least one possible rotation\n");
+ return false;
+ }
+
+ if ((vkms_config_plane_get_supported_rotations(plane_cfg) & DRM_MODE_ROTATE_MASK) == 0) {
+ drm_info(dev, "Configured supported rotations must contains at least one possible rotation\n");
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_rotation);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -303,6 +332,12 @@ static bool valid_connector_possible_encoders(const struct vkms_config *config)
bool vkms_config_is_valid(const struct vkms_config *config)
{
struct vkms_config_crtc *crtc_cfg;
+ struct vkms_config_plane *plane_cfg;
+
+ vkms_config_for_each_plane(config, plane_cfg) {
+ if (!vkms_config_valid_plane_rotation(config, plane_cfg))
+ return false;
+ }
if (!valid_plane_number(config))
return false;
@@ -334,6 +369,22 @@ bool vkms_config_is_valid(const struct vkms_config *config)
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_is_valid);
+static void show_bitfield(struct seq_file *m, uint32_t value, const char *callback(unsigned int))
+{
+ u32 offset = 0;
+ bool first = true;
+
+ while (value >= BIT(offset) && offset < 32) {
+ if (value & BIT(offset)) {
+ if (!first)
+ seq_puts(m, ",");
+ seq_printf(m, callback(offset));
+ first = false;
+ }
+ offset += 1;
+ }
+}
+
static int vkms_config_show(struct seq_file *m, void *data)
{
struct drm_debugfs_entry *entry = m->private;
@@ -354,6 +405,14 @@ static int vkms_config_show(struct seq_file *m, void *data)
drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
seq_printf(m, "\tname=%s\n",
vkms_config_plane_get_name(plane_cfg));
+ seq_puts(m, "\tsupported rotations=");
+ show_bitfield(m, vkms_config_plane_get_supported_rotations(plane_cfg),
+ drm_get_rotation_name);
+ seq_puts(m, "\n");
+ seq_puts(m, "\tdefault rotation=");
+ show_bitfield(m, vkms_config_plane_get_default_rotation(plane_cfg),
+ drm_get_rotation_name);
+ seq_puts(m, "\n");
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -395,6 +454,10 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
plane_cfg->config = config;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
vkms_config_plane_set_name(plane_cfg, NULL);
+ vkms_config_plane_set_supported_rotations(plane_cfg,
+ DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
list_add_tail(&plane_cfg->link, &config->planes);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 57342db5795a..8d413e02180a 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -39,6 +39,8 @@ struct vkms_config {
* @type: Type of the plane. The creator of configuration needs to ensures that
* at least one primary plane is present.
* @possible_crtcs: Array of CRTCs that can be used with this plane
+ * @default_rotation: Default rotation that should be used by this plane
+ * @supported_rotation: Rotation that this plane will support
* @plane: Internal usage. This pointer should never be considered as valid.
* It can be used to store a temporary reference to a VKMS plane during
* device creation. This pointer is not managed by the configuration and
@@ -50,6 +52,8 @@ struct vkms_config_plane {
const char *name;
enum drm_plane_type type;
+ unsigned int default_rotation;
+ unsigned int supported_rotations;
struct xarray possible_crtcs;
/* Internal usage */
@@ -290,6 +294,61 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
plane_cfg->type = type;
}
+/**
+ * vkms_config_plane_get_default_rotation() - Get the default rotation for a plane
+ * @plane_cfg: Plane to get the default rotation from
+ *
+ * Returns:
+ * The default rotation for the plane.
+ */
+static inline unsigned int
+vkms_config_plane_get_default_rotation(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_rotation;
+}
+
+/**
+ * vkms_config_plane_set_default_rotation() - Set the default rotation for a plane
+ * @plane_cfg: Plane to set the default rotation to
+ * @default_rotation: New default rotation for the plane
+ */
+static inline void
+vkms_config_plane_set_default_rotation(struct vkms_config_plane *plane_cfg,
+ unsigned int default_rotation)
+{
+ plane_cfg->default_rotation = default_rotation;
+}
+
+/**
+ * vkms_config_plane_get_supported_rotations() - Get the supported rotations for a plane
+ * @plane_cfg: Plane to get the supported rotations from
+ *
+ * Returns:
+ * The supported rotations for the plane.
+ */
+static inline unsigned int
+vkms_config_plane_get_supported_rotations(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_rotations;
+}
+
+/**
+ * vkms_config_plane_set_supported_rotations() - Set the supported rotations for a plane
+ * @plane_cfg: Plane to set the supported rotations to
+ * @supported_rotations: New supported rotations for the plane
+ */
+static inline void
+vkms_config_plane_set_supported_rotations(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_rotations)
+{
+ plane_cfg->supported_rotations = supported_rotations;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 73180cbb78b1..d147b70692fa 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
+#include "vkms_config.h"
#include <linux/iosys-map.h>
#include <drm/drm_atomic.h>
@@ -233,8 +234,9 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
drm_plane_helper_add(&plane->base, &vkms_plane_helper_funcs);
- drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0,
- DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
+ drm_plane_create_rotation_property(&plane->base,
+ vkms_config_plane_get_default_rotation(config),
+ vkms_config_plane_get_supported_rotations(config));
drm_plane_create_color_properties(&plane->base,
BIT(DRM_COLOR_YCBCR_BT601) |
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs for plane rotation
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (7 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name Louis Chauvet
` (22 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
To allows the userspace to test many hardware configuration, introduce a
new interface to configure the available rotation per planes. VKMS
supports any rotation and reflection, so the userspace can choose any
combination.
The supported rotations are configured by writing a rotation bitmask to
the file `supported_rotations` and the default rotation is chosen by
writing a rotation bitmask to `default_rotation`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 7 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 91 ++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 1fe6e420c963..eac1a942d6c4 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,11 +87,16 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 2 configurable attributes:
+Planes have 4 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
- name: Name of the plane
+- possible_rotations: Available rotation for a plane, as a bitmask: 0x01 no rotation,
+ 0x02 rotate 90°, 0x04 rotate 180°, 0x08 rotate 270°, 0x10 reflect x, 0x20 reflect y
+ (same values as those exposed by the "rotation" property of a plane)
+- default_rotation: Default rotation presented to the userspace, same values as
+ possible_rotations.
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index be6c3ba998b9..7cc8ba315ef0 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -352,12 +352,103 @@ static ssize_t plane_name_store(struct config_item *item, const char *page,
return (ssize_t)count;
}
+static ssize_t plane_supported_rotations_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int plane_supported_rotations;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ plane_supported_rotations = vkms_config_plane_get_supported_rotations(plane->config);
+ }
+
+ return sprintf(page, "%u", plane_supported_rotations);
+}
+
+static ssize_t plane_supported_rotations_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 0, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
+ return -EINVAL;
+ /* Should at least provide one rotation */
+ if (!(val & DRM_MODE_ROTATE_MASK))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+
+ vkms_config_plane_set_supported_rotations(plane->config, val);
+ }
+
+ return count;
+}
+
+static ssize_t plane_default_rotation_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int plane_default_rotation;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ plane_default_rotation = vkms_config_plane_get_default_rotation(plane->config);
+ }
+
+ return sprintf(page, "%u", plane_default_rotation);
+}
+
+static ssize_t plane_default_rotation_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
+ return -EINVAL;
+ /* Should at least provide one rotation */
+ if ((val & DRM_MODE_ROTATE_MASK) == 0)
+ return -EINVAL;
+ /* Should contains only one rotation */
+ if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+
+ vkms_config_plane_set_default_rotation(plane->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, name);
+CONFIGFS_ATTR(plane_, supported_rotations);
+CONFIGFS_ATTR(plane_, default_rotation);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
&plane_attr_name,
+ &plane_attr_supported_rotations,
+ &plane_attr_default_rotation,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (8 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding Louis Chauvet
` (21 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
drm_get_color_encoding_name can be useful to display debug information
outside drm core. Export it so it could be used for VKMS
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_color_mgmt.c | 2 +-
drivers/gpu/drm/drm_crtc_internal.h | 2 --
include/drm/drm_color_mgmt.h | 2 ++
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 131c1c9ae92f..b0a3be3cc016 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -496,7 +496,7 @@ const char *drm_get_color_encoding_name(enum drm_color_encoding encoding)
return color_encoding_name[encoding];
}
-EXPORT_SYMBOL_IF_KUNIT(drm_get_color_encoding_name);
+EXPORT_SYMBOL(drm_get_color_encoding_name);
/**
* drm_get_color_range_name - return a string for color range
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 89706aa8232f..68fd5385917f 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -38,7 +38,6 @@
#include <linux/err.h>
#include <linux/types.h>
-enum drm_color_encoding;
enum drm_color_range;
enum drm_connector_force;
enum drm_mode_status;
@@ -121,7 +120,6 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
/* drm_color_mgmt.c */
-const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
const char *drm_get_color_range_name(enum drm_color_range range);
/* IOCTLs */
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index eccb71ab335a..eb55bdd33f50 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -85,6 +85,8 @@ enum drm_color_range {
DRM_COLOR_RANGE_MAX,
};
+const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
+
int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
u32 supported_ranges,
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (9 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs " Louis Chauvet
` (20 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS driver supports all the color encoding on planes, but for testing it
can be useful to only advertise few of them. This new configuration
interface will allow configuring the color encoding per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 51 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 32 ++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 64 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 15 +++----
4 files changed, 154 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index 8d805084ad96..e9bc051188f9 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -179,6 +179,14 @@ static void vkms_config_test_default_config(struct kunit *test)
KUNIT_EXPECT_EQ(test,
vkms_config_plane_get_default_rotation(plane_cfg),
DRM_MODE_ROTATE_0);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_supported_color_encodings(plane_cfg),
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_plane_get_default_color_encoding(plane_cfg),
+ DRM_COLOR_YCBCR_BT601);
}
/* Encoders */
@@ -513,6 +521,48 @@ static void vkms_config_test_valid_plane_rotations(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, all color encoding supported */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default color encoding is not supported */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT709);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, no supported or color encoding */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_default_color_encoding(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, if no supported color encoding, default is ignored */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1036,6 +1086,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_invalid_plane_number),
KUNIT_CASE(vkms_config_test_valid_plane_type),
KUNIT_CASE(vkms_config_test_valid_plane_rotations),
+ KUNIT_CASE(vkms_config_test_valid_plane_color_encoding),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index dd951db88888..6a3d52c1141d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -175,6 +175,25 @@ bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_rotation);
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if (vkms_config_plane_get_supported_color_encodings(plane_cfg)) {
+ if ((BIT(vkms_config_plane_get_default_color_encoding(plane_cfg)) &
+ vkms_config_plane_get_supported_color_encodings(plane_cfg)) !=
+ BIT(vkms_config_plane_get_default_color_encoding(plane_cfg))) {
+ drm_info(dev, "Configured default color encoding is not supported by the plane\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_encoding);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -337,6 +356,9 @@ bool vkms_config_is_valid(const struct vkms_config *config)
vkms_config_for_each_plane(config, plane_cfg) {
if (!vkms_config_valid_plane_rotation(config, plane_cfg))
return false;
+
+ if (!vkms_config_valid_plane_color_encoding(config, plane_cfg))
+ return false;
}
if (!valid_plane_number(config))
@@ -413,6 +435,12 @@ static int vkms_config_show(struct seq_file *m, void *data)
show_bitfield(m, vkms_config_plane_get_default_rotation(plane_cfg),
drm_get_rotation_name);
seq_puts(m, "\n");
+ seq_puts(m, "\tsupported color encoding=");
+ show_bitfield(m, vkms_config_plane_get_supported_color_encodings(plane_cfg),
+ drm_get_color_encoding_name);
+ seq_puts(m, "\n");
+ seq_printf(m, "\tdefault color encoding=%s\n",
+ drm_get_color_encoding_name(vkms_config_plane_get_default_color_encoding(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -457,6 +485,10 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
vkms_config_plane_set_supported_rotations(plane_cfg,
DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK);
vkms_config_plane_set_default_rotation(plane_cfg, DRM_MODE_ROTATE_0);
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020));
+ vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 8d413e02180a..d740c9478256 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -45,6 +45,8 @@ struct vkms_config {
* It can be used to store a temporary reference to a VKMS plane during
* device creation. This pointer is not managed by the configuration and
* must be managed by other means.
+ * @default_color_encoding: Default color encoding that should be used by this plane
+ * @supported_color_encodings: Color encoding that this plane will support
*/
struct vkms_config_plane {
struct list_head link;
@@ -54,6 +56,8 @@ struct vkms_config_plane {
enum drm_plane_type type;
unsigned int default_rotation;
unsigned int supported_rotations;
+ enum drm_color_encoding default_color_encoding;
+ unsigned int supported_color_encodings;
struct xarray possible_crtcs;
/* Internal usage */
@@ -349,6 +353,66 @@ bool vkms_config_valid_plane_rotation(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+/**
+ * vkms_config_plane_get_default_color_encoding() - Get the default color encoding for a plane
+ * @plane_cfg: Plane to get the default color encoding from
+ *
+ * Returns:
+ * The default color encoding for the plane
+ */
+static inline enum drm_color_encoding
+vkms_config_plane_get_default_color_encoding(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_color_encoding;
+}
+
+/**
+ * vkms_config_plane_set_default_color_encoding() - Set the default color encoding for a plane
+ * @plane_cfg: Plane to set the default color encoding to
+ * @default_color_encoding: New default color encoding for the plane
+ */
+static inline void
+vkms_config_plane_set_default_color_encoding(struct vkms_config_plane *plane_cfg,
+ enum drm_color_encoding default_color_encoding)
+{
+ plane_cfg->default_color_encoding = default_color_encoding;
+}
+
+/**
+ * vkms_config_plane_get_supported_color_encodings() - Get the supported color encodings for a plane
+ * @plane_cfg: Plane to get the supported color encodings from
+ *
+ * Returns:
+ * The supported color encodings for the plane. Each set bit correspond to a value of enum
+ * drm_color_encoding: BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709) means that
+ * DRM_COLOR_YCBCR_BT601 and DRM_COLOR_YCBCR_BT709 are supported.
+ */
+static inline unsigned int
+vkms_config_plane_get_supported_color_encodings(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_color_encodings;
+}
+
+/**
+ * vkms_config_plane_set_supported_color_encodings() - Set the supported color encodings for a plane
+ * @plane_cfg: Plane to set the supported color encodings to
+ * @supported_color_encodings: New supported color encodings for the plane. Each set bit corresponds
+ * to a value of enum drm_color_encoding:
+ * BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709) means that
+ * DRM_COLOR_YCBCR_BT601 and DRM_COLOR_YCBCR_BT709 are supported.
+ */
+static inline void
+vkms_config_plane_set_supported_color_encodings(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_color_encodings)
+{
+ plane_cfg->supported_color_encodings = supported_color_encodings;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index d147b70692fa..9550831be51a 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -238,14 +238,13 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
vkms_config_plane_get_default_rotation(config),
vkms_config_plane_get_supported_rotations(config));
- drm_plane_create_color_properties(&plane->base,
- BIT(DRM_COLOR_YCBCR_BT601) |
- BIT(DRM_COLOR_YCBCR_BT709) |
- BIT(DRM_COLOR_YCBCR_BT2020),
- BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
- BIT(DRM_COLOR_YCBCR_FULL_RANGE),
- DRM_COLOR_YCBCR_BT601,
- DRM_COLOR_YCBCR_FULL_RANGE);
+ if (vkms_config_plane_get_supported_color_encodings(config) != 0)
+ drm_plane_create_color_properties(&plane->base,
+ vkms_config_plane_get_supported_color_encodings(config),
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ vkms_config_plane_get_default_color_encoding(config),
+ DRM_COLOR_YCBCR_FULL_RANGE);
return plane;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs for plane color encoding
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (10 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name Louis Chauvet
` (19 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
To allows the userspace to test many hardware configuration, introduce a
new interface to configure the available color encoding per planes. VKMS
supports multiple color encoding, so the userspace can choose any
combination.
The supported color encoding are configured by writing a color encoding
bitmask to the file `supported_color_encoding` and the default color
encoding is chosen by writing a color encoding bitmask to
`default_color_encoding`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 7 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 98 ++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index eac1a942d6c4..dab6811687a2 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,7 +87,7 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 4 configurable attributes:
+Planes have 6 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -97,6 +97,11 @@ Planes have 4 configurable attributes:
(same values as those exposed by the "rotation" property of a plane)
- default_rotation: Default rotation presented to the userspace, same values as
possible_rotations.
+- supported_color_encoding: Available encoding for a plane, as a bitmask:
+ 0x01 YCBCR_BT601, 0x02: YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
+ by the COLOR_ENCODING property of a plane)
+- default_color_encoding: Default color encoding presented to the userspace, same
+ values as supported_color_encoding
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 7cc8ba315ef0..ee2e8d141f9e 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -439,16 +439,114 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
return count;
}
+static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int supported_color_encoding;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ supported_color_encoding = vkms_config_plane_get_supported_color_encodings(plane->config);
+ }
+
+ return sprintf(page, "%u", supported_color_encoding);
+}
+
+static ssize_t plane_supported_color_encodings_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020)))
+ return -EINVAL;
+ /* Should at least provide one color range */
+ if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+
+ vkms_config_plane_set_supported_color_encodings(plane->config, val);
+ }
+
+ return count;
+}
+
+/* Plane default_color_encoding : vkms/<device>/planes/<plane>/default_color_encoding */
+
+static ssize_t plane_default_color_encoding_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int default_color_encoding;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ default_color_encoding = vkms_config_plane_get_default_color_encoding(plane->config);
+ }
+
+ return sprintf(page, "%u", default_color_encoding);
+}
+
+static ssize_t plane_default_color_encoding_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020)))
+ return -EINVAL;
+ /* Should at least provide one color range */
+ if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
+ BIT(DRM_COLOR_YCBCR_BT709) |
+ BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+
+ vkms_config_plane_set_default_color_encoding(plane->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, name);
CONFIGFS_ATTR(plane_, supported_rotations);
CONFIGFS_ATTR(plane_, default_rotation);
+CONFIGFS_ATTR(plane_, supported_color_encodings);
+CONFIGFS_ATTR(plane_, default_color_encoding);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
&plane_attr_name,
&plane_attr_supported_rotations,
&plane_attr_default_rotation,
+ &plane_attr_supported_color_encodings,
+ &plane_attr_default_color_encoding,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (11 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range Louis Chauvet
` (18 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
drm_get_color_range_name can be useful to print debugging information.
Export it so it could be used from VKMS.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_color_mgmt.c | 2 +-
drivers/gpu/drm/drm_crtc_internal.h | 4 ----
include/drm/drm_color_mgmt.h | 1 +
3 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index b0a3be3cc016..5b24b9843531 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -512,7 +512,7 @@ const char *drm_get_color_range_name(enum drm_color_range range)
return color_range_name[range];
}
-EXPORT_SYMBOL_IF_KUNIT(drm_get_color_range_name);
+EXPORT_SYMBOL(drm_get_color_range_name);
/**
* drm_plane_create_color_properties - color encoding related plane properties
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 68fd5385917f..9141127a16ab 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -38,7 +38,6 @@
#include <linux/err.h>
#include <linux/types.h>
-enum drm_color_range;
enum drm_connector_force;
enum drm_mode_status;
@@ -119,9 +118,6 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-/* drm_color_mgmt.c */
-const char *drm_get_color_range_name(enum drm_color_range range);
-
/* IOCTLs */
int drm_mode_gamma_get_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index eb55bdd33f50..0d25b7d9cb29 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -86,6 +86,7 @@ enum drm_color_range {
};
const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
+const char *drm_get_color_range_name(enum drm_color_range range);
int drm_plane_create_color_properties(struct drm_plane *plane,
u32 supported_encodings,
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (12 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs " Louis Chauvet
` (17 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS driver supports all the color range on planes, but for testing it can
be useful to only advertise few of them. This new configuration interface
will allow configuring the color range per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 44 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 39 ++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 35 +++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 8 ++---
4 files changed, 122 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index e9bc051188f9..d962fec8d3b3 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_mode.h>
#include <kunit/test.h>
@@ -549,6 +550,7 @@ static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
/* Valid, no supported or color encoding */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
vkms_config_plane_set_default_color_encoding(plane_cfg, 0);
KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_encoding(config, plane_cfg));
@@ -563,6 +565,47 @@ static void vkms_config_test_valid_plane_color_encoding(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_color_range(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, all color range supported */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_FULL_RANGE);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, default color range is not supported */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg,
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_LIMITED_RANGE);
+ KUNIT_EXPECT_FALSE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, no supported or color range */
+ vkms_config_plane_set_supported_color_encodings(plane_cfg, 0);
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
+ vkms_config_plane_set_default_color_range(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, if no supported color range, default is ignored */
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, 0);
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_LIMITED_RANGE);
+ KUNIT_EXPECT_TRUE(test, vkms_config_valid_plane_color_range(config, plane_cfg));
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1087,6 +1130,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_valid_plane_type),
KUNIT_CASE(vkms_config_test_valid_plane_rotations),
KUNIT_CASE(vkms_config_test_valid_plane_color_encoding),
+ KUNIT_CASE(vkms_config_test_valid_plane_color_range),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 6a3d52c1141d..823039fb4145 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -194,6 +194,25 @@ bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_encoding);
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if (vkms_config_plane_get_supported_color_ranges(plane_cfg)) {
+ if ((BIT(vkms_config_plane_get_default_color_range(plane_cfg)) &
+ vkms_config_plane_get_supported_color_ranges(plane_cfg)) !=
+ BIT(vkms_config_plane_get_default_color_range(plane_cfg))) {
+ drm_info(dev, "Configured default color range is not supported by the plane\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_range);
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -350,6 +369,7 @@ static bool valid_connector_possible_encoders(const struct vkms_config *config)
bool vkms_config_is_valid(const struct vkms_config *config)
{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
struct vkms_config_crtc *crtc_cfg;
struct vkms_config_plane *plane_cfg;
@@ -359,6 +379,16 @@ bool vkms_config_is_valid(const struct vkms_config *config)
if (!vkms_config_valid_plane_color_encoding(config, plane_cfg))
return false;
+
+ if (!vkms_config_valid_plane_color_range(config, plane_cfg))
+ return false;
+
+ if ((vkms_config_plane_get_supported_color_encodings(plane_cfg) == 0) !=
+ (vkms_config_plane_get_supported_color_ranges(plane_cfg) == 0)) {
+ drm_info(dev,
+ "Both supported color encoding and color range must be set, or none\n");
+ return false;
+ }
}
if (!valid_plane_number(config))
@@ -441,6 +471,12 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "\n");
seq_printf(m, "\tdefault color encoding=%s\n",
drm_get_color_encoding_name(vkms_config_plane_get_default_color_encoding(plane_cfg)));
+ seq_puts(m, "\tsupported color range=");
+ show_bitfield(m, vkms_config_plane_get_supported_color_ranges(plane_cfg),
+ drm_get_color_range_name);
+ seq_puts(m, "\n");
+ seq_printf(m, "\tdefault color range=%s\n",
+ drm_get_color_range_name(vkms_config_plane_get_default_color_range(plane_cfg)));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -489,6 +525,9 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
BIT(DRM_COLOR_YCBCR_BT709) |
BIT(DRM_COLOR_YCBCR_BT2020));
vkms_config_plane_set_default_color_encoding(plane_cfg, DRM_COLOR_YCBCR_BT601);
+ vkms_config_plane_set_supported_color_ranges(plane_cfg, BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE));
+ vkms_config_plane_set_default_color_range(plane_cfg, DRM_COLOR_YCBCR_FULL_RANGE);
xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index d740c9478256..d8648bf844d4 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -47,6 +47,8 @@ struct vkms_config {
* must be managed by other means.
* @default_color_encoding: Default color encoding that should be used by this plane
* @supported_color_encodings: Color encoding that this plane will support
+ * @default_color_range: Default color range that should be used by this plane
+ * @supported_color_ranges: Color range that this plane will support
*/
struct vkms_config_plane {
struct list_head link;
@@ -58,6 +60,8 @@ struct vkms_config_plane {
unsigned int supported_rotations;
enum drm_color_encoding default_color_encoding;
unsigned int supported_color_encodings;
+ enum drm_color_range default_color_range;
+ unsigned int supported_color_ranges;
struct xarray possible_crtcs;
/* Internal usage */
@@ -413,6 +417,37 @@ bool vkms_config_valid_plane_color_encoding(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+static inline enum drm_color_range
+vkms_config_plane_get_default_color_range(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->default_color_range;
+}
+
+static inline void
+vkms_config_plane_set_default_color_range(struct vkms_config_plane *plane_cfg,
+ enum drm_color_range default_color_range)
+{
+ plane_cfg->default_color_range = default_color_range;
+}
+
+static inline unsigned int
+vkms_config_plane_get_supported_color_ranges(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_color_ranges;
+}
+
+static inline void
+vkms_config_plane_set_supported_color_ranges(struct vkms_config_plane *plane_cfg,
+ unsigned int supported_color_ranges)
+{
+ plane_cfg->supported_color_ranges = supported_color_ranges;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 9550831be51a..5dbc7c67de1d 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -238,13 +238,13 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
vkms_config_plane_get_default_rotation(config),
vkms_config_plane_get_supported_rotations(config));
- if (vkms_config_plane_get_supported_color_encodings(config) != 0)
+ if (vkms_config_plane_get_supported_color_encodings(config) != 0 &&
+ vkms_config_plane_get_supported_color_ranges(config) != 0)
drm_plane_create_color_properties(&plane->base,
vkms_config_plane_get_supported_color_encodings(config),
- BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
- BIT(DRM_COLOR_YCBCR_FULL_RANGE),
+ vkms_config_plane_get_supported_color_ranges(config),
vkms_config_plane_get_default_color_encoding(config),
- DRM_COLOR_YCBCR_FULL_RANGE);
+ vkms_config_plane_get_default_color_range(config));
return plane;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs for plane color range
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (13 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-18 18:00 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format Louis Chauvet
` (16 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
To allows the userspace to test many hardware configuration, introduce a
new interface to configure the available color ranges per planes. VKMS
supports multiple color ranges, so the userspace can choose any
combination.
The supported color ranges are configured by writing a color range bitmask
to the file `supported_color_ranges` and the default color range is
chosen by writing a color encoding bitmask to `default_color_range`.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 11 ++++-
drivers/gpu/drm/vkms/vkms_configfs.c | 89 ++++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index dab6811687a2..8383e1b94668 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,7 +87,7 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 6 configurable attributes:
+Planes have 8 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -99,9 +99,16 @@ Planes have 6 configurable attributes:
possible_rotations.
- supported_color_encoding: Available encoding for a plane, as a bitmask:
0x01 YCBCR_BT601, 0x02: YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
- by the COLOR_ENCODING property of a plane)
+ by the COLOR_ENCODING property of a plane). If set, supported_color_range
+ must be set too.
- default_color_encoding: Default color encoding presented to the userspace, same
values as supported_color_encoding
+- supported_color_range: Available color range for a plane, as a bitmask:
+ 0x1 DRM_COLOR_YCBCR_LIMITED_RANGE, 0x2 DRM_COLOR_YCBCR_FULL_RANGE (same values as
+ those exposed by the COLOR_RANGE property of a plane). If set, supported_color_encoding
+ must be set too.
+- default_color_range: Default color range presented to the userspace, same
+ values as supported_color_range
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index ee2e8d141f9e..3f658dd41272 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -439,6 +439,91 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
return count;
}
+static ssize_t plane_supported_color_ranges_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int supported_color_range;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ supported_color_range = vkms_config_plane_get_supported_color_ranges(plane->config);
+ }
+
+ return sprintf(page, "%u", supported_color_range);
+}
+
+static ssize_t plane_supported_color_ranges_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
+ return -EINVAL;
+ /* Should at least provide one color range */
+ if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+ vkms_config_plane_set_supported_color_ranges(plane->config, val);
+ }
+
+ return count;
+}
+
+static ssize_t plane_default_color_range_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int default_color_range;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ default_color_range = vkms_config_plane_get_default_color_range(plane->config);
+
+ return sprintf(page, "%u", default_color_range);
+}
+
+static ssize_t plane_default_color_range_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
+ int ret, val = 0;
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ /* Should be a supported value */
+ if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
+ return -EINVAL;
+ /* Should at least provide one color range */
+ if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+ BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ /* Ensures that the default rotation is included in supported rotation */
+ if (plane->dev->enabled)
+ return -EINVAL;
+ vkms_config_plane_set_default_color_range(plane->config, val);
+ }
+
+ return count;
+}
+
static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
{
struct vkms_configfs_plane *plane;
@@ -537,6 +622,8 @@ CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, name);
CONFIGFS_ATTR(plane_, supported_rotations);
CONFIGFS_ATTR(plane_, default_rotation);
+CONFIGFS_ATTR(plane_, supported_color_ranges);
+CONFIGFS_ATTR(plane_, default_color_range);
CONFIGFS_ATTR(plane_, supported_color_encodings);
CONFIGFS_ATTR(plane_, default_color_encoding);
@@ -545,6 +632,8 @@ static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_name,
&plane_attr_supported_rotations,
&plane_attr_default_rotation,
+ &plane_attr_supported_color_ranges,
+ &plane_attr_default_color_range,
&plane_attr_supported_color_encodings,
&plane_attr_default_color_encoding,
NULL,
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (14 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 14:55 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs " Louis Chauvet
` (15 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS driver supports all the pixel formats for planes, but for testing it
can be useful to only advertise few of them. This new configuration
interface will allow configuring the pixel format per planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_config.c | 114 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.h | 51 +++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 39 +------------
3 files changed, 167 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 823039fb4145..a3fb80451b30 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -12,6 +12,42 @@
#include "vkms_config.h"
+static const u32 vkms_supported_plane_formats[] = {
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_RGBA8888,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_XRGB16161616,
+ DRM_FORMAT_XBGR16161616,
+ DRM_FORMAT_ARGB16161616,
+ DRM_FORMAT_ABGR16161616,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YUV422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU420,
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YVU444,
+ DRM_FORMAT_P010,
+ DRM_FORMAT_P012,
+ DRM_FORMAT_P016,
+ DRM_FORMAT_R1,
+ DRM_FORMAT_R2,
+ DRM_FORMAT_R4,
+ DRM_FORMAT_R8,
+};
+
struct vkms_config *vkms_config_create(const char *dev_name)
{
struct vkms_config *config;
@@ -437,6 +473,15 @@ static void show_bitfield(struct seq_file *m, uint32_t value, const char *callba
}
}
+static void show_formats(struct seq_file *m, u32 *formats, size_t formats_count)
+{
+ for (int i = 0; i < formats_count; i++) {
+ seq_printf(m, "%p4cc", &formats[i]);
+ if (i != formats_count - 1)
+ seq_puts(m, ", ");
+ }
+}
+
static int vkms_config_show(struct seq_file *m, void *data)
{
struct drm_debugfs_entry *entry = m->private;
@@ -477,6 +522,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "\n");
seq_printf(m, "\tdefault color range=%s\n",
drm_get_color_range_name(vkms_config_plane_get_default_color_range(plane_cfg)));
+ seq_puts(m, "\tsupported formats=");
+ show_formats(m, vkms_config_plane_get_supported_formats(plane_cfg),
+ vkms_config_plane_get_supported_formats_count(plane_cfg));
+ seq_puts(m, "\n");
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
@@ -515,6 +564,11 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
if (!plane_cfg)
return ERR_PTR(-ENOMEM);
+ if (vkms_config_plane_add_all_formats(plane_cfg)) {
+ kfree(plane_cfg);
+ return ERR_PTR(-ENOMEM);
+ }
+
plane_cfg->config = config;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
vkms_config_plane_set_name(plane_cfg, NULL);
@@ -644,6 +698,66 @@ static struct vkms_config_plane *vkms_config_crtc_get_plane(const struct vkms_co
return NULL;
}
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *plane_cfg)
+{
+ u32 *ret = krealloc_array(plane_cfg->supported_formats,
+ ARRAY_SIZE(vkms_supported_plane_formats),
+ sizeof(uint32_t), GFP_KERNEL);
+ if (!ret)
+ return -ENOMEM;
+ plane_cfg->supported_formats = ret;
+
+ memcpy(plane_cfg->supported_formats, vkms_supported_plane_formats,
+ sizeof(vkms_supported_plane_formats));
+ plane_cfg->supported_formats_count = ARRAY_SIZE(vkms_supported_plane_formats);
+ return 0;
+}
+
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
+{
+ bool found = false;
+
+ for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
+ if (vkms_supported_plane_formats[i] == drm_format) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return -EINVAL;
+ for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
+ if (plane_cfg->supported_formats[i] == drm_format)
+ return 0;
+ }
+ u32 *new_ptr = krealloc_array(plane_cfg->supported_formats,
+ plane_cfg->supported_formats_count + 1,
+ sizeof(*plane_cfg->supported_formats), GFP_KERNEL);
+ if (!new_ptr)
+ return -ENOMEM;
+
+ plane_cfg->supported_formats = new_ptr;
+ plane_cfg->supported_formats[plane_cfg->supported_formats_count] = drm_format;
+ plane_cfg->supported_formats_count++;
+
+ return 0;
+}
+
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *plane_cfg)
+{
+ plane_cfg->supported_formats_count = 0;
+}
+
+void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
+{
+ for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
+ if (plane_cfg->supported_formats[i] == drm_format) {
+ plane_cfg->supported_formats[i] = plane_cfg->supported_formats[plane_cfg->supported_formats_count - 1];
+ plane_cfg->supported_formats_count--;
+ }
+ }
+}
+
struct vkms_config_plane *vkms_config_crtc_primary_plane(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index d8648bf844d4..2d9e35b7caad 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -49,6 +49,8 @@ struct vkms_config {
* @supported_color_encodings: Color encoding that this plane will support
* @default_color_range: Default color range that should be used by this plane
* @supported_color_ranges: Color range that this plane will support
+ * @supported_formats: List of supported formats
+ * @supported_formats_count: Length of @supported_formats
*/
struct vkms_config_plane {
struct list_head link;
@@ -62,6 +64,8 @@ struct vkms_config_plane {
unsigned int supported_color_encodings;
enum drm_color_range default_color_range;
unsigned int supported_color_ranges;
+ u32 *supported_formats;
+ unsigned int supported_formats_count;
struct xarray possible_crtcs;
/* Internal usage */
@@ -448,6 +452,53 @@ bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
const struct vkms_config_plane *plane_cfg);
#endif
+static inline u32 *
+vkms_config_plane_get_supported_formats(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_formats;
+}
+
+static inline unsigned int
+vkms_config_plane_get_supported_formats_count(struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->supported_formats_count;
+}
+
+/** vkms_config_plane_add_format - Add a format to the list of supported format of a plane
+ *
+ * The passed drm_format can already be present in the list. This may fail if the allocation of a
+ * bigger array fails.
+ *
+ * @plane_cfg: Plane to add the format to
+ * @drm_format: Format to add to this plane
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails, -EINVAL if the format is not supported
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
+
+/**
+ * vkms_config_plane_add_all_formats - Helper to quickly add all the supported formats
+ * @plane_cfg: Plane to add the formats to
+ *
+ * Returns: 0 on success, -ENOMEM if array allocation fails, -EINVAL if the format is not supported
+ * by VKMS
+ */
+int __must_check vkms_config_plane_add_all_formats(struct vkms_config_plane *plane_cfg);
+
+/**
+ * vkms_config_plane_remove_format - Remove a specific format from a plane
+ * @plane_cfg: Plane to remove the format to
+ * @drm_format: Format to remove
+ */
+void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
+
+/**
+ * vkms_config_plane_remove_all_formats - Remove all formast from a plane
+ * @plane_cfg: Plane to remove the formats from
+ */
+void vkms_config_plane_remove_all_formats(struct vkms_config_plane *plane_cfg);
+
/**
* vkms_config_plane_set_name() - Set the plane name
* @plane_cfg: Plane to set the name to
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 5dbc7c67de1d..945abbbeac99 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -14,42 +14,6 @@
#include "vkms_drv.h"
#include "vkms_formats.h"
-static const u32 vkms_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_BGRA8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_XRGB8888,
- DRM_FORMAT_XBGR8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_BGR888,
- DRM_FORMAT_XRGB16161616,
- DRM_FORMAT_XBGR16161616,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
- DRM_FORMAT_NV21,
- DRM_FORMAT_NV61,
- DRM_FORMAT_NV42,
- DRM_FORMAT_YUV420,
- DRM_FORMAT_YUV422,
- DRM_FORMAT_YUV444,
- DRM_FORMAT_YVU420,
- DRM_FORMAT_YVU422,
- DRM_FORMAT_YVU444,
- DRM_FORMAT_P010,
- DRM_FORMAT_P012,
- DRM_FORMAT_P016,
- DRM_FORMAT_R1,
- DRM_FORMAT_R2,
- DRM_FORMAT_R4,
- DRM_FORMAT_R8,
-};
-
static struct drm_plane_state *
vkms_plane_duplicate_state(struct drm_plane *plane)
{
@@ -226,7 +190,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
&vkms_plane_funcs,
- vkms_formats, ARRAY_SIZE(vkms_formats),
+ vkms_config_plane_get_supported_formats(config),
+ vkms_config_plane_get_supported_formats_count(config),
NULL, vkms_config_plane_get_type(config),
vkms_config_plane_get_name(config));
if (IS_ERR(plane))
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs for plane format
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (15 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:07 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos Louis Chauvet
` (14 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
To allow the userspace to test many hardware configuration, introduce a
new interface to configure the available formats per planes. VKMS supports
multiple formats, so the userspace can choose any combination.
The supported formats are configured by writing the fourcc code in
supported_formats:
# enable AR24 format
echo '+AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
# disable AR24 format
echo '-AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
# enable all format supported by VKMS
echo '+*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
# disable all formats
echo '-*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 7 +-
drivers/gpu/drm/vkms/tests/Makefile | 1 +
drivers/gpu/drm/vkms/tests/vkms_configfs_test.c | 102 ++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_configfs.c | 119 ++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_configfs.h | 6 ++
5 files changed, 234 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 8383e1b94668..779ae363110d 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,7 +87,7 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 8 configurable attributes:
+Planes have 9 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -109,6 +109,11 @@ Planes have 8 configurable attributes:
must be set too.
- default_color_range: Default color range presented to the userspace, same
values as supported_color_range
+- supported_formats: List of supported formats for this plane. To add a new item in the
+ list, write it using a plus its fourcc code: +XR24
+ To remove a format, use a minus and its fourcc: -XR24
+ To add all formats use +*
+ To remove all formats, use -*
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/tests/Makefile b/drivers/gpu/drm/vkms/tests/Makefile
index 5750f0bd9d40..a2dc4008d27e 100644
--- a/drivers/gpu/drm/vkms/tests/Makefile
+++ b/drivers/gpu/drm/vkms/tests/Makefile
@@ -2,6 +2,7 @@
vkms-kunit-tests-y := \
vkms_config_test.o \
+ vkms_configfs_test.o \
vkms_format_test.o
obj-$(CONFIG_DRM_VKMS_KUNIT_TEST) += vkms-kunit-tests.o
diff --git a/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c b/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c
new file mode 100644
index 000000000000..0963a8e8a585
--- /dev/null
+++ b/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "linux/printk.h"
+#include <kunit/test.h>
+
+#include "../vkms_configfs.h"
+
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+
+/**
+ * struct vkms_configfs_parse_format_case - Store test case for format parsing
+ * @data: Contains the string to parse
+ * @data_len: data len
+ * @expected_len: expected len of the matched format
+ * @expected_offset: expected offset in the string for the parsed format
+ */
+struct vkms_configfs_parse_format_case {
+ const char *data;
+ int data_len;
+ int expected_len;
+ int expected_offset;
+};
+
+struct vkms_configfs_parse_format_case vkms_configfs_parse_format_test_cases[] = {
+ {
+ .data = "+RG24",
+ .data_len = 6,
+ .expected_len = 5,
+ .expected_offset = 0,
+ }, {
+ .data = "-RG24",
+ .data_len = 6,
+ .expected_len = 5,
+ .expected_offset = 0
+ }, {
+ .data = " -RG24",
+ .data_len = 8,
+ .expected_len = 5,
+ .expected_offset = 2
+ }, {
+ .data = "+*",
+ .data_len = 3,
+ .expected_len = 2,
+ .expected_offset = 0
+ }, {
+ .data = "-RG24+RG24",
+ .data_len = 11,
+ .expected_len = 5,
+ .expected_offset = 0
+ }, {
+ .data = "-R1+RG24",
+ .data_len = 9,
+ .expected_len = 3,
+ .expected_offset = 0
+ }, {
+ .data = "\n-R1",
+ .data_len = 5,
+ .expected_len = 3,
+ .expected_offset = 1
+ }, {
+ .data = "-R1111",
+ .data_len = 3,
+ .expected_len = 3,
+ .expected_offset = 0
+ }
+};
+
+static void vkms_configfs_test_parse_format(struct kunit *test)
+{
+ const struct vkms_configfs_parse_format_case *param = test->param_value;
+ char *out;
+ int len = vkms_configfs_parse_next_format(param->data, param->data + param->data_len, &out);
+
+ KUNIT_EXPECT_EQ(test, len, param->expected_len);
+ KUNIT_EXPECT_PTR_EQ(test, out, param->data + param->expected_offset);
+}
+
+static void vkms_configfs_test_parse_format_get_desc(struct vkms_configfs_parse_format_case *t,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", t->data);
+}
+
+KUNIT_ARRAY_PARAM(vkms_configfs_test_parse_format, vkms_configfs_parse_format_test_cases,
+ vkms_configfs_test_parse_format_get_desc
+);
+
+static struct kunit_case vkms_configfs_test_cases[] = {
+ KUNIT_CASE_PARAM(vkms_configfs_test_parse_format,
+ vkms_configfs_test_parse_format_gen_params),
+ {}
+};
+
+static struct kunit_suite vkms_configfs_test_suite = {
+ .name = "vkms-configfs",
+ .test_cases = vkms_configfs_test_cases,
+};
+
+kunit_test_suite(vkms_configfs_test_suite);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kunit test for vkms configfs utility");
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 3f658dd41272..b0a26c4dbebe 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0+
+
#include <linux/cleanup.h>
#include <linux/configfs.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/string.h>
+#include <kunit/visibility.h>
#include "vkms_drv.h"
#include "vkms_config.h"
@@ -618,6 +621,120 @@ static ssize_t plane_default_color_encoding_store(struct config_item *item,
return count;
}
+static ssize_t plane_supported_formats_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ page[0] = '\0';
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ u32 *formats = vkms_config_plane_get_supported_formats(plane->config);
+
+ for (int i = 0;
+ i < vkms_config_plane_get_supported_formats_count(plane->config);
+ i++) {
+ char tmp[6] = { 0 };
+ const ssize_t ret = snprintf(tmp, ARRAY_SIZE(tmp), "%.*s\n",
+ (int)sizeof(*formats),
+ (char *)&formats[i]);
+ if (ret < 0)
+ return ret;
+ /*
+ * Limitation of ConfigFS attributes, an attribute can't be bigger
+ * than PAGE_SIZE. This will crop the result if this plane support
+ * more than ≈1000 formats.
+ */
+ if (ret + strlen(page) > PAGE_SIZE - 1)
+ return -ENOMEM;
+ strncat(page, tmp, ARRAY_SIZE(tmp));
+ }
+ }
+
+ return strlen(page);
+}
+
+/**
+ * parse_next_format() - Parse the next format in page, skipping all non fourcc-related characters
+ * @page: page to search into
+ * @page_end: last charater of the page
+ * @out: Output pointer, will point inside page
+ *
+ * Returns: size of the matched format, @out will point to the + or -
+ */
+VISIBLE_IF_KUNIT
+int vkms_configfs_parse_next_format(const char *page, const char *page_end, char **out)
+{
+ int count = page - page_end;
+ char *tmp_plus = strnchr(page, count, '+');
+ char *tmp_minus = strnchr(page, count, '-');
+
+ if (!tmp_plus && !tmp_minus)
+ return 0;
+ if (!tmp_plus)
+ *out = tmp_minus;
+ else if (!tmp_minus)
+ *out = tmp_plus;
+ else
+ *out = min(tmp_plus, tmp_minus);
+
+ char *end = *out + 1;
+
+ while (end < page_end) {
+ if (!isalnum(*end) && *end != '*')
+ break;
+ end++;
+ }
+
+ return end - *out;
+}
+EXPORT_SYMBOL_IF_KUNIT(vkms_configfs_parse_next_format);
+
+static ssize_t plane_supported_formats_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_plane *plane;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+ int ret = 0;
+ const char *end_page = page + count;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ while (1) {
+ char *tmp;
+ char fmt[4] = {' ', ' ', ' ', ' '};
+ int len = vkms_configfs_parse_next_format(page, end_page, &tmp);
+
+ // No fourcc code found
+ if (len <= 1)
+ break;
+
+ page = tmp + len;
+ memcpy(tmp, &fmt[1], min(len - 1, 4));
+ if (tmp[0] == '+') {
+ if (fmt[0] == '*') {
+ ret = vkms_config_plane_add_all_formats(plane->config);
+ if (ret)
+ return ret;
+ } else {
+ ret = vkms_config_plane_add_format(plane->config,
+ *(int *)fmt);
+ if (ret)
+ return ret;
+ }
+ } else if (tmp[0] == '-') {
+ if (fmt[0] == '*')
+ vkms_config_plane_remove_all_formats(plane->config);
+ else
+ vkms_config_plane_remove_format(plane->config, *(int *)fmt);
+ }
+ }
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, name);
CONFIGFS_ATTR(plane_, supported_rotations);
@@ -626,6 +743,7 @@ CONFIGFS_ATTR(plane_, supported_color_ranges);
CONFIGFS_ATTR(plane_, default_color_range);
CONFIGFS_ATTR(plane_, supported_color_encodings);
CONFIGFS_ATTR(plane_, default_color_encoding);
+CONFIGFS_ATTR(plane_, supported_formats);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
@@ -636,6 +754,7 @@ static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_default_color_range,
&plane_attr_supported_color_encodings,
&plane_attr_default_color_encoding,
+ &plane_attr_supported_formats,
NULL,
};
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.h b/drivers/gpu/drm/vkms/vkms_configfs.h
index e9020b0043db..2774655bfcc5 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.h
+++ b/drivers/gpu/drm/vkms/vkms_configfs.h
@@ -2,7 +2,13 @@
#ifndef _VKMS_CONFIGFS_H_
#define _VKMS_CONFIGFS_H_
+#include <linux/types.h>
+
int vkms_configfs_register(void);
void vkms_configfs_unregister(void);
+#if IS_ENABLED(CONFIG_KUNIT)
+int vkms_configfs_parse_next_format(const char *page, const char *end_page, char **out);
+#endif
+
#endif /* _VKMS_CONFIGFS_H_ */
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (16 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property Louis Chauvet
` (13 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Currently planes are rendered in creation order. This is not an issue, but
with the introduction of new zpos configuration, it is required to
properly render planes.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_crtc.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index bac0790c6577..0524c47460fb 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -4,6 +4,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -141,14 +142,20 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
return -ENOMEM;
vkms_state->num_active_planes = i;
- i = 0;
+ ret = drm_atomic_normalize_zpos(crtc->dev, state);
+ if (ret)
+ return ret;
+
drm_for_each_plane_mask(plane, crtc->dev, crtc_state->plane_mask) {
plane_state = drm_atomic_get_new_plane_state(crtc_state->state, plane);
if (!plane_state->visible)
continue;
- vkms_state->active_planes[i++] =
+ // Order planes according to their normalized_zpos
+ // After drm_atomic_normalize_zpos, the possible values are 0..n_planes-1
+ // so store them using this index
+ vkms_state->active_planes[plane_state->normalized_zpos] =
to_vkms_plane_state(plane_state);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (17 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs " Louis Chauvet
` (12 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
VKMS can render plane in any order. Introduce the appropriate
configuration.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 92 ++++++++++++++++
drivers/gpu/drm/vkms/vkms_config.c | 47 ++++++++
drivers/gpu/drm/vkms/vkms_config.h | 147 ++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_plane.c | 11 ++
4 files changed, 297 insertions(+)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index d962fec8d3b3..518e68c17122 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -188,6 +188,9 @@ static void vkms_config_test_default_config(struct kunit *test)
KUNIT_EXPECT_EQ(test,
vkms_config_plane_get_default_color_encoding(plane_cfg),
DRM_COLOR_YCBCR_BT601);
+ KUNIT_EXPECT_EQ(test, vkms_config_plane_get_zpos_enabled(plane_cfg), false);
+ // No need to test the other zpos configurations as they are discarded if
+ // the zpos property is not created.
}
/* Encoders */
@@ -606,6 +609,94 @@ static void vkms_config_test_valid_plane_color_range(struct kunit *test)
vkms_config_destroy(config);
}
+static void vkms_config_test_valid_plane_zpos(struct kunit *test)
+{
+ struct vkms_config *config;
+ struct vkms_config_plane *plane_cfg;
+
+ config = vkms_config_default_create(false, false, false);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
+
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, all color range supported */
+ plane_cfg = get_first_plane(config);
+
+ /* Valid, zpos disabled */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, false);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, false);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 0);
+ vkms_config_plane_set_zpos_min(plane_cfg, 0);
+ vkms_config_plane_set_zpos_max(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, zpos disabled, min/max are ignored */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, false);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, false);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 8);
+ vkms_config_plane_set_zpos_min(plane_cfg, 3);
+ vkms_config_plane_set_zpos_max(plane_cfg, 2);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, zpos enabled but initial value is out of range */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, false);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 1);
+ vkms_config_plane_set_zpos_min(plane_cfg, 0);
+ vkms_config_plane_set_zpos_max(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Valid, zpos enabled with valid initial value */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, false);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 0);
+ vkms_config_plane_set_zpos_min(plane_cfg, 0);
+ vkms_config_plane_set_zpos_max(plane_cfg, 0);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, zpos enabled with min > max */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, true);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 0);
+ vkms_config_plane_set_zpos_min(plane_cfg, 1);
+ vkms_config_plane_set_zpos_max(plane_cfg, 0);
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, zpos enabled with min <= max */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, true);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 0);
+ vkms_config_plane_set_zpos_min(plane_cfg, 0);
+ vkms_config_plane_set_zpos_max(plane_cfg, 1);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ /* Invalid, zpos enabled with initial < min */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, true);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 0);
+ vkms_config_plane_set_zpos_min(plane_cfg, 1);
+ vkms_config_plane_set_zpos_max(plane_cfg, 2);
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Invalid, zpos enabled with initial > max */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, true);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 3);
+ vkms_config_plane_set_zpos_min(plane_cfg, 1);
+ vkms_config_plane_set_zpos_max(plane_cfg, 2);
+ KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config));
+
+ /* Valid, zpos enabled with initial between min and max */
+ vkms_config_plane_set_zpos_enabled(plane_cfg, true);
+ vkms_config_plane_set_zpos_mutable(plane_cfg, true);
+ vkms_config_plane_set_zpos_initial(plane_cfg, 1);
+ vkms_config_plane_set_zpos_min(plane_cfg, 0);
+ vkms_config_plane_set_zpos_max(plane_cfg, 2);
+ KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
+
+ vkms_config_destroy(config);
+}
+
static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test)
{
struct vkms_config *config;
@@ -1131,6 +1222,7 @@ static struct kunit_case vkms_config_test_cases[] = {
KUNIT_CASE(vkms_config_test_valid_plane_rotations),
KUNIT_CASE(vkms_config_test_valid_plane_color_encoding),
KUNIT_CASE(vkms_config_test_valid_plane_color_range),
+ KUNIT_CASE(vkms_config_test_valid_plane_zpos),
KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs),
KUNIT_CASE(vkms_config_test_invalid_crtc_number),
KUNIT_CASE(vkms_config_test_invalid_encoder_number),
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index a3fb80451b30..801019cf04c1 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -90,6 +90,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor,
if (IS_ERR(plane_cfg))
goto err_alloc;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY);
+ vkms_config_plane_set_zpos_enabled(plane_cfg, false);
crtc_cfg = vkms_config_create_crtc(config);
if (IS_ERR(crtc_cfg))
@@ -107,6 +108,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor,
vkms_config_plane_set_type(plane_cfg,
DRM_PLANE_TYPE_OVERLAY);
+ vkms_config_plane_set_zpos_enabled(plane_cfg, false);
if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg))
goto err_alloc;
@@ -119,6 +121,7 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor,
goto err_alloc;
vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR);
+ vkms_config_plane_set_zpos_enabled(plane_cfg, false);
if (vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg))
goto err_alloc;
@@ -249,6 +252,37 @@ bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
}
EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_range);
+VISIBLE_IF_KUNIT
+bool vkms_config_valid_plane_zpos(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg)
+{
+ struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
+
+ if (!vkms_config_plane_get_zpos_enabled(plane_cfg) ||
+ !vkms_config_plane_get_zpos_mutable(plane_cfg))
+ return true;
+
+ if (vkms_config_plane_get_zpos_initial(plane_cfg) >
+ vkms_config_plane_get_zpos_max(plane_cfg)) {
+ drm_info(dev, "Configured initial zpos value bigger than zpos max\n");
+ return false;
+ }
+
+ if (vkms_config_plane_get_zpos_max(plane_cfg) <
+ vkms_config_plane_get_zpos_min(plane_cfg)) {
+ drm_info(dev, "Configured zpos max value smaller than zpos min\n");
+ return false;
+ }
+
+ if (vkms_config_plane_get_zpos_initial(plane_cfg) <
+ vkms_config_plane_get_zpos_min(plane_cfg)) {
+ drm_info(dev, "Configured initial zpos value smaller than zpos min\n");
+ return false;
+ }
+
+ return true;
+}
+
static bool valid_planes_for_crtc(const struct vkms_config *config,
struct vkms_config_crtc *crtc_cfg)
{
@@ -425,6 +459,9 @@ bool vkms_config_is_valid(const struct vkms_config *config)
"Both supported color encoding and color range must be set, or none\n");
return false;
}
+
+ if (!vkms_config_valid_plane_zpos(config, plane_cfg))
+ return false;
}
if (!valid_plane_number(config))
@@ -526,6 +563,16 @@ static int vkms_config_show(struct seq_file *m, void *data)
show_formats(m, vkms_config_plane_get_supported_formats(plane_cfg),
vkms_config_plane_get_supported_formats_count(plane_cfg));
seq_puts(m, "\n");
+ seq_printf(m, "\tzpos_enabled=%s\n",
+ str_true_false(vkms_config_plane_get_zpos_enabled(plane_cfg)));
+ seq_printf(m, "\tzpos_mutable=%s\n",
+ str_true_false(vkms_config_plane_get_zpos_mutable(plane_cfg)));
+ seq_printf(m, "\tzpos_min=%d\n",
+ vkms_config_plane_get_zpos_min(plane_cfg));
+ seq_printf(m, "\tzpos_initial=%d\n",
+ vkms_config_plane_get_zpos_initial(plane_cfg));
+ seq_printf(m, "\tzpos_max=%d\n",
+ vkms_config_plane_get_zpos_max(plane_cfg));
}
vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 2d9e35b7caad..baed036a07cd 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -51,6 +51,11 @@ struct vkms_config {
* @supported_color_ranges: Color range that this plane will support
* @supported_formats: List of supported formats
* @supported_formats_count: Length of @supported_formats
+ * @zpos_enabled: Enable or disable the zpos property
+ * @zpos_mutable: Make the zpos property mutable or not (ignored if @zpos_enabled is false)
+ * @zpos_initial: Initial value for zpos property (ignored if @zpos_enabled is false)
+ * @zpos_min: Minimal value for zpos property (ignored if @zpos_enabled is false)
+ * @zpos_max: Maximal value for zpos property (ignored if @zpos_enabled is false)
*/
struct vkms_config_plane {
struct list_head link;
@@ -67,6 +72,11 @@ struct vkms_config_plane {
u32 *supported_formats;
unsigned int supported_formats_count;
struct xarray possible_crtcs;
+ bool zpos_enabled;
+ bool zpos_mutable;
+ unsigned int zpos_initial;
+ unsigned int zpos_min;
+ unsigned int zpos_max;
/* Internal usage */
struct vkms_plane *plane;
@@ -523,6 +533,143 @@ vkms_config_plane_get_name(const struct vkms_config_plane *plane_cfg)
return plane_cfg->name;
}
+/**
+ * vkms_config_plane_set_zpos_enabled() - Enable or disable zpos property for a plane
+ * @plane_cfg: Plane configuration to modify
+ * @zpos_enabled: Whether to enable the zpos property
+ */
+static inline
+void vkms_config_plane_set_zpos_enabled(struct vkms_config_plane *plane_cfg,
+ bool zpos_enabled)
+{
+ plane_cfg->zpos_enabled = zpos_enabled;
+}
+
+/**
+ * vkms_config_plane_set_zpos_mutable() - Set whether zpos property is mutable
+ * @plane_cfg: Plane configuration to modify
+ * @zpos_mutable: Whether the zpos property should be mutable
+ */
+static inline
+void vkms_config_plane_set_zpos_mutable(struct vkms_config_plane *plane_cfg,
+ bool zpos_mutable)
+{
+ plane_cfg->zpos_mutable = zpos_mutable;
+}
+
+/**
+ * vkms_config_plane_set_zpos_initial() - Set the initial zpos value
+ * @plane_cfg: Plane configuration to modify
+ * @zpos_initial: Initial zpos value
+ */
+static inline
+void vkms_config_plane_set_zpos_initial(struct vkms_config_plane *plane_cfg,
+ unsigned int zpos_initial)
+{
+ plane_cfg->zpos_initial = zpos_initial;
+}
+
+/**
+ * vkms_config_plane_set_zpos_min() - Set the minimum zpos value
+ * @plane_cfg: Plane configuration to modify
+ * @zpos_min: Minimum zpos value
+ */
+static inline
+void vkms_config_plane_set_zpos_min(struct vkms_config_plane *plane_cfg,
+ unsigned int zpos_min)
+{
+ plane_cfg->zpos_min = zpos_min;
+}
+
+/**
+ * vkms_config_plane_set_zpos_max() - Set the maximum zpos value
+ * @plane_cfg: Plane configuration to modify
+ * @zpos_max: Maximum zpos value
+ *
+ * Sets the maximum allowed value for the zpos property. This setting is
+ * ignored if zpos is disabled.
+ */
+static inline
+void vkms_config_plane_set_zpos_max(struct vkms_config_plane *plane_cfg,
+ unsigned int zpos_max)
+{
+ plane_cfg->zpos_max = zpos_max;
+}
+
+/**
+ * vkms_config_plane_get_zpos_enabled() - Check if zpos property is enabled
+ * @plane_cfg: Plane configuration to check
+ *
+ * Returns:
+ * True if the zpos property is enabled for this plane, false otherwise.
+ */
+static inline
+bool vkms_config_plane_get_zpos_enabled(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->zpos_enabled;
+}
+
+/**
+ * vkms_config_plane_get_zpos_mutable() - Check if zpos property is mutable
+ * @plane_cfg: Plane configuration to check
+ *
+ * Returns:
+ * True if the zpos property is mutable for this plane, false otherwise.
+ * Returns false if zpos is disabled.
+ */
+static inline
+bool vkms_config_plane_get_zpos_mutable(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->zpos_mutable;
+}
+
+/**
+ * vkms_config_plane_get_zpos_initial() - Get the initial zpos value
+ * @plane_cfg: Plane configuration to check
+ *
+ * Returns:
+ * The initial zpos value for this plane. The return value is undefined if
+ * zpos is disabled.
+ */
+static inline
+unsigned int vkms_config_plane_get_zpos_initial(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->zpos_initial;
+}
+
+/**
+ * vkms_config_plane_get_zpos_min() - Get the minimum zpos value
+ * @plane_cfg: Plane configuration to check
+ *
+ * Returns:
+ * The minimum allowed zpos value for this plane. The return value is undefined
+ * if zpos is disabled.
+ */
+static inline
+unsigned int vkms_config_plane_get_zpos_min(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->zpos_min;
+}
+
+/**
+ * vkms_config_plane_get_zpos_max() - Get the maximum zpos value
+ * @plane_cfg: Plane configuration to check
+ *
+ * Returns:
+ * The maximum allowed zpos value for this plane. The return value is undefined
+ * if zpos is disabled.
+ */
+static inline
+unsigned int vkms_config_plane_get_zpos_max(const struct vkms_config_plane *plane_cfg)
+{
+ return plane_cfg->zpos_max;
+}
+
+#if IS_ENABLED(CONFIG_KUNIT)
+bool vkms_config_valid_plane_zpos(const struct vkms_config *config,
+ const struct vkms_config_plane *plane_cfg);
+#endif
+
/**
* vkms_config_plane_attach_crtc - Attach a plane to a CRTC
* @plane_cfg: Plane to attach
diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
index 945abbbeac99..11a6b7bc74a7 100644
--- a/drivers/gpu/drm/vkms/vkms_plane.c
+++ b/drivers/gpu/drm/vkms/vkms_plane.c
@@ -211,5 +211,16 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
vkms_config_plane_get_default_color_encoding(config),
vkms_config_plane_get_default_color_range(config));
+ if (vkms_config_plane_get_zpos_enabled(config)) {
+ if (vkms_config_plane_get_zpos_mutable(config))
+ drm_plane_create_zpos_property(&plane->base,
+ vkms_config_plane_get_zpos_initial(config),
+ vkms_config_plane_get_zpos_min(config),
+ vkms_config_plane_get_zpos_max(config));
+ else
+ drm_plane_create_zpos_immutable_property(&plane->base,
+ vkms_config_plane_get_zpos_initial(config));
+ }
+
return plane;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs for plane zpos property
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (18 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type Louis Chauvet
` (11 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Modern compositor rely on zpos management to offload some processing to
deticated hardware. In order to test multiple configurations, add zpos
configuration to configFS.
Introduce multiple attributes to configure zpos:
- zpos_enabled - Create or not the zpos property. If not created, the zpos
is undefined.
- zpos_mutable - If the zpos property is created, allow or not the
userspace to modify it
- zpos_initial - Initial value for zpos property. Must be between zpos_min
and zpos_max
- zpos_min - Minimal zpos value for this plane. Must be smaller than or
equals to zpos_max
- zpos_max - Maximal zpos value for this plane. Must be greater than or
equals to zpos_min
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 9 +-
drivers/gpu/drm/vkms/vkms_configfs.c | 180 +++++++++++++++++++++++++++++++++++
2 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 779ae363110d..32858f9a3357 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -87,7 +87,7 @@ Start by creating one or more planes::
sudo mkdir /config/vkms/my-vkms/planes/plane0
-Planes have 9 configurable attributes:
+Planes have 14 configurable attributes:
- type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
exposed by the "type" property of a plane)
@@ -114,6 +114,13 @@ Planes have 9 configurable attributes:
To remove a format, use a minus and its fourcc: -XR24
To add all formats use +*
To remove all formats, use -*
+- zpos_enabled: Enable or not the zpos property: 1 enable, 0 disable
+- zpos_mutable: Create the zpos property as a mutable or imutable property: 1 mutable,
+ 0 disable. No effect if zpos_enabled is not set.
+- zpos_initial: Set the initial zpos value. Must be between zpos_min and zpos_max. No
+ effect if zpos_enabled is not set.
+- zpos_min: Set the minimal zpos value. No effect if zpos_enabled is not set.
+- zpos_max: Set the maximal zpos value. No effect if zpos_enabled is not set.
Continue by creating one or more CRTCs::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index b0a26c4dbebe..1c0a6ecf2f29 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -735,6 +735,176 @@ static ssize_t plane_supported_formats_store(struct config_item *item,
return count;
}
+static ssize_t plane_zpos_enabled_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ bool enabled;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ enabled = vkms_config_plane_get_zpos_enabled(plane->config);
+
+ return sprintf(page, "%d\n", enabled);
+}
+
+static ssize_t plane_zpos_enabled_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+ bool enabled;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ if (kstrtobool(page, &enabled))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_zpos_enabled(plane->config, enabled);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t plane_zpos_mutable_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ bool mutable;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ mutable = vkms_config_plane_get_zpos_mutable(plane->config);
+
+ return sprintf(page, "%d\n", mutable);
+}
+
+static ssize_t plane_zpos_mutable_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+ bool mutable;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ if (kstrtobool(page, &mutable))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_zpos_mutable(plane->config, mutable);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t plane_zpos_initial_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int initial;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ initial = vkms_config_plane_get_zpos_initial(plane->config);
+
+ return sprintf(page, "%u\n", initial);
+}
+
+static ssize_t plane_zpos_initial_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int initial;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ if (kstrtouint(page, 10, &initial))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_zpos_initial(plane->config, initial);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t plane_zpos_min_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int min;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ min = vkms_config_plane_get_zpos_min(plane->config);
+
+ return sprintf(page, "%u\n", min);
+}
+
+static ssize_t plane_zpos_min_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int min;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ if (kstrtouint(page, 10, &min))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_zpos_min(plane->config, min);
+ }
+
+ return (ssize_t)count;
+}
+
+static ssize_t plane_zpos_max_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int max;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ scoped_guard(mutex, &plane->dev->lock)
+ max = vkms_config_plane_get_zpos_max(plane->config);
+
+ return sprintf(page, "%u\n", max);
+}
+
+static ssize_t plane_zpos_max_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct vkms_configfs_plane *plane;
+ unsigned int max;
+
+ plane = plane_item_to_vkms_configfs_plane(item);
+
+ if (kstrtouint(page, 10, &max))
+ return -EINVAL;
+
+ scoped_guard(mutex, &plane->dev->lock) {
+ if (plane->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_plane_set_zpos_max(plane->config, max);
+ }
+
+ return (ssize_t)count;
+}
+
CONFIGFS_ATTR(plane_, type);
CONFIGFS_ATTR(plane_, name);
CONFIGFS_ATTR(plane_, supported_rotations);
@@ -744,6 +914,11 @@ CONFIGFS_ATTR(plane_, default_color_range);
CONFIGFS_ATTR(plane_, supported_color_encodings);
CONFIGFS_ATTR(plane_, default_color_encoding);
CONFIGFS_ATTR(plane_, supported_formats);
+CONFIGFS_ATTR(plane_, zpos_enabled);
+CONFIGFS_ATTR(plane_, zpos_mutable);
+CONFIGFS_ATTR(plane_, zpos_initial);
+CONFIGFS_ATTR(plane_, zpos_min);
+CONFIGFS_ATTR(plane_, zpos_max);
static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_type,
@@ -755,6 +930,11 @@ static struct configfs_attribute *plane_item_attrs[] = {
&plane_attr_supported_color_encodings,
&plane_attr_default_color_encoding,
&plane_attr_supported_formats,
+ &plane_attr_zpos_enabled,
+ &plane_attr_zpos_mutable,
+ &plane_attr_zpos_initial,
+ &plane_attr_zpos_min,
+ &plane_attr_zpos_max,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (19 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs " Louis Chauvet
` (10 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
In order to emulate connector-specific behavior, add connector type
configuration.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 5 +++++
drivers/gpu/drm/vkms/vkms_config.c | 3 +++
drivers/gpu/drm/vkms/vkms_config.h | 24 ++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_connector.c | 5 +++--
drivers/gpu/drm/vkms/vkms_connector.h | 3 ++-
drivers/gpu/drm/vkms/vkms_output.c | 2 +-
6 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index 518e68c17122..c8b885306eed 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -128,6 +128,7 @@ static void vkms_config_test_default_config(struct kunit *test)
struct vkms_config *config;
struct vkms_config_plane *plane_cfg;
struct vkms_config_crtc *crtc_cfg;
+ struct vkms_config_connector *connector_cfg;
int n_primaries = 0;
int n_cursors = 0;
int n_overlays = 0;
@@ -198,6 +199,10 @@ static void vkms_config_test_default_config(struct kunit *test)
/* Connectors */
KUNIT_EXPECT_EQ(test, vkms_config_get_num_connectors(config), 1);
+ vkms_config_for_each_connector(config, connector_cfg) {
+ KUNIT_EXPECT_EQ(test, vkms_config_connector_get_type(connector_cfg),
+ DRM_MODE_CONNECTOR_VIRTUAL);
+ }
KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 801019cf04c1..02e2f0249fb0 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -588,6 +588,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
seq_puts(m, "connector:\n");
seq_printf(m, "\tstatus=%s\n",
drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
+ seq_printf(m, "\ttype=%s\n",
+ drm_get_connector_type_name(vkms_config_connector_get_type(connector_cfg)));
}
return 0;
@@ -893,6 +895,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c
connector_cfg->config = config;
connector_cfg->status = connector_status_connected;
+ vkms_config_connector_set_type(connector_cfg, DRM_MODE_CONNECTOR_VIRTUAL);
xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC);
list_add_tail(&connector_cfg->link, &config->connectors);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index baed036a07cd..6a50ec7535af 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -128,6 +128,7 @@ struct vkms_config_encoder {
* struct vkms_config_connector
*
* @link: Link to the others connector in vkms_config
+ * @type: Store the type of connector using DRM_MODE_CONNECTOR_* values
* @config: The vkms_config this connector belongs to
* @status: Status (connected, disconnected...) of the connector
* @possible_encoders: Array of encoders that can be used with this connector
@@ -140,6 +141,7 @@ struct vkms_config_connector {
struct list_head link;
struct vkms_config *config;
+ int type;
enum drm_connector_status status;
struct xarray possible_encoders;
@@ -317,6 +319,28 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
}
/**
+ * vkms_config_connector_get_type() - Return the connector type
+ * @connector_cfg: Connector to get the type from
+ */
+static inline int
+vkms_config_connector_get_type(const struct vkms_config_connector *connector_cfg)
+{
+ return connector_cfg->type;
+}
+
+/**
+ * vkms_config_connector_set_type() - Set the connector type
+ * @connector_cfg: Connector to set the type to
+ * @type: New connector type
+ */
+static inline void
+vkms_config_connector_set_type(struct vkms_config_connector *connector_cfg,
+ int type)
+{
+ connector_cfg->type = type;
+}
+
+/*
* vkms_config_plane_get_default_rotation() - Get the default rotation for a plane
* @plane_cfg: Plane to get the default rotation from
*
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index b0a6b212d3f4..5a87dc2d4c63 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -68,7 +68,8 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
.best_encoder = vkms_conn_best_encoder,
};
-struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev)
+struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg)
{
struct drm_device *dev = &vkmsdev->drm;
struct vkms_connector *connector;
@@ -79,7 +80,7 @@ struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev)
return ERR_PTR(-ENOMEM);
ret = drmm_connector_init(dev, &connector->base, &vkms_connector_funcs,
- DRM_MODE_CONNECTOR_VIRTUAL, NULL);
+ vkms_config_connector_get_type(connector_cfg), NULL);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/vkms_connector.h
index ed312f4eff3a..a124c5403697 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.h
+++ b/drivers/gpu/drm/vkms/vkms_connector.h
@@ -24,7 +24,8 @@ struct vkms_connector {
* Returns:
* The connector or an error on failure.
*/
-struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev);
+struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg);
/**
* vkms_trigger_connector_hotplug() - Update the device's connectors status
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 22208d02afa4..217f054d9598 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -96,7 +96,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
struct vkms_config_encoder *possible_encoder;
unsigned long idx = 0;
- connector_cfg->connector = vkms_connector_init(vkmsdev);
+ connector_cfg->connector = vkms_connector_init(vkmsdev, connector_cfg);
if (IS_ERR(connector_cfg->connector)) {
DRM_ERROR("Failed to init connector\n");
return PTR_ERR(connector_cfg->connector);
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs for connector type
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (20 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type Louis Chauvet
@ 2025-10-29 14:36 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name Louis Chauvet
` (9 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:36 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Add a new attribute to connector to change its type. This is mostly
cosmetic and don't have direct effect in VKMS behavior.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 3 +-
drivers/gpu/drm/vkms/vkms_configfs.c | 64 ++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 32858f9a3357..99c5cf3dbd78 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -138,10 +138,11 @@ Last but not least, create one or more connectors::
sudo mkdir /config/vkms/my-vkms/connectors/connector0
-Connectors have 1 configurable attribute:
+Connectors have 2 configurable attribute:
- status: Connection status: 1 connected, 2 disconnected, 3 unknown (same values
as those exposed by the "status" property of a connector)
+- type: Type of connector. Same values as exposed by the "type" field in drm_connector.
To finish the configuration, link the different pipeline items::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 1c0a6ecf2f29..b03e9af569b6 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1161,10 +1161,74 @@ static ssize_t connector_status_store(struct config_item *item,
return (ssize_t)count;
}
+static ssize_t connector_type_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+ int type;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock) {
+ type = vkms_config_connector_get_type(connector->config);
+ }
+
+ return sprintf(page, "%u", type);
+}
+
+static ssize_t connector_type_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+ int val, ret;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ ret = kstrtouint(page, 10, &val);
+
+ if (ret)
+ return ret;
+
+ switch (val) {
+ case DRM_MODE_CONNECTOR_Unknown:
+ case DRM_MODE_CONNECTOR_VGA:
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DVIA:
+ case DRM_MODE_CONNECTOR_Composite:
+ case DRM_MODE_CONNECTOR_SVIDEO:
+ case DRM_MODE_CONNECTOR_LVDS:
+ case DRM_MODE_CONNECTOR_Component:
+ case DRM_MODE_CONNECTOR_9PinDIN:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ case DRM_MODE_CONNECTOR_TV:
+ case DRM_MODE_CONNECTOR_eDP:
+ case DRM_MODE_CONNECTOR_VIRTUAL:
+ case DRM_MODE_CONNECTOR_DSI:
+ case DRM_MODE_CONNECTOR_DPI:
+ case DRM_MODE_CONNECTOR_SPI:
+ case DRM_MODE_CONNECTOR_USB:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ scoped_guard(mutex, &connector->dev->lock) {
+ if (connector->dev->enabled)
+ return -EINVAL;
+ vkms_config_connector_set_type(connector->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(connector_, status);
+CONFIGFS_ATTR(connector_, type);
static struct configfs_attribute *connector_item_attrs[] = {
&connector_attr_status,
+ &connector_attr_type,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (21 preceding siblings ...)
2025-10-29 14:36 ` [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace Louis Chauvet
` (8 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Export drm_get_colorspace_name so it could be used by VKMS
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/drm_connector.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 272d6254ea47..5b777fb75b05 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1362,6 +1362,7 @@ const char *drm_get_colorspace_name(enum drm_colorspace colorspace)
else
return "(null)";
}
+EXPORT_SYMBOL(drm_get_colorspace_name);
static const u32 hdmi_colorspaces =
BIT(DRM_MODE_COLORIMETRY_SMPTE_170M_YCC) |
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (22 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs " Louis Chauvet
` (7 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
To emulate some HDR features of displays, it is required to expose some
properties on HDMI, eDP and DP connectors.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 3 +++
drivers/gpu/drm/vkms/vkms_config.c | 5 +++++
drivers/gpu/drm/vkms/vkms_config.h | 30 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_connector.c | 15 ++++++++++++++
4 files changed, 53 insertions(+)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index c8b885306eed..e0ceecf2e2dd 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -202,6 +202,9 @@ static void vkms_config_test_default_config(struct kunit *test)
vkms_config_for_each_connector(config, connector_cfg) {
KUNIT_EXPECT_EQ(test, vkms_config_connector_get_type(connector_cfg),
DRM_MODE_CONNECTOR_VIRTUAL);
+ KUNIT_EXPECT_EQ(test,
+ vkms_config_connector_get_supported_colorspaces(connector_cfg),
+ 0);
}
KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 02e2f0249fb0..6f939b82c33f 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -590,6 +590,10 @@ static int vkms_config_show(struct seq_file *m, void *data)
drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
seq_printf(m, "\ttype=%s\n",
drm_get_connector_type_name(vkms_config_connector_get_type(connector_cfg)));
+ seq_puts(m, "\tsupported colorspaces=");
+ show_bitfield(m, vkms_config_connector_get_supported_colorspaces(connector_cfg),
+ drm_get_colorspace_name);
+ seq_puts(m, "\n");
}
return 0;
@@ -896,6 +900,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c
connector_cfg->config = config;
connector_cfg->status = connector_status_connected;
vkms_config_connector_set_type(connector_cfg, DRM_MODE_CONNECTOR_VIRTUAL);
+ vkms_config_connector_set_supported_colorspaces(connector_cfg, 0);
xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC);
list_add_tail(&connector_cfg->link, &config->connectors);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 6a50ec7535af..d68133723444 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -131,6 +131,10 @@ struct vkms_config_encoder {
* @type: Store the type of connector using DRM_MODE_CONNECTOR_* values
* @config: The vkms_config this connector belongs to
* @status: Status (connected, disconnected...) of the connector
+ * @supported_colorspaces: Bitmask of all the supported colorspaces. Values
+ * are the sames as ones accepted by
+ * drm_mode_create_hdmi_colorspace_property() and
+ * drm_mode_create_dp_colorspace_property()
* @possible_encoders: Array of encoders that can be used with this connector
* @connector: Internal usage. This pointer should never be considered as valid.
* It can be used to store a temporary reference to a VKMS connector
@@ -143,6 +147,7 @@ struct vkms_config_connector {
int type;
enum drm_connector_status status;
+ u32 supported_colorspaces;
struct xarray possible_encoders;
/* Internal usage */
@@ -241,6 +246,31 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor,
*/
void vkms_config_destroy(struct vkms_config *config);
+/**
+ * vkms_config_connector_set_supported_colorspaces() - Set the supported colorspaces for a connector
+ * @connector_cfg: Connector configuration to modify
+ * @supported_colorspaces: Bitmask of supported colorspaces (DRM_COLOR_YCBCR_*)
+ */
+static inline void
+vkms_config_connector_set_supported_colorspaces(struct vkms_config_connector *connector_cfg,
+ u32 supported_colorspaces)
+{
+ connector_cfg->supported_colorspaces = supported_colorspaces;
+}
+
+/**
+ * vkms_config_connector_get_supported_colorspaces() - Get the supported colorspaces for a connector
+ * @connector_cfg: Connector configuration to query
+ *
+ * Returns:
+ * Bitmask of supported colorspaces (DRM_COLOR_YCBCR_*)
+ */
+static inline u32
+vkms_config_connector_get_supported_colorspaces(const struct vkms_config_connector *connector_cfg)
+{
+ return connector_cfg->supported_colorspaces;
+}
+
/**
* vkms_config_get_device_name() - Return the name of the device
* @config: Configuration to get the device name from
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index 5a87dc2d4c63..cc59d13c2d22 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -84,6 +84,21 @@ struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
if (ret)
return ERR_PTR(ret);
+ if (vkms_config_connector_get_supported_colorspaces(connector_cfg)) {
+ if (connector_cfg->type == DRM_MODE_CONNECTOR_HDMIA) {
+ drm_mode_create_hdmi_colorspace_property(&connector->base,
+ vkms_config_connector_get_supported_colorspaces(connector_cfg));
+ drm_connector_attach_hdr_output_metadata_property(&connector->base);
+ drm_connector_attach_colorspace_property(&connector->base);
+ } else if (connector_cfg->type == DRM_MODE_CONNECTOR_DisplayPort ||
+ connector_cfg->type == DRM_MODE_CONNECTOR_eDP) {
+ drm_mode_create_dp_colorspace_property(&connector->base,
+ vkms_config_connector_get_supported_colorspaces(connector_cfg));
+ drm_connector_attach_hdr_output_metadata_property(&connector->base);
+ drm_connector_attach_colorspace_property(&connector->base);
+ }
+ }
+
drm_connector_helper_add(&connector->base, &vkms_conn_helper_funcs);
return connector;
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs for connector supported colorspace
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (23 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID Louis Chauvet
` (6 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Add the attribute supported_colorspaces to configure the supported
colorspace of a connector. It will allows emulating some HDR features of
displays. This feature is only supported for HDMI, DP and eDP connectors.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 7 ++++++-
drivers/gpu/drm/vkms/vkms_configfs.c | 39 ++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 99c5cf3dbd78..c762cadac6f4 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -138,11 +138,16 @@ Last but not least, create one or more connectors::
sudo mkdir /config/vkms/my-vkms/connectors/connector0
-Connectors have 2 configurable attribute:
+Connectors have 3 configurable attribute:
- status: Connection status: 1 connected, 2 disconnected, 3 unknown (same values
as those exposed by the "status" property of a connector)
- type: Type of connector. Same values as exposed by the "type" field in drm_connector.
+- supported_colorspaces: Supported colorspaces values for HDMI, DP and eDP connectors.
+ If supported_colorspaces is not 0, the HDR_OUTPUT_METADATA will also be created.
+ Value is a bitfield, 0x1 = NO_DATA, 0x2 = SMPTE_170M_YCC... see enum drm_colorspace
+ for full list.
+
To finish the configuration, link the different pipeline items::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index b03e9af569b6..a7f4589403ce 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1223,12 +1223,51 @@ static ssize_t connector_type_store(struct config_item *item,
return count;
}
+static ssize_t connector_supported_colorspaces_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+ int type;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock)
+ type = vkms_config_connector_get_supported_colorspaces(connector->config);
+
+ return sprintf(page, "%u", type);
+}
+
+static ssize_t connector_supported_colorspaces_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+ int val, ret;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ ret = kstrtouint(page, 10, &val);
+ if (ret)
+ return ret;
+
+ if ((val & -BIT(DRM_MODE_COLORIMETRY_COUNT)) != 0)
+ return -EINVAL;
+
+ scoped_guard(mutex, &connector->dev->lock) {
+ if (connector->dev->enabled)
+ return -EBUSY;
+ vkms_config_connector_set_supported_colorspaces(connector->config, val);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(connector_, status);
CONFIGFS_ATTR(connector_, type);
+CONFIGFS_ATTR(connector_, supported_colorspaces);
static struct configfs_attribute *connector_item_attrs[] = {
&connector_attr_status,
&connector_attr_type,
+ &connector_attr_supported_colorspaces,
NULL,
};
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (24 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs " Louis Chauvet
` (5 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Allows configuration of EDID for each connector.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 2 +
drivers/gpu/drm/vkms/vkms_config.c | 6 +++
drivers/gpu/drm/vkms/vkms_config.h | 75 +++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_connector.c | 48 +++++++++++++++--
4 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index e0ceecf2e2dd..531c3b76b58d 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -205,6 +205,8 @@ static void vkms_config_test_default_config(struct kunit *test)
KUNIT_EXPECT_EQ(test,
vkms_config_connector_get_supported_colorspaces(connector_cfg),
0);
+ KUNIT_EXPECT_EQ(test, vkms_config_connector_get_edid_enabled(connector_cfg),
+ false);
}
KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 6f939b82c33f..02c0e944adf8 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -525,6 +525,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
const char *dev_name;
+ int edid_len;
struct vkms_config_plane *plane_cfg;
struct vkms_config_crtc *crtc_cfg;
struct vkms_config_encoder *encoder_cfg;
@@ -594,6 +595,11 @@ static int vkms_config_show(struct seq_file *m, void *data)
show_bitfield(m, vkms_config_connector_get_supported_colorspaces(connector_cfg),
drm_get_colorspace_name);
seq_puts(m, "\n");
+ vkms_config_connector_get_edid(connector_cfg, &edid_len);
+ seq_printf(m, "\tEDID=%s (len=%d)\n",
+ str_enabled_disabled(vkms_config_connector_get_edid_enabled(connector_cfg)),
+ edid_len
+ );
}
return 0;
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index d68133723444..42f5b5edaf1d 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -135,6 +135,9 @@ struct vkms_config_encoder {
* are the sames as ones accepted by
* drm_mode_create_hdmi_colorspace_property() and
* drm_mode_create_dp_colorspace_property()
+ * @edid_enabled: If true, create the EDID property
+ * @edid: Stores the current EDID. The value will be ignored if @edid_enabled is false
+ * @edid_len: Current EDID length. The value will be ignored if @edid_enabled is false
* @possible_encoders: Array of encoders that can be used with this connector
* @connector: Internal usage. This pointer should never be considered as valid.
* It can be used to store a temporary reference to a VKMS connector
@@ -148,6 +151,9 @@ struct vkms_config_connector {
int type;
enum drm_connector_status status;
u32 supported_colorspaces;
+ bool edid_enabled;
+ u8 *edid;
+ unsigned int edid_len;
struct xarray possible_encoders;
/* Internal usage */
@@ -271,6 +277,75 @@ vkms_config_connector_get_supported_colorspaces(const struct vkms_config_connect
return connector_cfg->supported_colorspaces;
}
+/**
+ * vkms_config_connector_get_edid_enabled() - Check if EDID is enabled for a connector
+ * @connector_cfg: Connector configuration to check
+ *
+ * Returns:
+ * True if EDID is enabled for this connector, false otherwise.
+ */
+static inline bool
+vkms_config_connector_get_edid_enabled(const struct vkms_config_connector *connector_cfg)
+{
+ return connector_cfg->edid_enabled;
+}
+
+/**
+ * vkms_config_connector_set_edid_enabled() - Enable or disable EDID for a connector
+ * @connector_cfg: Connector configuration to modify
+ * @enabled: Whether to enable EDID for this connector
+ */
+static inline void
+vkms_config_connector_set_edid_enabled(struct vkms_config_connector *connector_cfg,
+ bool enabled)
+{
+ connector_cfg->edid_enabled = enabled;
+}
+
+/**
+ * vkms_config_connector_get_edid() - Get the EDID data for a connector
+ * @connector_cfg: Connector configuration to get the EDID from
+ * @len: Pointer to store the length of the EDID data
+ *
+ * Returns:
+ * Pointer to the EDID data buffer, or NULL if no EDID is set.
+ * The length of the EDID data is stored in @len.
+ */
+static inline const u8 *
+vkms_config_connector_get_edid(const struct vkms_config_connector *connector_cfg, int *len)
+{
+ *len = connector_cfg->edid_len;
+ return connector_cfg->edid;
+}
+
+/**
+ * vkms_config_connector_set_edid() - Set the EDID data for a connector
+ * @connector_cfg: Connector configuration to modify
+ * @edid: Pointer to the EDID data buffer
+ * @len: Length of the EDID data
+ *
+ * If @len is 0, the EDID data will be cleared. If memory allocation fails,
+ * the existing EDID data will be preserved.
+ */
+static inline void
+vkms_config_connector_set_edid(struct vkms_config_connector *connector_cfg,
+ const u8 *edid, unsigned int len)
+{
+ if (len) {
+ void *edid_tmp = krealloc(connector_cfg->edid, len, GFP_KERNEL);
+
+ if (edid_tmp) {
+ connector_cfg->edid = edid_tmp;
+ memcpy(connector_cfg->edid, edid, len);
+ connector_cfg->edid_len = len;
+ }
+ } else {
+ kfree(connector_cfg->edid);
+ connector_cfg->edid = NULL;
+ connector_cfg->edid_len = len;
+ }
+}
+
/**
* vkms_config_get_device_name() - Return the name of the device
* @config: Configuration to get the device name from
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index cc59d13c2d22..339d747e729e 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -42,13 +42,53 @@ static const struct drm_connector_funcs vkms_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
+static int vkms_connector_read_block(void *context, u8 *buf, unsigned int block, size_t len)
+{
+ struct vkms_config_connector *config = context;
+ unsigned int edid_len;
+ const u8 *edid = vkms_config_connector_get_edid(config, &edid_len);
+
+ if (block * len + len > edid_len)
+ return 1;
+ memcpy(buf, &edid[block * len], len);
+ return 0;
+}
+
static int vkms_conn_get_modes(struct drm_connector *connector)
{
- int count;
+ struct vkms_connector *vkms_connector = drm_connector_to_vkms_connector(connector);
+ const struct drm_edid *drm_edid = NULL;
+ int count = 0;
+ struct vkms_config_connector *context = NULL;
+ struct drm_device *dev = connector->dev;
+ struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
+ struct vkms_config_connector *connector_cfg;
- /* Use the default modes list from DRM */
- count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
- drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
+ vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
+ if (connector_cfg->connector == vkms_connector)
+ context = connector_cfg;
+ }
+ if (context) {
+ if (vkms_config_connector_get_edid_enabled(context)) {
+ drm_edid = drm_edid_read_custom(connector,
+ vkms_connector_read_block, context);
+
+ /*
+ * Unconditionally update the connector. If the EDID was read
+ * successfully, fill in the connector information derived from the
+ * EDID. Otherwise, if the EDID is NULL, clear the connector
+ * information.
+ */
+ drm_edid_connector_update(connector, drm_edid);
+
+ count = drm_edid_connector_add_modes(connector);
+
+ drm_edid_free(drm_edid);
+ } else {
+ count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
+ drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
+ }
+ }
return count;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs for connector EDID
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (25 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector Louis Chauvet
` (4 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
Introduce new attributes to configure EDID of a connector:
- edid_enable - chose if the connector will have an EDD or not
- edid - raw edid content
Due to limitation of ConfigFS, the max len of EDID is PAGE_SIZE (4kB on
x86), it should be sufficient for many tests. One possible evolution is
using a ConfigFS blob to allow bigger EDID.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 5 ++-
drivers/gpu/drm/vkms/vkms_configfs.c | 80 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_connector.c | 3 ++
3 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index c762cadac6f4..0cc7897d7b83 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -138,7 +138,7 @@ Last but not least, create one or more connectors::
sudo mkdir /config/vkms/my-vkms/connectors/connector0
-Connectors have 3 configurable attribute:
+Connectors have 5 configurable attribute:
- status: Connection status: 1 connected, 2 disconnected, 3 unknown (same values
as those exposed by the "status" property of a connector)
@@ -147,6 +147,9 @@ Connectors have 3 configurable attribute:
If supported_colorspaces is not 0, the HDR_OUTPUT_METADATA will also be created.
Value is a bitfield, 0x1 = NO_DATA, 0x2 = SMPTE_170M_YCC... see enum drm_colorspace
for full list.
+- edid_enabled: Enable or not EDID for this connector. Some connectors may not have an
+ EDID but just a list of modes, this attribute allows to disable EDID property.
+- edid: Content of the EDID. Ignored if edid_enabled is not set
To finish the configuration, link the different pipeline items::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index a7f4589403ce..1843e5d9e1e1 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1260,14 +1260,94 @@ static ssize_t connector_supported_colorspaces_store(struct config_item *item,
return count;
}
+static ssize_t connector_edid_enabled_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+ bool enabled;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock)
+ enabled = vkms_config_connector_get_edid_enabled(connector->config);
+
+ return sprintf(page, "%d\n", enabled);
+}
+
+static ssize_t connector_edid_enabled_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+ struct vkms_config_connector *connector_cfg;
+ bool enabled;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+ connector_cfg = connector->config;
+
+ if (kstrtobool(page, &enabled))
+ return -EINVAL;
+
+ scoped_guard(mutex, &connector->dev->lock)
+ {
+ vkms_config_connector_set_edid_enabled(connector_cfg, enabled);
+
+ if (connector->dev->enabled &&
+ vkms_config_connector_get_status(connector_cfg) !=
+ connector_status_disconnected)
+ vkms_trigger_connector_hotplug(connector->dev->config->dev);
+ }
+ return count;
+}
+
+static ssize_t connector_edid_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock)
+ {
+ unsigned int len = 0;
+ const u8 *edid = vkms_config_connector_get_edid(connector->config, &len);
+
+ memcpy(page, edid, min(len, PAGE_SIZE));
+ return min(len, PAGE_SIZE);
+ }
+
+ return -EINVAL;
+}
+
+static ssize_t connector_edid_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock)
+ {
+ vkms_config_connector_set_edid(connector->config, page, count);
+
+ if (connector->dev->enabled &&
+ vkms_config_connector_get_status(connector->config) !=
+ connector_status_disconnected)
+ vkms_trigger_connector_hotplug(connector->dev->config->dev);
+ }
+
+ return count;
+}
+
CONFIGFS_ATTR(connector_, status);
CONFIGFS_ATTR(connector_, type);
CONFIGFS_ATTR(connector_, supported_colorspaces);
+CONFIGFS_ATTR(connector_, edid_enabled);
+CONFIGFS_ATTR(connector_, edid);
static struct configfs_attribute *connector_item_attrs[] = {
&connector_attr_status,
&connector_attr_type,
&connector_attr_supported_colorspaces,
+ &connector_attr_edid_enabled,
+ &connector_attr_edid,
NULL,
};
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index 339d747e729e..699b6779a46c 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -141,6 +141,9 @@ struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
drm_connector_helper_add(&connector->base, &vkms_conn_helper_funcs);
+ if (vkms_config_connector_get_edid_enabled(connector_cfg))
+ drm_connector_attach_edid_property(&connector->base);
+
return connector;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (26 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 18:57 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static Louis Chauvet
` (3 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
In order to prepare for dynamic connector configuration, we need to store
if a connector is dynamic and if it is enabled.
The two new vkms_config_connector fields will helps for that.
Co-developed-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/tests/vkms_config_test.c | 4 ++
drivers/gpu/drm/vkms/vkms_config.c | 6 +++
drivers/gpu/drm/vkms/vkms_config.h | 66 +++++++++++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/drivers/gpu/drm/vkms/tests/vkms_config_test.c b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
index 531c3b76b58d..b1d95385263f 100644
--- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
+++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
@@ -207,6 +207,10 @@ static void vkms_config_test_default_config(struct kunit *test)
0);
KUNIT_EXPECT_EQ(test, vkms_config_connector_get_edid_enabled(connector_cfg),
false);
+ KUNIT_EXPECT_EQ(test, vkms_config_connector_is_enabled(connector_cfg),
+ true);
+ KUNIT_EXPECT_EQ(test, vkms_config_connector_is_dynamic(connector_cfg),
+ false);
}
KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
index 02c0e944adf8..e86173ad61a6 100644
--- a/drivers/gpu/drm/vkms/vkms_config.c
+++ b/drivers/gpu/drm/vkms/vkms_config.c
@@ -587,6 +587,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
seq_puts(m, "connector:\n");
+ seq_printf(m, "\t%s\n",
+ str_enabled_disabled(vkms_config_connector_is_enabled(connector_cfg)));
seq_printf(m, "\tstatus=%s\n",
drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
seq_printf(m, "\ttype=%s\n",
@@ -600,6 +602,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
str_enabled_disabled(vkms_config_connector_get_edid_enabled(connector_cfg)),
edid_len
);
+ seq_printf(m, "\tdynamic=%s\n",
+ str_true_false(vkms_config_connector_is_dynamic(connector_cfg)));
}
return 0;
@@ -907,6 +911,8 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c
connector_cfg->status = connector_status_connected;
vkms_config_connector_set_type(connector_cfg, DRM_MODE_CONNECTOR_VIRTUAL);
vkms_config_connector_set_supported_colorspaces(connector_cfg, 0);
+ vkms_config_connector_set_dynamic(connector_cfg, false);
+ vkms_config_connector_set_enabled(connector_cfg, true);
xa_init_flags(&connector_cfg->possible_encoders, XA_FLAGS_ALLOC);
list_add_tail(&connector_cfg->link, &config->connectors);
diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
index 42f5b5edaf1d..a4aa7ad7be71 100644
--- a/drivers/gpu/drm/vkms/vkms_config.h
+++ b/drivers/gpu/drm/vkms/vkms_config.h
@@ -130,6 +130,8 @@ struct vkms_config_encoder {
* @link: Link to the others connector in vkms_config
* @type: Store the type of connector using DRM_MODE_CONNECTOR_* values
* @config: The vkms_config this connector belongs to
+ * @dynamic: Store if a connector should be created with drm_connector_dynamic_init
+ * @enabled: If @dynamic, this means that the correct is currently registered in drm
* @status: Status (connected, disconnected...) of the connector
* @supported_colorspaces: Bitmask of all the supported colorspaces. Values
* are the sames as ones accepted by
@@ -149,6 +151,8 @@ struct vkms_config_connector {
struct vkms_config *config;
int type;
+ bool enabled;
+ bool dynamic;
enum drm_connector_status status;
u32 supported_colorspaces;
bool edid_enabled;
@@ -192,6 +196,24 @@ struct vkms_config_connector {
#define vkms_config_for_each_connector(config, connector_cfg) \
list_for_each_entry((connector_cfg), &(config)->connectors, link)
+/**
+ * vkms_config_for_each_connector_static - Iterate over the static vkms_config connectors
+ * @config: &struct vkms_config pointer
+ * @connector_cfg: &struct vkms_config_connector pointer used as cursor
+ */
+#define vkms_config_for_each_connector_static(config, connector_cfg) \
+ vkms_config_for_each_connector((config), (connector_cfg)) \
+ if (!(connector_cfg)->dynamic)
+
+/**
+ * vkms_config_for_each_connector_dynamic - Iterate over the dynamic vkms_config connectors
+ * @config: &struct vkms_config pointer
+ * @connector_cfg: &struct vkms_config_connector pointer used as cursor
+ */
+#define vkms_config_for_each_connector_dynamic(config, connector_cfg) \
+ vkms_config_for_each_connector((config), (connector_cfg)) \
+ if ((connector_cfg)->dynamic)
+
/**
* vkms_config_plane_for_each_possible_crtc - Iterate over the vkms_config_plane
* possible CRTCs
@@ -445,6 +467,50 @@ vkms_config_connector_set_type(struct vkms_config_connector *connector_cfg,
connector_cfg->type = type;
}
+/**
+ * vkms_config_connector_set_enabled() - If the connector is part of the device
+ * @crtc_cfg: Target connector
+ * @enabled: Add or remove the connector
+ */
+static inline void
+vkms_config_connector_set_enabled(struct vkms_config_connector *connector_cfg,
+ bool enabled)
+{
+ connector_cfg->enabled = enabled;
+}
+
+/**
+ * vkms_config_connector_is_enabled() - If the connector is part of the device
+ * @connector_cfg: The connector
+ */
+static inline bool
+vkms_config_connector_is_enabled(const struct vkms_config_connector *connector_cfg)
+{
+ return connector_cfg->enabled;
+}
+
+/**
+ * vkms_config_connector_set_dynamic() - If the connector is dynamic
+ * @crtc_cfg: Target connector
+ * @enabled: Enable or disable the dynamic status
+ */
+static inline void
+vkms_config_connector_set_dynamic(struct vkms_config_connector *connector_cfg,
+ bool dynamic)
+{
+ connector_cfg->dynamic = dynamic;
+}
+
+/**
+ * vkms_config_connector_is_enabled() - If the connector is dynamic
+ * @connector_cfg: The connector
+ */
+static inline bool
+vkms_config_connector_is_dynamic(struct vkms_config_connector *connector_cfg)
+{
+ return connector_cfg->dynamic;
+}
+
/*
* vkms_config_plane_get_default_rotation() - Get the default rotation for a plane
* @plane_cfg: Plane to get the default rotation from
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (27 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 18:58 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization Louis Chauvet
` (2 subsequent siblings)
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
With the introduction of dynamic connectors we will have two way of
initializing a VKMS connector. Rename the current function to clarify
the case.
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_connector.c | 4 ++--
drivers/gpu/drm/vkms/vkms_connector.h | 7 ++++---
drivers/gpu/drm/vkms/vkms_output.c | 4 ++--
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index 699b6779a46c..1b7ccca2abc0 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -108,8 +108,8 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
.best_encoder = vkms_conn_best_encoder,
};
-struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
- struct vkms_config_connector *connector_cfg)
+struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg)
{
struct drm_device *dev = &vkmsdev->drm;
struct vkms_connector *connector;
diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/vkms_connector.h
index a124c5403697..85f9082c710e 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.h
+++ b/drivers/gpu/drm/vkms/vkms_connector.h
@@ -4,6 +4,7 @@
#define _VKMS_CONNECTOR_H_
#include "vkms_drv.h"
+#include "vkms_config.h"
#define drm_connector_to_vkms_connector(target) \
container_of(target, struct vkms_connector, base)
@@ -18,14 +19,14 @@ struct vkms_connector {
};
/**
- * vkms_connector_init() - Initialize a connector
+ * vkms_connector_init_static() - Initialize a connector
* @vkmsdev: VKMS device containing the connector
*
* Returns:
* The connector or an error on failure.
*/
-struct vkms_connector *vkms_connector_init(struct vkms_device *vkmsdev,
- struct vkms_config_connector *connector_cfg);
+struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg);
/**
* vkms_trigger_connector_hotplug() - Update the device's connectors status
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 217f054d9598..44f8f53c9194 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -92,11 +92,11 @@ int vkms_output_init(struct vkms_device *vkmsdev)
}
}
- vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
+ vkms_config_for_each_connector_static(vkmsdev->config, connector_cfg) {
struct vkms_config_encoder *possible_encoder;
unsigned long idx = 0;
- connector_cfg->connector = vkms_connector_init(vkmsdev, connector_cfg);
+ connector_cfg->connector = vkms_connector_init_static(vkmsdev, connector_cfg);
if (IS_ERR(connector_cfg->connector)) {
DRM_ERROR("Failed to init connector\n");
return PTR_ERR(connector_cfg->connector);
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (28 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors Louis Chauvet
2025-10-29 14:37 ` [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation Louis Chauvet
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
With the introduction of dynamic connector, some code will be shared
between dynamic and static connectors. Extract this part to avoid code
duplication
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_connector.c | 44 +++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index 1b7ccca2abc0..2c5f04af8784 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -108,22 +108,17 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = {
.best_encoder = vkms_conn_best_encoder,
};
-struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
- struct vkms_config_connector *connector_cfg)
+/**
+ * vkms_connector_init() - Common initialization of vkms connector
+ * @vkmsdev: VKMS device containing the device
+ * @connector: VKMS connector to init. @connector->base must be
+ * already initialized by DRM core.
+ * @connector_cfg: Connector configuration to apply
+ */
+static void vkms_connector_init(struct vkms_device *vkmsdev,
+ struct vkms_connector *connector,
+ const struct vkms_config_connector *connector_cfg)
{
- struct drm_device *dev = &vkmsdev->drm;
- struct vkms_connector *connector;
- int ret;
-
- connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
- if (!connector)
- return ERR_PTR(-ENOMEM);
-
- ret = drmm_connector_init(dev, &connector->base, &vkms_connector_funcs,
- vkms_config_connector_get_type(connector_cfg), NULL);
- if (ret)
- return ERR_PTR(ret);
-
if (vkms_config_connector_get_supported_colorspaces(connector_cfg)) {
if (connector_cfg->type == DRM_MODE_CONNECTOR_HDMIA) {
drm_mode_create_hdmi_colorspace_property(&connector->base,
@@ -143,6 +138,25 @@ struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
if (vkms_config_connector_get_edid_enabled(connector_cfg))
drm_connector_attach_edid_property(&connector->base);
+}
+
+struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg)
+{
+ struct drm_device *dev = &vkmsdev->drm;
+ struct vkms_connector *connector;
+ int ret;
+
+ connector = drmm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
+ if (!connector)
+ return ERR_PTR(-ENOMEM);
+
+ ret = drmm_connector_init(dev, &connector->base, &vkms_connector_funcs,
+ vkms_config_connector_get_type(connector_cfg), NULL);
+ if (ret)
+ return ERR_PTR(ret);
+
+ vkms_connector_init(vkmsdev, connector, connector_cfg);
return connector;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (29 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation Louis Chauvet
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
In order to allow creating dynamic connector, add the required
infrastructure in vkms_connector.
Co-developed-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
[Louis Chauvet: use drm_atomic_helper_connector_reset instead of
drm_mode_config_reset because connector is not yet registered]
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
drivers/gpu/drm/vkms/vkms_connector.c | 81 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_connector.h | 32 ++++++++++++++
drivers/gpu/drm/vkms/vkms_output.c | 9 ++++
3 files changed, 122 insertions(+)
diff --git a/drivers/gpu/drm/vkms/vkms_connector.c b/drivers/gpu/drm/vkms/vkms_connector.c
index 2c5f04af8784..bd0e368d5598 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.c
+++ b/drivers/gpu/drm/vkms/vkms_connector.c
@@ -161,9 +161,90 @@ struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
return connector;
}
+static void vkms_connector_dynamic_destroy(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct vkms_connector *vkms_connector;
+
+ drm_connector_cleanup(connector);
+
+ vkms_connector = drm_connector_to_vkms_connector(connector);
+ drmm_kfree(dev, vkms_connector);
+}
+
+static const struct drm_connector_funcs vkms_dynamic_connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .destroy = vkms_connector_dynamic_destroy,
+ .detect = vkms_connector_detect,
+};
+
void vkms_trigger_connector_hotplug(struct vkms_device *vkmsdev)
{
struct drm_device *dev = &vkmsdev->drm;
drm_kms_helper_hotplug_event(dev);
}
+
+struct vkms_connector *vkms_connector_hot_add(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg)
+{
+ struct vkms_config_encoder *encoder_cfg;
+ struct vkms_connector *connector;
+ int ret;
+ unsigned long idx = 0;
+
+ connector = drmm_kzalloc(&vkmsdev->drm, sizeof(*connector), GFP_KERNEL);
+ if (IS_ERR(connector))
+ return connector;
+ ret = drm_connector_dynamic_init(&vkmsdev->drm,
+ &connector->base,
+ &vkms_dynamic_connector_funcs,
+ connector_cfg->type,
+ NULL);
+ if (ret)
+ return ERR_PTR(ret);
+ drm_connector_helper_add(&connector->base, &vkms_conn_helper_funcs);
+
+ vkms_config_connector_for_each_possible_encoder(connector_cfg, idx, encoder_cfg) {
+ ret = drm_connector_attach_encoder(&connector->base,
+ encoder_cfg->encoder);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
+ drm_atomic_helper_connector_reset(&connector->base);
+
+ vkms_connector_init(vkmsdev, connector, connector_cfg);
+
+ ret = drm_connector_dynamic_register(&connector->base);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return connector;
+}
+
+void vkms_connector_hot_remove(struct vkms_device *vkmsdev,
+ struct vkms_connector *connector)
+{
+ drm_connector_unregister(&connector->base);
+ drm_mode_config_reset(&vkmsdev->drm);
+ drm_connector_put(&connector->base);
+}
+
+int vkms_connector_hot_attach_encoder(struct vkms_device *vkmsdev,
+ struct vkms_connector *connector,
+ struct drm_encoder *encoder)
+{
+ int ret;
+
+ ret = drm_connector_attach_encoder(&connector->base, encoder);
+ if (ret)
+ return ret;
+
+ drm_mode_config_reset(&vkmsdev->drm);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/vkms/vkms_connector.h b/drivers/gpu/drm/vkms/vkms_connector.h
index 85f9082c710e..f53e3f85c684 100644
--- a/drivers/gpu/drm/vkms/vkms_connector.h
+++ b/drivers/gpu/drm/vkms/vkms_connector.h
@@ -34,4 +34,36 @@ struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
*/
void vkms_trigger_connector_hotplug(struct vkms_device *vkmsdev);
+/**
+ * vkms_connector_hot_add() - Create a connector after the device is created
+ * @vkmsdev: Device to hot-add the connector to
+ * @connector_cfg: Connector's configuration
+ *
+ * Returns:
+ * The connector or an error on failure.
+ */
+struct vkms_connector *vkms_connector_hot_add(struct vkms_device *vkmsdev,
+ struct vkms_config_connector *connector_cfg);
+
+/**
+ * vkms_connector_hot_remove() - Remove a connector after a device is created
+ * @connector: The connector to hot-remove
+ */
+void vkms_connector_hot_remove(struct vkms_device *vkmsdev,
+ struct vkms_connector *connector);
+
+/**
+ * vkms_connector_hot_attach_encoder() - Attach a connector to a encoder after
+ * the device is created.
+ * @vkmsdev: Device containing the connector and the encoder
+ * @connector: Connector to attach to @encoder
+ * @encoder: Target encoder
+ *
+ * Returns:
+ * 0 on success or an error on failure.
+ */
+int vkms_connector_hot_attach_encoder(struct vkms_device *vkmsdev,
+ struct vkms_connector *connector,
+ struct drm_encoder *encoder);
+
#endif /* _VKMS_CONNECTOR_H_ */
diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
index 44f8f53c9194..56c9c0b56151 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -116,5 +116,14 @@ int vkms_output_init(struct vkms_device *vkmsdev)
drm_mode_config_reset(dev);
+ vkms_config_for_each_connector_dynamic(vkmsdev->config, connector_cfg) {
+ if (connector_cfg->enabled) {
+ connector_cfg->connector = vkms_connector_hot_add(vkmsdev, connector_cfg);
+
+ if (IS_ERR(connector_cfg->connector))
+ return PTR_ERR(connector_cfg->connector);
+ }
+ }
+
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
` (30 preceding siblings ...)
2025-10-29 14:37 ` [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors Louis Chauvet
@ 2025-10-29 14:37 ` Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
31 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-10-29 14:37 UTC (permalink / raw)
To: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, jose.exposito89,
Jonathan Corbet
Cc: victoria, sebastian.wick, victoria, airlied, thomas.petazzoni,
dri-devel, linux-kernel, linux-doc, Louis Chauvet
DRM allows the connector to be created after the device. To allows
emulating this, add two configfs attributes to connector to allows this.
Using the dynamic attribute you can set if a connector will be dynamic or
not.
Using the enabled attribute, you can set at runtime if a dynamic connector
is present or not.
Co-developed-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
---
Documentation/gpu/vkms.rst | 6 +-
drivers/gpu/drm/vkms/vkms_configfs.c | 153 ++++++++++++++++++++++++++++++++---
2 files changed, 146 insertions(+), 13 deletions(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index 0cc7897d7b83..afed12132ae7 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -138,7 +138,7 @@ Last but not least, create one or more connectors::
sudo mkdir /config/vkms/my-vkms/connectors/connector0
-Connectors have 5 configurable attribute:
+Connectors have 7 configurable attribute:
- status: Connection status: 1 connected, 2 disconnected, 3 unknown (same values
as those exposed by the "status" property of a connector)
@@ -150,7 +150,9 @@ Connectors have 5 configurable attribute:
- edid_enabled: Enable or not EDID for this connector. Some connectors may not have an
EDID but just a list of modes, this attribute allows to disable EDID property.
- edid: Content of the EDID. Ignored if edid_enabled is not set
-
+- dynamic: Set to 1 while configuring the device to create a dynamic connector. A dynamic
+ connector can be used to emulate DP MST connectors.
+- enabled: For dynamic connector, set it to 1 to create the connector, 0 to remove it.
To finish the configuration, link the different pipeline items::
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 1843e5d9e1e1..b4315c6cb25c 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1135,6 +1135,12 @@ static ssize_t connector_status_show(struct config_item *item, char *page)
return sprintf(page, "%u", status);
}
+static bool connector_is_enabled(struct vkms_config_connector *connector_cfg)
+{
+ return !connector_cfg->dynamic ||
+ (connector_cfg->dynamic && connector_cfg->enabled);
+}
+
static ssize_t connector_status_store(struct config_item *item,
const char *page, size_t count)
{
@@ -1154,8 +1160,10 @@ static ssize_t connector_status_store(struct config_item *item,
scoped_guard(mutex, &connector->dev->lock) {
vkms_config_connector_set_status(connector->config, status);
- if (connector->dev->enabled)
- vkms_trigger_connector_hotplug(connector->dev->config->dev);
+ if (connector->dev->enabled) {
+ if (connector_is_enabled(connector->config))
+ vkms_trigger_connector_hotplug(connector->dev->config->dev);
+ }
}
return (ssize_t)count;
@@ -1215,8 +1223,10 @@ static ssize_t connector_type_store(struct config_item *item,
}
scoped_guard(mutex, &connector->dev->lock) {
- if (connector->dev->enabled)
- return -EINVAL;
+ if (connector->dev->enabled) {
+ if (connector_is_enabled(connector->config))
+ return -EBUSY;
+ }
vkms_config_connector_set_type(connector->config, val);
}
@@ -1332,6 +1342,107 @@ static ssize_t connector_edid_store(struct config_item *item,
connector_status_disconnected)
vkms_trigger_connector_hotplug(connector->dev->config->dev);
}
+ return count;
+}
+
+static ssize_t connector_enabled_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+ bool enabled;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock)
+ enabled = vkms_config_connector_is_enabled(connector->config);
+
+ return sprintf(page, "%d\n", enabled);
+}
+
+static ssize_t connector_enabled_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+ struct vkms_config_connector *connector_cfg;
+ bool enabled, was_enabled;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+ connector_cfg = connector->config;
+
+ if (kstrtobool(page, &enabled))
+ return -EINVAL;
+ scoped_guard(mutex, &connector->dev->lock) {
+ if (!connector->dev->enabled) {
+ vkms_config_connector_set_enabled(connector_cfg, enabled);
+ } else {
+ // Only dynamic connector can be enabled/disabled at runtime
+ if (!connector_cfg->dynamic)
+ return -EBUSY;
+
+ was_enabled = vkms_config_connector_is_enabled(connector_cfg);
+ vkms_config_connector_set_enabled(connector_cfg, enabled);
+
+ // Resulting configuration is invalid (missing encoder for example)
+ // Early return to avoid drm core issue
+ if (!vkms_config_is_valid(connector->dev->config)) {
+ count = -EINVAL;
+ goto rollback;
+ }
+
+ if (!was_enabled && enabled) {
+ // Adding the connector
+ connector_cfg->connector = vkms_connector_hot_add(connector->dev->config->dev,
+ connector_cfg);
+ if (IS_ERR(connector_cfg->connector)) {
+ count = PTR_ERR(connector_cfg->connector);
+ goto rollback;
+ }
+ } else if (was_enabled && !enabled) {
+ vkms_connector_hot_remove(connector->dev->config->dev,
+ connector_cfg->connector);
+ }
+ }
+ }
+ return count;
+
+rollback:
+ vkms_config_connector_set_enabled(connector_cfg, was_enabled);
+ return count;
+}
+
+static ssize_t connector_dynamic_show(struct config_item *item, char *page)
+{
+ struct vkms_configfs_connector *connector;
+ bool enabled;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+
+ scoped_guard(mutex, &connector->dev->lock) {
+ enabled = vkms_config_connector_is_dynamic(connector->config);
+ }
+
+ return sprintf(page, "%d\n", enabled);
+}
+
+static ssize_t connector_dynamic_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct vkms_configfs_connector *connector;
+ struct vkms_config_connector *connector_cfg;
+ bool dynamic;
+
+ connector = connector_item_to_vkms_configfs_connector(item);
+ connector_cfg = connector->config;
+
+ if (kstrtobool(page, &dynamic))
+ return -EINVAL;
+
+ scoped_guard(mutex, &connector->dev->lock) {
+ // Can't change the dynamic status when the device is activated
+ if (connector->dev->enabled)
+ return -EBUSY;
+
+ vkms_config_connector_set_dynamic(connector_cfg, dynamic);
+ }
return count;
}
@@ -1341,6 +1452,8 @@ CONFIGFS_ATTR(connector_, type);
CONFIGFS_ATTR(connector_, supported_colorspaces);
CONFIGFS_ATTR(connector_, edid_enabled);
CONFIGFS_ATTR(connector_, edid);
+CONFIGFS_ATTR(connector_, dynamic);
+CONFIGFS_ATTR(connector_, enabled);
static struct configfs_attribute *connector_item_attrs[] = {
&connector_attr_status,
@@ -1348,19 +1461,28 @@ static struct configfs_attribute *connector_item_attrs[] = {
&connector_attr_supported_colorspaces,
&connector_attr_edid_enabled,
&connector_attr_edid,
+ &connector_attr_dynamic,
+ &connector_attr_enabled,
NULL,
};
static void connector_release(struct config_item *item)
{
struct vkms_configfs_connector *connector;
+ struct vkms_config_connector *connector_cfg;
struct mutex *lock;
connector = connector_item_to_vkms_configfs_connector(item);
+ connector_cfg = connector->config;
lock = &connector->dev->lock;
scoped_guard(mutex, lock) {
+ if (connector->dev->enabled && connector_cfg->dynamic && connector_cfg->enabled)
+ vkms_connector_hot_remove(connector->dev->config->dev,
+ connector_cfg->connector);
+
vkms_config_destroy_connector(connector->config);
+
kfree(connector);
}
}
@@ -1379,6 +1501,7 @@ static int connector_possible_encoders_allow_link(struct config_item *src,
struct config_item *target)
{
struct vkms_configfs_connector *connector;
+ struct vkms_config_connector *connector_cfg;
struct vkms_configfs_encoder *encoder;
int ret;
@@ -1386,16 +1509,25 @@ static int connector_possible_encoders_allow_link(struct config_item *src,
return -EINVAL;
connector = connector_possible_encoders_item_to_vkms_configfs_connector(src);
+ connector_cfg = connector->config;
encoder = encoder_item_to_vkms_configfs_encoder(target);
scoped_guard(mutex, &connector->dev->lock) {
- if (connector->dev->enabled)
- return -EBUSY;
+ if (connector->dev->enabled && connector_cfg->enabled) {
+ if (!connector_cfg->dynamic)
+ return -EBUSY;
+ ret = vkms_connector_hot_attach_encoder(connector->dev->config->dev,
+ connector->config->connector,
+ encoder->config->encoder);
+ if (ret)
+ return ret;
+ }
ret = vkms_config_connector_attach_encoder(connector->config,
encoder->config);
+ if (ret)
+ return ret;
}
-
return ret;
}
@@ -1433,9 +1565,6 @@ static struct config_group *make_connector_group(struct config_group *group,
dev = child_group_to_vkms_configfs_device(group);
scoped_guard(mutex, &dev->lock) {
- if (dev->enabled)
- return ERR_PTR(-EBUSY);
-
connector = kzalloc(sizeof(*connector), GFP_KERNEL);
if (!connector)
return ERR_PTR(-ENOMEM);
@@ -1448,9 +1577,11 @@ static struct config_group *make_connector_group(struct config_group *group,
return ERR_CAST(connector->config);
}
+ vkms_config_connector_set_dynamic(connector->config, connector->dev->enabled);
+ vkms_config_connector_set_enabled(connector->config, !connector->dev->enabled);
+
config_group_init_type_name(&connector->group, name,
&connector_item_type);
-
config_group_init_type_name(&connector->possible_encoders_group,
"possible_encoders",
&connector_possible_encoders_group_type);
--
2.51.0
^ permalink raw reply related [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
@ 2025-11-13 14:06 ` José Expósito
2025-11-17 11:28 ` Louis Chauvet
2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 1 reply; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:06 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
Hey Louis,
On Wed, Oct 29, 2025 at 03:36:38PM +0100, Louis Chauvet wrote:
> Create and export an helper to display plane type using the
> property string. This could be used to display debug
> information in VKMS.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/drm_mode_config.c | 13 +++++++++++++
> include/drm/drm_mode_config.h | 3 +++
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 25f376869b3a..1a1a3f43db4d 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -226,6 +226,19 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
> { DRM_PLANE_TYPE_CURSOR, "Cursor" },
> };
>
> +/**
> + * drm_get_plane_type_name - return a string for plane name
> + * @type: plane type to compute name of
Maybe we could document here what happens when the plane type is
not valid.
Returns: The name of the plane type. "(unknown)" if type is not a
known plane type.
Other than that:
Reviewed-by: José Expósito <jose.exposito@redhat.com>
> + */
> +const char *drm_get_plane_type_name(enum drm_plane_type type)
> +{
> + if (type < ARRAY_SIZE(drm_plane_type_enum_list))
> + return drm_plane_type_enum_list[type].name;
> + else
> + return "(unknown)";
> +}
> +EXPORT_SYMBOL(drm_get_plane_type_name);
> +
> static int drm_mode_create_standard_properties(struct drm_device *dev)
> {
> struct drm_property *prop;
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 2e848b816218..89f3dd46178d 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -30,6 +30,7 @@
> #include <linux/llist.h>
>
> #include <drm/drm_modeset_lock.h>
> +#include <drm/drm_plane.h>
>
> struct drm_file;
> struct drm_device;
> @@ -983,4 +984,6 @@ static inline int drm_mode_config_init(struct drm_device *dev)
> void drm_mode_config_reset(struct drm_device *dev);
> void drm_mode_config_cleanup(struct drm_device *dev);
>
> +const char *drm_get_plane_type_name(enum drm_plane_type type);
> +
> #endif
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type
2025-10-29 14:36 ` [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type Louis Chauvet
@ 2025-11-13 14:07 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:07 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:39PM +0100, Louis Chauvet wrote:
> Debug information are mainly read by human, so use full name instead
> of values.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index f8394a063ecf..cfdd5f32f234 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -348,8 +348,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
>
> vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
> seq_puts(m, "plane:\n");
> - seq_printf(m, "\ttype=%d\n",
> - vkms_config_plane_get_type(plane_cfg));
> + seq_printf(m, "\ttype=%s\n",
> + drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
> }
>
> vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug
2025-10-29 14:36 ` [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug Louis Chauvet
@ 2025-11-13 14:09 ` José Expósito
2025-12-18 17:57 ` Luca Ceresoli
0 siblings, 1 reply; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:09 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:40PM +0100, Louis Chauvet wrote:
> Debug information are mainly read by human, so display human
> readable values.
Today I learned. I wasn't aware of those helpers, nice!
Reviewed-by: José Expósito <jose.exposito@redhat.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index cfdd5f32f234..391794d391c5 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0+
>
> #include <linux/slab.h>
> +#include <linux/string_choices.h>
>
> #include <drm/drm_print.h>
> #include <drm/drm_debugfs.h>
> @@ -354,8 +355,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
>
> vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
> seq_puts(m, "crtc:\n");
> - seq_printf(m, "\twriteback=%d\n",
> - vkms_config_crtc_get_writeback(crtc_cfg));
> + seq_printf(m, "\twriteback=%s\n",
> + str_enabled_disabled(vkms_config_crtc_get_writeback(crtc_cfg)));
> }
>
> vkms_config_for_each_encoder(vkmsdev->config, encoder_cfg)
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status
2025-10-29 14:36 ` [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status Louis Chauvet
@ 2025-11-13 14:11 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:11 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:41PM +0100, Louis Chauvet wrote:
> Debug information are mainly read by human, so use full name instead
> of raw values for connector status.
These simple patches improving vkms_config_show() could be merged
independently if it makes easier your work.
Thanks for these changes!
Reviewed-by: José Expósito <jose.exposito@redhat.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index 391794d391c5..858bec2d1312 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -3,6 +3,7 @@
> #include <linux/slab.h>
> #include <linux/string_choices.h>
>
> +#include <drm/drm_connector.h>
> #include <drm/drm_print.h>
> #include <drm/drm_debugfs.h>
> #include <kunit/visibility.h>
> @@ -364,8 +365,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
>
> vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
> seq_puts(m, "connector:\n");
> - seq_printf(m, "\tstatus=%d\n",
> - vkms_config_connector_get_status(connector_cfg));
> + seq_printf(m, "\tstatus=%s\n",
> + drm_get_connector_status_name(vkms_config_connector_get_status(connector_cfg)));
> }
>
> return 0;
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name
2025-10-29 14:36 ` [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name Louis Chauvet
@ 2025-11-13 14:17 ` José Expósito
2025-11-17 14:12 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:17 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:42PM +0100, Louis Chauvet wrote:
> As planes can have a name in DRM, prepare VKMS to configure it using
> ConfigFS.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/vkms/vkms_config.c | 4 ++++
> drivers/gpu/drm/vkms/vkms_config.h | 26 ++++++++++++++++++++++++++
> drivers/gpu/drm/vkms/vkms_drv.h | 5 +++--
> drivers/gpu/drm/vkms/vkms_output.c | 6 +-----
> drivers/gpu/drm/vkms/vkms_plane.c | 6 ++++--
> 5 files changed, 38 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
> index 858bec2d1312..bfafb5d2504d 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -352,6 +352,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
> seq_puts(m, "plane:\n");
> seq_printf(m, "\ttype=%s\n",
> drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
> + seq_printf(m, "\tname=%s\n",
> + vkms_config_plane_get_name(plane_cfg));
I discovered this while working on some basic IGT tests to validate
your changes.
I think that this triggers undefined behavior. printf() and friends
expect a non NULL value for %s:
https://stackoverflow.com/a/11589479
In my Fedora system, this prints "name=(null)", instead of an empty
string.
The same happens with the ConfigFS API:
$ cat /sys/kernel/config/vkms/test_plane_default_values/planes/plane0/name
(null)
We'd need to return in both places an empty string instead.
> }
>
> vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
> @@ -392,6 +394,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
>
> plane_cfg->config = config;
> vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
> + vkms_config_plane_set_name(plane_cfg, NULL);
> xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
>
> list_add_tail(&plane_cfg->link, &config->planes);
> @@ -404,6 +407,7 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg)
> {
> xa_destroy(&plane_cfg->possible_crtcs);
> list_del(&plane_cfg->link);
> + kfree_const(plane_cfg->name);
> kfree(plane_cfg);
> }
> EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane);
> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
> index 4c8d668e7ef8..57342db5795a 100644
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -35,6 +35,7 @@ struct vkms_config {
> *
> * @link: Link to the others planes in vkms_config
> * @config: The vkms_config this plane belongs to
> + * @name: Name of the plane
> * @type: Type of the plane. The creator of configuration needs to ensures that
> * at least one primary plane is present.
> * @possible_crtcs: Array of CRTCs that can be used with this plane
> @@ -47,6 +48,7 @@ struct vkms_config_plane {
> struct list_head link;
> struct vkms_config *config;
>
> + const char *name;
> enum drm_plane_type type;
> struct xarray possible_crtcs;
>
> @@ -288,6 +290,30 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
> plane_cfg->type = type;
> }
>
> +/**
> + * vkms_config_plane_set_name() - Set the plane name
> + * @plane_cfg: Plane to set the name to
> + * @name: New plane name. The name is copied.
> + */
> +static inline void
> +vkms_config_plane_set_name(struct vkms_config_plane *plane_cfg,
> + const char *name)
> +{
> + if (plane_cfg->name)
> + kfree_const(plane_cfg->name);
> + plane_cfg->name = kstrdup_const(name, GFP_KERNEL);
> +}
> +
> +/**
> + * vkms_config_plane_get_name - Get the plane name
> + * @plane_cfg: Plane to get the name from
> + */
> +static inline const char *
> +vkms_config_plane_get_name(const struct vkms_config_plane *plane_cfg)
> +{
> + return plane_cfg->name;
> +}
> +
> /**
> * vkms_config_plane_attach_crtc - Attach a plane to a CRTC
> * @plane_cfg: Plane to attach
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index db260df1d4f6..9ad286f043b5 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -225,6 +225,7 @@ struct vkms_output {
> };
>
> struct vkms_config;
> +struct vkms_config_plane;
>
> /**
> * struct vkms_device - Description of a VKMS device
> @@ -298,10 +299,10 @@ int vkms_output_init(struct vkms_device *vkmsdev);
> * vkms_plane_init() - Initialize a plane
> *
> * @vkmsdev: VKMS device containing the plane
> - * @type: type of plane to initialize
> + * @config: plane configuration
> */
> struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
> - enum drm_plane_type type);
> + struct vkms_config_plane *config);
>
> /* CRC Support */
> const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
> index 2ee3749e2b28..22208d02afa4 100644
> --- a/drivers/gpu/drm/vkms/vkms_output.c
> +++ b/drivers/gpu/drm/vkms/vkms_output.c
> @@ -19,11 +19,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
> return -EINVAL;
>
> vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
> - enum drm_plane_type type;
> -
> - type = vkms_config_plane_get_type(plane_cfg);
> -
> - plane_cfg->plane = vkms_plane_init(vkmsdev, type);
> + plane_cfg->plane = vkms_plane_init(vkmsdev, plane_cfg);
> if (IS_ERR(plane_cfg->plane)) {
> DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n");
> return PTR_ERR(plane_cfg->plane);
> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
> index e592e47a5736..73180cbb78b1 100644
> --- a/drivers/gpu/drm/vkms/vkms_plane.c
> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
> @@ -9,6 +9,7 @@
> #include <drm/drm_gem_atomic_helper.h>
> #include <drm/drm_gem_framebuffer_helper.h>
>
> +#include "vkms_config.h"
> #include "vkms_drv.h"
> #include "vkms_formats.h"
>
> @@ -217,7 +218,7 @@ static const struct drm_plane_helper_funcs vkms_plane_helper_funcs = {
> };
>
> struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
> - enum drm_plane_type type)
> + struct vkms_config_plane *config)
> {
> struct drm_device *dev = &vkmsdev->drm;
> struct vkms_plane *plane;
> @@ -225,7 +226,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
> plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
> &vkms_plane_funcs,
> vkms_formats, ARRAY_SIZE(vkms_formats),
> - NULL, type, NULL);
> + NULL, vkms_config_plane_get_type(config),
> + vkms_config_plane_get_name(config));
> if (IS_ERR(plane))
> return plane;
>
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs for plane name
2025-10-29 14:36 ` [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-11-13 14:21 ` José Expósito
2025-11-17 9:56 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:21 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:43PM +0100, Louis Chauvet wrote:
> Planes can have name, create a plane attribute to configure it. Currently
> plane name is mainly used in logs.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> Documentation/gpu/vkms.rst | 3 ++-
> drivers/gpu/drm/vkms/vkms_configfs.c | 32 ++++++++++++++++++++++++++++++++
> 2 files changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
> index 3574e01b928d..1fe6e420c963 100644
> --- a/Documentation/gpu/vkms.rst
> +++ b/Documentation/gpu/vkms.rst
> @@ -87,10 +87,11 @@ Start by creating one or more planes::
>
> sudo mkdir /config/vkms/my-vkms/planes/plane0
>
> -Planes have 1 configurable attribute:
> +Planes have 2 configurable attributes:
>
> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
> exposed by the "type" property of a plane)
> +- name: Name of the plane
I'd like to mention again my comment on limiting the name to a set of
well-known characters [1].
The reason is that, in libinput, we had a format string vulnerability
due to the kernel exposing devices with names containing strings like
"%s" in the name (CVE-2022-1215):
https://gitlab.freedesktop.org/libinput/libinput/-/issues/752
In my opinion, we should avoid surprising user-space too much and allow
only a set of "safe" characters.
Maybe I'm too cautious, as this is valid code, but I'd like to bring up
the discussion again to see if someone else agrees or disagrees.
[1] https://lore.kernel.org/all/aPtgCUX5kixTh2ua@fedora/
> Continue by creating one or more CRTCs::
>
> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
> index 07ab794e1052..be6c3ba998b9 100644
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -322,10 +322,42 @@ static ssize_t plane_type_store(struct config_item *item, const char *page,
> return (ssize_t)count;
> }
>
> +static ssize_t plane_name_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + const char *name;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
> +
> + scoped_guard(mutex, &plane->dev->lock)
> + name = vkms_config_plane_get_name(plane->config);
> +
> + return sprintf(page, "%s\n", name);
> +}
> +
> +static ssize_t plane_name_store(struct config_item *item, const char *page,
> + size_t count)
> +{
> + struct vkms_configfs_plane *plane;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + if (plane->dev->enabled)
> + return -EBUSY;
> +
> + vkms_config_plane_set_name(plane->config, page);
> + }
> +
> + return (ssize_t)count;
> +}
> +
> CONFIGFS_ATTR(plane_, type);
> +CONFIGFS_ATTR(plane_, name);
>
> static struct configfs_attribute *plane_item_attrs[] = {
> &plane_attr_type,
> + &plane_attr_name,
> NULL,
> };
>
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield
2025-10-29 14:36 ` [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield Louis Chauvet
@ 2025-11-13 14:23 ` José Expósito
2025-12-18 17:58 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: José Expósito @ 2025-11-13 14:23 UTC (permalink / raw)
To: Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed, Oct 29, 2025 at 03:36:44PM +0100, Louis Chauvet wrote:
> Having the rotation/reflection name from its value can be useful for
> debugging purpose. Extract the rotation property table and implement
> drm_get_rotation_name.
Reviewed-by: José Expósito <jose.exposito@redhat.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/drm_blend.c | 35 ++++++++++++++++++++++++++---------
> include/drm/drm_blend.h | 2 ++
> 2 files changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 6852d73c931c..bc7c05e20242 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -241,6 +241,31 @@ int drm_plane_create_alpha_property(struct drm_plane *plane)
> }
> EXPORT_SYMBOL(drm_plane_create_alpha_property);
>
> +static const struct drm_prop_enum_list rotation_props[] = {
> + { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
> + { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
> + { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
> + { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
> + { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
> + { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
> +};
> +
> +/**
> + * drm_get_rotation_name - Return the name of a rotation
> + * @rotation: The rotation mask (DRM_MODE_ROTATE_* | DRM_MODE_REFLECT_*)
> + *
> + * Returns: the name of the rotation type (unknown) if rotation is not
> + * a known rotation/reflection
> + */
> +const char *drm_get_rotation_name(unsigned int rotation)
> +{
> + if (rotation < ARRAY_SIZE(rotation_props))
> + return rotation_props[rotation].name;
> +
> + return "(unknown)";
> +}
> +EXPORT_SYMBOL(drm_get_rotation_name);
> +
> /**
> * drm_plane_create_rotation_property - create a new rotation property
> * @plane: drm plane
> @@ -279,14 +304,6 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
> unsigned int rotation,
> unsigned int supported_rotations)
> {
> - static const struct drm_prop_enum_list props[] = {
> - { __builtin_ffs(DRM_MODE_ROTATE_0) - 1, "rotate-0" },
> - { __builtin_ffs(DRM_MODE_ROTATE_90) - 1, "rotate-90" },
> - { __builtin_ffs(DRM_MODE_ROTATE_180) - 1, "rotate-180" },
> - { __builtin_ffs(DRM_MODE_ROTATE_270) - 1, "rotate-270" },
> - { __builtin_ffs(DRM_MODE_REFLECT_X) - 1, "reflect-x" },
> - { __builtin_ffs(DRM_MODE_REFLECT_Y) - 1, "reflect-y" },
> - };
> struct drm_property *prop;
>
> WARN_ON((supported_rotations & DRM_MODE_ROTATE_MASK) == 0);
> @@ -294,7 +311,7 @@ int drm_plane_create_rotation_property(struct drm_plane *plane,
> WARN_ON(rotation & ~supported_rotations);
>
> prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
> - props, ARRAY_SIZE(props),
> + rotation_props, ARRAY_SIZE(rotation_props),
> supported_rotations);
> if (!prop)
> return -ENOMEM;
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 88bdfec3bd88..381d1f8d815b 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -42,6 +42,8 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
>
> #define DRM_BLEND_ALPHA_OPAQUE 0xffff
>
> +const char *drm_get_rotation_name(unsigned int rotation);
> +
> int drm_plane_create_alpha_property(struct drm_plane *plane);
> int drm_plane_create_rotation_property(struct drm_plane *plane,
> unsigned int rotation,
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs for plane name
2025-11-13 14:21 ` José Expósito
@ 2025-11-17 9:56 ` Louis Chauvet
2025-12-18 17:58 ` Luca Ceresoli
0 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-11-17 9:56 UTC (permalink / raw)
To: José Expósito
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 11/13/25 14:21, José Expósito wrote:
> On Wed, Oct 29, 2025 at 03:36:43PM +0100, Louis Chauvet wrote:
>> Planes can have name, create a plane attribute to configure it. Currently
>> plane name is mainly used in logs.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> Documentation/gpu/vkms.rst | 3 ++-
>> drivers/gpu/drm/vkms/vkms_configfs.c | 32 ++++++++++++++++++++++++++++++++
>> 2 files changed, 34 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>> index 3574e01b928d..1fe6e420c963 100644
>> --- a/Documentation/gpu/vkms.rst
>> +++ b/Documentation/gpu/vkms.rst
>> @@ -87,10 +87,11 @@ Start by creating one or more planes::
>>
>> sudo mkdir /config/vkms/my-vkms/planes/plane0
>>
>> -Planes have 1 configurable attribute:
>> +Planes have 2 configurable attributes:
>>
>> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
>> exposed by the "type" property of a plane)
>> +- name: Name of the plane
>
> I'd like to mention again my comment on limiting the name to a set of
> well-known characters [1].
>
> The reason is that, in libinput, we had a format string vulnerability
> due to the kernel exposing devices with names containing strings like
> "%s" in the name (CVE-2022-1215):
> https://gitlab.freedesktop.org/libinput/libinput/-/issues/752
>
> In my opinion, we should avoid surprising user-space too much and allow
> only a set of "safe" characters.
>
> Maybe I'm too cautious, as this is valid code, but I'd like to bring up
> the discussion again to see if someone else agrees or disagrees.
>
> [1] https://lore.kernel.org/all/aPtgCUX5kixTh2ua@fedora/
Sorry, I completely forgot to send my mail drafts for your comments...
It was mainly "Will do for v2" except here:
For me this should not be a kernel concern, when the userspace read a
file/folder name, it can be anything, so the userspace should do the
proper sanitization.
For libinput it was "easy" to exploit because unauthenticated users can
create any device name, but for VKMS, you must already be a
"privilegied" user (can write to configfs). I don't see the added value
for a kernel-side limitation, it will be more code for almost no
security improvement.
If you really think this is important, do you know if the kernel have a
helper to do this kind of checks? I did not found anything in strings.h
and I don't want to implement it in VKMS.
>> Continue by creating one or more CRTCs::
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
>> index 07ab794e1052..be6c3ba998b9 100644
>> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
>> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
>> @@ -322,10 +322,42 @@ static ssize_t plane_type_store(struct config_item *item, const char *page,
>> return (ssize_t)count;
>> }
>>
>> +static ssize_t plane_name_show(struct config_item *item, char *page)
>> +{
>> + struct vkms_configfs_plane *plane;
>> + const char *name;
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>> +
>> + scoped_guard(mutex, &plane->dev->lock)
>> + name = vkms_config_plane_get_name(plane->config);
>> +
>> + return sprintf(page, "%s\n", name);
>> +}
>> +
>> +static ssize_t plane_name_store(struct config_item *item, const char *page,
>> + size_t count)
>> +{
>> + struct vkms_configfs_plane *plane;
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + if (plane->dev->enabled)
>> + return -EBUSY;
>> +
>> + vkms_config_plane_set_name(plane->config, page);
>> + }
>> +
>> + return (ssize_t)count;
>> +}
>> +
>> CONFIGFS_ATTR(plane_, type);
>> +CONFIGFS_ATTR(plane_, name);
>>
>> static struct configfs_attribute *plane_item_attrs[] = {
>> &plane_attr_type,
>> + &plane_attr_name,
>> NULL,
>> };
>>
>>
>> --
>> 2.51.0
>>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name
2025-11-13 14:06 ` José Expósito
@ 2025-11-17 11:28 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-11-17 11:28 UTC (permalink / raw)
To: José Expósito
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 11/13/25 14:06, José Expósito wrote:
> Hey Louis,
>
> On Wed, Oct 29, 2025 at 03:36:38PM +0100, Louis Chauvet wrote:
>> Create and export an helper to display plane type using the
>> property string. This could be used to display debug
>> information in VKMS.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> drivers/gpu/drm/drm_mode_config.c | 13 +++++++++++++
>> include/drm/drm_mode_config.h | 3 +++
>> 2 files changed, 16 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
>> index 25f376869b3a..1a1a3f43db4d 100644
>> --- a/drivers/gpu/drm/drm_mode_config.c
>> +++ b/drivers/gpu/drm/drm_mode_config.c
>> @@ -226,6 +226,19 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
>> { DRM_PLANE_TYPE_CURSOR, "Cursor" },
>> };
>>
>> +/**
>> + * drm_get_plane_type_name - return a string for plane name
>> + * @type: plane type to compute name of
>
> Maybe we could document here what happens when the plane type is
> not valid.
>
> Returns: The name of the plane type. "(unknown)" if type is not a
> known plane type.
Ack, I will integrate it for v3
> Other than that:
> Reviewed-by: José Expósito <jose.exposito@redhat.com>
>
>> + */
>> +const char *drm_get_plane_type_name(enum drm_plane_type type)
>> +{
>> + if (type < ARRAY_SIZE(drm_plane_type_enum_list))
>> + return drm_plane_type_enum_list[type].name;
>> + else
>> + return "(unknown)";
>> +}
>> +EXPORT_SYMBOL(drm_get_plane_type_name);
>> +
>> static int drm_mode_create_standard_properties(struct drm_device *dev)
>> {
>> struct drm_property *prop;
>> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> index 2e848b816218..89f3dd46178d 100644
>> --- a/include/drm/drm_mode_config.h
>> +++ b/include/drm/drm_mode_config.h
>> @@ -30,6 +30,7 @@
>> #include <linux/llist.h>
>>
>> #include <drm/drm_modeset_lock.h>
>> +#include <drm/drm_plane.h>
>>
>> struct drm_file;
>> struct drm_device;
>> @@ -983,4 +984,6 @@ static inline int drm_mode_config_init(struct drm_device *dev)
>> void drm_mode_config_reset(struct drm_device *dev);
>> void drm_mode_config_cleanup(struct drm_device *dev);
>>
>> +const char *drm_get_plane_type_name(enum drm_plane_type type);
>> +
>> #endif
>>
>> --
>> 2.51.0
>>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name
2025-11-13 14:17 ` José Expósito
@ 2025-11-17 14:12 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-11-17 14:12 UTC (permalink / raw)
To: José Expósito
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 11/13/25 14:17, José Expósito wrote:
> On Wed, Oct 29, 2025 at 03:36:42PM +0100, Louis Chauvet wrote:
>> As planes can have a name in DRM, prepare VKMS to configure it using
>> ConfigFS.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> drivers/gpu/drm/vkms/vkms_config.c | 4 ++++
>> drivers/gpu/drm/vkms/vkms_config.h | 26 ++++++++++++++++++++++++++
>> drivers/gpu/drm/vkms/vkms_drv.h | 5 +++--
>> drivers/gpu/drm/vkms/vkms_output.c | 6 +-----
>> drivers/gpu/drm/vkms/vkms_plane.c | 6 ++++--
>> 5 files changed, 38 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c
>> index 858bec2d1312..bfafb5d2504d 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.c
>> +++ b/drivers/gpu/drm/vkms/vkms_config.c
>> @@ -352,6 +352,8 @@ static int vkms_config_show(struct seq_file *m, void *data)
>> seq_puts(m, "plane:\n");
>> seq_printf(m, "\ttype=%s\n",
>> drm_get_plane_type_name(vkms_config_plane_get_type(plane_cfg)));
>> + seq_printf(m, "\tname=%s\n",
>> + vkms_config_plane_get_name(plane_cfg));
>
> I discovered this while working on some basic IGT tests to validate
> your changes.
>
> I think that this triggers undefined behavior. printf() and friends
> expect a non NULL value for %s:
> https://stackoverflow.com/a/11589479
>
> In my Fedora system, this prints "name=(null)", instead of an empty
> string.
>
> The same happens with the ConfigFS API:
>
> $ cat /sys/kernel/config/vkms/test_plane_default_values/planes/plane0/name
> (null)
>
> We'd need to return in both places an empty string instead.
Good catch, I will fix for v3!
>> }
>>
>> vkms_config_for_each_crtc(vkmsdev->config, crtc_cfg) {
>> @@ -392,6 +394,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config)
>>
>> plane_cfg->config = config;
>> vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY);
>> + vkms_config_plane_set_name(plane_cfg, NULL);
>> xa_init_flags(&plane_cfg->possible_crtcs, XA_FLAGS_ALLOC);
>>
>> list_add_tail(&plane_cfg->link, &config->planes);
>> @@ -404,6 +407,7 @@ void vkms_config_destroy_plane(struct vkms_config_plane *plane_cfg)
>> {
>> xa_destroy(&plane_cfg->possible_crtcs);
>> list_del(&plane_cfg->link);
>> + kfree_const(plane_cfg->name);
>> kfree(plane_cfg);
>> }
>> EXPORT_SYMBOL_IF_KUNIT(vkms_config_destroy_plane);
>> diff --git a/drivers/gpu/drm/vkms/vkms_config.h b/drivers/gpu/drm/vkms/vkms_config.h
>> index 4c8d668e7ef8..57342db5795a 100644
>> --- a/drivers/gpu/drm/vkms/vkms_config.h
>> +++ b/drivers/gpu/drm/vkms/vkms_config.h
>> @@ -35,6 +35,7 @@ struct vkms_config {
>> *
>> * @link: Link to the others planes in vkms_config
>> * @config: The vkms_config this plane belongs to
>> + * @name: Name of the plane
>> * @type: Type of the plane. The creator of configuration needs to ensures that
>> * at least one primary plane is present.
>> * @possible_crtcs: Array of CRTCs that can be used with this plane
>> @@ -47,6 +48,7 @@ struct vkms_config_plane {
>> struct list_head link;
>> struct vkms_config *config;
>>
>> + const char *name;
>> enum drm_plane_type type;
>> struct xarray possible_crtcs;
>>
>> @@ -288,6 +290,30 @@ vkms_config_plane_set_type(struct vkms_config_plane *plane_cfg,
>> plane_cfg->type = type;
>> }
>>
>> +/**
>> + * vkms_config_plane_set_name() - Set the plane name
>> + * @plane_cfg: Plane to set the name to
>> + * @name: New plane name. The name is copied.
>> + */
>> +static inline void
>> +vkms_config_plane_set_name(struct vkms_config_plane *plane_cfg,
>> + const char *name)
>> +{
>> + if (plane_cfg->name)
>> + kfree_const(plane_cfg->name);
>> + plane_cfg->name = kstrdup_const(name, GFP_KERNEL);
>> +}
>> +
>> +/**
>> + * vkms_config_plane_get_name - Get the plane name
>> + * @plane_cfg: Plane to get the name from
>> + */
>> +static inline const char *
>> +vkms_config_plane_get_name(const struct vkms_config_plane *plane_cfg)
>> +{
>> + return plane_cfg->name;
>> +}
>> +
>> /**
>> * vkms_config_plane_attach_crtc - Attach a plane to a CRTC
>> * @plane_cfg: Plane to attach
>> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
>> index db260df1d4f6..9ad286f043b5 100644
>> --- a/drivers/gpu/drm/vkms/vkms_drv.h
>> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
>> @@ -225,6 +225,7 @@ struct vkms_output {
>> };
>>
>> struct vkms_config;
>> +struct vkms_config_plane;
>>
>> /**
>> * struct vkms_device - Description of a VKMS device
>> @@ -298,10 +299,10 @@ int vkms_output_init(struct vkms_device *vkmsdev);
>> * vkms_plane_init() - Initialize a plane
>> *
>> * @vkmsdev: VKMS device containing the plane
>> - * @type: type of plane to initialize
>> + * @config: plane configuration
>> */
>> struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
>> - enum drm_plane_type type);
>> + struct vkms_config_plane *config);
>>
>> /* CRC Support */
>> const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
>> diff --git a/drivers/gpu/drm/vkms/vkms_output.c b/drivers/gpu/drm/vkms/vkms_output.c
>> index 2ee3749e2b28..22208d02afa4 100644
>> --- a/drivers/gpu/drm/vkms/vkms_output.c
>> +++ b/drivers/gpu/drm/vkms/vkms_output.c
>> @@ -19,11 +19,7 @@ int vkms_output_init(struct vkms_device *vkmsdev)
>> return -EINVAL;
>>
>> vkms_config_for_each_plane(vkmsdev->config, plane_cfg) {
>> - enum drm_plane_type type;
>> -
>> - type = vkms_config_plane_get_type(plane_cfg);
>> -
>> - plane_cfg->plane = vkms_plane_init(vkmsdev, type);
>> + plane_cfg->plane = vkms_plane_init(vkmsdev, plane_cfg);
>> if (IS_ERR(plane_cfg->plane)) {
>> DRM_DEV_ERROR(dev->dev, "Failed to init vkms plane\n");
>> return PTR_ERR(plane_cfg->plane);
>> diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c
>> index e592e47a5736..73180cbb78b1 100644
>> --- a/drivers/gpu/drm/vkms/vkms_plane.c
>> +++ b/drivers/gpu/drm/vkms/vkms_plane.c
>> @@ -9,6 +9,7 @@
>> #include <drm/drm_gem_atomic_helper.h>
>> #include <drm/drm_gem_framebuffer_helper.h>
>>
>> +#include "vkms_config.h"
>> #include "vkms_drv.h"
>> #include "vkms_formats.h"
>>
>> @@ -217,7 +218,7 @@ static const struct drm_plane_helper_funcs vkms_plane_helper_funcs = {
>> };
>>
>> struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
>> - enum drm_plane_type type)
>> + struct vkms_config_plane *config)
>> {
>> struct drm_device *dev = &vkmsdev->drm;
>> struct vkms_plane *plane;
>> @@ -225,7 +226,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
>> plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 0,
>> &vkms_plane_funcs,
>> vkms_formats, ARRAY_SIZE(vkms_formats),
>> - NULL, type, NULL);
>> + NULL, vkms_config_plane_get_type(config),
>> + vkms_config_plane_get_name(config));
>> if (IS_ERR(plane))
>> return plane;
>>
>>
>> --
>> 2.51.0
>>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
2025-11-13 14:06 ` José Expósito
@ 2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
Hi Louis,
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Create and export an helper to display plane type using the
> property string. This could be used to display debug
> information in VKMS.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> drivers/gpu/drm/drm_mode_config.c | 13 +++++++++++++
> include/drm/drm_mode_config.h | 3 +++
> 2 files changed, 16 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index 25f376869b3a..1a1a3f43db4d 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -226,6 +226,19 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = {
> { DRM_PLANE_TYPE_CURSOR, "Cursor" },
> };
>
> +/**
> + * drm_get_plane_type_name - return a string for plane name
> + * @type: plane type to compute name of
> + */
> +const char *drm_get_plane_type_name(enum drm_plane_type type)
> +{
> + if (type < ARRAY_SIZE(drm_plane_type_enum_list))
> + return drm_plane_type_enum_list[type].name;
> + else
> + return "(unknown)";
> +}
AFAIK an enum can be signed, so you should check for >= 0 too for extra
safety.
Otherwise looks good.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type
2025-10-29 14:36 ` [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type Louis Chauvet
2025-11-13 14:07 ` José Expósito
@ 2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Debug information are mainly read by human, so use full name instead
> of values.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status
2025-10-29 14:36 ` [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status Louis Chauvet
2025-11-13 14:11 ` José Expósito
@ 2025-12-18 17:56 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Debug information are mainly read by human, so use full name instead
> of raw values for connector status.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug
2025-11-13 14:09 ` José Expósito
@ 2025-12-18 17:57 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:57 UTC (permalink / raw)
To: José Expósito, Louis Chauvet
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Thu Nov 13, 2025 at 3:09 PM CET, José Expósito wrote:
> On Wed, Oct 29, 2025 at 03:36:40PM +0100, Louis Chauvet wrote:
>> Debug information are mainly read by human, so display human
>> readable values.
>
> Today I learned. I wasn't aware of those helpers, nice!
Me too! :-)
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs for plane name
2025-11-17 9:56 ` Louis Chauvet
@ 2025-12-18 17:58 ` Luca Ceresoli
2025-12-19 15:49 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:58 UTC (permalink / raw)
To: Louis Chauvet, José Expósito
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Mon Nov 17, 2025 at 10:56 AM CET, Louis Chauvet wrote:
>
>
> On 11/13/25 14:21, José Expósito wrote:
>> On Wed, Oct 29, 2025 at 03:36:43PM +0100, Louis Chauvet wrote:
>>> Planes can have name, create a plane attribute to configure it. Currently
>>> plane name is mainly used in logs.
>>>
>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>> ---
>>> Documentation/gpu/vkms.rst | 3 ++-
>>> drivers/gpu/drm/vkms/vkms_configfs.c | 32 ++++++++++++++++++++++++++++++++
>>> 2 files changed, 34 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>>> index 3574e01b928d..1fe6e420c963 100644
>>> --- a/Documentation/gpu/vkms.rst
>>> +++ b/Documentation/gpu/vkms.rst
>>> @@ -87,10 +87,11 @@ Start by creating one or more planes::
>>>
>>> sudo mkdir /config/vkms/my-vkms/planes/plane0
>>>
>>> -Planes have 1 configurable attribute:
>>> +Planes have 2 configurable attributes:
>>>
>>> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
>>> exposed by the "type" property of a plane)
>>> +- name: Name of the plane
>>
>> I'd like to mention again my comment on limiting the name to a set of
>> well-known characters [1].
>>
>> The reason is that, in libinput, we had a format string vulnerability
>> due to the kernel exposing devices with names containing strings like
>> "%s" in the name (CVE-2022-1215):
>> https://gitlab.freedesktop.org/libinput/libinput/-/issues/752
>>
>> In my opinion, we should avoid surprising user-space too much and allow
>> only a set of "safe" characters.
>>
>> Maybe I'm too cautious, as this is valid code, but I'd like to bring up
>> the discussion again to see if someone else agrees or disagrees.
>>
>> [1] https://lore.kernel.org/all/aPtgCUX5kixTh2ua@fedora/
>
> Sorry, I completely forgot to send my mail drafts for your comments...
> It was mainly "Will do for v2" except here:
>
>
> For me this should not be a kernel concern, when the userspace read a
> file/folder name, it can be anything, so the userspace should do the
> proper sanitization.
>
> For libinput it was "easy" to exploit because unauthenticated users can
> create any device name, but for VKMS, you must already be a
> "privilegied" user (can write to configfs). I don't see the added value
> for a kernel-side limitation, it will be more code for almost no
> security improvement.
>
> If you really think this is important, do you know if the kernel have a
> helper to do this kind of checks? I did not found anything in strings.h
> and I don't want to implement it in VKMS.
I tend to agree with José here, being strict on accepted input is good.
I guess you can stick to [A-Za-z0-9_-], then if there is a good reason to
relax the constraint it can be done later.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield
2025-10-29 14:36 ` [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield Louis Chauvet
2025-11-13 14:23 ` José Expósito
@ 2025-12-18 17:58 ` Luca Ceresoli
1 sibling, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:58 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Having the rotation/reflection name from its value can be useful for
> debugging purpose. Extract the rotation property table and implement
> drm_get_rotation_name.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation
2025-10-29 14:36 ` [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> VKMS driver supports all the rotation on planes, but for testing it can be
> useful to only advertise few of them. This new configuration interface
> will allow configuring the rotation per planes.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs for plane rotation
2025-10-29 14:36 ` [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> To allows the userspace to test many hardware configuration, introduce a
configurations
> new interface to configure the available rotation per planes. VKMS
> supports any rotation and reflection, so the userspace can choose any
> combination.
>
> The supported rotations are configured by writing a rotation bitmask to
> the file `supported_rotations` and the default rotation is chosen by
> writing a rotation bitmask to `default_rotation`.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> Documentation/gpu/vkms.rst | 7 ++-
> drivers/gpu/drm/vkms/vkms_configfs.c | 91 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 97 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
> index 1fe6e420c963..eac1a942d6c4 100644
> --- a/Documentation/gpu/vkms.rst
> +++ b/Documentation/gpu/vkms.rst
> @@ -87,11 +87,16 @@ Start by creating one or more planes::
>
> sudo mkdir /config/vkms/my-vkms/planes/plane0
>
> -Planes have 2 configurable attributes:
> +Planes have 4 configurable attributes:
>
> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
> exposed by the "type" property of a plane)
> - name: Name of the plane
> +- possible_rotations: Available rotation for a plane, as a bitmask: 0x01 no rotation,
> + 0x02 rotate 90°, 0x04 rotate 180°, 0x08 rotate 270°, 0x10 reflect x, 0x20 reflect y
> + (same values as those exposed by the "rotation" property of a plane)
> +- default_rotation: Default rotation presented to the userspace, same values as
> + possible_rotations.
>
> Continue by creating one or more CRTCs::
>
> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
> index be6c3ba998b9..7cc8ba315ef0 100644
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -352,12 +352,103 @@ static ssize_t plane_name_store(struct config_item *item, const char *page,
> return (ssize_t)count;
> }
>
> +static ssize_t plane_supported_rotations_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + unsigned int plane_supported_rotations;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
Small nit: below you do
struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
Why not here as well?
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + plane_supported_rotations = vkms_config_plane_get_supported_rotations(plane->config);
> + }
> +
> + return sprintf(page, "%u", plane_supported_rotations);
> +}
> +
> +static ssize_t plane_supported_rotations_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 0, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
> + return -EINVAL;
> + /* Should at least provide one rotation */
> + if (!(val & DRM_MODE_ROTATE_MASK))
> + return -EINVAL;
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + /* Ensures that the default rotation is included in supported rotation */
> + if (plane->dev->enabled)
> + return -EINVAL;
The comment does not seem related to the code.
> +
> + vkms_config_plane_set_supported_rotations(plane->config, val);
> + }
> +
> + return count;
> +}
> +
> +static ssize_t plane_default_rotation_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + unsigned int plane_default_rotation;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
Same as above.
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + plane_default_rotation = vkms_config_plane_get_default_rotation(plane->config);
> + }
> +
> + return sprintf(page, "%u", plane_default_rotation);
> +}
> +
> +static ssize_t plane_default_rotation_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 10, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK))
> + return -EINVAL;
> + /* Should at least provide one rotation */
> + if ((val & DRM_MODE_ROTATE_MASK) == 0)
> + return -EINVAL;
This if is redundant because...
> + /* Should contains only one rotation */
/* Should contain exactly one rotation */
> + if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> + return -EINVAL;
...is_power_of_2() returns false if the parameter is 0.
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + /* Ensures that the default rotation is included in supported rotation */
> + if (plane->dev->enabled)
> + return -EINVAL;
Same as above.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name
2025-10-29 14:36 ` [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> drm_get_color_encoding_name can be useful to display debug information
> outside drm core. Export it so it could be used for VKMS
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding
2025-10-29 14:36 ` [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> VKMS driver supports all the color encoding on planes, but for testing it
> can be useful to only advertise few of them. This new configuration
> interface will allow configuring the color encoding per planes.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -45,6 +45,8 @@ struct vkms_config {
> * It can be used to store a temporary reference to a VKMS plane during
> * device creation. This pointer is not managed by the configuration and
> * must be managed by other means.
> + * @default_color_encoding: Default color encoding that should be used by this plane
> + * @supported_color_encodings: Color encoding that this plane will support
encodings
With that fixed you can add:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs for plane color encoding
2025-10-29 14:36 ` [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
2025-12-19 16:40 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> To allows the userspace to test many hardware configuration, introduce a
> new interface to configure the available color encoding per planes. VKMS
> supports multiple color encoding, so the userspace can choose any
> combination.
>
> The supported color encoding are configured by writing a color encoding
> bitmask to the file `supported_color_encoding` and the default color
> encoding is chosen by writing a color encoding bitmask to
> `default_color_encoding`.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> ---
> Documentation/gpu/vkms.rst | 7 ++-
> drivers/gpu/drm/vkms/vkms_configfs.c | 98 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 104 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
> index eac1a942d6c4..dab6811687a2 100644
> --- a/Documentation/gpu/vkms.rst
> +++ b/Documentation/gpu/vkms.rst
> @@ -87,7 +87,7 @@ Start by creating one or more planes::
>
> sudo mkdir /config/vkms/my-vkms/planes/plane0
>
> -Planes have 4 configurable attributes:
> +Planes have 6 configurable attributes:
>
> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
> exposed by the "type" property of a plane)
> @@ -97,6 +97,11 @@ Planes have 4 configurable attributes:
> (same values as those exposed by the "rotation" property of a plane)
> - default_rotation: Default rotation presented to the userspace, same values as
> possible_rotations.
> +- supported_color_encoding: Available encoding for a plane, as a bitmask:
encodings
> + 0x01 YCBCR_BT601, 0x02: YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
^
Unintended colon? While I think it's nice to have, there is none elsewhere,
even in previous patches, and I'd say we can live happy without.
> + by the COLOR_ENCODING property of a plane)
> +- default_color_encoding: Default color encoding presented to the userspace, same
> + values as supported_color_encoding
>
> Continue by creating one or more CRTCs::
>
> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
> index 7cc8ba315ef0..ee2e8d141f9e 100644
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -439,16 +439,114 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
> return count;
> }
>
> +static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + unsigned int supported_color_encoding;
supported_color_encodings
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
As for patch 9, for consistency:
struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + supported_color_encoding = vkms_config_plane_get_supported_color_encodings(plane->config);
> + }
> +
> + return sprintf(page, "%u", supported_color_encoding);
> +}
> +
> +static ssize_t plane_supported_color_encodings_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 10, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
> + BIT(DRM_COLOR_YCBCR_BT709) |
> + BIT(DRM_COLOR_YCBCR_BT2020)))
> + return -EINVAL;
> + /* Should at least provide one color range */
> + if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
> + BIT(DRM_COLOR_YCBCR_BT709) |
> + BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
I'm mentioning here as it comes to mind, but it's valid for other similar
patches in this series: why not adding a
#define DRM_COLOR_ENCODINGS_SUPPORTED ( \
BIT(DRM_COLOR_YCBCR_BT601) |
BIT(DRM_COLOR_YCBCR_BT709) |
BIT(DRM_COLOR_YCBCR_BT2020))
and use it in place of the various bitwise-or sequences?
This would simplify work later on if adding a new color encoding (or color
range, or...).
Somewhat like DRM_MODE_*_MASK.
> + return -EINVAL;
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + /* Ensures that the default rotation is included in supported rotation */
> + if (plane->dev->enabled)
> + return -EINVAL;
And here the comment is definitely wrong. :-)
> +
> + vkms_config_plane_set_supported_color_encodings(plane->config, val);
> + }
> +
> + return count;
> +}
> +
> +/* Plane default_color_encoding : vkms/<device>/planes/<plane>/default_color_encoding */
There's no such comment in other places, so for consistency remove it (or
add it everywhere?!? ... no, just kidding).
> +
> +static ssize_t plane_default_color_encoding_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + unsigned int default_color_encoding;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + default_color_encoding = vkms_config_plane_get_default_color_encoding(plane->config);
> + }
> +
> + return sprintf(page, "%u", default_color_encoding);
> +}
> +
> +static ssize_t plane_default_color_encoding_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 10, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
> + BIT(DRM_COLOR_YCBCR_BT709) |
> + BIT(DRM_COLOR_YCBCR_BT2020)))
> + return -EINVAL;
> + /* Should at least provide one color range */
> + if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
> + BIT(DRM_COLOR_YCBCR_BT709) |
> + BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
> + return -EINVAL;
Shouldn't you check that exactly one bit is set? As in patch 9.
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + /* Ensures that the default rotation is included in supported rotation */
> + if (plane->dev->enabled)
> + return -EINVAL;
As before, wrong comment.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name
2025-10-29 14:36 ` [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> drm_get_color_range_name can be useful to print debugging information.
> Export it so it could be used from VKMS.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range
2025-10-29 14:36 ` [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range Louis Chauvet
@ 2025-12-18 17:59 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 17:59 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> VKMS driver supports all the color range on planes, but for testing it can
> be useful to only advertise few of them. This new configuration interface
> will allow configuring the color range per planes.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -359,6 +379,16 @@ bool vkms_config_is_valid(const struct vkms_config *config)
>
> if (!vkms_config_valid_plane_color_encoding(config, plane_cfg))
> return false;
> +
> + if (!vkms_config_valid_plane_color_range(config, plane_cfg))
> + return false;
> +
> + if ((vkms_config_plane_get_supported_color_encodings(plane_cfg) == 0) !=
> + (vkms_config_plane_get_supported_color_ranges(plane_cfg) == 0)) {
> + drm_info(dev,
> + "Both supported color encoding and color range must be set, or none\n");
encodings ranges
> @@ -441,6 +471,12 @@ static int vkms_config_show(struct seq_file *m, void *data)
> seq_puts(m, "\n");
> seq_printf(m, "\tdefault color encoding=%s\n",
> drm_get_color_encoding_name(vkms_config_plane_get_default_color_encoding(plane_cfg)));
> + seq_puts(m, "\tsupported color range=");
ranges
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -47,6 +47,8 @@ struct vkms_config {
> * must be managed by other means.
> * @default_color_encoding: Default color encoding that should be used by this plane
> * @supported_color_encodings: Color encoding that this plane will support
> + * @default_color_range: Default color range that should be used by this plane
> + * @supported_color_ranges: Color range that this plane will support
ranges
With those fixed you can add:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs for plane color range
2025-10-29 14:36 ` [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-18 18:00 ` Luca Ceresoli
2025-12-19 16:55 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-18 18:00 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> To allows the userspace to test many hardware configuration, introduce a
> new interface to configure the available color ranges per planes. VKMS
> supports multiple color ranges, so the userspace can choose any
> combination.
>
> The supported color ranges are configured by writing a color range bitmask
> to the file `supported_color_ranges` and the default color range is
> chosen by writing a color encoding bitmask to `default_color_range`.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
> index ee2e8d141f9e..3f658dd41272 100644
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -439,6 +439,91 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
> return count;
> }
>
> +static ssize_t plane_supported_color_ranges_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_plane *plane;
> + unsigned int supported_color_range;
supported_color_ranges
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
As for previous patches, set this on declaration for consistency (same below).
> +static ssize_t plane_supported_color_ranges_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 10, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> + BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
> + return -EINVAL;
> + /* Should at least provide one color range */
> + if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> + BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
> + return -EINVAL;
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + /* Ensures that the default rotation is included in supported rotation */
Oh no, that comment again! :-)
> +static ssize_t plane_default_color_range_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
> + int ret, val = 0;
> +
> + ret = kstrtouint(page, 10, &val);
> + if (ret)
> + return ret;
> +
> + /* Should be a supported value */
> + if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> + BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
> + return -EINVAL;
> + /* Should at least provide one color range */
> + if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
> + BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
> + return -EINVAL;
As in patch 12, replace this with is_power_of_2() to check that exactly one
bit is set.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format
2025-10-29 14:36 ` [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format Louis Chauvet
@ 2025-12-19 14:55 ` Luca Ceresoli
2025-12-19 18:31 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 14:55 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
Hi Louis,
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> VKMS driver supports all the pixel formats for planes, but for testing it
> can be useful to only advertise few of them. This new configuration
> interface will allow configuring the pixel format per planes.
[...]
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> +int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
> +{
> + bool found = false;
> +
> + for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
> + if (vkms_supported_plane_formats[i] == drm_format) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return -EINVAL;
> + for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
> + if (plane_cfg->supported_formats[i] == drm_format)
> + return 0;
> + }
> + u32 *new_ptr = krealloc_array(plane_cfg->supported_formats,
> + plane_cfg->supported_formats_count + 1,
> + sizeof(*plane_cfg->supported_formats), GFP_KERNEL);
> + if (!new_ptr)
> + return -ENOMEM;
> +
> + plane_cfg->supported_formats = new_ptr;
> + plane_cfg->supported_formats[plane_cfg->supported_formats_count] = drm_format;
> + plane_cfg->supported_formats_count++;
> +
> + return 0;
> +}
This whole logic appears quite complex for what you need here. I suspect
using the facilities in linux/bitmap.h would make your code simpler by
allocating a (multi-)ulong array of
ARRAY_SIZE(vkms_supported_plane_formats) bits. This would surely use less
memory and avoid all reallocations, too.
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> +/**
> + * vkms_config_plane_remove_format - Remove a specific format from a plane
> + * @plane_cfg: Plane to remove the format to
> + * @drm_format: Format to remove
> + */
> +void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
> +
> +/**
> + * vkms_config_plane_remove_all_formats - Remove all formast from a plane
formats
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs for plane name
2025-12-18 17:58 ` Luca Ceresoli
@ 2025-12-19 15:49 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 15:49 UTC (permalink / raw)
To: Luca Ceresoli, José Expósito
Cc: Haneen Mohammed, Simona Vetter, Melissa Wen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Jonathan Corbet,
victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/18/25 18:58, Luca Ceresoli wrote:
> On Mon Nov 17, 2025 at 10:56 AM CET, Louis Chauvet wrote:
>>
>>
>> On 11/13/25 14:21, José Expósito wrote:
>>> On Wed, Oct 29, 2025 at 03:36:43PM +0100, Louis Chauvet wrote:
>>>> Planes can have name, create a plane attribute to configure it. Currently
>>>> plane name is mainly used in logs.
>>>>
>>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>>> ---
>>>> Documentation/gpu/vkms.rst | 3 ++-
>>>> drivers/gpu/drm/vkms/vkms_configfs.c | 32 ++++++++++++++++++++++++++++++++
>>>> 2 files changed, 34 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>>>> index 3574e01b928d..1fe6e420c963 100644
>>>> --- a/Documentation/gpu/vkms.rst
>>>> +++ b/Documentation/gpu/vkms.rst
>>>> @@ -87,10 +87,11 @@ Start by creating one or more planes::
>>>>
>>>> sudo mkdir /config/vkms/my-vkms/planes/plane0
>>>>
>>>> -Planes have 1 configurable attribute:
>>>> +Planes have 2 configurable attributes:
>>>>
>>>> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
>>>> exposed by the "type" property of a plane)
>>>> +- name: Name of the plane
>>>
>>> I'd like to mention again my comment on limiting the name to a set of
>>> well-known characters [1].
>>>
>>> The reason is that, in libinput, we had a format string vulnerability
>>> due to the kernel exposing devices with names containing strings like
>>> "%s" in the name (CVE-2022-1215):
>>> https://gitlab.freedesktop.org/libinput/libinput/-/issues/752
>>>
>>> In my opinion, we should avoid surprising user-space too much and allow
>>> only a set of "safe" characters.
>>>
>>> Maybe I'm too cautious, as this is valid code, but I'd like to bring up
>>> the discussion again to see if someone else agrees or disagrees.
>>>
>>> [1] https://lore.kernel.org/all/aPtgCUX5kixTh2ua@fedora/
>>
>> Sorry, I completely forgot to send my mail drafts for your comments...
>> It was mainly "Will do for v2" except here:
>>
>>
>> For me this should not be a kernel concern, when the userspace read a
>> file/folder name, it can be anything, so the userspace should do the
>> proper sanitization.
>>
>> For libinput it was "easy" to exploit because unauthenticated users can
>> create any device name, but for VKMS, you must already be a
>> "privilegied" user (can write to configfs). I don't see the added value
>> for a kernel-side limitation, it will be more code for almost no
>> security improvement.
>>
>> If you really think this is important, do you know if the kernel have a
>> helper to do this kind of checks? I did not found anything in strings.h
>> and I don't want to implement it in VKMS.
>
> I tend to agree with José here, being strict on accepted input is good.
>
> I guess you can stick to [A-Za-z0-9_-], then if there is a good reason to
> relax the constraint it can be done later.
I don't have very strong opinion, I will add this!
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs for plane color encoding
2025-12-18 17:59 ` Luca Ceresoli
@ 2025-12-19 16:40 ` Louis Chauvet
2025-12-19 17:51 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 16:40 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/18/25 18:59, Luca Ceresoli wrote:
> On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
>> To allows the userspace to test many hardware configuration, introduce a
>> new interface to configure the available color encoding per planes. VKMS
>> supports multiple color encoding, so the userspace can choose any
>> combination.
>>
>> The supported color encoding are configured by writing a color encoding
>> bitmask to the file `supported_color_encoding` and the default color
>> encoding is chosen by writing a color encoding bitmask to
>> `default_color_encoding`.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> ---
>> Documentation/gpu/vkms.rst | 7 ++-
>> drivers/gpu/drm/vkms/vkms_configfs.c | 98 ++++++++++++++++++++++++++++++++++++
>> 2 files changed, 104 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
>> index eac1a942d6c4..dab6811687a2 100644
>> --- a/Documentation/gpu/vkms.rst
>> +++ b/Documentation/gpu/vkms.rst
>> @@ -87,7 +87,7 @@ Start by creating one or more planes::
>>
>> sudo mkdir /config/vkms/my-vkms/planes/plane0
>>
>> -Planes have 4 configurable attributes:
>> +Planes have 6 configurable attributes:
>>
>> - type: Plane type: 0 overlay, 1 primary, 2 cursor (same values as those
>> exposed by the "type" property of a plane)
>> @@ -97,6 +97,11 @@ Planes have 4 configurable attributes:
>> (same values as those exposed by the "rotation" property of a plane)
>> - default_rotation: Default rotation presented to the userspace, same values as
>> possible_rotations.
>> +- supported_color_encoding: Available encoding for a plane, as a bitmask:
> encodings
>
>> + 0x01 YCBCR_BT601, 0x02: YCBCR_BT709, 0x04 YCBCR_BT2020 (same values as those exposed
> ^
>
> Unintended colon? While I think it's nice to have, there is none elsewhere,
> even in previous patches, and I'd say we can live happy without.
>
>> + by the COLOR_ENCODING property of a plane)
>> +- default_color_encoding: Default color encoding presented to the userspace, same
>> + values as supported_color_encoding
>>
>> Continue by creating one or more CRTCs::
>>
>> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
>> index 7cc8ba315ef0..ee2e8d141f9e 100644
>> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
>> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
>> @@ -439,16 +439,114 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
>> return count;
>> }
>>
>> +static ssize_t plane_supported_color_encodings_show(struct config_item *item, char *page)
>> +{
>> + struct vkms_configfs_plane *plane;
>> + unsigned int supported_color_encoding;
> supported_color_encodings
>
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>
> As for patch 9, for consistency:
>
> struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
>
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + supported_color_encoding = vkms_config_plane_get_supported_color_encodings(plane->config);
>> + }
>> +
>> + return sprintf(page, "%u", supported_color_encoding);
>> +}
>> +
>> +static ssize_t plane_supported_color_encodings_store(struct config_item *item,
>> + const char *page, size_t count)
>> +{
>> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
>> + int ret, val = 0;
>> +
>> + ret = kstrtouint(page, 10, &val);
>> + if (ret)
>> + return ret;
>> +
>> + /* Should be a supported value */
>> + if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
>> + BIT(DRM_COLOR_YCBCR_BT709) |
>> + BIT(DRM_COLOR_YCBCR_BT2020)))
>> + return -EINVAL;
>> + /* Should at least provide one color range */
>> + if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
>> + BIT(DRM_COLOR_YCBCR_BT709) |
>> + BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
>
> I'm mentioning here as it comes to mind, but it's valid for other similar
> patches in this series: why not adding a
>
> #define DRM_COLOR_ENCODINGS_SUPPORTED ( \
> BIT(DRM_COLOR_YCBCR_BT601) |
> BIT(DRM_COLOR_YCBCR_BT709) |
> BIT(DRM_COLOR_YCBCR_BT2020))
>
> and use it in place of the various bitwise-or sequences?
>
> This would simplify work later on if adding a new color encoding (or color
> range, or...).
>
> Somewhat like DRM_MODE_*_MASK.
>
>> + return -EINVAL;
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + /* Ensures that the default rotation is included in supported rotation */
>> + if (plane->dev->enabled)
>> + return -EINVAL;
>
> And here the comment is definitely wrong. :-)
>
>> +
>> + vkms_config_plane_set_supported_color_encodings(plane->config, val);
>> + }
>> +
>> + return count;
>> +}
>> +
>> +/* Plane default_color_encoding : vkms/<device>/planes/<plane>/default_color_encoding */
>
> There's no such comment in other places, so for consistency remove it (or
> add it everywhere?!? ... no, just kidding).
>
>> +
>> +static ssize_t plane_default_color_encoding_show(struct config_item *item, char *page)
>> +{
>> + struct vkms_configfs_plane *plane;
>> + unsigned int default_color_encoding;
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + default_color_encoding = vkms_config_plane_get_default_color_encoding(plane->config);
>> + }
>> +
>> + return sprintf(page, "%u", default_color_encoding);
>> +}
>> +
>> +static ssize_t plane_default_color_encoding_store(struct config_item *item,
>> + const char *page, size_t count)
>> +{
>> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
>> + int ret, val = 0;
>> +
>> + ret = kstrtouint(page, 10, &val);
>> + if (ret)
>> + return ret;
>> +
>> + /* Should be a supported value */
>> + if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
>> + BIT(DRM_COLOR_YCBCR_BT709) |
>> + BIT(DRM_COLOR_YCBCR_BT2020)))
>> + return -EINVAL;
>> + /* Should at least provide one color range */
>> + if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
>> + BIT(DRM_COLOR_YCBCR_BT709) |
>> + BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
>> + return -EINVAL;
>
> Shouldn't you check that exactly one bit is set? As in patch 9.
Because this code is wrong... the default rotation should be
DRM_COLOR_YCBCR_BT601 / DRM_COLOR_YCBCR_BT709 / DRM_COLOR_YCBCR_BT2020
not a bitfield...
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + /* Ensures that the default rotation is included in supported rotation */
>> + if (plane->dev->enabled)
>> + return -EINVAL;
>
> As before, wrong comment.
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs for plane color range
2025-12-18 18:00 ` Luca Ceresoli
@ 2025-12-19 16:55 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 16:55 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/18/25 19:00, Luca Ceresoli wrote:
> On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
>> To allows the userspace to test many hardware configuration, introduce a
>> new interface to configure the available color ranges per planes. VKMS
>> supports multiple color ranges, so the userspace can choose any
>> combination.
>>
>> The supported color ranges are configured by writing a color range bitmask
>> to the file `supported_color_ranges` and the default color range is
>> chosen by writing a color encoding bitmask to `default_color_range`.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
>> diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
>> index ee2e8d141f9e..3f658dd41272 100644
>> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
>> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
>> @@ -439,6 +439,91 @@ static ssize_t plane_default_rotation_store(struct config_item *item,
>> return count;
>> }
>>
>> +static ssize_t plane_supported_color_ranges_show(struct config_item *item, char *page)
>> +{
>> + struct vkms_configfs_plane *plane;
>> + unsigned int supported_color_range;
> supported_color_ranges
>
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>
> As for previous patches, set this on declaration for consistency (same below).
>
>> +static ssize_t plane_supported_color_ranges_store(struct config_item *item,
>> + const char *page, size_t count)
>> +{
>> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
>> + int ret, val = 0;
>> +
>> + ret = kstrtouint(page, 10, &val);
>> + if (ret)
>> + return ret;
>> +
>> + /* Should be a supported value */
>> + if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
>> + BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
>> + return -EINVAL;
>> + /* Should at least provide one color range */
>> + if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
>> + BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
>> + return -EINVAL;
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + /* Ensures that the default rotation is included in supported rotation */
>
> Oh no, that comment again! :-)
>
>> +static ssize_t plane_default_color_range_store(struct config_item *item,
>> + const char *page, size_t count)
>> +{
>> + struct vkms_configfs_plane *plane = plane_item_to_vkms_configfs_plane(item);
>> + int ret, val = 0;
>> +
>> + ret = kstrtouint(page, 10, &val);
>> + if (ret)
>> + return ret;
>> +
>> + /* Should be a supported value */
>> + if (val & ~(BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
>> + BIT(DRM_COLOR_YCBCR_FULL_RANGE)))
>> + return -EINVAL;
>> + /* Should at least provide one color range */
>> + if ((val & (BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
>> + BIT(DRM_COLOR_YCBCR_FULL_RANGE))) == 0)
>> + return -EINVAL;
>
> As in patch 12, replace this with is_power_of_2() to check that exactly one
> bit is set.
And as the previous patch, this code is simply wrong...
I shoud check if val is one of DRM_COLOR_YCBCR_LIMITED_RANGE /
DRM_COLOR_YCBCR_FULL_RANGE
Thanks
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs for plane format
2025-10-29 14:36 ` [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-19 17:07 ` Luca Ceresoli
2025-12-19 17:28 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:07 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> To allow the userspace to test many hardware configuration, introduce a
> new interface to configure the available formats per planes. VKMS supports
> multiple formats, so the userspace can choose any combination.
>
> The supported formats are configured by writing the fourcc code in
> supported_formats:
> # enable AR24 format
> echo '+AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
> # disable AR24 format
> echo '-AR24' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
> # enable all format supported by VKMS
> echo '+*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
> # disable all formats
> echo '-*' > /config/vkms/DEVICE_1/planes/PLANE_1/supported_formats
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/Documentation/gpu/vkms.rst
> +++ b/Documentation/gpu/vkms.rst
> @@ -109,6 +109,11 @@ Planes have 8 configurable attributes:
> must be set too.
> - default_color_range: Default color range presented to the userspace, same
> values as supported_color_range
> +- supported_formats: List of supported formats for this plane. To add a new item in the
> + list, write it using a plus its fourcc code: +XR24
^ and
> +++ b/drivers/gpu/drm/vkms/tests/vkms_configfs_test.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include "linux/printk.h"
> +#include <kunit/test.h>
> +
> +#include "../vkms_configfs.h"
> +
> +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
> +
> +/**
> + * struct vkms_configfs_parse_format_case - Store test case for format parsing
> + * @data: Contains the string to parse
> + * @data_len: data len
> + * @expected_len: expected len of the matched format
> + * @expected_offset: expected offset in the string for the parsed format
> + */
> +struct vkms_configfs_parse_format_case {
> + const char *data;
This is a string, why not calling it 'string', or 'str'?
> +struct vkms_configfs_parse_format_case vkms_configfs_parse_format_test_cases[] = {
> + {
> + .data = "+RG24",
> + .data_len = 6,
> + .expected_len = 5,
> + .expected_offset = 0,
> + }, {
> + .data = "-RG24",
> + .data_len = 6,
> + .expected_len = 5,
> + .expected_offset = 0
> + }, {
> + .data = " -RG24",
> + .data_len = 8,
> + .expected_len = 5,
> + .expected_offset = 2
> + }, {
> + .data = "+*",
> + .data_len = 3,
> + .expected_len = 2,
> + .expected_offset = 0
> + }, {
> + .data = "-RG24+RG24",
> + .data_len = 11,
> + .expected_len = 5,
> + .expected_offset = 0
> + }, {
> + .data = "-R1+RG24",
> + .data_len = 9,
> + .expected_len = 3,
> + .expected_offset = 0
> + }, {
> + .data = "\n-R1",
> + .data_len = 5,
> + .expected_len = 3,
> + .expected_offset = 1
> + }, {
> + .data = "-R1111",
> + .data_len = 3,
The string is longer than 3 chars, is this intended?
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> +static ssize_t plane_supported_formats_store(struct config_item *item,
> + const char *page, size_t count)
> +{
> + struct vkms_configfs_plane *plane;
> +
> + plane = plane_item_to_vkms_configfs_plane(item);
> + int ret = 0;
> + const char *end_page = page + count;
> +
> + scoped_guard(mutex, &plane->dev->lock) {
> + while (1) {
> + char *tmp;
> + char fmt[4] = {' ', ' ', ' ', ' '};
> + int len = vkms_configfs_parse_next_format(page, end_page, &tmp);
> +
> + // No fourcc code found
> + if (len <= 1)
> + break;
> +
> + page = tmp + len;
> + memcpy(tmp, &fmt[1], min(len - 1, 4));
Should this be instead: fmt tmp
?
Also I think it would be good to reject strings longer than 4 chars (len >
5), because they cannot br fourccs.
Otherwise looks good.
BTW, I feel your pain in implementing the parsing!
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos
2025-10-29 14:36 ` [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Currently planes are rendered in creation order. This is not an issue, but
> with the introduction of new zpos configuration, it is required to
> properly render planes.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property
2025-10-29 14:36 ` [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> VKMS can render plane in any order. Introduce the appropriate
> configuration.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/tests/vkms_config_test.c
> +++ b/drivers/gpu/drm/vkms/tests/vkms_config_test.c
> @@ -606,6 +609,94 @@ static void vkms_config_test_valid_plane_color_range(struct kunit *test)
> vkms_config_destroy(config);
> }
>
> +static void vkms_config_test_valid_plane_zpos(struct kunit *test)
> +{
> + struct vkms_config *config;
> + struct vkms_config_plane *plane_cfg;
> +
> + config = vkms_config_default_create(false, false, false);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config);
> +
> + plane_cfg = get_first_plane(config);
> +
> + /* Valid, all color range supported */
> + plane_cfg = get_first_plane(config);
These 2 lines should be removed? Invalid comment and duplicated line,
apparently.
> + /* Valid, zpos disabled */
> + vkms_config_plane_set_zpos_enabled(plane_cfg, false);
> + vkms_config_plane_set_zpos_mutable(plane_cfg, false);
> + vkms_config_plane_set_zpos_initial(plane_cfg, 0);
> + vkms_config_plane_set_zpos_min(plane_cfg, 0);
> + vkms_config_plane_set_zpos_max(plane_cfg, 0);
> + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
> +
> + /* Valid, zpos disabled, min/max are ignored */
> + vkms_config_plane_set_zpos_enabled(plane_cfg, false);
> + vkms_config_plane_set_zpos_mutable(plane_cfg, false);
> + vkms_config_plane_set_zpos_initial(plane_cfg, 8);
> + vkms_config_plane_set_zpos_min(plane_cfg, 3);
> + vkms_config_plane_set_zpos_max(plane_cfg, 2);
> + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
> +
> + /* Valid, zpos enabled but initial value is out of range */
> + vkms_config_plane_set_zpos_enabled(plane_cfg, true);
> + vkms_config_plane_set_zpos_mutable(plane_cfg, false);
> + vkms_config_plane_set_zpos_initial(plane_cfg, 1);
> + vkms_config_plane_set_zpos_min(plane_cfg, 0);
> + vkms_config_plane_set_zpos_max(plane_cfg, 0);
> + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
vkms_config_valid_plane_zpos() returns OK if mutable is false. So the test
is correct but the comment is misleading. It should read:
/* Valid, zpos enabled but mutable disabled */
> + /* Valid, zpos enabled with valid initial value */
> + vkms_config_plane_set_zpos_enabled(plane_cfg, true);
> + vkms_config_plane_set_zpos_mutable(plane_cfg, false);
> + vkms_config_plane_set_zpos_initial(plane_cfg, 0);
> + vkms_config_plane_set_zpos_min(plane_cfg, 0);
> + vkms_config_plane_set_zpos_max(plane_cfg, 0);
> + KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config));
Here the comment is misleading as well, it should still be:
/* Valid, zpos enabled but mutable disabled */
> --- a/drivers/gpu/drm/vkms/vkms_config.c
> +++ b/drivers/gpu/drm/vkms/vkms_config.c
> @@ -249,6 +252,37 @@ bool vkms_config_valid_plane_color_range(const struct vkms_config *config,
> }
> EXPORT_SYMBOL_IF_KUNIT(vkms_config_valid_plane_color_range);
>
> +VISIBLE_IF_KUNIT
> +bool vkms_config_valid_plane_zpos(const struct vkms_config *config,
> + const struct vkms_config_plane *plane_cfg)
> +{
> + struct drm_device *dev = config->dev ? &config->dev->drm : NULL;
> +
> + if (!vkms_config_plane_get_zpos_enabled(plane_cfg) ||
> + !vkms_config_plane_get_zpos_mutable(plane_cfg))
> + return true;
> +
> + if (vkms_config_plane_get_zpos_initial(plane_cfg) >
> + vkms_config_plane_get_zpos_max(plane_cfg)) {
> + drm_info(dev, "Configured initial zpos value bigger than zpos max\n");
> + return false;
> + }
> +
> + if (vkms_config_plane_get_zpos_max(plane_cfg) <
> + vkms_config_plane_get_zpos_min(plane_cfg)) {
> + drm_info(dev, "Configured zpos max value smaller than zpos min\n");
> + return false;
> + }
> +
> + if (vkms_config_plane_get_zpos_initial(plane_cfg) <
> + vkms_config_plane_get_zpos_min(plane_cfg)) {
> + drm_info(dev, "Configured initial zpos value smaller than zpos min\n");
> + return false;
> + }
Maybe merge the if(initial < min) and the if(initial > max) into a single
if(), to avoid unnecessarily detailed error reporting. Not a strong request
however, up to you.
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -51,6 +51,11 @@ struct vkms_config {
> * @supported_color_ranges: Color range that this plane will support
> * @supported_formats: List of supported formats
> * @supported_formats_count: Length of @supported_formats
> + * @zpos_enabled: Enable or disable the zpos property
> + * @zpos_mutable: Make the zpos property mutable or not (ignored if @zpos_enabled is false)
> + * @zpos_initial: Initial value for zpos property (ignored if @zpos_enabled is false)
> + * @zpos_min: Minimal value for zpos property (ignored if @zpos_enabled is false)
> + * @zpos_max: Maximal value for zpos property (ignored if @zpos_enabled is false)
> */
> struct vkms_config_plane {
> struct list_head link;
[...]
> +/**
> + * vkms_config_plane_set_zpos_min() - Set the minimum zpos value
> + * @plane_cfg: Plane configuration to modify
> + * @zpos_min: Minimum zpos value
> + */
> +static inline
> +void vkms_config_plane_set_zpos_min(struct vkms_config_plane *plane_cfg,
> + unsigned int zpos_min)
> +{
> + plane_cfg->zpos_min = zpos_min;
> +}
> +
> +/**
> + * vkms_config_plane_set_zpos_max() - Set the maximum zpos value
> + * @plane_cfg: Plane configuration to modify
> + * @zpos_max: Maximum zpos value
> + *
> + * Sets the maximum allowed value for the zpos property. This setting is
> + * ignored if zpos is disabled.
These two lines are not present for the other functions. I suggest removing
them here, the kdoc in struct vkms_config is already saying so.
> +/**
> + * vkms_config_plane_get_zpos_mutable() - Check if zpos property is mutable
> + * @plane_cfg: Plane configuration to check
> + *
> + * Returns:
> + * True if the zpos property is mutable for this plane, false otherwise.
> + * Returns false if zpos is disabled.
This last line is correct? There is no check in the code. I think it's OK
to leave the code as is and remove this line.
> + */
> +static inline
> +bool vkms_config_plane_get_zpos_mutable(const struct vkms_config_plane *plane_cfg)
> +{
> + return plane_cfg->zpos_mutable;
> +}
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs for plane zpos property
2025-10-29 14:36 ` [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Modern compositor rely on zpos management to offload some processing to
> deticated hardware. In order to test multiple configurations, add zpos
> configuration to configFS.
>
> Introduce multiple attributes to configure zpos:
> - zpos_enabled - Create or not the zpos property. If not created, the zpos
> is undefined.
> - zpos_mutable - If the zpos property is created, allow or not the
> userspace to modify it
> - zpos_initial - Initial value for zpos property. Must be between zpos_min
> and zpos_max
> - zpos_min - Minimal zpos value for this plane. Must be smaller than or
Minimum
> equals to zpos_max
equal
or, more simply:
- zpos_min - Minimal zpos value for this plane. Must be <= zpos_max
> - zpos_max - Maximal zpos value for this plane. Must be greater than or
Maximum
> equals to zpos_min
As above
> --- a/Documentation/gpu/vkms.rst
> +++ b/Documentation/gpu/vkms.rst
> @@ -114,6 +114,13 @@ Planes have 9 configurable attributes:
> To remove a format, use a minus and its fourcc: -XR24
> To add all formats use +*
> To remove all formats, use -*
> +- zpos_enabled: Enable or not the zpos property: 1 enable, 0 disable
> +- zpos_mutable: Create the zpos property as a mutable or imutable property: 1 mutable,
> + 0 disable. No effect if zpos_enabled is not set.
s/disable/immutable/
> +- zpos_initial: Set the initial zpos value. Must be between zpos_min and zpos_max. No
> + effect if zpos_enabled is not set.
> +- zpos_min: Set the minimal zpos value. No effect if zpos_enabled is not set.
minimum
> +- zpos_max: Set the maximal zpos value. No effect if zpos_enabled is not set.
maximum
With those fixed:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type
2025-10-29 14:36 ` [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> In order to emulate connector-specific behavior, add connector type
> configuration.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs for connector type
2025-10-29 14:36 ` [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
> Add a new attribute to connector to change its type. This is mostly
> cosmetic and don't have direct effect in VKMS behavior.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name
2025-10-29 14:37 ` [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> Export drm_get_colorspace_name so it could be used by VKMS
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace
2025-10-29 14:37 ` [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace Louis Chauvet
@ 2025-12-19 17:08 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 17:08 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> To emulate some HDR features of displays, it is required to expose some
> properties on HDMI, eDP and DP connectors.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -241,6 +246,31 @@ struct vkms_config *vkms_config_default_create(bool enable_cursor,
> */
> void vkms_config_destroy(struct vkms_config *config);
>
> +/**
> + * vkms_config_connector_set_supported_colorspaces() - Set the supported colorspaces for a connector
> + * @connector_cfg: Connector configuration to modify
> + * @supported_colorspaces: Bitmask of supported colorspaces (DRM_COLOR_YCBCR_*)
^^^^^^^^^^^^^^^^
You're dealing with colorpsaces, so this should be DRM_MODE_COLORIMETRY_*.
> + */
> +static inline void
> +vkms_config_connector_set_supported_colorspaces(struct vkms_config_connector *connector_cfg,
> + u32 supported_colorspaces)
> +{
> + connector_cfg->supported_colorspaces = supported_colorspaces;
> +}
> +
> +/**
> + * vkms_config_connector_get_supported_colorspaces() - Get the supported colorspaces for a connector
> + * @connector_cfg: Connector configuration to query
> + *
> + * Returns:
> + * Bitmask of supported colorspaces (DRM_COLOR_YCBCR_*)
Same here.
With those fixed you can add:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs for plane format
2025-12-19 17:07 ` Luca Ceresoli
@ 2025-12-19 17:28 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 17:28 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
[...]
>> + .expected_offset = 1
>> + }, {
>> + .data = "-R1111",
>> + .data_len = 3,
>
> The string is longer than 3 chars, is this intended?
Yes, I wanted to ensure that the algorithm stop at data_len and not \0
>> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
>> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
>
>> +static ssize_t plane_supported_formats_store(struct config_item *item,
>> + const char *page, size_t count)
>> +{
>> + struct vkms_configfs_plane *plane;
>> +
>> + plane = plane_item_to_vkms_configfs_plane(item);
>> + int ret = 0;
>> + const char *end_page = page + count;
>> +
>> + scoped_guard(mutex, &plane->dev->lock) {
>> + while (1) {
>> + char *tmp;
>> + char fmt[4] = {' ', ' ', ' ', ' '};
>> + int len = vkms_configfs_parse_next_format(page, end_page, &tmp);
>> +
>> + // No fourcc code found
>> + if (len <= 1)
>> + break;
>> +
>> + page = tmp + len;
>> + memcpy(tmp, &fmt[1], min(len - 1, 4));
> Should this be instead: fmt tmp
> ?
memcpy(void *to, const void *from
Make sense yes... My tests were not sufficient :(
I will triple check this before sending the v3
> Also I think it would be good to reject strings longer than 4 chars (len >
> 5), because they cannot br fourccs.
I will add this limitation.
Thanks!
> Otherwise looks good.
>
> BTW, I feel your pain in implementing the parsing!
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs for plane color encoding
2025-12-19 16:40 ` Louis Chauvet
@ 2025-12-19 17:51 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 17:51 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
>>> +
>>> + ret = kstrtouint(page, 10, &val);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + /* Should be a supported value */
>>> + if (val & ~(BIT(DRM_COLOR_YCBCR_BT601) |
>>> + BIT(DRM_COLOR_YCBCR_BT709) |
>>> + BIT(DRM_COLOR_YCBCR_BT2020)))
>>> + return -EINVAL;
>>> + /* Should at least provide one color range */
>>> + if ((val & (BIT(DRM_COLOR_YCBCR_BT601) |
>>> + BIT(DRM_COLOR_YCBCR_BT709) |
>>> + BIT(DRM_COLOR_YCBCR_BT2020))) == 0)
>>> + return -EINVAL;
>>
>> Shouldn't you check that exactly one bit is set? As in patch 9.
>
> Because this code is wrong... the default rotation should be
> DRM_COLOR_YCBCR_BT601 / DRM_COLOR_YCBCR_BT709 / DRM_COLOR_YCBCR_BT2020
> not a bitfield...
And after fixing this, I think I will keep bitmask with only one bit set
so supported_color_encodings and default_color_encoding will have
exactly the same values. Same for color ranges. Thanks for the report!
>
>>> +
>>> + scoped_guard(mutex, &plane->dev->lock) {
>>> + /* Ensures that the default rotation is included in
>>> supported rotation */
>>> + if (plane->dev->enabled)
>>> + return -EINVAL;
>>
>> As before, wrong comment.
>>
>> Luca
>>
>> --
>> Luca Ceresoli, Bootlin
>> Embedded Linux and Kernel engineering
>> https://bootlin.com
>
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format
2025-12-19 14:55 ` Luca Ceresoli
@ 2025-12-19 18:31 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 18:31 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/19/25 15:55, Luca Ceresoli wrote:
> Hi Louis,
>
> On Wed Oct 29, 2025 at 3:36 PM CET, Louis Chauvet wrote:
>> VKMS driver supports all the pixel formats for planes, but for testing it
>> can be useful to only advertise few of them. This new configuration
>> interface will allow configuring the pixel format per planes.
>
> [...]
>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>> +int __must_check vkms_config_plane_add_format(struct vkms_config_plane *plane_cfg, u32 drm_format)
>> +{
>> + bool found = false;
>> +
>> + for (int i = 0; i < ARRAY_SIZE(vkms_supported_plane_formats); i++) {
>> + if (vkms_supported_plane_formats[i] == drm_format) {
>> + found = true;
>> + break;
>> + }
>> + }
>> +
>> + if (!found)
>> + return -EINVAL;
>> + for (unsigned int i = 0; i < plane_cfg->supported_formats_count; i++) {
>> + if (plane_cfg->supported_formats[i] == drm_format)
>> + return 0;
>> + }
>> + u32 *new_ptr = krealloc_array(plane_cfg->supported_formats,
>> + plane_cfg->supported_formats_count + 1,
>> + sizeof(*plane_cfg->supported_formats), GFP_KERNEL);
>> + if (!new_ptr)
>> + return -ENOMEM;
>> +
>> + plane_cfg->supported_formats = new_ptr;
>> + plane_cfg->supported_formats[plane_cfg->supported_formats_count] = drm_format;
>> + plane_cfg->supported_formats_count++;
>> +
>> + return 0;
>> +}
>
> This whole logic appears quite complex for what you need here. I suspect
> using the facilities in linux/bitmap.h would make your code simpler by
> allocating a (multi-)ulong array of
> ARRAY_SIZE(vkms_supported_plane_formats) bits. This would surely use less
> memory and avoid all reallocations, too.
I agree this look complex, but I need an array anyway to interface with
DRM core. If I use a bitmap, I would have to manage a mapping bit <=>
fourcc value, which would not be really simpler I think.
I will simplify it a little bit by extracting some helpers for v2:
int __must_check vkms_config_plane_add_format(struct vkms_config_plane
*plane_cfg, u32 drm_format) {
if (!supported_format(drm_format))
return -EINVAL;
if (already_present(drm_format))
return 0;
new_ptr = krealloc
[...]
}
If this is not sufficient, I will take a look at bitfield next year.
>> --- a/drivers/gpu/drm/vkms/vkms_config.h
>> +++ b/drivers/gpu/drm/vkms/vkms_config.h
>
>> +/**
>> + * vkms_config_plane_remove_format - Remove a specific format from a plane
>> + * @plane_cfg: Plane to remove the format to
>> + * @drm_format: Format to remove
>> + */
>> +void vkms_config_plane_remove_format(struct vkms_config_plane *plane_cfg, u32 drm_format);
>> +
>> +/**
>> + * vkms_config_plane_remove_all_formats - Remove all formast from a plane
> formats
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs for connector supported colorspace
2025-10-29 14:37 ` [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-19 18:56 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 18:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> Add the attribute supported_colorspaces to configure the supported
> colorspace of a connector. It will allows emulating some HDR features of
> displays. This feature is only supported for HDMI, DP and eDP connectors.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -1223,12 +1223,51 @@ static ssize_t connector_type_store(struct config_item *item,
> return count;
> }
>
> +static ssize_t connector_supported_colorspaces_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_connector *connector;
> + int type;
This variable name is not really intuitive. 'colorspaces' maybe?
With that change:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID
2025-10-29 14:37 ` [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID Louis Chauvet
@ 2025-12-19 18:56 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 18:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> Allows configuration of EDID for each connector.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> +/**
> + * vkms_config_connector_set_edid() - Set the EDID data for a connector
> + * @connector_cfg: Connector configuration to modify
> + * @edid: Pointer to the EDID data buffer
> + * @len: Length of the EDID data
> + *
> + * If @len is 0, the EDID data will be cleared. If memory allocation fails,
^
Adding "and @edid ignored" would be useful.
> static int vkms_conn_get_modes(struct drm_connector *connector)
> {
> - int count;
> + struct vkms_connector *vkms_connector = drm_connector_to_vkms_connector(connector);
> + const struct drm_edid *drm_edid = NULL;
> + int count = 0;
> + struct vkms_config_connector *context = NULL;
> + struct drm_device *dev = connector->dev;
> + struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
> + struct vkms_config_connector *connector_cfg;
>
> - /* Use the default modes list from DRM */
> - count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
> - drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
> + vkms_config_for_each_connector(vkmsdev->config, connector_cfg) {
> + if (connector_cfg->connector == vkms_connector)
> + context = connector_cfg;
You can add a break statement here to avoid keeping on looping after the
connector has been found.
With the above two changes:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs for connector EDID
2025-10-29 14:37 ` [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs " Louis Chauvet
@ 2025-12-19 18:56 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 18:56 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> Introduce new attributes to configure EDID of a connector:
> - edid_enable - chose if the connector will have an EDD or not
EDID
> - edid - raw edid content
>
> Due to limitation of ConfigFS, the max len of EDID is PAGE_SIZE (4kB on
> x86), it should be sufficient for many tests. One possible evolution is
> using a ConfigFS blob to allow bigger EDID.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
With that fixed:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector
2025-10-29 14:37 ` [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector Louis Chauvet
@ 2025-12-19 18:57 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 18:57 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> In order to prepare for dynamic connector configuration, we need to store
> if a connector is dynamic and if it is enabled.
>
> The two new vkms_config_connector fields will helps for that.
>
> Co-developed-by: José Expósito <jose.exposito89@gmail.com>
> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_config.h
> +++ b/drivers/gpu/drm/vkms/vkms_config.h
> @@ -130,6 +130,8 @@ struct vkms_config_encoder {
> * @link: Link to the others connector in vkms_config
> * @type: Store the type of connector using DRM_MODE_CONNECTOR_* values
> * @config: The vkms_config this connector belongs to
> + * @dynamic: Store if a connector should be created with drm_connector_dynamic_init
> + * @enabled: If @dynamic, this means that the correct is currently registered in drm
^^^^^^^
"connector", I guess.
With that fixed:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
2025-10-29 14:37 ` [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static Louis Chauvet
@ 2025-12-19 18:58 ` Luca Ceresoli
2025-12-19 19:11 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 18:58 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> With the introduction of dynamic connectors we will have two way of
> initializing a VKMS connector. Rename the current function to clarify
> the case.
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_connector.h
> +++ b/drivers/gpu/drm/vkms/vkms_connector.h
> @@ -4,6 +4,7 @@
> #define _VKMS_CONNECTOR_H_
>
> #include "vkms_drv.h"
> +#include "vkms_config.h"
Why? Maybe this is for another patch in the series?
With that line removed:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
2025-12-19 18:58 ` Luca Ceresoli
@ 2025-12-19 19:11 ` Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
0 siblings, 1 reply; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 19:11 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/19/25 19:58, Luca Ceresoli wrote:
> On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
>> With the introduction of dynamic connectors we will have two way of
>> initializing a VKMS connector. Rename the current function to clarify
>> the case.
>>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
>> --- a/drivers/gpu/drm/vkms/vkms_connector.h
>> +++ b/drivers/gpu/drm/vkms/vkms_connector.h
>> @@ -4,6 +4,7 @@
>> #define _VKMS_CONNECTOR_H_
>>
>> #include "vkms_drv.h"
>> +#include "vkms_config.h"
>
> Why? Maybe this is for another patch in the series?
This line is useful, I use struct vkms_config_connector
But I agree, this should be a separate patch.
> With that line removed:
>
> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static
2025-12-19 19:11 ` Louis Chauvet
@ 2025-12-19 20:47 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 20:47 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Fri Dec 19, 2025 at 8:11 PM CET, Louis Chauvet wrote:
>
>
> On 12/19/25 19:58, Luca Ceresoli wrote:
>> On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
>>> With the introduction of dynamic connectors we will have two way of
>>> initializing a VKMS connector. Rename the current function to clarify
>>> the case.
>>>
>>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>>
>>> --- a/drivers/gpu/drm/vkms/vkms_connector.h
>>> +++ b/drivers/gpu/drm/vkms/vkms_connector.h
>>> @@ -4,6 +4,7 @@
>>> #define _VKMS_CONNECTOR_H_
>>>
>>> #include "vkms_drv.h"
>>> +#include "vkms_config.h"
>>
>> Why? Maybe this is for another patch in the series?
>
> This line is useful, I use struct vkms_config_connector
> But I agree, this should be a separate patch.
Ah, I see, perhaps it is working currently because it is included by some
other .h files. Yes, better making that explicit (include what you use), or
use a forward declaration if you want. In any case, a separate patch
indeed.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization
2025-10-29 14:37 ` [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization Louis Chauvet
@ 2025-12-19 20:47 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 20:47 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> With the introduction of dynamic connector, some code will be shared
> between dynamic and static connectors. Extract this part to avoid code
> duplication
>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors
2025-10-29 14:37 ` [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors Louis Chauvet
@ 2025-12-19 20:47 ` Luca Ceresoli
0 siblings, 0 replies; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 20:47 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> In order to allow creating dynamic connector, add the required
> infrastructure in vkms_connector.
>
> Co-developed-by: José Expósito <jose.exposito89@gmail.com>
> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> [Louis Chauvet: use drm_atomic_helper_connector_reset instead of
> drm_mode_config_reset because connector is not yet registered]
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_connector.h
> +++ b/drivers/gpu/drm/vkms/vkms_connector.h
> @@ -34,4 +34,36 @@ struct vkms_connector *vkms_connector_init_static(struct vkms_device *vkmsdev,
> */
> void vkms_trigger_connector_hotplug(struct vkms_device *vkmsdev);
>
> +/**
> + * vkms_connector_hot_add() - Create a connector after the device is created
> + * @vkmsdev: Device to hot-add the connector to
> + * @connector_cfg: Connector's configuration
> + *
> + * Returns:
> + * The connector or an error on failure.
"A pointer to the newly created connector or a PTR_ERR on failure."
> + */
> +struct vkms_connector *vkms_connector_hot_add(struct vkms_device *vkmsdev,
> + struct vkms_config_connector *connector_cfg);
> +
> +/**
> + * vkms_connector_hot_remove() - Remove a connector after a device is created
Missing kdoc for @vkmsdev:
@vkmsdev: Device to containing the connector to be removed
> + * @connector: The connector to hot-remove
> + */
> +void vkms_connector_hot_remove(struct vkms_device *vkmsdev,
> + struct vkms_connector *connector);
With these changes:
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation
2025-10-29 14:37 ` [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation Louis Chauvet
@ 2025-12-19 20:47 ` Luca Ceresoli
2025-12-19 22:01 ` Louis Chauvet
0 siblings, 1 reply; 83+ messages in thread
From: Luca Ceresoli @ 2025-12-19 20:47 UTC (permalink / raw)
To: Louis Chauvet, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
> DRM allows the connector to be created after the device. To allows
> emulating this, add two configfs attributes to connector to allows this.
>
> Using the dynamic attribute you can set if a connector will be dynamic or
> not.
> Using the enabled attribute, you can set at runtime if a dynamic connector
> is present or not.
>
> Co-developed-by: José Expósito <jose.exposito89@gmail.com>
> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
> @@ -1215,8 +1223,10 @@ static ssize_t connector_type_store(struct config_item *item,
> }
>
> scoped_guard(mutex, &connector->dev->lock) {
> - if (connector->dev->enabled)
> - return -EINVAL;
> + if (connector->dev->enabled) {
> + if (connector_is_enabled(connector->config))
> + return -EBUSY;
> + }
You are changing from -EINVAL to -EBUSY. Why? Was -EINVAL wrong in the
first place?
And you can avoid the nested if:
if (connector->dev->enabled && connector_is_enabled(connector->config))
return -E<WHATEVER>;
> +static ssize_t connector_dynamic_show(struct config_item *item, char *page)
> +{
> + struct vkms_configfs_connector *connector;
> + bool enabled;
^^^^^^^
dynamic
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
* Re: [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation
2025-12-19 20:47 ` Luca Ceresoli
@ 2025-12-19 22:01 ` Louis Chauvet
0 siblings, 0 replies; 83+ messages in thread
From: Louis Chauvet @ 2025-12-19 22:01 UTC (permalink / raw)
To: Luca Ceresoli, Haneen Mohammed, Simona Vetter, Melissa Wen,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
jose.exposito89, Jonathan Corbet
Cc: victoria, sebastian.wick, thomas.petazzoni, dri-devel,
linux-kernel, linux-doc
On 12/19/25 21:47, Luca Ceresoli wrote:
> On Wed Oct 29, 2025 at 3:37 PM CET, Louis Chauvet wrote:
>> DRM allows the connector to be created after the device. To allows
>> emulating this, add two configfs attributes to connector to allows this.
>>
>> Using the dynamic attribute you can set if a connector will be dynamic or
>> not.
>> Using the enabled attribute, you can set at runtime if a dynamic connector
>> is present or not.
>>
>> Co-developed-by: José Expósito <jose.exposito89@gmail.com>
>> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
>> Signed-off-by: Louis Chauvet <louis.chauvet@bootlin.com>
>
>> --- a/drivers/gpu/drm/vkms/vkms_configfs.c
>> +++ b/drivers/gpu/drm/vkms/vkms_configfs.c
>
>> @@ -1215,8 +1223,10 @@ static ssize_t connector_type_store(struct config_item *item,
>> }
>>
>> scoped_guard(mutex, &connector->dev->lock) {
>> - if (connector->dev->enabled)
>> - return -EINVAL;
>> + if (connector->dev->enabled) {
>> + if (connector_is_enabled(connector->config))
>> + return -EBUSY;
>> + }
>
> You are changing from -EINVAL to -EBUSY. Why? Was -EINVAL wrong in the
> first place?
EINVAL was wrong in the first place, we try to remove EBUSY when you
can't do something because the device is already enabled and EINVAL when
the value is false.
>
> And you can avoid the nested if:
>
> if (connector->dev->enabled && connector_is_enabled(connector->config))
> return -E<WHATEVER>;
It is probably a remaining of previous implementation, thanks!
>> +static ssize_t connector_dynamic_show(struct config_item *item, char *page)
>> +{
>> + struct vkms_configfs_connector *connector;
>> + bool enabled;
> ^^^^^^^
> dynamic
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
^ permalink raw reply [flat|nested] 83+ messages in thread
end of thread, other threads:[~2025-12-19 22:01 UTC | newest]
Thread overview: 83+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-29 14:36 [PATCH RESEND v2 00/32] VKMS: Introduce multiple configFS attributes Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 01/32] drm/drm_mode_config: Add helper to get plane type name Louis Chauvet
2025-11-13 14:06 ` José Expósito
2025-11-17 11:28 ` Louis Chauvet
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 02/32] drm/vkms: Explicitly display plane type Louis Chauvet
2025-11-13 14:07 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 03/32] drm/vkms: Use enabled/disabled instead of 1/0 for debug Louis Chauvet
2025-11-13 14:09 ` José Expósito
2025-12-18 17:57 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 04/32] drm/vkms: Explicitly display connector status Louis Chauvet
2025-11-13 14:11 ` José Expósito
2025-12-18 17:56 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 05/32] drm/vkms: Introduce config for plane name Louis Chauvet
2025-11-13 14:17 ` José Expósito
2025-11-17 14:12 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 06/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-11-13 14:21 ` José Expósito
2025-11-17 9:56 ` Louis Chauvet
2025-12-18 17:58 ` Luca Ceresoli
2025-12-19 15:49 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 07/32] drm/blend: Get a rotation name from it's bitfield Louis Chauvet
2025-11-13 14:23 ` José Expósito
2025-12-18 17:58 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 08/32] drm/vkms: Introduce config for plane rotation Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 09/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 10/32] drm/drm_color_mgmt: Expose drm_get_color_encoding_name Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 11/32] drm/vkms: Introduce config for plane color encoding Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 12/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-12-19 16:40 ` Louis Chauvet
2025-12-19 17:51 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 13/32] drm/drm_color_mgmt: Expose drm_get_color_range_name Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 14/32] drm/vkms: Introduce config for plane color range Louis Chauvet
2025-12-18 17:59 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 15/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-18 18:00 ` Luca Ceresoli
2025-12-19 16:55 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 16/32] drm/vkms: Introduce config for plane format Louis Chauvet
2025-12-19 14:55 ` Luca Ceresoli
2025-12-19 18:31 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 17/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-19 17:07 ` Luca Ceresoli
2025-12-19 17:28 ` Louis Chauvet
2025-10-29 14:36 ` [PATCH RESEND v2 18/32] drm/vkms: Properly render plane using their zpos Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 19/32] drm/vkms: Introduce config for plane zpos property Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 20/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 21/32] drm/vkms: Introduce config for connector type Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:36 ` [PATCH RESEND v2 22/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 23/32] drm/connector: Export drm_get_colorspace_name Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 24/32] drm/vkms: Introduce config for connector supported colorspace Louis Chauvet
2025-12-19 17:08 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 25/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 26/32] drm/vkms: Introduce config for connector EDID Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 27/32] drm/vkms: Introduce configfs " Louis Chauvet
2025-12-19 18:56 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 28/32] drm/vkms: Store the enabled/disabled status for connector Louis Chauvet
2025-12-19 18:57 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 29/32] drm/vkms: Rename vkms_connector_init to vkms_connector_init_static Louis Chauvet
2025-12-19 18:58 ` Luca Ceresoli
2025-12-19 19:11 ` Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 30/32] drm/vkms: Extract common code for connector initialization Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 31/32] drm/vkms: Allow to hot-add connectors Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-10-29 14:37 ` [PATCH RESEND v2 32/32] drm/vkms: Introduce configfs for dynamic connector creation Louis Chauvet
2025-12-19 20:47 ` Luca Ceresoli
2025-12-19 22:01 ` Louis Chauvet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).