mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-03-03 18:28:01 +01:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
222 lines
5.8 KiB
C
222 lines
5.8 KiB
C
// SPDX-License-Identifier: GPL-2.0 or MIT
|
|
/*
|
|
* Copyright (c) 2025 Red Hat.
|
|
* Author: Jocelyn Falempe <jfalempe@redhat.com>
|
|
*
|
|
* KUNIT tests for drm panic
|
|
*/
|
|
|
|
#include <drm/drm_fourcc.h>
|
|
#include <drm/drm_panic.h>
|
|
|
|
#include <kunit/test.h>
|
|
|
|
#include <linux/units.h>
|
|
#include <linux/vmalloc.h>
|
|
|
|
/* Check the framebuffer color only if the panic colors are the default */
|
|
#if (CONFIG_DRM_PANIC_BACKGROUND_COLOR == 0 && \
|
|
CONFIG_DRM_PANIC_FOREGROUND_COLOR == 0xffffff)
|
|
|
|
static void drm_panic_check_color_byte(struct kunit *test, u8 b)
|
|
{
|
|
KUNIT_EXPECT_TRUE(test, (b == 0 || b == 0xff));
|
|
}
|
|
#else
|
|
static void drm_panic_check_color_byte(struct kunit *test, u8 b) {}
|
|
#endif
|
|
|
|
struct drm_test_mode {
|
|
const int width;
|
|
const int height;
|
|
const u32 format;
|
|
void (*draw_screen)(struct drm_scanout_buffer *sb);
|
|
const char *fname;
|
|
};
|
|
|
|
/*
|
|
* Run all tests for the 3 panic screens: user, kmsg and qr_code
|
|
*/
|
|
#define DRM_TEST_MODE_LIST(func) \
|
|
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
|
|
DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
|
|
DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
|
|
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
|
|
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \
|
|
|
|
#define DRM_PANIC_TEST_MODE(w, h, f, name) { \
|
|
.width = w, \
|
|
.height = h, \
|
|
.format = f, \
|
|
.draw_screen = draw_panic_screen_##name, \
|
|
.fname = #name, \
|
|
}, \
|
|
|
|
static const struct drm_test_mode drm_test_modes_cases[] = {
|
|
DRM_TEST_MODE_LIST(user)
|
|
DRM_TEST_MODE_LIST(kmsg)
|
|
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
|
|
DRM_TEST_MODE_LIST(qr_code)
|
|
#endif
|
|
};
|
|
|
|
#undef DRM_PANIC_TEST_MODE
|
|
|
|
static int drm_test_panic_init(struct kunit *test)
|
|
{
|
|
struct drm_scanout_buffer *priv;
|
|
|
|
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
|
|
KUNIT_ASSERT_NOT_NULL(test, priv);
|
|
|
|
test->priv = priv;
|
|
|
|
drm_panic_set_description("Kunit testing");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Test drawing the panic screen, using a memory mapped framebuffer
|
|
* Set the whole buffer to 0xa5, and then check that all pixels have been
|
|
* written.
|
|
*/
|
|
static void drm_test_panic_screen_user_map(struct kunit *test)
|
|
{
|
|
struct drm_scanout_buffer *sb = test->priv;
|
|
const struct drm_test_mode *params = test->param_value;
|
|
char *fb;
|
|
int fb_size;
|
|
int i;
|
|
|
|
sb->format = drm_format_info(params->format);
|
|
fb_size = params->width * params->height * sb->format->cpp[0];
|
|
|
|
fb = vmalloc(fb_size);
|
|
KUNIT_ASSERT_NOT_NULL(test, fb);
|
|
|
|
memset(fb, 0xa5, fb_size);
|
|
|
|
iosys_map_set_vaddr(&sb->map[0], fb);
|
|
sb->width = params->width;
|
|
sb->height = params->height;
|
|
sb->pitch[0] = params->width * sb->format->cpp[0];
|
|
|
|
params->draw_screen(sb);
|
|
|
|
for (i = 0; i < fb_size; i++)
|
|
drm_panic_check_color_byte(test, fb[i]);
|
|
|
|
vfree(fb);
|
|
}
|
|
|
|
/*
|
|
* Test drawing the panic screen, using a list of pages framebuffer
|
|
* Set the whole buffer to 0xa5, and then check that all pixels have been
|
|
* written.
|
|
*/
|
|
static void drm_test_panic_screen_user_page(struct kunit *test)
|
|
{
|
|
struct drm_scanout_buffer *sb = test->priv;
|
|
const struct drm_test_mode *params = test->param_value;
|
|
int fb_size, p, i, npages;
|
|
struct page **pages;
|
|
u8 *vaddr;
|
|
|
|
sb->format = drm_format_info(params->format);
|
|
fb_size = params->width * params->height * sb->format->cpp[0];
|
|
npages = DIV_ROUND_UP(fb_size, PAGE_SIZE);
|
|
|
|
pages = kmalloc_objs(struct page *, npages);
|
|
KUNIT_ASSERT_NOT_NULL(test, pages);
|
|
|
|
for (p = 0; p < npages; p++) {
|
|
pages[p] = alloc_page(GFP_KERNEL);
|
|
if (!pages[p]) {
|
|
npages = p - 1;
|
|
KUNIT_FAIL(test, "Can't allocate page\n");
|
|
goto free_pages;
|
|
}
|
|
vaddr = kmap_local_page(pages[p]);
|
|
memset(vaddr, 0xa5, PAGE_SIZE);
|
|
kunmap_local(vaddr);
|
|
}
|
|
sb->pages = pages;
|
|
sb->width = params->width;
|
|
sb->height = params->height;
|
|
sb->pitch[0] = params->width * sb->format->cpp[0];
|
|
|
|
params->draw_screen(sb);
|
|
|
|
for (p = 0; p < npages; p++) {
|
|
int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE : PAGE_SIZE;
|
|
|
|
vaddr = kmap_local_page(pages[p]);
|
|
for (i = 0; i < bytes_in_page; i++)
|
|
drm_panic_check_color_byte(test, vaddr[i]);
|
|
|
|
kunmap_local(vaddr);
|
|
}
|
|
|
|
free_pages:
|
|
for (p = 0; p < npages; p++)
|
|
__free_page(pages[p]);
|
|
kfree(pages);
|
|
}
|
|
|
|
static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
|
|
unsigned int x,
|
|
unsigned int y,
|
|
u32 color)
|
|
{
|
|
struct kunit *test = (struct kunit *)sb->private;
|
|
|
|
KUNIT_ASSERT_TRUE(test, x < sb->width && y < sb->height);
|
|
}
|
|
|
|
/*
|
|
* Test drawing the panic screen, using the set_pixel callback
|
|
* Check that all calls to set_pixel() are within the framebuffer
|
|
*/
|
|
static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
|
|
{
|
|
struct drm_scanout_buffer *sb = test->priv;
|
|
const struct drm_test_mode *params = test->param_value;
|
|
|
|
sb->format = drm_format_info(params->format);
|
|
sb->set_pixel = drm_test_panic_set_pixel;
|
|
sb->width = params->width;
|
|
sb->height = params->height;
|
|
sb->private = test;
|
|
|
|
params->draw_screen(sb);
|
|
}
|
|
|
|
static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
|
|
{
|
|
sprintf(desc, "Panic screen %s, mode: %d x %d \t%p4cc",
|
|
t->fname, t->width, t->height, &t->format);
|
|
}
|
|
|
|
KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_map, drm_test_modes_cases, drm_test_panic_desc);
|
|
KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_page, drm_test_modes_cases, drm_test_panic_desc);
|
|
KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_set_pixel, drm_test_modes_cases, drm_test_panic_desc);
|
|
|
|
static struct kunit_case drm_panic_screen_user_test[] = {
|
|
KUNIT_CASE_PARAM(drm_test_panic_screen_user_map,
|
|
drm_test_panic_screen_user_map_gen_params),
|
|
KUNIT_CASE_PARAM(drm_test_panic_screen_user_page,
|
|
drm_test_panic_screen_user_page_gen_params),
|
|
KUNIT_CASE_PARAM(drm_test_panic_screen_user_set_pixel,
|
|
drm_test_panic_screen_user_set_pixel_gen_params),
|
|
{ }
|
|
};
|
|
|
|
static struct kunit_suite drm_panic_suite = {
|
|
.name = "drm_panic",
|
|
.init = drm_test_panic_init,
|
|
.test_cases = drm_panic_screen_user_test,
|
|
};
|
|
|
|
kunit_test_suite(drm_panic_suite);
|