[PULL 2/2] core/register: Specify instance_size in the TypeInfo

Alistair Francis posted 2 patches 5 years, 4 months ago
Maintainers: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, "Philippe Mathieu-Daudé" <f4bug@amsat.org>, Aurelien Jarno <aurelien@aurel32.net>, Marek Vasut <marex@denx.de>, Max Filippov <jcmvbkbc@gmail.com>, Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Sagar Karandikar <sagark@eecs.berkeley.edu>, Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>, Richard Henderson <rth@twiddle.net>, BALATON Zoltan <balaton@eik.bme.hu>, Huacai Chen <chenhc@lemote.com>, Palmer Dabbelt <palmer@dabbelt.com>, Bastian Koppelmann <kbastian@mail.uni-paderborn.de>, Alistair Francis <Alistair.Francis@wdc.com>, Peter Maydell <peter.maydell@linaro.org>, David Gibson <david@gibson.dropbear.id.au>, Anthony Green <green@moxielogic.com>, Chris Wulff <crwulff@gmail.com>
[PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Alistair Francis 5 years, 4 months ago
Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
---
 hw/core/register.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/hw/core/register.c b/hw/core/register.c
index ddf91eb445..31038bd7cc 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -176,17 +176,6 @@ void register_reset(RegisterInfo *reg)
     }
 }
 
-void register_init(RegisterInfo *reg)
-{
-    assert(reg);
-
-    if (!reg->data || !reg->access) {
-        return;
-    }
-
-    object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
-}
-
 void register_write_memory(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
 {
@@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
         int index = rae[i].addr / data_size;
         RegisterInfo *r = &ri[index];
 
-        *r = (RegisterInfo) {
-            .data = data + data_size * index,
-            .data_size = data_size,
-            .access = &rae[i],
-            .opaque = owner,
-        };
-        register_init(r);
+        if (data + data_size * index == 0 || !&rae[i]) {
+            continue;
+        }
+
+        /* Init the register, this will zero it. */
+        object_initialize((void *)r, sizeof(*r), TYPE_REGISTER);
+
+        /* Set the properties of the register */
+        r->data = data + data_size * index;
+        r->data_size = data_size;
+        r->access = &rae[i];
+        r->opaque = owner;
 
         r_array->r[i] = r;
     }
@@ -329,6 +323,7 @@ static const TypeInfo register_info = {
     .name  = TYPE_REGISTER,
     .parent = TYPE_DEVICE,
     .class_init = register_class_init,
+    .instance_size = sizeof(RegisterInfo),
 };
 
 static void register_register_types(void)
-- 
2.28.0


Re: [PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Peter Maydell 5 years, 4 months ago
On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
>
> Reported-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
> ---
> @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
>          int index = rae[i].addr / data_size;
>          RegisterInfo *r = &ri[index];
>
> -        *r = (RegisterInfo) {
> -            .data = data + data_size * index,
> -            .data_size = data_size,
> -            .access = &rae[i],
> -            .opaque = owner,
> -        };
> -        register_init(r);
> +        if (data + data_size * index == 0 || !&rae[i]) {
> +            continue;

Coverity thinks (CID 1432800) that this is dead code, because
"data + data_size * index" can never be NULL[*]. What was this
intending to test for ? (maybe data == NULL? Missing dereference
operator ?)

[*] The C spec is quite strict about what valid pointer arithmetic
is; in particular adding to a NULL pointer is undefined behaviour,
and pointer arithmetic that overflows and wraps around is
undefined behaviour, so there's no way to get a 0 result from
"ptr + offset" without the expression being UB.

thanks
-- PMM

Re: [PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Eduardo Habkost 5 years, 4 months ago
On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:
> On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
> >
> > Reported-by: Eduardo Habkost <ehabkost@redhat.com>
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
> > ---
> > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> >          int index = rae[i].addr / data_size;
> >          RegisterInfo *r = &ri[index];
> >
> > -        *r = (RegisterInfo) {
> > -            .data = data + data_size * index,
> > -            .data_size = data_size,
> > -            .access = &rae[i],
> > -            .opaque = owner,
> > -        };
> > -        register_init(r);
> > +        if (data + data_size * index == 0 || !&rae[i]) {
> > +            continue;
> 
> Coverity thinks (CID 1432800) that this is dead code, because
> "data + data_size * index" can never be NULL[*]. What was this
> intending to test for ? (maybe data == NULL? Missing dereference
> operator ?)

I believe the original check in the old register_init() function
were just to make the function more flexible by allowing NULL
arguments, but it was always unnecessary.  We have 4 callers of
register_init_block*() and neither rae or data are NULL on those
calls.

> 
> [*] The C spec is quite strict about what valid pointer arithmetic
> is; in particular adding to a NULL pointer is undefined behaviour,
> and pointer arithmetic that overflows and wraps around is
> undefined behaviour, so there's no way to get a 0 result from
> "ptr + offset" without the expression being UB.
> 
> thanks
> -- PMM
> 

-- 
Eduardo


Re: [PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Alistair Francis 5 years, 4 months ago
On Tue, Sep 29, 2020 at 6:22 AM Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:
> > On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
> > >
> > > Reported-by: Eduardo Habkost <ehabkost@redhat.com>
> > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
> > > ---
> > > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> > >          int index = rae[i].addr / data_size;
> > >          RegisterInfo *r = &ri[index];
> > >
> > > -        *r = (RegisterInfo) {
> > > -            .data = data + data_size * index,
> > > -            .data_size = data_size,
> > > -            .access = &rae[i],
> > > -            .opaque = owner,
> > > -        };
> > > -        register_init(r);
> > > +        if (data + data_size * index == 0 || !&rae[i]) {
> > > +            continue;
> >
> > Coverity thinks (CID 1432800) that this is dead code, because
> > "data + data_size * index" can never be NULL[*]. What was this
> > intending to test for ? (maybe data == NULL? Missing dereference
> > operator ?)
>
> I believe the original check in the old register_init() function
> were just to make the function more flexible by allowing NULL
> arguments, but it was always unnecessary.  We have 4 callers of
> register_init_block*() and neither rae or data are NULL on those
> calls.

In this case *data is an array, I guess the idea was to try and catch
if somehow a point in the array was NULL?

I'll send a patch to remove the check.

Alistair

>
> >
> > [*] The C spec is quite strict about what valid pointer arithmetic
> > is; in particular adding to a NULL pointer is undefined behaviour,
> > and pointer arithmetic that overflows and wraps around is
> > undefined behaviour, so there's no way to get a 0 result from
> > "ptr + offset" without the expression being UB.
> >
> > thanks
> > -- PMM
> >
>
> --
> Eduardo
>

Re: [PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Eduardo Habkost 5 years, 4 months ago
On Thu, Oct 01, 2020 at 08:37:31AM -0700, Alistair Francis wrote:
> On Tue, Sep 29, 2020 at 6:22 AM Eduardo Habkost <ehabkost@redhat.com> wrote:
> >
> > On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:
> > > On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
> > > >
> > > > Reported-by: Eduardo Habkost <ehabkost@redhat.com>
> > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > > > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
> > > > ---
> > > > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> > > >          int index = rae[i].addr / data_size;
> > > >          RegisterInfo *r = &ri[index];
> > > >
> > > > -        *r = (RegisterInfo) {
> > > > -            .data = data + data_size * index,
> > > > -            .data_size = data_size,
> > > > -            .access = &rae[i],
> > > > -            .opaque = owner,
> > > > -        };
> > > > -        register_init(r);
> > > > +        if (data + data_size * index == 0 || !&rae[i]) {
> > > > +            continue;
> > >
> > > Coverity thinks (CID 1432800) that this is dead code, because
> > > "data + data_size * index" can never be NULL[*]. What was this
> > > intending to test for ? (maybe data == NULL? Missing dereference
> > > operator ?)
> >
> > I believe the original check in the old register_init() function
> > were just to make the function more flexible by allowing NULL
> > arguments, but it was always unnecessary.  We have 4 callers of
> > register_init_block*() and neither rae or data are NULL on those
> > calls.
> 
> In this case *data is an array, I guess the idea was to try and catch
> if somehow a point in the array was NULL?

I don't understand what you mean.  The area pointed by data
doesn't contain any pointers, just the register values.

> 
> I'll send a patch to remove the check.

Thanks!

-- 
Eduardo


Re: [PULL 2/2] core/register: Specify instance_size in the TypeInfo
Posted by Alistair Francis 5 years, 4 months ago
On Thu, Oct 1, 2020 at 9:05 AM Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> On Thu, Oct 01, 2020 at 08:37:31AM -0700, Alistair Francis wrote:
> > On Tue, Sep 29, 2020 at 6:22 AM Eduardo Habkost <ehabkost@redhat.com> wrote:
> > >
> > > On Tue, Sep 29, 2020 at 01:55:35PM +0100, Peter Maydell wrote:
> > > > On Sun, 27 Sep 2020 at 15:00, Alistair Francis <alistair.francis@wdc.com> wrote:
> > > > >
> > > > > Reported-by: Eduardo Habkost <ehabkost@redhat.com>
> > > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > > > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > > > > Message-Id: <4cf1beb7dafb9143c261d266557d3173bf160524.1598376594.git.alistair.francis@wdc.com>
> > > > > ---
> > > > > @@ -269,13 +258,18 @@ static RegisterInfoArray *register_init_block(DeviceState *owner,
> > > > >          int index = rae[i].addr / data_size;
> > > > >          RegisterInfo *r = &ri[index];
> > > > >
> > > > > -        *r = (RegisterInfo) {
> > > > > -            .data = data + data_size * index,
> > > > > -            .data_size = data_size,
> > > > > -            .access = &rae[i],
> > > > > -            .opaque = owner,
> > > > > -        };
> > > > > -        register_init(r);
> > > > > +        if (data + data_size * index == 0 || !&rae[i]) {
> > > > > +            continue;
> > > >
> > > > Coverity thinks (CID 1432800) that this is dead code, because
> > > > "data + data_size * index" can never be NULL[*]. What was this
> > > > intending to test for ? (maybe data == NULL? Missing dereference
> > > > operator ?)
> > >
> > > I believe the original check in the old register_init() function
> > > were just to make the function more flexible by allowing NULL
> > > arguments, but it was always unnecessary.  We have 4 callers of
> > > register_init_block*() and neither rae or data are NULL on those
> > > calls.
> >
> > In this case *data is an array, I guess the idea was to try and catch
> > if somehow a point in the array was NULL?
>
> I don't understand what you mean.  The area pointed by data
> doesn't contain any pointers, just the register values.

Yeah, I don't think this was ever right.

The idea I guess was to make sure that r.data was not NULL, but unless
data was NULL it couldn't be.

Alistair

>
> >
> > I'll send a patch to remove the check.
>
> Thanks!
>
> --
> Eduardo
>