From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ale.deltatee.com ([207.54.116.67]:58464 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728505AbeI0XNp (ORCPT ); Thu, 27 Sep 2018 19:13:45 -0400 From: Logan Gunthorpe To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-nvme@lists.infradead.org, linux-rdma@vger.kernel.org, linux-nvdimm@lists.01.org, linux-block@vger.kernel.org Cc: Stephen Bates , Christoph Hellwig , Keith Busch , Sagi Grimberg , Bjorn Helgaas , Jason Gunthorpe , Max Gurtovoy , Dan Williams , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Benjamin Herrenschmidt , Alex Williamson , =?UTF-8?q?Christian=20K=C3=B6nig?= , Jens Axboe , Logan Gunthorpe , Steve Wise Date: Thu, 27 Sep 2018 10:54:20 -0600 Message-Id: <20180927165420.5290-14-logang@deltatee.com> In-Reply-To: <20180927165420.5290-1-logang@deltatee.com> References: <20180927165420.5290-1-logang@deltatee.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Subject: [PATCH v8 13/13] nvmet: Optionally use PCI P2P memory Sender: linux-block-owner@vger.kernel.org List-Id: linux-block@vger.kernel.org We create a configfs attribute in each nvme-fabrics target port to enable p2p memory use. When enabled, the port will only then use the p2p memory if a p2p memory device can be found which is behind the same switch hierarchy as the RDMA port and all the block devices in use. If the user enabled it and no devices are found, then the system will silently fall back on using regular memory. If appropriate, that port will allocate memory for the RDMA buffers for queues from the p2pmem device falling back to system memory should anything fail. Ideally, we'd want to use an NVME CMB buffer as p2p memory. This would save an extra PCI transfer as the NVME card could just take the data out of it's own memory. However, at this time, only a limited number of cards with CMB buffers seem to be available. Signed-off-by: Stephen Bates Signed-off-by: Steve Wise [hch: partial rewrite of the initial code] Signed-off-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe --- drivers/nvme/target/configfs.c | 36 ++++++++ drivers/nvme/target/core.c | 138 +++++++++++++++++++++++++++++- drivers/nvme/target/io-cmd-bdev.c | 3 + drivers/nvme/target/nvmet.h | 13 +++ drivers/nvme/target/rdma.c | 2 + 5 files changed, 191 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index b37a8e3e3f80..0dfb0e0c3d21 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "nvmet.h" @@ -1094,6 +1096,37 @@ static void nvmet_port_release(struct config_item *item) kfree(port); } +#ifdef CONFIG_PCI_P2PDMA +static ssize_t nvmet_p2pmem_show(struct config_item *item, char *page) +{ + struct nvmet_port *port = to_nvmet_port(item); + + return pci_p2pdma_enable_show(page, port->p2p_dev, port->use_p2pmem); +} + +static ssize_t nvmet_p2pmem_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_port *port = to_nvmet_port(item); + struct pci_dev *p2p_dev = NULL; + bool use_p2pmem; + int error; + + error = pci_p2pdma_enable_store(page, &p2p_dev, &use_p2pmem); + if (error) + return error; + + down_write(&nvmet_config_sem); + port->use_p2pmem = use_p2pmem; + pci_dev_put(port->p2p_dev); + port->p2p_dev = p2p_dev; + up_write(&nvmet_config_sem); + + return count; +} +CONFIGFS_ATTR(nvmet_, p2pmem); +#endif /* CONFIG_PCI_P2PDMA */ + static struct configfs_attribute *nvmet_port_attrs[] = { &nvmet_attr_addr_adrfam, &nvmet_attr_addr_treq, @@ -1101,6 +1134,9 @@ static struct configfs_attribute *nvmet_port_attrs[] = { &nvmet_attr_addr_trsvcid, &nvmet_attr_addr_trtype, &nvmet_attr_param_inline_data_size, +#ifdef CONFIG_PCI_P2PDMA + &nvmet_attr_p2pmem, +#endif NULL, }; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index bddd1599b826..7ade16cb4ed3 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "nvmet.h" @@ -365,9 +366,29 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns) nvmet_file_ns_disable(ns); } +static int nvmet_p2pdma_add_client(struct nvmet_ctrl *ctrl, + struct nvmet_ns *ns) +{ + int ret; + + if (!blk_queue_pci_p2pdma(ns->bdev->bd_queue)) { + pr_err("peer-to-peer DMA is not supported by %s\n", + ns->device_path); + return -EINVAL; + } + + ret = pci_p2pdma_add_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); + if (ret) + pr_err("failed to add peer-to-peer DMA client %s: %d\n", + ns->device_path, ret); + + return ret; +} + int nvmet_ns_enable(struct nvmet_ns *ns) { struct nvmet_subsys *subsys = ns->subsys; + struct nvmet_ctrl *ctrl; int ret; mutex_lock(&subsys->lock); @@ -389,6 +410,14 @@ int nvmet_ns_enable(struct nvmet_ns *ns) if (ret) goto out_dev_put; + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + if (ctrl->p2p_dev) { + ret = nvmet_p2pdma_add_client(ctrl, ns); + if (ret) + goto out_remove_clients; + } + } + if (ns->nsid > subsys->max_nsid) subsys->max_nsid = ns->nsid; @@ -417,6 +446,9 @@ int nvmet_ns_enable(struct nvmet_ns *ns) out_unlock: mutex_unlock(&subsys->lock); return ret; +out_remove_clients: + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) + pci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); out_dev_put: nvmet_ns_dev_disable(ns); goto out_unlock; @@ -425,6 +457,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns) void nvmet_ns_disable(struct nvmet_ns *ns) { struct nvmet_subsys *subsys = ns->subsys; + struct nvmet_ctrl *ctrl; mutex_lock(&subsys->lock); if (!ns->enabled) @@ -450,6 +483,12 @@ void nvmet_ns_disable(struct nvmet_ns *ns) percpu_ref_exit(&ns->ref); mutex_lock(&subsys->lock); + + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + pci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); + nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0); + } + subsys->nr_namespaces--; nvmet_ns_changed(subsys, ns->nsid); nvmet_ns_dev_disable(ns); @@ -727,6 +766,23 @@ EXPORT_SYMBOL_GPL(nvmet_req_execute); int nvmet_req_alloc_sgl(struct nvmet_req *req, struct nvmet_sq *sq) { + struct pci_dev *p2p_dev = NULL; + + if (IS_ENABLED(CONFIG_PCI_P2PDMA)) { + if (sq->ctrl) + p2p_dev = sq->ctrl->p2p_dev; + + req->p2p_dev = NULL; + if (sq->qid && p2p_dev) { + req->sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->sg_cnt, + req->transfer_len); + if (req->sg) { + req->p2p_dev = p2p_dev; + return 0; + } + } + } + req->sg = sgl_alloc(req->transfer_len, GFP_KERNEL, &req->sg_cnt); if (!req->sg) return -ENOMEM; @@ -737,7 +793,11 @@ EXPORT_SYMBOL_GPL(nvmet_req_alloc_sgl); void nvmet_req_free_sgl(struct nvmet_req *req) { - sgl_free(req->sg); + if (req->p2p_dev) + pci_p2pmem_free_sgl(req->p2p_dev, req->sg); + else + sgl_free(req->sg); + req->sg = NULL; req->sg_cnt = 0; } @@ -939,6 +999,79 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys, return __nvmet_host_allowed(subsys, hostnqn); } +/* + * If allow_p2pmem is set, we will try to use P2P memory for the SGL lists for + * Ι/O commands. This requires the PCI p2p device to be compatible with the + * backing device for every namespace on this controller. + */ +static void nvmet_setup_p2pmem(struct nvmet_ctrl *ctrl, struct nvmet_req *req) +{ + struct nvmet_ns *ns; + int ret; + + if (!req->port->use_p2pmem || !req->p2p_client) + return; + + mutex_lock(&ctrl->subsys->lock); + + ret = pci_p2pdma_add_client(&ctrl->p2p_clients, req->p2p_client); + if (ret) { + pr_err("failed adding peer-to-peer DMA client %s: %d\n", + dev_name(req->p2p_client), ret); + goto free_devices; + } + + list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link) { + ret = nvmet_p2pdma_add_client(ctrl, ns); + if (ret) + goto free_devices; + } + + if (req->port->p2p_dev) { + /* A specific P2P device was selected in configfs */ + if (!pci_p2pdma_assign_provider(req->port->p2p_dev, + &ctrl->p2p_clients)) { + pr_info("peer-to-peer memory on %s is not supported\n", + pci_name(req->port->p2p_dev)); + goto free_devices; + } + ctrl->p2p_dev = pci_dev_get(req->port->p2p_dev); + } else { + /* + * No P2P device was provided in configfs, therefore find one + * automatically. + */ + ctrl->p2p_dev = pci_p2pmem_find(&ctrl->p2p_clients); + if (!ctrl->p2p_dev) { + pr_info("no supported peer-to-peer memory devices found\n"); + goto free_devices; + } + } + + mutex_unlock(&ctrl->subsys->lock); + + pr_info("using peer-to-peer memory on %s\n", pci_name(ctrl->p2p_dev)); + return; + +free_devices: + pci_p2pdma_client_list_free(&ctrl->p2p_clients); + mutex_unlock(&ctrl->subsys->lock); +} + +static void nvmet_release_p2pmem(struct nvmet_ctrl *ctrl) +{ + if (!ctrl->p2p_dev) + return; + + mutex_lock(&ctrl->subsys->lock); + + pci_p2pdma_client_list_free(&ctrl->p2p_clients); + pci_dev_put(ctrl->p2p_dev); + ctrl->p2p_dev = NULL; + + mutex_unlock(&ctrl->subsys->lock); +} + u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp) { @@ -980,6 +1113,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); + INIT_LIST_HEAD(&ctrl->p2p_clients); memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); @@ -1041,6 +1175,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, ctrl->kato = DIV_ROUND_UP(kato, 1000); } nvmet_start_keep_alive_timer(ctrl); + nvmet_setup_p2pmem(ctrl, req); mutex_lock(&subsys->lock); list_add_tail(&ctrl->subsys_entry, &subsys->ctrls); @@ -1079,6 +1214,7 @@ static void nvmet_ctrl_free(struct kref *ref) flush_work(&ctrl->async_event_work); cancel_work_sync(&ctrl->fatal_err_work); + nvmet_release_p2pmem(ctrl); ida_simple_remove(&cntlid_ida, ctrl->cntlid); kfree(ctrl->sqs); diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 7bc9f6240432..5660dd7ca755 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -78,6 +78,9 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req) op = REQ_OP_READ; } + if (is_pci_p2pdma_page(sg_page(req->sg))) + op_flags |= REQ_NOMERGE; + sector = le64_to_cpu(req->cmd->rw.slba); sector <<= (req->ns->blksize_shift - 9); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 7d6cb61021e4..297861064dd8 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -84,6 +84,11 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item) return container_of(to_config_group(item), struct nvmet_ns, group); } +static inline struct device *nvmet_ns_dev(struct nvmet_ns *ns) +{ + return disk_to_dev(ns->bdev->bd_disk); +} + struct nvmet_cq { u16 qid; u16 size; @@ -134,6 +139,8 @@ struct nvmet_port { void *priv; bool enabled; int inline_data_size; + bool use_p2pmem; + struct pci_dev *p2p_dev; }; static inline struct nvmet_port *to_nvmet_port(struct config_item *item) @@ -182,6 +189,9 @@ struct nvmet_ctrl { __le32 *changed_ns_list; u32 nr_changed_ns; + struct pci_dev *p2p_dev; + struct list_head p2p_clients; + char subsysnqn[NVMF_NQN_FIELD_LEN]; char hostnqn[NVMF_NQN_FIELD_LEN]; }; @@ -294,6 +304,9 @@ struct nvmet_req { void (*execute)(struct nvmet_req *req); const struct nvmet_fabrics_ops *ops; + + struct pci_dev *p2p_dev; + struct device *p2p_client; }; extern struct workqueue_struct *buffered_io_wq; diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index b0d0cedc74bb..e5f00449ac68 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -749,6 +749,8 @@ static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue, cmd->send_sge.addr, cmd->send_sge.length, DMA_TO_DEVICE); + cmd->req.p2p_client = &queue->dev->device->dev; + if (!nvmet_req_init(&cmd->req, &queue->nvme_cq, &queue->nvme_sq, &nvmet_rdma_ops)) return; -- 2.19.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ale.deltatee.com (ale.deltatee.com [207.54.116.67]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 8280321159C96 for ; Thu, 27 Sep 2018 09:54:35 -0700 (PDT) From: Logan Gunthorpe Date: Thu, 27 Sep 2018 10:54:20 -0600 Message-Id: <20180927165420.5290-14-logang@deltatee.com> In-Reply-To: <20180927165420.5290-1-logang@deltatee.com> References: <20180927165420.5290-1-logang@deltatee.com> MIME-Version: 1.0 Subject: [PATCH v8 13/13] nvmet: Optionally use PCI P2P memory List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-nvme@lists.infradead.org, linux-rdma@vger.kernel.org, linux-nvdimm@lists.01.org, linux-block@vger.kernel.org Cc: Jens Axboe , =?UTF-8?q?Christian=20K=C3=B6nig?= , Benjamin Herrenschmidt , Steve Wise , Alex Williamson , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Jason Gunthorpe , Bjorn Helgaas , Max Gurtovoy , Christoph Hellwig List-ID: V2UgY3JlYXRlIGEgY29uZmlnZnMgYXR0cmlidXRlIGluIGVhY2ggbnZtZS1mYWJyaWNzIHRhcmdl dCBwb3J0IHRvCmVuYWJsZSBwMnAgbWVtb3J5IHVzZS4gV2hlbiBlbmFibGVkLCB0aGUgcG9ydCB3 aWxsIG9ubHkgdGhlbiB1c2UgdGhlCnAycCBtZW1vcnkgaWYgYSBwMnAgbWVtb3J5IGRldmljZSBj YW4gYmUgZm91bmQgd2hpY2ggaXMgYmVoaW5kIHRoZQpzYW1lIHN3aXRjaCBoaWVyYXJjaHkgYXMg dGhlIFJETUEgcG9ydCBhbmQgYWxsIHRoZSBibG9jayBkZXZpY2VzIGluCnVzZS4gSWYgdGhlIHVz ZXIgZW5hYmxlZCBpdCBhbmQgbm8gZGV2aWNlcyBhcmUgZm91bmQsIHRoZW4gdGhlIHN5c3RlbQp3 aWxsIHNpbGVudGx5IGZhbGwgYmFjayBvbiB1c2luZyByZWd1bGFyIG1lbW9yeS4KCklmIGFwcHJv cHJpYXRlLCB0aGF0IHBvcnQgd2lsbCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBSRE1BIGJ1ZmZl cnMKZm9yIHF1ZXVlcyBmcm9tIHRoZSBwMnBtZW0gZGV2aWNlIGZhbGxpbmcgYmFjayB0byBzeXN0 ZW0gbWVtb3J5IHNob3VsZAphbnl0aGluZyBmYWlsLgoKSWRlYWxseSwgd2UnZCB3YW50IHRvIHVz ZSBhbiBOVk1FIENNQiBidWZmZXIgYXMgcDJwIG1lbW9yeS4gVGhpcyB3b3VsZApzYXZlIGFuIGV4 dHJhIFBDSSB0cmFuc2ZlciBhcyB0aGUgTlZNRSBjYXJkIGNvdWxkIGp1c3QgdGFrZSB0aGUgZGF0 YQpvdXQgb2YgaXQncyBvd24gbWVtb3J5LiBIb3dldmVyLCBhdCB0aGlzIHRpbWUsIG9ubHkgYSBs aW1pdGVkIG51bWJlcgpvZiBjYXJkcyB3aXRoIENNQiBidWZmZXJzIHNlZW0gdG8gYmUgYXZhaWxh YmxlLgoKU2lnbmVkLW9mZi1ieTogU3RlcGhlbiBCYXRlcyA8c2JhdGVzQHJhaXRobGluLmNvbT4K U2lnbmVkLW9mZi1ieTogU3RldmUgV2lzZSA8c3dpc2VAb3BlbmdyaWRjb21wdXRpbmcuY29tPgpb aGNoOiBwYXJ0aWFsIHJld3JpdGUgb2YgdGhlIGluaXRpYWwgY29kZV0KU2lnbmVkLW9mZi1ieTog Q2hyaXN0b3BoIEhlbGx3aWcgPGhjaEBsc3QuZGU+ClNpZ25lZC1vZmYtYnk6IExvZ2FuIEd1bnRo b3JwZSA8bG9nYW5nQGRlbHRhdGVlLmNvbT4KLS0tCiBkcml2ZXJzL252bWUvdGFyZ2V0L2NvbmZp Z2ZzLmMgICAgfCAgMzYgKysrKysrKysKIGRyaXZlcnMvbnZtZS90YXJnZXQvY29yZS5jICAgICAg ICB8IDEzOCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0KIGRyaXZlcnMvbnZtZS90YXJn ZXQvaW8tY21kLWJkZXYuYyB8ICAgMyArCiBkcml2ZXJzL252bWUvdGFyZ2V0L252bWV0LmggICAg ICAgfCAgMTMgKysrCiBkcml2ZXJzL252bWUvdGFyZ2V0L3JkbWEuYyAgICAgICAgfCAgIDIgKwog NSBmaWxlcyBjaGFuZ2VkLCAxOTEgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQoKZGlmZiAt LWdpdCBhL2RyaXZlcnMvbnZtZS90YXJnZXQvY29uZmlnZnMuYyBiL2RyaXZlcnMvbnZtZS90YXJn ZXQvY29uZmlnZnMuYwppbmRleCBiMzdhOGUzZTNmODAuLjBkZmIwZTBjM2QyMSAxMDA2NDQKLS0t IGEvZHJpdmVycy9udm1lL3RhcmdldC9jb25maWdmcy5jCisrKyBiL2RyaXZlcnMvbnZtZS90YXJn ZXQvY29uZmlnZnMuYwpAQCAtMTcsNiArMTcsOCBAQAogI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4K ICNpbmNsdWRlIDxsaW51eC9zdGF0Lmg+CiAjaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KKyNpbmNs dWRlIDxsaW51eC9wY2kuaD4KKyNpbmNsdWRlIDxsaW51eC9wY2ktcDJwZG1hLmg+CiAKICNpbmNs dWRlICJudm1ldC5oIgogCkBAIC0xMDk0LDYgKzEwOTYsMzcgQEAgc3RhdGljIHZvaWQgbnZtZXRf cG9ydF9yZWxlYXNlKHN0cnVjdCBjb25maWdfaXRlbSAqaXRlbSkKIAlrZnJlZShwb3J0KTsKIH0K IAorI2lmZGVmIENPTkZJR19QQ0lfUDJQRE1BCitzdGF0aWMgc3NpemVfdCBudm1ldF9wMnBtZW1f c2hvdyhzdHJ1Y3QgY29uZmlnX2l0ZW0gKml0ZW0sIGNoYXIgKnBhZ2UpCit7CisJc3RydWN0IG52 bWV0X3BvcnQgKnBvcnQgPSB0b19udm1ldF9wb3J0KGl0ZW0pOworCisJcmV0dXJuIHBjaV9wMnBk bWFfZW5hYmxlX3Nob3cocGFnZSwgcG9ydC0+cDJwX2RldiwgcG9ydC0+dXNlX3AycG1lbSk7Cit9 CisKK3N0YXRpYyBzc2l6ZV90IG52bWV0X3AycG1lbV9zdG9yZShzdHJ1Y3QgY29uZmlnX2l0ZW0g Kml0ZW0sCisJCWNvbnN0IGNoYXIgKnBhZ2UsIHNpemVfdCBjb3VudCkKK3sKKwlzdHJ1Y3QgbnZt ZXRfcG9ydCAqcG9ydCA9IHRvX252bWV0X3BvcnQoaXRlbSk7CisJc3RydWN0IHBjaV9kZXYgKnAy cF9kZXYgPSBOVUxMOworCWJvb2wgdXNlX3AycG1lbTsKKwlpbnQgZXJyb3I7CisKKwllcnJvciA9 IHBjaV9wMnBkbWFfZW5hYmxlX3N0b3JlKHBhZ2UsICZwMnBfZGV2LCAmdXNlX3AycG1lbSk7CisJ aWYgKGVycm9yKQorCQlyZXR1cm4gZXJyb3I7CisKKwlkb3duX3dyaXRlKCZudm1ldF9jb25maWdf c2VtKTsKKwlwb3J0LT51c2VfcDJwbWVtID0gdXNlX3AycG1lbTsKKwlwY2lfZGV2X3B1dChwb3J0 LT5wMnBfZGV2KTsKKwlwb3J0LT5wMnBfZGV2ID0gcDJwX2RldjsKKwl1cF93cml0ZSgmbnZtZXRf Y29uZmlnX3NlbSk7CisKKwlyZXR1cm4gY291bnQ7Cit9CitDT05GSUdGU19BVFRSKG52bWV0Xywg cDJwbWVtKTsKKyNlbmRpZiAvKiBDT05GSUdfUENJX1AyUERNQSAqLworCiBzdGF0aWMgc3RydWN0 IGNvbmZpZ2ZzX2F0dHJpYnV0ZSAqbnZtZXRfcG9ydF9hdHRyc1tdID0gewogCSZudm1ldF9hdHRy X2FkZHJfYWRyZmFtLAogCSZudm1ldF9hdHRyX2FkZHJfdHJlcSwKQEAgLTExMDEsNiArMTEzNCw5 IEBAIHN0YXRpYyBzdHJ1Y3QgY29uZmlnZnNfYXR0cmlidXRlICpudm1ldF9wb3J0X2F0dHJzW10g PSB7CiAJJm52bWV0X2F0dHJfYWRkcl90cnN2Y2lkLAogCSZudm1ldF9hdHRyX2FkZHJfdHJ0eXBl LAogCSZudm1ldF9hdHRyX3BhcmFtX2lubGluZV9kYXRhX3NpemUsCisjaWZkZWYgQ09ORklHX1BD SV9QMlBETUEKKwkmbnZtZXRfYXR0cl9wMnBtZW0sCisjZW5kaWYKIAlOVUxMLAogfTsKIApkaWZm IC0tZ2l0IGEvZHJpdmVycy9udm1lL3RhcmdldC9jb3JlLmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0 L2NvcmUuYwppbmRleCBiZGRkMTU5OWI4MjYuLjdhZGUxNmNiNGVkMyAxMDA2NDQKLS0tIGEvZHJp dmVycy9udm1lL3RhcmdldC9jb3JlLmMKKysrIGIvZHJpdmVycy9udm1lL3RhcmdldC9jb3JlLmMK QEAgLTE1LDYgKzE1LDcgQEAKICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KICNpbmNsdWRlIDxs aW51eC9yYW5kb20uaD4KICNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CisjaW5jbHVkZSA8bGlu dXgvcGNpLXAycGRtYS5oPgogCiAjaW5jbHVkZSAibnZtZXQuaCIKIApAQCAtMzY1LDkgKzM2Niwy OSBAQCBzdGF0aWMgdm9pZCBudm1ldF9uc19kZXZfZGlzYWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5z KQogCW52bWV0X2ZpbGVfbnNfZGlzYWJsZShucyk7CiB9CiAKK3N0YXRpYyBpbnQgbnZtZXRfcDJw ZG1hX2FkZF9jbGllbnQoc3RydWN0IG52bWV0X2N0cmwgKmN0cmwsCisJCXN0cnVjdCBudm1ldF9u cyAqbnMpCit7CisJaW50IHJldDsKKworCWlmICghYmxrX3F1ZXVlX3BjaV9wMnBkbWEobnMtPmJk ZXYtPmJkX3F1ZXVlKSkgeworCQlwcl9lcnIoInBlZXItdG8tcGVlciBETUEgaXMgbm90IHN1cHBv cnRlZCBieSAlc1xuIiwKKwkJICAgICAgIG5zLT5kZXZpY2VfcGF0aCk7CisJCXJldHVybiAtRUlO VkFMOworCX0KKworCXJldCA9IHBjaV9wMnBkbWFfYWRkX2NsaWVudCgmY3RybC0+cDJwX2NsaWVu dHMsIG52bWV0X25zX2RldihucykpOworCWlmIChyZXQpCisJCXByX2VycigiZmFpbGVkIHRvIGFk ZCBwZWVyLXRvLXBlZXIgRE1BIGNsaWVudCAlczogJWRcbiIsCisJCSAgICAgICBucy0+ZGV2aWNl X3BhdGgsIHJldCk7CisKKwlyZXR1cm4gcmV0OworfQorCiBpbnQgbnZtZXRfbnNfZW5hYmxlKHN0 cnVjdCBudm1ldF9ucyAqbnMpCiB7CiAJc3RydWN0IG52bWV0X3N1YnN5cyAqc3Vic3lzID0gbnMt PnN1YnN5czsKKwlzdHJ1Y3QgbnZtZXRfY3RybCAqY3RybDsKIAlpbnQgcmV0OwogCiAJbXV0ZXhf bG9jaygmc3Vic3lzLT5sb2NrKTsKQEAgLTM4OSw2ICs0MTAsMTQgQEAgaW50IG52bWV0X25zX2Vu YWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5zKQogCWlmIChyZXQpCiAJCWdvdG8gb3V0X2Rldl9wdXQ7 CiAKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KGN0cmwsICZzdWJzeXMtPmN0cmxzLCBzdWJzeXNfZW50 cnkpIHsKKwkJaWYgKGN0cmwtPnAycF9kZXYpIHsKKwkJCXJldCA9IG52bWV0X3AycGRtYV9hZGRf Y2xpZW50KGN0cmwsIG5zKTsKKwkJCWlmIChyZXQpCisJCQkJZ290byBvdXRfcmVtb3ZlX2NsaWVu dHM7CisJCX0KKwl9CisKIAlpZiAobnMtPm5zaWQgPiBzdWJzeXMtPm1heF9uc2lkKQogCQlzdWJz eXMtPm1heF9uc2lkID0gbnMtPm5zaWQ7CiAKQEAgLTQxNyw2ICs0NDYsOSBAQCBpbnQgbnZtZXRf bnNfZW5hYmxlKHN0cnVjdCBudm1ldF9ucyAqbnMpCiBvdXRfdW5sb2NrOgogCW11dGV4X3VubG9j aygmc3Vic3lzLT5sb2NrKTsKIAlyZXR1cm4gcmV0Oworb3V0X3JlbW92ZV9jbGllbnRzOgorCWxp c3RfZm9yX2VhY2hfZW50cnkoY3RybCwgJnN1YnN5cy0+Y3RybHMsIHN1YnN5c19lbnRyeSkKKwkJ cGNpX3AycGRtYV9yZW1vdmVfY2xpZW50KCZjdHJsLT5wMnBfY2xpZW50cywgbnZtZXRfbnNfZGV2 KG5zKSk7CiBvdXRfZGV2X3B1dDoKIAludm1ldF9uc19kZXZfZGlzYWJsZShucyk7CiAJZ290byBv dXRfdW5sb2NrOwpAQCAtNDI1LDYgKzQ1Nyw3IEBAIGludCBudm1ldF9uc19lbmFibGUoc3RydWN0 IG52bWV0X25zICpucykKIHZvaWQgbnZtZXRfbnNfZGlzYWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5z KQogewogCXN0cnVjdCBudm1ldF9zdWJzeXMgKnN1YnN5cyA9IG5zLT5zdWJzeXM7CisJc3RydWN0 IG52bWV0X2N0cmwgKmN0cmw7CiAKIAltdXRleF9sb2NrKCZzdWJzeXMtPmxvY2spOwogCWlmICgh bnMtPmVuYWJsZWQpCkBAIC00NTAsNiArNDgzLDEyIEBAIHZvaWQgbnZtZXRfbnNfZGlzYWJsZShz dHJ1Y3QgbnZtZXRfbnMgKm5zKQogCXBlcmNwdV9yZWZfZXhpdCgmbnMtPnJlZik7CiAKIAltdXRl eF9sb2NrKCZzdWJzeXMtPmxvY2spOworCisJbGlzdF9mb3JfZWFjaF9lbnRyeShjdHJsLCAmc3Vi c3lzLT5jdHJscywgc3Vic3lzX2VudHJ5KSB7CisJCXBjaV9wMnBkbWFfcmVtb3ZlX2NsaWVudCgm Y3RybC0+cDJwX2NsaWVudHMsIG52bWV0X25zX2RldihucykpOworCQludm1ldF9hZGRfYXN5bmNf ZXZlbnQoY3RybCwgTlZNRV9BRVJfVFlQRV9OT1RJQ0UsIDAsIDApOworCX0KKwogCXN1YnN5cy0+ bnJfbmFtZXNwYWNlcy0tOwogCW52bWV0X25zX2NoYW5nZWQoc3Vic3lzLCBucy0+bnNpZCk7CiAJ bnZtZXRfbnNfZGV2X2Rpc2FibGUobnMpOwpAQCAtNzI3LDYgKzc2NiwyMyBAQCBFWFBPUlRfU1lN Qk9MX0dQTChudm1ldF9yZXFfZXhlY3V0ZSk7CiAKIGludCBudm1ldF9yZXFfYWxsb2Nfc2dsKHN0 cnVjdCBudm1ldF9yZXEgKnJlcSwgc3RydWN0IG52bWV0X3NxICpzcSkKIHsKKwlzdHJ1Y3QgcGNp X2RldiAqcDJwX2RldiA9IE5VTEw7CisKKwlpZiAoSVNfRU5BQkxFRChDT05GSUdfUENJX1AyUERN QSkpIHsKKwkJaWYgKHNxLT5jdHJsKQorCQkJcDJwX2RldiA9IHNxLT5jdHJsLT5wMnBfZGV2Owor CisJCXJlcS0+cDJwX2RldiA9IE5VTEw7CisJCWlmIChzcS0+cWlkICYmIHAycF9kZXYpIHsKKwkJ CXJlcS0+c2cgPSBwY2lfcDJwbWVtX2FsbG9jX3NnbChwMnBfZGV2LCAmcmVxLT5zZ19jbnQsCisJ CQkJCQkgICAgICAgcmVxLT50cmFuc2Zlcl9sZW4pOworCQkJaWYgKHJlcS0+c2cpIHsKKwkJCQly ZXEtPnAycF9kZXYgPSBwMnBfZGV2OworCQkJCXJldHVybiAwOworCQkJfQorCQl9CisJfQorCiAJ cmVxLT5zZyA9IHNnbF9hbGxvYyhyZXEtPnRyYW5zZmVyX2xlbiwgR0ZQX0tFUk5FTCwgJnJlcS0+ c2dfY250KTsKIAlpZiAoIXJlcS0+c2cpCiAJCXJldHVybiAtRU5PTUVNOwpAQCAtNzM3LDcgKzc5 MywxMSBAQCBFWFBPUlRfU1lNQk9MX0dQTChudm1ldF9yZXFfYWxsb2Nfc2dsKTsKIAogdm9pZCBu dm1ldF9yZXFfZnJlZV9zZ2woc3RydWN0IG52bWV0X3JlcSAqcmVxKQogewotCXNnbF9mcmVlKHJl cS0+c2cpOworCWlmIChyZXEtPnAycF9kZXYpCisJCXBjaV9wMnBtZW1fZnJlZV9zZ2wocmVxLT5w MnBfZGV2LCByZXEtPnNnKTsKKwllbHNlCisJCXNnbF9mcmVlKHJlcS0+c2cpOworCiAJcmVxLT5z ZyA9IE5VTEw7CiAJcmVxLT5zZ19jbnQgPSAwOwogfQpAQCAtOTM5LDYgKzk5OSw3OSBAQCBib29s IG52bWV0X2hvc3RfYWxsb3dlZChzdHJ1Y3QgbnZtZXRfcmVxICpyZXEsIHN0cnVjdCBudm1ldF9z dWJzeXMgKnN1YnN5cywKIAkJcmV0dXJuIF9fbnZtZXRfaG9zdF9hbGxvd2VkKHN1YnN5cywgaG9z dG5xbik7CiB9CiAKKy8qCisgKiBJZiBhbGxvd19wMnBtZW0gaXMgc2V0LCB3ZSB3aWxsIHRyeSB0 byB1c2UgUDJQIG1lbW9yeSBmb3IgdGhlIFNHTCBsaXN0cyBmb3IKKyAqIM6ZL08gY29tbWFuZHMu IFRoaXMgcmVxdWlyZXMgdGhlIFBDSSBwMnAgZGV2aWNlIHRvIGJlIGNvbXBhdGlibGUgd2l0aCB0 aGUKKyAqIGJhY2tpbmcgZGV2aWNlIGZvciBldmVyeSBuYW1lc3BhY2Ugb24gdGhpcyBjb250cm9s bGVyLgorICovCitzdGF0aWMgdm9pZCBudm1ldF9zZXR1cF9wMnBtZW0oc3RydWN0IG52bWV0X2N0 cmwgKmN0cmwsIHN0cnVjdCBudm1ldF9yZXEgKnJlcSkKK3sKKwlzdHJ1Y3QgbnZtZXRfbnMgKm5z OworCWludCByZXQ7CisKKwlpZiAoIXJlcS0+cG9ydC0+dXNlX3AycG1lbSB8fCAhcmVxLT5wMnBf Y2xpZW50KQorCQlyZXR1cm47CisKKwltdXRleF9sb2NrKCZjdHJsLT5zdWJzeXMtPmxvY2spOwor CisJcmV0ID0gcGNpX3AycGRtYV9hZGRfY2xpZW50KCZjdHJsLT5wMnBfY2xpZW50cywgcmVxLT5w MnBfY2xpZW50KTsKKwlpZiAocmV0KSB7CisJCXByX2VycigiZmFpbGVkIGFkZGluZyBwZWVyLXRv LXBlZXIgRE1BIGNsaWVudCAlczogJWRcbiIsCisJCSAgICAgICBkZXZfbmFtZShyZXEtPnAycF9j bGllbnQpLCByZXQpOworCQlnb3RvIGZyZWVfZGV2aWNlczsKKwl9CisKKwlsaXN0X2Zvcl9lYWNo X2VudHJ5X3JjdShucywgJmN0cmwtPnN1YnN5cy0+bmFtZXNwYWNlcywgZGV2X2xpbmspIHsKKwkJ cmV0ID0gbnZtZXRfcDJwZG1hX2FkZF9jbGllbnQoY3RybCwgbnMpOworCQlpZiAocmV0KQorCQkJ Z290byBmcmVlX2RldmljZXM7CisJfQorCisJaWYgKHJlcS0+cG9ydC0+cDJwX2RldikgeworCQkv KiBBIHNwZWNpZmljIFAyUCBkZXZpY2Ugd2FzIHNlbGVjdGVkIGluIGNvbmZpZ2ZzICovCisJCWlm ICghcGNpX3AycGRtYV9hc3NpZ25fcHJvdmlkZXIocmVxLT5wb3J0LT5wMnBfZGV2LAorCQkJCQkJ JmN0cmwtPnAycF9jbGllbnRzKSkgeworCQkJcHJfaW5mbygicGVlci10by1wZWVyIG1lbW9yeSBv biAlcyBpcyBub3Qgc3VwcG9ydGVkXG4iLAorCQkJCXBjaV9uYW1lKHJlcS0+cG9ydC0+cDJwX2Rl dikpOworCQkJZ290byBmcmVlX2RldmljZXM7CisJCX0KKwkJY3RybC0+cDJwX2RldiA9IHBjaV9k ZXZfZ2V0KHJlcS0+cG9ydC0+cDJwX2Rldik7CisJfSBlbHNlIHsKKwkJLyoKKwkJICogTm8gUDJQ IGRldmljZSB3YXMgcHJvdmlkZWQgaW4gY29uZmlnZnMsIHRoZXJlZm9yZSBmaW5kIG9uZQorCQkg KiBhdXRvbWF0aWNhbGx5LgorCQkgKi8KKwkJY3RybC0+cDJwX2RldiA9IHBjaV9wMnBtZW1fZmlu ZCgmY3RybC0+cDJwX2NsaWVudHMpOworCQlpZiAoIWN0cmwtPnAycF9kZXYpIHsKKwkJCXByX2lu Zm8oIm5vIHN1cHBvcnRlZCBwZWVyLXRvLXBlZXIgbWVtb3J5IGRldmljZXMgZm91bmRcbiIpOwor CQkJZ290byBmcmVlX2RldmljZXM7CisJCX0KKwl9CisKKwltdXRleF91bmxvY2soJmN0cmwtPnN1 YnN5cy0+bG9jayk7CisKKwlwcl9pbmZvKCJ1c2luZyBwZWVyLXRvLXBlZXIgbWVtb3J5IG9uICVz XG4iLCBwY2lfbmFtZShjdHJsLT5wMnBfZGV2KSk7CisJcmV0dXJuOworCitmcmVlX2RldmljZXM6 CisJcGNpX3AycGRtYV9jbGllbnRfbGlzdF9mcmVlKCZjdHJsLT5wMnBfY2xpZW50cyk7CisJbXV0 ZXhfdW5sb2NrKCZjdHJsLT5zdWJzeXMtPmxvY2spOworfQorCitzdGF0aWMgdm9pZCBudm1ldF9y ZWxlYXNlX3AycG1lbShzdHJ1Y3QgbnZtZXRfY3RybCAqY3RybCkKK3sKKwlpZiAoIWN0cmwtPnAy cF9kZXYpCisJCXJldHVybjsKKworCW11dGV4X2xvY2soJmN0cmwtPnN1YnN5cy0+bG9jayk7CisK KwlwY2lfcDJwZG1hX2NsaWVudF9saXN0X2ZyZWUoJmN0cmwtPnAycF9jbGllbnRzKTsKKwlwY2lf ZGV2X3B1dChjdHJsLT5wMnBfZGV2KTsKKwljdHJsLT5wMnBfZGV2ID0gTlVMTDsKKworCW11dGV4 X3VubG9jaygmY3RybC0+c3Vic3lzLT5sb2NrKTsKK30KKwogdTE2IG52bWV0X2FsbG9jX2N0cmwo Y29uc3QgY2hhciAqc3Vic3lzbnFuLCBjb25zdCBjaGFyICpob3N0bnFuLAogCQlzdHJ1Y3QgbnZt ZXRfcmVxICpyZXEsIHUzMiBrYXRvLCBzdHJ1Y3QgbnZtZXRfY3RybCAqKmN0cmxwKQogewpAQCAt OTgwLDYgKzExMTMsNyBAQCB1MTYgbnZtZXRfYWxsb2NfY3RybChjb25zdCBjaGFyICpzdWJzeXNu cW4sIGNvbnN0IGNoYXIgKmhvc3RucW4sCiAKIAlJTklUX1dPUksoJmN0cmwtPmFzeW5jX2V2ZW50 X3dvcmssIG52bWV0X2FzeW5jX2V2ZW50X3dvcmspOwogCUlOSVRfTElTVF9IRUFEKCZjdHJsLT5h c3luY19ldmVudHMpOworCUlOSVRfTElTVF9IRUFEKCZjdHJsLT5wMnBfY2xpZW50cyk7CiAKIAlt ZW1jcHkoY3RybC0+c3Vic3lzbnFuLCBzdWJzeXNucW4sIE5WTUZfTlFOX1NJWkUpOwogCW1lbWNw eShjdHJsLT5ob3N0bnFuLCBob3N0bnFuLCBOVk1GX05RTl9TSVpFKTsKQEAgLTEwNDEsNiArMTE3 NSw3IEBAIHUxNiBudm1ldF9hbGxvY19jdHJsKGNvbnN0IGNoYXIgKnN1YnN5c25xbiwgY29uc3Qg Y2hhciAqaG9zdG5xbiwKIAkJY3RybC0+a2F0byA9IERJVl9ST1VORF9VUChrYXRvLCAxMDAwKTsK IAl9CiAJbnZtZXRfc3RhcnRfa2VlcF9hbGl2ZV90aW1lcihjdHJsKTsKKwludm1ldF9zZXR1cF9w MnBtZW0oY3RybCwgcmVxKTsKIAogCW11dGV4X2xvY2soJnN1YnN5cy0+bG9jayk7CiAJbGlzdF9h ZGRfdGFpbCgmY3RybC0+c3Vic3lzX2VudHJ5LCAmc3Vic3lzLT5jdHJscyk7CkBAIC0xMDc5LDYg KzEyMTQsNyBAQCBzdGF0aWMgdm9pZCBudm1ldF9jdHJsX2ZyZWUoc3RydWN0IGtyZWYgKnJlZikK IAlmbHVzaF93b3JrKCZjdHJsLT5hc3luY19ldmVudF93b3JrKTsKIAljYW5jZWxfd29ya19zeW5j KCZjdHJsLT5mYXRhbF9lcnJfd29yayk7CiAKKwludm1ldF9yZWxlYXNlX3AycG1lbShjdHJsKTsK IAlpZGFfc2ltcGxlX3JlbW92ZSgmY250bGlkX2lkYSwgY3RybC0+Y250bGlkKTsKIAogCWtmcmVl KGN0cmwtPnNxcyk7CmRpZmYgLS1naXQgYS9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2 LmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2LmMKaW5kZXggN2JjOWY2MjQwNDMy Li41NjYwZGQ3Y2E3NTUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvbnZtZS90YXJnZXQvaW8tY21kLWJk ZXYuYworKysgYi9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2LmMKQEAgLTc4LDYgKzc4 LDkgQEAgc3RhdGljIHZvaWQgbnZtZXRfYmRldl9leGVjdXRlX3J3KHN0cnVjdCBudm1ldF9yZXEg KnJlcSkKIAkJb3AgPSBSRVFfT1BfUkVBRDsKIAl9CiAKKwlpZiAoaXNfcGNpX3AycGRtYV9wYWdl KHNnX3BhZ2UocmVxLT5zZykpKQorCQlvcF9mbGFncyB8PSBSRVFfTk9NRVJHRTsKKwogCXNlY3Rv ciA9IGxlNjRfdG9fY3B1KHJlcS0+Y21kLT5ydy5zbGJhKTsKIAlzZWN0b3IgPDw9IChyZXEtPm5z LT5ibGtzaXplX3NoaWZ0IC0gOSk7CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbnZtZS90YXJnZXQv bnZtZXQuaCBiL2RyaXZlcnMvbnZtZS90YXJnZXQvbnZtZXQuaAppbmRleCA3ZDZjYjYxMDIxZTQu LjI5Nzg2MTA2NGRkOCAxMDA2NDQKLS0tIGEvZHJpdmVycy9udm1lL3RhcmdldC9udm1ldC5oCisr KyBiL2RyaXZlcnMvbnZtZS90YXJnZXQvbnZtZXQuaApAQCAtODQsNiArODQsMTEgQEAgc3RhdGlj IGlubGluZSBzdHJ1Y3QgbnZtZXRfbnMgKnRvX252bWV0X25zKHN0cnVjdCBjb25maWdfaXRlbSAq aXRlbSkKIAlyZXR1cm4gY29udGFpbmVyX29mKHRvX2NvbmZpZ19ncm91cChpdGVtKSwgc3RydWN0 IG52bWV0X25zLCBncm91cCk7CiB9CiAKK3N0YXRpYyBpbmxpbmUgc3RydWN0IGRldmljZSAqbnZt ZXRfbnNfZGV2KHN0cnVjdCBudm1ldF9ucyAqbnMpCit7CisJcmV0dXJuIGRpc2tfdG9fZGV2KG5z LT5iZGV2LT5iZF9kaXNrKTsKK30KKwogc3RydWN0IG52bWV0X2NxIHsKIAl1MTYJCQlxaWQ7CiAJ dTE2CQkJc2l6ZTsKQEAgLTEzNCw2ICsxMzksOCBAQCBzdHJ1Y3QgbnZtZXRfcG9ydCB7CiAJdm9p ZAkJCQkqcHJpdjsKIAlib29sCQkJCWVuYWJsZWQ7CiAJaW50CQkJCWlubGluZV9kYXRhX3NpemU7 CisJYm9vbAkJCQl1c2VfcDJwbWVtOworCXN0cnVjdCBwY2lfZGV2CQkJKnAycF9kZXY7CiB9Owog CiBzdGF0aWMgaW5saW5lIHN0cnVjdCBudm1ldF9wb3J0ICp0b19udm1ldF9wb3J0KHN0cnVjdCBj b25maWdfaXRlbSAqaXRlbSkKQEAgLTE4Miw2ICsxODksOSBAQCBzdHJ1Y3QgbnZtZXRfY3RybCB7 CiAJX19sZTMyCQkJKmNoYW5nZWRfbnNfbGlzdDsKIAl1MzIJCQlucl9jaGFuZ2VkX25zOwogCisJ c3RydWN0IHBjaV9kZXYJCSpwMnBfZGV2OworCXN0cnVjdCBsaXN0X2hlYWQJcDJwX2NsaWVudHM7 CisKIAljaGFyCQkJc3Vic3lzbnFuW05WTUZfTlFOX0ZJRUxEX0xFTl07CiAJY2hhcgkJCWhvc3Ru cW5bTlZNRl9OUU5fRklFTERfTEVOXTsKIH07CkBAIC0yOTQsNiArMzA0LDkgQEAgc3RydWN0IG52 bWV0X3JlcSB7CiAKIAl2b2lkICgqZXhlY3V0ZSkoc3RydWN0IG52bWV0X3JlcSAqcmVxKTsKIAlj b25zdCBzdHJ1Y3QgbnZtZXRfZmFicmljc19vcHMgKm9wczsKKworCXN0cnVjdCBwY2lfZGV2ICpw MnBfZGV2OworCXN0cnVjdCBkZXZpY2UgKnAycF9jbGllbnQ7CiB9OwogCiBleHRlcm4gc3RydWN0 IHdvcmtxdWV1ZV9zdHJ1Y3QgKmJ1ZmZlcmVkX2lvX3dxOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9u dm1lL3RhcmdldC9yZG1hLmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0L3JkbWEuYwppbmRleCBiMGQw Y2VkYzc0YmIuLmU1ZjAwNDQ5YWM2OCAxMDA2NDQKLS0tIGEvZHJpdmVycy9udm1lL3RhcmdldC9y ZG1hLmMKKysrIGIvZHJpdmVycy9udm1lL3RhcmdldC9yZG1hLmMKQEAgLTc0OSw2ICs3NDksOCBA QCBzdGF0aWMgdm9pZCBudm1ldF9yZG1hX2hhbmRsZV9jb21tYW5kKHN0cnVjdCBudm1ldF9yZG1h X3F1ZXVlICpxdWV1ZSwKIAkJY21kLT5zZW5kX3NnZS5hZGRyLCBjbWQtPnNlbmRfc2dlLmxlbmd0 aCwKIAkJRE1BX1RPX0RFVklDRSk7CiAKKwljbWQtPnJlcS5wMnBfY2xpZW50ID0gJnF1ZXVlLT5k ZXYtPmRldmljZS0+ZGV2OworCiAJaWYgKCFudm1ldF9yZXFfaW5pdCgmY21kLT5yZXEsICZxdWV1 ZS0+bnZtZV9jcSwKIAkJCSZxdWV1ZS0+bnZtZV9zcSwgJm52bWV0X3JkbWFfb3BzKSkKIAkJcmV0 dXJuOwotLSAKMi4xOS4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpMaW51eC1udmRpbW0gbWFpbGluZyBsaXN0CkxpbnV4LW52ZGltbUBsaXN0cy4wMS5v cmcKaHR0cHM6Ly9saXN0cy4wMS5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1udmRpbW0K From mboxrd@z Thu Jan 1 00:00:00 1970 From: logang@deltatee.com (Logan Gunthorpe) Date: Thu, 27 Sep 2018 10:54:20 -0600 Subject: [PATCH v8 13/13] nvmet: Optionally use PCI P2P memory In-Reply-To: <20180927165420.5290-1-logang@deltatee.com> References: <20180927165420.5290-1-logang@deltatee.com> Message-ID: <20180927165420.5290-14-logang@deltatee.com> We create a configfs attribute in each nvme-fabrics target port to enable p2p memory use. When enabled, the port will only then use the p2p memory if a p2p memory device can be found which is behind the same switch hierarchy as the RDMA port and all the block devices in use. If the user enabled it and no devices are found, then the system will silently fall back on using regular memory. If appropriate, that port will allocate memory for the RDMA buffers for queues from the p2pmem device falling back to system memory should anything fail. Ideally, we'd want to use an NVME CMB buffer as p2p memory. This would save an extra PCI transfer as the NVME card could just take the data out of it's own memory. However, at this time, only a limited number of cards with CMB buffers seem to be available. Signed-off-by: Stephen Bates Signed-off-by: Steve Wise [hch: partial rewrite of the initial code] Signed-off-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe --- drivers/nvme/target/configfs.c | 36 ++++++++ drivers/nvme/target/core.c | 138 +++++++++++++++++++++++++++++- drivers/nvme/target/io-cmd-bdev.c | 3 + drivers/nvme/target/nvmet.h | 13 +++ drivers/nvme/target/rdma.c | 2 + 5 files changed, 191 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index b37a8e3e3f80..0dfb0e0c3d21 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "nvmet.h" @@ -1094,6 +1096,37 @@ static void nvmet_port_release(struct config_item *item) kfree(port); } +#ifdef CONFIG_PCI_P2PDMA +static ssize_t nvmet_p2pmem_show(struct config_item *item, char *page) +{ + struct nvmet_port *port = to_nvmet_port(item); + + return pci_p2pdma_enable_show(page, port->p2p_dev, port->use_p2pmem); +} + +static ssize_t nvmet_p2pmem_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_port *port = to_nvmet_port(item); + struct pci_dev *p2p_dev = NULL; + bool use_p2pmem; + int error; + + error = pci_p2pdma_enable_store(page, &p2p_dev, &use_p2pmem); + if (error) + return error; + + down_write(&nvmet_config_sem); + port->use_p2pmem = use_p2pmem; + pci_dev_put(port->p2p_dev); + port->p2p_dev = p2p_dev; + up_write(&nvmet_config_sem); + + return count; +} +CONFIGFS_ATTR(nvmet_, p2pmem); +#endif /* CONFIG_PCI_P2PDMA */ + static struct configfs_attribute *nvmet_port_attrs[] = { &nvmet_attr_addr_adrfam, &nvmet_attr_addr_treq, @@ -1101,6 +1134,9 @@ static struct configfs_attribute *nvmet_port_attrs[] = { &nvmet_attr_addr_trsvcid, &nvmet_attr_addr_trtype, &nvmet_attr_param_inline_data_size, +#ifdef CONFIG_PCI_P2PDMA + &nvmet_attr_p2pmem, +#endif NULL, }; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index bddd1599b826..7ade16cb4ed3 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "nvmet.h" @@ -365,9 +366,29 @@ static void nvmet_ns_dev_disable(struct nvmet_ns *ns) nvmet_file_ns_disable(ns); } +static int nvmet_p2pdma_add_client(struct nvmet_ctrl *ctrl, + struct nvmet_ns *ns) +{ + int ret; + + if (!blk_queue_pci_p2pdma(ns->bdev->bd_queue)) { + pr_err("peer-to-peer DMA is not supported by %s\n", + ns->device_path); + return -EINVAL; + } + + ret = pci_p2pdma_add_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); + if (ret) + pr_err("failed to add peer-to-peer DMA client %s: %d\n", + ns->device_path, ret); + + return ret; +} + int nvmet_ns_enable(struct nvmet_ns *ns) { struct nvmet_subsys *subsys = ns->subsys; + struct nvmet_ctrl *ctrl; int ret; mutex_lock(&subsys->lock); @@ -389,6 +410,14 @@ int nvmet_ns_enable(struct nvmet_ns *ns) if (ret) goto out_dev_put; + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + if (ctrl->p2p_dev) { + ret = nvmet_p2pdma_add_client(ctrl, ns); + if (ret) + goto out_remove_clients; + } + } + if (ns->nsid > subsys->max_nsid) subsys->max_nsid = ns->nsid; @@ -417,6 +446,9 @@ int nvmet_ns_enable(struct nvmet_ns *ns) out_unlock: mutex_unlock(&subsys->lock); return ret; +out_remove_clients: + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) + pci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); out_dev_put: nvmet_ns_dev_disable(ns); goto out_unlock; @@ -425,6 +457,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns) void nvmet_ns_disable(struct nvmet_ns *ns) { struct nvmet_subsys *subsys = ns->subsys; + struct nvmet_ctrl *ctrl; mutex_lock(&subsys->lock); if (!ns->enabled) @@ -450,6 +483,12 @@ void nvmet_ns_disable(struct nvmet_ns *ns) percpu_ref_exit(&ns->ref); mutex_lock(&subsys->lock); + + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + pci_p2pdma_remove_client(&ctrl->p2p_clients, nvmet_ns_dev(ns)); + nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0); + } + subsys->nr_namespaces--; nvmet_ns_changed(subsys, ns->nsid); nvmet_ns_dev_disable(ns); @@ -727,6 +766,23 @@ EXPORT_SYMBOL_GPL(nvmet_req_execute); int nvmet_req_alloc_sgl(struct nvmet_req *req, struct nvmet_sq *sq) { + struct pci_dev *p2p_dev = NULL; + + if (IS_ENABLED(CONFIG_PCI_P2PDMA)) { + if (sq->ctrl) + p2p_dev = sq->ctrl->p2p_dev; + + req->p2p_dev = NULL; + if (sq->qid && p2p_dev) { + req->sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->sg_cnt, + req->transfer_len); + if (req->sg) { + req->p2p_dev = p2p_dev; + return 0; + } + } + } + req->sg = sgl_alloc(req->transfer_len, GFP_KERNEL, &req->sg_cnt); if (!req->sg) return -ENOMEM; @@ -737,7 +793,11 @@ EXPORT_SYMBOL_GPL(nvmet_req_alloc_sgl); void nvmet_req_free_sgl(struct nvmet_req *req) { - sgl_free(req->sg); + if (req->p2p_dev) + pci_p2pmem_free_sgl(req->p2p_dev, req->sg); + else + sgl_free(req->sg); + req->sg = NULL; req->sg_cnt = 0; } @@ -939,6 +999,79 @@ bool nvmet_host_allowed(struct nvmet_req *req, struct nvmet_subsys *subsys, return __nvmet_host_allowed(subsys, hostnqn); } +/* + * If allow_p2pmem is set, we will try to use P2P memory for the SGL lists for + * ?/O commands. This requires the PCI p2p device to be compatible with the + * backing device for every namespace on this controller. + */ +static void nvmet_setup_p2pmem(struct nvmet_ctrl *ctrl, struct nvmet_req *req) +{ + struct nvmet_ns *ns; + int ret; + + if (!req->port->use_p2pmem || !req->p2p_client) + return; + + mutex_lock(&ctrl->subsys->lock); + + ret = pci_p2pdma_add_client(&ctrl->p2p_clients, req->p2p_client); + if (ret) { + pr_err("failed adding peer-to-peer DMA client %s: %d\n", + dev_name(req->p2p_client), ret); + goto free_devices; + } + + list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link) { + ret = nvmet_p2pdma_add_client(ctrl, ns); + if (ret) + goto free_devices; + } + + if (req->port->p2p_dev) { + /* A specific P2P device was selected in configfs */ + if (!pci_p2pdma_assign_provider(req->port->p2p_dev, + &ctrl->p2p_clients)) { + pr_info("peer-to-peer memory on %s is not supported\n", + pci_name(req->port->p2p_dev)); + goto free_devices; + } + ctrl->p2p_dev = pci_dev_get(req->port->p2p_dev); + } else { + /* + * No P2P device was provided in configfs, therefore find one + * automatically. + */ + ctrl->p2p_dev = pci_p2pmem_find(&ctrl->p2p_clients); + if (!ctrl->p2p_dev) { + pr_info("no supported peer-to-peer memory devices found\n"); + goto free_devices; + } + } + + mutex_unlock(&ctrl->subsys->lock); + + pr_info("using peer-to-peer memory on %s\n", pci_name(ctrl->p2p_dev)); + return; + +free_devices: + pci_p2pdma_client_list_free(&ctrl->p2p_clients); + mutex_unlock(&ctrl->subsys->lock); +} + +static void nvmet_release_p2pmem(struct nvmet_ctrl *ctrl) +{ + if (!ctrl->p2p_dev) + return; + + mutex_lock(&ctrl->subsys->lock); + + pci_p2pdma_client_list_free(&ctrl->p2p_clients); + pci_dev_put(ctrl->p2p_dev); + ctrl->p2p_dev = NULL; + + mutex_unlock(&ctrl->subsys->lock); +} + u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp) { @@ -980,6 +1113,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); + INIT_LIST_HEAD(&ctrl->p2p_clients); memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE); memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE); @@ -1041,6 +1175,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, ctrl->kato = DIV_ROUND_UP(kato, 1000); } nvmet_start_keep_alive_timer(ctrl); + nvmet_setup_p2pmem(ctrl, req); mutex_lock(&subsys->lock); list_add_tail(&ctrl->subsys_entry, &subsys->ctrls); @@ -1079,6 +1214,7 @@ static void nvmet_ctrl_free(struct kref *ref) flush_work(&ctrl->async_event_work); cancel_work_sync(&ctrl->fatal_err_work); + nvmet_release_p2pmem(ctrl); ida_simple_remove(&cntlid_ida, ctrl->cntlid); kfree(ctrl->sqs); diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 7bc9f6240432..5660dd7ca755 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -78,6 +78,9 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req) op = REQ_OP_READ; } + if (is_pci_p2pdma_page(sg_page(req->sg))) + op_flags |= REQ_NOMERGE; + sector = le64_to_cpu(req->cmd->rw.slba); sector <<= (req->ns->blksize_shift - 9); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 7d6cb61021e4..297861064dd8 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -84,6 +84,11 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item) return container_of(to_config_group(item), struct nvmet_ns, group); } +static inline struct device *nvmet_ns_dev(struct nvmet_ns *ns) +{ + return disk_to_dev(ns->bdev->bd_disk); +} + struct nvmet_cq { u16 qid; u16 size; @@ -134,6 +139,8 @@ struct nvmet_port { void *priv; bool enabled; int inline_data_size; + bool use_p2pmem; + struct pci_dev *p2p_dev; }; static inline struct nvmet_port *to_nvmet_port(struct config_item *item) @@ -182,6 +189,9 @@ struct nvmet_ctrl { __le32 *changed_ns_list; u32 nr_changed_ns; + struct pci_dev *p2p_dev; + struct list_head p2p_clients; + char subsysnqn[NVMF_NQN_FIELD_LEN]; char hostnqn[NVMF_NQN_FIELD_LEN]; }; @@ -294,6 +304,9 @@ struct nvmet_req { void (*execute)(struct nvmet_req *req); const struct nvmet_fabrics_ops *ops; + + struct pci_dev *p2p_dev; + struct device *p2p_client; }; extern struct workqueue_struct *buffered_io_wq; diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index b0d0cedc74bb..e5f00449ac68 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -749,6 +749,8 @@ static void nvmet_rdma_handle_command(struct nvmet_rdma_queue *queue, cmd->send_sge.addr, cmd->send_sge.length, DMA_TO_DEVICE); + cmd->req.p2p_client = &queue->dev->device->dev; + if (!nvmet_req_init(&cmd->req, &queue->nvme_cq, &queue->nvme_sq, &nvmet_rdma_ops)) return; -- 2.19.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Logan Gunthorpe Subject: [PATCH v8 13/13] nvmet: Optionally use PCI P2P memory Date: Thu, 27 Sep 2018 10:54:20 -0600 Message-ID: <20180927165420.5290-14-logang@deltatee.com> References: <20180927165420.5290-1-logang@deltatee.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180927165420.5290-1-logang-OTvnGxWRz7hWk0Htik3J/w@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces-hn68Rpc1hR1g9hUCZPvPmw@public.gmane.org Sender: "Linux-nvdimm" To: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-nvme-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw@public.gmane.org, linux-block-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: Jens Axboe , =?UTF-8?q?Christian=20K=C3=B6nig?= , Benjamin Herrenschmidt , Steve Wise , Alex Williamson , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Jason Gunthorpe , Bjorn Helgaas , Max Gurtovoy , Christoph Hellwig List-Id: linux-rdma@vger.kernel.org V2UgY3JlYXRlIGEgY29uZmlnZnMgYXR0cmlidXRlIGluIGVhY2ggbnZtZS1mYWJyaWNzIHRhcmdl dCBwb3J0IHRvCmVuYWJsZSBwMnAgbWVtb3J5IHVzZS4gV2hlbiBlbmFibGVkLCB0aGUgcG9ydCB3 aWxsIG9ubHkgdGhlbiB1c2UgdGhlCnAycCBtZW1vcnkgaWYgYSBwMnAgbWVtb3J5IGRldmljZSBj YW4gYmUgZm91bmQgd2hpY2ggaXMgYmVoaW5kIHRoZQpzYW1lIHN3aXRjaCBoaWVyYXJjaHkgYXMg dGhlIFJETUEgcG9ydCBhbmQgYWxsIHRoZSBibG9jayBkZXZpY2VzIGluCnVzZS4gSWYgdGhlIHVz ZXIgZW5hYmxlZCBpdCBhbmQgbm8gZGV2aWNlcyBhcmUgZm91bmQsIHRoZW4gdGhlIHN5c3RlbQp3 aWxsIHNpbGVudGx5IGZhbGwgYmFjayBvbiB1c2luZyByZWd1bGFyIG1lbW9yeS4KCklmIGFwcHJv cHJpYXRlLCB0aGF0IHBvcnQgd2lsbCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBSRE1BIGJ1ZmZl cnMKZm9yIHF1ZXVlcyBmcm9tIHRoZSBwMnBtZW0gZGV2aWNlIGZhbGxpbmcgYmFjayB0byBzeXN0 ZW0gbWVtb3J5IHNob3VsZAphbnl0aGluZyBmYWlsLgoKSWRlYWxseSwgd2UnZCB3YW50IHRvIHVz ZSBhbiBOVk1FIENNQiBidWZmZXIgYXMgcDJwIG1lbW9yeS4gVGhpcyB3b3VsZApzYXZlIGFuIGV4 dHJhIFBDSSB0cmFuc2ZlciBhcyB0aGUgTlZNRSBjYXJkIGNvdWxkIGp1c3QgdGFrZSB0aGUgZGF0 YQpvdXQgb2YgaXQncyBvd24gbWVtb3J5LiBIb3dldmVyLCBhdCB0aGlzIHRpbWUsIG9ubHkgYSBs aW1pdGVkIG51bWJlcgpvZiBjYXJkcyB3aXRoIENNQiBidWZmZXJzIHNlZW0gdG8gYmUgYXZhaWxh YmxlLgoKU2lnbmVkLW9mZi1ieTogU3RlcGhlbiBCYXRlcyA8c2JhdGVzQHJhaXRobGluLmNvbT4K U2lnbmVkLW9mZi1ieTogU3RldmUgV2lzZSA8c3dpc2VAb3BlbmdyaWRjb21wdXRpbmcuY29tPgpb aGNoOiBwYXJ0aWFsIHJld3JpdGUgb2YgdGhlIGluaXRpYWwgY29kZV0KU2lnbmVkLW9mZi1ieTog Q2hyaXN0b3BoIEhlbGx3aWcgPGhjaEBsc3QuZGU+ClNpZ25lZC1vZmYtYnk6IExvZ2FuIEd1bnRo b3JwZSA8bG9nYW5nQGRlbHRhdGVlLmNvbT4KLS0tCiBkcml2ZXJzL252bWUvdGFyZ2V0L2NvbmZp Z2ZzLmMgICAgfCAgMzYgKysrKysrKysKIGRyaXZlcnMvbnZtZS90YXJnZXQvY29yZS5jICAgICAg ICB8IDEzOCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0KIGRyaXZlcnMvbnZtZS90YXJn ZXQvaW8tY21kLWJkZXYuYyB8ICAgMyArCiBkcml2ZXJzL252bWUvdGFyZ2V0L252bWV0LmggICAg ICAgfCAgMTMgKysrCiBkcml2ZXJzL252bWUvdGFyZ2V0L3JkbWEuYyAgICAgICAgfCAgIDIgKwog NSBmaWxlcyBjaGFuZ2VkLCAxOTEgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQoKZGlmZiAt LWdpdCBhL2RyaXZlcnMvbnZtZS90YXJnZXQvY29uZmlnZnMuYyBiL2RyaXZlcnMvbnZtZS90YXJn ZXQvY29uZmlnZnMuYwppbmRleCBiMzdhOGUzZTNmODAuLjBkZmIwZTBjM2QyMSAxMDA2NDQKLS0t IGEvZHJpdmVycy9udm1lL3RhcmdldC9jb25maWdmcy5jCisrKyBiL2RyaXZlcnMvbnZtZS90YXJn ZXQvY29uZmlnZnMuYwpAQCAtMTcsNiArMTcsOCBAQAogI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4K ICNpbmNsdWRlIDxsaW51eC9zdGF0Lmg+CiAjaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KKyNpbmNs dWRlIDxsaW51eC9wY2kuaD4KKyNpbmNsdWRlIDxsaW51eC9wY2ktcDJwZG1hLmg+CiAKICNpbmNs dWRlICJudm1ldC5oIgogCkBAIC0xMDk0LDYgKzEwOTYsMzcgQEAgc3RhdGljIHZvaWQgbnZtZXRf cG9ydF9yZWxlYXNlKHN0cnVjdCBjb25maWdfaXRlbSAqaXRlbSkKIAlrZnJlZShwb3J0KTsKIH0K IAorI2lmZGVmIENPTkZJR19QQ0lfUDJQRE1BCitzdGF0aWMgc3NpemVfdCBudm1ldF9wMnBtZW1f c2hvdyhzdHJ1Y3QgY29uZmlnX2l0ZW0gKml0ZW0sIGNoYXIgKnBhZ2UpCit7CisJc3RydWN0IG52 bWV0X3BvcnQgKnBvcnQgPSB0b19udm1ldF9wb3J0KGl0ZW0pOworCisJcmV0dXJuIHBjaV9wMnBk bWFfZW5hYmxlX3Nob3cocGFnZSwgcG9ydC0+cDJwX2RldiwgcG9ydC0+dXNlX3AycG1lbSk7Cit9 CisKK3N0YXRpYyBzc2l6ZV90IG52bWV0X3AycG1lbV9zdG9yZShzdHJ1Y3QgY29uZmlnX2l0ZW0g Kml0ZW0sCisJCWNvbnN0IGNoYXIgKnBhZ2UsIHNpemVfdCBjb3VudCkKK3sKKwlzdHJ1Y3QgbnZt ZXRfcG9ydCAqcG9ydCA9IHRvX252bWV0X3BvcnQoaXRlbSk7CisJc3RydWN0IHBjaV9kZXYgKnAy cF9kZXYgPSBOVUxMOworCWJvb2wgdXNlX3AycG1lbTsKKwlpbnQgZXJyb3I7CisKKwllcnJvciA9 IHBjaV9wMnBkbWFfZW5hYmxlX3N0b3JlKHBhZ2UsICZwMnBfZGV2LCAmdXNlX3AycG1lbSk7CisJ aWYgKGVycm9yKQorCQlyZXR1cm4gZXJyb3I7CisKKwlkb3duX3dyaXRlKCZudm1ldF9jb25maWdf c2VtKTsKKwlwb3J0LT51c2VfcDJwbWVtID0gdXNlX3AycG1lbTsKKwlwY2lfZGV2X3B1dChwb3J0 LT5wMnBfZGV2KTsKKwlwb3J0LT5wMnBfZGV2ID0gcDJwX2RldjsKKwl1cF93cml0ZSgmbnZtZXRf Y29uZmlnX3NlbSk7CisKKwlyZXR1cm4gY291bnQ7Cit9CitDT05GSUdGU19BVFRSKG52bWV0Xywg cDJwbWVtKTsKKyNlbmRpZiAvKiBDT05GSUdfUENJX1AyUERNQSAqLworCiBzdGF0aWMgc3RydWN0 IGNvbmZpZ2ZzX2F0dHJpYnV0ZSAqbnZtZXRfcG9ydF9hdHRyc1tdID0gewogCSZudm1ldF9hdHRy X2FkZHJfYWRyZmFtLAogCSZudm1ldF9hdHRyX2FkZHJfdHJlcSwKQEAgLTExMDEsNiArMTEzNCw5 IEBAIHN0YXRpYyBzdHJ1Y3QgY29uZmlnZnNfYXR0cmlidXRlICpudm1ldF9wb3J0X2F0dHJzW10g PSB7CiAJJm52bWV0X2F0dHJfYWRkcl90cnN2Y2lkLAogCSZudm1ldF9hdHRyX2FkZHJfdHJ0eXBl LAogCSZudm1ldF9hdHRyX3BhcmFtX2lubGluZV9kYXRhX3NpemUsCisjaWZkZWYgQ09ORklHX1BD SV9QMlBETUEKKwkmbnZtZXRfYXR0cl9wMnBtZW0sCisjZW5kaWYKIAlOVUxMLAogfTsKIApkaWZm IC0tZ2l0IGEvZHJpdmVycy9udm1lL3RhcmdldC9jb3JlLmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0 L2NvcmUuYwppbmRleCBiZGRkMTU5OWI4MjYuLjdhZGUxNmNiNGVkMyAxMDA2NDQKLS0tIGEvZHJp dmVycy9udm1lL3RhcmdldC9jb3JlLmMKKysrIGIvZHJpdmVycy9udm1lL3RhcmdldC9jb3JlLmMK QEAgLTE1LDYgKzE1LDcgQEAKICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KICNpbmNsdWRlIDxs aW51eC9yYW5kb20uaD4KICNpbmNsdWRlIDxsaW51eC9yY3VsaXN0Lmg+CisjaW5jbHVkZSA8bGlu dXgvcGNpLXAycGRtYS5oPgogCiAjaW5jbHVkZSAibnZtZXQuaCIKIApAQCAtMzY1LDkgKzM2Niwy OSBAQCBzdGF0aWMgdm9pZCBudm1ldF9uc19kZXZfZGlzYWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5z KQogCW52bWV0X2ZpbGVfbnNfZGlzYWJsZShucyk7CiB9CiAKK3N0YXRpYyBpbnQgbnZtZXRfcDJw ZG1hX2FkZF9jbGllbnQoc3RydWN0IG52bWV0X2N0cmwgKmN0cmwsCisJCXN0cnVjdCBudm1ldF9u cyAqbnMpCit7CisJaW50IHJldDsKKworCWlmICghYmxrX3F1ZXVlX3BjaV9wMnBkbWEobnMtPmJk ZXYtPmJkX3F1ZXVlKSkgeworCQlwcl9lcnIoInBlZXItdG8tcGVlciBETUEgaXMgbm90IHN1cHBv cnRlZCBieSAlc1xuIiwKKwkJICAgICAgIG5zLT5kZXZpY2VfcGF0aCk7CisJCXJldHVybiAtRUlO VkFMOworCX0KKworCXJldCA9IHBjaV9wMnBkbWFfYWRkX2NsaWVudCgmY3RybC0+cDJwX2NsaWVu dHMsIG52bWV0X25zX2RldihucykpOworCWlmIChyZXQpCisJCXByX2VycigiZmFpbGVkIHRvIGFk ZCBwZWVyLXRvLXBlZXIgRE1BIGNsaWVudCAlczogJWRcbiIsCisJCSAgICAgICBucy0+ZGV2aWNl X3BhdGgsIHJldCk7CisKKwlyZXR1cm4gcmV0OworfQorCiBpbnQgbnZtZXRfbnNfZW5hYmxlKHN0 cnVjdCBudm1ldF9ucyAqbnMpCiB7CiAJc3RydWN0IG52bWV0X3N1YnN5cyAqc3Vic3lzID0gbnMt PnN1YnN5czsKKwlzdHJ1Y3QgbnZtZXRfY3RybCAqY3RybDsKIAlpbnQgcmV0OwogCiAJbXV0ZXhf bG9jaygmc3Vic3lzLT5sb2NrKTsKQEAgLTM4OSw2ICs0MTAsMTQgQEAgaW50IG52bWV0X25zX2Vu YWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5zKQogCWlmIChyZXQpCiAJCWdvdG8gb3V0X2Rldl9wdXQ7 CiAKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KGN0cmwsICZzdWJzeXMtPmN0cmxzLCBzdWJzeXNfZW50 cnkpIHsKKwkJaWYgKGN0cmwtPnAycF9kZXYpIHsKKwkJCXJldCA9IG52bWV0X3AycGRtYV9hZGRf Y2xpZW50KGN0cmwsIG5zKTsKKwkJCWlmIChyZXQpCisJCQkJZ290byBvdXRfcmVtb3ZlX2NsaWVu dHM7CisJCX0KKwl9CisKIAlpZiAobnMtPm5zaWQgPiBzdWJzeXMtPm1heF9uc2lkKQogCQlzdWJz eXMtPm1heF9uc2lkID0gbnMtPm5zaWQ7CiAKQEAgLTQxNyw2ICs0NDYsOSBAQCBpbnQgbnZtZXRf bnNfZW5hYmxlKHN0cnVjdCBudm1ldF9ucyAqbnMpCiBvdXRfdW5sb2NrOgogCW11dGV4X3VubG9j aygmc3Vic3lzLT5sb2NrKTsKIAlyZXR1cm4gcmV0Oworb3V0X3JlbW92ZV9jbGllbnRzOgorCWxp c3RfZm9yX2VhY2hfZW50cnkoY3RybCwgJnN1YnN5cy0+Y3RybHMsIHN1YnN5c19lbnRyeSkKKwkJ cGNpX3AycGRtYV9yZW1vdmVfY2xpZW50KCZjdHJsLT5wMnBfY2xpZW50cywgbnZtZXRfbnNfZGV2 KG5zKSk7CiBvdXRfZGV2X3B1dDoKIAludm1ldF9uc19kZXZfZGlzYWJsZShucyk7CiAJZ290byBv dXRfdW5sb2NrOwpAQCAtNDI1LDYgKzQ1Nyw3IEBAIGludCBudm1ldF9uc19lbmFibGUoc3RydWN0 IG52bWV0X25zICpucykKIHZvaWQgbnZtZXRfbnNfZGlzYWJsZShzdHJ1Y3QgbnZtZXRfbnMgKm5z KQogewogCXN0cnVjdCBudm1ldF9zdWJzeXMgKnN1YnN5cyA9IG5zLT5zdWJzeXM7CisJc3RydWN0 IG52bWV0X2N0cmwgKmN0cmw7CiAKIAltdXRleF9sb2NrKCZzdWJzeXMtPmxvY2spOwogCWlmICgh bnMtPmVuYWJsZWQpCkBAIC00NTAsNiArNDgzLDEyIEBAIHZvaWQgbnZtZXRfbnNfZGlzYWJsZShz dHJ1Y3QgbnZtZXRfbnMgKm5zKQogCXBlcmNwdV9yZWZfZXhpdCgmbnMtPnJlZik7CiAKIAltdXRl eF9sb2NrKCZzdWJzeXMtPmxvY2spOworCisJbGlzdF9mb3JfZWFjaF9lbnRyeShjdHJsLCAmc3Vi c3lzLT5jdHJscywgc3Vic3lzX2VudHJ5KSB7CisJCXBjaV9wMnBkbWFfcmVtb3ZlX2NsaWVudCgm Y3RybC0+cDJwX2NsaWVudHMsIG52bWV0X25zX2RldihucykpOworCQludm1ldF9hZGRfYXN5bmNf ZXZlbnQoY3RybCwgTlZNRV9BRVJfVFlQRV9OT1RJQ0UsIDAsIDApOworCX0KKwogCXN1YnN5cy0+ bnJfbmFtZXNwYWNlcy0tOwogCW52bWV0X25zX2NoYW5nZWQoc3Vic3lzLCBucy0+bnNpZCk7CiAJ bnZtZXRfbnNfZGV2X2Rpc2FibGUobnMpOwpAQCAtNzI3LDYgKzc2NiwyMyBAQCBFWFBPUlRfU1lN Qk9MX0dQTChudm1ldF9yZXFfZXhlY3V0ZSk7CiAKIGludCBudm1ldF9yZXFfYWxsb2Nfc2dsKHN0 cnVjdCBudm1ldF9yZXEgKnJlcSwgc3RydWN0IG52bWV0X3NxICpzcSkKIHsKKwlzdHJ1Y3QgcGNp X2RldiAqcDJwX2RldiA9IE5VTEw7CisKKwlpZiAoSVNfRU5BQkxFRChDT05GSUdfUENJX1AyUERN QSkpIHsKKwkJaWYgKHNxLT5jdHJsKQorCQkJcDJwX2RldiA9IHNxLT5jdHJsLT5wMnBfZGV2Owor CisJCXJlcS0+cDJwX2RldiA9IE5VTEw7CisJCWlmIChzcS0+cWlkICYmIHAycF9kZXYpIHsKKwkJ CXJlcS0+c2cgPSBwY2lfcDJwbWVtX2FsbG9jX3NnbChwMnBfZGV2LCAmcmVxLT5zZ19jbnQsCisJ CQkJCQkgICAgICAgcmVxLT50cmFuc2Zlcl9sZW4pOworCQkJaWYgKHJlcS0+c2cpIHsKKwkJCQly ZXEtPnAycF9kZXYgPSBwMnBfZGV2OworCQkJCXJldHVybiAwOworCQkJfQorCQl9CisJfQorCiAJ cmVxLT5zZyA9IHNnbF9hbGxvYyhyZXEtPnRyYW5zZmVyX2xlbiwgR0ZQX0tFUk5FTCwgJnJlcS0+ c2dfY250KTsKIAlpZiAoIXJlcS0+c2cpCiAJCXJldHVybiAtRU5PTUVNOwpAQCAtNzM3LDcgKzc5 MywxMSBAQCBFWFBPUlRfU1lNQk9MX0dQTChudm1ldF9yZXFfYWxsb2Nfc2dsKTsKIAogdm9pZCBu dm1ldF9yZXFfZnJlZV9zZ2woc3RydWN0IG52bWV0X3JlcSAqcmVxKQogewotCXNnbF9mcmVlKHJl cS0+c2cpOworCWlmIChyZXEtPnAycF9kZXYpCisJCXBjaV9wMnBtZW1fZnJlZV9zZ2wocmVxLT5w MnBfZGV2LCByZXEtPnNnKTsKKwllbHNlCisJCXNnbF9mcmVlKHJlcS0+c2cpOworCiAJcmVxLT5z ZyA9IE5VTEw7CiAJcmVxLT5zZ19jbnQgPSAwOwogfQpAQCAtOTM5LDYgKzk5OSw3OSBAQCBib29s IG52bWV0X2hvc3RfYWxsb3dlZChzdHJ1Y3QgbnZtZXRfcmVxICpyZXEsIHN0cnVjdCBudm1ldF9z dWJzeXMgKnN1YnN5cywKIAkJcmV0dXJuIF9fbnZtZXRfaG9zdF9hbGxvd2VkKHN1YnN5cywgaG9z dG5xbik7CiB9CiAKKy8qCisgKiBJZiBhbGxvd19wMnBtZW0gaXMgc2V0LCB3ZSB3aWxsIHRyeSB0 byB1c2UgUDJQIG1lbW9yeSBmb3IgdGhlIFNHTCBsaXN0cyBmb3IKKyAqIM6ZL08gY29tbWFuZHMu IFRoaXMgcmVxdWlyZXMgdGhlIFBDSSBwMnAgZGV2aWNlIHRvIGJlIGNvbXBhdGlibGUgd2l0aCB0 aGUKKyAqIGJhY2tpbmcgZGV2aWNlIGZvciBldmVyeSBuYW1lc3BhY2Ugb24gdGhpcyBjb250cm9s bGVyLgorICovCitzdGF0aWMgdm9pZCBudm1ldF9zZXR1cF9wMnBtZW0oc3RydWN0IG52bWV0X2N0 cmwgKmN0cmwsIHN0cnVjdCBudm1ldF9yZXEgKnJlcSkKK3sKKwlzdHJ1Y3QgbnZtZXRfbnMgKm5z OworCWludCByZXQ7CisKKwlpZiAoIXJlcS0+cG9ydC0+dXNlX3AycG1lbSB8fCAhcmVxLT5wMnBf Y2xpZW50KQorCQlyZXR1cm47CisKKwltdXRleF9sb2NrKCZjdHJsLT5zdWJzeXMtPmxvY2spOwor CisJcmV0ID0gcGNpX3AycGRtYV9hZGRfY2xpZW50KCZjdHJsLT5wMnBfY2xpZW50cywgcmVxLT5w MnBfY2xpZW50KTsKKwlpZiAocmV0KSB7CisJCXByX2VycigiZmFpbGVkIGFkZGluZyBwZWVyLXRv LXBlZXIgRE1BIGNsaWVudCAlczogJWRcbiIsCisJCSAgICAgICBkZXZfbmFtZShyZXEtPnAycF9j bGllbnQpLCByZXQpOworCQlnb3RvIGZyZWVfZGV2aWNlczsKKwl9CisKKwlsaXN0X2Zvcl9lYWNo X2VudHJ5X3JjdShucywgJmN0cmwtPnN1YnN5cy0+bmFtZXNwYWNlcywgZGV2X2xpbmspIHsKKwkJ cmV0ID0gbnZtZXRfcDJwZG1hX2FkZF9jbGllbnQoY3RybCwgbnMpOworCQlpZiAocmV0KQorCQkJ Z290byBmcmVlX2RldmljZXM7CisJfQorCisJaWYgKHJlcS0+cG9ydC0+cDJwX2RldikgeworCQkv KiBBIHNwZWNpZmljIFAyUCBkZXZpY2Ugd2FzIHNlbGVjdGVkIGluIGNvbmZpZ2ZzICovCisJCWlm ICghcGNpX3AycGRtYV9hc3NpZ25fcHJvdmlkZXIocmVxLT5wb3J0LT5wMnBfZGV2LAorCQkJCQkJ JmN0cmwtPnAycF9jbGllbnRzKSkgeworCQkJcHJfaW5mbygicGVlci10by1wZWVyIG1lbW9yeSBv biAlcyBpcyBub3Qgc3VwcG9ydGVkXG4iLAorCQkJCXBjaV9uYW1lKHJlcS0+cG9ydC0+cDJwX2Rl dikpOworCQkJZ290byBmcmVlX2RldmljZXM7CisJCX0KKwkJY3RybC0+cDJwX2RldiA9IHBjaV9k ZXZfZ2V0KHJlcS0+cG9ydC0+cDJwX2Rldik7CisJfSBlbHNlIHsKKwkJLyoKKwkJICogTm8gUDJQ IGRldmljZSB3YXMgcHJvdmlkZWQgaW4gY29uZmlnZnMsIHRoZXJlZm9yZSBmaW5kIG9uZQorCQkg KiBhdXRvbWF0aWNhbGx5LgorCQkgKi8KKwkJY3RybC0+cDJwX2RldiA9IHBjaV9wMnBtZW1fZmlu ZCgmY3RybC0+cDJwX2NsaWVudHMpOworCQlpZiAoIWN0cmwtPnAycF9kZXYpIHsKKwkJCXByX2lu Zm8oIm5vIHN1cHBvcnRlZCBwZWVyLXRvLXBlZXIgbWVtb3J5IGRldmljZXMgZm91bmRcbiIpOwor CQkJZ290byBmcmVlX2RldmljZXM7CisJCX0KKwl9CisKKwltdXRleF91bmxvY2soJmN0cmwtPnN1 YnN5cy0+bG9jayk7CisKKwlwcl9pbmZvKCJ1c2luZyBwZWVyLXRvLXBlZXIgbWVtb3J5IG9uICVz XG4iLCBwY2lfbmFtZShjdHJsLT5wMnBfZGV2KSk7CisJcmV0dXJuOworCitmcmVlX2RldmljZXM6 CisJcGNpX3AycGRtYV9jbGllbnRfbGlzdF9mcmVlKCZjdHJsLT5wMnBfY2xpZW50cyk7CisJbXV0 ZXhfdW5sb2NrKCZjdHJsLT5zdWJzeXMtPmxvY2spOworfQorCitzdGF0aWMgdm9pZCBudm1ldF9y ZWxlYXNlX3AycG1lbShzdHJ1Y3QgbnZtZXRfY3RybCAqY3RybCkKK3sKKwlpZiAoIWN0cmwtPnAy cF9kZXYpCisJCXJldHVybjsKKworCW11dGV4X2xvY2soJmN0cmwtPnN1YnN5cy0+bG9jayk7CisK KwlwY2lfcDJwZG1hX2NsaWVudF9saXN0X2ZyZWUoJmN0cmwtPnAycF9jbGllbnRzKTsKKwlwY2lf ZGV2X3B1dChjdHJsLT5wMnBfZGV2KTsKKwljdHJsLT5wMnBfZGV2ID0gTlVMTDsKKworCW11dGV4 X3VubG9jaygmY3RybC0+c3Vic3lzLT5sb2NrKTsKK30KKwogdTE2IG52bWV0X2FsbG9jX2N0cmwo Y29uc3QgY2hhciAqc3Vic3lzbnFuLCBjb25zdCBjaGFyICpob3N0bnFuLAogCQlzdHJ1Y3QgbnZt ZXRfcmVxICpyZXEsIHUzMiBrYXRvLCBzdHJ1Y3QgbnZtZXRfY3RybCAqKmN0cmxwKQogewpAQCAt OTgwLDYgKzExMTMsNyBAQCB1MTYgbnZtZXRfYWxsb2NfY3RybChjb25zdCBjaGFyICpzdWJzeXNu cW4sIGNvbnN0IGNoYXIgKmhvc3RucW4sCiAKIAlJTklUX1dPUksoJmN0cmwtPmFzeW5jX2V2ZW50 X3dvcmssIG52bWV0X2FzeW5jX2V2ZW50X3dvcmspOwogCUlOSVRfTElTVF9IRUFEKCZjdHJsLT5h c3luY19ldmVudHMpOworCUlOSVRfTElTVF9IRUFEKCZjdHJsLT5wMnBfY2xpZW50cyk7CiAKIAlt ZW1jcHkoY3RybC0+c3Vic3lzbnFuLCBzdWJzeXNucW4sIE5WTUZfTlFOX1NJWkUpOwogCW1lbWNw eShjdHJsLT5ob3N0bnFuLCBob3N0bnFuLCBOVk1GX05RTl9TSVpFKTsKQEAgLTEwNDEsNiArMTE3 NSw3IEBAIHUxNiBudm1ldF9hbGxvY19jdHJsKGNvbnN0IGNoYXIgKnN1YnN5c25xbiwgY29uc3Qg Y2hhciAqaG9zdG5xbiwKIAkJY3RybC0+a2F0byA9IERJVl9ST1VORF9VUChrYXRvLCAxMDAwKTsK IAl9CiAJbnZtZXRfc3RhcnRfa2VlcF9hbGl2ZV90aW1lcihjdHJsKTsKKwludm1ldF9zZXR1cF9w MnBtZW0oY3RybCwgcmVxKTsKIAogCW11dGV4X2xvY2soJnN1YnN5cy0+bG9jayk7CiAJbGlzdF9h ZGRfdGFpbCgmY3RybC0+c3Vic3lzX2VudHJ5LCAmc3Vic3lzLT5jdHJscyk7CkBAIC0xMDc5LDYg KzEyMTQsNyBAQCBzdGF0aWMgdm9pZCBudm1ldF9jdHJsX2ZyZWUoc3RydWN0IGtyZWYgKnJlZikK IAlmbHVzaF93b3JrKCZjdHJsLT5hc3luY19ldmVudF93b3JrKTsKIAljYW5jZWxfd29ya19zeW5j KCZjdHJsLT5mYXRhbF9lcnJfd29yayk7CiAKKwludm1ldF9yZWxlYXNlX3AycG1lbShjdHJsKTsK IAlpZGFfc2ltcGxlX3JlbW92ZSgmY250bGlkX2lkYSwgY3RybC0+Y250bGlkKTsKIAogCWtmcmVl KGN0cmwtPnNxcyk7CmRpZmYgLS1naXQgYS9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2 LmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2LmMKaW5kZXggN2JjOWY2MjQwNDMy Li41NjYwZGQ3Y2E3NTUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvbnZtZS90YXJnZXQvaW8tY21kLWJk ZXYuYworKysgYi9kcml2ZXJzL252bWUvdGFyZ2V0L2lvLWNtZC1iZGV2LmMKQEAgLTc4LDYgKzc4 LDkgQEAgc3RhdGljIHZvaWQgbnZtZXRfYmRldl9leGVjdXRlX3J3KHN0cnVjdCBudm1ldF9yZXEg KnJlcSkKIAkJb3AgPSBSRVFfT1BfUkVBRDsKIAl9CiAKKwlpZiAoaXNfcGNpX3AycGRtYV9wYWdl KHNnX3BhZ2UocmVxLT5zZykpKQorCQlvcF9mbGFncyB8PSBSRVFfTk9NRVJHRTsKKwogCXNlY3Rv ciA9IGxlNjRfdG9fY3B1KHJlcS0+Y21kLT5ydy5zbGJhKTsKIAlzZWN0b3IgPDw9IChyZXEtPm5z LT5ibGtzaXplX3NoaWZ0IC0gOSk7CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvbnZtZS90YXJnZXQv bnZtZXQuaCBiL2RyaXZlcnMvbnZtZS90YXJnZXQvbnZtZXQuaAppbmRleCA3ZDZjYjYxMDIxZTQu LjI5Nzg2MTA2NGRkOCAxMDA2NDQKLS0tIGEvZHJpdmVycy9udm1lL3RhcmdldC9udm1ldC5oCisr KyBiL2RyaXZlcnMvbnZtZS90YXJnZXQvbnZtZXQuaApAQCAtODQsNiArODQsMTEgQEAgc3RhdGlj IGlubGluZSBzdHJ1Y3QgbnZtZXRfbnMgKnRvX252bWV0X25zKHN0cnVjdCBjb25maWdfaXRlbSAq aXRlbSkKIAlyZXR1cm4gY29udGFpbmVyX29mKHRvX2NvbmZpZ19ncm91cChpdGVtKSwgc3RydWN0 IG52bWV0X25zLCBncm91cCk7CiB9CiAKK3N0YXRpYyBpbmxpbmUgc3RydWN0IGRldmljZSAqbnZt ZXRfbnNfZGV2KHN0cnVjdCBudm1ldF9ucyAqbnMpCit7CisJcmV0dXJuIGRpc2tfdG9fZGV2KG5z LT5iZGV2LT5iZF9kaXNrKTsKK30KKwogc3RydWN0IG52bWV0X2NxIHsKIAl1MTYJCQlxaWQ7CiAJ dTE2CQkJc2l6ZTsKQEAgLTEzNCw2ICsxMzksOCBAQCBzdHJ1Y3QgbnZtZXRfcG9ydCB7CiAJdm9p ZAkJCQkqcHJpdjsKIAlib29sCQkJCWVuYWJsZWQ7CiAJaW50CQkJCWlubGluZV9kYXRhX3NpemU7 CisJYm9vbAkJCQl1c2VfcDJwbWVtOworCXN0cnVjdCBwY2lfZGV2CQkJKnAycF9kZXY7CiB9Owog CiBzdGF0aWMgaW5saW5lIHN0cnVjdCBudm1ldF9wb3J0ICp0b19udm1ldF9wb3J0KHN0cnVjdCBj b25maWdfaXRlbSAqaXRlbSkKQEAgLTE4Miw2ICsxODksOSBAQCBzdHJ1Y3QgbnZtZXRfY3RybCB7 CiAJX19sZTMyCQkJKmNoYW5nZWRfbnNfbGlzdDsKIAl1MzIJCQlucl9jaGFuZ2VkX25zOwogCisJ c3RydWN0IHBjaV9kZXYJCSpwMnBfZGV2OworCXN0cnVjdCBsaXN0X2hlYWQJcDJwX2NsaWVudHM7 CisKIAljaGFyCQkJc3Vic3lzbnFuW05WTUZfTlFOX0ZJRUxEX0xFTl07CiAJY2hhcgkJCWhvc3Ru cW5bTlZNRl9OUU5fRklFTERfTEVOXTsKIH07CkBAIC0yOTQsNiArMzA0LDkgQEAgc3RydWN0IG52 bWV0X3JlcSB7CiAKIAl2b2lkICgqZXhlY3V0ZSkoc3RydWN0IG52bWV0X3JlcSAqcmVxKTsKIAlj b25zdCBzdHJ1Y3QgbnZtZXRfZmFicmljc19vcHMgKm9wczsKKworCXN0cnVjdCBwY2lfZGV2ICpw MnBfZGV2OworCXN0cnVjdCBkZXZpY2UgKnAycF9jbGllbnQ7CiB9OwogCiBleHRlcm4gc3RydWN0 IHdvcmtxdWV1ZV9zdHJ1Y3QgKmJ1ZmZlcmVkX2lvX3dxOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9u dm1lL3RhcmdldC9yZG1hLmMgYi9kcml2ZXJzL252bWUvdGFyZ2V0L3JkbWEuYwppbmRleCBiMGQw Y2VkYzc0YmIuLmU1ZjAwNDQ5YWM2OCAxMDA2NDQKLS0tIGEvZHJpdmVycy9udm1lL3RhcmdldC9y ZG1hLmMKKysrIGIvZHJpdmVycy9udm1lL3RhcmdldC9yZG1hLmMKQEAgLTc0OSw2ICs3NDksOCBA QCBzdGF0aWMgdm9pZCBudm1ldF9yZG1hX2hhbmRsZV9jb21tYW5kKHN0cnVjdCBudm1ldF9yZG1h X3F1ZXVlICpxdWV1ZSwKIAkJY21kLT5zZW5kX3NnZS5hZGRyLCBjbWQtPnNlbmRfc2dlLmxlbmd0 aCwKIAkJRE1BX1RPX0RFVklDRSk7CiAKKwljbWQtPnJlcS5wMnBfY2xpZW50ID0gJnF1ZXVlLT5k ZXYtPmRldmljZS0+ZGV2OworCiAJaWYgKCFudm1ldF9yZXFfaW5pdCgmY21kLT5yZXEsICZxdWV1 ZS0+bnZtZV9jcSwKIAkJCSZxdWV1ZS0+bnZtZV9zcSwgJm52bWV0X3JkbWFfb3BzKSkKIAkJcmV0 dXJuOwotLSAKMi4xOS4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpMaW51eC1udmRpbW0gbWFpbGluZyBsaXN0CkxpbnV4LW52ZGltbUBsaXN0cy4wMS5v cmcKaHR0cHM6Ly9saXN0cy4wMS5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1udmRpbW0K