From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751924AbdIOXB7 (ORCPT ); Fri, 15 Sep 2017 19:01:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:37066 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751610AbdIOXAp (ORCPT ); Fri, 15 Sep 2017 19:00:45 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3EFB622A7E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=sstabellini@kernel.org From: Stefano Stabellini To: xen-devel@lists.xen.org Cc: linux-kernel@vger.kernel.org, sstabellini@kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, Stefano Stabellini Subject: [PATCH v4 08/13] xen/pvcalls: implement accept command Date: Fri, 15 Sep 2017 16:00:35 -0700 Message-Id: <1505516440-11111-8-git-send-email-sstabellini@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1505516440-11111-1-git-send-email-sstabellini@kernel.org> References: <1505516440-11111-1-git-send-email-sstabellini@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Introduce a waitqueue to allow only one outstanding accept command at any given time and to implement polling on the passive socket. Introduce a flags field to keep track of in-flight accept and poll commands. Send PVCALLS_ACCEPT to the backend. Allocate a new active socket. Make sure that only one accept command is executed at any given time by setting PVCALLS_FLAG_ACCEPT_INFLIGHT and waiting on the inflight_accept_req waitqueue. Convert the new struct sock_mapping pointer into an uint64_t and use it as id for the new socket to pass to the backend. Check if the accept call is non-blocking: in that case after sending the ACCEPT command to the backend store the sock_mapping pointer of the new struct and the inflight req_id then return -EAGAIN (which will respond only when there is something to accept). Next time accept is called, we'll check if the ACCEPT command has been answered, if so we'll pick up where we left off, otherwise we return -EAGAIN again. Note that, differently from the other commands, we can use wait_event_interruptible (instead of wait_event) in the case of accept as we are able to track the req_id of the ACCEPT response that we are waiting. Signed-off-by: Stefano Stabellini CC: boris.ostrovsky@oracle.com CC: jgross@suse.com --- drivers/xen/pvcalls-front.c | 135 ++++++++++++++++++++++++++++++++++++++++++++ drivers/xen/pvcalls-front.h | 3 + 2 files changed, 138 insertions(+) diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 4ecc1e5..414eafd 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -78,6 +78,16 @@ struct sock_mapping { #define PVCALLS_STATUS_BIND 1 #define PVCALLS_STATUS_LISTEN 2 uint8_t status; + /* + * Internal state-machine flags. + * Only one accept operation can be inflight for a socket. + * Only one poll operation can be inflight for a given socket. + */ +#define PVCALLS_FLAG_ACCEPT_INFLIGHT 0 + uint8_t flags; + uint32_t inflight_req_id; + struct sock_mapping *accept_map; + wait_queue_head_t inflight_accept_req; } passive; }; }; @@ -470,6 +480,131 @@ int pvcalls_front_listen(struct socket *sock, int backlog) return ret; } +int pvcalls_front_accept(struct socket *sock, struct socket *newsock, int flags) +{ + struct pvcalls_bedata *bedata; + struct sock_mapping *map; + struct sock_mapping *map2 = NULL; + struct xen_pvcalls_request *req; + int notify, req_id, ret, evtchn, nonblock; + + pvcalls_enter; + if (!pvcalls_front_dev) { + pvcalls_exit; + return -ENOTCONN; + } + bedata = dev_get_drvdata(&pvcalls_front_dev->dev); + + map = (struct sock_mapping *) sock->sk->sk_send_head; + if (!map) { + pvcalls_exit; + return -ENOTSOCK; + } + + if (map->passive.status != PVCALLS_STATUS_LISTEN) { + pvcalls_exit; + return -EINVAL; + } + + nonblock = flags & SOCK_NONBLOCK; + /* + * Backend only supports 1 inflight accept request, will return + * errors for the others + */ + if (test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, + (void *)&map->passive.flags)) { + req_id = READ_ONCE(map->passive.inflight_req_id); + if (req_id != PVCALLS_INVALID_ID && + READ_ONCE(bedata->rsp[req_id].req_id) == req_id) { + map2 = map->passive.accept_map; + goto received; + } + if (nonblock) { + pvcalls_exit; + return -EAGAIN; + } + if (wait_event_interruptible(map->passive.inflight_accept_req, + !test_and_set_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, + (void *)&map->passive.flags))) { + pvcalls_exit; + return -EINTR; + } + } + + spin_lock(&bedata->socket_lock); + ret = get_request(bedata, &req_id); + if (ret < 0) { + spin_unlock(&bedata->socket_lock); + pvcalls_exit; + return ret; + } + map2 = kzalloc(sizeof(*map2), GFP_KERNEL); + if (map2 == NULL) { + spin_unlock(&bedata->socket_lock); + pvcalls_exit; + return -ENOMEM; + } + ret = create_active(map2, &evtchn); + if (ret < 0) { + kfree(map2); + spin_unlock(&bedata->socket_lock); + pvcalls_exit; + return -ENOMEM; + } + list_add_tail(&map2->list, &bedata->socket_mappings); + + req = RING_GET_REQUEST(&bedata->ring, req_id); + req->req_id = req_id; + req->cmd = PVCALLS_ACCEPT; + req->u.accept.id = (uint64_t) map; + req->u.accept.ref = map2->active.ref; + req->u.accept.id_new = (uint64_t) map2; + req->u.accept.evtchn = evtchn; + map->passive.accept_map = map2; + + bedata->ring.req_prod_pvt++; + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&bedata->ring, notify); + spin_unlock(&bedata->socket_lock); + if (notify) + notify_remote_via_irq(bedata->irq); + /* We could check if we have received a response before returning. */ + if (nonblock) { + WRITE_ONCE(map->passive.inflight_req_id, req_id); + pvcalls_exit; + return -EAGAIN; + } + + if (wait_event_interruptible(bedata->inflight_req, + READ_ONCE(bedata->rsp[req_id].req_id) == req_id)) { + pvcalls_exit; + return -EINTR; + } + +received: + map2->sock = newsock; + newsock->sk = kzalloc(sizeof(*newsock->sk), GFP_KERNEL); + if (!newsock->sk) { + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID); + WRITE_ONCE(map->passive.inflight_req_id, PVCALLS_INVALID_ID); + pvcalls_front_free_map(bedata, map2); + kfree(map2); + pvcalls_exit; + return -ENOMEM; + } + newsock->sk->sk_send_head = (void *)map2; + + clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); + wake_up(&map->passive.inflight_accept_req); + + ret = bedata->rsp[req_id].ret; + /* read ret, then set this rsp slot to be reused */ + smp_mb(); + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID); + WRITE_ONCE(map->passive.inflight_req_id, PVCALLS_INVALID_ID); + pvcalls_exit; + return ret; +} + static const struct xenbus_device_id pvcalls_front_ids[] = { { "pvcalls" }, { "" } diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h index aa8fe10..ab4f1da 100644 --- a/drivers/xen/pvcalls-front.h +++ b/drivers/xen/pvcalls-front.h @@ -10,5 +10,8 @@ int pvcalls_front_bind(struct socket *sock, struct sockaddr *addr, int addr_len); int pvcalls_front_listen(struct socket *sock, int backlog); +int pvcalls_front_accept(struct socket *sock, + struct socket *newsock, + int flags); #endif -- 1.9.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Stabellini Subject: [PATCH v4 08/13] xen/pvcalls: implement accept command Date: Fri, 15 Sep 2017 16:00:35 -0700 Message-ID: <1505516440-11111-8-git-send-email-sstabellini@kernel.org> References: <1505516440-11111-1-git-send-email-sstabellini@kernel.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1505516440-11111-1-git-send-email-sstabellini@kernel.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: xen-devel@lists.xen.org Cc: jgross@suse.com, Stefano Stabellini , boris.ostrovsky@oracle.com, sstabellini@kernel.org, linux-kernel@vger.kernel.org List-Id: xen-devel@lists.xenproject.org SW50cm9kdWNlIGEgd2FpdHF1ZXVlIHRvIGFsbG93IG9ubHkgb25lIG91dHN0YW5kaW5nIGFjY2Vw dCBjb21tYW5kIGF0CmFueSBnaXZlbiB0aW1lIGFuZCB0byBpbXBsZW1lbnQgcG9sbGluZyBvbiB0 aGUgcGFzc2l2ZSBzb2NrZXQuIEludHJvZHVjZQphIGZsYWdzIGZpZWxkIHRvIGtlZXAgdHJhY2sg b2YgaW4tZmxpZ2h0IGFjY2VwdCBhbmQgcG9sbCBjb21tYW5kcy4KClNlbmQgUFZDQUxMU19BQ0NF UFQgdG8gdGhlIGJhY2tlbmQuIEFsbG9jYXRlIGEgbmV3IGFjdGl2ZSBzb2NrZXQuIE1ha2UKc3Vy ZSB0aGF0IG9ubHkgb25lIGFjY2VwdCBjb21tYW5kIGlzIGV4ZWN1dGVkIGF0IGFueSBnaXZlbiB0 aW1lIGJ5CnNldHRpbmcgUFZDQUxMU19GTEFHX0FDQ0VQVF9JTkZMSUdIVCBhbmQgd2FpdGluZyBv biB0aGUKaW5mbGlnaHRfYWNjZXB0X3JlcSB3YWl0cXVldWUuCgpDb252ZXJ0IHRoZSBuZXcgc3Ry dWN0IHNvY2tfbWFwcGluZyBwb2ludGVyIGludG8gYW4gdWludDY0X3QgYW5kIHVzZSBpdAphcyBp ZCBmb3IgdGhlIG5ldyBzb2NrZXQgdG8gcGFzcyB0byB0aGUgYmFja2VuZC4KCkNoZWNrIGlmIHRo ZSBhY2NlcHQgY2FsbCBpcyBub24tYmxvY2tpbmc6IGluIHRoYXQgY2FzZSBhZnRlciBzZW5kaW5n IHRoZQpBQ0NFUFQgY29tbWFuZCB0byB0aGUgYmFja2VuZCBzdG9yZSB0aGUgc29ja19tYXBwaW5n IHBvaW50ZXIgb2YgdGhlIG5ldwpzdHJ1Y3QgYW5kIHRoZSBpbmZsaWdodCByZXFfaWQgdGhlbiBy ZXR1cm4gLUVBR0FJTiAod2hpY2ggd2lsbCByZXNwb25kCm9ubHkgd2hlbiB0aGVyZSBpcyBzb21l dGhpbmcgdG8gYWNjZXB0KS4gTmV4dCB0aW1lIGFjY2VwdCBpcyBjYWxsZWQsCndlJ2xsIGNoZWNr IGlmIHRoZSBBQ0NFUFQgY29tbWFuZCBoYXMgYmVlbiBhbnN3ZXJlZCwgaWYgc28gd2UnbGwgcGlj ayB1cAp3aGVyZSB3ZSBsZWZ0IG9mZiwgb3RoZXJ3aXNlIHdlIHJldHVybiAtRUFHQUlOIGFnYWlu LgoKTm90ZSB0aGF0LCBkaWZmZXJlbnRseSBmcm9tIHRoZSBvdGhlciBjb21tYW5kcywgd2UgY2Fu IHVzZQp3YWl0X2V2ZW50X2ludGVycnVwdGlibGUgKGluc3RlYWQgb2Ygd2FpdF9ldmVudCkgaW4g dGhlIGNhc2Ugb2YgYWNjZXB0CmFzIHdlIGFyZSBhYmxlIHRvIHRyYWNrIHRoZSByZXFfaWQgb2Yg dGhlIEFDQ0VQVCByZXNwb25zZSB0aGF0IHdlIGFyZQp3YWl0aW5nLgoKU2lnbmVkLW9mZi1ieTog U3RlZmFubyBTdGFiZWxsaW5pIDxzdGVmYW5vQGFwb3JldG8uY29tPgpDQzogYm9yaXMub3N0cm92 c2t5QG9yYWNsZS5jb20KQ0M6IGpncm9zc0BzdXNlLmNvbQotLS0KIGRyaXZlcnMveGVuL3B2Y2Fs bHMtZnJvbnQuYyB8IDEzNSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKwogZHJpdmVycy94ZW4vcHZjYWxscy1mcm9udC5oIHwgICAzICsKIDIgZmlsZXMgY2hhbmdl ZCwgMTM4IGluc2VydGlvbnMoKykKCmRpZmYgLS1naXQgYS9kcml2ZXJzL3hlbi9wdmNhbGxzLWZy b250LmMgYi9kcml2ZXJzL3hlbi9wdmNhbGxzLWZyb250LmMKaW5kZXggNGVjYzFlNS4uNDE0ZWFm ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vcHZjYWxscy1mcm9udC5jCisrKyBiL2RyaXZlcnMv eGVuL3B2Y2FsbHMtZnJvbnQuYwpAQCAtNzgsNiArNzgsMTYgQEAgc3RydWN0IHNvY2tfbWFwcGlu ZyB7CiAjZGVmaW5lIFBWQ0FMTFNfU1RBVFVTX0JJTkQgICAgICAgICAgMQogI2RlZmluZSBQVkNB TExTX1NUQVRVU19MSVNURU4gICAgICAgIDIKIAkJCXVpbnQ4X3Qgc3RhdHVzOworCQkvKgorCQkg KiBJbnRlcm5hbCBzdGF0ZS1tYWNoaW5lIGZsYWdzLgorCQkgKiBPbmx5IG9uZSBhY2NlcHQgb3Bl cmF0aW9uIGNhbiBiZSBpbmZsaWdodCBmb3IgYSBzb2NrZXQuCisJCSAqIE9ubHkgb25lIHBvbGwg b3BlcmF0aW9uIGNhbiBiZSBpbmZsaWdodCBmb3IgYSBnaXZlbiBzb2NrZXQuCisJCSAqLworI2Rl ZmluZSBQVkNBTExTX0ZMQUdfQUNDRVBUX0lORkxJR0hUIDAKKwkJCXVpbnQ4X3QgZmxhZ3M7CisJ CQl1aW50MzJfdCBpbmZsaWdodF9yZXFfaWQ7CisJCQlzdHJ1Y3Qgc29ja19tYXBwaW5nICphY2Nl cHRfbWFwOworCQkJd2FpdF9xdWV1ZV9oZWFkX3QgaW5mbGlnaHRfYWNjZXB0X3JlcTsKIAkJfSBw YXNzaXZlOwogCX07CiB9OwpAQCAtNDcwLDYgKzQ4MCwxMzEgQEAgaW50IHB2Y2FsbHNfZnJvbnRf bGlzdGVuKHN0cnVjdCBzb2NrZXQgKnNvY2ssIGludCBiYWNrbG9nKQogCXJldHVybiByZXQ7CiB9 CiAKK2ludCBwdmNhbGxzX2Zyb250X2FjY2VwdChzdHJ1Y3Qgc29ja2V0ICpzb2NrLCBzdHJ1Y3Qg c29ja2V0ICpuZXdzb2NrLCBpbnQgZmxhZ3MpCit7CisJc3RydWN0IHB2Y2FsbHNfYmVkYXRhICpi ZWRhdGE7CisJc3RydWN0IHNvY2tfbWFwcGluZyAqbWFwOworCXN0cnVjdCBzb2NrX21hcHBpbmcg Km1hcDIgPSBOVUxMOworCXN0cnVjdCB4ZW5fcHZjYWxsc19yZXF1ZXN0ICpyZXE7CisJaW50IG5v dGlmeSwgcmVxX2lkLCByZXQsIGV2dGNobiwgbm9uYmxvY2s7CisKKwlwdmNhbGxzX2VudGVyOwor CWlmICghcHZjYWxsc19mcm9udF9kZXYpIHsKKwkJcHZjYWxsc19leGl0OworCQlyZXR1cm4gLUVO T1RDT05OOworCX0KKwliZWRhdGEgPSBkZXZfZ2V0X2RydmRhdGEoJnB2Y2FsbHNfZnJvbnRfZGV2 LT5kZXYpOworCisJbWFwID0gKHN0cnVjdCBzb2NrX21hcHBpbmcgKikgc29jay0+c2stPnNrX3Nl bmRfaGVhZDsKKwlpZiAoIW1hcCkgeworCQlwdmNhbGxzX2V4aXQ7CisJCXJldHVybiAtRU5PVFNP Q0s7CisJfQorCisJaWYgKG1hcC0+cGFzc2l2ZS5zdGF0dXMgIT0gUFZDQUxMU19TVEFUVVNfTElT VEVOKSB7CisJCXB2Y2FsbHNfZXhpdDsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJbm9uYmxv Y2sgPSBmbGFncyAmIFNPQ0tfTk9OQkxPQ0s7CisJLyoKKwkgKiBCYWNrZW5kIG9ubHkgc3VwcG9y dHMgMSBpbmZsaWdodCBhY2NlcHQgcmVxdWVzdCwgd2lsbCByZXR1cm4KKwkgKiBlcnJvcnMgZm9y IHRoZSBvdGhlcnMKKwkgKi8KKwlpZiAodGVzdF9hbmRfc2V0X2JpdChQVkNBTExTX0ZMQUdfQUND RVBUX0lORkxJR0hULAorCQkJICAgICAodm9pZCAqKSZtYXAtPnBhc3NpdmUuZmxhZ3MpKSB7CisJ CXJlcV9pZCA9IFJFQURfT05DRShtYXAtPnBhc3NpdmUuaW5mbGlnaHRfcmVxX2lkKTsKKwkJaWYg KHJlcV9pZCAhPSBQVkNBTExTX0lOVkFMSURfSUQgJiYKKwkJICAgIFJFQURfT05DRShiZWRhdGEt PnJzcFtyZXFfaWRdLnJlcV9pZCkgPT0gcmVxX2lkKSB7CisJCQltYXAyID0gbWFwLT5wYXNzaXZl LmFjY2VwdF9tYXA7CisJCQlnb3RvIHJlY2VpdmVkOworCQl9CisJCWlmIChub25ibG9jaykgewor CQkJcHZjYWxsc19leGl0OworCQkJcmV0dXJuIC1FQUdBSU47CisJCX0KKwkJaWYgKHdhaXRfZXZl bnRfaW50ZXJydXB0aWJsZShtYXAtPnBhc3NpdmUuaW5mbGlnaHRfYWNjZXB0X3JlcSwKKwkJCSF0 ZXN0X2FuZF9zZXRfYml0KFBWQ0FMTFNfRkxBR19BQ0NFUFRfSU5GTElHSFQsCisJCQkJCSAgKHZv aWQgKikmbWFwLT5wYXNzaXZlLmZsYWdzKSkpIHsKKwkJCXB2Y2FsbHNfZXhpdDsKKwkJCXJldHVy biAtRUlOVFI7CisJCX0KKwl9CisKKwlzcGluX2xvY2soJmJlZGF0YS0+c29ja2V0X2xvY2spOwor CXJldCA9IGdldF9yZXF1ZXN0KGJlZGF0YSwgJnJlcV9pZCk7CisJaWYgKHJldCA8IDApIHsKKwkJ c3Bpbl91bmxvY2soJmJlZGF0YS0+c29ja2V0X2xvY2spOworCQlwdmNhbGxzX2V4aXQ7CisJCXJl dHVybiByZXQ7CisJfQorCW1hcDIgPSBremFsbG9jKHNpemVvZigqbWFwMiksIEdGUF9LRVJORUwp OworCWlmIChtYXAyID09IE5VTEwpIHsKKwkJc3Bpbl91bmxvY2soJmJlZGF0YS0+c29ja2V0X2xv Y2spOworCQlwdmNhbGxzX2V4aXQ7CisJCXJldHVybiAtRU5PTUVNOworCX0KKwlyZXQgPSAgY3Jl YXRlX2FjdGl2ZShtYXAyLCAmZXZ0Y2huKTsKKwlpZiAocmV0IDwgMCkgeworCQlrZnJlZShtYXAy KTsKKwkJc3Bpbl91bmxvY2soJmJlZGF0YS0+c29ja2V0X2xvY2spOworCQlwdmNhbGxzX2V4aXQ7 CisJCXJldHVybiAtRU5PTUVNOworCX0KKwlsaXN0X2FkZF90YWlsKCZtYXAyLT5saXN0LCAmYmVk YXRhLT5zb2NrZXRfbWFwcGluZ3MpOworCisJcmVxID0gUklOR19HRVRfUkVRVUVTVCgmYmVkYXRh LT5yaW5nLCByZXFfaWQpOworCXJlcS0+cmVxX2lkID0gcmVxX2lkOworCXJlcS0+Y21kID0gUFZD QUxMU19BQ0NFUFQ7CisJcmVxLT51LmFjY2VwdC5pZCA9ICh1aW50NjRfdCkgbWFwOworCXJlcS0+ dS5hY2NlcHQucmVmID0gbWFwMi0+YWN0aXZlLnJlZjsKKwlyZXEtPnUuYWNjZXB0LmlkX25ldyA9 ICh1aW50NjRfdCkgbWFwMjsKKwlyZXEtPnUuYWNjZXB0LmV2dGNobiA9IGV2dGNobjsKKwltYXAt PnBhc3NpdmUuYWNjZXB0X21hcCA9IG1hcDI7CisKKwliZWRhdGEtPnJpbmcucmVxX3Byb2RfcHZ0 Kys7CisJUklOR19QVVNIX1JFUVVFU1RTX0FORF9DSEVDS19OT1RJRlkoJmJlZGF0YS0+cmluZywg bm90aWZ5KTsKKwlzcGluX3VubG9jaygmYmVkYXRhLT5zb2NrZXRfbG9jayk7CisJaWYgKG5vdGlm eSkKKwkJbm90aWZ5X3JlbW90ZV92aWFfaXJxKGJlZGF0YS0+aXJxKTsKKwkvKiBXZSBjb3VsZCBj aGVjayBpZiB3ZSBoYXZlIHJlY2VpdmVkIGEgcmVzcG9uc2UgYmVmb3JlIHJldHVybmluZy4gKi8K KwlpZiAobm9uYmxvY2spIHsKKwkJV1JJVEVfT05DRShtYXAtPnBhc3NpdmUuaW5mbGlnaHRfcmVx X2lkLCByZXFfaWQpOworCQlwdmNhbGxzX2V4aXQ7CisJCXJldHVybiAtRUFHQUlOOworCX0KKwor CWlmICh3YWl0X2V2ZW50X2ludGVycnVwdGlibGUoYmVkYXRhLT5pbmZsaWdodF9yZXEsCisJCVJF QURfT05DRShiZWRhdGEtPnJzcFtyZXFfaWRdLnJlcV9pZCkgPT0gcmVxX2lkKSkgeworCQlwdmNh bGxzX2V4aXQ7CisJCXJldHVybiAtRUlOVFI7CisJfQorCityZWNlaXZlZDoKKwltYXAyLT5zb2Nr ID0gbmV3c29jazsKKwluZXdzb2NrLT5zayA9IGt6YWxsb2Moc2l6ZW9mKCpuZXdzb2NrLT5zayks IEdGUF9LRVJORUwpOworCWlmICghbmV3c29jay0+c2spIHsKKwkJV1JJVEVfT05DRShiZWRhdGEt PnJzcFtyZXFfaWRdLnJlcV9pZCwgUFZDQUxMU19JTlZBTElEX0lEKTsKKwkJV1JJVEVfT05DRSht YXAtPnBhc3NpdmUuaW5mbGlnaHRfcmVxX2lkLCBQVkNBTExTX0lOVkFMSURfSUQpOworCQlwdmNh bGxzX2Zyb250X2ZyZWVfbWFwKGJlZGF0YSwgbWFwMik7CisJCWtmcmVlKG1hcDIpOworCQlwdmNh bGxzX2V4aXQ7CisJCXJldHVybiAtRU5PTUVNOworCX0KKwluZXdzb2NrLT5zay0+c2tfc2VuZF9o ZWFkID0gKHZvaWQgKiltYXAyOworCisJY2xlYXJfYml0KFBWQ0FMTFNfRkxBR19BQ0NFUFRfSU5G TElHSFQsICh2b2lkICopJm1hcC0+cGFzc2l2ZS5mbGFncyk7CisJd2FrZV91cCgmbWFwLT5wYXNz aXZlLmluZmxpZ2h0X2FjY2VwdF9yZXEpOworCisJcmV0ID0gYmVkYXRhLT5yc3BbcmVxX2lkXS5y ZXQ7CisJLyogcmVhZCByZXQsIHRoZW4gc2V0IHRoaXMgcnNwIHNsb3QgdG8gYmUgcmV1c2VkICov CisJc21wX21iKCk7CisJV1JJVEVfT05DRShiZWRhdGEtPnJzcFtyZXFfaWRdLnJlcV9pZCwgUFZD QUxMU19JTlZBTElEX0lEKTsKKwlXUklURV9PTkNFKG1hcC0+cGFzc2l2ZS5pbmZsaWdodF9yZXFf aWQsIFBWQ0FMTFNfSU5WQUxJRF9JRCk7CisJcHZjYWxsc19leGl0OworCXJldHVybiByZXQ7Cit9 CisKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgeGVuYnVzX2RldmljZV9pZCBwdmNhbGxzX2Zyb250X2lk c1tdID0gewogCXsgInB2Y2FsbHMiIH0sCiAJeyAiIiB9CmRpZmYgLS1naXQgYS9kcml2ZXJzL3hl bi9wdmNhbGxzLWZyb250LmggYi9kcml2ZXJzL3hlbi9wdmNhbGxzLWZyb250LmgKaW5kZXggYWE4 ZmUxMC4uYWI0ZjFkYSAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vcHZjYWxscy1mcm9udC5oCisr KyBiL2RyaXZlcnMveGVuL3B2Y2FsbHMtZnJvbnQuaApAQCAtMTAsNSArMTAsOCBAQCBpbnQgcHZj YWxsc19mcm9udF9iaW5kKHN0cnVjdCBzb2NrZXQgKnNvY2ssCiAJCSAgICAgICBzdHJ1Y3Qgc29j a2FkZHIgKmFkZHIsCiAJCSAgICAgICBpbnQgYWRkcl9sZW4pOwogaW50IHB2Y2FsbHNfZnJvbnRf bGlzdGVuKHN0cnVjdCBzb2NrZXQgKnNvY2ssIGludCBiYWNrbG9nKTsKK2ludCBwdmNhbGxzX2Zy b250X2FjY2VwdChzdHJ1Y3Qgc29ja2V0ICpzb2NrLAorCQkJIHN0cnVjdCBzb2NrZXQgKm5ld3Nv Y2ssCisJCQkgaW50IGZsYWdzKTsKIAogI2VuZGlmCi0tIAoxLjkuMQoKCl9fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QK WGVuLWRldmVsQGxpc3RzLnhlbi5vcmcKaHR0cHM6Ly9saXN0cy54ZW4ub3JnL3hlbi1kZXZlbAo=