diff mbox series

[1/1] efi_loader: device path for virtio block devices

Message ID 20200520212942.62536-1-xypron.glpk@gmx.de
State Accepted
Commit 19ecced71cfb92519e8ef7dddbc4138d871fe97c
Headers show
Series [1/1] efi_loader: device path for virtio block devices | expand

Commit Message

Heinrich Schuchardt May 20, 2020, 9:29 p.m. UTC
The UEFI specification does not define a device sub-type for virtio.
Let's use a vendor hardware node here.

This avoids creation of two handles with the same device path indicating
our root node.

Reported-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 include/efi_loader.h             |  4 ++++
 lib/efi_loader/efi_device_path.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

--
2.26.2
diff mbox series

Patch

diff --git a/include/efi_loader.h b/include/efi_loader.h
index 75c20e4679..f902d8765a 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -41,6 +41,10 @@  static inline void *guidcpy(void *dst, const void *src)
 #define U_BOOT_HOST_DEV_GUID \
 	EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
 		 0x9a, 0xab, 0x3a, 0x7d, 0xbf, 0x40, 0xc4, 0x82)
+/* GUID used as root for virtio devices */
+#define U_BOOT_VIRTIO_DEV_GUID \
+	EFI_GUID(0x63293792, 0xadf5, 0x9325, \
+		 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e)

 /* Use internal device tree when starting UEFI application */
 #define EFI_FDT_USE_INTERNAL NULL
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index f9349484a6..1606c830b8 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -20,6 +20,9 @@ 
 #ifdef CONFIG_SANDBOX
 const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
 #endif
+#ifdef CONFIG_VIRTIO_BLK
+const efi_guid_t efi_guid_virtio_dev = U_BOOT_VIRTIO_DEV_GUID;
+#endif

 /* template END node: */
 static const struct efi_device_path END = {
@@ -467,6 +470,16 @@  __maybe_unused static unsigned int dp_size(struct udevice *dev)
 			  */
 			return dp_size(dev->parent)
 				+ sizeof(struct efi_device_path_vendor) + 1;
+#endif
+#ifdef CONFIG_VIRTIO_BLK
+		case UCLASS_VIRTIO:
+			 /*
+			  * Virtio devices will be represented as a vendor
+			  * device node with an extra byte for the device
+			  * number.
+			  */
+			return dp_size(dev->parent)
+				+ sizeof(struct efi_device_path_vendor) + 1;
 #endif
 		default:
 			return dp_size(dev->parent);
@@ -545,6 +558,23 @@  __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
 			return &dp->vendor_data[1];
 			}
 #endif
+#ifdef CONFIG_VIRTIO_BLK
+		case UCLASS_VIRTIO: {
+			struct efi_device_path_vendor *dp;
+			struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+			dp_fill(buf, dev->parent);
+			dp = buf;
+			++dp;
+			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+			dp->dp.length = sizeof(*dp) + 1;
+			memcpy(&dp->guid, &efi_guid_virtio_dev,
+			       sizeof(efi_guid_t));
+			dp->vendor_data[0] = desc->devnum;
+			return &dp->vendor_data[1];
+			}
+#endif
 #ifdef CONFIG_IDE
 		case UCLASS_IDE: {
 			struct efi_device_path_atapi *dp =