From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44742) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evSIi-0008Pt-Qa for qemu-devel@nongnu.org; Mon, 12 Mar 2018 14:36:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evSIh-0005YU-5K for qemu-devel@nongnu.org; Mon, 12 Mar 2018 14:36:00 -0400 Received: from mail-pl0-x22b.google.com ([2607:f8b0:400e:c01::22b]:45690) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1evSIg-0005YD-Se for qemu-devel@nongnu.org; Mon, 12 Mar 2018 14:35:59 -0400 Received: by mail-pl0-x22b.google.com with SMTP id v9-v6so9810258plp.12 for ; Mon, 12 Mar 2018 11:35:58 -0700 (PDT) From: Alexey Gerasimenko Date: Tue, 13 Mar 2018 04:34:07 +1000 Message-Id: <4918ab0dbd7e53ef3a83ff68a546e6cea9d8c7fa.1520867956.git.x1917x@gmail.com> In-Reply-To: References: In-Reply-To: References: Subject: [Qemu-devel] [RFC PATCH 22/30] xen/pt: add support for PCIe Extended Capabilities and larger config space List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: xen-devel@lists.xenproject.org Cc: Alexey Gerasimenko , qemu-devel@nongnu.org, Stefano Stabellini , Anthony Perard This patch provides basic facilities for PCIe Extended Capabilities and support for controlled (via s->pcie_enabled_dev flag) access to PCIe config space (>256). PCIe Extended Capabilities make use of 16-bit capability ID. Also, a capability size might exceed 8-bit width. So as the very first step we need to increase type size for grp_id, grp_size, etc -- they were limited to 8-bit. The only troublesome issue with PCIe Extended Capability IDs is that their value range is actually same as for basic PCI capabilities. Eg. capability ID 3 means VPD Capability for PCI and at the same time Device Serial Number Capability for PCIe Extended caps. This adds a bit of inconvenience. In order to distinguish between two sets of same capability IDs, the patch introduces a set of macros to mark a capability ID as PCIe Extended one (or check if it is basic/extended + get a raw ID value): - PCIE_EXT_CAP_ID(cap_id) - IS_PCIE_EXT_CAP_ID(grp_id) - GET_PCIE_EXT_CAP_ID(grp_id) Here is how it's used: /* Intel IGD Opregion group */ { .grp_id = XEN_PCI_INTEL_OPREGION, /* no change */ .grp_type = XEN_PT_GRP_TYPE_EMU, .grp_size = 0x4, .size_init = xen_pt_reg_grp_size_init, .emu_regs = xen_pt_emu_reg_igd_opregion, }, /* Vendor-specific Extended Capability reg group */ { .grp_id = PCIE_EXT_CAP_ID(PCI_EXT_CAP_ID_VNDR), .grp_type = XEN_PT_GRP_TYPE_EMU, .grp_size = 0xFF, .size_init = xen_pt_ext_cap_vendor_size_init, .emu_regs = xen_pt_ext_cap_emu_reg_vendor, }, By using the PCIE_EXT_CAP_ID() macro it is possible to reuse existing header files with already defined PCIe Extended Capability ID values. find_cap_offset() receive capabily ID and checks if it's an Extended one by using IS_PCIE_EXT_CAP_ID(cap) macro, passing the real capabiliy ID value to either xen_host_pci_find_next_ext_cap or xen_host_pci_find_next_cap. Signed-off-by: Alexey Gerasimenko --- hw/xen/xen_pt.c | 14 +++++- hw/xen/xen_pt.h | 13 +++-- hw/xen/xen_pt_config_init.c | 113 +++++++++++++++++++++----------------------- 3 files changed, 74 insertions(+), 66 deletions(-) diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index a902a9b685..bf098c26b3 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -82,10 +82,20 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...) /* Config Space */ -static int xen_pt_pci_config_access_check(PCIDevice *d, uint32_t addr, int len) +static int xen_pt_pci_config_access_check(PCIDevice *d, + uint32_t addr, int len) { + XenPCIPassthroughState *s = XEN_PT_DEVICE(d); + /* check offset range */ - if (addr > 0xFF) { + if (s->pcie_enabled_dev) { + if (addr >= PCIE_CONFIG_SPACE_SIZE) { + XEN_PT_ERR(d, "Failed to access register with offset " + "exceeding 0xFFF. (addr: 0x%02x, len: %d)\n", + addr, len); + return -1; + } + } else if (addr >= PCI_CONFIG_SPACE_SIZE) { XEN_PT_ERR(d, "Failed to access register with offset exceeding 0xFF. " "(addr: 0x%02x, len: %d)\n", addr, len); return -1; diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index 1204acbdce..5531347ab2 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -31,6 +31,11 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3); /* Helper */ #define XEN_PFN(x) ((x) >> XC_PAGE_SHIFT) +/* Macro's for PCIe Extended Capabilities */ +#define PCIE_EXT_CAP_ID(cap_id) ((cap_id) | (1U << 16)) +#define IS_PCIE_EXT_CAP_ID(grp_id) ((grp_id) & (1U << 16)) +#define GET_PCIE_EXT_CAP_ID(grp_id) ((grp_id) & 0xFFFF) + typedef const struct XenPTRegInfo XenPTRegInfo; typedef struct XenPTReg XenPTReg; @@ -152,13 +157,13 @@ typedef const struct XenPTRegGroupInfo XenPTRegGroupInfo; /* emul reg group size initialize method */ typedef int (*xen_pt_reg_size_init_fn) (XenPCIPassthroughState *, XenPTRegGroupInfo *, - uint32_t base_offset, uint8_t *size); + uint32_t base_offset, uint32_t *size); /* emulated register group information */ struct XenPTRegGroupInfo { - uint8_t grp_id; + uint32_t grp_id; XenPTRegisterGroupType grp_type; - uint8_t grp_size; + uint32_t grp_size; xen_pt_reg_size_init_fn size_init; XenPTRegInfo *emu_regs; }; @@ -168,7 +173,7 @@ typedef struct XenPTRegGroup { QLIST_ENTRY(XenPTRegGroup) entries; XenPTRegGroupInfo *reg_grp; uint32_t base_offset; - uint8_t size; + uint32_t size; QLIST_HEAD(, XenPTReg) reg_tbl_list; } XenPTRegGroup; diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 91de215407..9c041fa288 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -32,29 +32,42 @@ static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg, /* helper */ /* A return value of 1 means the capability should NOT be exposed to guest. */ -static int xen_pt_hide_dev_cap(const XenHostPCIDevice *d, uint8_t grp_id) +static int xen_pt_hide_dev_cap(const XenHostPCIDevice *d, uint32_t grp_id) { - switch (grp_id) { - case PCI_CAP_ID_EXP: - /* The PCI Express Capability Structure of the VF of Intel 82599 10GbE - * Controller looks trivial, e.g., the PCI Express Capabilities - * Register is 0. We should not try to expose it to guest. - * - * The datasheet is available at - * http://download.intel.com/design/network/datashts/82599_datasheet.pdf - * - * See 'Table 9.7. VF PCIe Configuration Space' of the datasheet, the - * PCI Express Capability Structure of the VF of Intel 82599 10GbE - * Controller looks trivial, e.g., the PCI Express Capabilities - * Register is 0, so the Capability Version is 0 and - * xen_pt_pcie_size_init() would fail. - */ - if (d->vendor_id == PCI_VENDOR_ID_INTEL && - d->device_id == PCI_DEVICE_ID_INTEL_82599_SFP_VF) { - return 1; + if (IS_PCIE_EXT_CAP_ID(grp_id)) { + switch (GET_PCIE_EXT_CAP_ID(grp_id)) { + /* Here can be added device-specific filtering + * for PCIe Extended capabilities (those with offset >= 0x100). + * This is simply a placeholder as no filtering needed for now. + */ + default: + break; + } + } else { + /* basic PCI capability */ + switch (grp_id) { + case PCI_CAP_ID_EXP: + /* The PCI Express Capability Structure of the VF of Intel 82599 10GbE + * Controller looks trivial, e.g., the PCI Express Capabilities + * Register is 0. We should not try to expose it to guest. + * + * The datasheet is available at + * http://download.intel.com/design/network/datashts/82599_datasheet.pdf + * + * See 'Table 9.7. VF PCIe Configuration Space' of the datasheet, the + * PCI Express Capability Structure of the VF of Intel 82599 10GbE + * Controller looks trivial, e.g., the PCI Express Capabilities + * Register is 0, so the Capability Version is 0 and + * xen_pt_pcie_size_init() would fail. + */ + if (d->vendor_id == PCI_VENDOR_ID_INTEL && + d->device_id == PCI_DEVICE_ID_INTEL_82599_SFP_VF) { + return 1; + } + break; } - break; } + return 0; } @@ -1622,7 +1635,7 @@ static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = { static int xen_pt_reg_grp_size_init(XenPCIPassthroughState *s, const XenPTRegGroupInfo *grp_reg, - uint32_t base_offset, uint8_t *size) + uint32_t base_offset, uint32_t *size) { *size = grp_reg->grp_size; return 0; @@ -1630,14 +1643,18 @@ static int xen_pt_reg_grp_size_init(XenPCIPassthroughState *s, /* get Vendor Specific Capability Structure register group size */ static int xen_pt_vendor_size_init(XenPCIPassthroughState *s, const XenPTRegGroupInfo *grp_reg, - uint32_t base_offset, uint8_t *size) + uint32_t base_offset, uint32_t *size) { - return xen_host_pci_get_byte(&s->real_device, base_offset + 0x02, size); + uint8_t sz = 0; + int ret = xen_host_pci_get_byte(&s->real_device, base_offset + 0x02, &sz); + + *size = sz; + return ret; } /* get PCI Express Capability Structure register group size */ static int xen_pt_pcie_size_init(XenPCIPassthroughState *s, const XenPTRegGroupInfo *grp_reg, - uint32_t base_offset, uint8_t *size) + uint32_t base_offset, uint32_t *size) { PCIDevice *d = &s->dev; uint8_t version = get_pcie_capability_version(s); @@ -1709,7 +1726,7 @@ static int xen_pt_pcie_size_init(XenPCIPassthroughState *s, /* get MSI Capability Structure register group size */ static int xen_pt_msi_size_init(XenPCIPassthroughState *s, const XenPTRegGroupInfo *grp_reg, - uint32_t base_offset, uint8_t *size) + uint32_t base_offset, uint32_t *size) { uint16_t msg_ctrl = 0; uint8_t msi_size = 0xa; @@ -1737,7 +1754,7 @@ static int xen_pt_msi_size_init(XenPCIPassthroughState *s, /* get MSI-X Capability Structure register group size */ static int xen_pt_msix_size_init(XenPCIPassthroughState *s, const XenPTRegGroupInfo *grp_reg, - uint32_t base_offset, uint8_t *size) + uint32_t base_offset, uint32_t *size) { int rc = 0; @@ -1920,44 +1937,20 @@ out: * Main */ -static uint8_t find_cap_offset(XenPCIPassthroughState *s, uint8_t cap) +static uint32_t find_cap_offset(XenPCIPassthroughState *s, uint32_t cap) { - uint8_t id; - unsigned max_cap = XEN_PCI_CAP_MAX; - uint8_t pos = PCI_CAPABILITY_LIST; - uint8_t status = 0; + uint32_t retval = 0; - if (xen_host_pci_get_byte(&s->real_device, PCI_STATUS, &status)) { - return 0; - } - if ((status & PCI_STATUS_CAP_LIST) == 0) { - return 0; - } - - while (max_cap--) { - if (xen_host_pci_get_byte(&s->real_device, pos, &pos)) { - break; - } - if (pos < PCI_CONFIG_HEADER_SIZE) { - break; + if (IS_PCIE_EXT_CAP_ID(cap)) { + if (s->pcie_enabled_dev) { + retval = xen_host_pci_find_next_ext_cap(&s->real_device, 0, + GET_PCIE_EXT_CAP_ID(cap)); } - - pos &= ~3; - if (xen_host_pci_get_byte(&s->real_device, - pos + PCI_CAP_LIST_ID, &id)) { - break; - } - - if (id == 0xff) { - break; - } - if (id == cap) { - return pos; - } - - pos += PCI_CAP_LIST_NEXT; + } else { + retval = xen_host_pci_find_next_cap(&s->real_device, 0, cap); } - return 0; + + return retval; } static void xen_pt_config_reg_init(XenPCIPassthroughState *s, -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexey Gerasimenko Subject: [RFC PATCH 22/30] xen/pt: add support for PCIe Extended Capabilities and larger config space Date: Tue, 13 Mar 2018 04:34:07 +1000 Message-ID: <4918ab0dbd7e53ef3a83ff68a546e6cea9d8c7fa.1520867956.git.x1917x@gmail.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1evSIi-0008HY-FX for xen-devel@lists.xenproject.org; Mon, 12 Mar 2018 18:36:00 +0000 Received: by mail-pl0-x22a.google.com with SMTP id w12-v6so9830623plp.4 for ; Mon, 12 Mar 2018 11:35:58 -0700 (PDT) In-Reply-To: In-Reply-To: References: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To: xen-devel@lists.xenproject.org Cc: Anthony Perard , Stefano Stabellini , Alexey Gerasimenko , qemu-devel@nongnu.org List-Id: xen-devel@lists.xenproject.org VGhpcyBwYXRjaCBwcm92aWRlcyBiYXNpYyBmYWNpbGl0aWVzIGZvciBQQ0llIEV4dGVuZGVkIENh cGFiaWxpdGllcyBhbmQKc3VwcG9ydCBmb3IgY29udHJvbGxlZCAodmlhIHMtPnBjaWVfZW5hYmxl ZF9kZXYgZmxhZykgYWNjZXNzIHRvIFBDSWUKY29uZmlnIHNwYWNlICg+MjU2KS4KClBDSWUgRXh0 ZW5kZWQgQ2FwYWJpbGl0aWVzIG1ha2UgdXNlIG9mIDE2LWJpdCBjYXBhYmlsaXR5IElELiBBbHNv LAphIGNhcGFiaWxpdHkgc2l6ZSBtaWdodCBleGNlZWQgOC1iaXQgd2lkdGguIFNvIGFzIHRoZSB2 ZXJ5IGZpcnN0IHN0ZXAKd2UgbmVlZCB0byBpbmNyZWFzZSB0eXBlIHNpemUgZm9yIGdycF9pZCwg Z3JwX3NpemUsIGV0YyAtLSB0aGV5IHdlcmUKbGltaXRlZCB0byA4LWJpdC4KClRoZSBvbmx5IHRy b3VibGVzb21lIGlzc3VlIHdpdGggUENJZSBFeHRlbmRlZCBDYXBhYmlsaXR5IElEcyBpcyB0aGF0 IHRoZWlyCnZhbHVlIHJhbmdlIGlzIGFjdHVhbGx5IHNhbWUgYXMgZm9yIGJhc2ljIFBDSSBjYXBh YmlsaXRpZXMuCkVnLiBjYXBhYmlsaXR5IElEIDMgbWVhbnMgVlBEIENhcGFiaWxpdHkgZm9yIFBD SSBhbmQgYXQgdGhlIHNhbWUgdGltZQpEZXZpY2UgU2VyaWFsIE51bWJlciBDYXBhYmlsaXR5IGZv ciBQQ0llIEV4dGVuZGVkIGNhcHMuIFRoaXMgYWRkcyBhIGJpdCBvZgppbmNvbnZlbmllbmNlLgoK SW4gb3JkZXIgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiB0d28gc2V0cyBvZiBzYW1lIGNhcGFiaWxp dHkgSURzLCB0aGUgcGF0Y2gKaW50cm9kdWNlcyBhIHNldCBvZiBtYWNyb3MgdG8gbWFyayBhIGNh cGFiaWxpdHkgSUQgYXMgUENJZSBFeHRlbmRlZCBvbmUKKG9yIGNoZWNrIGlmIGl0IGlzIGJhc2lj L2V4dGVuZGVkICsgZ2V0IGEgcmF3IElEIHZhbHVlKToKLSBQQ0lFX0VYVF9DQVBfSUQoY2FwX2lk KQotIElTX1BDSUVfRVhUX0NBUF9JRChncnBfaWQpCi0gR0VUX1BDSUVfRVhUX0NBUF9JRChncnBf aWQpCgpIZXJlIGlzIGhvdyBpdCdzIHVzZWQ6CiAgICAvKiBJbnRlbCBJR0QgT3ByZWdpb24gZ3Jv dXAgKi8KICAgIHsKICAgICAgICAuZ3JwX2lkICAgICAgPSBYRU5fUENJX0lOVEVMX09QUkVHSU9O LCAgLyogbm8gY2hhbmdlICovCiAgICAgICAgLmdycF90eXBlICAgID0gWEVOX1BUX0dSUF9UWVBF X0VNVSwKICAgICAgICAuZ3JwX3NpemUgICAgPSAweDQsCiAgICAgICAgLnNpemVfaW5pdCAgID0g eGVuX3B0X3JlZ19ncnBfc2l6ZV9pbml0LAogICAgICAgIC5lbXVfcmVncyAgICA9IHhlbl9wdF9l bXVfcmVnX2lnZF9vcHJlZ2lvbiwKICAgIH0sCiAgICAvKiBWZW5kb3Itc3BlY2lmaWMgRXh0ZW5k ZWQgQ2FwYWJpbGl0eSByZWcgZ3JvdXAgKi8KICAgIHsKICAgICAgICAuZ3JwX2lkICAgICAgPSBQ Q0lFX0VYVF9DQVBfSUQoUENJX0VYVF9DQVBfSURfVk5EUiksCiAgICAgICAgLmdycF90eXBlICAg ID0gWEVOX1BUX0dSUF9UWVBFX0VNVSwKICAgICAgICAuZ3JwX3NpemUgICAgPSAweEZGLAogICAg ICAgIC5zaXplX2luaXQgICA9IHhlbl9wdF9leHRfY2FwX3ZlbmRvcl9zaXplX2luaXQsCiAgICAg ICAgLmVtdV9yZWdzICAgID0geGVuX3B0X2V4dF9jYXBfZW11X3JlZ192ZW5kb3IsCiAgICB9LApC eSB1c2luZyB0aGUgUENJRV9FWFRfQ0FQX0lEKCkgbWFjcm8gaXQgaXMgcG9zc2libGUgdG8gcmV1 c2UgZXhpc3RpbmcKaGVhZGVyIGZpbGVzIHdpdGggYWxyZWFkeSBkZWZpbmVkIFBDSWUgRXh0ZW5k ZWQgQ2FwYWJpbGl0eSBJRCB2YWx1ZXMuCgpmaW5kX2NhcF9vZmZzZXQoKSByZWNlaXZlIGNhcGFi aWx5IElEIGFuZCBjaGVja3MgaWYgaXQncyBhbiBFeHRlbmRlZCBvbmUKYnkgdXNpbmcgSVNfUENJ RV9FWFRfQ0FQX0lEKGNhcCkgbWFjcm8sIHBhc3NpbmcgdGhlIHJlYWwgY2FwYWJpbGl5CklEIHZh bHVlIHRvIGVpdGhlciB4ZW5faG9zdF9wY2lfZmluZF9uZXh0X2V4dF9jYXAKb3IgeGVuX2hvc3Rf cGNpX2ZpbmRfbmV4dF9jYXAuCgpTaWduZWQtb2ZmLWJ5OiBBbGV4ZXkgR2VyYXNpbWVua28gPHgx OTE3eEBnbWFpbC5jb20+Ci0tLQogaHcveGVuL3hlbl9wdC5jICAgICAgICAgICAgIHwgIDE0ICsr KysrLQogaHcveGVuL3hlbl9wdC5oICAgICAgICAgICAgIHwgIDEzICsrKy0tCiBody94ZW4veGVu X3B0X2NvbmZpZ19pbml0LmMgfCAxMTMgKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0KIDMgZmlsZXMgY2hhbmdlZCwgNzQgaW5zZXJ0aW9ucygrKSwgNjYgZGVsZXRp b25zKC0pCgpkaWZmIC0tZ2l0IGEvaHcveGVuL3hlbl9wdC5jIGIvaHcveGVuL3hlbl9wdC5jCmlu ZGV4IGE5MDJhOWI2ODUuLmJmMDk4YzI2YjMgMTAwNjQ0Ci0tLSBhL2h3L3hlbi94ZW5fcHQuYwor KysgYi9ody94ZW4veGVuX3B0LmMKQEAgLTgyLDEwICs4MiwyMCBAQCB2b2lkIHhlbl9wdF9sb2co Y29uc3QgUENJRGV2aWNlICpkLCBjb25zdCBjaGFyICpmLCAuLi4pCiAKIC8qIENvbmZpZyBTcGFj ZSAqLwogCi1zdGF0aWMgaW50IHhlbl9wdF9wY2lfY29uZmlnX2FjY2Vzc19jaGVjayhQQ0lEZXZp Y2UgKmQsIHVpbnQzMl90IGFkZHIsIGludCBsZW4pCitzdGF0aWMgaW50IHhlbl9wdF9wY2lfY29u ZmlnX2FjY2Vzc19jaGVjayhQQ0lEZXZpY2UgKmQsCisgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICB1aW50MzJfdCBhZGRyLCBpbnQgbGVuKQogeworICAgIFhlblBDSVBh c3N0aHJvdWdoU3RhdGUgKnMgPSBYRU5fUFRfREVWSUNFKGQpOworCiAgICAgLyogY2hlY2sgb2Zm c2V0IHJhbmdlICovCi0gICAgaWYgKGFkZHIgPiAweEZGKSB7CisgICAgaWYgKHMtPnBjaWVfZW5h YmxlZF9kZXYpIHsKKyAgICAgICAgaWYgKGFkZHIgPj0gUENJRV9DT05GSUdfU1BBQ0VfU0laRSkg eworICAgICAgICAgICAgWEVOX1BUX0VSUihkLCAiRmFpbGVkIHRvIGFjY2VzcyByZWdpc3RlciB3 aXRoIG9mZnNldCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJleGNlZWRpbmcgMHhGRkYu IChhZGRyOiAweCUwMngsIGxlbjogJWQpXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICBh ZGRyLCBsZW4pOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfSBlbHNl IGlmIChhZGRyID49IFBDSV9DT05GSUdfU1BBQ0VfU0laRSkgewogICAgICAgICBYRU5fUFRfRVJS KGQsICJGYWlsZWQgdG8gYWNjZXNzIHJlZ2lzdGVyIHdpdGggb2Zmc2V0IGV4Y2VlZGluZyAweEZG LiAiCiAgICAgICAgICAgICAgICAgICAgIihhZGRyOiAweCUwMngsIGxlbjogJWQpXG4iLCBhZGRy LCBsZW4pOwogICAgICAgICByZXR1cm4gLTE7CmRpZmYgLS1naXQgYS9ody94ZW4veGVuX3B0Lmgg Yi9ody94ZW4veGVuX3B0LmgKaW5kZXggMTIwNGFjYmRjZS4uNTUzMTM0N2FiMiAxMDA2NDQKLS0t IGEvaHcveGVuL3hlbl9wdC5oCisrKyBiL2h3L3hlbi94ZW5fcHQuaApAQCAtMzEsNiArMzEsMTEg QEAgdm9pZCB4ZW5fcHRfbG9nKGNvbnN0IFBDSURldmljZSAqZCwgY29uc3QgY2hhciAqZiwgLi4u KSBHQ0NfRk1UX0FUVFIoMiwgMyk7CiAvKiBIZWxwZXIgKi8KICNkZWZpbmUgWEVOX1BGTih4KSAo KHgpID4+IFhDX1BBR0VfU0hJRlQpCiAKKy8qIE1hY3JvJ3MgZm9yIFBDSWUgRXh0ZW5kZWQgQ2Fw YWJpbGl0aWVzICovCisjZGVmaW5lIFBDSUVfRVhUX0NBUF9JRChjYXBfaWQpICAgICAoKGNhcF9p ZCkgfCAoMVUgPDwgMTYpKQorI2RlZmluZSBJU19QQ0lFX0VYVF9DQVBfSUQoZ3JwX2lkKSAgKChn cnBfaWQpICYgKDFVIDw8IDE2KSkKKyNkZWZpbmUgR0VUX1BDSUVfRVhUX0NBUF9JRChncnBfaWQp ICgoZ3JwX2lkKSAmIDB4RkZGRikKKwogdHlwZWRlZiBjb25zdCBzdHJ1Y3QgWGVuUFRSZWdJbmZv IFhlblBUUmVnSW5mbzsKIHR5cGVkZWYgc3RydWN0IFhlblBUUmVnIFhlblBUUmVnOwogCkBAIC0x NTIsMTMgKzE1NywxMyBAQCB0eXBlZGVmIGNvbnN0IHN0cnVjdCBYZW5QVFJlZ0dyb3VwSW5mbyBY ZW5QVFJlZ0dyb3VwSW5mbzsKIC8qIGVtdWwgcmVnIGdyb3VwIHNpemUgaW5pdGlhbGl6ZSBtZXRo b2QgKi8KIHR5cGVkZWYgaW50ICgqeGVuX3B0X3JlZ19zaXplX2luaXRfZm4pCiAgICAgKFhlblBD SVBhc3N0aHJvdWdoU3RhdGUgKiwgWGVuUFRSZWdHcm91cEluZm8gKiwKLSAgICAgdWludDMyX3Qg YmFzZV9vZmZzZXQsIHVpbnQ4X3QgKnNpemUpOworICAgICB1aW50MzJfdCBiYXNlX29mZnNldCwg dWludDMyX3QgKnNpemUpOwogCiAvKiBlbXVsYXRlZCByZWdpc3RlciBncm91cCBpbmZvcm1hdGlv biAqLwogc3RydWN0IFhlblBUUmVnR3JvdXBJbmZvIHsKLSAgICB1aW50OF90IGdycF9pZDsKKyAg ICB1aW50MzJfdCBncnBfaWQ7CiAgICAgWGVuUFRSZWdpc3Rlckdyb3VwVHlwZSBncnBfdHlwZTsK LSAgICB1aW50OF90IGdycF9zaXplOworICAgIHVpbnQzMl90IGdycF9zaXplOwogICAgIHhlbl9w dF9yZWdfc2l6ZV9pbml0X2ZuIHNpemVfaW5pdDsKICAgICBYZW5QVFJlZ0luZm8gKmVtdV9yZWdz OwogfTsKQEAgLTE2OCw3ICsxNzMsNyBAQCB0eXBlZGVmIHN0cnVjdCBYZW5QVFJlZ0dyb3VwIHsK ICAgICBRTElTVF9FTlRSWShYZW5QVFJlZ0dyb3VwKSBlbnRyaWVzOwogICAgIFhlblBUUmVnR3Jv dXBJbmZvICpyZWdfZ3JwOwogICAgIHVpbnQzMl90IGJhc2Vfb2Zmc2V0OwotICAgIHVpbnQ4X3Qg c2l6ZTsKKyAgICB1aW50MzJfdCBzaXplOwogICAgIFFMSVNUX0hFQUQoLCBYZW5QVFJlZykgcmVn X3RibF9saXN0OwogfSBYZW5QVFJlZ0dyb3VwOwogCmRpZmYgLS1naXQgYS9ody94ZW4veGVuX3B0 X2NvbmZpZ19pbml0LmMgYi9ody94ZW4veGVuX3B0X2NvbmZpZ19pbml0LmMKaW5kZXggOTFkZTIx NTQwNy4uOWMwNDFmYTI4OCAxMDA2NDQKLS0tIGEvaHcveGVuL3hlbl9wdF9jb25maWdfaW5pdC5j CisrKyBiL2h3L3hlbi94ZW5fcHRfY29uZmlnX2luaXQuYwpAQCAtMzIsMjkgKzMyLDQyIEBAIHN0 YXRpYyBpbnQgeGVuX3B0X3B0cl9yZWdfaW5pdChYZW5QQ0lQYXNzdGhyb3VnaFN0YXRlICpzLCBY ZW5QVFJlZ0luZm8gKnJlZywKIC8qIGhlbHBlciAqLwogCiAvKiBBIHJldHVybiB2YWx1ZSBvZiAx IG1lYW5zIHRoZSBjYXBhYmlsaXR5IHNob3VsZCBOT1QgYmUgZXhwb3NlZCB0byBndWVzdC4gKi8K LXN0YXRpYyBpbnQgeGVuX3B0X2hpZGVfZGV2X2NhcChjb25zdCBYZW5Ib3N0UENJRGV2aWNlICpk LCB1aW50OF90IGdycF9pZCkKK3N0YXRpYyBpbnQgeGVuX3B0X2hpZGVfZGV2X2NhcChjb25zdCBY ZW5Ib3N0UENJRGV2aWNlICpkLCB1aW50MzJfdCBncnBfaWQpCiB7Ci0gICAgc3dpdGNoIChncnBf aWQpIHsKLSAgICBjYXNlIFBDSV9DQVBfSURfRVhQOgotICAgICAgICAvKiBUaGUgUENJIEV4cHJl c3MgQ2FwYWJpbGl0eSBTdHJ1Y3R1cmUgb2YgdGhlIFZGIG9mIEludGVsIDgyNTk5IDEwR2JFCi0g ICAgICAgICAqIENvbnRyb2xsZXIgbG9va3MgdHJpdmlhbCwgZS5nLiwgdGhlIFBDSSBFeHByZXNz IENhcGFiaWxpdGllcwotICAgICAgICAgKiBSZWdpc3RlciBpcyAwLiBXZSBzaG91bGQgbm90IHRy eSB0byBleHBvc2UgaXQgdG8gZ3Vlc3QuCi0gICAgICAgICAqCi0gICAgICAgICAqIFRoZSBkYXRh c2hlZXQgaXMgYXZhaWxhYmxlIGF0Ci0gICAgICAgICAqIGh0dHA6Ly9kb3dubG9hZC5pbnRlbC5j b20vZGVzaWduL25ldHdvcmsvZGF0YXNodHMvODI1OTlfZGF0YXNoZWV0LnBkZgotICAgICAgICAg KgotICAgICAgICAgKiBTZWUgJ1RhYmxlIDkuNy4gVkYgUENJZSBDb25maWd1cmF0aW9uIFNwYWNl JyBvZiB0aGUgZGF0YXNoZWV0LCB0aGUKLSAgICAgICAgICogUENJIEV4cHJlc3MgQ2FwYWJpbGl0 eSBTdHJ1Y3R1cmUgb2YgdGhlIFZGIG9mIEludGVsIDgyNTk5IDEwR2JFCi0gICAgICAgICAqIENv bnRyb2xsZXIgbG9va3MgdHJpdmlhbCwgZS5nLiwgdGhlIFBDSSBFeHByZXNzIENhcGFiaWxpdGll cwotICAgICAgICAgKiBSZWdpc3RlciBpcyAwLCBzbyB0aGUgQ2FwYWJpbGl0eSBWZXJzaW9uIGlz IDAgYW5kCi0gICAgICAgICAqIHhlbl9wdF9wY2llX3NpemVfaW5pdCgpIHdvdWxkIGZhaWwuCi0g ICAgICAgICAqLwotICAgICAgICBpZiAoZC0+dmVuZG9yX2lkID09IFBDSV9WRU5ET1JfSURfSU5U RUwgJiYKLSAgICAgICAgICAgIGQtPmRldmljZV9pZCA9PSBQQ0lfREVWSUNFX0lEX0lOVEVMXzgy NTk5X1NGUF9WRikgewotICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgaWYgKElTX1BDSUVfRVhU X0NBUF9JRChncnBfaWQpKSB7CisgICAgICAgIHN3aXRjaCAoR0VUX1BDSUVfRVhUX0NBUF9JRChn cnBfaWQpKSB7CisgICAgICAgICAgICAvKiBIZXJlIGNhbiBiZSBhZGRlZCBkZXZpY2Utc3BlY2lm aWMgZmlsdGVyaW5nCisgICAgICAgICAgICAgKiBmb3IgUENJZSBFeHRlbmRlZCBjYXBhYmlsaXRp ZXMgKHRob3NlIHdpdGggb2Zmc2V0ID49IDB4MTAwKS4KKyAgICAgICAgICAgICAqIFRoaXMgaXMg c2ltcGx5IGEgcGxhY2Vob2xkZXIgYXMgbm8gZmlsdGVyaW5nIG5lZWRlZCBmb3Igbm93LgorICAg ICAgICAgICAgICovCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBicmVhazsKKyAgICAg ICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8qIGJhc2ljIFBDSSBjYXBhYmlsaXR5ICovCisg ICAgICAgIHN3aXRjaCAoZ3JwX2lkKSB7CisgICAgICAgIGNhc2UgUENJX0NBUF9JRF9FWFA6Cisg ICAgICAgICAgICAvKiBUaGUgUENJIEV4cHJlc3MgQ2FwYWJpbGl0eSBTdHJ1Y3R1cmUgb2YgdGhl IFZGIG9mIEludGVsIDgyNTk5IDEwR2JFCisgICAgICAgICAgICAgKiBDb250cm9sbGVyIGxvb2tz IHRyaXZpYWwsIGUuZy4sIHRoZSBQQ0kgRXhwcmVzcyBDYXBhYmlsaXRpZXMKKyAgICAgICAgICAg ICAqIFJlZ2lzdGVyIGlzIDAuIFdlIHNob3VsZCBub3QgdHJ5IHRvIGV4cG9zZSBpdCB0byBndWVz dC4KKyAgICAgICAgICAgICAqCisgICAgICAgICAgICAgKiBUaGUgZGF0YXNoZWV0IGlzIGF2YWls YWJsZSBhdAorICAgICAgICAgICAgICogaHR0cDovL2Rvd25sb2FkLmludGVsLmNvbS9kZXNpZ24v bmV0d29yay9kYXRhc2h0cy84MjU5OV9kYXRhc2hlZXQucGRmCisgICAgICAgICAgICAgKgorICAg ICAgICAgICAgICogU2VlICdUYWJsZSA5LjcuIFZGIFBDSWUgQ29uZmlndXJhdGlvbiBTcGFjZScg b2YgdGhlIGRhdGFzaGVldCwgdGhlCisgICAgICAgICAgICAgKiBQQ0kgRXhwcmVzcyBDYXBhYmls aXR5IFN0cnVjdHVyZSBvZiB0aGUgVkYgb2YgSW50ZWwgODI1OTkgMTBHYkUKKyAgICAgICAgICAg ICAqIENvbnRyb2xsZXIgbG9va3MgdHJpdmlhbCwgZS5nLiwgdGhlIFBDSSBFeHByZXNzIENhcGFi aWxpdGllcworICAgICAgICAgICAgICogUmVnaXN0ZXIgaXMgMCwgc28gdGhlIENhcGFiaWxpdHkg VmVyc2lvbiBpcyAwIGFuZAorICAgICAgICAgICAgICogeGVuX3B0X3BjaWVfc2l6ZV9pbml0KCkg d291bGQgZmFpbC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKGQtPnZlbmRvcl9p ZCA9PSBQQ0lfVkVORE9SX0lEX0lOVEVMICYmCisgICAgICAgICAgICAgICAgZC0+ZGV2aWNlX2lk ID09IFBDSV9ERVZJQ0VfSURfSU5URUxfODI1OTlfU0ZQX1ZGKSB7CisgICAgICAgICAgICAgICAg cmV0dXJuIDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKICAgICAgICAgfQot ICAgICAgICBicmVhazsKICAgICB9CisKICAgICByZXR1cm4gMDsKIH0KIApAQCAtMTYyMiw3ICsx NjM1LDcgQEAgc3RhdGljIFhlblBUUmVnSW5mbyB4ZW5fcHRfZW11X3JlZ19pZ2Rfb3ByZWdpb25b XSA9IHsKIAogc3RhdGljIGludCB4ZW5fcHRfcmVnX2dycF9zaXplX2luaXQoWGVuUENJUGFzc3Ro cm91Z2hTdGF0ZSAqcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0 IFhlblBUUmVnR3JvdXBJbmZvICpncnBfcmVnLAotICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgdWludDMyX3QgYmFzZV9vZmZzZXQsIHVpbnQ4X3QgKnNpemUpCisgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBiYXNlX29mZnNldCwgdWludDMyX3Qg KnNpemUpCiB7CiAgICAgKnNpemUgPSBncnBfcmVnLT5ncnBfc2l6ZTsKICAgICByZXR1cm4gMDsK QEAgLTE2MzAsMTQgKzE2NDMsMTggQEAgc3RhdGljIGludCB4ZW5fcHRfcmVnX2dycF9zaXplX2lu aXQoWGVuUENJUGFzc3Rocm91Z2hTdGF0ZSAqcywKIC8qIGdldCBWZW5kb3IgU3BlY2lmaWMgQ2Fw YWJpbGl0eSBTdHJ1Y3R1cmUgcmVnaXN0ZXIgZ3JvdXAgc2l6ZSAqLwogc3RhdGljIGludCB4ZW5f cHRfdmVuZG9yX3NpemVfaW5pdChYZW5QQ0lQYXNzdGhyb3VnaFN0YXRlICpzLAogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBYZW5QVFJlZ0dyb3VwSW5mbyAqZ3JwX3Jl ZywKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgYmFzZV9vZmZz ZXQsIHVpbnQ4X3QgKnNpemUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVp bnQzMl90IGJhc2Vfb2Zmc2V0LCB1aW50MzJfdCAqc2l6ZSkKIHsKLSAgICByZXR1cm4geGVuX2hv c3RfcGNpX2dldF9ieXRlKCZzLT5yZWFsX2RldmljZSwgYmFzZV9vZmZzZXQgKyAweDAyLCBzaXpl KTsKKyAgICB1aW50OF90IHN6ID0gMDsKKyAgICBpbnQgcmV0ID0geGVuX2hvc3RfcGNpX2dldF9i eXRlKCZzLT5yZWFsX2RldmljZSwgYmFzZV9vZmZzZXQgKyAweDAyLCAmc3opOworCisgICAgKnNp emUgPSBzejsKKyAgICByZXR1cm4gcmV0OwogfQogLyogZ2V0IFBDSSBFeHByZXNzIENhcGFiaWxp dHkgU3RydWN0dXJlIHJlZ2lzdGVyIGdyb3VwIHNpemUgKi8KIHN0YXRpYyBpbnQgeGVuX3B0X3Bj aWVfc2l6ZV9pbml0KFhlblBDSVBhc3N0aHJvdWdoU3RhdGUgKnMsCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBjb25zdCBYZW5QVFJlZ0dyb3VwSW5mbyAqZ3JwX3JlZywKLSAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGJhc2Vfb2Zmc2V0LCB1aW50OF90 ICpzaXplKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgYmFzZV9v ZmZzZXQsIHVpbnQzMl90ICpzaXplKQogewogICAgIFBDSURldmljZSAqZCA9ICZzLT5kZXY7CiAg ICAgdWludDhfdCB2ZXJzaW9uID0gZ2V0X3BjaWVfY2FwYWJpbGl0eV92ZXJzaW9uKHMpOwpAQCAt MTcwOSw3ICsxNzI2LDcgQEAgc3RhdGljIGludCB4ZW5fcHRfcGNpZV9zaXplX2luaXQoWGVuUENJ UGFzc3Rocm91Z2hTdGF0ZSAqcywKIC8qIGdldCBNU0kgQ2FwYWJpbGl0eSBTdHJ1Y3R1cmUgcmVn aXN0ZXIgZ3JvdXAgc2l6ZSAqLwogc3RhdGljIGludCB4ZW5fcHRfbXNpX3NpemVfaW5pdChYZW5Q Q0lQYXNzdGhyb3VnaFN0YXRlICpzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBj b25zdCBYZW5QVFJlZ0dyb3VwSW5mbyAqZ3JwX3JlZywKLSAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgdWludDMyX3QgYmFzZV9vZmZzZXQsIHVpbnQ4X3QgKnNpemUpCisgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGJhc2Vfb2Zmc2V0LCB1aW50MzJfdCAqc2l6 ZSkKIHsKICAgICB1aW50MTZfdCBtc2dfY3RybCA9IDA7CiAgICAgdWludDhfdCBtc2lfc2l6ZSA9 IDB4YTsKQEAgLTE3MzcsNyArMTc1NCw3IEBAIHN0YXRpYyBpbnQgeGVuX3B0X21zaV9zaXplX2lu aXQoWGVuUENJUGFzc3Rocm91Z2hTdGF0ZSAqcywKIC8qIGdldCBNU0ktWCBDYXBhYmlsaXR5IFN0 cnVjdHVyZSByZWdpc3RlciBncm91cCBzaXplICovCiBzdGF0aWMgaW50IHhlbl9wdF9tc2l4X3Np emVfaW5pdChYZW5QQ0lQYXNzdGhyb3VnaFN0YXRlICpzLAogICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgY29uc3QgWGVuUFRSZWdHcm91cEluZm8gKmdycF9yZWcsCi0gICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBiYXNlX29mZnNldCwgdWludDhfdCAqc2l6 ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGJhc2Vfb2Zmc2V0 LCB1aW50MzJfdCAqc2l6ZSkKIHsKICAgICBpbnQgcmMgPSAwOwogCkBAIC0xOTIwLDQ0ICsxOTM3 LDIwIEBAIG91dDoKICAqIE1haW4KICAqLwogCi1zdGF0aWMgdWludDhfdCBmaW5kX2NhcF9vZmZz ZXQoWGVuUENJUGFzc3Rocm91Z2hTdGF0ZSAqcywgdWludDhfdCBjYXApCitzdGF0aWMgdWludDMy X3QgZmluZF9jYXBfb2Zmc2V0KFhlblBDSVBhc3N0aHJvdWdoU3RhdGUgKnMsIHVpbnQzMl90IGNh cCkKIHsKLSAgICB1aW50OF90IGlkOwotICAgIHVuc2lnbmVkIG1heF9jYXAgPSBYRU5fUENJX0NB UF9NQVg7Ci0gICAgdWludDhfdCBwb3MgPSBQQ0lfQ0FQQUJJTElUWV9MSVNUOwotICAgIHVpbnQ4 X3Qgc3RhdHVzID0gMDsKKyAgICB1aW50MzJfdCByZXR2YWwgPSAwOwogCi0gICAgaWYgKHhlbl9o b3N0X3BjaV9nZXRfYnl0ZSgmcy0+cmVhbF9kZXZpY2UsIFBDSV9TVEFUVVMsICZzdGF0dXMpKSB7 Ci0gICAgICAgIHJldHVybiAwOwotICAgIH0KLSAgICBpZiAoKHN0YXR1cyAmIFBDSV9TVEFUVVNf Q0FQX0xJU1QpID09IDApIHsKLSAgICAgICAgcmV0dXJuIDA7Ci0gICAgfQotCi0gICAgd2hpbGUg KG1heF9jYXAtLSkgewotICAgICAgICBpZiAoeGVuX2hvc3RfcGNpX2dldF9ieXRlKCZzLT5yZWFs X2RldmljZSwgcG9zLCAmcG9zKSkgewotICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgIH0KLSAg ICAgICAgaWYgKHBvcyA8IFBDSV9DT05GSUdfSEVBREVSX1NJWkUpIHsKLSAgICAgICAgICAgIGJy ZWFrOworICAgIGlmIChJU19QQ0lFX0VYVF9DQVBfSUQoY2FwKSkgeworICAgICAgICBpZiAocy0+ cGNpZV9lbmFibGVkX2RldikgeworICAgICAgICAgICAgcmV0dmFsID0geGVuX2hvc3RfcGNpX2Zp bmRfbmV4dF9leHRfY2FwKCZzLT5yZWFsX2RldmljZSwgMCwKKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRVRfUENJRV9FWFRfQ0FQX0lEKGNhcCkp OwogICAgICAgICB9Ci0KLSAgICAgICAgcG9zICY9IH4zOwotICAgICAgICBpZiAoeGVuX2hvc3Rf cGNpX2dldF9ieXRlKCZzLT5yZWFsX2RldmljZSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBwb3MgKyBQQ0lfQ0FQX0xJU1RfSUQsICZpZCkpIHsKLSAgICAgICAgICAgIGJyZWFr OwotICAgICAgICB9Ci0KLSAgICAgICAgaWYgKGlkID09IDB4ZmYpIHsKLSAgICAgICAgICAgIGJy ZWFrOwotICAgICAgICB9Ci0gICAgICAgIGlmIChpZCA9PSBjYXApIHsKLSAgICAgICAgICAgIHJl dHVybiBwb3M7Ci0gICAgICAgIH0KLQotICAgICAgICBwb3MgKz0gUENJX0NBUF9MSVNUX05FWFQ7 CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dmFsID0geGVuX2hvc3RfcGNpX2ZpbmRfbmV4dF9j YXAoJnMtPnJlYWxfZGV2aWNlLCAwLCBjYXApOwogICAgIH0KLSAgICByZXR1cm4gMDsKKworICAg IHJldHVybiByZXR2YWw7CiB9CiAKIHN0YXRpYyB2b2lkIHhlbl9wdF9jb25maWdfcmVnX2luaXQo WGVuUENJUGFzc3Rocm91Z2hTdGF0ZSAqcywKLS0gCjIuMTEuMAoKCl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QKWGVu LWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnCmh0dHBzOi8vbGlzdHMueGVucHJvamVjdC5vcmcv bWFpbG1hbi9saXN0aW5mby94ZW4tZGV2ZWw=