]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/PlatformBootManagerLib: connect Virtio RNG devices again
authorLaszlo Ersek <lersek@redhat.com>
Thu, 17 May 2018 19:51:11 +0000 (21:51 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Fri, 18 May 2018 11:51:21 +0000 (13:51 +0200)
Virtio RNG devices are never boot devices, so in commit 245c643cc8b7 we
stopped connecting them. This is a problem because an OS boot loader may
depend on EFI_RNG_PROTOCOL to seed the OS's RNG.

Connect Virtio RNG devices again. And, while commit 245c643cc8b7 removed
that from PlatformBootManagerAfterConsole(), reintroduce it now to
PlatformBootManagerBeforeConsole() -- this way Driver#### options launched
between both functions may access EFI_RNG_PROTOCOL too.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Fixes: 245c643cc8b73240c3b88cb55b2911b285a8c10d
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1579518
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h

index 004b753f4d26a3ab19933b90ef0b192f67a0092b..5d4d323d730665bdaad25568214f8cbe557e927e 100644 (file)
@@ -318,6 +318,15 @@ ConnectRootBridge (
   IN VOID        *Context\r
   );\r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectVirtioPciRng (\r
+  IN EFI_HANDLE Handle,\r
+  IN VOID       *Instance,\r
+  IN VOID       *Context\r
+  );\r
+\r
 STATIC\r
 VOID\r
 SaveS3BootScript (\r
@@ -399,6 +408,13 @@ PlatformBootManagerBeforeConsole (
   ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   PlatformRegisterOptionsAndKeys ();\r
+\r
+  //\r
+  // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL\r
+  // instances on Virtio PCI RNG devices.\r
+  //\r
+  VisitAllInstancesOfProtocol (&gEfiPciIoProtocolGuid, ConnectVirtioPciRng,\r
+    NULL);\r
 }\r
 \r
 \r
@@ -427,6 +443,95 @@ ConnectRootBridge (
 }\r
 \r
 \r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectVirtioPciRng (\r
+  IN EFI_HANDLE Handle,\r
+  IN VOID       *Instance,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  EFI_STATUS          Status;\r
+  UINT16              VendorId;\r
+  UINT16              DeviceId;\r
+  UINT8               RevisionId;\r
+  BOOLEAN             Virtio10;\r
+  UINT16              SubsystemId;\r
+\r
+  PciIo = Instance;\r
+\r
+  //\r
+  // Read and check VendorId.\r
+  //\r
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET,\r
+                        1, &VendorId);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  if (VendorId != VIRTIO_VENDOR_ID) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Read DeviceId and RevisionId.\r
+  //\r
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,\r
+                        1, &DeviceId);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_REVISION_ID_OFFSET,\r
+                        1, &RevisionId);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // From DeviceId and RevisionId, determine whether the device is a\r
+  // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can\r
+  // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and\r
+  // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can\r
+  // only be sanity-checked, and SubsystemId will decide.\r
+  //\r
+  if (DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE &&\r
+      RevisionId >= 0x01) {\r
+    Virtio10 = TRUE;\r
+  } else if (DeviceId >= 0x1000 && DeviceId <= 0x103F && RevisionId == 0x00) {\r
+    Virtio10 = FALSE;\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Read and check SubsystemId as dictated by Virtio10.\r
+  //\r
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,\r
+                        PCI_SUBSYSTEM_ID_OFFSET, 1, &SubsystemId);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  if ((Virtio10 && SubsystemId >= 0x40) ||\r
+      (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {\r
+    Status = gBS->ConnectController (\r
+                    Handle, // ControllerHandle\r
+                    NULL,   // DriverImageHandle -- connect all drivers\r
+                    NULL,   // RemainingDevicePath -- produce all child handles\r
+                    FALSE   // Recursive -- don't follow child handles\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Error;\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+\r
+Error:\r
+  DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.\r
 \r
index 97ffbb51482524695ffb914903bf2b226a5fad86..4948ca6518ec0be1e96d4d7849289d5864030098 100644 (file)
@@ -30,6 +30,7 @@ Abstract:
 #include <IndustryStandard/Acpi.h>\r
 #include <IndustryStandard/SmBios.h>\r
 #include <IndustryStandard/PeImage.h>\r
+#include <IndustryStandard/Virtio095.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r