| From a3d241383f3d2ab0fe59d8ba11badd6c45fc4fb5 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 17 Jan 2020 16:34:28 +0100 |
| Subject: drm/modes: Make sure to parse valid rotation value from cmdline |
| |
| From: Stephan Gerhold <stephan@gerhold.net> |
| |
| [ Upstream commit e6980a727154b793adb218fbc7b4d6af52a7e364 ] |
| |
| A rotation value should have exactly one rotation angle. |
| At the moment there is no validation for this when parsing video= |
| parameters from the command line. This causes problems later on |
| when we try to combine the command line rotation with the panel |
| orientation. |
| |
| To make sure that we generate a valid rotation value: |
| - Set DRM_MODE_ROTATE_0 by default (if no rotate= option is set) |
| - Validate that there is exactly one rotation angle set |
| (i.e. specifying the rotate= option multiple times is invalid) |
| |
| Signed-off-by: Stephan Gerhold <stephan@gerhold.net> |
| Signed-off-by: Maxime Ripard <maxime@cerno.tech> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20200117153429.54700-2-stephan@gerhold.net |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/drm_modes.c | 7 +++++++ |
| drivers/gpu/drm/selftests/drm_cmdline_selftests.h | 1 + |
| .../gpu/drm/selftests/test-drm_cmdline_parser.c | 15 +++++++++++++-- |
| 3 files changed, 21 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c |
| index 88232698d7a00..3fd35e6b9d535 100644 |
| --- a/drivers/gpu/drm/drm_modes.c |
| +++ b/drivers/gpu/drm/drm_modes.c |
| @@ -1672,6 +1672,13 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len, |
| } |
| } |
| |
| + if (!(rotation & DRM_MODE_ROTATE_MASK)) |
| + rotation |= DRM_MODE_ROTATE_0; |
| + |
| + /* Make sure there is exactly one rotation defined */ |
| + if (!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK)) |
| + return -EINVAL; |
| + |
| mode->rotation_reflection = rotation; |
| |
| return 0; |
| diff --git a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h |
| index 6d61a0eb5d64f..84e6bc050bf2c 100644 |
| --- a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h |
| +++ b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h |
| @@ -53,6 +53,7 @@ cmdline_test(drm_cmdline_test_rotate_0) |
| cmdline_test(drm_cmdline_test_rotate_90) |
| cmdline_test(drm_cmdline_test_rotate_180) |
| cmdline_test(drm_cmdline_test_rotate_270) |
| +cmdline_test(drm_cmdline_test_rotate_multiple) |
| cmdline_test(drm_cmdline_test_rotate_invalid_val) |
| cmdline_test(drm_cmdline_test_rotate_truncated) |
| cmdline_test(drm_cmdline_test_hmirror) |
| diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c |
| index 013de9d27c35d..035f86c5d6482 100644 |
| --- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c |
| +++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c |
| @@ -856,6 +856,17 @@ static int drm_cmdline_test_rotate_270(void *ignored) |
| return 0; |
| } |
| |
| +static int drm_cmdline_test_rotate_multiple(void *ignored) |
| +{ |
| + struct drm_cmdline_mode mode = { }; |
| + |
| + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90", |
| + &no_connector, |
| + &mode)); |
| + |
| + return 0; |
| +} |
| + |
| static int drm_cmdline_test_rotate_invalid_val(void *ignored) |
| { |
| struct drm_cmdline_mode mode = { }; |
| @@ -888,7 +899,7 @@ static int drm_cmdline_test_hmirror(void *ignored) |
| FAIL_ON(!mode.specified); |
| FAIL_ON(mode.xres != 720); |
| FAIL_ON(mode.yres != 480); |
| - FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_X); |
| + FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X)); |
| |
| FAIL_ON(mode.refresh_specified); |
| |
| @@ -913,7 +924,7 @@ static int drm_cmdline_test_vmirror(void *ignored) |
| FAIL_ON(!mode.specified); |
| FAIL_ON(mode.xres != 720); |
| FAIL_ON(mode.yres != 480); |
| - FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_Y); |
| + FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y)); |
| |
| FAIL_ON(mode.refresh_specified); |
| |
| -- |
| 2.20.1 |
| |