On 01/24/19 12:37, Tomas Pilar (tpilar) wrote:
> 
> Hi Laszlo,
> 
>> Can you capture a call stack when Snp.Start() is invoked for the very
>> first time (which, IIUC, is a call that should not happen, in your
>> opinion)?
>>
> Unfortunately I do not have access to the platform firmware itself (I 
> maintain an IHV network driver that's shipped in OptionROMs) and I don't 
> believe a generic stack capture is available in EDK2 yet. However I have 
> comprehensive debug from my driver that shows that our driver gets a 
> DriverBinding.Start() at TPL_APPLICATION and we perform the entire probe at 
> TPL_NOTIFY and as soon as that completes and we drop the TPL, the newly 
> installed SNP gets a Snp.Start() call at TPL_CALLBACK - I assume that MNP or 
> something higher had an event registered that fired as soon as the TPL 
> dropped after the DriverBinding.Start() finished.
> 
> Here is a snip of the debug log (that I assume will not be of much interest). 
> We don't observe the actual call to DriverBinding.Start() because the debug 
> output is initialised as one of the first things that method does.
> 
> [...] 
> 
> The dots between [sfc] and | symbol indicate the TPL the operation is being 
> carried out at. No dots mean TPL_APPLICATION, one dot is TPL_CALLBACK etc. 
> You can see that the Snp.Start() on the first device is called before even 
> the second device gets a DriverBinding.Start().

This reeks. :)

It looks like some driver in the platform sets up a protocol notify
callback for SNP, with gBS->CreateEvent() +
gBS->RegisterProtocolNotify(). Your driver's DriverBindingStart()
function is called normally from BDS, via ConnectController(). In
DriverBindingStart(), you install an SNP instance, which signals the
event (makes it pending / queues the notification function for it). Once
you drop the TPL again, the notification function is called, on the
stack of gBS->RestoreTPL().

The event's notification funciton probably uses the "Registration"
feature of gBS->RegisterProtocolNotify(), together with
gBS->LocateProtocol(), to process only those SNP instances that it
hasn't seen yet. In other words, it catches exactly the SNP instance
that your driver just produced, and then it calls the Start() member of it.

This looks wrong to me; SNP is supposed to be consumed in accordance
with the UEFI Driver Model. An agent that behaved like described above
would most likely be a platform (DXE) driver lying in wait for network
connectivity (SNP), for some reason.

(The Driver Writer’s Guide for UEFI 2.3.1, Version 1.01, 03/08/2012,
explicitly lists RegisterProtocolNotify() in chapter 5.3 "Services that
UEFI drivers should not use".)

Something's fishy with the platform firmware, IMO. Even if the rest of
the network stack -- which consists of well-behaving UEFI drivers that
follow the UEFI Driver Model -- comes to life, that one sneaky platform
DXE driver will be there, poking at your SNP directly, for example under
the feet of the MNP driver. That seems plain wrong.


I've now run

  git grep -A10 -B10 -w gEfiSimpleNetworkProtocolGuid

on edk2, and then searched the output for "RegisterProtocolNotify".
There were no hits. So, I don't think anything in edk2 behaves like
described above (thankfully!).


You mentioned seeing this on "DELL 13G platforms". I suggest opening a
support case with Dell.

Thanks
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to