2023-10-16 20:10:29

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH] drm/i915/mtl: avoid stringop-overflow warning

From: Arnd Bergmann <[email protected]>

The newly added memset() causes a warning for some reason I could not figure out:

In file included from arch/x86/include/asm/string.h:3,
from drivers/gpu/drm/i915/gt/intel_rc6.c:6:
In function 'rc6_res_reg_init',
inlined from 'intel_rc6_init' at drivers/gpu/drm/i915/gt/intel_rc6.c:610:2:
arch/x86/include/asm/string_32.h:195:29: error: '__builtin_memset' writing 16 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
195 | #define memset(s, c, count) __builtin_memset(s, c, count)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/gpu/drm/i915/gt/intel_rc6.c:584:9: note: in expansion of macro 'memset'
584 | memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
| ^~~~~~
In function 'intel_rc6_init':

Change it to an normal initializer and an added memcpy() that does not have
this problem.

Fixes: 4bb9ca7ee0745 ("drm/i915/mtl: C6 residency and C state type for MTL SAMedia")
Signed-off-by: Arnd Bergmann <[email protected]>
---
drivers/gpu/drm/i915/gt/intel_rc6.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 8b67abd720be8..7090e4be29cb6 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -581,19 +581,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)

static void rc6_res_reg_init(struct intel_rc6 *rc6)
{
- memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
+ i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
+ [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
+ };

switch (rc6_to_gt(rc6)->type) {
case GT_MEDIA:
- rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
+ res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
break;
default:
- rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
- rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
- rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
- rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
+ res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
+ res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
+ res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
+ res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
break;
}
+
+ memcpy(rc6->res_reg, res_reg, sizeof(res_reg));
}

void intel_rc6_init(struct intel_rc6 *rc6)
--
2.39.2


2023-10-16 22:11:31

by Andi Shyti

[permalink] [raw]
Subject: Re: [Intel-gfx] [PATCH] drm/i915/mtl: avoid stringop-overflow warning

Hi Arnd,

> static void rc6_res_reg_init(struct intel_rc6 *rc6)
> {
> - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));

This is a complex initialization, indeed... how about just

memset(rc6->res_reg, 0, sizeof(rc6->res_reg));

> + i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
> + [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
> + };

This is basically a

i915_reg_t res_reg[INTEL_RC6_RES_MAX] = { };

Don't know which one is clearer.

Andi

2023-10-17 05:28:36

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [Intel-gfx] [PATCH] drm/i915/mtl: avoid stringop-overflow warning

On Tue, Oct 17, 2023, at 00:10, Andi Shyti wrote:
> Hi Arnd,
>
>> static void rc6_res_reg_init(struct intel_rc6 *rc6)
>> {
>> - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
>
> This is a complex initialization, indeed... how about just
>
> memset(rc6->res_reg, 0, sizeof(rc6->res_reg));
>
>> + i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
>> + [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
>> + };
>
> This is basically a
>
> i915_reg_t res_reg[INTEL_RC6_RES_MAX] = { };
>
> Don't know which one is clearer.

Right, the original code went out of its way to use INVALID_MMIO_REG
instead of assuming it is zero, so I tried to preserve that for
consistency.

Arnd

2023-10-23 12:50:04

by Jani Nikula

[permalink] [raw]
Subject: Re: [PATCH] drm/i915/mtl: avoid stringop-overflow warning

On Mon, 16 Oct 2023, Arnd Bergmann <[email protected]> wrote:
> From: Arnd Bergmann <[email protected]>
>
> The newly added memset() causes a warning for some reason I could not figure out:
>
> In file included from arch/x86/include/asm/string.h:3,
> from drivers/gpu/drm/i915/gt/intel_rc6.c:6:
> In function 'rc6_res_reg_init',
> inlined from 'intel_rc6_init' at drivers/gpu/drm/i915/gt/intel_rc6.c:610:2:
> arch/x86/include/asm/string_32.h:195:29: error: '__builtin_memset' writing 16 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
> 195 | #define memset(s, c, count) __builtin_memset(s, c, count)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/gpu/drm/i915/gt/intel_rc6.c:584:9: note: in expansion of macro 'memset'
> 584 | memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
> | ^~~~~~
> In function 'intel_rc6_init':
>
> Change it to an normal initializer and an added memcpy() that does not have
> this problem.
>
> Fixes: 4bb9ca7ee0745 ("drm/i915/mtl: C6 residency and C state type for MTL SAMedia")
> Signed-off-by: Arnd Bergmann <[email protected]>
> ---
> drivers/gpu/drm/i915/gt/intel_rc6.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
> index 8b67abd720be8..7090e4be29cb6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_rc6.c
> +++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
> @@ -581,19 +581,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)
>
> static void rc6_res_reg_init(struct intel_rc6 *rc6)
> {
> - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));

That's just bollocks. memset() is byte granularity, while
INVALID_MMIO_REG.reg is u32. If the value was anything other than 0,
this would break.

And you're not supposed to look at the guts of i915_reg_t to begin with,
that's why it's a typedef. Basically any code that accesses the members
of i915_reg_t outside of its implementation are doing it wrong.

Reviewed-by: Jani Nikula <[email protected]>


> + i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
> + [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
> + };
>
> switch (rc6_to_gt(rc6)->type) {
> case GT_MEDIA:
> - rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
> + res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
> break;
> default:
> - rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
> - rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
> - rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
> - rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
> + res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
> + res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
> + res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
> + res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
> break;
> }
> +
> + memcpy(rc6->res_reg, res_reg, sizeof(res_reg));
> }
>
> void intel_rc6_init(struct intel_rc6 *rc6)

--
Jani Nikula, Intel

2023-10-24 17:42:07

by Andi Shyti

[permalink] [raw]
Subject: Re: [PATCH] drm/i915/mtl: avoid stringop-overflow warning

Hi Jani,

> > static void rc6_res_reg_init(struct intel_rc6 *rc6)
> > {
> > - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
>
> That's just bollocks. memset() is byte granularity, while
> INVALID_MMIO_REG.reg is u32. If the value was anything other than 0,
> this would break.

Actually it's:

void *memset(void *s, int c, size_t count)

> And you're not supposed to look at the guts of i915_reg_t to begin with,
> that's why it's a typedef. Basically any code that accesses the members
> of i915_reg_t outside of its implementation are doing it wrong.
>
> Reviewed-by: Jani Nikula <[email protected]>

in any case, I agree with your argument, but why can't we simply
do:

memset(rc6->res_reg, 0, sizeof(rc6->res_reg));

?

The patch looks to me like it's being more complex that it
should.

Andi

2023-10-25 11:54:04

by Jani Nikula

[permalink] [raw]
Subject: Re: [PATCH] drm/i915/mtl: avoid stringop-overflow warning

On Tue, 24 Oct 2023, Andi Shyti <[email protected]> wrote:
> Hi Jani,
>
>> > static void rc6_res_reg_init(struct intel_rc6 *rc6)
>> > {
>> > - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
>>
>> That's just bollocks. memset() is byte granularity, while
>> INVALID_MMIO_REG.reg is u32. If the value was anything other than 0,
>> this would break.
>
> Actually it's:
>
> void *memset(void *s, int c, size_t count)

And? It still sets each byte in s to (the lowest 8 bits of) c.

>
>> And you're not supposed to look at the guts of i915_reg_t to begin with,
>> that's why it's a typedef. Basically any code that accesses the members
>> of i915_reg_t outside of its implementation are doing it wrong.
>>
>> Reviewed-by: Jani Nikula <[email protected]>
>
> in any case, I agree with your argument, but why can't we simply
> do:
>
> memset(rc6->res_reg, 0, sizeof(rc6->res_reg));
>
> ?

We can simply do a lot of things in C, but IMO that's semantically
wrong. i915_reg_t is supposed to be an opaque type. We're not supposed
to know what it contains, and what values are valid or invalid for it.
That's one of the reasons we have i915_reg_t in the first place (type
safety being the primary one).

Basically you should be able to do

-#define INVALID_MMIO_REG _MMIO(0)
+#define INVALID_MMIO_REG _MMIO(0xdeadbeef)

and expect everything to still work.

BR,
Jani.

>
> The patch looks to me like it's being more complex that it
> should.
>
> Andi

--
Jani Nikula, Intel

2023-10-26 12:19:14

by Jani Nikula

[permalink] [raw]
Subject: Re: [Intel-gfx] [PATCH] drm/i915/mtl: avoid stringop-overflow warning

On Mon, 23 Oct 2023, Jani Nikula <[email protected]> wrote:
> On Mon, 16 Oct 2023, Arnd Bergmann <[email protected]> wrote:
>> From: Arnd Bergmann <[email protected]>
>>
>> The newly added memset() causes a warning for some reason I could not figure out:
>>
>> In file included from arch/x86/include/asm/string.h:3,
>> from drivers/gpu/drm/i915/gt/intel_rc6.c:6:
>> In function 'rc6_res_reg_init',
>> inlined from 'intel_rc6_init' at drivers/gpu/drm/i915/gt/intel_rc6.c:610:2:
>> arch/x86/include/asm/string_32.h:195:29: error: '__builtin_memset' writing 16 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
>> 195 | #define memset(s, c, count) __builtin_memset(s, c, count)
>> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gt/intel_rc6.c:584:9: note: in expansion of macro 'memset'
>> 584 | memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
>> | ^~~~~~
>> In function 'intel_rc6_init':
>>
>> Change it to an normal initializer and an added memcpy() that does not have
>> this problem.
>>
>> Fixes: 4bb9ca7ee0745 ("drm/i915/mtl: C6 residency and C state type for MTL SAMedia")
>> Signed-off-by: Arnd Bergmann <[email protected]>
>> ---
>> drivers/gpu/drm/i915/gt/intel_rc6.c | 16 ++++++++++------
>> 1 file changed, 10 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
>> index 8b67abd720be8..7090e4be29cb6 100644
>> --- a/drivers/gpu/drm/i915/gt/intel_rc6.c
>> +++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
>> @@ -581,19 +581,23 @@ static void __intel_rc6_disable(struct intel_rc6 *rc6)
>>
>> static void rc6_res_reg_init(struct intel_rc6 *rc6)
>> {
>> - memset(rc6->res_reg, INVALID_MMIO_REG.reg, sizeof(rc6->res_reg));
>
> That's just bollocks. memset() is byte granularity, while
> INVALID_MMIO_REG.reg is u32. If the value was anything other than 0,
> this would break.
>
> And you're not supposed to look at the guts of i915_reg_t to begin with,
> that's why it's a typedef. Basically any code that accesses the members
> of i915_reg_t outside of its implementation are doing it wrong.
>
> Reviewed-by: Jani Nikula <[email protected]>

Thanks for the patch, pushed to drm-intel-gt-next.

BR,
Jani.

>
>
>> + i915_reg_t res_reg[INTEL_RC6_RES_MAX] = {
>> + [0 ... INTEL_RC6_RES_MAX - 1] = INVALID_MMIO_REG,
>> + };
>>
>> switch (rc6_to_gt(rc6)->type) {
>> case GT_MEDIA:
>> - rc6->res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
>> + res_reg[INTEL_RC6_RES_RC6] = MTL_MEDIA_MC6;
>> break;
>> default:
>> - rc6->res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
>> - rc6->res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
>> - rc6->res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
>> - rc6->res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
>> + res_reg[INTEL_RC6_RES_RC6_LOCKED] = GEN6_GT_GFX_RC6_LOCKED;
>> + res_reg[INTEL_RC6_RES_RC6] = GEN6_GT_GFX_RC6;
>> + res_reg[INTEL_RC6_RES_RC6p] = GEN6_GT_GFX_RC6p;
>> + res_reg[INTEL_RC6_RES_RC6pp] = GEN6_GT_GFX_RC6pp;
>> break;
>> }
>> +
>> + memcpy(rc6->res_reg, res_reg, sizeof(res_reg));
>> }
>>
>> void intel_rc6_init(struct intel_rc6 *rc6)

--
Jani Nikula, Intel