render / rpms / edk2

Forked from rpms/edk2 3 months ago
Clone

Blame 0051-ArmVirtPkg-PlatformBootManagerLib-connect-Virtio-RNG.patch

Paolo Bonzini 9fbea3
From c4add6b6e971e0bb3f276ed3636a083e782e96cc Mon Sep 17 00:00:00 2001
Paolo Bonzini 9fbea3
From: Laszlo Ersek <lersek@redhat.com>
Paolo Bonzini 9fbea3
Date: Thu, 17 May 2018 21:51:11 +0200
Paolo Bonzini 9fbea3
Subject: [PATCH] ArmVirtPkg/PlatformBootManagerLib: connect Virtio RNG devices
Paolo Bonzini 9fbea3
 again
Paolo Bonzini 9fbea3
Paolo Bonzini 9fbea3
Virtio RNG devices are never boot devices, so in commit ff1d0fbfbaec we
Paolo Bonzini 9fbea3
stopped connecting them. This is a problem because an OS boot loader may
Paolo Bonzini 9fbea3
depend on EFI_RNG_PROTOCOL to seed the OS's RNG.
Paolo Bonzini 9fbea3
Paolo Bonzini 9fbea3
Connect Virtio RNG devices again. And, while commit ff1d0fbfbaec removed
Paolo Bonzini 9fbea3
that from PlatformBootManagerAfterConsole(), reintroduce it now to
Paolo Bonzini 9fbea3
PlatformBootManagerBeforeConsole() -- this way Driver#### options launched
Paolo Bonzini 9fbea3
between both functions may access EFI_RNG_PROTOCOL too.
Paolo Bonzini 9fbea3
Paolo Bonzini 9fbea3
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Paolo Bonzini 9fbea3
Fixes: ff1d0fbfbaec55038ccf888759588fa4e21516f4
Paolo Bonzini 9fbea3
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1579518
Paolo Bonzini 9fbea3
Contributed-under: TianoCore Contribution Agreement 1.1
Paolo Bonzini 9fbea3
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Paolo Bonzini 9fbea3
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Paolo Bonzini 9fbea3
---
Paolo Bonzini 9fbea3
 .../PlatformBootManagerLib.inf                |   1 +
Paolo Bonzini 9fbea3
 .../PlatformBootManagerLib/PlatformBm.c       | 129 ++++++++++++++++++
Paolo Bonzini 9fbea3
 2 files changed, 130 insertions(+)
Paolo Bonzini 9fbea3
Paolo Bonzini 9fbea3
diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
Paolo Bonzini 9fbea3
index 1e22f8bb38..d6c1ef95dc 100644
Paolo Bonzini 9fbea3
--- a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
Paolo Bonzini 9fbea3
+++ b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
Paolo Bonzini 9fbea3
@@ -83,3 +83,4 @@ [Protocols]
Paolo Bonzini 9fbea3
   gEfiLoadedImageProtocolGuid
Paolo Bonzini 9fbea3
   gEfiPciRootBridgeIoProtocolGuid
Paolo Bonzini 9fbea3
   gEfiSimpleFileSystemProtocolGuid
Paolo Bonzini 9fbea3
+  gVirtioDeviceProtocolGuid
Paolo Bonzini 9fbea3
diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
Paolo Bonzini 9fbea3
index 5d5e51d8c8..62cce6a01e 100644
Paolo Bonzini 9fbea3
--- a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
Paolo Bonzini 9fbea3
+++ b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
Paolo Bonzini 9fbea3
@@ -16,6 +16,7 @@
Paolo Bonzini 9fbea3
 **/
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 #include <IndustryStandard/Pci22.h>
Paolo Bonzini 9fbea3
+#include <IndustryStandard/Virtio095.h>
Paolo Bonzini 9fbea3
 #include <Library/BootLogoLib.h>
Paolo Bonzini 9fbea3
 #include <Library/DevicePathLib.h>
Paolo Bonzini 9fbea3
 #include <Library/PcdLib.h>
Paolo Bonzini 9fbea3
@@ -27,6 +28,7 @@
Paolo Bonzini 9fbea3
 #include <Protocol/LoadedImage.h>
Paolo Bonzini 9fbea3
 #include <Protocol/PciIo.h>
Paolo Bonzini 9fbea3
 #include <Protocol/PciRootBridgeIo.h>
Paolo Bonzini 9fbea3
+#include <Protocol/VirtioDevice.h>
Paolo Bonzini 9fbea3
 #include <Guid/EventGroup.h>
Paolo Bonzini 9fbea3
 #include <Guid/RootBridgesConnectedEventGroup.h>
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
@@ -260,6 +262,121 @@ IsPciDisplay (
Paolo Bonzini 9fbea3
 }
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
+/**
Paolo Bonzini 9fbea3
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG device at
Paolo Bonzini 9fbea3
+  the VIRTIO_DEVICE_PROTOCOL level.
Paolo Bonzini 9fbea3
+**/
Paolo Bonzini 9fbea3
+STATIC
Paolo Bonzini 9fbea3
+BOOLEAN
Paolo Bonzini 9fbea3
+EFIAPI
Paolo Bonzini 9fbea3
+IsVirtioRng (
Paolo Bonzini 9fbea3
+  IN EFI_HANDLE   Handle,
Paolo Bonzini 9fbea3
+  IN CONST CHAR16 *ReportText
Paolo Bonzini 9fbea3
+  )
Paolo Bonzini 9fbea3
+{
Paolo Bonzini 9fbea3
+  EFI_STATUS             Status;
Paolo Bonzini 9fbea3
+  VIRTIO_DEVICE_PROTOCOL *VirtIo;
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  Status = gBS->HandleProtocol (Handle, &gVirtioDeviceProtocolGuid,
Paolo Bonzini 9fbea3
+                  (VOID**)&VirtIo);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    return FALSE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  return (BOOLEAN)(VirtIo->SubSystemDeviceId ==
Paolo Bonzini 9fbea3
+                   VIRTIO_SUBSYSTEM_ENTROPY_SOURCE);
Paolo Bonzini 9fbea3
+}
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+/**
Paolo Bonzini 9fbea3
+  This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG device at
Paolo Bonzini 9fbea3
+  the EFI_PCI_IO_PROTOCOL level.
Paolo Bonzini 9fbea3
+**/
Paolo Bonzini 9fbea3
+STATIC
Paolo Bonzini 9fbea3
+BOOLEAN
Paolo Bonzini 9fbea3
+EFIAPI
Paolo Bonzini 9fbea3
+IsVirtioPciRng (
Paolo Bonzini 9fbea3
+  IN EFI_HANDLE   Handle,
Paolo Bonzini 9fbea3
+  IN CONST CHAR16 *ReportText
Paolo Bonzini 9fbea3
+  )
Paolo Bonzini 9fbea3
+{
Paolo Bonzini 9fbea3
+  EFI_STATUS          Status;
Paolo Bonzini 9fbea3
+  EFI_PCI_IO_PROTOCOL *PciIo;
Paolo Bonzini 9fbea3
+  UINT16              VendorId;
Paolo Bonzini 9fbea3
+  UINT16              DeviceId;
Paolo Bonzini 9fbea3
+  UINT8               RevisionId;
Paolo Bonzini 9fbea3
+  BOOLEAN             Virtio10;
Paolo Bonzini 9fbea3
+  UINT16              SubsystemId;
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid,
Paolo Bonzini 9fbea3
+                  (VOID**)&PciIo);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    return FALSE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // Read and check VendorId.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET,
Paolo Bonzini 9fbea3
+                        1, &VendorId);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    goto PciError;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  if (VendorId != VIRTIO_VENDOR_ID) {
Paolo Bonzini 9fbea3
+    return FALSE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // Read DeviceId and RevisionId.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,
Paolo Bonzini 9fbea3
+                        1, &DeviceId);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    goto PciError;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_REVISION_ID_OFFSET,
Paolo Bonzini 9fbea3
+                        1, &RevisionId);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    goto PciError;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // From DeviceId and RevisionId, determine whether the device is a
Paolo Bonzini 9fbea3
+  // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can
Paolo Bonzini 9fbea3
+  // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and
Paolo Bonzini 9fbea3
+  // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can
Paolo Bonzini 9fbea3
+  // only be sanity-checked, and SubsystemId will decide.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  if (DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE &&
Paolo Bonzini 9fbea3
+      RevisionId >= 0x01) {
Paolo Bonzini 9fbea3
+    Virtio10 = TRUE;
Paolo Bonzini 9fbea3
+  } else if (DeviceId >= 0x1000 && DeviceId <= 0x103F && RevisionId == 0x00) {
Paolo Bonzini 9fbea3
+    Virtio10 = FALSE;
Paolo Bonzini 9fbea3
+  } else {
Paolo Bonzini 9fbea3
+    return FALSE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // Read and check SubsystemId as dictated by Virtio10.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
Paolo Bonzini 9fbea3
+                        PCI_SUBSYSTEM_ID_OFFSET, 1, &SubsystemId);
Paolo Bonzini 9fbea3
+  if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+    goto PciError;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  if (Virtio10 && SubsystemId >= 0x40) {
Paolo Bonzini 9fbea3
+    return TRUE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  if (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) {
Paolo Bonzini 9fbea3
+    return TRUE;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  return FALSE;
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+PciError:
Paolo Bonzini 9fbea3
+  DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));
Paolo Bonzini 9fbea3
+  return FALSE;
Paolo Bonzini 9fbea3
+}
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
 /**
Paolo Bonzini 9fbea3
   This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking
Paolo Bonzini 9fbea3
   the matching driver to produce all first-level child handles.
Paolo Bonzini 9fbea3
@@ -644,6 +761,18 @@ PlatformBootManagerBeforeConsole (
Paolo Bonzini 9fbea3
   // Register platform-specific boot options and keyboard shortcuts.
Paolo Bonzini 9fbea3
   //
Paolo Bonzini 9fbea3
   PlatformRegisterOptionsAndKeys ();
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // At this point, VIRTIO_DEVICE_PROTOCOL instances exist only for Virtio MMIO
Paolo Bonzini 9fbea3
+  // transports. Install EFI_RNG_PROTOCOL instances on Virtio MMIO RNG devices.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  FilterAndProcess (&gVirtioDeviceProtocolGuid, IsVirtioRng, Connect);
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL
Paolo Bonzini 9fbea3
+  // instances on Virtio PCI RNG devices.
Paolo Bonzini 9fbea3
+  //
Paolo Bonzini 9fbea3
+  FilterAndProcess (&gEfiPciIoProtocolGuid, IsVirtioPciRng, Connect);
Paolo Bonzini 9fbea3
 }
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 /**
Paolo Bonzini 9fbea3
-- 
Paolo Bonzini 9fbea3
2.17.0
Paolo Bonzini 9fbea3