[PATCH i-g-t v3 2/2] tests/kms_properties: add sanity checks for properties
Dmitry Baryshkov
dmitry.baryshkov at linaro.org
Thu Oct 31 23:14:06 UTC 2024
Provide a simple framework for running sanity checks on properties. As a
start, implement just immutability checks.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
---
tests/kms_properties.c | 102 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 87 insertions(+), 15 deletions(-)
diff --git a/tests/kms_properties.c b/tests/kms_properties.c
index be62e522166f..57f07e69909a 100644
--- a/tests/kms_properties.c
+++ b/tests/kms_properties.c
@@ -416,8 +416,72 @@ static void test_object_invalid_properties(igt_display_t *display,
test_invalid_properties(display->drm_fd, id, type, output->id, DRM_MODE_OBJECT_CONNECTOR, atomic);
}
+enum prop_imm_flags {
+ IMMUTABLE_REQ,
+ IMMUTABLE_IF_SINGLE_VALUE,
+};
+
+static const struct {
+ uint32_t obj_type;
+ const char *name;
+ enum prop_imm_flags flags;
+} prop_settings[] = {
+ /* generic */
+ { DRM_MODE_OBJECT_CONNECTOR, "EDID", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "PATH", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "TILE", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "WRITEBACK_PIXEL_FORMATS", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "non-desktop", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "panel orientation" ,IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "privacy-screen hw-state", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "subconnector", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "suggested X", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "suggested Y", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CONNECTOR, "vrr_capable", IMMUTABLE_REQ },
+
+ { DRM_MODE_OBJECT_CRTC, "DEGAMMA_LUT_SIZE", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_CRTC, "GAMMA_LUT_SIZE", IMMUTABLE_REQ },
+
+ { DRM_MODE_OBJECT_PLANE, "IN_FORMATS", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_PLANE, "SIZE_HINTS", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_PLANE, "type", IMMUTABLE_REQ },
+ { DRM_MODE_OBJECT_PLANE, "zpos", IMMUTABLE_IF_SINGLE_VALUE },
+
+ /* driver-specific */
+ { DRM_MODE_OBJECT_CONNECTOR, "hotplug_mode_update", IMMUTABLE_REQ }, // qxl, vmwgfx
+ { DRM_MODE_OBJECT_CONNECTOR, "implicit_placement", IMMUTABLE_REQ }, // vmwgfx
+ { DRM_MODE_OBJECT_PLANE, "AMD_PLANE_BLEND_LUT_SIZE", IMMUTABLE_REQ }, // amdgpu
+ { DRM_MODE_OBJECT_PLANE, "AMD_PLANE_DEGAMMA_LUT_SIZE", IMMUTABLE_REQ }, // amdgpu
+ { DRM_MODE_OBJECT_PLANE, "AMD_PLANE_LUT3D_SIZE", IMMUTABLE_REQ }, // amdgpu
+ { DRM_MODE_OBJECT_PLANE, "AMD_PLANE_SHAPER_LUT_SIZE", IMMUTABLE_REQ }, // amdgpu
+};
+
+static void validate_prop_immutable(const struct drm_mode_get_property *prop,
+ uint32_t obj_type, bool single_value)
+{
+ bool immutable = prop->flags & DRM_MODE_PROP_IMMUTABLE;
+ int i;
+
+ igt_debug("Testing property \"%s\"\n", prop->name);
+
+ for (i = 0; i < ARRAY_SIZE(prop_settings); i++) {
+ if (prop_settings[i].obj_type == obj_type &&
+ !strcmp(prop_settings[i].name, prop->name))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(prop_settings)) {
+ igt_assert(!immutable);
+ return;
+ }
+
+ igt_assert(immutable || prop_settings[i].flags != IMMUTABLE_REQ);
+ igt_assert(immutable || !single_value ||
+ prop_settings[i].flags != IMMUTABLE_IF_SINGLE_VALUE);
+}
+
static void validate_range_prop(const struct drm_mode_get_property *prop,
- uint64_t value)
+ uint64_t value, uint32_t obj_type)
{
const uint64_t *values = from_user_pointer(prop->values_ptr);
bool is_unsigned = prop->flags & DRM_MODE_PROP_RANGE;
@@ -425,6 +489,8 @@ static void validate_range_prop(const struct drm_mode_get_property *prop,
igt_assert_eq(prop->count_values, 2);
igt_assert_eq(prop->count_enum_blobs, 0);
+ validate_prop_immutable(prop, obj_type, values[0] == values[1]);
+
if (is_unsigned) {
igt_assert_lte_u64(values[0], values[1]);
igt_assert_lte_u64(values[0], value);
@@ -456,13 +522,14 @@ static void validate_enums(const struct drm_mode_get_property *prop)
}
static void validate_enum_prop(const struct drm_mode_get_property *prop,
- uint64_t value)
+ uint64_t value, uint32_t obj_type)
{
const uint64_t *values = from_user_pointer(prop->values_ptr);
int i;
igt_assert_lte(1, prop->count_values);
igt_assert_eq(prop->count_enum_blobs, prop->count_values);
+ validate_prop_immutable(prop, obj_type, prop->count_values == 1);
for (i = 0; i < prop->count_values; i++) {
if (value == values[i])
@@ -474,13 +541,14 @@ static void validate_enum_prop(const struct drm_mode_get_property *prop,
}
static void validate_bitmask_prop(const struct drm_mode_get_property *prop,
- uint64_t value)
+ uint64_t value, uint32_t obj_type)
{
const uint64_t *values = from_user_pointer(prop->values_ptr);
uint64_t mask = 0;
igt_assert_lte(1, prop->count_values);
igt_assert_eq(prop->count_enum_blobs, prop->count_values);
+ validate_prop_immutable(prop, obj_type, prop->count_values == 1);
for (int i = 0; i < prop->count_values; i++) {
igt_assert_lte_u64(values[i], 63);
@@ -495,7 +563,7 @@ static void validate_bitmask_prop(const struct drm_mode_get_property *prop,
static void validate_blob_prop(int fd,
const struct drm_mode_get_property *prop,
- uint64_t value)
+ uint64_t value, uint32_t obj_type)
{
struct drm_mode_get_blob blob;
@@ -509,6 +577,8 @@ static void validate_blob_prop(int fd,
igt_assert_lte_u64(value, 0xffffffff);
+ validate_prop_immutable(prop, obj_type, false);
+
/*
* Immutable blob properties can have value==0.
* Happens for example with the "EDID" property
@@ -526,7 +596,7 @@ static void validate_blob_prop(int fd,
static void validate_object_prop(int fd,
const struct drm_mode_get_property *prop,
- uint64_t value)
+ uint64_t value, uint32_t obj_type)
{
const uint64_t *values = from_user_pointer(prop->values_ptr);
struct drm_mode_crtc crtc;
@@ -536,6 +606,7 @@ static void validate_object_prop(int fd,
igt_assert_eq(prop->count_enum_blobs, 0);
igt_assert_lte_u64(value, 0xffffffff);
+ validate_prop_immutable(prop, obj_type, value == 0);
switch (values[0]) {
case DRM_MODE_OBJECT_CRTC:
@@ -560,7 +631,7 @@ static void validate_object_prop(int fd,
static void validate_property(int fd,
const struct drm_mode_get_property *prop,
- uint64_t value, bool atomic)
+ uint64_t value, bool atomic, uint32_t obj_type)
{
uint32_t flags = prop->flags;
uint32_t legacy_type = flags & DRM_MODE_PROP_LEGACY_TYPE;
@@ -581,16 +652,16 @@ static void validate_property(int fd,
switch (legacy_type) {
case DRM_MODE_PROP_RANGE:
- validate_range_prop(prop, value);
+ validate_range_prop(prop, value, obj_type);
break;
case DRM_MODE_PROP_ENUM:
- validate_enum_prop(prop, value);
+ validate_enum_prop(prop, value, obj_type);
break;
case DRM_MODE_PROP_BITMASK:
- validate_bitmask_prop(prop, value);
+ validate_bitmask_prop(prop, value, obj_type);
break;
case DRM_MODE_PROP_BLOB:
- validate_blob_prop(fd, prop, value);
+ validate_blob_prop(fd, prop, value, obj_type);
break;
default:
igt_assert_eq(legacy_type, 0);
@@ -598,17 +669,18 @@ static void validate_property(int fd,
switch (ext_type) {
case DRM_MODE_PROP_OBJECT:
- validate_object_prop(fd, prop, value);
+ validate_object_prop(fd, prop, value, obj_type);
break;
case DRM_MODE_PROP_SIGNED_RANGE:
- validate_range_prop(prop, value);
+ validate_range_prop(prop, value, obj_type);
break;
default:
igt_assert_eq(ext_type, 0);
}
}
-static void validate_prop(int fd, uint32_t prop_id, uint64_t value, bool atomic)
+static void validate_prop(int fd, uint32_t prop_id, uint64_t value,
+ bool atomic, uint32_t obj_type)
{
struct drm_mode_get_property prop;
struct drm_mode_property_enum *enums = NULL;
@@ -641,7 +713,7 @@ static void validate_prop(int fd, uint32_t prop_id, uint64_t value, bool atomic)
for (int i = 0; i < prop.count_enum_blobs; i++)
igt_assert_neq_u64(enums[i].value, 0x5c5c5c5c5c5c5c5cULL);
- validate_property(fd, &prop, value, atomic);
+ validate_property(fd, &prop, value, atomic, obj_type);
free(values);
free(enums);
@@ -679,7 +751,7 @@ static void validate_props(int fd, uint32_t obj_type, uint32_t obj_id, bool atom
igt_assert(properties.count_props == count);
for (int i = 0; i < count; i++)
- validate_prop(fd, props[i], values[i], atomic);
+ validate_prop(fd, props[i], values[i], atomic, obj_type);
free(values);
free(props);
--
2.45.2
More information about the igt-dev
mailing list