diff mbox series

[1/3] drm/i915/display: Do not assume zero offset when duplicating global state

Message ID 20241219214909.104869-2-gustavo.sousa@intel.com (mailing list archive)
State New
Headers show
Series drm/i915/display: Reduce global state funcs boilerplate | expand

Commit Message

Gustavo Sousa Dec. 19, 2024, 9:48 p.m. UTC
The current intel_*_duplicate_state() functions assume the offset for
the base member of their state structures is zero when calling
kmemdup(). While that is true today, such assumption should not be made
and proper offset must be applied when calling kmemdup(), otherwise we
will be duplicating the wrong memory area if, for some reason, the
offset is changed in the future.

As such, update each of those functions to use its respective
to_*_state() as the parameter to kmemdup().

Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bw.c       | 4 ++--
 drivers/gpu/drm/i915/display/intel_cdclk.c    | 4 ++--
 drivers/gpu/drm/i915/display/intel_pmdemand.c | 4 ++--
 drivers/gpu/drm/i915/display/skl_watermark.c  | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

Comments

Cavitt, Jonathan Dec. 19, 2024, 10:43 p.m. UTC | #1
-----Original Message-----
From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Gustavo Sousa
Sent: Thursday, December 19, 2024 1:49 PM
To: intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>; Nikula, Jani <jani.nikula@intel.com>
Subject: [PATCH 1/3] drm/i915/display: Do not assume zero offset when duplicating global state
> 
> The current intel_*_duplicate_state() functions assume the offset for
> the base member of their state structures is zero when calling
> kmemdup(). While that is true today, such assumption should not be made
> and proper offset must be applied when calling kmemdup(), otherwise we
> will be duplicating the wrong memory area if, for some reason, the
> offset is changed in the future.
> 
> As such, update each of those functions to use its respective
> to_*_state() as the parameter to kmemdup().
> 
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>

LGTM.
Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
-Jonathan Cavitt

> ---
>  drivers/gpu/drm/i915/display/intel_bw.c       | 4 ++--
>  drivers/gpu/drm/i915/display/intel_cdclk.c    | 4 ++--
>  drivers/gpu/drm/i915/display/intel_pmdemand.c | 4 ++--
>  drivers/gpu/drm/i915/display/skl_watermark.c  | 4 ++--
>  4 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index 08e8a67ca74c..30236010e0ed 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -1425,9 +1425,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  static struct intel_global_state *
>  intel_bw_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_bw_state *state;
> +	struct intel_bw_state *state = to_intel_bw_state(obj->state);
>  
> -	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
> +	state = kmemdup(state, sizeof(*state), GFP_KERNEL);
>  	if (!state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 3506e576bf6b..fc084e2a4c6a 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -3130,9 +3130,9 @@ static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
>  
>  static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_cdclk_state *cdclk_state;
> +	struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(obj->state);
>  
> -	cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);
> +	cdclk_state = kmemdup(cdclk_state, sizeof(*cdclk_state), GFP_KERNEL);
>  	if (!cdclk_state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c
> index cdd314956a31..1f71efb7d04d 100644
> --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c
> +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c
> @@ -18,9 +18,9 @@
>  static struct intel_global_state *
>  intel_pmdemand_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_pmdemand_state *pmdemand_state;
> +	struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(obj->state);
>  
> -	pmdemand_state = kmemdup(obj->state, sizeof(*pmdemand_state), GFP_KERNEL);
> +	pmdemand_state = kmemdup(pmdemand_state, sizeof(*pmdemand_state), GFP_KERNEL);
>  	if (!pmdemand_state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 29e8ea91c858..b3d38e09df5a 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3291,9 +3291,9 @@ static void skl_setup_wm_latency(struct drm_i915_private *i915)
>  
>  static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_dbuf_state *dbuf_state;
> +	struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(obj->state);
>  
> -	dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
> +	dbuf_state = kmemdup(dbuf_state, sizeof(*dbuf_state), GFP_KERNEL);
>  	if (!dbuf_state)
>  		return NULL;
>  
> -- 
> 2.47.1
> 
>
Ville Syrjälä Dec. 20, 2024, 9:11 a.m. UTC | #2
On Thu, Dec 19, 2024 at 06:48:36PM -0300, Gustavo Sousa wrote:
> The current intel_*_duplicate_state() functions assume the offset for
> the base member of their state structures is zero when calling
> kmemdup(). While that is true today, such assumption should not be made
> and proper offset must be applied when calling kmemdup(), otherwise we
> will be duplicating the wrong memory area if, for some reason, the
> offset is changed in the future.

All kms objects we use make that same assumption. I think the correct
thing to do is to just throw in some BUILD_BUG_ON()/etc. to make the
thing not build if that doesn't hold. I had a patch like that ages
ago, but it's no doubt 110% stale by now.

I suppose no real harm if avoiding that assumption in spots like
this, but the &foo->base==NULL <-> foo==NULL assumptions we have
all over the place are the far bigger issue.

> 
> As such, update each of those functions to use its respective
> to_*_state() as the parameter to kmemdup().
> 
> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c       | 4 ++--
>  drivers/gpu/drm/i915/display/intel_cdclk.c    | 4 ++--
>  drivers/gpu/drm/i915/display/intel_pmdemand.c | 4 ++--
>  drivers/gpu/drm/i915/display/skl_watermark.c  | 4 ++--
>  4 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index 08e8a67ca74c..30236010e0ed 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -1425,9 +1425,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>  static struct intel_global_state *
>  intel_bw_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_bw_state *state;
> +	struct intel_bw_state *state = to_intel_bw_state(obj->state);
>  
> -	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
> +	state = kmemdup(state, sizeof(*state), GFP_KERNEL);
>  	if (!state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 3506e576bf6b..fc084e2a4c6a 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -3130,9 +3130,9 @@ static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
>  
>  static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_cdclk_state *cdclk_state;
> +	struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(obj->state);
>  
> -	cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);
> +	cdclk_state = kmemdup(cdclk_state, sizeof(*cdclk_state), GFP_KERNEL);
>  	if (!cdclk_state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c
> index cdd314956a31..1f71efb7d04d 100644
> --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c
> +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c
> @@ -18,9 +18,9 @@
>  static struct intel_global_state *
>  intel_pmdemand_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_pmdemand_state *pmdemand_state;
> +	struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(obj->state);
>  
> -	pmdemand_state = kmemdup(obj->state, sizeof(*pmdemand_state), GFP_KERNEL);
> +	pmdemand_state = kmemdup(pmdemand_state, sizeof(*pmdemand_state), GFP_KERNEL);
>  	if (!pmdemand_state)
>  		return NULL;
>  
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 29e8ea91c858..b3d38e09df5a 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -3291,9 +3291,9 @@ static void skl_setup_wm_latency(struct drm_i915_private *i915)
>  
>  static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj)
>  {
> -	struct intel_dbuf_state *dbuf_state;
> +	struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(obj->state);
>  
> -	dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
> +	dbuf_state = kmemdup(dbuf_state, sizeof(*dbuf_state), GFP_KERNEL);
>  	if (!dbuf_state)
>  		return NULL;
>  
> -- 
> 2.47.1
Gustavo Sousa Dec. 20, 2024, 1:37 p.m. UTC | #3
Quoting Ville Syrjälä (2024-12-20 06:11:57-03:00)
>On Thu, Dec 19, 2024 at 06:48:36PM -0300, Gustavo Sousa wrote:
>> The current intel_*_duplicate_state() functions assume the offset for
>> the base member of their state structures is zero when calling
>> kmemdup(). While that is true today, such assumption should not be made
>> and proper offset must be applied when calling kmemdup(), otherwise we
>> will be duplicating the wrong memory area if, for some reason, the
>> offset is changed in the future.
>
>All kms objects we use make that same assumption. I think the correct
>thing to do is to just throw in some BUILD_BUG_ON()/etc. to make the
>thing not build if that doesn't hold. I had a patch like that ages
>ago, but it's no doubt 110% stale by now.

Okay. In this case, if we were to follow this route, some questions:

1) Where would be the best place to put BUILD_BUG_ON() (or
   static_assert())?

   Would requiring the usage of some macro provided by
   intel_global_state.h be acceptable? Something like:

   struct my_state {
       struct intel_global_state base;
       ...
   };
   INTEL_GLOBAL_STATE_SUBCLASS(struct my_state, base);

   Well, we are still requiring a macro call here when compared to the
   explicit assert on the offset, but now the semantics is that the
   developer advertising a subclass of intel_global_state instead of
   hand rolling the necessary checks herself.

2) If we require the embedded struct to be always the first member,
   would there be any point in defining and using the to_*_state()
   macros? I don't see much benefit of that over simply casting the
   pointer if the offset is always zero. I might be missing something
   though.

>
>I suppose no real harm if avoiding that assumption in spots like
>this, but the &foo->base==NULL <-> foo==NULL assumptions we have
>all over the place are the far bigger issue.

Yeah, maybe requiring base to be the first member is a more manageable
approach indeed.

--
Gustavo Sousa

>
>> 
>> As such, update each of those functions to use its respective
>> to_*_state() as the parameter to kmemdup().
>> 
>> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_bw.c       | 4 ++--
>>  drivers/gpu/drm/i915/display/intel_cdclk.c    | 4 ++--
>>  drivers/gpu/drm/i915/display/intel_pmdemand.c | 4 ++--
>>  drivers/gpu/drm/i915/display/skl_watermark.c  | 4 ++--
>>  4 files changed, 8 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>> index 08e8a67ca74c..30236010e0ed 100644
>> --- a/drivers/gpu/drm/i915/display/intel_bw.c
>> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
>> @@ -1425,9 +1425,9 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
>>  static struct intel_global_state *
>>  intel_bw_duplicate_state(struct intel_global_obj *obj)
>>  {
>> -        struct intel_bw_state *state;
>> +        struct intel_bw_state *state = to_intel_bw_state(obj->state);
>>  
>> -        state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
>> +        state = kmemdup(state, sizeof(*state), GFP_KERNEL);
>>          if (!state)
>>                  return NULL;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
>> index 3506e576bf6b..fc084e2a4c6a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
>> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
>> @@ -3130,9 +3130,9 @@ static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
>>  
>>  static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)
>>  {
>> -        struct intel_cdclk_state *cdclk_state;
>> +        struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(obj->state);
>>  
>> -        cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);
>> +        cdclk_state = kmemdup(cdclk_state, sizeof(*cdclk_state), GFP_KERNEL);
>>          if (!cdclk_state)
>>                  return NULL;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c
>> index cdd314956a31..1f71efb7d04d 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c
>> @@ -18,9 +18,9 @@
>>  static struct intel_global_state *
>>  intel_pmdemand_duplicate_state(struct intel_global_obj *obj)
>>  {
>> -        struct intel_pmdemand_state *pmdemand_state;
>> +        struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(obj->state);
>>  
>> -        pmdemand_state = kmemdup(obj->state, sizeof(*pmdemand_state), GFP_KERNEL);
>> +        pmdemand_state = kmemdup(pmdemand_state, sizeof(*pmdemand_state), GFP_KERNEL);
>>          if (!pmdemand_state)
>>                  return NULL;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
>> index 29e8ea91c858..b3d38e09df5a 100644
>> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
>> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
>> @@ -3291,9 +3291,9 @@ static void skl_setup_wm_latency(struct drm_i915_private *i915)
>>  
>>  static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj)
>>  {
>> -        struct intel_dbuf_state *dbuf_state;
>> +        struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(obj->state);
>>  
>> -        dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
>> +        dbuf_state = kmemdup(dbuf_state, sizeof(*dbuf_state), GFP_KERNEL);
>>          if (!dbuf_state)
>>                  return NULL;
>>  
>> -- 
>> 2.47.1
>
>-- 
>Ville Syrjälä
>Intel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 08e8a67ca74c..30236010e0ed 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -1425,9 +1425,9 @@  int intel_bw_atomic_check(struct intel_atomic_state *state)
 static struct intel_global_state *
 intel_bw_duplicate_state(struct intel_global_obj *obj)
 {
-	struct intel_bw_state *state;
+	struct intel_bw_state *state = to_intel_bw_state(obj->state);
 
-	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	state = kmemdup(state, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 3506e576bf6b..fc084e2a4c6a 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -3130,9 +3130,9 @@  static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
 
 static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)
 {
-	struct intel_cdclk_state *cdclk_state;
+	struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(obj->state);
 
-	cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);
+	cdclk_state = kmemdup(cdclk_state, sizeof(*cdclk_state), GFP_KERNEL);
 	if (!cdclk_state)
 		return NULL;
 
diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c
index cdd314956a31..1f71efb7d04d 100644
--- a/drivers/gpu/drm/i915/display/intel_pmdemand.c
+++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c
@@ -18,9 +18,9 @@ 
 static struct intel_global_state *
 intel_pmdemand_duplicate_state(struct intel_global_obj *obj)
 {
-	struct intel_pmdemand_state *pmdemand_state;
+	struct intel_pmdemand_state *pmdemand_state = to_intel_pmdemand_state(obj->state);
 
-	pmdemand_state = kmemdup(obj->state, sizeof(*pmdemand_state), GFP_KERNEL);
+	pmdemand_state = kmemdup(pmdemand_state, sizeof(*pmdemand_state), GFP_KERNEL);
 	if (!pmdemand_state)
 		return NULL;
 
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 29e8ea91c858..b3d38e09df5a 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3291,9 +3291,9 @@  static void skl_setup_wm_latency(struct drm_i915_private *i915)
 
 static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj)
 {
-	struct intel_dbuf_state *dbuf_state;
+	struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(obj->state);
 
-	dbuf_state = kmemdup(obj->state, sizeof(*dbuf_state), GFP_KERNEL);
+	dbuf_state = kmemdup(dbuf_state, sizeof(*dbuf_state), GFP_KERNEL);
 	if (!dbuf_state)
 		return NULL;