On Mon, 05 Dec 2016, Tomeu Vizoso <[email protected]> wrote:
> The kernel has now a new debugfs ABI that can also allow capturing frame
> CRCs for drivers other than i915.
>
> Add alternative codepaths so the new ABI is used if the kernel is recent
> enough, and fall back to the legacy ABI if not.
>
> Signed-off-by: Tomeu Vizoso <[email protected]>

...

>  static int read_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
>  {
>       ssize_t bytes_read;
> -     char buf[pipe_crc->buffer_len];
> +     char buf[MAX_LINE_LEN + 1];
> +     size_t read_len;
> +
> +     if (pipe_crc->is_legacy)
> +             read_len = LEGACY_LINE_LEN;
> +     else
> +             read_len = MAX_LINE_LEN;
>  
>       igt_set_timeout(5, "CRC reading");
> -     bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
> +     bytes_read = read(pipe_crc->crc_fd, &buf, read_len);
>       igt_reset_timeout();
>  
>       if (bytes_read < 0 && errno == EAGAIN) {
>               igt_assert(pipe_crc->flags & O_NONBLOCK);
>               bytes_read = 0;
> -     } else {
> -             igt_assert_eq(bytes_read, pipe_crc->line_len);
>       }

Leaving out the else branch leads to

igt_debugfs.c: In function 'read_crc':
igt_debugfs.c:604:5: error: array subscript is below array bounds 
[-Werror=array-bounds]
  buf[bytes_read] = '\0';
     ^

as bytes_read may end up being < 0.

BR,
Jani.


>       buf[bytes_read] = '\0';
>  
> -     if (bytes_read && !pipe_crc_init_from_string(out, buf))
> +     if (bytes_read && !pipe_crc_init_from_string(pipe_crc, out, buf))
>               return -EINVAL;
>  
>       return bytes_read;
> @@ -530,15 +610,18 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
>  
>       igt_assert(igt_pipe_crc_do_start(pipe_crc));
>  
> -     /*
> -      * For some no yet identified reason, the first CRC is bonkers. So
> -      * let's just wait for the next vblank and read out the buggy result.
> -      *
> -      * On CHV sometimes the second CRC is bonkers as well, so don't trust
> -      * that one either.
> -      */
> -     read_one_crc(pipe_crc, &crc);
> -     read_one_crc(pipe_crc, &crc);
> +     if (pipe_crc->is_legacy) {
> +             /*
> +              * For some no yet identified reason, the first CRC is
> +              * bonkers. So let's just wait for the next vblank and read
> +              * out the buggy result.
> +              *
> +              * On CHV sometimes the second CRC is bonkers as well, so
> +              * don't trust that one either.
> +              */
> +             read_one_crc(pipe_crc, &crc);
> +             read_one_crc(pipe_crc, &crc);
> +     }
>  }
>  
>  /**
> @@ -551,8 +634,15 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
>  {
>       char buf[32];
>  
> -     sprintf(buf, "pipe %s none", kmstest_pipe_name(pipe_crc->pipe));
> -     igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
> +     if (pipe_crc->is_legacy) {
> +             sprintf(buf, "pipe %s none",
> +                     kmstest_pipe_name(pipe_crc->pipe));
> +             igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)),
> +                           strlen(buf));
> +     } else {
> +             close(pipe_crc->crc_fd);
> +             pipe_crc->crc_fd = -1;
> +     }
>  }
>  
>  /**
> diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
> index fb189322633f..4c6572cd244c 100644
> --- a/lib/igt_debugfs.h
> +++ b/lib/igt_debugfs.h
> @@ -62,6 +62,7 @@ bool igt_debugfs_search(const char *filename, const char 
> *substring);
>   */
>  typedef struct _igt_pipe_crc igt_pipe_crc_t;
>  
> +#define DRM_MAX_CRC_NR 10
>  /**
>   * igt_crc_t:
>   * @frame: frame number of the capture CRC
> @@ -73,8 +74,9 @@ typedef struct _igt_pipe_crc igt_pipe_crc_t;
>   */
>  typedef struct {
>       uint32_t frame;
> +     bool has_valid_frame;
>       int n_words;
> -     uint32_t crc[5];
> +     uint32_t crc[DRM_MAX_CRC_NR];
>  } igt_crc_t;
>  
>  /**
> diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
> index 04d5a1345760..b106f9bd05ee 100644
> --- a/tests/kms_pipe_crc_basic.c
> +++ b/tests/kms_pipe_crc_basic.c
> @@ -49,6 +49,8 @@ static void test_bad_command(data_t *data, const char *cmd)
>       size_t written;
>  
>       ctl = igt_debugfs_fopen("i915_display_crc_ctl", "r+");
> +     igt_require(ctl);
> +
>       written = fwrite(cmd, 1, strlen(cmd), ctl);
>       fflush(ctl);
>       igt_assert_eq(written, strlen(cmd));
> @@ -58,6 +60,30 @@ static void test_bad_command(data_t *data, const char *cmd)
>       fclose(ctl);
>  }
>  
> +static void test_bad_source(data_t *data)
> +{
> +     FILE *f;
> +     size_t written;
> +     const char *source = "foo";
> +
> +     f = igt_debugfs_fopen("crtc-0/crc/control", "w");
> +     if (!f) {
> +             test_bad_command(data, "pipe A foo");
> +             return;
> +     }
> +
> +     written = fwrite(source, 1, strlen(source), f);
> +     fflush(f);
> +     igt_assert_eq(written, strlen(source));
> +     igt_assert(!ferror(f));
> +     igt_assert(!errno);
> +     fclose(f);
> +
> +     f = igt_debugfs_fopen("crtc-0/crc/data", "w");
> +     igt_assert(!f);
> +     igt_assert_eq(errno, EINVAL);
> +}
> +
>  #define N_CRCS       3
>  
>  #define TEST_SEQUENCE (1<<0)
> @@ -185,7 +211,7 @@ igt_main
>       igt_skip_on_simulation();
>  
>       igt_fixture {
> -             data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> +             data.drm_fd = drm_open_driver_master(DRIVER_ANY);
>  
>               igt_enable_connectors();
>  
> @@ -200,7 +226,7 @@ igt_main
>               test_bad_command(&data, "pipe D none");
>  
>       igt_subtest("bad-source")
> -             test_bad_command(&data, "pipe A foo");
> +             test_bad_source(&data);
>  
>       igt_subtest("bad-nb-words-1")
>               test_bad_command(&data, "pipe foo");

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to