Blame 0052-OvmfPkg-PlatformBootManagerLib-connect-Virtio-RNG-de.patch

Paolo Bonzini 9fbea3
From 7ebad830d6ab61f0395f6f4bae4156664bbd8086 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] OvmfPkg/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 245c643cc8b7 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 245c643cc8b7 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
Cc: Jordan Justen <jordan.l.justen@intel.com>
Paolo Bonzini 9fbea3
Fixes: 245c643cc8b73240c3b88cb55b2911b285a8c10d
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/BdsPlatform.h      |   1 +
Paolo Bonzini 9fbea3
 .../PlatformBootManagerLib/BdsPlatform.c      | 105 ++++++++++++++++++
Paolo Bonzini 9fbea3
 2 files changed, 106 insertions(+)
Paolo Bonzini 9fbea3
Paolo Bonzini 9fbea3
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
Paolo Bonzini 9fbea3
index 97ffbb5148..4948ca6518 100644
Paolo Bonzini 9fbea3
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
Paolo Bonzini 9fbea3
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h
Paolo Bonzini 9fbea3
@@ -30,6 +30,7 @@ Abstract:
Paolo Bonzini 9fbea3
 #include <IndustryStandard/Acpi.h>
Paolo Bonzini 9fbea3
 #include <IndustryStandard/SmBios.h>
Paolo Bonzini 9fbea3
 #include <IndustryStandard/PeImage.h>
Paolo Bonzini 9fbea3
+#include <IndustryStandard/Virtio095.h>
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 #include <Library/DebugLib.h>
Paolo Bonzini 9fbea3
 #include <Library/BaseMemoryLib.h>
Paolo Bonzini 9fbea3
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
Paolo Bonzini 9fbea3
index 004b753f4d..5d4d323d73 100644
Paolo Bonzini 9fbea3
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
Paolo Bonzini 9fbea3
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
Paolo Bonzini 9fbea3
@@ -318,6 +318,15 @@ ConnectRootBridge (
Paolo Bonzini 9fbea3
   IN VOID        *Context
Paolo Bonzini 9fbea3
   );
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
+STATIC
Paolo Bonzini 9fbea3
+EFI_STATUS
Paolo Bonzini 9fbea3
+EFIAPI
Paolo Bonzini 9fbea3
+ConnectVirtioPciRng (
Paolo Bonzini 9fbea3
+  IN EFI_HANDLE Handle,
Paolo Bonzini 9fbea3
+  IN VOID       *Instance,
Paolo Bonzini 9fbea3
+  IN VOID       *Context
Paolo Bonzini 9fbea3
+  );
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
 STATIC
Paolo Bonzini 9fbea3
 VOID
Paolo Bonzini 9fbea3
 SaveS3BootScript (
Paolo Bonzini 9fbea3
@@ -399,6 +408,13 @@ PlatformBootManagerBeforeConsole (
Paolo Bonzini 9fbea3
   ASSERT_RETURN_ERROR (PcdStatus);
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
   PlatformRegisterOptionsAndKeys ();
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
+  VisitAllInstancesOfProtocol (&gEfiPciIoProtocolGuid, ConnectVirtioPciRng,
Paolo Bonzini 9fbea3
+    NULL);
Paolo Bonzini 9fbea3
 }
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
@@ -427,6 +443,95 @@ ConnectRootBridge (
Paolo Bonzini 9fbea3
 }
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
+STATIC
Paolo Bonzini 9fbea3
+EFI_STATUS
Paolo Bonzini 9fbea3
+EFIAPI
Paolo Bonzini 9fbea3
+ConnectVirtioPciRng (
Paolo Bonzini 9fbea3
+  IN EFI_HANDLE Handle,
Paolo Bonzini 9fbea3
+  IN VOID       *Instance,
Paolo Bonzini 9fbea3
+  IN VOID       *Context
Paolo Bonzini 9fbea3
+  )
Paolo Bonzini 9fbea3
+{
Paolo Bonzini 9fbea3
+  EFI_PCI_IO_PROTOCOL *PciIo;
Paolo Bonzini 9fbea3
+  EFI_STATUS          Status;
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
+  PciIo = Instance;
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 Error;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  if (VendorId != VIRTIO_VENDOR_ID) {
Paolo Bonzini 9fbea3
+    return EFI_SUCCESS;
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 Error;
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 Error;
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 EFI_SUCCESS;
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 Error;
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  if ((Virtio10 && SubsystemId >= 0x40) ||
Paolo Bonzini 9fbea3
+      (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {
Paolo Bonzini 9fbea3
+    Status = gBS->ConnectController (
Paolo Bonzini 9fbea3
+                    Handle, // ControllerHandle
Paolo Bonzini 9fbea3
+                    NULL,   // DriverImageHandle -- connect all drivers
Paolo Bonzini 9fbea3
+                    NULL,   // RemainingDevicePath -- produce all child handles
Paolo Bonzini 9fbea3
+                    FALSE   // Recursive -- don't follow child handles
Paolo Bonzini 9fbea3
+                    );
Paolo Bonzini 9fbea3
+    if (EFI_ERROR (Status)) {
Paolo Bonzini 9fbea3
+      goto Error;
Paolo Bonzini 9fbea3
+    }
Paolo Bonzini 9fbea3
+  }
Paolo Bonzini 9fbea3
+  return EFI_SUCCESS;
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+Error:
Paolo Bonzini 9fbea3
+  DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
Paolo Bonzini 9fbea3
+  return Status;
Paolo Bonzini 9fbea3
+}
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
+
Paolo Bonzini 9fbea3
 /**
Paolo Bonzini 9fbea3
   Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
Paolo Bonzini 9fbea3
 
Paolo Bonzini 9fbea3
-- 
Paolo Bonzini 9fbea3
2.17.0
Paolo Bonzini 9fbea3