Commit 618efe6f authored by Phil Elwell's avatar Phil Elwell Committed by popcornmix
Browse files

drm/vc4: Prevent load tracking from breaking FKMS



Firmware KMS uses a mixture of VC4 processing and dedicated code. The
load tracking support in VC4 assumes it is dealing with vc4_plane_state
objects when up-casting with container_of, but FKMS uses unadorned
drm_plane_state structures causing the VC4 code to read off the end
into random portions of memory. Work around the problem in a minimally-
invasive way by over-allocating the FKMS plane state structures to be
large enough to contain a vc4_plane_state, filling the remainder with
zeroes.

Signed-off-by: default avatarPhil Elwell <phil@raspberrypi.org>
parent 38f2d0d1
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -559,6 +559,20 @@ static int vc4_plane_atomic_check(struct drm_plane *plane,
	return 0;
}

/* Called during init to allocate the plane's atomic state. */
static void vc4_plane_reset(struct drm_plane *plane)
{
	struct vc4_plane_state *vc4_state;

	WARN_ON(plane->state);

	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
	if (!vc4_state)
		return;

	__drm_atomic_helper_plane_reset(plane, &vc4_state->base);
}

static void vc4_plane_destroy(struct drm_plane *plane)
{
	drm_plane_cleanup(plane);
@@ -600,13 +614,29 @@ static bool vc4_fkms_format_mod_supported(struct drm_plane *plane,
	}
}

static struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
{
	struct vc4_plane_state *vc4_state;

	if (WARN_ON(!plane->state))
		return NULL;

	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
	if (!vc4_state)
		return NULL;

	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);

	return &vc4_state->base;
}

static const struct drm_plane_funcs vc4_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = vc4_plane_destroy,
	.set_property = NULL,
	.reset = drm_atomic_helper_plane_reset,
	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
	.reset = vc4_plane_reset,
	.atomic_duplicate_state = vc4_plane_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
	.format_mod_supported = vc4_fkms_format_mod_supported,
};