bcm27xx: update patches from RPi foundation
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0272-drm-vc4-Prevent-load-tracking-from-breaking-FKMS.patch
1 From 907dc84e0c7208b79ad57e0e2a7964dbc9155f50 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Thu, 15 Aug 2019 08:39:08 +0100
4 Subject: [PATCH] drm/vc4: Prevent load tracking from breaking FKMS
5
6 Firmware KMS uses a mixture of VC4 processing and dedicated code. The
7 load tracking support in VC4 assumes it is dealing with vc4_plane_state
8 objects when up-casting with container_of, but FKMS uses unadorned
9 drm_plane_state structures causing the VC4 code to read off the end
10 into random portions of memory. Work around the problem in a minimally-
11 invasive way by over-allocating the FKMS plane state structures to be
12 large enough to contain a vc4_plane_state, filling the remainder with
13 zeroes.
14
15 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
16 ---
17  drivers/gpu/drm/vc4/vc4_firmware_kms.c | 34 ++++++++++++++++++++++++--
18  1 file changed, 32 insertions(+), 2 deletions(-)
19
20 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
21 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
22 @@ -561,6 +561,20 @@ static int vc4_plane_atomic_check(struct
23         return 0;
24  }
25  
26 +/* Called during init to allocate the plane's atomic state. */
27 +static void vc4_plane_reset(struct drm_plane *plane)
28 +{
29 +       struct vc4_plane_state *vc4_state;
30 +
31 +       WARN_ON(plane->state);
32 +
33 +       vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
34 +       if (!vc4_state)
35 +               return;
36 +
37 +       __drm_atomic_helper_plane_reset(plane, &vc4_state->base);
38 +}
39 +
40  static void vc4_plane_destroy(struct drm_plane *plane)
41  {
42         drm_plane_cleanup(plane);
43 @@ -602,13 +616,29 @@ static bool vc4_fkms_format_mod_supporte
44         }
45  }
46  
47 +static struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
48 +{
49 +       struct vc4_plane_state *vc4_state;
50 +
51 +       if (WARN_ON(!plane->state))
52 +               return NULL;
53 +
54 +       vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
55 +       if (!vc4_state)
56 +               return NULL;
57 +
58 +       __drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
59 +
60 +       return &vc4_state->base;
61 +}
62 +
63  static const struct drm_plane_funcs vc4_plane_funcs = {
64         .update_plane = drm_atomic_helper_update_plane,
65         .disable_plane = drm_atomic_helper_disable_plane,
66         .destroy = vc4_plane_destroy,
67         .set_property = NULL,
68 -       .reset = drm_atomic_helper_plane_reset,
69 -       .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
70 +       .reset = vc4_plane_reset,
71 +       .atomic_duplicate_state = vc4_plane_duplicate_state,
72         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
73         .format_mod_supported = vc4_fkms_format_mod_supported,
74  };