public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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



  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