From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: [PATCH 6/8] xen/gntdev: Implement dma-buf export functionality Date: Fri, 25 May 2018 18:33:29 +0300 Message-ID: <20180525153331.31188-7-andr2000@gmail.com> References: <20180525153331.31188-1-andr2000@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 565116E95F for ; Fri, 25 May 2018 15:33:54 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id t11-v6so15545021wmt.0 for ; Fri, 25 May 2018 08:33:54 -0700 (PDT) In-Reply-To: <20180525153331.31188-1-andr2000@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: andr2000@gmail.com, daniel.vetter@intel.com, dongwon.kim@intel.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org RnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgoKMS4gQ3JlYXRlIGEgZG1hLWJ1ZiBmcm9tIGdyYW50IHJlZmVyZW5jZXMgcHJvdmlk ZWQgYnkgdGhlIGZvcmVpZ24KICAgZG9tYWluLiBCeSBkZWZhdWx0IGRtYS1idWYgaXMgYmFja2Vk IGJ5IHN5c3RlbSBtZW1vcnkgcGFnZXMsIGJ1dAogICBieSBwcm92aWRpbmcgR05UREVWX0RNQV9G TEFHX1hYWCBmbGFncyBpdCBjYW4gYWxzbyBiZSBjcmVhdGVkCiAgIGFzIGEgRE1BIHdyaXRlLWNv bWJpbmUvY29oZXJlbnQgYnVmZmVyLCBlLmcuIGFsbG9jYXRlZCB3aXRoCiAgIGNvcnJlc3BvbmRp bmcgZG1hX2FsbG9jX3h4eCBBUEkuCiAgIEV4cG9ydCB0aGUgcmVzdWx0aW5nIGJ1ZmZlciBhcyBh IG5ldyBkbWEtYnVmLgoKMi4gSW1wbGVtZW50IHdhaXRpbmcgZm9yIHRoZSBkbWEtYnVmIHRvIGJl IHJlbGVhc2VkOiBibG9jayB1bnRpbCB0aGUKICAgZG1hLWJ1ZiB3aXRoIHRoZSBmaWxlIGRlc2Ny aXB0b3IgcHJvdmlkZWQgaXMgcmVsZWFzZWQuCiAgIElmIHdpdGhpbiB0aGUgdGltZS1vdXQgcHJv dmlkZWQgdGhlIGJ1ZmZlciBpcyBub3QgcmVsZWFzZWQgdGhlbgogICAtRVRJTUVET1VUIGVycm9y IGlzIHJldHVybmVkLiBJZiB0aGUgYnVmZmVyIHdpdGggdGhlIGZpbGUgZGVzY3JpcHRvcgogICBk b2VzIG5vdCBleGlzdCBvciBoYXMgYWxyZWFkeSBiZWVuIHJlbGVhc2VkLCB0aGVuIC1FTk9FTlQg aXMgcmV0dXJuZWQuCiAgIEZvciB2YWxpZCBmaWxlIGRlc2NyaXB0b3JzIHRoaXMgbXVzdCBub3Qg YmUgdHJlYXRlZCBhcyBlcnJvci4KClNpZ25lZC1vZmYtYnk6IE9sZWtzYW5kciBBbmRydXNoY2hl bmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5rb0BlcGFtLmNvbT4KLS0tCiBkcml2ZXJzL3hlbi9n bnRkZXYuYyB8IDQ3OCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyst CiAxIGZpbGUgY2hhbmdlZCwgNDc2IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCgpkaWZm IC0tZ2l0IGEvZHJpdmVycy94ZW4vZ250ZGV2LmMgYi9kcml2ZXJzL3hlbi9nbnRkZXYuYwppbmRl eCA5ZTQ1MDYyMmFmMWEuLjUyYWJjNmNkNTg0NiAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vZ250 ZGV2LmMKKysrIGIvZHJpdmVycy94ZW4vZ250ZGV2LmMKQEAgLTQsNiArNCw4IEBACiAgKiBEZXZp Y2UgZm9yIGFjY2Vzc2luZyAoaW4gdXNlci1zcGFjZSkgcGFnZXMgdGhhdCBoYXZlIGJlZW4gZ3Jh bnRlZCBieSBvdGhlcgogICogZG9tYWlucy4KICAqCisgKiBETUEgYnVmZmVyIGltcGxlbWVudGF0 aW9uIGlzIGJhc2VkIG9uIGRyaXZlcnMvZ3B1L2RybS9kcm1fcHJpbWUuYy4KKyAqCiAgKiBDb3B5 cmlnaHQgKGMpIDIwMDYtMjAwNywgRCBHIE11cnJheS4KICAqICAgICAgICAgICAoYykgMjAwOSBH ZXJkIEhvZmZtYW5uIDxrcmF4ZWxAcmVkaGF0LmNvbT4KICAqICAgICAgICAgICAoYykgMjAxOCBP bGVrc2FuZHIgQW5kcnVzaGNoZW5rbywgRVBBTSBTeXN0ZW1zIEluYy4KQEAgLTQxLDYgKzQzLDkg QEAKICNpZmRlZiBDT05GSUdfWEVOX0dSQU5UX0RNQV9BTExPQwogI2luY2x1ZGUgPGxpbnV4L29m X2RldmljZS5oPgogI2VuZGlmCisjaWZkZWYgQ09ORklHX1hFTl9HTlRERVZfRE1BQlVGCisjaW5j bHVkZSA8bGludXgvZG1hLWJ1Zi5oPgorI2VuZGlmCiAKICNpbmNsdWRlIDx4ZW4veGVuLmg+CiAj aW5jbHVkZSA8eGVuL2dyYW50X3RhYmxlLmg+CkBAIC04MSw2ICs4NiwxNyBAQCBzdHJ1Y3QgZ250 ZGV2X3ByaXYgewogCS8qIERldmljZSBmb3Igd2hpY2ggRE1BIG1lbW9yeSBpcyBhbGxvY2F0ZWQu ICovCiAJc3RydWN0IGRldmljZSAqZG1hX2RldjsKICNlbmRpZgorCisjaWZkZWYgQ09ORklHX1hF Tl9HTlRERVZfRE1BQlVGCisJLyogUHJpdmF0ZSBkYXRhIG9mIHRoZSBoeXBlciBETUEgYnVmZmVy cy4gKi8KKworCS8qIExpc3Qgb2YgZXhwb3J0ZWQgRE1BIGJ1ZmZlcnMuICovCisJc3RydWN0IGxp c3RfaGVhZCBkbWFidWZfZXhwX2xpc3Q7CisJLyogTGlzdCBvZiB3YWl0IG9iamVjdHMuICovCisJ c3RydWN0IGxpc3RfaGVhZCBkbWFidWZfZXhwX3dhaXRfbGlzdDsKKwkvKiBUaGlzIGlzIHRoZSBs b2NrIHdoaWNoIHByb3RlY3RzIGRtYV9idWZfeHh4IGxpc3RzLiAqLworCXN0cnVjdCBtdXRleCBk bWFidWZfbG9jazsKKyNlbmRpZgogfTsKIAogc3RydWN0IHVubWFwX25vdGlmeSB7CkBAIC0xMjUs MTIgKzE0MSwzOCBAQCBzdHJ1Y3QgZ3JhbnRfbWFwIHsKIAogI2lmZGVmIENPTkZJR19YRU5fR05U REVWX0RNQUJVRgogc3RydWN0IHhlbl9kbWFidWYgeworCXN0cnVjdCBnbnRkZXZfcHJpdiAqcHJp djsKKwlzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmOworCXN0cnVjdCBsaXN0X2hlYWQgbmV4dDsKKwlp bnQgZmQ7CisKIAl1bmlvbiB7CisJCXN0cnVjdCB7CisJCQkvKiBFeHBvcnRlZCBidWZmZXJzIGFy ZSByZWZlcmVuY2UgY291bnRlZC4gKi8KKwkJCXN0cnVjdCBrcmVmIHJlZmNvdW50OworCQkJc3Ry dWN0IGdyYW50X21hcCAqbWFwOworCQl9IGV4cDsKIAkJc3RydWN0IHsKIAkJCS8qIEdyYW50ZWQg cmVmZXJlbmNlcyBvZiB0aGUgaW1wb3J0ZWQgYnVmZmVyLiAqLwogCQkJZ3JhbnRfcmVmX3QgKnJl ZnM7CiAJCX0gaW1wOwogCX0gdTsKKworCS8qIE51bWJlciBvZiBwYWdlcyB0aGlzIGJ1ZmZlciBo YXMuICovCisJaW50IG5yX3BhZ2VzOworCS8qIFBhZ2VzIG9mIHRoaXMgYnVmZmVyLiAqLworCXN0 cnVjdCBwYWdlICoqcGFnZXM7Cit9OworCitzdHJ1Y3QgeGVuX2RtYWJ1Zl93YWl0X29iaiB7CisJ c3RydWN0IGxpc3RfaGVhZCBuZXh0OworCXN0cnVjdCB4ZW5fZG1hYnVmICp4ZW5fZG1hYnVmOwor CXN0cnVjdCBjb21wbGV0aW9uIGNvbXBsZXRpb247Cit9OworCitzdHJ1Y3QgeGVuX2RtYWJ1Zl9h dHRhY2htZW50IHsKKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsKKwllbnVtIGRtYV9kYXRhX2RpcmVj dGlvbiBkaXI7CiB9OwogI2VuZGlmCiAKQEAgLTMyMCw2ICszNjIsMTYgQEAgc3RhdGljIHZvaWQg Z250ZGV2X3B1dF9tYXAoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBzdHJ1Y3QgZ3JhbnRfbWFw ICptYXApCiAJZ250ZGV2X2ZyZWVfbWFwKG1hcCk7CiB9CiAKKyNpZmRlZiBDT05GSUdfWEVOX0dO VERFVl9ETUFCVUYKK3N0YXRpYyB2b2lkIGdudGRldl9yZW1vdmVfbWFwKHN0cnVjdCBnbnRkZXZf cHJpdiAqcHJpdiwgc3RydWN0IGdyYW50X21hcCAqbWFwKQoreworCW11dGV4X2xvY2soJnByaXYt PmxvY2spOworCWxpc3RfZGVsKCZtYXAtPm5leHQpOworCWdudGRldl9wdXRfbWFwKE5VTEwgLyog YWxyZWFkeSByZW1vdmVkICovLCBtYXApOworCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cit9 CisjZW5kaWYKKwogLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAKIHN0YXRpYyBpbnQgZmluZF9ncmFudF9wdGVz KHB0ZV90ICpwdGUsIHBndGFibGVfdCB0b2tlbiwKQEAgLTYyOCw2ICs2ODAsMTIgQEAgc3RhdGlj IGludCBnbnRkZXZfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmxpcCkK IAlJTklUX0xJU1RfSEVBRCgmcHJpdi0+ZnJlZWFibGVfbWFwcyk7CiAJbXV0ZXhfaW5pdCgmcHJp di0+bG9jayk7CiAKKyNpZmRlZiBDT05GSUdfWEVOX0dOVERFVl9ETUFCVUYKKwltdXRleF9pbml0 KCZwcml2LT5kbWFidWZfbG9jayk7CisJSU5JVF9MSVNUX0hFQUQoJnByaXYtPmRtYWJ1Zl9leHBf bGlzdCk7CisJSU5JVF9MSVNUX0hFQUQoJnByaXYtPmRtYWJ1Zl9leHBfd2FpdF9saXN0KTsKKyNl bmRpZgorCiAJaWYgKHVzZV9wdGVtb2QpIHsKIAkJcHJpdi0+bW0gPSBnZXRfdGFza19tbShjdXJy ZW50KTsKIAkJaWYgKCFwcml2LT5tbSkgewpAQCAtMTA1MywxNyArMTExMSw0MzMgQEAgc3RhdGlj IGxvbmcgZ250ZGV2X2lvY3RsX2dyYW50X2NvcHkoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCB2 b2lkIF9fdXNlciAqdSkKIC8qIERNQSBidWZmZXIgZXhwb3J0IHN1cHBvcnQuICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAKKy8qIC0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLSAqLworLyogSW1wbGVtZW50YXRpb24gb2Ygd2FpdCBmb3IgZXhwb3J0ZWQgRE1BIGJ1 ZmZlciB0byBiZSByZWxlYXNlZC4gICAgICovCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworc3RhdGljIHZv aWQgZG1hYnVmX2V4cF9yZWxlYXNlKHN0cnVjdCBrcmVmICprcmVmKTsKKworc3RhdGljIHN0cnVj dCB4ZW5fZG1hYnVmX3dhaXRfb2JqICoKK2RtYWJ1Zl9leHBfd2FpdF9vYmpfbmV3KHN0cnVjdCBn bnRkZXZfcHJpdiAqcHJpdiwKKwkJCXN0cnVjdCB4ZW5fZG1hYnVmICp4ZW5fZG1hYnVmKQorewor CXN0cnVjdCB4ZW5fZG1hYnVmX3dhaXRfb2JqICpvYmo7CisKKwlvYmogPSBremFsbG9jKHNpemVv Zigqb2JqKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFvYmopCisJCXJldHVybiBFUlJfUFRSKC1FTk9N RU0pOworCisJaW5pdF9jb21wbGV0aW9uKCZvYmotPmNvbXBsZXRpb24pOworCW9iai0+eGVuX2Rt YWJ1ZiA9IHhlbl9kbWFidWY7CisKKwltdXRleF9sb2NrKCZwcml2LT5kbWFidWZfbG9jayk7CisJ bGlzdF9hZGQoJm9iai0+bmV4dCwgJnByaXYtPmRtYWJ1Zl9leHBfd2FpdF9saXN0KTsKKwkvKiBQ dXQgb3VyIHJlZmVyZW5jZSBhbmQgd2FpdCBmb3IgeGVuX2RtYWJ1ZidzIHJlbGVhc2UgdG8gZmly ZS4gKi8KKwlrcmVmX3B1dCgmeGVuX2RtYWJ1Zi0+dS5leHAucmVmY291bnQsIGRtYWJ1Zl9leHBf cmVsZWFzZSk7CisJbXV0ZXhfdW5sb2NrKCZwcml2LT5kbWFidWZfbG9jayk7CisJcmV0dXJuIG9i ajsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4cF93YWl0X29ial9mcmVlKHN0cnVjdCBnbnRk ZXZfcHJpdiAqcHJpdiwKKwkJCQkgICAgIHN0cnVjdCB4ZW5fZG1hYnVmX3dhaXRfb2JqICpvYmop Cit7CisJc3RydWN0IHhlbl9kbWFidWZfd2FpdF9vYmogKmN1cl9vYmosICpxOworCisJbXV0ZXhf bG9jaygmcHJpdi0+ZG1hYnVmX2xvY2spOworCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjdXJf b2JqLCBxLCAmcHJpdi0+ZG1hYnVmX2V4cF93YWl0X2xpc3QsIG5leHQpCisJCWlmIChjdXJfb2Jq ID09IG9iaikgeworCQkJbGlzdF9kZWwoJm9iai0+bmV4dCk7CisJCQlrZnJlZShvYmopOworCQkJ YnJlYWs7CisJCX0KKwltdXRleF91bmxvY2soJnByaXYtPmRtYWJ1Zl9sb2NrKTsKK30KKworc3Rh dGljIGludCBkbWFidWZfZXhwX3dhaXRfb2JqX3dhaXQoc3RydWN0IHhlbl9kbWFidWZfd2FpdF9v YmogKm9iaiwKKwkJCQkgICAgdTMyIHdhaXRfdG9fbXMpCit7CisJaWYgKHdhaXRfZm9yX2NvbXBs ZXRpb25fdGltZW91dCgmb2JqLT5jb21wbGV0aW9uLAorCQkJbXNlY3NfdG9famlmZmllcyh3YWl0 X3RvX21zKSkgPD0gMCkKKwkJcmV0dXJuIC1FVElNRURPVVQ7CisKKwlyZXR1cm4gMDsKK30KKwor c3RhdGljIHZvaWQgZG1hYnVmX2V4cF93YWl0X29ial9zaWduYWwoc3RydWN0IGdudGRldl9wcml2 ICpwcml2LAorCQkJCSAgICAgICBzdHJ1Y3QgeGVuX2RtYWJ1ZiAqeGVuX2RtYWJ1ZikKK3sKKwlz dHJ1Y3QgeGVuX2RtYWJ1Zl93YWl0X29iaiAqb2JqLCAqcTsKKworCWxpc3RfZm9yX2VhY2hfZW50 cnlfc2FmZShvYmosIHEsICZwcml2LT5kbWFidWZfZXhwX3dhaXRfbGlzdCwgbmV4dCkKKwkJaWYg KG9iai0+eGVuX2RtYWJ1ZiA9PSB4ZW5fZG1hYnVmKSB7CisJCQlwcl9kZWJ1ZygiRm91bmQgeGVu X2RtYWJ1ZiBpbiB0aGUgd2FpdCBsaXN0LCB3YWtlXG4iKTsKKwkJCWNvbXBsZXRlX2FsbCgmb2Jq LT5jb21wbGV0aW9uKTsKKwkJfQorfQorCitzdGF0aWMgc3RydWN0IHhlbl9kbWFidWYgKgorZG1h YnVmX2V4cF93YWl0X29ial9nZXRfYnlfZmQoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBpbnQg ZmQpCit7CisJc3RydWN0IHhlbl9kbWFidWYgKnEsICp4ZW5fZG1hYnVmLCAqcmV0ID0gRVJSX1BU UigtRU5PRU5UKTsKKworCW11dGV4X2xvY2soJnByaXYtPmRtYWJ1Zl9sb2NrKTsKKwlsaXN0X2Zv cl9lYWNoX2VudHJ5X3NhZmUoeGVuX2RtYWJ1ZiwgcSwgJnByaXYtPmRtYWJ1Zl9leHBfbGlzdCwg bmV4dCkKKwkJaWYgKHhlbl9kbWFidWYtPmZkID09IGZkKSB7CisJCQlwcl9kZWJ1ZygiRm91bmQg eGVuX2RtYWJ1ZiBpbiB0aGUgd2FpdCBsaXN0XG4iKTsKKwkJCWtyZWZfZ2V0KCZ4ZW5fZG1hYnVm LT51LmV4cC5yZWZjb3VudCk7CisJCQlyZXQgPSB4ZW5fZG1hYnVmOworCQkJYnJlYWs7CisJCX0K KwltdXRleF91bmxvY2soJnByaXYtPmRtYWJ1Zl9sb2NrKTsKKwlyZXR1cm4gcmV0OworfQorCiBz dGF0aWMgaW50IGRtYWJ1Zl9leHBfd2FpdF9yZWxlYXNlZChzdHJ1Y3QgZ250ZGV2X3ByaXYgKnBy aXYsIGludCBmZCwKIAkJCQkgICAgaW50IHdhaXRfdG9fbXMpCiB7Ci0JcmV0dXJuIC1FVElNRURP VVQ7CisJc3RydWN0IHhlbl9kbWFidWYgKnhlbl9kbWFidWY7CisJc3RydWN0IHhlbl9kbWFidWZf d2FpdF9vYmogKm9iajsKKwlpbnQgcmV0OworCisJcHJfZGVidWcoIldpbGwgd2FpdCBmb3IgZG1h LWJ1ZiB3aXRoIGZkICVkXG4iLCBmZCk7CisJLyoKKwkgKiBUcnkgdG8gZmluZCB0aGUgRE1BIGJ1 ZmZlcjogaWYgbm90IGZvdW5kIG1lYW5zIHRoYXQKKwkgKiBlaXRoZXIgdGhlIGJ1ZmZlciBoYXMg YWxyZWFkeSBiZWVuIHJlbGVhc2VkIG9yIGZpbGUgZGVzY3JpcHRvcgorCSAqIHByb3ZpZGVkIGlz IHdyb25nLgorCSAqLworCXhlbl9kbWFidWYgPSBkbWFidWZfZXhwX3dhaXRfb2JqX2dldF9ieV9m ZChwcml2LCBmZCk7CisJaWYgKElTX0VSUih4ZW5fZG1hYnVmKSkKKwkJcmV0dXJuIFBUUl9FUlIo eGVuX2RtYWJ1Zik7CisKKwkvKgorCSAqIHhlbl9kbWFidWYgc3RpbGwgZXhpc3RzIGFuZCBpcyBy ZWZlcmVuY2UgY291bnQgbG9ja2VkIGJ5IHVzIG5vdywKKwkgKiBzbyBwcmVwYXJlIHRvIHdhaXQ6 IGFsbG9jYXRlIHdhaXQgb2JqZWN0IGFuZCBhZGQgaXQgdG8gdGhlIHdhaXQgbGlzdCwKKwkgKiBz byB3ZSBjYW4gZmluZCBpdCBvbiByZWxlYXNlLgorCSAqLworCW9iaiA9IGRtYWJ1Zl9leHBfd2Fp dF9vYmpfbmV3KHByaXYsIHhlbl9kbWFidWYpOworCWlmIChJU19FUlIob2JqKSkgeworCQlwcl9l cnIoIkZhaWxlZCB0byBzZXR1cCB3YWl0IG9iamVjdCwgcmV0ICVsZFxuIiwgUFRSX0VSUihvYmop KTsKKwkJcmV0dXJuIFBUUl9FUlIob2JqKTsKKwl9CisKKwlyZXQgPSBkbWFidWZfZXhwX3dhaXRf b2JqX3dhaXQob2JqLCB3YWl0X3RvX21zKTsKKwlkbWFidWZfZXhwX3dhaXRfb2JqX2ZyZWUocHJp diwgb2JqKTsKKwlyZXR1cm4gcmV0OworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKy8qIERNQSBidWZm ZXIgZXhwb3J0IHN1cHBvcnQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAqLworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tICovCisKK3N0YXRpYyBzdHJ1Y3Qgc2dfdGFibGUgKgorZG1hYnVm X3BhZ2VzX3RvX3NndChzdHJ1Y3QgcGFnZSAqKnBhZ2VzLCB1bnNpZ25lZCBpbnQgbnJfcGFnZXMp Cit7CisJc3RydWN0IHNnX3RhYmxlICpzZ3Q7CisJaW50IHJldDsKKworCXNndCA9IGttYWxsb2Mo c2l6ZW9mKCpzZ3QpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXNndCkgeworCQlyZXQgPSAtRU5PTUVN OworCQlnb3RvIG91dDsKKwl9CisKKwlyZXQgPSBzZ19hbGxvY190YWJsZV9mcm9tX3BhZ2VzKHNn dCwgcGFnZXMsIG5yX3BhZ2VzLCAwLAorCQkJCQlucl9wYWdlcyA8PCBQQUdFX1NISUZULAorCQkJ CQlHRlBfS0VSTkVMKTsKKwlpZiAocmV0KQorCQlnb3RvIG91dDsKKworCXJldHVybiBzZ3Q7CisK K291dDoKKwlrZnJlZShzZ3QpOworCXJldHVybiBFUlJfUFRSKHJldCk7Cit9CisKK3N0YXRpYyBp bnQgZG1hYnVmX2V4cF9vcHNfYXR0YWNoKHN0cnVjdCBkbWFfYnVmICpkbWFfYnVmLAorCQkJCSBz dHJ1Y3QgZGV2aWNlICp0YXJnZXRfZGV2LAorCQkJCSBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50 ICphdHRhY2gpCit7CisJc3RydWN0IHhlbl9kbWFidWZfYXR0YWNobWVudCAqeGVuX2RtYWJ1Zl9h dHRhY2g7CisKKwl4ZW5fZG1hYnVmX2F0dGFjaCA9IGt6YWxsb2Moc2l6ZW9mKCp4ZW5fZG1hYnVm X2F0dGFjaCksIEdGUF9LRVJORUwpOworCWlmICgheGVuX2RtYWJ1Zl9hdHRhY2gpCisJCXJldHVy biAtRU5PTUVNOworCisJeGVuX2RtYWJ1Zl9hdHRhY2gtPmRpciA9IERNQV9OT05FOworCWF0dGFj aC0+cHJpdiA9IHhlbl9kbWFidWZfYXR0YWNoOworCS8qIE1pZ2h0IG5lZWQgdG8gcGluIHRoZSBw YWdlcyBvZiB0aGUgYnVmZmVyIG5vdy4gKi8KKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQg ZG1hYnVmX2V4cF9vcHNfZGV0YWNoKHN0cnVjdCBkbWFfYnVmICpkbWFfYnVmLAorCQkJCSAgc3Ry dWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoKQoreworCXN0cnVjdCB4ZW5fZG1hYnVmX2F0 dGFjaG1lbnQgKnhlbl9kbWFidWZfYXR0YWNoID0gYXR0YWNoLT5wcml2OworCisJaWYgKHhlbl9k bWFidWZfYXR0YWNoKSB7CisJCXN0cnVjdCBzZ190YWJsZSAqc2d0ID0geGVuX2RtYWJ1Zl9hdHRh Y2gtPnNndDsKKworCQlpZiAoc2d0KSB7CisJCQlpZiAoeGVuX2RtYWJ1Zl9hdHRhY2gtPmRpciAh PSBETUFfTk9ORSkKKwkJCQlkbWFfdW5tYXBfc2dfYXR0cnMoYXR0YWNoLT5kZXYsIHNndC0+c2ds LAorCQkJCQkJICAgc2d0LT5uZW50cywKKwkJCQkJCSAgIHhlbl9kbWFidWZfYXR0YWNoLT5kaXIs CisJCQkJCQkgICBETUFfQVRUUl9TS0lQX0NQVV9TWU5DKTsKKwkJCXNnX2ZyZWVfdGFibGUoc2d0 KTsKKwkJfQorCisJCWtmcmVlKHNndCk7CisJCWtmcmVlKHhlbl9kbWFidWZfYXR0YWNoKTsKKwkJ YXR0YWNoLT5wcml2ID0gTlVMTDsKKwl9CisJLyogTWlnaHQgbmVlZCB0byB1bnBpbiB0aGUgcGFn ZXMgb2YgdGhlIGJ1ZmZlciBub3cuICovCit9CisKK3N0YXRpYyBzdHJ1Y3Qgc2dfdGFibGUgKgor ZG1hYnVmX2V4cF9vcHNfbWFwX2RtYV9idWYoc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0 YWNoLAorCQkJICAgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyKQoreworCXN0cnVjdCB4ZW5f ZG1hYnVmX2F0dGFjaG1lbnQgKnhlbl9kbWFidWZfYXR0YWNoID0gYXR0YWNoLT5wcml2OworCXN0 cnVjdCB4ZW5fZG1hYnVmICp4ZW5fZG1hYnVmID0gYXR0YWNoLT5kbWFidWYtPnByaXY7CisJc3Ry dWN0IHNnX3RhYmxlICpzZ3Q7CisKKwlwcl9kZWJ1ZygiTWFwcGluZyAlZCBwYWdlcyBmb3IgZGV2 ICVwXG4iLCB4ZW5fZG1hYnVmLT5ucl9wYWdlcywKKwkJIGF0dGFjaC0+ZGV2KTsKKworCWlmIChX QVJOX09OKGRpciA9PSBETUFfTk9ORSB8fCAheGVuX2RtYWJ1Zl9hdHRhY2gpKQorCQlyZXR1cm4g RVJSX1BUUigtRUlOVkFMKTsKKworCS8qIFJldHVybiB0aGUgY2FjaGVkIG1hcHBpbmcgd2hlbiBw b3NzaWJsZS4gKi8KKwlpZiAoeGVuX2RtYWJ1Zl9hdHRhY2gtPmRpciA9PSBkaXIpCisJCXJldHVy biB4ZW5fZG1hYnVmX2F0dGFjaC0+c2d0OworCisJLyoKKwkgKiBUd28gbWFwcGluZ3Mgd2l0aCBk aWZmZXJlbnQgZGlyZWN0aW9ucyBmb3IgdGhlIHNhbWUgYXR0YWNobWVudCBhcmUKKwkgKiBub3Qg YWxsb3dlZC4KKwkgKi8KKwlpZiAoV0FSTl9PTih4ZW5fZG1hYnVmX2F0dGFjaC0+ZGlyICE9IERN QV9OT05FKSkKKwkJcmV0dXJuIEVSUl9QVFIoLUVCVVNZKTsKKworCXNndCA9IGRtYWJ1Zl9wYWdl c190b19zZ3QoeGVuX2RtYWJ1Zi0+cGFnZXMsIHhlbl9kbWFidWYtPm5yX3BhZ2VzKTsKKwlpZiAo IUlTX0VSUihzZ3QpKSB7CisJCWlmICghZG1hX21hcF9zZ19hdHRycyhhdHRhY2gtPmRldiwgc2d0 LT5zZ2wsIHNndC0+bmVudHMsIGRpciwKKwkJCQkgICAgICBETUFfQVRUUl9TS0lQX0NQVV9TWU5D KSkgeworCQkJc2dfZnJlZV90YWJsZShzZ3QpOworCQkJa2ZyZWUoc2d0KTsKKwkJCXNndCA9IEVS Ul9QVFIoLUVOT01FTSk7CisJCX0gZWxzZSB7CisJCQl4ZW5fZG1hYnVmX2F0dGFjaC0+c2d0ID0g c2d0OworCQkJeGVuX2RtYWJ1Zl9hdHRhY2gtPmRpciA9IGRpcjsKKwkJfQorCX0KKwlpZiAoSVNf RVJSKHNndCkpCisJCXByX2VycigiRmFpbGVkIHRvIG1hcCBzZyB0YWJsZSBmb3IgZGV2ICVwXG4i LCBhdHRhY2gtPmRldik7CisJcmV0dXJuIHNndDsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4 cF9vcHNfdW5tYXBfZG1hX2J1ZihzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRhY2gsCisJ CQkJCSBzdHJ1Y3Qgc2dfdGFibGUgKnNndCwKKwkJCQkJIGVudW0gZG1hX2RhdGFfZGlyZWN0aW9u IGRpcikKK3sKKwkvKiBOb3QgaW1wbGVtZW50ZWQuIFRoZSB1bm1hcCBpcyBkb25lIGF0IGRtYWJ1 Zl9leHBfb3BzX2RldGFjaCgpLiAqLworfQorCitzdGF0aWMgdm9pZCBkbWFidWZfZXhwX3JlbGVh c2Uoc3RydWN0IGtyZWYgKmtyZWYpCit7CisJc3RydWN0IHhlbl9kbWFidWYgKnhlbl9kbWFidWYg PQorCQljb250YWluZXJfb2Yoa3JlZiwgc3RydWN0IHhlbl9kbWFidWYsIHUuZXhwLnJlZmNvdW50 KTsKKworCWRtYWJ1Zl9leHBfd2FpdF9vYmpfc2lnbmFsKHhlbl9kbWFidWYtPnByaXYsIHhlbl9k bWFidWYpOworCWxpc3RfZGVsKCZ4ZW5fZG1hYnVmLT5uZXh0KTsKKwlrZnJlZSh4ZW5fZG1hYnVm KTsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4cF9vcHNfcmVsZWFzZShzdHJ1Y3QgZG1hX2J1 ZiAqZG1hX2J1ZikKK3sKKwlzdHJ1Y3QgeGVuX2RtYWJ1ZiAqeGVuX2RtYWJ1ZiA9IGRtYV9idWYt PnByaXY7CisJc3RydWN0IGdudGRldl9wcml2ICpwcml2ID0geGVuX2RtYWJ1Zi0+cHJpdjsKKwor CWdudGRldl9yZW1vdmVfbWFwKHByaXYsIHhlbl9kbWFidWYtPnUuZXhwLm1hcCk7CisJbXV0ZXhf bG9jaygmcHJpdi0+ZG1hYnVmX2xvY2spOworCWtyZWZfcHV0KCZ4ZW5fZG1hYnVmLT51LmV4cC5y ZWZjb3VudCwgZG1hYnVmX2V4cF9yZWxlYXNlKTsKKwltdXRleF91bmxvY2soJnByaXYtPmRtYWJ1 Zl9sb2NrKTsKK30KKworc3RhdGljIHZvaWQgKmRtYWJ1Zl9leHBfb3BzX2ttYXBfYXRvbWljKHN0 cnVjdCBkbWFfYnVmICpkbWFfYnVmLAorCQkJCQl1bnNpZ25lZCBsb25nIHBhZ2VfbnVtKQorewor CS8qIE5vdCBpbXBsZW1lbnRlZC4gKi8KKwlyZXR1cm4gTlVMTDsKK30KKworc3RhdGljIHZvaWQg ZG1hYnVmX2V4cF9vcHNfa3VubWFwX2F0b21pYyhzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1ZiwKKwkJ CQkJIHVuc2lnbmVkIGxvbmcgcGFnZV9udW0sIHZvaWQgKmFkZHIpCit7CisJLyogTm90IGltcGxl bWVudGVkLiAqLworfQorCitzdGF0aWMgdm9pZCAqZG1hYnVmX2V4cF9vcHNfa21hcChzdHJ1Y3Qg ZG1hX2J1ZiAqZG1hX2J1ZiwKKwkJCQkgdW5zaWduZWQgbG9uZyBwYWdlX251bSkKK3sKKwkvKiBO b3QgaW1wbGVtZW50ZWQuICovCisJcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyB2b2lkIGRtYWJ1 Zl9leHBfb3BzX2t1bm1hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1ZiwKKwkJCQkgIHVuc2lnbmVk IGxvbmcgcGFnZV9udW0sIHZvaWQgKmFkZHIpCit7CisJLyogTm90IGltcGxlbWVudGVkLiAqLwor fQorCitzdGF0aWMgaW50IGRtYWJ1Zl9leHBfb3BzX21tYXAoc3RydWN0IGRtYV9idWYgKmRtYV9i dWYsCisJCQkgICAgICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCit7CisJLyogTm90IGlt cGxlbWVudGVkLiAqLworCXJldHVybiAwOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGRtYV9i dWZfb3BzIGRtYWJ1Zl9leHBfb3BzID0gIHsKKwkuYXR0YWNoID0gZG1hYnVmX2V4cF9vcHNfYXR0 YWNoLAorCS5kZXRhY2ggPSBkbWFidWZfZXhwX29wc19kZXRhY2gsCisJLm1hcF9kbWFfYnVmID0g ZG1hYnVmX2V4cF9vcHNfbWFwX2RtYV9idWYsCisJLnVubWFwX2RtYV9idWYgPSBkbWFidWZfZXhw X29wc191bm1hcF9kbWFfYnVmLAorCS5yZWxlYXNlID0gZG1hYnVmX2V4cF9vcHNfcmVsZWFzZSwK KwkubWFwID0gZG1hYnVmX2V4cF9vcHNfa21hcCwKKwkubWFwX2F0b21pYyA9IGRtYWJ1Zl9leHBf b3BzX2ttYXBfYXRvbWljLAorCS51bm1hcCA9IGRtYWJ1Zl9leHBfb3BzX2t1bm1hcCwKKwkudW5t YXBfYXRvbWljID0gZG1hYnVmX2V4cF9vcHNfa3VubWFwX2F0b21pYywKKwkubW1hcCA9IGRtYWJ1 Zl9leHBfb3BzX21tYXAsCit9OworCitzdGF0aWMgaW50IGRtYWJ1Zl9leHBvcnQoc3RydWN0IGdu dGRldl9wcml2ICpwcml2LCBzdHJ1Y3QgZ3JhbnRfbWFwICptYXAsCisJCQkgaW50ICpmZCkKK3sK KwlERUZJTkVfRE1BX0JVRl9FWFBPUlRfSU5GTyhleHBfaW5mbyk7CisJc3RydWN0IHhlbl9kbWFi dWYgKnhlbl9kbWFidWY7CisJaW50IHJldCA9IDA7CisKKwl4ZW5fZG1hYnVmID0ga3phbGxvYyhz aXplb2YoKnhlbl9kbWFidWYpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXhlbl9kbWFidWYpCisJCXJl dHVybiAtRU5PTUVNOworCisJa3JlZl9pbml0KCZ4ZW5fZG1hYnVmLT51LmV4cC5yZWZjb3VudCk7 CisKKwl4ZW5fZG1hYnVmLT5wcml2ID0gcHJpdjsKKwl4ZW5fZG1hYnVmLT5ucl9wYWdlcyA9IG1h cC0+Y291bnQ7CisJeGVuX2RtYWJ1Zi0+cGFnZXMgPSBtYXAtPnBhZ2VzOworCXhlbl9kbWFidWYt PnUuZXhwLm1hcCA9IG1hcDsKKworCWV4cF9pbmZvLmV4cF9uYW1lID0gS0JVSUxEX01PRE5BTUU7 CisJaWYgKG1hcC0+ZG1hX2Rldi0+ZHJpdmVyICYmIG1hcC0+ZG1hX2Rldi0+ZHJpdmVyLT5vd25l cikKKwkJZXhwX2luZm8ub3duZXIgPSBtYXAtPmRtYV9kZXYtPmRyaXZlci0+b3duZXI7CisJZWxz ZQorCQlleHBfaW5mby5vd25lciA9IFRISVNfTU9EVUxFOworCWV4cF9pbmZvLm9wcyA9ICZkbWFi dWZfZXhwX29wczsKKwlleHBfaW5mby5zaXplID0gbWFwLT5jb3VudCA8PCBQQUdFX1NISUZUOwor CWV4cF9pbmZvLmZsYWdzID0gT19SRFdSOworCWV4cF9pbmZvLnByaXYgPSB4ZW5fZG1hYnVmOwor CisJeGVuX2RtYWJ1Zi0+ZG1hYnVmID0gZG1hX2J1Zl9leHBvcnQoJmV4cF9pbmZvKTsKKwlpZiAo SVNfRVJSKHhlbl9kbWFidWYtPmRtYWJ1ZikpIHsKKwkJcmV0ID0gUFRSX0VSUih4ZW5fZG1hYnVm LT5kbWFidWYpOworCQl4ZW5fZG1hYnVmLT5kbWFidWYgPSBOVUxMOworCQlnb3RvIGZhaWw7CisJ fQorCisJcmV0ID0gZG1hX2J1Zl9mZCh4ZW5fZG1hYnVmLT5kbWFidWYsIE9fQ0xPRVhFQyk7CisJ aWYgKHJldCA8IDApCisJCWdvdG8gZmFpbDsKKworCXhlbl9kbWFidWYtPmZkID0gcmV0OworCSpm ZCA9IHJldDsKKworCXByX2RlYnVnKCJFeHBvcnRpbmcgRE1BIGJ1ZmZlciB3aXRoIGZkICVkXG4i LCByZXQpOworCisJbXV0ZXhfbG9jaygmcHJpdi0+ZG1hYnVmX2xvY2spOworCWxpc3RfYWRkKCZ4 ZW5fZG1hYnVmLT5uZXh0LCAmcHJpdi0+ZG1hYnVmX2V4cF9saXN0KTsKKwltdXRleF91bmxvY2so JnByaXYtPmRtYWJ1Zl9sb2NrKTsKKwlyZXR1cm4gMDsKKworZmFpbDoKKwlpZiAoeGVuX2RtYWJ1 Zi0+ZG1hYnVmKQorCQlkbWFfYnVmX3B1dCh4ZW5fZG1hYnVmLT5kbWFidWYpOworCWtmcmVlKHhl bl9kbWFidWYpOworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBzdHJ1Y3QgZ3JhbnRfbWFwICoK K2RtYWJ1Zl9leHBfYWxsb2NfYmFja2luZ19zdG9yYWdlKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJp diwgaW50IGRtYWJ1Zl9mbGFncywKKwkJCQkgaW50IGNvdW50KQoreworCXN0cnVjdCBncmFudF9t YXAgKm1hcDsKKworCWlmICh1bmxpa2VseShjb3VudCA8PSAwKSkKKwkJcmV0dXJuIEVSUl9QVFIo LUVJTlZBTCk7CisKKwlpZiAoKGRtYWJ1Zl9mbGFncyAmIEdOVERFVl9ETUFfRkxBR19XQykgJiYK KwkgICAgKGRtYWJ1Zl9mbGFncyAmIEdOVERFVl9ETUFfRkxBR19DT0hFUkVOVCkpIHsKKwkJcHJf ZXJyKCJXcm9uZyBkbWEtYnVmIGZsYWdzOiBlaXRoZXIgV0Mgb3IgY29oZXJlbnQsIG5vdCBib3Ro XG4iKTsKKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CisJfQorCisJbWFwID0gZ250ZGV2X2Fs bG9jX21hcChwcml2LCBjb3VudCwgZG1hYnVmX2ZsYWdzKTsKKwlpZiAoIW1hcCkKKwkJcmV0dXJu IEVSUl9QVFIoLUVOT01FTSk7CisKKwlpZiAodW5saWtlbHkoYXRvbWljX2FkZF9yZXR1cm4oY291 bnQsICZwYWdlc19tYXBwZWQpID4gbGltaXQpKSB7CisJCXByX2VycigiY2FuJ3QgbWFwOiBvdmVy IGxpbWl0XG4iKTsKKwkJZ250ZGV2X3B1dF9tYXAoTlVMTCwgbWFwKTsKKwkJcmV0dXJuIEVSUl9Q VFIoLUVOT01FTSk7CisJfQorCXJldHVybiBtYXA7CiB9CiAKIHN0YXRpYyBpbnQgZG1hYnVmX2V4 cF9mcm9tX3JlZnMoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBpbnQgZmxhZ3MsCiAJCQkJaW50 IGNvdW50LCB1MzIgZG9taWQsIHUzMiAqcmVmcywgdTMyICpmZCkKIHsKKwlzdHJ1Y3QgZ3JhbnRf bWFwICptYXA7CisJaW50IGksIHJldDsKKwogCSpmZCA9IC0xOwotCXJldHVybiAtRUlOVkFMOwor CisJaWYgKHVzZV9wdGVtb2QpIHsKKwkJcHJfZXJyKCJDYW5ub3QgcHJvdmlkZSBkbWEtYnVmOiB1 c2VfcHRlbW9kZSAlZFxuIiwKKwkJICAgICAgIHVzZV9wdGVtb2QpOworCQlyZXR1cm4gLUVJTlZB TDsKKwl9CisKKwltYXAgPSBkbWFidWZfZXhwX2FsbG9jX2JhY2tpbmdfc3RvcmFnZShwcml2LCBm bGFncywgY291bnQpOworCWlmIChJU19FUlIobWFwKSkKKwkJcmV0dXJuIFBUUl9FUlIobWFwKTsK KworCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisJCW1hcC0+Z3JhbnRzW2ldLmRvbWlk ID0gZG9taWQ7CisJCW1hcC0+Z3JhbnRzW2ldLnJlZiA9IHJlZnNbaV07CisJfQorCisJbXV0ZXhf bG9jaygmcHJpdi0+bG9jayk7CisJZ250ZGV2X2FkZF9tYXAocHJpdiwgbWFwKTsKKwltdXRleF91 bmxvY2soJnByaXYtPmxvY2spOworCisJbWFwLT5mbGFncyB8PSBHTlRNQVBfaG9zdF9tYXA7Cisj aWYgZGVmaW5lZChDT05GSUdfWDg2KQorCW1hcC0+ZmxhZ3MgfD0gR05UTUFQX2RldmljZV9tYXA7 CisjZW5kaWYKKworCXJldCA9IG1hcF9ncmFudF9wYWdlcyhtYXApOworCWlmIChyZXQgPCAwKQor CQlnb3RvIG91dDsKKworCXJldCA9IGRtYWJ1Zl9leHBvcnQocHJpdiwgbWFwLCBmZCk7CisJaWYg KHJldCA8IDApCisJCWdvdG8gb3V0OworCisJcmV0dXJuIDA7CisKK291dDoKKwlnbnRkZXZfcmVt b3ZlX21hcChwcml2LCBtYXApOworCXJldHVybiByZXQ7CiB9CiAKIC8qIC0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwot LSAKMi4xNy4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcK aHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mail-wm0-f66.google.com ([74.125.82.66]:53818 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966674AbeEYPdy (ORCPT ); Fri, 25 May 2018 11:33:54 -0400 From: Oleksandr Andrushchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: daniel.vetter@intel.com, andr2000@gmail.com, dongwon.kim@intel.com, matthew.d.roper@intel.com, Oleksandr Andrushchenko Subject: [PATCH 6/8] xen/gntdev: Implement dma-buf export functionality Date: Fri, 25 May 2018 18:33:29 +0300 Message-Id: <20180525153331.31188-7-andr2000@gmail.com> In-Reply-To: <20180525153331.31188-1-andr2000@gmail.com> References: <20180525153331.31188-1-andr2000@gmail.com> Sender: linux-media-owner@vger.kernel.org List-ID: From: Oleksandr Andrushchenko 1. Create a dma-buf from grant references provided by the foreign domain. By default dma-buf is backed by system memory pages, but by providing GNTDEV_DMA_FLAG_XXX flags it can also be created as a DMA write-combine/coherent buffer, e.g. allocated with corresponding dma_alloc_xxx API. Export the resulting buffer as a new dma-buf. 2. Implement waiting for the dma-buf to be released: block until the dma-buf with the file descriptor provided is released. If within the time-out provided the buffer is not released then -ETIMEDOUT error is returned. If the buffer with the file descriptor does not exist or has already been released, then -ENOENT is returned. For valid file descriptors this must not be treated as error. Signed-off-by: Oleksandr Andrushchenko --- drivers/xen/gntdev.c | 478 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 476 insertions(+), 2 deletions(-) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 9e450622af1a..52abc6cd5846 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -4,6 +4,8 @@ * Device for accessing (in user-space) pages that have been granted by other * domains. * + * DMA buffer implementation is based on drivers/gpu/drm/drm_prime.c. + * * Copyright (c) 2006-2007, D G Murray. * (c) 2009 Gerd Hoffmann * (c) 2018 Oleksandr Andrushchenko, EPAM Systems Inc. @@ -41,6 +43,9 @@ #ifdef CONFIG_XEN_GRANT_DMA_ALLOC #include #endif +#ifdef CONFIG_XEN_GNTDEV_DMABUF +#include +#endif #include #include @@ -81,6 +86,17 @@ struct gntdev_priv { /* Device for which DMA memory is allocated. */ struct device *dma_dev; #endif + +#ifdef CONFIG_XEN_GNTDEV_DMABUF + /* Private data of the hyper DMA buffers. */ + + /* List of exported DMA buffers. */ + struct list_head dmabuf_exp_list; + /* List of wait objects. */ + struct list_head dmabuf_exp_wait_list; + /* This is the lock which protects dma_buf_xxx lists. */ + struct mutex dmabuf_lock; +#endif }; struct unmap_notify { @@ -125,12 +141,38 @@ struct grant_map { #ifdef CONFIG_XEN_GNTDEV_DMABUF struct xen_dmabuf { + struct gntdev_priv *priv; + struct dma_buf *dmabuf; + struct list_head next; + int fd; + union { + struct { + /* Exported buffers are reference counted. */ + struct kref refcount; + struct grant_map *map; + } exp; struct { /* Granted references of the imported buffer. */ grant_ref_t *refs; } imp; } u; + + /* Number of pages this buffer has. */ + int nr_pages; + /* Pages of this buffer. */ + struct page **pages; +}; + +struct xen_dmabuf_wait_obj { + struct list_head next; + struct xen_dmabuf *xen_dmabuf; + struct completion completion; +}; + +struct xen_dmabuf_attachment { + struct sg_table *sgt; + enum dma_data_direction dir; }; #endif @@ -320,6 +362,16 @@ static void gntdev_put_map(struct gntdev_priv *priv, struct grant_map *map) gntdev_free_map(map); } +#ifdef CONFIG_XEN_GNTDEV_DMABUF +static void gntdev_remove_map(struct gntdev_priv *priv, struct grant_map *map) +{ + mutex_lock(&priv->lock); + list_del(&map->next); + gntdev_put_map(NULL /* already removed */, map); + mutex_unlock(&priv->lock); +} +#endif + /* ------------------------------------------------------------------ */ static int find_grant_ptes(pte_t *pte, pgtable_t token, @@ -628,6 +680,12 @@ static int gntdev_open(struct inode *inode, struct file *flip) INIT_LIST_HEAD(&priv->freeable_maps); mutex_init(&priv->lock); +#ifdef CONFIG_XEN_GNTDEV_DMABUF + mutex_init(&priv->dmabuf_lock); + INIT_LIST_HEAD(&priv->dmabuf_exp_list); + INIT_LIST_HEAD(&priv->dmabuf_exp_wait_list); +#endif + if (use_ptemod) { priv->mm = get_task_mm(current); if (!priv->mm) { @@ -1053,17 +1111,433 @@ static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u) /* DMA buffer export support. */ /* ------------------------------------------------------------------ */ +/* ------------------------------------------------------------------ */ +/* Implementation of wait for exported DMA buffer to be released. */ +/* ------------------------------------------------------------------ */ + +static void dmabuf_exp_release(struct kref *kref); + +static struct xen_dmabuf_wait_obj * +dmabuf_exp_wait_obj_new(struct gntdev_priv *priv, + struct xen_dmabuf *xen_dmabuf) +{ + struct xen_dmabuf_wait_obj *obj; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return ERR_PTR(-ENOMEM); + + init_completion(&obj->completion); + obj->xen_dmabuf = xen_dmabuf; + + mutex_lock(&priv->dmabuf_lock); + list_add(&obj->next, &priv->dmabuf_exp_wait_list); + /* Put our reference and wait for xen_dmabuf's release to fire. */ + kref_put(&xen_dmabuf->u.exp.refcount, dmabuf_exp_release); + mutex_unlock(&priv->dmabuf_lock); + return obj; +} + +static void dmabuf_exp_wait_obj_free(struct gntdev_priv *priv, + struct xen_dmabuf_wait_obj *obj) +{ + struct xen_dmabuf_wait_obj *cur_obj, *q; + + mutex_lock(&priv->dmabuf_lock); + list_for_each_entry_safe(cur_obj, q, &priv->dmabuf_exp_wait_list, next) + if (cur_obj == obj) { + list_del(&obj->next); + kfree(obj); + break; + } + mutex_unlock(&priv->dmabuf_lock); +} + +static int dmabuf_exp_wait_obj_wait(struct xen_dmabuf_wait_obj *obj, + u32 wait_to_ms) +{ + if (wait_for_completion_timeout(&obj->completion, + msecs_to_jiffies(wait_to_ms)) <= 0) + return -ETIMEDOUT; + + return 0; +} + +static void dmabuf_exp_wait_obj_signal(struct gntdev_priv *priv, + struct xen_dmabuf *xen_dmabuf) +{ + struct xen_dmabuf_wait_obj *obj, *q; + + list_for_each_entry_safe(obj, q, &priv->dmabuf_exp_wait_list, next) + if (obj->xen_dmabuf == xen_dmabuf) { + pr_debug("Found xen_dmabuf in the wait list, wake\n"); + complete_all(&obj->completion); + } +} + +static struct xen_dmabuf * +dmabuf_exp_wait_obj_get_by_fd(struct gntdev_priv *priv, int fd) +{ + struct xen_dmabuf *q, *xen_dmabuf, *ret = ERR_PTR(-ENOENT); + + mutex_lock(&priv->dmabuf_lock); + list_for_each_entry_safe(xen_dmabuf, q, &priv->dmabuf_exp_list, next) + if (xen_dmabuf->fd == fd) { + pr_debug("Found xen_dmabuf in the wait list\n"); + kref_get(&xen_dmabuf->u.exp.refcount); + ret = xen_dmabuf; + break; + } + mutex_unlock(&priv->dmabuf_lock); + return ret; +} + static int dmabuf_exp_wait_released(struct gntdev_priv *priv, int fd, int wait_to_ms) { - return -ETIMEDOUT; + struct xen_dmabuf *xen_dmabuf; + struct xen_dmabuf_wait_obj *obj; + int ret; + + pr_debug("Will wait for dma-buf with fd %d\n", fd); + /* + * Try to find the DMA buffer: if not found means that + * either the buffer has already been released or file descriptor + * provided is wrong. + */ + xen_dmabuf = dmabuf_exp_wait_obj_get_by_fd(priv, fd); + if (IS_ERR(xen_dmabuf)) + return PTR_ERR(xen_dmabuf); + + /* + * xen_dmabuf still exists and is reference count locked by us now, + * so prepare to wait: allocate wait object and add it to the wait list, + * so we can find it on release. + */ + obj = dmabuf_exp_wait_obj_new(priv, xen_dmabuf); + if (IS_ERR(obj)) { + pr_err("Failed to setup wait object, ret %ld\n", PTR_ERR(obj)); + return PTR_ERR(obj); + } + + ret = dmabuf_exp_wait_obj_wait(obj, wait_to_ms); + dmabuf_exp_wait_obj_free(priv, obj); + return ret; +} + +/* ------------------------------------------------------------------ */ +/* DMA buffer export support. */ +/* ------------------------------------------------------------------ */ + +static struct sg_table * +dmabuf_pages_to_sgt(struct page **pages, unsigned int nr_pages) +{ + struct sg_table *sgt; + int ret; + + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) { + ret = -ENOMEM; + goto out; + } + + ret = sg_alloc_table_from_pages(sgt, pages, nr_pages, 0, + nr_pages << PAGE_SHIFT, + GFP_KERNEL); + if (ret) + goto out; + + return sgt; + +out: + kfree(sgt); + return ERR_PTR(ret); +} + +static int dmabuf_exp_ops_attach(struct dma_buf *dma_buf, + struct device *target_dev, + struct dma_buf_attachment *attach) +{ + struct xen_dmabuf_attachment *xen_dmabuf_attach; + + xen_dmabuf_attach = kzalloc(sizeof(*xen_dmabuf_attach), GFP_KERNEL); + if (!xen_dmabuf_attach) + return -ENOMEM; + + xen_dmabuf_attach->dir = DMA_NONE; + attach->priv = xen_dmabuf_attach; + /* Might need to pin the pages of the buffer now. */ + return 0; +} + +static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf, + struct dma_buf_attachment *attach) +{ + struct xen_dmabuf_attachment *xen_dmabuf_attach = attach->priv; + + if (xen_dmabuf_attach) { + struct sg_table *sgt = xen_dmabuf_attach->sgt; + + if (sgt) { + if (xen_dmabuf_attach->dir != DMA_NONE) + dma_unmap_sg_attrs(attach->dev, sgt->sgl, + sgt->nents, + xen_dmabuf_attach->dir, + DMA_ATTR_SKIP_CPU_SYNC); + sg_free_table(sgt); + } + + kfree(sgt); + kfree(xen_dmabuf_attach); + attach->priv = NULL; + } + /* Might need to unpin the pages of the buffer now. */ +} + +static struct sg_table * +dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach, + enum dma_data_direction dir) +{ + struct xen_dmabuf_attachment *xen_dmabuf_attach = attach->priv; + struct xen_dmabuf *xen_dmabuf = attach->dmabuf->priv; + struct sg_table *sgt; + + pr_debug("Mapping %d pages for dev %p\n", xen_dmabuf->nr_pages, + attach->dev); + + if (WARN_ON(dir == DMA_NONE || !xen_dmabuf_attach)) + return ERR_PTR(-EINVAL); + + /* Return the cached mapping when possible. */ + if (xen_dmabuf_attach->dir == dir) + return xen_dmabuf_attach->sgt; + + /* + * Two mappings with different directions for the same attachment are + * not allowed. + */ + if (WARN_ON(xen_dmabuf_attach->dir != DMA_NONE)) + return ERR_PTR(-EBUSY); + + sgt = dmabuf_pages_to_sgt(xen_dmabuf->pages, xen_dmabuf->nr_pages); + if (!IS_ERR(sgt)) { + if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, + DMA_ATTR_SKIP_CPU_SYNC)) { + sg_free_table(sgt); + kfree(sgt); + sgt = ERR_PTR(-ENOMEM); + } else { + xen_dmabuf_attach->sgt = sgt; + xen_dmabuf_attach->dir = dir; + } + } + if (IS_ERR(sgt)) + pr_err("Failed to map sg table for dev %p\n", attach->dev); + return sgt; +} + +static void dmabuf_exp_ops_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ + /* Not implemented. The unmap is done at dmabuf_exp_ops_detach(). */ +} + +static void dmabuf_exp_release(struct kref *kref) +{ + struct xen_dmabuf *xen_dmabuf = + container_of(kref, struct xen_dmabuf, u.exp.refcount); + + dmabuf_exp_wait_obj_signal(xen_dmabuf->priv, xen_dmabuf); + list_del(&xen_dmabuf->next); + kfree(xen_dmabuf); +} + +static void dmabuf_exp_ops_release(struct dma_buf *dma_buf) +{ + struct xen_dmabuf *xen_dmabuf = dma_buf->priv; + struct gntdev_priv *priv = xen_dmabuf->priv; + + gntdev_remove_map(priv, xen_dmabuf->u.exp.map); + mutex_lock(&priv->dmabuf_lock); + kref_put(&xen_dmabuf->u.exp.refcount, dmabuf_exp_release); + mutex_unlock(&priv->dmabuf_lock); +} + +static void *dmabuf_exp_ops_kmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num) +{ + /* Not implemented. */ + return NULL; +} + +static void dmabuf_exp_ops_kunmap_atomic(struct dma_buf *dma_buf, + unsigned long page_num, void *addr) +{ + /* Not implemented. */ +} + +static void *dmabuf_exp_ops_kmap(struct dma_buf *dma_buf, + unsigned long page_num) +{ + /* Not implemented. */ + return NULL; +} + +static void dmabuf_exp_ops_kunmap(struct dma_buf *dma_buf, + unsigned long page_num, void *addr) +{ + /* Not implemented. */ +} + +static int dmabuf_exp_ops_mmap(struct dma_buf *dma_buf, + struct vm_area_struct *vma) +{ + /* Not implemented. */ + return 0; +} + +static const struct dma_buf_ops dmabuf_exp_ops = { + .attach = dmabuf_exp_ops_attach, + .detach = dmabuf_exp_ops_detach, + .map_dma_buf = dmabuf_exp_ops_map_dma_buf, + .unmap_dma_buf = dmabuf_exp_ops_unmap_dma_buf, + .release = dmabuf_exp_ops_release, + .map = dmabuf_exp_ops_kmap, + .map_atomic = dmabuf_exp_ops_kmap_atomic, + .unmap = dmabuf_exp_ops_kunmap, + .unmap_atomic = dmabuf_exp_ops_kunmap_atomic, + .mmap = dmabuf_exp_ops_mmap, +}; + +static int dmabuf_export(struct gntdev_priv *priv, struct grant_map *map, + int *fd) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct xen_dmabuf *xen_dmabuf; + int ret = 0; + + xen_dmabuf = kzalloc(sizeof(*xen_dmabuf), GFP_KERNEL); + if (!xen_dmabuf) + return -ENOMEM; + + kref_init(&xen_dmabuf->u.exp.refcount); + + xen_dmabuf->priv = priv; + xen_dmabuf->nr_pages = map->count; + xen_dmabuf->pages = map->pages; + xen_dmabuf->u.exp.map = map; + + exp_info.exp_name = KBUILD_MODNAME; + if (map->dma_dev->driver && map->dma_dev->driver->owner) + exp_info.owner = map->dma_dev->driver->owner; + else + exp_info.owner = THIS_MODULE; + exp_info.ops = &dmabuf_exp_ops; + exp_info.size = map->count << PAGE_SHIFT; + exp_info.flags = O_RDWR; + exp_info.priv = xen_dmabuf; + + xen_dmabuf->dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(xen_dmabuf->dmabuf)) { + ret = PTR_ERR(xen_dmabuf->dmabuf); + xen_dmabuf->dmabuf = NULL; + goto fail; + } + + ret = dma_buf_fd(xen_dmabuf->dmabuf, O_CLOEXEC); + if (ret < 0) + goto fail; + + xen_dmabuf->fd = ret; + *fd = ret; + + pr_debug("Exporting DMA buffer with fd %d\n", ret); + + mutex_lock(&priv->dmabuf_lock); + list_add(&xen_dmabuf->next, &priv->dmabuf_exp_list); + mutex_unlock(&priv->dmabuf_lock); + return 0; + +fail: + if (xen_dmabuf->dmabuf) + dma_buf_put(xen_dmabuf->dmabuf); + kfree(xen_dmabuf); + return ret; +} + +static struct grant_map * +dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags, + int count) +{ + struct grant_map *map; + + if (unlikely(count <= 0)) + return ERR_PTR(-EINVAL); + + if ((dmabuf_flags & GNTDEV_DMA_FLAG_WC) && + (dmabuf_flags & GNTDEV_DMA_FLAG_COHERENT)) { + pr_err("Wrong dma-buf flags: either WC or coherent, not both\n"); + return ERR_PTR(-EINVAL); + } + + map = gntdev_alloc_map(priv, count, dmabuf_flags); + if (!map) + return ERR_PTR(-ENOMEM); + + if (unlikely(atomic_add_return(count, &pages_mapped) > limit)) { + pr_err("can't map: over limit\n"); + gntdev_put_map(NULL, map); + return ERR_PTR(-ENOMEM); + } + return map; } static int dmabuf_exp_from_refs(struct gntdev_priv *priv, int flags, int count, u32 domid, u32 *refs, u32 *fd) { + struct grant_map *map; + int i, ret; + *fd = -1; - return -EINVAL; + + if (use_ptemod) { + pr_err("Cannot provide dma-buf: use_ptemode %d\n", + use_ptemod); + return -EINVAL; + } + + map = dmabuf_exp_alloc_backing_storage(priv, flags, count); + if (IS_ERR(map)) + return PTR_ERR(map); + + for (i = 0; i < count; i++) { + map->grants[i].domid = domid; + map->grants[i].ref = refs[i]; + } + + mutex_lock(&priv->lock); + gntdev_add_map(priv, map); + mutex_unlock(&priv->lock); + + map->flags |= GNTMAP_host_map; +#if defined(CONFIG_X86) + map->flags |= GNTMAP_device_map; +#endif + + ret = map_grant_pages(map); + if (ret < 0) + goto out; + + ret = dmabuf_export(priv, map, fd); + if (ret < 0) + goto out; + + return 0; + +out: + gntdev_remove_map(priv, map); + return ret; } /* ------------------------------------------------------------------ */ -- 2.17.0