Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freeze during "initialising devices" in Virtualbox when chainloading #977

Open
mcb30 opened this issue Jun 22, 2023 · 4 comments
Open

Freeze during "initialising devices" in Virtualbox when chainloading #977

mcb30 opened this issue Jun 22, 2023 · 4 comments

Comments

@mcb30
Copy link
Member

mcb30 commented Jun 22, 2023

Same problem with Virtualbox 7.0.8 and all Intel 1000 cards in EFI mode

Originally posted by @Reonaydo in #624 (comment)

Reproduction instructions: create new VirtualBox VM with EFI mode selected, attempt chainloading ipxe.efi.

@mcb30
Copy link
Member Author

mcb30 commented Jun 22, 2023

Testing with some extra debug shows that the freeze occurs when we attempt to open the PCI I/O protocol with BY_DRIVER attributes:

	/* Open PCI device */
	if ( ( rc = efipci_open ( device, ( EFI_OPEN_PROTOCOL_BY_DRIVER |
					    EFI_OPEN_PROTOCOL_EXCLUSIVE ),
				  efipci ) ) != 0 ) {
		DBGC ( device, "EFIPCI %s could not open PCI device: %s\n",
		       efi_handle_name ( device ), strerror ( rc ) );
		DBGC_EFI_OPENERS ( device, device, &efi_pci_io_protocol_guid );
		goto err_open;
	}

image

The debug messages show that even after disconnection, the VirtualBox "E1000 network interface card Driver" still has the handle open with BY_DRIVER attributes. This suggests that the freeze is caused by the platform firmware being stuck in a loop attempting to repeatedly disconnect the driver, but the driver is failing each time to close its BY_DRIVER handle.

@mcb30
Copy link
Member Author

mcb30 commented Jun 22, 2023

This failure of the VirtualBox "E1000 network interface card Driver" to disconnect properly can be reproduced without any iPXE code using the UEFI shell:

image

@mcb30
Copy link
Member Author

mcb30 commented Jun 22, 2023

I have found the root cause bug within the VirtualBox VBoxPkg E1kNetDxe driver.

The VirtualBox driver's Stop() method will do absolutely nothing unless called with a non-zero number of children:

STATIC
EFI_STATUS
EFIAPI
E1kNetDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  ControllerHandle,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
{
  if (NumberOfChildren > 0) {
    //
    // free all resources for whose access we need the child handle, because
    // the child handle is going away
    //
    EFI_STATUS                  Status;
    EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
    E1K_NET_DEV                 *Dev;
    EFI_TPL                     OldTpl;

    ASSERT (NumberOfChildren == 1);

    ......

      gBS->CloseProtocol (
             ControllerHandle,
             &gEfiPciIoProtocolGuid,
             This->DriverBindingHandle,
             ControllerHandle
             );

    ......
  }

  return EFI_SUCCESS;
}

This relies on the driver's Start() method having opened the underlying PCI I/O protocol handle with BY_CHILD_CONTROLLER attributes on behalf of its newly created SNP protocol handle, so that the UEFI firmware can be aware of the parent-child relationship and therefore pass in a list of child handles to the Stop() method. However, the VirtualBox driver's Start() method never performs this BY_CHILD_CONTROLLER open.

This bug can be observed directly in the UEFI shell's list of devices:

image

Note that device AB (the SNP protocol handle) is not shown as a child of device 9E (the PCI I/O protocol handle).

The net effect is that the VirtualBox driver's Stop() method is a pure no-op: it will never close the PCI I/O protocol handle as required.

@veeyoung
Copy link

solved it by chaging network adapter type from intel pro 1000 to pcnet fast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants