From: "Liran Alon" <liran.alon@oracle.com>
To: Laszlo Ersek <lersek@redhat.com>,
devel@edk2.groups.io, sean.brogan@microsoft.com
Subject: Re: [edk2-devel] [PATCH] OvmfPkg/PvScsiDxe: Fix VS2019 build error because of implicit cast
Date: Wed, 1 Apr 2020 01:17:56 +0300 [thread overview]
Message-ID: <30a57406-0c09-043f-6b19-7e6e94afcb44@oracle.com> (raw)
In-Reply-To: <5221e324-9f86-24b4-56a0-301a948151f8@oracle.com>
On 01/04/2020 1:13, Liran Alon wrote:
>
> On 01/04/2020 0:56, Laszlo Ersek wrote:
>> On 03/31/20 17:53, Sean via Groups.Io wrote:
>>> A couple of thoughts.
>>> 1. I would suggest that ASSERT should not be the only protection for
>>> an invalid operation as ASSERT is usually disabled on release builds.
>>> 2. We do have a library to make this more explicit and common.
>>> https://urldefense.com/v3/__https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/SafeIntLib.h*L548__;Iw!!GqivPVa7Brio!LNp76poqa4dly7M8C8F3aX66wzZA68yStF_9jS-pD3izw3uJ24i_mDygFJEBsLc$
>>>
>> In this case, when "Response->ScsiStatus" does not fit in
>> "Packet->TargetStatus", the device model is obviously (and blatantly)
>> misbehaving, so I would agree with Liran that trying to recover from
>> that (or to cover it up with a nice error code passed out) is futile.
> Exactly.
>>
>> I do agree with the observation however that ASSERT()s disappear from
>> RELEASE builds.
>>
>> Mike Kinney taught me a pattern to deal with this. There are various
>> ways to write it; one example (for this case) is:
>>
>> ASSERT (Response->ScsiStatus <= MAX_UINT8);
>> if (Response->ScsiStatus > MAX_UINT8) {
>> CpuDeadLoop ();
>> }
>> Packet->TargetStatus = (UINT8)Response->ScsiStatus;
>>
>> An alternative way to write it is (by moving the ASSERT into the block):
>>
>> if (Response->ScsiStatus > MAX_UINT8) {
>> ASSERT (Response->ScsiStatus <= MAX_UINT8);
>> CpuDeadLoop ();
>> }
>> Packet->TargetStatus = (UINT8)Response->ScsiStatus;
>>
>> Yet another (simply assert FALSE in the block):
>>
>> if (Response->ScsiStatus > MAX_UINT8) {
>> ASSERT (FALSE);
>> CpuDeadLoop ();
>> }
>> Packet->TargetStatus = (UINT8)Response->ScsiStatus;
>>
>>
>> Why:
>>
>> - in DEBUG builds, the assertion failure will be logged, and the proper
>> assertion failure action will be triggered (CpuDeadLoop / exception /
>> ..., as configured by the platform)
>>
>> - in RELEASE builds, we'll still hang, and might have a chance to
>> investigate (get a stack dump perhaps).
>>
>> Regarding SafeIntLib, I'm a fan in general. In this case, I did not
>> think of it (possible integer truncations seem so rare in this driver).
>> For this patch, I'm OK either way (with or without using SafeIntLib), as
>> long as we add both the ASSERT and the explicit CpuDeadLoop (either
>> variant of the three).
>>
>> Thanks
>> Laszlo
> Honestly, I don't quite understand why using SafeIntLib is useful in
> this case.
> It just internally does even more branches and checks for exactly same
> overflow and return RETURN_BUFFER_TOO_SMALL in case value is bigger
> than MAX_UINT8.
> Externally, I would still need to do a check on SafeUint16ToUint8()
> return-value. So what's the benefit?... Seems to me to just be an
> useless overhead.
> I believe checking against MAX_UINT8 and casting immediately one line
> afterwards, is explicit enough.
>
> Regarding above comment that ASSERT() doesn't do anything for RELEASE
> builds:
> The point in ASSERT() is to be able to check a condition early to
> assist debugging but not worth putting this condition in RELEASE as it
> should never happen and just waste CPU cycles.
> I thought this is the case we have here. If a weird ScsiStatus would
> return, it is highly unlikely that boot would just succeed as usual,
> and if it does, does the user really care?
> In contrast, when boot fails because of this, it makes sense to build
> in DEBUG in attempt to verify what happened.
> Note that if this condition will ever evaluate to FALSE (i.e.
> ScsiStatus is bigger than MAX_UINT8), then it is probably very
> deterministic. As it means PVSCSI device emulation on host is broken
> and broke because of a very specific commit on host userspace VMM
> (E.g. QEMU).
> Therefore, I still think an ASSERT() is what fits here best. But if
> you still think otherwise, then I have no objection to change it (Or
> Laszlo change it when applying).
> I would say though, that if the pattern above is common, why isn't
> there a macro in EDK2 for that instead of manually writing it?
> Something like:
>
> #define RELEASE_ASSERT(Cond) \
> if (!(Cond)) { \
> ASSERT (FALSE); \
> CpuDeadLoop (); \
> }
>
> That would be more elegant.
>
> -Liran
>
I would also mention that there are some bizzare code in EDK2 that
defines it's own ASSERT() macro that just does CpuDeadLoop().
E.g. ArmVirtPkg/Library/ArmVirtDxeHobLib/HobLib.c and
OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.c)
-Liran
next prev parent reply other threads:[~2020-03-31 22:18 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-31 11:04 [PATCH] OvmfPkg/PvScsiDxe: Fix VS2019 build error because of implicit cast Liran Alon
2020-03-31 15:53 ` [edk2-devel] " Sean
2020-03-31 21:56 ` Laszlo Ersek
2020-03-31 22:13 ` Liran Alon
2020-03-31 22:17 ` Liran Alon [this message]
2020-03-31 22:54 ` Sean
2020-04-01 11:02 ` Laszlo Ersek
2020-04-01 8:36 ` Laszlo Ersek
2020-04-01 8:50 ` Ard Biesheuvel
2020-04-01 11:47 ` Laszlo Ersek
2020-04-01 8:22 ` Laszlo Ersek
2020-04-01 14:46 ` Laszlo Ersek
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-list 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=30a57406-0c09-043f-6b19-7e6e94afcb44@oracle.com \
--to=devel@edk2.groups.io \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox