All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
	"Andrew Jeffery" <andrew@aj.id.au>,
	qemu-devel@nongnu.org, qemu-arm@nongnu.org,
	"Joel Stanley" <joel@jms.id.au>,
	"Cédric Le Goater" <clg@kaod.org>
Subject: Re: [PATCH-for-5.1] hw/misc/aspeed_sdmc: Fix incorrect memory size
Date: Tue, 21 Jul 2020 10:13:06 +0200	[thread overview]
Message-ID: <877duxb819.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <f7dc7d48-6fd7-e1ba-f94b-cd2764490eb7@amsat.org> ("Philippe =?utf-8?Q?Mathieu-Daud=C3=A9=22's?= message of "Mon, 20 Jul 2020 19:39:02 +0200")

Philippe Mathieu-Daudé <f4bug@amsat.org> writes:

> On 7/20/20 6:07 PM, Cédric Le Goater wrote:
>> On 7/20/20 11:58 AM, Philippe Mathieu-Daudé wrote:
>>> The SDRAM Memory Controller has a 32-bit address bus, thus
>>> supports up to 4 GiB of DRAM. There is a signed to unsigned
>>> conversion error with the AST2600 maximum memory size:
>>>
>>>   (uint64_t)(2048 << 20) = (uint64_t)(-2147483648)
>>>                          = 0xffffffff40000000
>>>                          = 16 EiB - 2 GiB
>>>
>>> Fix by using the IEC suffixes which are usually safer, and add
>>> a check to verify the memory is valid. This would have catched

caught

>>> this bug:
>>>
>>>     Unexpected error in aspeed_sdmc_realize() at hw/misc/aspeed_sdmc.c:261:
>>>     qemu-system-arm: Invalid RAM size 16 EiB
>> 
>> Indeed :/
>> 
>>>
>>> Fixes: 1550d72679 ("aspeed/sdmc: Add AST2600 support")
>>> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>>> ---
>>>  hw/misc/aspeed_sdmc.c | 12 +++++++++---
>>>  1 file changed, 9 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
>>> index 0737d8de81..76dd7e6a20 100644
>>> --- a/hw/misc/aspeed_sdmc.c
>>> +++ b/hw/misc/aspeed_sdmc.c
>>> @@ -256,6 +256,12 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
>>>      AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
>>>  
>>>      s->max_ram_size = asc->max_ram_size;
>>> +    if (s->max_ram_size >= 4 * GiB) {
>>> +        char *szstr = size_to_str(s->max_ram_size);
>>> +        error_setg(errp, "Invalid RAM size %s", szstr);
>>> +        g_free(szstr);
>>> +        return;
>>> +    }
>>>
>> 
>> I would put an assert() since the max RAM size is not user configurable. 
>
> As you wish, at this point I'm completely lost with error reporting.

:-/

> Per the manual
> (https://www.mail-archive.com/qemu-devel@nongnu.org/msg723217.html):
>
>  "Many, many devices neglect to clean up properly on error, and get away
>   with it only because all callers treat errors as fatal.
>
>   If you decide to take cleanup shortcuts, say because the cleanup is
>   untestable, consider adding a comment at least."
>
> So I'll go for address + comment:
>
>   assert(s->max_ram_size < 4 * GiB); /* 32-bit address bus */

Makes sense.

Note this is *not* a cleanup shortcut, at least not the kind I had in
mind.

What I had in mind is unclean failure, i.e. returning on error without
proper cleanup: revert changes made so far, free resources.  This is
*wrong*.  But the wrongness doesn't matter when all callers treat errors
as fatal.

Checking an impossible condition with assert() is better than treating
it as an error and bungling its handling.  If you treat it as an error,
do it properly.  Since I'm quite skeptical about the chances of pulling
off "properly" for untestable things, I prefer assertions.

There's another reason.  User errors need to be handled gracefully.
Programming errors should (in my opinion) trigger abort(), so they get
fixed.

When the spot that detects the error can't know which kind it is, you
have to fail cleanly and let the caller decide how to handle the error.

Example: object_property_find() errors out when the property doesn't
exist.  This may be a programming error, e.g. a well-known property
isn't found, because a programmer mistyped the property name.  Or it may
be a user error, e.g. a user mistyped the property name argument of
qom-get.

When functions have multiple failure modes, and only some of them are
programming errors, the caller typically can't tell them apart, and errs
on the side of user error.  Programming errors then get reported as
(typically confusing!) user errors.

The #1 reason for such awkward functions is lazy thinking + eager
typing: by treating anything that can go wrong as an error for the
caller to handle, I can replace thinking about what may go wrong and
what must not go wrong by typing up a bunch of error paths.  Great time
saver as long as I stick to the time-honored strategy of not bothering
to test my error paths.



  reply	other threads:[~2020-07-21  8:17 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-20  9:58 [PATCH-for-5.1] hw/misc/aspeed_sdmc: Fix incorrect memory size Philippe Mathieu-Daudé
2020-07-20 10:04 ` no-reply
2020-07-20 10:04 ` no-reply
2020-07-20 16:07 ` Cédric Le Goater
2020-07-20 17:39   ` Philippe Mathieu-Daudé
2020-07-21  8:13     ` Markus Armbruster [this message]
2020-07-21  9:06       ` Philippe Mathieu-Daudé
2020-07-21  9:55         ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877duxb819.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=andrew@aj.id.au \
    --cc=clg@kaod.org \
    --cc=f4bug@amsat.org \
    --cc=joel@jms.id.au \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.