From 8af74298b9cae6e149b59375919f968e0523de97 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 18:17:22 +0100 Subject: tests: s/core_prop_blob/kms_prop_blob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a kms test, name it accordingly. Also sort the build lists while at it, one test got misplaced. Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- tests/kms_prop_blob.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 tests/kms_prop_blob.c (limited to 'tests/kms_prop_blob.c') diff --git a/tests/kms_prop_blob.c b/tests/kms_prop_blob.c new file mode 100644 index 00000000..0a2004c3 --- /dev/null +++ b/tests/kms_prop_blob.c @@ -0,0 +1,330 @@ +/* + * Copyright © 2014-2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Damien Lespiau + * Daniel Stone + */ + +#include "igt.h" +#include +#include +#include +#include + +IGT_TEST_DESCRIPTION("Tests behaviour of mass-data 'blob' properties."); + +static const struct drm_mode_modeinfo test_mode_valid = { + .clock = 1234, + .hdisplay = 640, + .hsync_start = 641, + .hsync_end = 642, + .htotal = 643, + .hskew = 0, + .vdisplay = 480, + .vsync_start = 481, + .vsync_end = 482, + .vtotal = 483, + .vscan = 0, + .vrefresh = 60000, + .flags = 0, + .type = 0, + .name = "FROMUSER", +}; + + +#define ioctl_or_ret_errno(fd, ioc, ioc_data) { \ + if (drmIoctl(fd, ioc, ioc_data) != 0) \ + return errno; \ +} + +static void igt_require_propblob(int fd) +{ + struct drm_mode_create_blob c; + struct drm_mode_destroy_blob d; + uint32_t blob_data; + c.data = (uintptr_t) &blob_data; + c.length = sizeof(blob_data); + + igt_require(drmIoctl(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &c) == 0); + d.blob_id = c.blob_id; + igt_require(drmIoctl(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &d) == 0); +} + +static int +validate_prop(int fd, uint32_t prop_id) +{ + struct drm_mode_get_blob get; + struct drm_mode_modeinfo ret_mode; + + get.blob_id = prop_id; + get.length = 0; + get.data = (uintptr_t) 0; + ioctl_or_ret_errno(fd, DRM_IOCTL_MODE_GETPROPBLOB, &get); + + if (get.length != sizeof(test_mode_valid)) + return ENOMEM; + + get.data = (uintptr_t) &ret_mode; + ioctl_or_ret_errno(fd, DRM_IOCTL_MODE_GETPROPBLOB, &get); + + if (memcmp(&ret_mode, &test_mode_valid, sizeof(test_mode_valid)) != 0) + return EINVAL; + + return 0; +} + +static uint32_t +create_prop(int fd) +{ + struct drm_mode_create_blob create; + + create.length = sizeof(test_mode_valid); + create.data = (uintptr_t) &test_mode_valid; + + do_ioctl(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create); + igt_assert_neq_u32(create.blob_id, 0); + + return create.blob_id; +} + +static int +destroy_prop(int fd, uint32_t prop_id) +{ + struct drm_mode_destroy_blob destroy; + + destroy.blob_id = prop_id; + ioctl_or_ret_errno(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); + + return 0; +} + +static void +test_validate(int fd) +{ + struct drm_mode_create_blob create; + struct drm_mode_get_blob get; + char too_small[32]; + uint32_t prop_id; + + memset(too_small, 0, sizeof(too_small)); + + /* Outlandish size. */ + create.length = 0x10000; + create.data = (uintptr_t) &too_small; + do_ioctl_err(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create, EFAULT); + + /* Outlandish address. */ + create.length = sizeof(test_mode_valid); + create.data = (uintptr_t) 0xdeadbeee; + do_ioctl_err(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create, EFAULT); + + /* When we pass an incorrect size, the kernel should correct us. */ + prop_id = create_prop(fd); + get.blob_id = prop_id; + get.length = sizeof(too_small); + get.data = (uintptr_t) too_small; + do_ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &get); + igt_assert_eq_u32(get.length, sizeof(test_mode_valid)); + + get.blob_id = prop_id; + get.data = (uintptr_t) 0xdeadbeee; + do_ioctl_err(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create, EFAULT); +} + +static void +test_lifetime(int fd) +{ + int fd2; + uint32_t prop_id, prop_id2; + + fd2 = drm_open_driver(DRIVER_ANY); + igt_assert_fd(fd2); + + /* Ensure clients can see properties created by other clients. */ + prop_id = create_prop(fd); + igt_assert_eq(validate_prop(fd, prop_id), 0); + igt_assert_eq(validate_prop(fd2, prop_id), 0); + + /* ... but can't destroy them. */ + igt_assert_eq(destroy_prop(fd2, prop_id), EPERM); + + /* Make sure properties can't be accessed once explicitly destroyed. */ + prop_id2 = create_prop(fd2); + igt_assert_eq(validate_prop(fd2, prop_id2), 0); + igt_assert_eq(destroy_prop(fd2, prop_id2), 0); + igt_assert_eq(validate_prop(fd2, prop_id2), ENOENT); + igt_assert_eq(validate_prop(fd, prop_id2), ENOENT); + + /* Make sure properties are cleaned up on client exit. */ + prop_id2 = create_prop(fd2); + igt_assert_eq(validate_prop(fd, prop_id2), 0); + igt_assert_eq(close(fd2), 0); + igt_assert_eq(validate_prop(fd, prop_id2), ENOENT); + + igt_assert_eq(validate_prop(fd, prop_id), 0); + igt_assert_eq(destroy_prop(fd, prop_id), 0); + igt_assert_eq(validate_prop(fd, prop_id), ENOENT); +} + +static void +test_multiple(int fd) +{ + uint32_t prop_ids[5]; + int fd2; + int i; + + fd2 = drm_open_driver(DRIVER_ANY); + igt_assert_fd(fd2); + + /* Ensure destroying multiple properties explicitly works as needed. */ + for (i = 0; i < ARRAY_SIZE(prop_ids); i++) { + prop_ids[i] = create_prop(fd2); + igt_assert_eq(validate_prop(fd, prop_ids[i]), 0); + igt_assert_eq(validate_prop(fd2, prop_ids[i]), 0); + } + for (i = 0; i < ARRAY_SIZE(prop_ids); i++) { + igt_assert_eq(destroy_prop(fd2, prop_ids[i]), 0); + igt_assert_eq(validate_prop(fd2, prop_ids[i]), ENOENT); + } + igt_assert_eq(close(fd2), 0); + + fd2 = drm_open_driver(DRIVER_ANY); + igt_assert_fd(fd2); + + /* Ensure that multiple properties get cleaned up on fd close. */ + for (i = 0; i < ARRAY_SIZE(prop_ids); i++) { + prop_ids[i] = create_prop(fd2); + igt_assert_eq(validate_prop(fd, prop_ids[i]), 0); + igt_assert_eq(validate_prop(fd2, prop_ids[i]), 0); + } + igt_assert_eq(close(fd2), 0); + + for (i = 0; i < ARRAY_SIZE(prop_ids); i++) + igt_assert_eq(validate_prop(fd, prop_ids[i]), ENOENT); +} + +static void +test_core(int fd) +{ + uint32_t prop_id; + + /* The first hurdle. */ + prop_id = create_prop(fd); + igt_assert_eq(validate_prop(fd, prop_id), 0); + igt_assert_eq(destroy_prop(fd, prop_id), 0); + + /* Look up some invalid property IDs. They should fail. */ + igt_assert_eq(validate_prop(fd, 0xffffffff), ENOENT); + igt_assert_eq(validate_prop(fd, 0), ENOENT); +} + +static void +test_basic(int fd) +{ + uint32_t prop_id; + + /* A very simple gating test to ensure property support exists. */ + prop_id = create_prop(fd); + igt_assert_eq(destroy_prop(fd, prop_id), 0); +} + +static void prop_tests(int fd) +{ + struct drm_mode_obj_get_properties get_props = {}; + struct drm_mode_obj_set_property set_prop = {}; + uint64_t prop, prop_val, blob_id; + + igt_fixture + blob_id = create_prop(fd); + + get_props.props_ptr = (uintptr_t) ∝ + get_props.prop_values_ptr = (uintptr_t) &prop_val; + get_props.count_props = 1; + get_props.obj_id = blob_id; + + igt_subtest("invalid-get-prop-any") { + get_props.obj_type = 0; /* DRM_MODE_OBJECT_ANY */ + + igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, + &get_props) == -1 && errno == EINVAL); + } + + igt_subtest("invalid-get-prop") { + get_props.obj_type = DRM_MODE_OBJECT_BLOB; + + igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, + &get_props) == -1 && errno == EINVAL); + } + + set_prop.value = 0; + set_prop.prop_id = 1; + set_prop.obj_id = blob_id; + + igt_subtest("invalid-set-prop-any") { + set_prop.obj_type = 0; /* DRM_MODE_OBJECT_ANY */ + + igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, + &set_prop) == -1 && errno == EINVAL); + } + + igt_subtest("invalid-set-prop") { + set_prop.obj_type = DRM_MODE_OBJECT_BLOB; + + igt_assert(drmIoctl(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, + &set_prop) == -1 && errno == EINVAL); + } + + igt_fixture + destroy_prop(fd, blob_id); +} + +igt_main +{ + int fd; + + igt_fixture { + fd = drm_open_driver(DRIVER_ANY); + igt_require(fd >= 0); + igt_require_propblob(fd); + } + + igt_subtest("basic") + test_basic(fd); + + igt_subtest("blob-prop-core") + test_core(fd); + + igt_subtest("blob-prop-validate") + test_validate(fd); + + igt_subtest("blob-prop-lifetime") + test_lifetime(fd); + + igt_subtest("blob-multiple") + test_multiple(fd); + + prop_tests(fd); + + igt_fixture + close(fd); +} -- cgit v1.2.3