[PATCH 2/2] [virtio] Add virtio block device sanboot support

Stefan Hajnoczi stefanha at gmail.com
Tue Jan 5 12:39:18 EST 2010


This patch adds virtio block device support alongside the existing
iSCSI, ATA-over-Ethernet, and ramdisk block devices.  A gPXE option ROM
can boot a QEMU/KVM virtual machine directly from a virtio block device:

    # Ensure SANBOOT_PROTO_VIRTIO_BLK is defined in config/defaults.h
    make bin/1af41001.rom

The sanboot gPXE command is used with the virtio_blk: root path scheme.
The virtio block device instance is identified by its PCI bus, device,
and function (there could be multiple virtio block devices).

    sanboot virtio_blk:PCI00:04.0

Successfully boots Debian testing i386 and FreeDOS 0.84-pre2 under QEMU.
---
 src/arch/i386/interface/pcbios/virtio_blkboot.c |   70 ++++++
 src/config/config.c                             |    3 +
 src/config/general.h                            |    1 +
 src/drivers/block/virtio-blk.c                  |  271 +++++++++++++++++++++++
 src/drivers/block/virtio-blk.h                  |   30 +++
 src/include/gpxe/errfile.h                      |    2 +
 src/include/gpxe/virtblk.h                      |   37 +++
 7 files changed, 414 insertions(+), 0 deletions(-)
 create mode 100644 src/arch/i386/interface/pcbios/virtio_blkboot.c
 create mode 100644 src/drivers/block/virtio-blk.c
 create mode 100644 src/drivers/block/virtio-blk.h
 create mode 100644 src/include/gpxe/virtblk.h

diff --git a/src/arch/i386/interface/pcbios/virtio_blkboot.c
b/src/arch/i386/interface/pcbios/virtio_blkboot.c
new file mode 100644
index 0000000..3c2dd47
--- /dev/null
+++ b/src/arch/i386/interface/pcbios/virtio_blkboot.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Stefan Hajnoczi <stefanha at gmail.com>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <gpxe/sanboot.h>
+#include <gpxe/virtblk.h>
+#include <int13.h>
+
+/**
+ * @file
+ *
+ * Virtio block device boot
+ *
+ */
+
+static int virtio_blkboot ( const char *root_path ) {
+	struct int13_drive *drive;
+	struct virtblk *virtblk;
+	int rc;
+
+	virtblk = find_virtblk ( root_path + sizeof ( "virtio_blk:" ) - 1 );
+	if ( ! virtblk )
+		return -ENOENT;
+
+	drive = zalloc ( sizeof ( *drive ) );
+	if ( ! drive )
+		return -ENOMEM;
+
+	drive->blockdev = &virtblk->blockdev;
+
+	register_int13_drive ( drive );
+	printf ( "Registered as BIOS drive %#02x\n", drive->drive );
+	printf ( "Booting from BIOS drive %#02x\n", drive->drive );
+	rc = int13_boot ( drive->drive );
+	printf ( "Boot failed\n" );
+
+	/* Leave drive registered, if instructed to do so */
+	if ( keep_san() )
+		return rc;
+
+	printf ( "Unregistering BIOS drive %#02x\n", drive->drive );
+	unregister_int13_drive ( drive );
+	free ( drive );
+	return rc;
+}
+
+struct sanboot_protocol virtblk_sanboot_protocol __sanboot_protocol = {
+	.prefix = "virtio_blk:",
+	.boot = virtio_blkboot,
+};
diff --git a/src/config/config.c b/src/config/config.c
index 3c43dfb..bb0ff67 100644
--- a/src/config/config.c
+++ b/src/config/config.c
@@ -130,6 +130,9 @@ REQUIRE_OBJECT ( aoeboot );
 #ifdef SANBOOT_PROTO_IB_SRP
 REQUIRE_OBJECT ( ib_srpboot );
 #endif
+#ifdef SANBOOT_PROTO_VIRTIO_BLK
+REQUIRE_OBJECT ( virtio_blkboot );
+#endif

 /*
  * Drag in all requested resolvers
diff --git a/src/config/general.h b/src/config/general.h
index ee07dfc..a1dec39 100644
--- a/src/config/general.h
+++ b/src/config/general.h
@@ -63,6 +63,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 //#undef	SANBOOT_PROTO_ISCSI	/* iSCSI protocol */
 //#undef	SANBOOT_PROTO_AOE	/* AoE protocol */
 //#undef	SANBOOT_PROTO_IB_SRP	/* Infiniband SCSI RDMA protocol */
+//#undef	SANBOOT_PROTO_VIRTIO_BLK /* Virtio block device */

 /*
  * Name resolution modules
diff --git a/src/drivers/block/virtio-blk.c b/src/drivers/block/virtio-blk.c
new file mode 100644
index 0000000..fab5930
--- /dev/null
+++ b/src/drivers/block/virtio-blk.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2010 Stefan Hajnoczi <stefanha at gmail.com>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <errno.h>
+#include <stdlib.h>
+#include <gpxe/process.h>
+#include <gpxe/virtblk.h>
+#include "virtio-blk.h"
+
+/**
+ * @file
+ *
+ * Virtio block devices
+ *
+ */
+
+/** List of virtio block devices */
+static LIST_HEAD ( virtblk_devices );
+
+/**
+ * Register virtio block device
+ *
+ * @v virtblk		Virtio block device
+ *
+ * Adds the virtio block device to the list of virtio block devices.
+ */
+static void register_virtblk ( struct virtblk *virtblk ) {
+	list_add_tail ( &virtblk->virtblk_devices, &virtblk_devices );
+}
+
+/**
+ * Unregister virtio block device
+ *
+ * @v virtblk		Virtio block device
+ *
+ * Removes the virtio block device from the list of virtio block devices.
+ */
+static void unregister_virtblk ( struct virtblk *virtblk ) {
+	list_del ( &virtblk->virtblk_devices );
+}
+
+/**
+ * Find virtio block device by name
+ *
+ * @v device_name	Device name
+ * @ret virtblk		Virtio block device or NULL
+ *
+ * Searches the list of virtio block devices by name.
+ */
+struct virtblk *find_virtblk ( const char *device_name ) {
+	struct virtblk *virtblk;
+	DBG ( "find_virtblk \"%s\"\n", device_name );
+	list_for_each_entry ( virtblk, &virtblk_devices, virtblk_devices ) {
+		if ( ! strcmp ( device_name, virtblk->pdev->dev.name ) )
+			return virtblk;
+	}
+	return NULL;
+}
+
+/**
+ * Issue an I/O request and wait for completion
+ *
+ * @v virtblk		Virtio block device
+ * @v type		VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT
+ * @v block		Block number
+ * @v count		Block count
+ * @v buffer		Data buffer
+ * @ret rc		Return status code
+ */
+static int virtblk_command ( struct virtblk *virtblk, u32 type,
+			     uint64_t block, unsigned long count,
+			     userptr_t buffer ) {
+	/*
+	 * Virtio block requests have the following format:
+	 *
+	 *   +--------------------------------+
+	 *   | struct virtio_blk_outhdr  [IN] |
+	 *   +--------------------------------+
+	 *   | In/out buffer         [IN/OUT] |
+	 *   +--------------------------------+
+	 *   | Status byte              [OUT] |
+	 *   +--------------------------------+
+	 *
+	 * The device fills in the status byte to indicate the outcome the
+	 * operation.
+	 */
+	struct vring_virtqueue *vq = &virtblk->virtqueue;
+	struct virtio_blk_outhdr hdr = {
+		.type = type,
+		.ioprio = 0,
+		.sector = block,
+	};
+	uint8_t status = VIRTIO_BLK_S_UNSUPP;
+	struct vring_list list[] = {
+		{
+			.addr	= ( char * ) &hdr,
+			.length	= sizeof ( hdr ),
+		},
+		{
+			.addr	= ( char * ) user_to_virt ( buffer, 0 ),
+			.length	= virtblk->blockdev.blksize * count,
+		},
+		{
+			.addr	= ( char * ) &status,
+			.length	= sizeof ( status ),
+		},
+	};
+	unsigned int in, out;
+
+	DBG ( "VIRTBLK req 0x%02x LBA 0x%llx count 0x%lx\n",
+	      type, block, count );
+
+	/* Number of elements readable and writable */
+	if ( type == VIRTIO_BLK_T_IN ) {
+		out = 1;
+		in = 2;
+	} else {
+		out = 2;
+		in = 1;
+	}
+
+	/* Add to virtqueue and kick host */
+	vring_add_buf ( vq, list, out, in, 0, 0 );
+	vring_kick ( virtblk->pdev->ioaddr, vq, 1 );
+
+	/* Wait for reply */
+	while ( ! vring_more_used ( vq ) ) {
+		mb();
+		step();
+	}
+
+	/* Reclaim virtqueue element */
+	vring_get_buf ( vq, NULL );
+	return status == VIRTIO_BLK_S_OK ? 0 : -EIO;
+}
+
+/**
+ * Read block
+ *
+ * @v blockdev		Block device
+ * @v block		Block number
+ * @v count		Block count
+ * @v buffer		Data buffer
+ * @ret rc		Return status code
+ */
+static int virtblk_read ( struct block_device *blockdev, uint64_t block,
+			  unsigned long count, userptr_t buffer ) {
+	struct virtblk *virtblk =
+		container_of ( blockdev, struct virtblk, blockdev );
+	return virtblk_command ( virtblk, VIRTIO_BLK_T_IN, block,
+				 count, buffer );
+}
+
+/**
+ * Write block
+ *
+ * @v blockdev		Block device
+ * @v block		Block number
+ * @v count		Block count
+ * @v buffer		Data buffer
+ * @ret rc		Return status code
+ */
+static int virtblk_write ( struct block_device *blockdev __unused,
uint64_t block __unused,
+			   unsigned long count __unused, userptr_t buffer __unused ) {
+	struct virtblk *virtblk =
+		container_of ( blockdev, struct virtblk, blockdev );
+	return virtblk_command ( virtblk, VIRTIO_BLK_T_OUT, block,
+				 count, buffer );
+}
+
+static struct block_device_operations virtblk_operations = {
+	.read	= virtblk_read,
+	.write	= virtblk_write,
+};
+
+/**
+ * Probe PCI device
+ *
+ * @v pci	PCI device
+ * @v id	PCI ID
+ * @ret rc	Return status code
+ */
+static int virtblk_probe ( struct pci_device *pci,
+			   const struct pci_device_id *id __unused ) {
+	unsigned long ioaddr = pci->ioaddr;
+
+	/* Initialize driver state */
+	struct virtblk *virtblk = zalloc ( sizeof *virtblk );
+	if ( ! virtblk )
+		return -ENOMEM;
+	INIT_LIST_HEAD ( &virtblk->virtblk_devices );
+	virtblk->blockdev.op = &virtblk_operations;
+	virtblk->pdev = pci;
+	pci->priv = virtblk;
+
+	/* Prepare the device */
+	adjust_pci_device ( pci );
+	vp_reset ( ioaddr );
+
+	/* Indicate that the driver is starting */
+	vp_set_status ( ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+				VIRTIO_CONFIG_S_DRIVER );
+
+	/* Grab the I/O requests virtqueue */
+	if ( vp_find_vq ( ioaddr, 0, &virtblk->virtqueue ) < 0 ) {
+		free ( virtblk );
+		return -ENOENT;
+	}
+
+	/* Feature negotiation */
+	u32 features = vp_get_features ( ioaddr );
+	vp_set_features ( ioaddr, 0 ); /* no features required */
+
+	/* Find out the drive capacity */
+	virtblk->blockdev.blksize = 512; /* the default */
+	vp_get ( ioaddr, 0, &virtblk->blockdev.blocks,
+		 sizeof virtblk->blockdev.blocks );
+
+	/* Indicate that the driver is ready */
+	vp_set_status ( ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+				VIRTIO_CONFIG_S_DRIVER |
+				VIRTIO_CONFIG_S_DRIVER_OK );
+
+	DBGC ( virtblk, "VIRTBLK %p virtio_blk:%s ioaddr=0x%lx irq=%d
features=0x%x capacity=%lld\n",
+	       virtblk, pci->dev.name, ioaddr, pci->irq,
+	       features, virtblk->blockdev.blocks );
+
+	register_virtblk ( virtblk );
+	return 0;
+}
+
+/**
+ * Remove PCI device
+ *
+ * @v pci	PCI device
+ */
+static void virtblk_remove ( struct pci_device *pci ) {
+	struct virtblk *virtblk = pci->priv;
+
+	unregister_virtblk ( virtblk );
+	vp_reset ( pci->ioaddr );
+	free ( virtblk );
+}
+
+static struct pci_device_id virtblk_ids[] = {
+	PCI_ROM(0x1af4, 0x1001, "virtio-blk", "Virtio Block Device", 0),
+};
+
+struct pci_driver virtblk_driver __pci_driver = {
+  .ids = virtblk_ids,
+  .id_count = ( sizeof ( virtblk_ids ) / sizeof ( virtblk_ids[0] ) ),
+  .probe = virtblk_probe,
+  .remove = virtblk_remove,
+};
diff --git a/src/drivers/block/virtio-blk.h b/src/drivers/block/virtio-blk.h
new file mode 100644
index 0000000..3a34868
--- /dev/null
+++ b/src/drivers/block/virtio-blk.h
@@ -0,0 +1,30 @@
+#ifndef _VIRTIO_BLK_H
+#define _VIRTIO_BLK_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers. */
+
+FILE_LICENCE ( BSD2 );
+
+/*
+ * Command types
+ */
+
+/* These two define direction. */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+/* This is the first element of the read scatter-gather list. */
+struct virtio_blk_outhdr {
+	/* VIRTIO_BLK_T* */
+	u32 type;
+	/* io priority. */
+	u32 ioprio;
+	/* Sector (ie. 512 byte offset) */
+	u64 sector;
+};
+
+/* And this is the final byte of the write scatter-gather list. */
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+#endif /* _VIRTIO_BLK_H */
diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h
index 5231c14..092d7eb 100644
--- a/src/include/gpxe/errfile.h
+++ b/src/include/gpxe/errfile.h
@@ -122,6 +122,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define ERRFILE_linda		     ( ERRFILE_DRIVER | 0x00730000 )
 #define ERRFILE_ata		     ( ERRFILE_DRIVER | 0x00740000 )
 #define ERRFILE_srp		     ( ERRFILE_DRIVER | 0x00750000 )
+#define ERRFILE_virtio_blk	     ( ERRFILE_DRIVER | 0x00760000 )

 #define ERRFILE_aoe			( ERRFILE_NET | 0x00000000 )
 #define ERRFILE_arp			( ERRFILE_NET | 0x00010000 )
@@ -191,6 +192,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define ERRFILE_x509		      ( ERRFILE_OTHER | 0x00160000 )
 #define ERRFILE_login_ui	      ( ERRFILE_OTHER | 0x00170000 )
 #define ERRFILE_ib_srpboot	      ( ERRFILE_OTHER | 0x00180000 )
+#define ERRFILE_virtio_blkboot	      ( ERRFILE_OTHER | 0x00190000 )

 /** @} */

diff --git a/src/include/gpxe/virtblk.h b/src/include/gpxe/virtblk.h
new file mode 100644
index 0000000..781d433
--- /dev/null
+++ b/src/include/gpxe/virtblk.h
@@ -0,0 +1,37 @@
+#ifndef _GPXE_VIRTBLK_H
+#define _GPXE_VIRTBLK_H
+
+/** @file
+ *
+ * Virtio block device
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/list.h>
+#include <gpxe/pci.h>
+#include <gpxe/virtio-ring.h>
+#include <gpxe/virtio-pci.h>
+#include <gpxe/blockdev.h>
+
+/**
+ * Virtio block device
+ */
+struct virtblk {
+	/** List of virtio-blk devices */
+	struct list_head virtblk_devices;
+
+	/** Underlying PCI device */
+	struct pci_device *pdev;
+
+	/** Outgoing requests virtqueue */
+	struct vring_virtqueue virtqueue;
+
+	/** Block device */
+	struct block_device blockdev;
+};
+
+extern struct virtblk *find_virtblk ( const char *device_name );
+
+#endif /* _GPXE_VIRTBLK_H */
-- 
1.6.5

--001485eafef29d92c3047c70ef97
Content-Type: text/x-patch; charset=US-ASCII; name="virtio_blk.diff"
Content-Disposition: attachment; filename="virtio_blk.diff"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_g435hafq0

RnJvbSAwOTI2NjQ5YmVjZThlMDZkZmRiMTllNGY4MTk3OTVkYTZlZTM2NGRkIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBTdGVmYW4gSGFqbm9jemkgPHN0ZWZhbmhhQGdtYWlsLmNvbT4K
RGF0ZTogVHVlLCA1IEphbiAyMDEwIDA4OjA1OjMyICswMDAwClN1YmplY3Q6IFtQQVRDSCAxLzJd
IFtzYW5ib290XSBQcmV2ZW50IGxlYWtpbmcgYSBzdGFjayByZWZlcmVuY2UgZm9yICJrZWVwLXNh
biIgQW9FCgpXaGVuIHRoZSAia2VlcC1zYW4iIG9wdGlvbiBpcyB1c2VkLCB0aGUgZnVuY3Rpb24g
aXMgZXhpdGVkIHdpdGhvdXQKdW5yZWdpc3RlcmluZyB0aGUgc3RhY2sgYWxsb2NhdGVkIGludDEz
aCBkcml2ZS4gIFRvIHByZXZlbnQgYSBkYW5nbGluZwpwb2ludGVyIHRvIHRoZSBzdGFjaywgdGhl
c2Ugc3RydWN0cyBzaG91bGQgYmUgaGVhcCBhbGxvY2F0ZWQuCi0tLQogc3JjL2FyY2gvaTM4Ni9p
bnRlcmZhY2UvcGNiaW9zL2FvZWJvb3QuYyB8ICAgNTQgKysrKysrKysrKysrKysrKysrLS0tLS0t
LS0tLS0KIDEgZmlsZXMgY2hhbmdlZCwgMzMgaW5zZXJ0aW9ucygrKSwgMjEgZGVsZXRpb25zKC0p
CgpkaWZmIC0tZ2l0IGEvc3JjL2FyY2gvaTM4Ni9pbnRlcmZhY2UvcGNiaW9zL2FvZWJvb3QuYyBi
L3NyYy9hcmNoL2kzODYvaW50ZXJmYWNlL3BjYmlvcy9hb2Vib290LmMKaW5kZXggODQ0NmMxNS4u
MjY3MGIxNSAxMDA2NDQKLS0tIGEvc3JjL2FyY2gvaTM4Ni9pbnRlcmZhY2UvcGNiaW9zL2FvZWJv
b3QuYworKysgYi9zcmMvYXJjaC9pMzg2L2ludGVyZmFjZS9wY2Jpb3MvYW9lYm9vdC5jCkBAIC0x
LDExICsxLDExIEBACiAjaW5jbHVkZSA8c3RkaW50Lmg+CiAjaW5jbHVkZSA8c3RyaW5nLmg+Cisj
aW5jbHVkZSA8c3RkbGliLmg+CiAjaW5jbHVkZSA8c3RkaW8uaD4KLSNpbmNsdWRlIDxieXRlc3dh
cC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CiAjaW5jbHVkZSA8Z3B4ZS9hb2UuaD4KICNpbmNsdWRl
IDxncHhlL2F0YS5oPgogI2luY2x1ZGUgPGdweGUvbmV0ZGV2aWNlLmg+Ci0jaW5jbHVkZSA8Z3B4
ZS9zZXR0aW5ncy5oPgogI2luY2x1ZGUgPGdweGUvc2FuYm9vdC5oPgogI2luY2x1ZGUgPGdweGUv
YWJmdC5oPgogI2luY2x1ZGUgPGludDEzLmg+CkBAIC0xMyw1MCArMTMsNjIgQEAKIEZJTEVfTElD
RU5DRSAoIEdQTDJfT1JfTEFURVIgKTsKIAogc3RhdGljIGludCBhb2Vib290ICggY29uc3QgY2hh
ciAqcm9vdF9wYXRoICkgewotCXN0cnVjdCBhdGFfZGV2aWNlIGF0YTsKLQlzdHJ1Y3QgaW50MTNf
ZHJpdmUgZHJpdmU7CisJc3RydWN0IGF0YV9kZXZpY2UgKmF0YTsKKwlzdHJ1Y3QgaW50MTNfZHJp
dmUgKmRyaXZlOwogCWludCByYzsKIAotCW1lbXNldCAoICZhdGEsIDAsIHNpemVvZiAoIGF0YSAp
ICk7Ci0JbWVtc2V0ICggJmRyaXZlLCAwLCBzaXplb2YgKCBkcml2ZSApICk7CisJYXRhID0gemFs
bG9jICggc2l6ZW9mICggKmF0YSApICk7CisJaWYgKCAhIGF0YSApIHsKKwkJcmMgPSAtRU5PTUVN
OworCQlnb3RvIGVycl9hbGxvY19hdGE7CisJfQorCWRyaXZlID0gemFsbG9jICggc2l6ZW9mICgg
KmRyaXZlICkgKTsKKwlpZiAoICEgZHJpdmUgKSB7CisJCXJjID0gLUVOT01FTTsKKwkJZ290byBl
cnJfYWxsb2NfZHJpdmU7CisJfQogCiAJLyogRklYTUU6IHVnbHksIHVnbHkgaGFjayAqLwogCXN0
cnVjdCBuZXRfZGV2aWNlICpuZXRkZXYgPSBsYXN0X29wZW5lZF9uZXRkZXYoKTsKIAotCWlmICgg
KCByYyA9IGFvZV9hdHRhY2ggKCAmYXRhLCBuZXRkZXYsIHJvb3RfcGF0aCApICkgIT0gMCApIHsK
KwlpZiAoICggcmMgPSBhb2VfYXR0YWNoICggYXRhLCBuZXRkZXYsIHJvb3RfcGF0aCApICkgIT0g
MCApIHsKIAkJcHJpbnRmICggIkNvdWxkIG5vdCBhdHRhY2ggQW9FIGRldmljZTogJXNcbiIsCiAJ
CQkgc3RyZXJyb3IgKCByYyApICk7Ci0JCWdvdG8gZXJyb3JfYXR0YWNoOworCQlnb3RvIGVycl9h
dHRhY2g7CiAJfQotCWlmICggKCByYyA9IGluaXRfYXRhZGV2ICggJmF0YSApICkgIT0gMCApIHsK
KwlpZiAoICggcmMgPSBpbml0X2F0YWRldiAoIGF0YSApICkgIT0gMCApIHsKIAkJcHJpbnRmICgg
IkNvdWxkIG5vdCBpbml0aWFsaXNlIEFvRSBkZXZpY2U6ICVzXG4iLAogCQkJIHN0cmVycm9yICgg
cmMgKSApOwotCQlnb3RvIGVycm9yX2luaXQ7CisJCWdvdG8gZXJyX2luaXQ7CiAJfQogCiAJLyog
RklYTUU6IHVnbHksIHVnbHkgaGFjayAqLwogCXN0cnVjdCBhb2Vfc2Vzc2lvbiAqYW9lID0KLQkJ
Y29udGFpbmVyX29mICggYXRhLmJhY2tlbmQsIHN0cnVjdCBhb2Vfc2Vzc2lvbiwgcmVmY250ICk7
CisJCWNvbnRhaW5lcl9vZiAoIGF0YS0+YmFja2VuZCwgc3RydWN0IGFvZV9zZXNzaW9uLCByZWZj
bnQgKTsKIAlhYmZ0X2ZpbGxfZGF0YSAoIGFvZSApOwogCi0JZHJpdmUuYmxvY2tkZXYgPSAmYXRh
LmJsb2NrZGV2OworCWRyaXZlLT5ibG9ja2RldiA9ICZhdGEtPmJsb2NrZGV2OwogCi0JcmVnaXN0
ZXJfaW50MTNfZHJpdmUgKCAmZHJpdmUgKTsKLQlwcmludGYgKCAiUmVnaXN0ZXJlZCBhcyBCSU9T
IGRyaXZlICUjMDJ4XG4iLCBkcml2ZS5kcml2ZSApOwotCXByaW50ZiAoICJCb290aW5nIGZyb20g
QklPUyBkcml2ZSAlIzAyeFxuIiwgZHJpdmUuZHJpdmUgKTsKLQlyYyA9IGludDEzX2Jvb3QgKCBk
cml2ZS5kcml2ZSApOworCXJlZ2lzdGVyX2ludDEzX2RyaXZlICggZHJpdmUgKTsKKwlwcmludGYg
KCAiUmVnaXN0ZXJlZCBhcyBCSU9TIGRyaXZlICUjMDJ4XG4iLCBkcml2ZS0+ZHJpdmUgKTsKKwlw
cmludGYgKCAiQm9vdGluZyBmcm9tIEJJT1MgZHJpdmUgJSMwMnhcbiIsIGRyaXZlLT5kcml2ZSAp
OworCXJjID0gaW50MTNfYm9vdCAoIGRyaXZlLT5kcml2ZSApOwogCXByaW50ZiAoICJCb290IGZh
aWxlZFxuIiApOwogCiAJLyogTGVhdmUgZHJpdmUgcmVnaXN0ZXJlZCwgaWYgaW5zdHJ1Y3RlZCB0
byBkbyBzbyAqLwogCWlmICgga2VlcF9zYW4oKSApCiAJCXJldHVybiByYzsKIAotCXByaW50ZiAo
ICJVbnJlZ2lzdGVyaW5nIEJJT1MgZHJpdmUgJSMwMnhcbiIsIGRyaXZlLmRyaXZlICk7Ci0JdW5y
ZWdpc3Rlcl9pbnQxM19kcml2ZSAoICZkcml2ZSApOworCXByaW50ZiAoICJVbnJlZ2lzdGVyaW5n
IEJJT1MgZHJpdmUgJSMwMnhcbiIsIGRyaXZlLT5kcml2ZSApOworCXVucmVnaXN0ZXJfaW50MTNf
ZHJpdmUgKCBkcml2ZSApOwogCi0gZXJyb3JfaW5pdDoKLQlhb2VfZGV0YWNoICggJmF0YSApOwot
IGVycm9yX2F0dGFjaDoKKyBlcnJfaW5pdDoKKwlhb2VfZGV0YWNoICggYXRhICk7CisgZXJyX2F0
dGFjaDoKKwlmcmVlICggZHJpdmUgKTsKKyBlcnJfYWxsb2NfZHJpdmU6CisJZnJlZSAoIGF0YSAp
OworIGVycl9hbGxvY19hdGE6CiAJcmV0dXJuIHJjOwogfQogCi0tIAoxLjYuNQoKCkZyb20gM2Ri
YzM4NWQyOWNiZGZmNTIwZWQwNjk0OTM0YzAxYTY4MDhmZjFkYyBNb24gU2VwIDE3IDAwOjAwOjAw
IDIwMDEKRnJvbTogU3RlZmFuIEhham5vY3ppIDxzdGVmYW5oYUBnbWFpbC5jb20+CkRhdGU6IFR1
ZSwgNSBKYW4gMjAxMCAxNzozOToxOCArMDAwMApTdWJqZWN0OiBbUEFUQ0ggMi8yXSBbdmlydGlv
XSBBZGQgdmlydGlvIGJsb2NrIGRldmljZSBzYW5ib290IHN1cHBvcnQKClRoaXMgcGF0Y2ggYWRk
cyB2aXJ0aW8gYmxvY2sgZGV2aWNlIHN1cHBvcnQgYWxvbmdzaWRlIHRoZSBleGlzdGluZwppU0NT
SSwgQVRBLW92ZXItRXRoZXJuZXQsIGFuZCByYW1kaXNrIGJsb2NrIGRldmljZXMuICBBIGdQWEUg
b3B0aW9uIFJPTQpjYW4gYm9vdCBhIFFFTVUvS1ZNIHZpcnR1YWwgbWFjaGluZSBkaXJlY3RseSBm
cm9tIGEgdmlydGlvIGJsb2NrIGRldmljZToKCiAgICAjIEVuc3VyZSBTQU5CT09UX1BST1RPX1ZJ
UlRJT19CTEsgaXMgZGVmaW5lZCBpbiBjb25maWcvZGVmYXVsdHMuaAogICAgbWFrZSBiaW4vMWFm
NDEwMDEucm9tCgpUaGUgc2FuYm9vdCBnUFhFIGNvbW1hbmQgaXMgdXNlZCB3aXRoIHRoZSB2aXJ0
aW9fYmxrOiByb290IHBhdGggc2NoZW1lLgpUaGUgdmlydGlvIGJsb2NrIGRldmljZSBpbnN0YW5j
ZSBpcyBpZGVudGlmaWVkIGJ5IGl0cyBQQ0kgYnVzLCBkZXZpY2UsCmFuZCBmdW5jdGlvbiAodGhl
cmUgY291bGQgYmUgbXVsdGlwbGUgdmlydGlvIGJsb2NrIGRldmljZXMpLgoKICAgIHNhbmJvb3Qg
dmlydGlvX2JsazpQQ0kwMDowNC4wCgpTdWNjZXNzZnVsbHkgYm9vdHMgRGViaWFuIHRlc3Rpbmcg
aTM4NiBhbmQgRnJlZURPUyAwLjg0LXByZTIgdW5kZXIgUUVNVS4KLS0tCiBzcmMvYXJjaC9pMzg2
L2ludGVyZmFjZS9wY2Jpb3MvdmlydGlvX2Jsa2Jvb3QuYyB8ICAgNzAgKysrKysrCiBzcmMvY29u
ZmlnL2NvbmZpZy5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDMgKwogc3JjL2Nv
bmZpZy9nZW5lcmFsLmggICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxICsKIHNyYy9k
cml2ZXJzL2Jsb2NrL3ZpcnRpby1ibGsuYyAgICAgICAgICAgICAgICAgIHwgIDI3MSArKysrKysr
KysrKysrKysrKysrKysrKwogc3JjL2RyaXZlcnMvYmxvY2svdmlydGlvLWJsay5oICAgICAgICAg
ICAgICAgICAgfCAgIDMwICsrKwogc3JjL2luY2x1ZGUvZ3B4ZS9lcnJmaWxlLmggICAgICAgICAg
ICAgICAgICAgICAgfCAgICAyICsKIHNyYy9pbmNsdWRlL2dweGUvdmlydGJsay5oICAgICAgICAg
ICAgICAgICAgICAgIHwgICAzNyArKysKIDcgZmlsZXMgY2hhbmdlZCwgNDE0IGluc2VydGlvbnMo
KyksIDAgZGVsZXRpb25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgc3JjL2FyY2gvaTM4Ni9pbnRl
cmZhY2UvcGNiaW9zL3ZpcnRpb19ibGtib290LmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBzcmMvZHJp
dmVycy9ibG9jay92aXJ0aW8tYmxrLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBzcmMvZHJpdmVycy9i
bG9jay92aXJ0aW8tYmxrLmgKIGNyZWF0ZSBtb2RlIDEwMDY0NCBzcmMvaW5jbHVkZS9ncHhlL3Zp
cnRibGsuaAoKZGlmZiAtLWdpdCBhL3NyYy9hcmNoL2kzODYvaW50ZXJmYWNlL3BjYmlvcy92aXJ0
aW9fYmxrYm9vdC5jIGIvc3JjL2FyY2gvaTM4Ni9pbnRlcmZhY2UvcGNiaW9zL3ZpcnRpb19ibGti
b290LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2MyZGQ0NwotLS0gL2Rl
di9udWxsCisrKyBiL3NyYy9hcmNoL2kzODYvaW50ZXJmYWNlL3BjYmlvcy92aXJ0aW9fYmxrYm9v
dC5jCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgU3RlZmFuIEhh
am5vY3ppIDxzdGVmYW5oYUBnbWFpbC5jb20+LgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVl
IHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKKyAqIG1vZGlmeSBpdCB1
bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCisgKiBw
dWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24g
MiBvZiB0aGUKKyAqIExpY2Vuc2UsIG9yIGFueSBsYXRlciB2ZXJzaW9uLgorICoKKyAqIFRoaXMg
cHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVs
LCBidXQKKyAqIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQg
d2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VM
QVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCisgKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBt
b3JlIGRldGFpbHMuCisgKgorICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0
aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKKyAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFt
OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCisgKiBGb3VuZGF0aW9uLCBJbmMu
LCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KKyAqLworCitGSUxFX0xJ
Q0VOQ0UgKCBHUEwyX09SX0xBVEVSICk7CisKKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRl
IDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5j
bHVkZSA8Z3B4ZS9zYW5ib290Lmg+CisjaW5jbHVkZSA8Z3B4ZS92aXJ0YmxrLmg+CisjaW5jbHVk
ZSA8aW50MTMuaD4KKworLyoqCisgKiBAZmlsZQorICoKKyAqIFZpcnRpbyBibG9jayBkZXZpY2Ug
Ym9vdAorICoKKyAqLworCitzdGF0aWMgaW50IHZpcnRpb19ibGtib290ICggY29uc3QgY2hhciAq
cm9vdF9wYXRoICkgeworCXN0cnVjdCBpbnQxM19kcml2ZSAqZHJpdmU7CisJc3RydWN0IHZpcnRi
bGsgKnZpcnRibGs7CisJaW50IHJjOworCisJdmlydGJsayA9IGZpbmRfdmlydGJsayAoIHJvb3Rf
cGF0aCArIHNpemVvZiAoICJ2aXJ0aW9fYmxrOiIgKSAtIDEgKTsKKwlpZiAoICEgdmlydGJsayAp
CisJCXJldHVybiAtRU5PRU5UOworCisJZHJpdmUgPSB6YWxsb2MgKCBzaXplb2YgKCAqZHJpdmUg
KSApOworCWlmICggISBkcml2ZSApCisJCXJldHVybiAtRU5PTUVNOworCisJZHJpdmUtPmJsb2Nr
ZGV2ID0gJnZpcnRibGstPmJsb2NrZGV2OworCisJcmVnaXN0ZXJfaW50MTNfZHJpdmUgKCBkcml2
ZSApOworCXByaW50ZiAoICJSZWdpc3RlcmVkIGFzIEJJT1MgZHJpdmUgJSMwMnhcbiIsIGRyaXZl
LT5kcml2ZSApOworCXByaW50ZiAoICJCb290aW5nIGZyb20gQklPUyBkcml2ZSAlIzAyeFxuIiwg
ZHJpdmUtPmRyaXZlICk7CisJcmMgPSBpbnQxM19ib290ICggZHJpdmUtPmRyaXZlICk7CisJcHJp
bnRmICggIkJvb3QgZmFpbGVkXG4iICk7CisKKwkvKiBMZWF2ZSBkcml2ZSByZWdpc3RlcmVkLCBp
ZiBpbnN0cnVjdGVkIHRvIGRvIHNvICovCisJaWYgKCBrZWVwX3NhbigpICkKKwkJcmV0dXJuIHJj
OworCisJcHJpbnRmICggIlVucmVnaXN0ZXJpbmcgQklPUyBkcml2ZSAlIzAyeFxuIiwgZHJpdmUt
PmRyaXZlICk7CisJdW5yZWdpc3Rlcl9pbnQxM19kcml2ZSAoIGRyaXZlICk7CisJZnJlZSAoIGRy
aXZlICk7CisJcmV0dXJuIHJjOworfQorCitzdHJ1Y3Qgc2FuYm9vdF9wcm90b2NvbCB2aXJ0Ymxr
X3NhbmJvb3RfcHJvdG9jb2wgX19zYW5ib290X3Byb3RvY29sID0geworCS5wcmVmaXggPSAidmly
dGlvX2JsazoiLAorCS5ib290ID0gdmlydGlvX2Jsa2Jvb3QsCit9OwpkaWZmIC0tZ2l0IGEvc3Jj
L2NvbmZpZy9jb25maWcuYyBiL3NyYy9jb25maWcvY29uZmlnLmMKaW5kZXggM2M0M2RmYi4uYmIw
ZmY2NyAxMDA2NDQKLS0tIGEvc3JjL2NvbmZpZy9jb25maWcuYworKysgYi9zcmMvY29uZmlnL2Nv
bmZpZy5jCkBAIC0xMzAsNiArMTMwLDkgQEAgUkVRVUlSRV9PQkpFQ1QgKCBhb2Vib290ICk7CiAj
aWZkZWYgU0FOQk9PVF9QUk9UT19JQl9TUlAKIFJFUVVJUkVfT0JKRUNUICggaWJfc3JwYm9vdCAp
OwogI2VuZGlmCisjaWZkZWYgU0FOQk9PVF9QUk9UT19WSVJUSU9fQkxLCitSRVFVSVJFX09CSkVD
VCAoIHZpcnRpb19ibGtib290ICk7CisjZW5kaWYKIAogLyoKICAqIERyYWcgaW4gYWxsIHJlcXVl
c3RlZCByZXNvbHZlcnMKZGlmZiAtLWdpdCBhL3NyYy9jb25maWcvZ2VuZXJhbC5oIGIvc3JjL2Nv
bmZpZy9nZW5lcmFsLmgKaW5kZXggZWUwN2RmYy4uYTFkZWMzOSAxMDA2NDQKLS0tIGEvc3JjL2Nv
bmZpZy9nZW5lcmFsLmgKKysrIGIvc3JjL2NvbmZpZy9nZW5lcmFsLmgKQEAgLTYzLDYgKzYzLDcg
QEAgRklMRV9MSUNFTkNFICggR1BMMl9PUl9MQVRFUiApOwogLy8jdW5kZWYJU0FOQk9PVF9QUk9U
T19JU0NTSQkvKiBpU0NTSSBwcm90b2NvbCAqLwogLy8jdW5kZWYJU0FOQk9PVF9QUk9UT19BT0UJ
LyogQW9FIHByb3RvY29sICovCiAvLyN1bmRlZglTQU5CT09UX1BST1RPX0lCX1NSUAkvKiBJbmZp
bmliYW5kIFNDU0kgUkRNQSBwcm90b2NvbCAqLworLy8jdW5kZWYJU0FOQk9PVF9QUk9UT19WSVJU
SU9fQkxLIC8qIFZpcnRpbyBibG9jayBkZXZpY2UgKi8KIAogLyoKICAqIE5hbWUgcmVzb2x1dGlv
biBtb2R1bGVzCmRpZmYgLS1naXQgYS9zcmMvZHJpdmVycy9ibG9jay92aXJ0aW8tYmxrLmMgYi9z
cmMvZHJpdmVycy9ibG9jay92aXJ0aW8tYmxrLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXgg
MDAwMDAwMC4uZmFiNTkzMAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9kcml2ZXJzL2Jsb2NrL3Zp
cnRpby1ibGsuYwpAQCAtMCwwICsxLDI3MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBT
dGVmYW4gSGFqbm9jemkgPHN0ZWZhbmhhQGdtYWlsLmNvbT4uCisgKgorICogVGhpcyBwcm9ncmFt
IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9k
aWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug
YXMKKyAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIg
dmVyc2lvbiAyIG9mIHRoZQorICogTGljZW5zZSwgb3IgYW55IGxhdGVyIHZlcnNpb24uCisgKgor
ICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBi
ZSB1c2VmdWwsIGJ1dAorICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUg
aW1wbGllZCB3YXJyYW50eSBvZgorICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEg
UEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKKyAqIEdlbmVyYWwgUHVibGljIExpY2Vu
c2UgZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBj
b3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQorICogYWxvbmcgd2l0aCB0aGlz
IHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKKyAqIEZvdW5kYXRp
b24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgorICovCisK
K0ZJTEVfTElDRU5DRSAoIEdQTDJfT1JfTEFURVIgKTsKKworI2luY2x1ZGUgPGVycm5vLmg+Cisj
aW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8Z3B4ZS9wcm9jZXNzLmg+CisjaW5jbHVkZSA8
Z3B4ZS92aXJ0YmxrLmg+CisjaW5jbHVkZSAidmlydGlvLWJsay5oIgorCisvKioKKyAqIEBmaWxl
CisgKgorICogVmlydGlvIGJsb2NrIGRldmljZXMKKyAqCisgKi8KKworLyoqIExpc3Qgb2Ygdmly
dGlvIGJsb2NrIGRldmljZXMgKi8KK3N0YXRpYyBMSVNUX0hFQUQgKCB2aXJ0YmxrX2RldmljZXMg
KTsKKworLyoqCisgKiBSZWdpc3RlciB2aXJ0aW8gYmxvY2sgZGV2aWNlCisgKgorICogQHYgdmly
dGJsawkJVmlydGlvIGJsb2NrIGRldmljZQorICoKKyAqIEFkZHMgdGhlIHZpcnRpbyBibG9jayBk
ZXZpY2UgdG8gdGhlIGxpc3Qgb2YgdmlydGlvIGJsb2NrIGRldmljZXMuCisgKi8KK3N0YXRpYyB2
b2lkIHJlZ2lzdGVyX3ZpcnRibGsgKCBzdHJ1Y3QgdmlydGJsayAqdmlydGJsayApIHsKKwlsaXN0
X2FkZF90YWlsICggJnZpcnRibGstPnZpcnRibGtfZGV2aWNlcywgJnZpcnRibGtfZGV2aWNlcyAp
OworfQorCisvKioKKyAqIFVucmVnaXN0ZXIgdmlydGlvIGJsb2NrIGRldmljZQorICoKKyAqIEB2
IHZpcnRibGsJCVZpcnRpbyBibG9jayBkZXZpY2UKKyAqCisgKiBSZW1vdmVzIHRoZSB2aXJ0aW8g
YmxvY2sgZGV2aWNlIGZyb20gdGhlIGxpc3Qgb2YgdmlydGlvIGJsb2NrIGRldmljZXMuCisgKi8K
K3N0YXRpYyB2b2lkIHVucmVnaXN0ZXJfdmlydGJsayAoIHN0cnVjdCB2aXJ0YmxrICp2aXJ0Ymxr
ICkgeworCWxpc3RfZGVsICggJnZpcnRibGstPnZpcnRibGtfZGV2aWNlcyApOworfQorCisvKioK
KyAqIEZpbmQgdmlydGlvIGJsb2NrIGRldmljZSBieSBuYW1lCisgKgorICogQHYgZGV2aWNlX25h
bWUJRGV2aWNlIG5hbWUKKyAqIEByZXQgdmlydGJsawkJVmlydGlvIGJsb2NrIGRldmljZSBvciBO
VUxMCisgKgorICogU2VhcmNoZXMgdGhlIGxpc3Qgb2YgdmlydGlvIGJsb2NrIGRldmljZXMgYnkg
bmFtZS4KKyAqLworc3RydWN0IHZpcnRibGsgKmZpbmRfdmlydGJsayAoIGNvbnN0IGNoYXIgKmRl
dmljZV9uYW1lICkgeworCXN0cnVjdCB2aXJ0YmxrICp2aXJ0YmxrOworCURCRyAoICJmaW5kX3Zp
cnRibGsgXCIlc1wiXG4iLCBkZXZpY2VfbmFtZSApOworCWxpc3RfZm9yX2VhY2hfZW50cnkgKCB2
aXJ0YmxrLCAmdmlydGJsa19kZXZpY2VzLCB2aXJ0YmxrX2RldmljZXMgKSB7CisJCWlmICggISBz
dHJjbXAgKCBkZXZpY2VfbmFtZSwgdmlydGJsay0+cGRldi0+ZGV2Lm5hbWUgKSApCisJCQlyZXR1
cm4gdmlydGJsazsKKwl9CisJcmV0dXJuIE5VTEw7Cit9CisKKy8qKgorICogSXNzdWUgYW4gSS9P
IHJlcXVlc3QgYW5kIHdhaXQgZm9yIGNvbXBsZXRpb24KKyAqCisgKiBAdiB2aXJ0YmxrCQlWaXJ0
aW8gYmxvY2sgZGV2aWNlCisgKiBAdiB0eXBlCQlWSVJUSU9fQkxLX1RfSU4gb3IgVklSVElPX0JM
S19UX09VVAorICogQHYgYmxvY2sJCUJsb2NrIG51bWJlcgorICogQHYgY291bnQJCUJsb2NrIGNv
dW50CisgKiBAdiBidWZmZXIJCURhdGEgYnVmZmVyCisgKiBAcmV0IHJjCQlSZXR1cm4gc3RhdHVz
IGNvZGUKKyAqLworc3RhdGljIGludCB2aXJ0YmxrX2NvbW1hbmQgKCBzdHJ1Y3QgdmlydGJsayAq
dmlydGJsaywgdTMyIHR5cGUsCisJCQkgICAgIHVpbnQ2NF90IGJsb2NrLCB1bnNpZ25lZCBsb25n
IGNvdW50LAorCQkJICAgICB1c2VycHRyX3QgYnVmZmVyICkgeworCS8qCisJICogVmlydGlvIGJs
b2NrIHJlcXVlc3RzIGhhdmUgdGhlIGZvbGxvd2luZyBmb3JtYXQ6CisJICoKKwkgKiAgICstLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKwkgKiAgIHwgc3RydWN0IHZpcnRpb19ibGtf
b3V0aGRyICBbSU5dIHwKKwkgKiAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsK
KwkgKiAgIHwgSW4vb3V0IGJ1ZmZlciAgICAgICAgIFtJTi9PVVRdIHwKKwkgKiAgICstLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKwkgKiAgIHwgU3RhdHVzIGJ5dGUgICAgICAgICAg
ICAgIFtPVVRdIHwKKwkgKiAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKKwkg
KgorCSAqIFRoZSBkZXZpY2UgZmlsbHMgaW4gdGhlIHN0YXR1cyBieXRlIHRvIGluZGljYXRlIHRo
ZSBvdXRjb21lIHRoZQorCSAqIG9wZXJhdGlvbi4KKwkgKi8KKwlzdHJ1Y3QgdnJpbmdfdmlydHF1
ZXVlICp2cSA9ICZ2aXJ0YmxrLT52aXJ0cXVldWU7CisJc3RydWN0IHZpcnRpb19ibGtfb3V0aGRy
IGhkciA9IHsKKwkJLnR5cGUgPSB0eXBlLAorCQkuaW9wcmlvID0gMCwKKwkJLnNlY3RvciA9IGJs
b2NrLAorCX07CisJdWludDhfdCBzdGF0dXMgPSBWSVJUSU9fQkxLX1NfVU5TVVBQOworCXN0cnVj
dCB2cmluZ19saXN0IGxpc3RbXSA9IHsKKwkJeworCQkJLmFkZHIJPSAoIGNoYXIgKiApICZoZHIs
CisJCQkubGVuZ3RoCT0gc2l6ZW9mICggaGRyICksCisJCX0sCisJCXsKKwkJCS5hZGRyCT0gKCBj
aGFyICogKSB1c2VyX3RvX3ZpcnQgKCBidWZmZXIsIDAgKSwKKwkJCS5sZW5ndGgJPSB2aXJ0Ymxr
LT5ibG9ja2Rldi5ibGtzaXplICogY291bnQsCisJCX0sCisJCXsKKwkJCS5hZGRyCT0gKCBjaGFy
ICogKSAmc3RhdHVzLAorCQkJLmxlbmd0aAk9IHNpemVvZiAoIHN0YXR1cyApLAorCQl9LAorCX07
CisJdW5zaWduZWQgaW50IGluLCBvdXQ7CisKKwlEQkcgKCAiVklSVEJMSyByZXEgMHglMDJ4IExC
QSAweCVsbHggY291bnQgMHglbHhcbiIsCisJICAgICAgdHlwZSwgYmxvY2ssIGNvdW50ICk7CisK
KwkvKiBOdW1iZXIgb2YgZWxlbWVudHMgcmVhZGFibGUgYW5kIHdyaXRhYmxlICovCisJaWYgKCB0
eXBlID09IFZJUlRJT19CTEtfVF9JTiApIHsKKwkJb3V0ID0gMTsKKwkJaW4gPSAyOworCX0gZWxz
ZSB7CisJCW91dCA9IDI7CisJCWluID0gMTsKKwl9CisKKwkvKiBBZGQgdG8gdmlydHF1ZXVlIGFu
ZCBraWNrIGhvc3QgKi8KKwl2cmluZ19hZGRfYnVmICggdnEsIGxpc3QsIG91dCwgaW4sIDAsIDAg
KTsKKwl2cmluZ19raWNrICggdmlydGJsay0+cGRldi0+aW9hZGRyLCB2cSwgMSApOworCisJLyog
V2FpdCBmb3IgcmVwbHkgKi8KKwl3aGlsZSAoICEgdnJpbmdfbW9yZV91c2VkICggdnEgKSApIHsK
KwkJbWIoKTsKKwkJc3RlcCgpOworCX0KKworCS8qIFJlY2xhaW0gdmlydHF1ZXVlIGVsZW1lbnQg
Ki8KKwl2cmluZ19nZXRfYnVmICggdnEsIE5VTEwgKTsKKwlyZXR1cm4gc3RhdHVzID09IFZJUlRJ
T19CTEtfU19PSyA/IDAgOiAtRUlPOworfQorCisvKioKKyAqIFJlYWQgYmxvY2sKKyAqCisgKiBA
diBibG9ja2RldgkJQmxvY2sgZGV2aWNlCisgKiBAdiBibG9jawkJQmxvY2sgbnVtYmVyCisgKiBA
diBjb3VudAkJQmxvY2sgY291bnQKKyAqIEB2IGJ1ZmZlcgkJRGF0YSBidWZmZXIKKyAqIEByZXQg
cmMJCVJldHVybiBzdGF0dXMgY29kZQorICovCitzdGF0aWMgaW50IHZpcnRibGtfcmVhZCAoIHN0
cnVjdCBibG9ja19kZXZpY2UgKmJsb2NrZGV2LCB1aW50NjRfdCBibG9jaywKKwkJCSAgdW5zaWdu
ZWQgbG9uZyBjb3VudCwgdXNlcnB0cl90IGJ1ZmZlciApIHsKKwlzdHJ1Y3QgdmlydGJsayAqdmly
dGJsayA9CisJCWNvbnRhaW5lcl9vZiAoIGJsb2NrZGV2LCBzdHJ1Y3QgdmlydGJsaywgYmxvY2tk
ZXYgKTsKKwlyZXR1cm4gdmlydGJsa19jb21tYW5kICggdmlydGJsaywgVklSVElPX0JMS19UX0lO
LCBibG9jaywKKwkJCQkgY291bnQsIGJ1ZmZlciApOworfQorCisvKioKKyAqIFdyaXRlIGJsb2Nr
CisgKgorICogQHYgYmxvY2tkZXYJCUJsb2NrIGRldmljZQorICogQHYgYmxvY2sJCUJsb2NrIG51
bWJlcgorICogQHYgY291bnQJCUJsb2NrIGNvdW50CisgKiBAdiBidWZmZXIJCURhdGEgYnVmZmVy
CisgKiBAcmV0IHJjCQlSZXR1cm4gc3RhdHVzIGNvZGUKKyAqLworc3RhdGljIGludCB2aXJ0Ymxr
X3dyaXRlICggc3RydWN0IGJsb2NrX2RldmljZSAqYmxvY2tkZXYgX191bnVzZWQsIHVpbnQ2NF90
IGJsb2NrIF9fdW51c2VkLAorCQkJICAgdW5zaWduZWQgbG9uZyBjb3VudCBfX3VudXNlZCwgdXNl
cnB0cl90IGJ1ZmZlciBfX3VudXNlZCApIHsKKwlzdHJ1Y3QgdmlydGJsayAqdmlydGJsayA9CisJ
CWNvbnRhaW5lcl9vZiAoIGJsb2NrZGV2LCBzdHJ1Y3QgdmlydGJsaywgYmxvY2tkZXYgKTsKKwly
ZXR1cm4gdmlydGJsa19jb21tYW5kICggdmlydGJsaywgVklSVElPX0JMS19UX09VVCwgYmxvY2ss
CisJCQkJIGNvdW50LCBidWZmZXIgKTsKK30KKworc3RhdGljIHN0cnVjdCBibG9ja19kZXZpY2Vf
b3BlcmF0aW9ucyB2aXJ0YmxrX29wZXJhdGlvbnMgPSB7CisJLnJlYWQJPSB2aXJ0YmxrX3JlYWQs
CisJLndyaXRlCT0gdmlydGJsa193cml0ZSwKK307CisKKy8qKgorICogUHJvYmUgUENJIGRldmlj
ZQorICoKKyAqIEB2IHBjaQlQQ0kgZGV2aWNlCisgKiBAdiBpZAlQQ0kgSUQKKyAqIEByZXQgcmMJ
UmV0dXJuIHN0YXR1cyBjb2RlCisgKi8KK3N0YXRpYyBpbnQgdmlydGJsa19wcm9iZSAoIHN0cnVj
dCBwY2lfZGV2aWNlICpwY2ksCisJCQkgICBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQg
X191bnVzZWQgKSB7CisJdW5zaWduZWQgbG9uZyBpb2FkZHIgPSBwY2ktPmlvYWRkcjsKKworCS8q
IEluaXRpYWxpemUgZHJpdmVyIHN0YXRlICovCisJc3RydWN0IHZpcnRibGsgKnZpcnRibGsgPSB6
YWxsb2MgKCBzaXplb2YgKnZpcnRibGsgKTsKKwlpZiAoICEgdmlydGJsayApCisJCXJldHVybiAt
RU5PTUVNOworCUlOSVRfTElTVF9IRUFEICggJnZpcnRibGstPnZpcnRibGtfZGV2aWNlcyApOwor
CXZpcnRibGstPmJsb2NrZGV2Lm9wID0gJnZpcnRibGtfb3BlcmF0aW9uczsKKwl2aXJ0YmxrLT5w
ZGV2ID0gcGNpOworCXBjaS0+cHJpdiA9IHZpcnRibGs7CisKKwkvKiBQcmVwYXJlIHRoZSBkZXZp
Y2UgKi8KKwlhZGp1c3RfcGNpX2RldmljZSAoIHBjaSApOworCXZwX3Jlc2V0ICggaW9hZGRyICk7
CisKKwkvKiBJbmRpY2F0ZSB0aGF0IHRoZSBkcml2ZXIgaXMgc3RhcnRpbmcgKi8KKwl2cF9zZXRf
c3RhdHVzICggaW9hZGRyLCBWSVJUSU9fQ09ORklHX1NfQUNLTk9XTEVER0UgfAorCQkJCVZJUlRJ
T19DT05GSUdfU19EUklWRVIgKTsKKworCS8qIEdyYWIgdGhlIEkvTyByZXF1ZXN0cyB2aXJ0cXVl
dWUgKi8KKwlpZiAoIHZwX2ZpbmRfdnEgKCBpb2FkZHIsIDAsICZ2aXJ0YmxrLT52aXJ0cXVldWUg
KSA8IDAgKSB7CisJCWZyZWUgKCB2aXJ0YmxrICk7CisJCXJldHVybiAtRU5PRU5UOworCX0KKwor
CS8qIEZlYXR1cmUgbmVnb3RpYXRpb24gKi8KKwl1MzIgZmVhdHVyZXMgPSB2cF9nZXRfZmVhdHVy
ZXMgKCBpb2FkZHIgKTsKKwl2cF9zZXRfZmVhdHVyZXMgKCBpb2FkZHIsIDAgKTsgLyogbm8gZmVh
dHVyZXMgcmVxdWlyZWQgKi8KKworCS8qIEZpbmQgb3V0IHRoZSBkcml2ZSBjYXBhY2l0eSAqLwor
CXZpcnRibGstPmJsb2NrZGV2LmJsa3NpemUgPSA1MTI7IC8qIHRoZSBkZWZhdWx0ICovCisJdnBf
Z2V0ICggaW9hZGRyLCAwLCAmdmlydGJsay0+YmxvY2tkZXYuYmxvY2tzLAorCQkgc2l6ZW9mIHZp
cnRibGstPmJsb2NrZGV2LmJsb2NrcyApOworCisJLyogSW5kaWNhdGUgdGhhdCB0aGUgZHJpdmVy
IGlzIHJlYWR5ICovCisJdnBfc2V0X3N0YXR1cyAoIGlvYWRkciwgVklSVElPX0NPTkZJR19TX0FD
S05PV0xFREdFIHwKKwkJCQlWSVJUSU9fQ09ORklHX1NfRFJJVkVSIHwKKwkJCQlWSVJUSU9fQ09O
RklHX1NfRFJJVkVSX09LICk7CisKKwlEQkdDICggdmlydGJsaywgIlZJUlRCTEsgJXAgdmlydGlv
X2JsazolcyBpb2FkZHI9MHglbHggaXJxPSVkIGZlYXR1cmVzPTB4JXggY2FwYWNpdHk9JWxsZFxu
IiwKKwkgICAgICAgdmlydGJsaywgcGNpLT5kZXYubmFtZSwgaW9hZGRyLCBwY2ktPmlycSwKKwkg
ICAgICAgZmVhdHVyZXMsIHZpcnRibGstPmJsb2NrZGV2LmJsb2NrcyApOworCisJcmVnaXN0ZXJf
dmlydGJsayAoIHZpcnRibGsgKTsKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBSZW1vdmUgUENJ
IGRldmljZQorICoKKyAqIEB2IHBjaQlQQ0kgZGV2aWNlCisgKi8KK3N0YXRpYyB2b2lkIHZpcnRi
bGtfcmVtb3ZlICggc3RydWN0IHBjaV9kZXZpY2UgKnBjaSApIHsKKwlzdHJ1Y3QgdmlydGJsayAq
dmlydGJsayA9IHBjaS0+cHJpdjsKKworCXVucmVnaXN0ZXJfdmlydGJsayAoIHZpcnRibGsgKTsK
Kwl2cF9yZXNldCAoIHBjaS0+aW9hZGRyICk7CisJZnJlZSAoIHZpcnRibGsgKTsKK30KKworc3Rh
dGljIHN0cnVjdCBwY2lfZGV2aWNlX2lkIHZpcnRibGtfaWRzW10gPSB7CisJUENJX1JPTSgweDFh
ZjQsIDB4MTAwMSwgInZpcnRpby1ibGsiLCAiVmlydGlvIEJsb2NrIERldmljZSIsIDApLAorfTsK
Kworc3RydWN0IHBjaV9kcml2ZXIgdmlydGJsa19kcml2ZXIgX19wY2lfZHJpdmVyID0geworICAu
aWRzID0gdmlydGJsa19pZHMsCisgIC5pZF9jb3VudCA9ICggc2l6ZW9mICggdmlydGJsa19pZHMg
KSAvIHNpemVvZiAoIHZpcnRibGtfaWRzWzBdICkgKSwKKyAgLnByb2JlID0gdmlydGJsa19wcm9i
ZSwKKyAgLnJlbW92ZSA9IHZpcnRibGtfcmVtb3ZlLAorfTsKZGlmZiAtLWdpdCBhL3NyYy9kcml2
ZXJzL2Jsb2NrL3ZpcnRpby1ibGsuaCBiL3NyYy9kcml2ZXJzL2Jsb2NrL3ZpcnRpby1ibGsuaApu
ZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTM0ODY4Ci0tLSAvZGV2L251bGwK
KysrIGIvc3JjL2RyaXZlcnMvYmxvY2svdmlydGlvLWJsay5oCkBAIC0wLDAgKzEsMzAgQEAKKyNp
Zm5kZWYgX1ZJUlRJT19CTEtfSAorI2RlZmluZSBfVklSVElPX0JMS19ICisvKiBUaGlzIGhlYWRl
ciBpcyBCU0QgbGljZW5zZWQgc28gYW55b25lIGNhbiB1c2UgdGhlIGRlZmluaXRpb25zIHRvIGlt
cGxlbWVudAorICogY29tcGF0aWJsZSBkcml2ZXJzL3NlcnZlcnMuICovCisKK0ZJTEVfTElDRU5D
RSAoIEJTRDIgKTsKKworLyoKKyAqIENvbW1hbmQgdHlwZXMKKyAqLworCisvKiBUaGVzZSB0d28g
ZGVmaW5lIGRpcmVjdGlvbi4gKi8KKyNkZWZpbmUgVklSVElPX0JMS19UX0lOCQkwCisjZGVmaW5l
IFZJUlRJT19CTEtfVF9PVVQJMQorCisvKiBUaGlzIGlzIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRo
ZSByZWFkIHNjYXR0ZXItZ2F0aGVyIGxpc3QuICovCitzdHJ1Y3QgdmlydGlvX2Jsa19vdXRoZHIg
eworCS8qIFZJUlRJT19CTEtfVCogKi8KKwl1MzIgdHlwZTsKKwkvKiBpbyBwcmlvcml0eS4gKi8K
Kwl1MzIgaW9wcmlvOworCS8qIFNlY3RvciAoaWUuIDUxMiBieXRlIG9mZnNldCkgKi8KKwl1NjQg
c2VjdG9yOworfTsKKworLyogQW5kIHRoaXMgaXMgdGhlIGZpbmFsIGJ5dGUgb2YgdGhlIHdyaXRl
IHNjYXR0ZXItZ2F0aGVyIGxpc3QuICovCisjZGVmaW5lIFZJUlRJT19CTEtfU19PSwkJMAorI2Rl
ZmluZSBWSVJUSU9fQkxLX1NfSU9FUlIJMQorI2RlZmluZSBWSVJUSU9fQkxLX1NfVU5TVVBQCTIK
KyNlbmRpZiAvKiBfVklSVElPX0JMS19IICovCmRpZmYgLS1naXQgYS9zcmMvaW5jbHVkZS9ncHhl
L2VycmZpbGUuaCBiL3NyYy9pbmNsdWRlL2dweGUvZXJyZmlsZS5oCmluZGV4IDUyMzFjMTQuLjA5
MmQ3ZWIgMTAwNjQ0Ci0tLSBhL3NyYy9pbmNsdWRlL2dweGUvZXJyZmlsZS5oCisrKyBiL3NyYy9p
bmNsdWRlL2dweGUvZXJyZmlsZS5oCkBAIC0xMjIsNiArMTIyLDcgQEAgRklMRV9MSUNFTkNFICgg
R1BMMl9PUl9MQVRFUiApOwogI2RlZmluZSBFUlJGSUxFX2xpbmRhCQkgICAgICggRVJSRklMRV9E
UklWRVIgfCAweDAwNzMwMDAwICkKICNkZWZpbmUgRVJSRklMRV9hdGEJCSAgICAgKCBFUlJGSUxF
X0RSSVZFUiB8IDB4MDA3NDAwMDAgKQogI2RlZmluZSBFUlJGSUxFX3NycAkJICAgICAoIEVSUkZJ
TEVfRFJJVkVSIHwgMHgwMDc1MDAwMCApCisjZGVmaW5lIEVSUkZJTEVfdmlydGlvX2JsawkgICAg
ICggRVJSRklMRV9EUklWRVIgfCAweDAwNzYwMDAwICkKIAogI2RlZmluZSBFUlJGSUxFX2FvZQkJ
CSggRVJSRklMRV9ORVQgfCAweDAwMDAwMDAwICkKICNkZWZpbmUgRVJSRklMRV9hcnAJCQkoIEVS
UkZJTEVfTkVUIHwgMHgwMDAxMDAwMCApCkBAIC0xOTEsNiArMTkyLDcgQEAgRklMRV9MSUNFTkNF
ICggR1BMMl9PUl9MQVRFUiApOwogI2RlZmluZSBFUlJGSUxFX3g1MDkJCSAgICAgICggRVJSRklM
RV9PVEhFUiB8IDB4MDAxNjAwMDAgKQogI2RlZmluZSBFUlJGSUxFX2xvZ2luX3VpCSAgICAgICgg
RVJSRklMRV9PVEhFUiB8IDB4MDAxNzAwMDAgKQogI2RlZmluZSBFUlJGSUxFX2liX3NycGJvb3QJ
ICAgICAgKCBFUlJGSUxFX09USEVSIHwgMHgwMDE4MDAwMCApCisjZGVmaW5lIEVSUkZJTEVfdmly
dGlvX2Jsa2Jvb3QJICAgICAgKCBFUlJGSUxFX09USEVSIHwgMHgwMDE5MDAwMCApCiAKIC8qKiBA
fSAqLwogCmRpZmYgLS1naXQgYS9zcmMvaW5jbHVkZS9ncHhlL3ZpcnRibGsuaCBiL3NyYy9pbmNs
dWRlL2dweGUvdmlydGJsay5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4
MWQ0MzMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvaW5jbHVkZS9ncHhlL3ZpcnRibGsuaApAQCAt
MCwwICsxLDM3IEBACisjaWZuZGVmIF9HUFhFX1ZJUlRCTEtfSAorI2RlZmluZSBfR1BYRV9WSVJU
QkxLX0gKKworLyoqIEBmaWxlCisgKgorICogVmlydGlvIGJsb2NrIGRldmljZQorICoKKyAqLwor
CitGSUxFX0xJQ0VOQ0UgKCBHUEwyX09SX0xBVEVSICk7CisKKyNpbmNsdWRlIDxncHhlL2xpc3Qu
aD4KKyNpbmNsdWRlIDxncHhlL3BjaS5oPgorI2luY2x1ZGUgPGdweGUvdmlydGlvLXJpbmcuaD4K
KyNpbmNsdWRlIDxncHhlL3ZpcnRpby1wY2kuaD4KKyNpbmNsdWRlIDxncHhlL2Jsb2NrZGV2Lmg+
CisKKy8qKgorICogVmlydGlvIGJsb2NrIGRldmljZQorICovCitzdHJ1Y3QgdmlydGJsayB7CisJ
LyoqIExpc3Qgb2YgdmlydGlvLWJsayBkZXZpY2VzICovCisJc3RydWN0IGxpc3RfaGVhZCB2aXJ0
YmxrX2RldmljZXM7CisKKwkvKiogVW5kZXJseWluZyBQQ0kgZGV2aWNlICovCisJc3RydWN0IHBj
aV9kZXZpY2UgKnBkZXY7CisKKwkvKiogT3V0Z29pbmcgcmVxdWVzdHMgdmlydHF1ZXVlICovCisJ
c3RydWN0IHZyaW5nX3ZpcnRxdWV1ZSB2aXJ0cXVldWU7CisKKwkvKiogQmxvY2sgZGV2aWNlICov
CisJc3RydWN0IGJsb2NrX2RldmljZSBibG9ja2RldjsKK307CisKK2V4dGVybiBzdHJ1Y3Qgdmly
dGJsayAqZmluZF92aXJ0YmxrICggY29uc3QgY2hhciAqZGV2aWNlX25hbWUgKTsKKworI2VuZGlm
IC8qIF9HUFhFX1ZJUlRCTEtfSCAqLwotLSAKMS42LjUKCg==
--001485eafef29d92c3047c70ef97--


More information about the gPXE mailing list