OptionROM driver update failing in UEFI 2.4 but works on UEFI 2.3.1


UdayS <udai16787@...>
 

Hi All,
SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using component name to get the revision info and if existing version is older than current, then UninstallMultipleProtocolInterfaces and unloadImage.
This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a hang.
I have been banging my around this for last couple for days and now I am in need of some expert advice.
All suggestions are welcome..

Thanks
US


udai sharma <udai16787@...>
 

Hi Team,
I have developed a UEFI Bus Driver, loaded it as an PCI Option ROM on PCI adapter.

Issue I am facing is with the during version updates.
In DriverSupported, SW update logic present looks for existing driver using componentname, gets its
version number and compares with the version number of current driver. If Current driver version is
better, UninstallMultipleProtocolInterfaces and UnloadImage using the HandleBuffer[index]. After
unload, EfiLibInstallAllDriverProtocols on new image handle and InstallMultipleProtocolInterfaces for
other protocols.

This update logic seem to work fine on 2.3.1 based system, but when I tested the same on 2.4 system, it
goes for a hang.

Steps followed to verify from Shell:
1. 'loadpcirom MyRom.rom' with version 1.0.
2. verify the 'dh '
3. Now try to upgrade image, 'loadpcirom MyRom.rom' with version 2.0. UnloadImage, because it is already present in the SW update logic.>
4. At this point I see DriverSupported and DriverStart logic getting called. But after that system goes
for a hang.

I am unable to figure where is the issue. Can you please guide me here.

Thanks in advance.
-US


Laszlo Ersek
 

+Andrew:

On 07/27/20 11:57, UdayS via groups.io wrote:
Hi All,
SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using component name to get the revision info and if existing version is older than current, then UninstallMultipleProtocolInterfaces and unloadImage.
This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a hang.
I have been banging my around this for last couple for days and now I am in need of some expert advice.
All suggestions are welcome..
Andrew, do you recall changes related to driver dispatch between 2.3.1
and 2.4? Not necessarily in the spec, but maybe in edk2.

Thanks
Laszlo


Tomas Pilar (tpilar)
 

I wouldn't be surprised if this was caused by improper memory management on unload (I actually wrote this kind of Highlander Protocol for the sfc driver). This is what I would expect the driver to do:

0. If a newer driver exists in the system, the loading driver should just exit without doing anything.
1. If the current driver finds an older driver in the system, it should only call LoadedImage->Unload() on the image handle, nothing more.
2. The old driver should perform protocol uninstallation in its Unload() function - it should clean up after itself perfectly. (This is where most of the problems will likely lie)
3. The new driver can proceed with loading as normal.

This can and should be tested by taking each driver and repeatedly loading and unloading it (the same driver) in shell - you will likely catch a few bugs this way. Then you can add tests for two different versions interacting with each other.

Cheers,
Tom


Andrew Fish <afish@...>
 

On Jul 30, 2020, at 5:23 AM, Laszlo Ersek <lersek@redhat.com> wrote:

+Andrew:

On 07/27/20 11:57, UdayS via groups.io wrote:
Hi All,
SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using component name to get the revision info and if existing version is older than current, then UninstallMultipleProtocolInterfaces and unloadImage.
What protocols are being uninstalled, and what driver is being unloaded? If you return an error from your driver it will get unloaded.

I don’t understand the combination of gBS->UnloadIMage() and UninstallMultipleProtocolInterfaces()? The unload function in the driver should do all the work? You would use UninstallMultipleProtocolInterfaces() on your protocols prior to error exiting. If you driver returns an error it gets unloaded.

Maybe there is a bug in the Unload function. Is the Unload function disconnecting other drivers off its handle properly?

This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a hang.
I have been banging my around this for last couple for days and now I am in need of some expert advice.
All suggestions are welcome..
Andrew, do you recall changes related to driver dispatch between 2.3.1
and 2.4? Not necessarily in the spec, but maybe in edk2.
I don’t recall any changes in spec or edk2.

Thanks,

Andrew Fish

Thanks
Laszlo


Andrew Fish <afish@...>
 



On Aug 3, 2020, at 8:58 AM, udai sharma <udai16787@...> wrote:

Hi Andrew, Laszlo, Tomas,
Thanks for your comments. 

I wrote a simple Test optiom Driver [Attached init.c] to verify the unload part, with minimum protocol 
install for a UEFI PCI BUS driver.

From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then 'unload '. I saw it seem 
to work. 
So I created two ROM versions, 0xAA and 0xBB. I updated the 'TestDxeAA.rom' in the option rom of the 
two PCI devices present in my system. At bootup I see DriverStart getting called, just fine. From 
Shell, I see the 'dh ' dumping proper data. 
Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a hang again. I did capture 
everything [Attached TestROM.log]. 
In 2.3.1 based system I see it works fine but the similar procedure doesn't work in 2.4 system.
It ASSERT's with "Status = UNSUPPORTED" in 2.4.  

So gBS->UnloadImage() is returning EFI_UNSUPPORTED. Per the UEFI Spec that implies that driver did not register an unload function. Unload functions are not required. 

Thanks,

Andrew Fish


Thanks in advance.


On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote
>



> On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:

> 

> +Andrew:

> 

> On 07/27/20 11:57, UdayS via groups.io wrote:

>> Hi All,

>> SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using 
component name to get the revision info and if existing version is older than current, then 
UninstallMultipleProtocolInterfaces and unloadImage. 



What protocols are being uninstalled, and what driver is being unloaded? If you return an error from 
your driver it will get unloaded. 



I don’t understand the combination of gBS->UnloadIMage() and UninstallMultipleProtocolInterfaces()? The 
unload function in the driver should do all the work? You would use 
UninstallMultipleProtocolInterfaces() on your protocols prior to error exiting. If you driver returns 
an error it gets unloaded. 



Maybe there is a bug in the Unload function. Is the Unload function disconnecting other drivers off its 
handle properly? 



>> This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a 
hang.

>> I have been banging my around this for last couple for days and now I am in need of some expert 
advice.

>> All suggestions are welcome..

> 

> Andrew, do you recall changes related to driver dispatch between 2.3.1

> and 2.4? Not necessarily in the spec, but maybe in edk2.

> 



I don’t recall any changes in spec or edk2. 



Thanks,



Andrew Fish



> Thanks

> Laszlo

> 

<TestRom.log><Init.c>


udai sharma <udai16787@...>
 

Hi Andrew, Laszlo, Tomas,
Thanks for your comments.

I wrote a simple Test optiom Driver [Attached init.c] to verify the unload part, with minimum protocol
install for a UEFI PCI BUS driver.

From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then 'unload '. I saw it seem
to work.
So I created two ROM versions, 0xAA and 0xBB. I updated the 'TestDxeAA.rom' in the option rom of the
two PCI devices present in my system. At bootup I see DriverStart getting called, just fine. From
Shell, I see the 'dh ' dumping proper data.
Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a hang again. I did capture
everything [Attached TestROM.log].
In 2.3.1 based system I see it works fine but the similar procedure doesn't work in 2.4 system.
It ASSERT's with "Status = UNSUPPORTED" in 2.4.

Thanks in advance.


On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote
>



> On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:

>

> +Andrew:

>

> On 07/27/20 11:57, UdayS via groups.io wrote:

>> Hi All,

>> SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using
component name to get the revision info and if existing version is older than current, then
UninstallMultipleProtocolInterfaces and unloadImage.



What protocols are being uninstalled, and what driver is being unloaded? If you return an error from
your driver it will get unloaded.



I don’t understand the combination of gBS->UnloadIMage() and UninstallMultipleProtocolInterfaces()? The
unload function in the driver should do all the work? You would use
UninstallMultipleProtocolInterfaces() on your protocols prior to error exiting. If you driver returns
an error it gets unloaded.



Maybe there is a bug in the Unload function. Is the Unload function disconnecting other drivers off its
handle properly?



>> This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a
hang.

>> I have been banging my around this for last couple for days and now I am in need of some expert
advice.

>> All suggestions are welcome..

>

> Andrew, do you recall changes related to driver dispatch between 2.3.1

> and 2.4? Not necessarily in the spec, but maybe in edk2.

>



I don’t recall any changes in spec or edk2.



Thanks,



Andrew Fish



> Thanks

> Laszlo

>


Liming Gao
 

I review Edk2 DxeMain history. gBS->UnloadImage() behavior has no change in UEFI2.3 and UEFI2.4. Which UEFI system are you using?

Thanks
Liming
From: discuss@edk2.groups.io <discuss@edk2.groups.io> On Behalf Of Andrew Fish via groups.io
Sent: 2020年8月4日 2:44
To: udai sharma <udai16787@rediffmail.com>
Cc: tomas@nuviainc.com; lersek@redhat.com; discuss@edk2.groups.io
Subject: Re: [edk2-discuss] OptionROM driver update failing in UEFI 2.4 but works on UEFI 2.3.1




On Aug 3, 2020, at 8:58 AM, udai sharma <udai16787@rediffmail.com<mailto:udai16787@rediffmail.com>> wrote:

Hi Andrew, Laszlo, Tomas,
Thanks for your comments.

I wrote a simple Test optiom Driver [Attached init.c] to verify the unload part, with minimum protocol
install for a UEFI PCI BUS driver.

From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then 'unload '. I saw it seem
to work.
So I created two ROM versions, 0xAA and 0xBB. I updated the 'TestDxeAA.rom' in the option rom of the
two PCI devices present in my system. At bootup I see DriverStart getting called, just fine. From
Shell, I see the 'dh ' dumping proper data.
Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a hang again. I did capture
everything [Attached TestROM.log].
In 2.3.1 based system I see it works fine but the similar procedure doesn't work in 2.4 system.
It ASSERT's with "Status = UNSUPPORTED" in 2.4.

So gBS->UnloadImage() is returning EFI_UNSUPPORTED. Per the UEFI Spec that implies that driver did not register an unload function. Unload functions are not required.

Thanks,

Andrew Fish



Thanks in advance.


On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote


On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:
+Andrew:
On 07/27/20 11:57, UdayS via groups.io<http://groups.io/> wrote:
Hi All,
SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using
component name to get the revision info and if existing version is older than current, then
UninstallMultipleProtocolInterfaces and unloadImage.



What protocols are being uninstalled, and what driver is being unloaded? If you return an error from
your driver it will get unloaded.



I don’t understand the combination of gBS->UnloadIMage() and UninstallMultipleProtocolInterfaces()? The
unload function in the driver should do all the work? You would use
UninstallMultipleProtocolInterfaces() on your protocols prior to error exiting. If you driver returns
an error it gets unloaded.



Maybe there is a bug in the Unload function. Is the Unload function disconnecting other drivers off its
handle properly?



This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a
hang.

I have been banging my around this for last couple for days and now I am in need of some expert
advice.

All suggestions are welcome..
Andrew, do you recall changes related to driver dispatch between 2.3.1
and 2.4? Not necessarily in the spec, but maybe in edk2.


I don’t recall any changes in spec or edk2.



Thanks,



Andrew Fish



Thanks
Laszlo
<TestRom.log><Init.c>


Tomas Pilar (tpilar)
 

You can register your unload function in the .inf file for your driver like this:

[Defines]
...
UNLOAD_IMAGE = MyUnloadFunction


Tomas Pilar (tpilar)
 

The difference between the 5.11 AMI bios and 4.654 AMI bios will be much,
much bigger than just the difference between the spec revisions from 2.31
to 2.4. The spec revision is just the set of APIs the bios is compliant
with, it says nothing about the internal implementation. And while it's
probably based on EDK2, the IBV has almost certainly added many more
features between those two versions.

What you are hitting is likely some guard that has simply failed silently
previously, but with the new bios it has been made stricter and now hangs
instead.

Your first point of call should be to actually register the Unload()
function in the driver .inf file. Then you should test your driver to be
safe to repeatedly reload in the UEFI shell - the same version of the
driver, not two different versions. Then you can start thinking about how
different versions interact.

Cheers,
Tom

On Tue, Aug 4, 2020 at 12:36 PM udai sharma <udai16787@rediffmail.com>
wrote:

Hi Liming,

I have SuperMicro X8 and X10 UEFI systems with me.

X10 AMI motherboard version:
EFI spec revision 2.4
EFI revision 5.11

X8 AMI motherboard version:
EFI spec revision 2.31
EFI revision 4.654

Even I did comparison between UEFI2.3.1 and UEFI2.4 code in TianoCore,
CoreUnloadImage SW remains
unchanged.

Can you suggest what is the correct way to unload Old driver and install
the current/new one. I was not
expecting this breakage to happen in our driver.

Thanks.


On Tue, 04 Aug 2020 13:23:51 +0530 "Gao, Liming" wrote






I review Edk2 DxeMain history. gBS->UnloadImage() behavior has no change
in UEFI2.3 and UEFI2.4. Which
UEFI system are you using?

Thanks
Liming


From: discuss@edk2.groups.io
On Behalf Of Andrew Fish via groups.io

Sent: 2020年8月4日
2:44

To: udai sharma

Cc: tomas@nuviainc.com; lersek@redhat.com; discuss@edk2.groups.io

Subject: Re: [edk2-discuss] OptionROM driver update failing in UEFI 2.4
but works on UEFI 2.3.1












On Aug 3, 2020, at 8:58 AM, udai sharma wrote:



Hi Andrew, Laszlo, Tomas,

Thanks for your comments.



I wrote a simple Test optiom Driver [Attached init.c] to verify the unload
part, with minimum protocol

install for a UEFI PCI BUS driver.



From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then
'unload '. I saw it seem

to work.

So I created two ROM versions, 0xAA and 0xBB. I updated the
'TestDxeAA.rom' in the option rom of the

two PCI devices present in my system. At bootup I see DriverStart getting
called, just fine. From

Shell, I see the 'dh ' dumping proper data.

Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a
hang again. I did capture

everything [Attached TestROM.log].

In 2.3.1 based system I see it works fine but the similar procedure
doesn't work in 2.4 system.

It ASSERT's with "Status = UNSUPPORTED" in 2.4.






So gBS->UnloadImage() is returning EFI_UNSUPPORTED. Per the UEFI Spec that
implies that driver did not
register an unload function. Unload functions are not required.





Thanks,





Andrew Fish










Thanks in advance.





On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote







On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:




+Andrew:




On 07/27/20 11:57, UdayS viagroups.iowrote:


Hi All,


SW Revision updates to my Option Rom/Driver is handled properly during
the EntryPoint i.e., using

component name to get the revision info and if existing version is older
than current, then

UninstallMultipleProtocolInterfaces and unloadImage.







What protocols are being uninstalled, and what driver is being unloaded?
If you return an error from

your driver it will get unloaded.







I don’t understand the combination of gBS->UnloadIMage() and
UninstallMultipleProtocolInterfaces()? The

unload function in the driver should do all the work? You would use

UninstallMultipleProtocolInterfaces() on your protocols prior to error
exiting. If you driver returns

an error it gets unloaded.







Maybe there is a bug in the Unload function. Is the Unload function
disconnecting other drivers off its

handle properly?







This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4
based system, it goes for a

hang.



I have been banging my around this for last couple for days and now I
am in need of some expert

advice.



All suggestions are welcome..




Andrew, do you recall changes related to driver dispatch between 2.3.1


and 2.4? Not necessarily in the spec, but maybe in edk2.








I don’t recall any changes in spec or edk2.







Thanks,







Andrew Fish







Thanks


Laszlo

















Tomas Pilar (tpilar)
 

You can register your unload function in the .inf file for your driver like
this:

[Defines]
...
UNLOAD_IMAGE = MyUnloadFunction

On Mon, Aug 3, 2020 at 7:43 PM Andrew Fish <afish@apple.com> wrote:



On Aug 3, 2020, at 8:58 AM, udai sharma <udai16787@rediffmail.com> wrote:

Hi Andrew, Laszlo, Tomas,
Thanks for your comments.

I wrote a simple Test optiom Driver [Attached init.c] to verify the unload
part, with minimum protocol
install for a UEFI PCI BUS driver.

From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then
'unload '. I saw it seem
to work.
So I created two ROM versions, 0xAA and 0xBB. I updated the
'TestDxeAA.rom' in the option rom of the
two PCI devices present in my system. At bootup I see DriverStart getting
called, just fine. From
Shell, I see the 'dh ' dumping proper data.
Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a
hang again. I did capture
everything [Attached TestROM.log].
In 2.3.1 based system I see it works fine but the similar procedure
doesn't work in 2.4 system.
It ASSERT's with "Status = UNSUPPORTED" in 2.4.


So gBS->UnloadImage() is returning EFI_UNSUPPORTED. Per the UEFI Spec that
implies that driver did not register an unload function. Unload functions
are not required.

Thanks,

Andrew Fish


Thanks in advance.


On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote


On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:
+Andrew:
On 07/27/20 11:57, UdayS via groups.io wrote:
Hi All,
SW Revision updates to my Option Rom/Driver is handled properly during
the EntryPoint i.e., using
component name to get the revision info and if existing version is older
than current, then
UninstallMultipleProtocolInterfaces and unloadImage.



What protocols are being uninstalled, and what driver is being unloaded?
If you return an error from
your driver it will get unloaded.



I don’t understand the combination of gBS->UnloadIMage() and
UninstallMultipleProtocolInterfaces()? The
unload function in the driver should do all the work? You would use
UninstallMultipleProtocolInterfaces() on your protocols prior to error
exiting. If you driver returns
an error it gets unloaded.



Maybe there is a bug in the Unload function. Is the Unload function
disconnecting other drivers off its
handle properly?



This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4
based system, it goes for a
hang.

I have been banging my around this for last couple for days and now I
am in need of some expert
advice.

All suggestions are welcome..
Andrew, do you recall changes related to driver dispatch between 2.3.1
and 2.4? Not necessarily in the spec, but maybe in edk2.


I don’t recall any changes in spec or edk2.



Thanks,



Andrew Fish



Thanks
Laszlo
<TestRom.log><Init.c>



udai sharma <udai16787@...>
 

Hi Liming,

I have SuperMicro X8 and X10 UEFI systems with me.

X10 AMI motherboard version:
EFI spec revision 2.4
EFI revision 5.11

X8 AMI motherboard version:
EFI spec revision 2.31
EFI revision 4.654

Even I did comparison between UEFI2.3.1 and UEFI2.4 code in TianoCore, CoreUnloadImage SW remains
unchanged.

Can you suggest what is the correct way to unload Old driver and install the current/new one. I was not
expecting this breakage to happen in our driver.

Thanks.


On Tue, 04 Aug 2020 13:23:51 +0530 "Gao, Liming" wrote
>







I review Edk2 DxeMain history. gBS->UnloadImage() behavior has no change in UEFI2.3 and UEFI2.4. Which
UEFI system are you using?

Thanks
Liming


From: discuss@edk2.groups.io
On Behalf Of Andrew Fish via groups.io

Sent: 2020年8月4日
2:44

To: udai sharma

Cc: tomas@...; lersek@...; discuss@edk2.groups.io

Subject: Re: [edk2-discuss] OptionROM driver update failing in UEFI 2.4 but works on UEFI 2.3.1












On Aug 3, 2020, at 8:58 AM, udai sharma wrote:



Hi Andrew, Laszlo, Tomas,

Thanks for your comments.



I wrote a simple Test optiom Driver [Attached init.c] to verify the unload part, with minimum protocol

install for a UEFI PCI BUS driver.



From shell I loaded the ROM using 'loadpcirom TestDxeAA.rom' and then 'unload '. I saw it seem

to work.

So I created two ROM versions, 0xAA and 0xBB. I updated the 'TestDxeAA.rom' in the option rom of the

two PCI devices present in my system. At bootup I see DriverStart getting called, just fine. From

Shell, I see the 'dh ' dumping proper data.

Then I tried 'loadpcirom TestDxeBB.rom' to update existing driver, I see a hang again. I did capture

everything [Attached TestROM.log].

In 2.3.1 based system I see it works fine but the similar procedure doesn't work in 2.4 system.

It ASSERT's with "Status = UNSUPPORTED" in 2.4.






So gBS->UnloadImage() is returning EFI_UNSUPPORTED. Per the UEFI Spec that implies that driver did not
register an unload function. Unload functions are not required.





Thanks,





Andrew Fish










Thanks in advance.





On Thu, 30 Jul 2020 21:11:55 +0530 Andrew Fish wrote

>







> On Jul 30, 2020, at 5:23 AM, Laszlo Ersek wrote:



>



> +Andrew:



>



> On 07/27/20 11:57, UdayS viagroups.iowrote:



>> Hi All,



>> SW Revision updates to my Option Rom/Driver is handled properly during the EntryPoint i.e., using

component name to get the revision info and if existing version is older than current, then

UninstallMultipleProtocolInterfaces and unloadImage.







What protocols are being uninstalled, and what driver is being unloaded? If you return an error from

your driver it will get unloaded.







I don’t understand the combination of gBS->UnloadIMage() and UninstallMultipleProtocolInterfaces()? The

unload function in the driver should do all the work? You would use

UninstallMultipleProtocolInterfaces() on your protocols prior to error exiting. If you driver returns

an error it gets unloaded.







Maybe there is a bug in the Unload function. Is the Unload function disconnecting other drivers off its

handle properly?







>> This seem to work in UEFI 2.3.1 but when I test the same SW in UEFI 2.4 based system, it goes for a

hang.



>> I have been banging my around this for last couple for days and now I am in need of some expert

advice.



>> All suggestions are welcome..



>



> Andrew, do you recall changes related to driver dispatch between 2.3.1



> and 2.4? Not necessarily in the spec, but maybe in edk2.



>







I don’t recall any changes in spec or edk2.







Thanks,







Andrew Fish







> Thanks



> Laszlo



>