From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2B24C433F5 for ; Wed, 5 Jan 2022 15:03:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241275AbiAEPDP (ORCPT ); Wed, 5 Jan 2022 10:03:15 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:46606 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241228AbiAEPDD (ORCPT ); Wed, 5 Jan 2022 10:03:03 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3FE02617A8; Wed, 5 Jan 2022 15:03:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C2E4C36AE3; Wed, 5 Jan 2022 15:03:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1641394982; bh=sZYbAaXvHCjJ8xZRJhvZZlXtKdnDj8NhiQIhca59GpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jJaKATxAAkKi35RQrvv7nwsUBRA8ib3IqR63KStLuz0UVuvrFc2MN/c7JU2aSmlTL 3InnPH8iEeeHLsmZ/LMoAEvG3BeLkUe3ZXrmnb3PAsetvzy8jDj/zdE7Pj6AZH9fag TgIdnnIM54WUMmwi3U4KR0l+b1O2jAihaIy0nnHep/ohx+DEAgij2vHzE+Wk6crnqA MgiLj6MGXlr8wdZDNXyjdnyVBqCqZjv9NHk0oW3OaFrZzvi8pa8MfGv37GzEApCaKh vBDUbX73BnV+EOo2Qj06OjY35SOfee5tu2FndpBJeZ/N0kcbQTz1V3oDBaRohmGZfB V08ygs9JjZKWQ== Received: by pali.im (Postfix) id 129F882A; Wed, 5 Jan 2022 16:03:02 +0100 (CET) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Lorenzo Pieralisi , Bjorn Helgaas , Rob Herring , Thomas Petazzoni , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Russell King , Marc Zyngier Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx interrupts Date: Wed, 5 Jan 2022 16:02:38 +0100 Message-Id: <20220105150239.9628-11-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220105150239.9628-1-pali@kernel.org> References: <20220105150239.9628-1-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org This adds support for legacy INTx interrupts received from other PCIe devices and which are reported by a new INTx irq chip. With this change, kernel can distinguish between INTA, INTB, INTC and INTD interrupts. Note that for this support, device tree files has to be properly adjusted to provide "interrupts" or "interrupts-extended" property with intx interrupt source, "interrupt-names" property with "intx" string and also 'interrupt-controller' subnode must be defined. If device tree files do not provide these nodes then driver would work as before. Signed-off-by: Pali Rohár --- drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 8 deletions(-) diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index 1e90ab888075..04bcdd7b7a6d 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c @@ -54,9 +54,10 @@ PCIE_CONF_ADDR_EN) #define PCIE_CONF_DATA_OFF 0x18fc #define PCIE_INT_CAUSE_OFF 0x1900 +#define PCIE_INT_UNMASK_OFF 0x1910 +#define PCIE_INT_INTX(i) BIT(24+i) #define PCIE_INT_PM_PME BIT(28) -#define PCIE_MASK_OFF 0x1910 -#define PCIE_MASK_ENABLE_INTS 0x0f000000 +#define PCIE_INT_ALL_MASK GENMASK(31, 0) #define PCIE_CTRL_OFF 0x1a00 #define PCIE_CTRL_X1_MODE 0x0001 #define PCIE_CTRL_RC_MODE BIT(1) @@ -110,6 +111,10 @@ struct mvebu_pcie_port { struct mvebu_pcie_window iowin; u32 saved_pcie_stat; struct resource regs; + struct irq_domain *intx_irq_domain; + struct irq_chip intx_irq_chip; + raw_spinlock_t irq_lock; + int intx_irq; }; static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) { - u32 ctrl, lnkcap, cmd, dev_rev, mask; + u32 ctrl, lnkcap, cmd, dev_rev, unmask; /* Setup PCIe controller to Root Complex mode. */ ctrl = mvebu_readl(port, PCIE_CTRL_OFF); @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) /* Point PCIe unit MBUS decode windows to DRAM space. */ mvebu_pcie_setup_wins(port); - /* Enable interrupt lines A-D. */ - mask = mvebu_readl(port, PCIE_MASK_OFF); - mask |= PCIE_MASK_ENABLE_INTS; - mvebu_writel(port, mask, PCIE_MASK_OFF); + /* Mask all interrupt sources. */ + mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF); + + /* Clear all interrupt causes. */ + mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF); + + if (port->intx_irq <= 0) { + /* + * When neither "summary" interrupt, nor "intx" interrupt was + * specified in DT then unmask all legacy INTx interrupts as in + * this case driver does not provide a way for masking and + * unmasking of individual legacy INTx interrupts. In this case + * all interrupts, including legacy INTx are reported via one + * shared GIC source and therefore kernel cannot distinguish + * which individual legacy INTx was triggered. These interrupts + * are shared, so it should not cause any issue. Just + * performance penalty as every PCIe interrupt handler needs to + * be called when some interrupt is triggered. + */ + unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF); + unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) | + PCIE_INT_INTX(2) | PCIE_INT_INTX(3); + mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF); + } } static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie, @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = { .write = mvebu_pcie_wr_conf, }; +static void mvebu_pcie_intx_irq_mask(struct irq_data *d) +{ + struct mvebu_pcie_port *port = d->domain->host_data; + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; + u32 unmask; + + raw_spin_lock_irqsave(&port->irq_lock, flags); + unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF); + unmask &= ~PCIE_INT_INTX(hwirq); + mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF); + raw_spin_unlock_irqrestore(&port->irq_lock, flags); +} + +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d) +{ + struct mvebu_pcie_port *port = d->domain->host_data; + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; + u32 unmask; + + raw_spin_lock_irqsave(&port->irq_lock, flags); + unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF); + unmask |= PCIE_INT_INTX(hwirq); + mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF); + raw_spin_unlock_irqrestore(&port->irq_lock, flags); +} + +static int mvebu_pcie_intx_irq_map(struct irq_domain *h, + unsigned int virq, irq_hw_number_t hwirq) +{ + struct mvebu_pcie_port *port = h->host_data; + + irq_set_status_flags(virq, IRQ_LEVEL); + irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq); + irq_set_chip_data(virq, port); + + return 0; +} + +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = { + .map = mvebu_pcie_intx_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port) +{ + struct device *dev = &port->pcie->pdev->dev; + struct device_node *pcie_intc_node; + + raw_spin_lock_init(&port->irq_lock); + + port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, + "mvebu-%s-INTx", + port->name); + port->intx_irq_chip.irq_mask = mvebu_pcie_intx_irq_mask; + port->intx_irq_chip.irq_unmask = mvebu_pcie_intx_irq_unmask; + + pcie_intc_node = of_get_next_child(port->dn, NULL); + if (!pcie_intc_node) { + dev_err(dev, "No PCIe Intc node found for %s\n", port->name); + return -ENODEV; + } + + port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, + &mvebu_pcie_intx_irq_domain_ops, + port); + of_node_put(pcie_intc_node); + if (!port->intx_irq_domain) { + devm_kfree(dev, port->intx_irq_chip.name); + dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name); + return -ENOMEM; + } + + return 0; +} + +static void mvebu_pcie_irq_handler(struct irq_desc *desc) +{ + struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + struct device *dev = &port->pcie->pdev->dev; + u32 cause, unmask, status; + int i; + + chained_irq_enter(chip, desc); + + cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF); + unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF); + status = cause & unmask; + + /* Process legacy INTx interrupts */ + for (i = 0; i < PCI_NUM_INTX; i++) { + if (!(status & PCIE_INT_INTX(i))) + continue; + + if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL) + dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A'); + } + + chained_irq_exit(chip, desc); +} + static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* Interrupt support on mvebu emulated bridges is not implemented yet */ @@ -1121,6 +1249,16 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie, port->io_attr = -1; } + /* + * Old DT bindings do not contain "intx" interrupt + * so do not fail probing driver when interrupt does not exist. + */ + port->intx_irq = of_irq_get_byname(child, "intx"); + if (port->intx_irq == -EPROBE_DEFER) { + ret = port->intx_irq; + goto err; + } + reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags); if (reset_gpio == -EPROBE_DEFER) { ret = reset_gpio; @@ -1317,6 +1455,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev) for (i = 0; i < pcie->nports; i++) { struct mvebu_pcie_port *port = &pcie->ports[i]; + int irq = port->intx_irq; child = port->dn; if (!child) @@ -1344,6 +1483,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev) continue; } + if (irq > 0) { + ret = mvebu_pcie_init_irq_domain(port); + if (ret) { + dev_err(dev, "%s: cannot init irq domain\n", + port->name); + pci_bridge_emul_cleanup(&port->bridge); + devm_iounmap(dev, port->base); + port->base = NULL; + mvebu_pcie_powerdown(port); + continue; + } + irq_set_chained_handler_and_data(irq, + mvebu_pcie_irq_handler, + port); + } + /* * PCIe topology exported by mvebu hw is quite complicated. In * reality has something like N fully independent host bridges @@ -1448,6 +1603,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev) for (i = 0; i < pcie->nports; i++) { struct mvebu_pcie_port *port = &pcie->ports[i]; + int irq = port->intx_irq; if (!port->base) continue; @@ -1458,7 +1614,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev) mvebu_writel(port, cmd, PCIE_CMD_OFF); /* Mask all interrupt sources. */ - mvebu_writel(port, 0, PCIE_MASK_OFF); + mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF); + + /* Clear all interrupt causes. */ + mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF); + + /* Remove IRQ domains. */ + if (port->intx_irq_domain) + irq_domain_remove(port->intx_irq_domain); + + if (irq > 0) + irq_set_chained_handler_and_data(irq, NULL, NULL); /* Free config space for emulated root bridge. */ pci_bridge_emul_cleanup(&port->bridge); -- 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E8D4FC433EF for ; Wed, 5 Jan 2022 15:08:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=MQqik7lUxGJKr8EysadAx7lIXdpTIGvRLRhWYATIxkc=; b=wc5VQg4xNGsoDd xmHbf+ZG0S+Iy5CfCVWeKLFbUZNIziKDVOAQuYiiQ1KzKAi5kwGSGhLDmGNxmnPKwWAQAH/RR4xsm hs+spCMgKPqMlLr4ORbWl+869JpvetBVgbe/9HdfIIJ2EqW5Ycvq4vZ+jx5cXencnc/sicxjQaR09 a/2PBKOnKBEuFEdUYJbF2kPlDZTtvvOO+DQFs14ufC9s6wQQBtfV3+NDu7PboxEX+RQtn273x+9YN eMMrfALPEWUVIwxbBX4wSpDPvYbXKTdxhVvddj5vgbouEm8k3506wz7jB1s5uJ2S3/9ldYAonqRTj 85wbsNVGnpykiL2r5p3w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1n57s4-00F64X-MC; Wed, 05 Jan 2022 15:06:37 +0000 Received: from ams.source.kernel.org ([145.40.68.75]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1n57oe-00F4Fk-Hg for linux-arm-kernel@lists.infradead.org; Wed, 05 Jan 2022 15:03:07 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 4647BB81BAA; Wed, 5 Jan 2022 15:03:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C2E4C36AE3; Wed, 5 Jan 2022 15:03:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1641394982; bh=sZYbAaXvHCjJ8xZRJhvZZlXtKdnDj8NhiQIhca59GpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jJaKATxAAkKi35RQrvv7nwsUBRA8ib3IqR63KStLuz0UVuvrFc2MN/c7JU2aSmlTL 3InnPH8iEeeHLsmZ/LMoAEvG3BeLkUe3ZXrmnb3PAsetvzy8jDj/zdE7Pj6AZH9fag TgIdnnIM54WUMmwi3U4KR0l+b1O2jAihaIy0nnHep/ohx+DEAgij2vHzE+Wk6crnqA MgiLj6MGXlr8wdZDNXyjdnyVBqCqZjv9NHk0oW3OaFrZzvi8pa8MfGv37GzEApCaKh vBDUbX73BnV+EOo2Qj06OjY35SOfee5tu2FndpBJeZ/N0kcbQTz1V3oDBaRohmGZfB V08ygs9JjZKWQ== Received: by pali.im (Postfix) id 129F882A; Wed, 5 Jan 2022 16:03:02 +0100 (CET) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Lorenzo Pieralisi , Bjorn Helgaas , Rob Herring , Thomas Petazzoni , =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Russell King , Marc Zyngier Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx interrupts Date: Wed, 5 Jan 2022 16:02:38 +0100 Message-Id: <20220105150239.9628-11-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220105150239.9628-1-pali@kernel.org> References: <20220105150239.9628-1-pali@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220105_070304_909713_47449071 X-CRM114-Status: GOOD ( 28.61 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org VGhpcyBhZGRzIHN1cHBvcnQgZm9yIGxlZ2FjeSBJTlR4IGludGVycnVwdHMgcmVjZWl2ZWQgZnJv bSBvdGhlciBQQ0llCmRldmljZXMgYW5kIHdoaWNoIGFyZSByZXBvcnRlZCBieSBhIG5ldyBJTlR4 IGlycSBjaGlwLgoKV2l0aCB0aGlzIGNoYW5nZSwga2VybmVsIGNhbiBkaXN0aW5ndWlzaCBiZXR3 ZWVuIElOVEEsIElOVEIsIElOVEMgYW5kIElOVEQKaW50ZXJydXB0cy4KCk5vdGUgdGhhdCBmb3Ig dGhpcyBzdXBwb3J0LCBkZXZpY2UgdHJlZSBmaWxlcyBoYXMgdG8gYmUgcHJvcGVybHkgYWRqdXN0 ZWQKdG8gcHJvdmlkZSAiaW50ZXJydXB0cyIgb3IgImludGVycnVwdHMtZXh0ZW5kZWQiIHByb3Bl cnR5IHdpdGggaW50eAppbnRlcnJ1cHQgc291cmNlLCAiaW50ZXJydXB0LW5hbWVzIiBwcm9wZXJ0 eSB3aXRoICJpbnR4IiBzdHJpbmcgYW5kIGFsc28KJ2ludGVycnVwdC1jb250cm9sbGVyJyBzdWJu b2RlIG11c3QgYmUgZGVmaW5lZC4KCklmIGRldmljZSB0cmVlIGZpbGVzIGRvIG5vdCBwcm92aWRl IHRoZXNlIG5vZGVzIHRoZW4gZHJpdmVyIHdvdWxkIHdvcmsgYXMKYmVmb3JlLgoKU2lnbmVkLW9m Zi1ieTogUGFsaSBSb2jDoXIgPHBhbGlAa2VybmVsLm9yZz4KLS0tCiBkcml2ZXJzL3BjaS9jb250 cm9sbGVyL3BjaS1tdmVidS5jIHwgMTgyICsrKysrKysrKysrKysrKysrKysrKysrKysrKy0tCiAx IGZpbGUgY2hhbmdlZCwgMTc0IGluc2VydGlvbnMoKyksIDggZGVsZXRpb25zKC0pCgpkaWZmIC0t Z2l0IGEvZHJpdmVycy9wY2kvY29udHJvbGxlci9wY2ktbXZlYnUuYyBiL2RyaXZlcnMvcGNpL2Nv bnRyb2xsZXIvcGNpLW12ZWJ1LmMKaW5kZXggMWU5MGFiODg4MDc1Li4wNGJjZGQ3YjdhNmQgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvcGNpL2NvbnRyb2xsZXIvcGNpLW12ZWJ1LmMKKysrIGIvZHJpdmVy cy9wY2kvY29udHJvbGxlci9wY2ktbXZlYnUuYwpAQCAtNTQsOSArNTQsMTAgQEAKIAkgUENJRV9D T05GX0FERFJfRU4pCiAjZGVmaW5lIFBDSUVfQ09ORl9EQVRBX09GRgkweDE4ZmMKICNkZWZpbmUg UENJRV9JTlRfQ0FVU0VfT0ZGCTB4MTkwMAorI2RlZmluZSBQQ0lFX0lOVF9VTk1BU0tfT0ZGCTB4 MTkxMAorI2RlZmluZSAgUENJRV9JTlRfSU5UWChpKQkJQklUKDI0K2kpCiAjZGVmaW5lICBQQ0lF X0lOVF9QTV9QTUUJCUJJVCgyOCkKLSNkZWZpbmUgUENJRV9NQVNLX09GRgkJMHgxOTEwCi0jZGVm aW5lICBQQ0lFX01BU0tfRU5BQkxFX0lOVFMgICAgICAgICAgMHgwZjAwMDAwMAorI2RlZmluZSAg UENJRV9JTlRfQUxMX01BU0sJCUdFTk1BU0soMzEsIDApCiAjZGVmaW5lIFBDSUVfQ1RSTF9PRkYJ CTB4MWEwMAogI2RlZmluZSAgUENJRV9DVFJMX1gxX01PREUJCTB4MDAwMQogI2RlZmluZSAgUENJ RV9DVFJMX1JDX01PREUJCUJJVCgxKQpAQCAtMTEwLDYgKzExMSwxMCBAQCBzdHJ1Y3QgbXZlYnVf cGNpZV9wb3J0IHsKIAlzdHJ1Y3QgbXZlYnVfcGNpZV93aW5kb3cgaW93aW47CiAJdTMyIHNhdmVk X3BjaWVfc3RhdDsKIAlzdHJ1Y3QgcmVzb3VyY2UgcmVnczsKKwlzdHJ1Y3QgaXJxX2RvbWFpbiAq aW50eF9pcnFfZG9tYWluOworCXN0cnVjdCBpcnFfY2hpcCBpbnR4X2lycV9jaGlwOworCXJhd19z cGlubG9ja190IGlycV9sb2NrOworCWludCBpbnR4X2lycTsKIH07CiAKIHN0YXRpYyBpbmxpbmUg dm9pZCBtdmVidV93cml0ZWwoc3RydWN0IG12ZWJ1X3BjaWVfcG9ydCAqcG9ydCwgdTMyIHZhbCwg dTMyIHJlZykKQEAgLTIzNSw3ICsyNDAsNyBAQCBzdGF0aWMgdm9pZCBtdmVidV9wY2llX3NldHVw X3dpbnMoc3RydWN0IG12ZWJ1X3BjaWVfcG9ydCAqcG9ydCkKIAogc3RhdGljIHZvaWQgbXZlYnVf cGNpZV9zZXR1cF9odyhzdHJ1Y3QgbXZlYnVfcGNpZV9wb3J0ICpwb3J0KQogewotCXUzMiBjdHJs LCBsbmtjYXAsIGNtZCwgZGV2X3JldiwgbWFzazsKKwl1MzIgY3RybCwgbG5rY2FwLCBjbWQsIGRl dl9yZXYsIHVubWFzazsKIAogCS8qIFNldHVwIFBDSWUgY29udHJvbGxlciB0byBSb290IENvbXBs ZXggbW9kZS4gKi8KIAljdHJsID0gbXZlYnVfcmVhZGwocG9ydCwgUENJRV9DVFJMX09GRik7CkBA IC0yODgsMTAgKzI5MywzMCBAQCBzdGF0aWMgdm9pZCBtdmVidV9wY2llX3NldHVwX2h3KHN0cnVj dCBtdmVidV9wY2llX3BvcnQgKnBvcnQpCiAJLyogUG9pbnQgUENJZSB1bml0IE1CVVMgZGVjb2Rl IHdpbmRvd3MgdG8gRFJBTSBzcGFjZS4gKi8KIAltdmVidV9wY2llX3NldHVwX3dpbnMocG9ydCk7 CiAKLQkvKiBFbmFibGUgaW50ZXJydXB0IGxpbmVzIEEtRC4gKi8KLQltYXNrID0gbXZlYnVfcmVh ZGwocG9ydCwgUENJRV9NQVNLX09GRik7Ci0JbWFzayB8PSBQQ0lFX01BU0tfRU5BQkxFX0lOVFM7 Ci0JbXZlYnVfd3JpdGVsKHBvcnQsIG1hc2ssIFBDSUVfTUFTS19PRkYpOworCS8qIE1hc2sgYWxs IGludGVycnVwdCBzb3VyY2VzLiAqLworCW12ZWJ1X3dyaXRlbChwb3J0LCB+UENJRV9JTlRfQUxM X01BU0ssIFBDSUVfSU5UX1VOTUFTS19PRkYpOworCisJLyogQ2xlYXIgYWxsIGludGVycnVwdCBj YXVzZXMuICovCisJbXZlYnVfd3JpdGVsKHBvcnQsIH5QQ0lFX0lOVF9BTExfTUFTSywgUENJRV9J TlRfQ0FVU0VfT0ZGKTsKKworCWlmIChwb3J0LT5pbnR4X2lycSA8PSAwKSB7CisJCS8qCisJCSAq IFdoZW4gbmVpdGhlciAic3VtbWFyeSIgaW50ZXJydXB0LCBub3IgImludHgiIGludGVycnVwdCB3 YXMKKwkJICogc3BlY2lmaWVkIGluIERUIHRoZW4gdW5tYXNrIGFsbCBsZWdhY3kgSU5UeCBpbnRl cnJ1cHRzIGFzIGluCisJCSAqIHRoaXMgY2FzZSBkcml2ZXIgZG9lcyBub3QgcHJvdmlkZSBhIHdh eSBmb3IgbWFza2luZyBhbmQKKwkJICogdW5tYXNraW5nIG9mIGluZGl2aWR1YWwgbGVnYWN5IElO VHggaW50ZXJydXB0cy4gSW4gdGhpcyBjYXNlCisJCSAqIGFsbCBpbnRlcnJ1cHRzLCBpbmNsdWRp bmcgbGVnYWN5IElOVHggYXJlIHJlcG9ydGVkIHZpYSBvbmUKKwkJICogc2hhcmVkIEdJQyBzb3Vy Y2UgYW5kIHRoZXJlZm9yZSBrZXJuZWwgY2Fubm90IGRpc3Rpbmd1aXNoCisJCSAqIHdoaWNoIGlu ZGl2aWR1YWwgbGVnYWN5IElOVHggd2FzIHRyaWdnZXJlZC4gVGhlc2UgaW50ZXJydXB0cworCQkg KiBhcmUgc2hhcmVkLCBzbyBpdCBzaG91bGQgbm90IGNhdXNlIGFueSBpc3N1ZS4gSnVzdAorCQkg KiBwZXJmb3JtYW5jZSBwZW5hbHR5IGFzIGV2ZXJ5IFBDSWUgaW50ZXJydXB0IGhhbmRsZXIgbmVl ZHMgdG8KKwkJICogYmUgY2FsbGVkIHdoZW4gc29tZSBpbnRlcnJ1cHQgaXMgdHJpZ2dlcmVkLgor CQkgKi8KKwkJdW5tYXNrID0gbXZlYnVfcmVhZGwocG9ydCwgUENJRV9JTlRfVU5NQVNLX09GRik7 CisJCXVubWFzayB8PSBQQ0lFX0lOVF9JTlRYKDApIHwgUENJRV9JTlRfSU5UWCgxKSB8CisJCQkg IFBDSUVfSU5UX0lOVFgoMikgfCBQQ0lFX0lOVF9JTlRYKDMpOworCQltdmVidV93cml0ZWwocG9y dCwgdW5tYXNrLCBQQ0lFX0lOVF9VTk1BU0tfT0ZGKTsKKwl9CiB9CiAKIHN0YXRpYyBzdHJ1Y3Qg bXZlYnVfcGNpZV9wb3J0ICptdmVidV9wY2llX2ZpbmRfcG9ydChzdHJ1Y3QgbXZlYnVfcGNpZSAq cGNpZSwKQEAgLTkyNCw2ICs5NDksMTA5IEBAIHN0YXRpYyBzdHJ1Y3QgcGNpX29wcyBtdmVidV9w Y2llX29wcyA9IHsKIAkud3JpdGUgPSBtdmVidV9wY2llX3dyX2NvbmYsCiB9OwogCitzdGF0aWMg dm9pZCBtdmVidV9wY2llX2ludHhfaXJxX21hc2soc3RydWN0IGlycV9kYXRhICpkKQoreworCXN0 cnVjdCBtdmVidV9wY2llX3BvcnQgKnBvcnQgPSBkLT5kb21haW4tPmhvc3RfZGF0YTsKKwlpcnFf aHdfbnVtYmVyX3QgaHdpcnEgPSBpcnFkX3RvX2h3aXJxKGQpOworCXVuc2lnbmVkIGxvbmcgZmxh Z3M7CisJdTMyIHVubWFzazsKKworCXJhd19zcGluX2xvY2tfaXJxc2F2ZSgmcG9ydC0+aXJxX2xv Y2ssIGZsYWdzKTsKKwl1bm1hc2sgPSBtdmVidV9yZWFkbChwb3J0LCBQQ0lFX0lOVF9VTk1BU0tf T0ZGKTsKKwl1bm1hc2sgJj0gflBDSUVfSU5UX0lOVFgoaHdpcnEpOworCW12ZWJ1X3dyaXRlbChw b3J0LCB1bm1hc2ssIFBDSUVfSU5UX1VOTUFTS19PRkYpOworCXJhd19zcGluX3VubG9ja19pcnFy ZXN0b3JlKCZwb3J0LT5pcnFfbG9jaywgZmxhZ3MpOworfQorCitzdGF0aWMgdm9pZCBtdmVidV9w Y2llX2ludHhfaXJxX3VubWFzayhzdHJ1Y3QgaXJxX2RhdGEgKmQpCit7CisJc3RydWN0IG12ZWJ1 X3BjaWVfcG9ydCAqcG9ydCA9IGQtPmRvbWFpbi0+aG9zdF9kYXRhOworCWlycV9od19udW1iZXJf dCBod2lycSA9IGlycWRfdG9faHdpcnEoZCk7CisJdW5zaWduZWQgbG9uZyBmbGFnczsKKwl1MzIg dW5tYXNrOworCisJcmF3X3NwaW5fbG9ja19pcnFzYXZlKCZwb3J0LT5pcnFfbG9jaywgZmxhZ3Mp OworCXVubWFzayA9IG12ZWJ1X3JlYWRsKHBvcnQsIFBDSUVfSU5UX1VOTUFTS19PRkYpOworCXVu bWFzayB8PSBQQ0lFX0lOVF9JTlRYKGh3aXJxKTsKKwltdmVidV93cml0ZWwocG9ydCwgdW5tYXNr LCBQQ0lFX0lOVF9VTk1BU0tfT0ZGKTsKKwlyYXdfc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcG9y dC0+aXJxX2xvY2ssIGZsYWdzKTsKK30KKworc3RhdGljIGludCBtdmVidV9wY2llX2ludHhfaXJx X21hcChzdHJ1Y3QgaXJxX2RvbWFpbiAqaCwKKwkJCQkgICB1bnNpZ25lZCBpbnQgdmlycSwgaXJx X2h3X251bWJlcl90IGh3aXJxKQoreworCXN0cnVjdCBtdmVidV9wY2llX3BvcnQgKnBvcnQgPSBo LT5ob3N0X2RhdGE7CisKKwlpcnFfc2V0X3N0YXR1c19mbGFncyh2aXJxLCBJUlFfTEVWRUwpOwor CWlycV9zZXRfY2hpcF9hbmRfaGFuZGxlcih2aXJxLCAmcG9ydC0+aW50eF9pcnFfY2hpcCwgaGFu ZGxlX2xldmVsX2lycSk7CisJaXJxX3NldF9jaGlwX2RhdGEodmlycSwgcG9ydCk7CisKKwlyZXR1 cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBpcnFfZG9tYWluX29wcyBtdmVidV9wY2ll X2ludHhfaXJxX2RvbWFpbl9vcHMgPSB7CisJLm1hcCA9IG12ZWJ1X3BjaWVfaW50eF9pcnFfbWFw LAorCS54bGF0ZSA9IGlycV9kb21haW5feGxhdGVfb25lY2VsbCwKK307CisKK3N0YXRpYyBpbnQg bXZlYnVfcGNpZV9pbml0X2lycV9kb21haW4oc3RydWN0IG12ZWJ1X3BjaWVfcG9ydCAqcG9ydCkK K3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcG9ydC0+cGNpZS0+cGRldi0+ZGV2OworCXN0cnVj dCBkZXZpY2Vfbm9kZSAqcGNpZV9pbnRjX25vZGU7CisKKwlyYXdfc3Bpbl9sb2NrX2luaXQoJnBv cnQtPmlycV9sb2NrKTsKKworCXBvcnQtPmludHhfaXJxX2NoaXAubmFtZSA9IGRldm1fa2FzcHJp bnRmKGRldiwgR0ZQX0tFUk5FTCwKKwkJCQkJCSAgIm12ZWJ1LSVzLUlOVHgiLAorCQkJCQkJICBw b3J0LT5uYW1lKTsKKwlwb3J0LT5pbnR4X2lycV9jaGlwLmlycV9tYXNrID0gbXZlYnVfcGNpZV9p bnR4X2lycV9tYXNrOworCXBvcnQtPmludHhfaXJxX2NoaXAuaXJxX3VubWFzayA9IG12ZWJ1X3Bj aWVfaW50eF9pcnFfdW5tYXNrOworCisJcGNpZV9pbnRjX25vZGUgPSBvZl9nZXRfbmV4dF9jaGls ZChwb3J0LT5kbiwgTlVMTCk7CisJaWYgKCFwY2llX2ludGNfbm9kZSkgeworCQlkZXZfZXJyKGRl diwgIk5vIFBDSWUgSW50YyBub2RlIGZvdW5kIGZvciAlc1xuIiwgcG9ydC0+bmFtZSk7CisJCXJl dHVybiAtRU5PREVWOworCX0KKworCXBvcnQtPmludHhfaXJxX2RvbWFpbiA9IGlycV9kb21haW5f YWRkX2xpbmVhcihwY2llX2ludGNfbm9kZSwgUENJX05VTV9JTlRYLAorCQkJCQkJICAgICAgJm12 ZWJ1X3BjaWVfaW50eF9pcnFfZG9tYWluX29wcywKKwkJCQkJCSAgICAgIHBvcnQpOworCW9mX25v ZGVfcHV0KHBjaWVfaW50Y19ub2RlKTsKKwlpZiAoIXBvcnQtPmludHhfaXJxX2RvbWFpbikgewor CQlkZXZtX2tmcmVlKGRldiwgcG9ydC0+aW50eF9pcnFfY2hpcC5uYW1lKTsKKwkJZGV2X2Vycihk ZXYsICJGYWlsZWQgdG8gZ2V0IElOVHggSVJRIGRvbWFpbiBmb3IgJXNcbiIsIHBvcnQtPm5hbWUp OworCQlyZXR1cm4gLUVOT01FTTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQg bXZlYnVfcGNpZV9pcnFfaGFuZGxlcihzdHJ1Y3QgaXJxX2Rlc2MgKmRlc2MpCit7CisJc3RydWN0 IG12ZWJ1X3BjaWVfcG9ydCAqcG9ydCA9IGlycV9kZXNjX2dldF9oYW5kbGVyX2RhdGEoZGVzYyk7 CisJc3RydWN0IGlycV9jaGlwICpjaGlwID0gaXJxX2Rlc2NfZ2V0X2NoaXAoZGVzYyk7CisJc3Ry dWN0IGRldmljZSAqZGV2ID0gJnBvcnQtPnBjaWUtPnBkZXYtPmRldjsKKwl1MzIgY2F1c2UsIHVu bWFzaywgc3RhdHVzOworCWludCBpOworCisJY2hhaW5lZF9pcnFfZW50ZXIoY2hpcCwgZGVzYyk7 CisKKwljYXVzZSA9IG12ZWJ1X3JlYWRsKHBvcnQsIFBDSUVfSU5UX0NBVVNFX09GRik7CisJdW5t YXNrID0gbXZlYnVfcmVhZGwocG9ydCwgUENJRV9JTlRfVU5NQVNLX09GRik7CisJc3RhdHVzID0g Y2F1c2UgJiB1bm1hc2s7CisKKwkvKiBQcm9jZXNzIGxlZ2FjeSBJTlR4IGludGVycnVwdHMgKi8K Kwlmb3IgKGkgPSAwOyBpIDwgUENJX05VTV9JTlRYOyBpKyspIHsKKwkJaWYgKCEoc3RhdHVzICYg UENJRV9JTlRfSU5UWChpKSkpCisJCQljb250aW51ZTsKKworCQlpZiAoZ2VuZXJpY19oYW5kbGVf ZG9tYWluX2lycShwb3J0LT5pbnR4X2lycV9kb21haW4sIGkpID09IC1FSU5WQUwpCisJCQlkZXZf ZXJyX3JhdGVsaW1pdGVkKGRldiwgInVuZXhwZWN0ZWQgSU5UJWMgSVJRXG4iLCAoY2hhcilpKydB Jyk7CisJfQorCisJY2hhaW5lZF9pcnFfZXhpdChjaGlwLCBkZXNjKTsKK30KKwogc3RhdGljIGlu dCBtdmVidV9wY2llX21hcF9pcnEoY29uc3Qgc3RydWN0IHBjaV9kZXYgKmRldiwgdTggc2xvdCwg dTggcGluKQogewogCS8qIEludGVycnVwdCBzdXBwb3J0IG9uIG12ZWJ1IGVtdWxhdGVkIGJyaWRn ZXMgaXMgbm90IGltcGxlbWVudGVkIHlldCAqLwpAQCAtMTEyMSw2ICsxMjQ5LDE2IEBAIHN0YXRp YyBpbnQgbXZlYnVfcGNpZV9wYXJzZV9wb3J0KHN0cnVjdCBtdmVidV9wY2llICpwY2llLAogCQlw b3J0LT5pb19hdHRyID0gLTE7CiAJfQogCisJLyoKKwkgKiBPbGQgRFQgYmluZGluZ3MgZG8gbm90 IGNvbnRhaW4gImludHgiIGludGVycnVwdAorCSAqIHNvIGRvIG5vdCBmYWlsIHByb2JpbmcgZHJp dmVyIHdoZW4gaW50ZXJydXB0IGRvZXMgbm90IGV4aXN0LgorCSAqLworCXBvcnQtPmludHhfaXJx ID0gb2ZfaXJxX2dldF9ieW5hbWUoY2hpbGQsICJpbnR4Iik7CisJaWYgKHBvcnQtPmludHhfaXJx ID09IC1FUFJPQkVfREVGRVIpIHsKKwkJcmV0ID0gcG9ydC0+aW50eF9pcnE7CisJCWdvdG8gZXJy OworCX0KKwogCXJlc2V0X2dwaW8gPSBvZl9nZXRfbmFtZWRfZ3Bpb19mbGFncyhjaGlsZCwgInJl c2V0LWdwaW9zIiwgMCwgJmZsYWdzKTsKIAlpZiAocmVzZXRfZ3BpbyA9PSAtRVBST0JFX0RFRkVS KSB7CiAJCXJldCA9IHJlc2V0X2dwaW87CkBAIC0xMzE3LDYgKzE0NTUsNyBAQCBzdGF0aWMgaW50 IG12ZWJ1X3BjaWVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIAogCWZvciAo aSA9IDA7IGkgPCBwY2llLT5ucG9ydHM7IGkrKykgewogCQlzdHJ1Y3QgbXZlYnVfcGNpZV9wb3J0 ICpwb3J0ID0gJnBjaWUtPnBvcnRzW2ldOworCQlpbnQgaXJxID0gcG9ydC0+aW50eF9pcnE7CiAK IAkJY2hpbGQgPSBwb3J0LT5kbjsKIAkJaWYgKCFjaGlsZCkKQEAgLTEzNDQsNiArMTQ4MywyMiBA QCBzdGF0aWMgaW50IG12ZWJ1X3BjaWVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRl dikKIAkJCWNvbnRpbnVlOwogCQl9CiAKKwkJaWYgKGlycSA+IDApIHsKKwkJCXJldCA9IG12ZWJ1 X3BjaWVfaW5pdF9pcnFfZG9tYWluKHBvcnQpOworCQkJaWYgKHJldCkgeworCQkJCWRldl9lcnIo ZGV2LCAiJXM6IGNhbm5vdCBpbml0IGlycSBkb21haW5cbiIsCisJCQkJCXBvcnQtPm5hbWUpOwor CQkJCXBjaV9icmlkZ2VfZW11bF9jbGVhbnVwKCZwb3J0LT5icmlkZ2UpOworCQkJCWRldm1faW91 bm1hcChkZXYsIHBvcnQtPmJhc2UpOworCQkJCXBvcnQtPmJhc2UgPSBOVUxMOworCQkJCW12ZWJ1 X3BjaWVfcG93ZXJkb3duKHBvcnQpOworCQkJCWNvbnRpbnVlOworCQkJfQorCQkJaXJxX3NldF9j aGFpbmVkX2hhbmRsZXJfYW5kX2RhdGEoaXJxLAorCQkJCQkJCSBtdmVidV9wY2llX2lycV9oYW5k bGVyLAorCQkJCQkJCSBwb3J0KTsKKwkJfQorCiAJCS8qCiAJCSAqIFBDSWUgdG9wb2xvZ3kgZXhw b3J0ZWQgYnkgbXZlYnUgaHcgaXMgcXVpdGUgY29tcGxpY2F0ZWQuIEluCiAJCSAqIHJlYWxpdHkg aGFzIHNvbWV0aGluZyBsaWtlIE4gZnVsbHkgaW5kZXBlbmRlbnQgaG9zdCBicmlkZ2VzCkBAIC0x NDQ4LDYgKzE2MDMsNyBAQCBzdGF0aWMgaW50IG12ZWJ1X3BjaWVfcmVtb3ZlKHN0cnVjdCBwbGF0 Zm9ybV9kZXZpY2UgKnBkZXYpCiAKIAlmb3IgKGkgPSAwOyBpIDwgcGNpZS0+bnBvcnRzOyBpKysp IHsKIAkJc3RydWN0IG12ZWJ1X3BjaWVfcG9ydCAqcG9ydCA9ICZwY2llLT5wb3J0c1tpXTsKKwkJ aW50IGlycSA9IHBvcnQtPmludHhfaXJxOwogCiAJCWlmICghcG9ydC0+YmFzZSkKIAkJCWNvbnRp bnVlOwpAQCAtMTQ1OCw3ICsxNjE0LDE3IEBAIHN0YXRpYyBpbnQgbXZlYnVfcGNpZV9yZW1vdmUo c3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIAkJbXZlYnVfd3JpdGVsKHBvcnQsIGNtZCwg UENJRV9DTURfT0ZGKTsKIAogCQkvKiBNYXNrIGFsbCBpbnRlcnJ1cHQgc291cmNlcy4gKi8KLQkJ bXZlYnVfd3JpdGVsKHBvcnQsIDAsIFBDSUVfTUFTS19PRkYpOworCQltdmVidV93cml0ZWwocG9y dCwgflBDSUVfSU5UX0FMTF9NQVNLLCBQQ0lFX0lOVF9VTk1BU0tfT0ZGKTsKKworCQkvKiBDbGVh ciBhbGwgaW50ZXJydXB0IGNhdXNlcy4gKi8KKwkJbXZlYnVfd3JpdGVsKHBvcnQsIH5QQ0lFX0lO VF9BTExfTUFTSywgUENJRV9JTlRfQ0FVU0VfT0ZGKTsKKworCQkvKiBSZW1vdmUgSVJRIGRvbWFp bnMuICovCisJCWlmIChwb3J0LT5pbnR4X2lycV9kb21haW4pCisJCQlpcnFfZG9tYWluX3JlbW92 ZShwb3J0LT5pbnR4X2lycV9kb21haW4pOworCisJCWlmIChpcnEgPiAwKQorCQkJaXJxX3NldF9j aGFpbmVkX2hhbmRsZXJfYW5kX2RhdGEoaXJxLCBOVUxMLCBOVUxMKTsKIAogCQkvKiBGcmVlIGNv bmZpZyBzcGFjZSBmb3IgZW11bGF0ZWQgcm9vdCBicmlkZ2UuICovCiAJCXBjaV9icmlkZ2VfZW11 bF9jbGVhbnVwKCZwb3J0LT5icmlkZ2UpOwotLSAKMi4yMC4xCgoKX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxp c3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZy YWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=