From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael S. Tsirkin" Subject: Re: [PATCH v3 4/4] Add virtio gpu driver. Date: Tue, 2 Jun 2015 10:33:26 +0200 Message-ID: <20150602102929-mutt-send-email-mst@redhat.com> References: <1432300312-24792-1-git-send-email-kraxel@redhat.com> <1432300312-24792-5-git-send-email-kraxel@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Content-Disposition: inline In-Reply-To: <1432300312-24792-5-git-send-email-kraxel@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Gerd Hoffmann Cc: "open list:ABI/API" , open list , dri-devel@lists.freedesktop.org, "open list:VIRTIO CORE, NET..." , airlied@redhat.com List-Id: linux-api@vger.kernel.org T24gRnJpLCBNYXkgMjIsIDIwMTUgYXQgMDM6MTE6NTJQTSArMDIwMCwgR2VyZCBIb2ZmbWFubiB3 cm90ZToKPiBGcm9tOiBEYXZlIEFpcmxpZSA8YWlybGllZEBnbWFpbC5jb20+Cj4gCj4gVGhpcyBw YXRjaCBhZGRzIGEga21zIGRyaXZlciBmb3IgdGhlIHZpcnRpbyBncHUuICBUaGUgeG9yZyBtb2Rl c2V0dGluZwo+IGRyaXZlciBjYW4gaGFuZGxlIHRoZSBkZXZpY2UganVzdCBmaW5lLCB0aGUgZnJh bWVidWZmZXIgZm9yIGZiY29uIGlzCj4gdGhlcmUgdG9vLgo+IAo+IFFlbXUgcGF0Y2hlcyBmb3Ig dGhlIGhvc3Qgc2lkZSBhcmUgdW5kZXIgcmV2aWV3IGN1cnJlbnRseS4KPiAKPiBUaGUgcGNpIHZl cnNpb24gb2YgdGhlIGRldmljZSBjb21lcyBpbiB0d28gdmFyaWFudHM6IHdpdGggYW5kIHdpdGhv dXQKPiB2Z2EgY29tcGF0aWJpbGl0eS4gIFRoZSBmb3JtZXIgaGFzIGEgZXh0cmEgbWVtb3J5IGJh ciBmb3IgdGhlIHZnYQo+IGZyYW1lYnVmZmVyLCB0aGUgbGF0ZXIgaXMgYSBwdXJlIHZpcnRpbyBk ZXZpY2UuICBUaGUgb25seSBjb25jZXJuIGZvcgo+IHRoaXMgZHJpdmVyIGlzIHRoYXQgaW4gdGhl IHZpcnRpby12Z2EgY2FzZSB3ZSBoYXZlIHRvIGtpY2sgb3V0IHRoZQo+IGZpcm13YXJlIGZyYW1l YnVmZmVyLgo+IAo+IEluaXRpYWwgcmV2aXNpb24gaGFzIG9ubHkgMmQgc3VwcG9ydCwgM2QgKHZp cmdsKSBzdXBwb3J0IHJlcXVpcmVzCj4gc29tZSBtb3JlIHdvcmsgb24gdGhlIHFlbXUgc2lkZSBh bmQgd2lsbCBiZSBhZGRlZCBsYXRlci4KPiAKPiBTaWduZWQtb2ZmLWJ5OiBEYXZlIEFpcmxpZSA8 YWlybGllZEByZWRoYXQuY29tPgo+IFNpZ25lZC1vZmYtYnk6IEdlcmQgSG9mZm1hbm4gPGtyYXhl bEByZWRoYXQuY29tPgoKSSB0aGluayBpdCdzIG9rIHRvIG1lcmdlIHRoaXMgdGhyb3VnaCB0aGUg ZHJpIHRyZWUuCkFja2VkLWJ5OiBNaWNoYWVsIFMuIFRzaXJraW4gPG1zdEByZWRoYXQuY29tPgoK PiAtLS0KPiAgZHJpdmVycy9ncHUvZHJtL0tjb25maWcgICAgICAgICAgICAgICAgICB8ICAgMiAr Cj4gIGRyaXZlcnMvZ3B1L2RybS9NYWtlZmlsZSAgICAgICAgICAgICAgICAgfCAgIDEgKwo+ICBk cml2ZXJzL2dwdS9kcm0vdmlydGlvL0tjb25maWcgICAgICAgICAgIHwgIDE0ICsKPiAgZHJpdmVy cy9ncHUvZHJtL3ZpcnRpby9NYWtlZmlsZSAgICAgICAgICB8ICAxMSArCj4gIGRyaXZlcnMvZ3B1 L2RybS92aXJ0aW8vdmlydGdwdV9kZWJ1Z2ZzLmMgfCAgNjQgKysrKwo+ICBkcml2ZXJzL2dwdS9k cm0vdmlydGlvL3ZpcnRncHVfZGlzcGxheS5jIHwgNDg1ICsrKysrKysrKysrKysrKysrKysrKysr Kwo+ICBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJtX2J1cy5jIHwgIDkxICsrKysr Cj4gIGRyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9kcnYuYyAgICAgfCAxMzYgKysrKysr Kwo+ICBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmggICAgIHwgMzUwICsrKysr KysrKysrKysrKysrKwo+ICBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZmIuYyAgICAg IHwgNDMxICsrKysrKysrKysrKysrKysrKysrKysKPiAgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92 aXJ0Z3B1X2ZlbmNlLmMgICB8IDExOSArKysrKysKPiAgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92 aXJ0Z3B1X2dlbS5jICAgICB8IDE0MCArKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS92aXJ0aW8v dmlydGdwdV9rbXMuYyAgICAgfCAxNjQgKysrKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS92aXJ0 aW8vdmlydGdwdV9vYmplY3QuYyAgfCAxNzAgKysrKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS92 aXJ0aW8vdmlydGdwdV9wbGFuZS5jICAgfCAxMjAgKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS92 aXJ0aW8vdmlydGdwdV90dG0uYyAgICAgfCA0NjkgKysrKysrKysrKysrKysrKysrKysrKysKPiAg ZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X3ZxLmMgICAgICB8IDYxNCArKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrCj4gIGluY2x1ZGUvZHJtL2RybVAuaCAgICAgICAgICAgICAg ICAgICAgICAgfCAgIDEgKwo+ICBpbmNsdWRlL3VhcGkvbGludXgvS2J1aWxkICAgICAgICAgICAg ICAgIHwgICAxICsKPiAgaW5jbHVkZS91YXBpL2xpbnV4L3ZpcnRpb19ncHUuaCAgICAgICAgICB8 IDIwNCArKysrKysrKysrCj4gIGluY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9faWRzLmggICAgICAg ICAgfCAgIDEgKwo+ICAyMSBmaWxlcyBjaGFuZ2VkLCAzNTg4IGluc2VydGlvbnMoKykKPiAgY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS92aXJ0aW8vS2NvbmZpZwo+ICBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby9NYWtlZmlsZQo+ICBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2RlYnVnZnMuYwo+ICBjcmVh dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2Rpc3BsYXkuYwo+ ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2RybV9i dXMuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1 X2Rydi5jCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRn cHVfZHJ2LmgKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmly dGdwdV9mYi5jCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3Zp cnRncHVfZmVuY2UuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3ZpcnRp by92aXJ0Z3B1X2dlbS5jCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vdmly dGlvL3ZpcnRncHVfa21zLmMKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS92 aXJ0aW8vdmlydGdwdV9vYmplY3QuYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUv ZHJtL3ZpcnRpby92aXJ0Z3B1X3BsYW5lLmMKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMv Z3B1L2RybS92aXJ0aW8vdmlydGdwdV90dG0uYwo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X3ZxLmMKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGluY2x1 ZGUvdWFwaS9saW51eC92aXJ0aW9fZ3B1LmgKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUv ZHJtL0tjb25maWcgYi9kcml2ZXJzL2dwdS9kcm0vS2NvbmZpZwo+IGluZGV4IDQ3ZjJjZTguLmQ0 YjY1NDUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL0tjb25maWcKPiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vS2NvbmZpZwo+IEBAIC0yMDYsNiArMjA2LDggQEAgc291cmNlICJkcml2ZXJz L2dwdS9kcm0vcXhsL0tjb25maWciCj4gIAo+ICBzb3VyY2UgImRyaXZlcnMvZ3B1L2RybS9ib2No cy9LY29uZmlnIgo+ICAKPiArc291cmNlICJkcml2ZXJzL2dwdS9kcm0vdmlydGlvL0tjb25maWci Cj4gKwo+ICBzb3VyY2UgImRyaXZlcnMvZ3B1L2RybS9tc20vS2NvbmZpZyIKPiAgCj4gIHNvdXJj ZSAiZHJpdmVycy9ncHUvZHJtL3RlZ3JhL0tjb25maWciCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv Z3B1L2RybS9NYWtlZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS9NYWtlZmlsZQo+IGluZGV4IDdkNDk0 NGUuLmRiYmMxMDEgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlCj4gKysr IGIvZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlCj4gQEAgLTYzLDYgKzYzLDcgQEAgb2JqLSQoQ09O RklHX0RSTV9PTUFQKQkrPSBvbWFwZHJtLwo+ICBvYmotJChDT05GSUdfRFJNX1RJTENEQykJKz0g dGlsY2RjLwo+ICBvYmotJChDT05GSUdfRFJNX1FYTCkgKz0gcXhsLwo+ICBvYmotJChDT05GSUdf RFJNX0JPQ0hTKSArPSBib2Nocy8KPiArb2JqLSQoQ09ORklHX0RSTV9WSVJUSU9fR1BVKSArPSB2 aXJ0aW8vCj4gIG9iai0kKENPTkZJR19EUk1fTVNNKSArPSBtc20vCj4gIG9iai0kKENPTkZJR19E Uk1fVEVHUkEpICs9IHRlZ3JhLwo+ICBvYmotJChDT05GSUdfRFJNX1NUSSkgKz0gc3RpLwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL0tjb25maWcgYi9kcml2ZXJzL2dwdS9k cm0vdmlydGlvL0tjb25maWcKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAu Ljk5ODNlYWQKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby9L Y29uZmlnCj4gQEAgLTAsMCArMSwxNCBAQAo+ICtjb25maWcgRFJNX1ZJUlRJT19HUFUKPiArCXRy aXN0YXRlICJWaXJ0aW8gR1BVIGRyaXZlciIKPiArCWRlcGVuZHMgb24gRFJNICYmIFZJUlRJTwo+ ICsJc2VsZWN0IEZCX1NZU19GSUxMUkVDVAo+ICsJc2VsZWN0IEZCX1NZU19DT1BZQVJFQQo+ICsJ c2VsZWN0IEZCX1NZU19JTUFHRUJMSVQKPiArICAgICAgICBzZWxlY3QgRFJNX0tNU19IRUxQRVIK PiArICAgICAgICBzZWxlY3QgRFJNX0tNU19GQl9IRUxQRVIKPiArICAgICAgICBzZWxlY3QgRFJN X1RUTQo+ICsJaGVscAo+ICsJICAgVGhpcyBpcyB0aGUgdmlydHVhbCBHUFUgZHJpdmVyIGZvciB2 aXJ0aW8uICBJdCBjYW4gYmUgdXNlZCB3aXRoCj4gKyAgICAgICAgICAgUUVNVSBiYXNlZCBWTU1z IChsaWtlIEtWTSBvciBYZW4pLgo+ICsKPiArCSAgIElmIHVuc3VyZSBzYXkgTS4KPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby9NYWtlZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS92 aXJ0aW8vTWFrZWZpbGUKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjJl ZTE2MDIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby9NYWtl ZmlsZQo+IEBAIC0wLDAgKzEsMTEgQEAKPiArIwo+ICsjIE1ha2VmaWxlIGZvciB0aGUgZHJtIGRl dmljZSBkcml2ZXIuICBUaGlzIGRyaXZlciBwcm92aWRlcyBzdXBwb3J0IGZvciB0aGUKPiArIyBE aXJlY3QgUmVuZGVyaW5nIEluZnJhc3RydWN0dXJlIChEUkkpIGluIFhGcmVlODYgNC4xLjAgYW5k IGhpZ2hlci4KPiArCj4gK2NjZmxhZ3MteSA6PSAtSWluY2x1ZGUvZHJtCj4gKwo+ICt2aXJ0aW8t Z3B1LXkgOj0gdmlydGdwdV9kcnYubyB2aXJ0Z3B1X2ttcy5vIHZpcnRncHVfZHJtX2J1cy5vIHZp cnRncHVfZ2VtLm8gXAo+ICsJdmlydGdwdV9mYi5vIHZpcnRncHVfZGlzcGxheS5vIHZpcnRncHVf dnEubyB2aXJ0Z3B1X3R0bS5vIFwKPiArCXZpcnRncHVfZmVuY2UubyB2aXJ0Z3B1X29iamVjdC5v IHZpcnRncHVfZGVidWdmcy5vIHZpcnRncHVfcGxhbmUubwo+ICsKPiArb2JqLSQoQ09ORklHX0RS TV9WSVJUSU9fR1BVKSArPSB2aXJ0aW8tZ3B1Lm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUv ZHJtL3ZpcnRpby92aXJ0Z3B1X2RlYnVnZnMuYyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmly dGdwdV9kZWJ1Z2ZzLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLmRi OGI0OTEKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0 Z3B1X2RlYnVnZnMuYwo+IEBAIC0wLDAgKzEsNjQgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChD KSAyMDE1IFJlZCBIYXQsIEluYy4KPiArICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPiArICoKPiAr ICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBw ZXJzb24gb2J0YWluaW5nCj4gKyAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lh dGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQo+ICsgKiAiU29mdHdhcmUiKSwgdG8gZGVhbCBp biB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCj4gKyAqIHdpdGhv dXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVi bGlzaCwKPiArICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9m IHRoZSBTb2Z0d2FyZSwgYW5kIHRvCj4gKyAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNv ZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwo+ICsgKiB0aGUgZm9sbG93 aW5nIGNvbmRpdGlvbnM6Cj4gKyAqCj4gKyAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFu ZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCj4gKyAqIG5leHQgcGFyYWdy YXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsCj4gKyAq IHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KPiArICoKPiArICogVEhFIFNPRlRXQVJFIElTIFBS T1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCj4gKyAqIEVYUFJF U1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElF UyBPRgo+ICsgKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQ T1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCj4gKyAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZ UklHSFQgT1dORVIoUykgQU5EL09SIElUUyBTVVBQTElFUlMgQkUKPiArICogTElBQkxFIEZPUiBB TlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElP Tgo+ICsgKiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VU IE9GIE9SIElOIENPTk5FQ1RJT04KPiArICogV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBP UiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUg PGxpbnV4L2RlYnVnZnMuaD4KPiArCj4gKyNpbmNsdWRlICJkcm1QLmgiCj4gKyNpbmNsdWRlICJ2 aXJ0Z3B1X2Rydi5oIgo+ICsKPiArc3RhdGljIGludAo+ICt2aXJ0aW9fZ3B1X2RlYnVnZnNfaXJx X2luZm8oc3RydWN0IHNlcV9maWxlICptLCB2b2lkICpkYXRhKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJt X2luZm9fbm9kZSAqbm9kZSA9IChzdHJ1Y3QgZHJtX2luZm9fbm9kZSAqKSBtLT5wcml2YXRlOwo+ ICsJc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiA9IG5vZGUtPm1pbm9yLT5kZXYtPmRl dl9wcml2YXRlOwo+ICsKPiArCXNlcV9wcmludGYobSwgImZlbmNlICVsZCAlbGxkXG4iLAo+ICsJ CSAgIGF0b21pYzY0X3JlYWQoJnZnZGV2LT5mZW5jZV9kcnYubGFzdF9zZXEpLAo+ICsJCSAgIHZn ZGV2LT5mZW5jZV9kcnYuc3luY19zZXEpOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRp YyBzdHJ1Y3QgZHJtX2luZm9fbGlzdCB2aXJ0aW9fZ3B1X2RlYnVnZnNfbGlzdFtdID0gewo+ICsJ eyAiaXJxX2ZlbmNlIiwgdmlydGlvX2dwdV9kZWJ1Z2ZzX2lycV9pbmZvLCAwLCBOVUxMIH0sCj4g K307Cj4gKwo+ICsjZGVmaW5lIFZJUlRJT19HUFVfREVCVUdGU19FTlRSSUVTIEFSUkFZX1NJWkUo dmlydGlvX2dwdV9kZWJ1Z2ZzX2xpc3QpCj4gKwo+ICtpbnQKPiArdmlydGlvX2dwdV9kZWJ1Z2Zz X2luaXQoc3RydWN0IGRybV9taW5vciAqbWlub3IpCj4gK3sKPiArCWRybV9kZWJ1Z2ZzX2NyZWF0 ZV9maWxlcyh2aXJ0aW9fZ3B1X2RlYnVnZnNfbGlzdCwKPiArCQkJCSBWSVJUSU9fR1BVX0RFQlVH RlNfRU5UUklFUywKPiArCQkJCSBtaW5vci0+ZGVidWdmc19yb290LCBtaW5vcik7Cj4gKwlyZXR1 cm4gMDsKPiArfQo+ICsKPiArdm9pZAo+ICt2aXJ0aW9fZ3B1X2RlYnVnZnNfdGFrZWRvd24oc3Ry dWN0IGRybV9taW5vciAqbWlub3IpCj4gK3sKPiArCWRybV9kZWJ1Z2ZzX3JlbW92ZV9maWxlcyh2 aXJ0aW9fZ3B1X2RlYnVnZnNfbGlzdCwKPiArCQkJCSBWSVJUSU9fR1BVX0RFQlVHRlNfRU5UUklF UywKPiArCQkJCSBtaW5vcik7Cj4gK30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3Zp cnRpby92aXJ0Z3B1X2Rpc3BsYXkuYyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9k aXNwbGF5LmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLmEyZWNhNWYK PiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2Rp c3BsYXkuYwo+IEBAIC0wLDAgKzEsNDg1IEBACj4gKy8qCj4gKyAqIENvcHlyaWdodCAoQykgMjAx NSBSZWQgSGF0LCBJbmMuCj4gKyAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCj4gKyAqCj4gKyAqIEF1 dGhvcnM6Cj4gKyAqICAgIERhdmUgQWlybGllCj4gKyAqICAgIEFsb24gTGV2eQo+ICsgKgo+ICsg KiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBl cnNvbiBvYnRhaW5pbmcgYQo+ICsgKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0 ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAo+ICsgKiB0byBkZWFsIGlu IHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1p dGF0aW9uCj4gKyAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJs aXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAo+ICsgKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2Yg dGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKPiArICogU29m dHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29u ZGl0aW9uczoKPiArICoKPiArICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMg cGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KPiArICogYWxsIGNvcGllcyBv ciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCj4gKyAqCj4gKyAqIFRIRSBT T0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5E LCBFWFBSRVNTIE9SCj4gKyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8g VEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAo+ICsgKiBGSVRORVNTIEZPUiBBIFBB UlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwK PiArICogVEhFIENPUFlSSUdIVCBIT0xERVIoUykgT1IgQVVUSE9SKFMpIEJFIExJQUJMRSBGT1Ig QU5ZIENMQUlNLCBEQU1BR0VTIE9SCj4gKyAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBB TiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAo+ICsgKiBBUklTSU5HIEZS T00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0Ug T1IKPiArICogT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgo+ICsgKi8KPiArCj4gKyNp bmNsdWRlICJ2aXJ0Z3B1X2Rydi5oIgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5o Pgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9hdG9taWNfaGVscGVyLmg+Cj4gKwo+ICsjZGVmaW5lIFhS RVNfTUlOICAgMzIwCj4gKyNkZWZpbmUgWVJFU19NSU4gICAyMDAKPiArCj4gKyNkZWZpbmUgWFJF U19ERUYgIDEwMjQKPiArI2RlZmluZSBZUkVTX0RFRiAgIDc2OAo+ICsKPiArI2RlZmluZSBYUkVT X01BWCAgODE5Mgo+ICsjZGVmaW5lIFlSRVNfTUFYICA4MTkyCj4gKwo+ICtzdGF0aWMgaW50IHZp cnRpb19ncHVfZmJkZXYgPSAxOwo+ICsKPiArTU9EVUxFX1BBUk1fREVTQyhmYmRldiwgIkRpc2Fi bGUvRW5hYmxlIGZyYW1lYnVmZmVyIGRldmljZSAmIGNvbnNvbGUiKTsKPiArbW9kdWxlX3BhcmFt X25hbWVkKGZiZGV2LCB2aXJ0aW9fZ3B1X2ZiZGV2LCBpbnQsIDA0MDApOwo+ICsKPiArc3RhdGlj IHZvaWQgdmlydGlvX2dwdV9jcnRjX2dhbW1hX3NldChzdHJ1Y3QgZHJtX2NydGMgKmNydGMsCj4g KwkJCQkgICAgICB1MTYgKnJlZCwgdTE2ICpncmVlbiwgdTE2ICpibHVlLAo+ICsJCQkJICAgICAg dWludDMyX3Qgc3RhcnQsIHVpbnQzMl90IHNpemUpCj4gK3sKPiArCS8qIFRPRE8gKi8KPiArfQo+ ICsKPiArc3RhdGljIHZvaWQKPiArdmlydGlvX2dwdV9oaWRlX2N1cnNvcihzdHJ1Y3QgdmlydGlv X2dwdV9kZXZpY2UgKnZnZGV2LAo+ICsJCSAgICAgICBzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQg Km91dHB1dCkKPiArewo+ICsJb3V0cHV0LT5jdXJzb3IuaGRyLnR5cGUgPSBjcHVfdG9fbGUzMihW SVJUSU9fR1BVX0NNRF9VUERBVEVfQ1VSU09SKTsKPiArCW91dHB1dC0+Y3Vyc29yLnJlc291cmNl X2lkID0gMDsKPiArCXZpcnRpb19ncHVfY3Vyc29yX3BpbmcodmdkZXYsIG91dHB1dCk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgdmlydGlvX2dwdV9jcnRjX2N1cnNvcl9zZXQoc3RydWN0IGRybV9j cnRjICpjcnRjLAo+ICsJCQkJICAgICAgc3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsCj4gKwkJ CQkgICAgICB1aW50MzJfdCBoYW5kbGUsCj4gKwkJCQkgICAgICB1aW50MzJfdCB3aWR0aCwKPiAr CQkJCSAgICAgIHVpbnQzMl90IGhlaWdodCwKPiArCQkJCSAgICAgIGludDMyX3QgaG90X3gsIGlu dDMyX3QgaG90X3kpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYgPSBj cnRjLT5kZXYtPmRldl9wcml2YXRlOwo+ICsJc3RydWN0IHZpcnRpb19ncHVfb3V0cHV0ICpvdXRw dXQgPQo+ICsJCWNvbnRhaW5lcl9vZihjcnRjLCBzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQsIGNy dGMpOwo+ICsJc3RydWN0IGRybV9nZW1fb2JqZWN0ICpnb2JqID0gTlVMTDsKPiArCXN0cnVjdCB2 aXJ0aW9fZ3B1X29iamVjdCAqcW9iaiA9IE5VTEw7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9mZW5j ZSAqZmVuY2UgPSBOVUxMOwo+ICsJaW50IHJldCA9IDA7Cj4gKwo+ICsJaWYgKGhhbmRsZSA9PSAw KSB7Cj4gKwkJdmlydGlvX2dwdV9oaWRlX2N1cnNvcih2Z2Rldiwgb3V0cHV0KTsKPiArCQlyZXR1 cm4gMDsKPiArCX0KPiArCj4gKwkvKiBsb29rdXAgdGhlIGN1cnNvciAqLwo+ICsJZ29iaiA9IGRy bV9nZW1fb2JqZWN0X2xvb2t1cChjcnRjLT5kZXYsIGZpbGVfcHJpdiwgaGFuZGxlKTsKPiArCWlm IChnb2JqID09IE5VTEwpCj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwo+ICsJcW9iaiA9IGdlbV90 b192aXJ0aW9fZ3B1X29iaihnb2JqKTsKPiArCj4gKwlpZiAoIXFvYmotPmh3X3Jlc19oYW5kbGUp IHsKPiArCQlyZXQgPSAtRUlOVkFMOwo+ICsJCWdvdG8gb3V0Owo+ICsJfQo+ICsKPiArCXZpcnRp b19ncHVfY21kX3RyYW5zZmVyX3RvX2hvc3RfMmQodmdkZXYsIHFvYmotPmh3X3Jlc19oYW5kbGUs IDAsCj4gKwkJCQkJICAgY3B1X3RvX2xlMzIoNjQpLAo+ICsJCQkJCSAgIGNwdV90b19sZTMyKDY0 KSwKPiArCQkJCQkgICAwLCAwLCAmZmVuY2UpOwo+ICsKPiArCW91dHB1dC0+Y3Vyc29yLmhkci50 eXBlID0gY3B1X3RvX2xlMzIoVklSVElPX0dQVV9DTURfVVBEQVRFX0NVUlNPUik7Cj4gKwlvdXRw dXQtPmN1cnNvci5yZXNvdXJjZV9pZCA9IGNwdV90b19sZTMyKHFvYmotPmh3X3Jlc19oYW5kbGUp Owo+ICsJb3V0cHV0LT5jdXJzb3IuaG90X3ggPSBjcHVfdG9fbGUzMihob3RfeCk7Cj4gKwlvdXRw dXQtPmN1cnNvci5ob3RfeSA9IGNwdV90b19sZTMyKGhvdF95KTsKPiArCXZpcnRpb19ncHVfY3Vy c29yX3BpbmcodmdkZXYsIG91dHB1dCk7Cj4gKwlyZXQgPSAwOwo+ICsKPiArb3V0Ogo+ICsJZHJt X2dlbV9vYmplY3RfdW5yZWZlcmVuY2VfdW5sb2NrZWQoZ29iaik7Cj4gKwlyZXR1cm4gcmV0Owo+ ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHZpcnRpb19ncHVfY3J0Y19jdXJzb3JfbW92ZShzdHJ1Y3Qg ZHJtX2NydGMgKmNydGMsCj4gKwkJCQkgICAgaW50IHgsIGludCB5KQo+ICt7Cj4gKwlzdHJ1Y3Qg dmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2ID0gY3J0Yy0+ZGV2LT5kZXZfcHJpdmF0ZTsKPiArCXN0 cnVjdCB2aXJ0aW9fZ3B1X291dHB1dCAqb3V0cHV0ID0KPiArCQljb250YWluZXJfb2YoY3J0Yywg c3RydWN0IHZpcnRpb19ncHVfb3V0cHV0LCBjcnRjKTsKPiArCj4gKwlvdXRwdXQtPmN1cnNvci5o ZHIudHlwZSA9IGNwdV90b19sZTMyKFZJUlRJT19HUFVfQ01EX01PVkVfQ1VSU09SKTsKPiArCW91 dHB1dC0+Y3Vyc29yLnBvcy54ID0gY3B1X3RvX2xlMzIoeCk7Cj4gKwlvdXRwdXQtPmN1cnNvci5w b3MueSA9IGNwdV90b19sZTMyKHkpOwo+ICsJdmlydGlvX2dwdV9jdXJzb3JfcGluZyh2Z2Rldiwg b3V0cHV0KTsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRy bV9jcnRjX2Z1bmNzIHZpcnRpb19ncHVfY3J0Y19mdW5jcyA9IHsKPiArCS5jdXJzb3Jfc2V0MiAg ICAgICAgICAgID0gdmlydGlvX2dwdV9jcnRjX2N1cnNvcl9zZXQsCj4gKwkuY3Vyc29yX21vdmUg ICAgICAgICAgICA9IHZpcnRpb19ncHVfY3J0Y19jdXJzb3JfbW92ZSwKPiArCS5nYW1tYV9zZXQg ICAgICAgICAgICAgID0gdmlydGlvX2dwdV9jcnRjX2dhbW1hX3NldCwKPiArCS5zZXRfY29uZmln ICAgICAgICAgICAgID0gZHJtX2F0b21pY19oZWxwZXJfc2V0X2NvbmZpZywKPiArCS5kZXN0cm95 ICAgICAgICAgICAgICAgID0gZHJtX2NydGNfY2xlYW51cCwKPiArCj4gKyNpZiAwIC8qIG5vdCAo eWV0KSB3b3JraW5nIHdpdGhvdXQgdmJsYW5rIHN1cHBvcnQgYWNjb3JkaW5nIHRvIGRvY3MgKi8K PiArCS5wYWdlX2ZsaXAgICAgICAgICAgICAgID0gZHJtX2F0b21pY19oZWxwZXJfcGFnZV9mbGlw LAo+ICsjZW5kaWYKPiArCS5yZXNldCAgICAgICAgICAgICAgICAgID0gZHJtX2F0b21pY19oZWxw ZXJfY3J0Y19yZXNldCwKPiArCS5hdG9taWNfZHVwbGljYXRlX3N0YXRlID0gZHJtX2F0b21pY19o ZWxwZXJfY3J0Y19kdXBsaWNhdGVfc3RhdGUsCj4gKwkuYXRvbWljX2Rlc3Ryb3lfc3RhdGUgICA9 IGRybV9hdG9taWNfaGVscGVyX2NydGNfZGVzdHJveV9zdGF0ZSwKPiArfTsKPiArCj4gK3N0YXRp YyB2b2lkIHZpcnRpb19ncHVfdXNlcl9mcmFtZWJ1ZmZlcl9kZXN0cm95KHN0cnVjdCBkcm1fZnJh bWVidWZmZXIgKmZiKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9mcmFtZWJ1ZmZlciAqdmly dGlvX2dwdV9mYgo+ICsJCT0gdG9fdmlydGlvX2dwdV9mcmFtZWJ1ZmZlcihmYik7Cj4gKwo+ICsJ aWYgKHZpcnRpb19ncHVfZmItPm9iaikKPiArCQlkcm1fZ2VtX29iamVjdF91bnJlZmVyZW5jZV91 bmxvY2tlZCh2aXJ0aW9fZ3B1X2ZiLT5vYmopOwo+ICsJZHJtX2ZyYW1lYnVmZmVyX2NsZWFudXAo ZmIpOwo+ICsJa2ZyZWUodmlydGlvX2dwdV9mYik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQKPiAr dmlydGlvX2dwdV9mcmFtZWJ1ZmZlcl9zdXJmYWNlX2RpcnR5KHN0cnVjdCBkcm1fZnJhbWVidWZm ZXIgKmZiLAo+ICsJCQkJICAgICBzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVfcHJpdiwKPiArCQkJCSAg ICAgdW5zaWduZWQgZmxhZ3MsIHVuc2lnbmVkIGNvbG9yLAo+ICsJCQkJICAgICBzdHJ1Y3QgZHJt X2NsaXBfcmVjdCAqY2xpcHMsCj4gKwkJCQkgICAgIHVuc2lnbmVkIG51bV9jbGlwcykKPiArewo+ ICsJc3RydWN0IHZpcnRpb19ncHVfZnJhbWVidWZmZXIgKnZpcnRpb19ncHVfZmIKPiArCQk9IHRv X3ZpcnRpb19ncHVfZnJhbWVidWZmZXIoZmIpOwo+ICsKPiArCXJldHVybiB2aXJ0aW9fZ3B1X3N1 cmZhY2VfZGlydHkodmlydGlvX2dwdV9mYiwgY2xpcHMsIG51bV9jbGlwcyk7Cj4gK30KPiArCj4g K3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyX2Z1bmNzIHZpcnRpb19ncHVfZmJf ZnVuY3MgPSB7Cj4gKwkuZGVzdHJveSA9IHZpcnRpb19ncHVfdXNlcl9mcmFtZWJ1ZmZlcl9kZXN0 cm95LAo+ICsJLmRpcnR5ID0gdmlydGlvX2dwdV9mcmFtZWJ1ZmZlcl9zdXJmYWNlX2RpcnR5LAo+ ICt9Owo+ICsKPiAraW50Cj4gK3ZpcnRpb19ncHVfZnJhbWVidWZmZXJfaW5pdChzdHJ1Y3QgZHJt X2RldmljZSAqZGV2LAo+ICsJCQkgICAgc3RydWN0IHZpcnRpb19ncHVfZnJhbWVidWZmZXIgKnZn ZmIsCj4gKwkJCSAgICBzdHJ1Y3QgZHJtX21vZGVfZmJfY21kMiAqbW9kZV9jbWQsCj4gKwkJCSAg ICBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaikKPiArewo+ICsJaW50IHJldDsKPiArCXN0cnVj dCB2aXJ0aW9fZ3B1X29iamVjdCAqYm87Cj4gKwl2Z2ZiLT5vYmogPSBvYmo7Cj4gKwo+ICsJYm8g PSBnZW1fdG9fdmlydGlvX2dwdV9vYmoob2JqKTsKPiArCj4gKwlyZXQgPSBkcm1fZnJhbWVidWZm ZXJfaW5pdChkZXYsICZ2Z2ZiLT5iYXNlLCAmdmlydGlvX2dwdV9mYl9mdW5jcyk7Cj4gKwlpZiAo cmV0KSB7Cj4gKwkJdmdmYi0+b2JqID0gTlVMTDsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsJ ZHJtX2hlbHBlcl9tb2RlX2ZpbGxfZmJfc3RydWN0KCZ2Z2ZiLT5iYXNlLCBtb2RlX2NtZCk7Cj4g Kwo+ICsJc3Bpbl9sb2NrX2luaXQoJnZnZmItPmRpcnR5X2xvY2spOwo+ICsJdmdmYi0+eDEgPSB2 Z2ZiLT55MSA9IElOVF9NQVg7Cj4gKwl2Z2ZiLT54MiA9IHZnZmItPnkyID0gMDsKPiArCXJldHVy biAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCB2aXJ0aW9fZ3B1X2NydGNfbW9kZV9maXh1cChz dHJ1Y3QgZHJtX2NydGMgKmNydGMsCj4gKwkJCQkgICAgICAgY29uc3Qgc3RydWN0IGRybV9kaXNw bGF5X21vZGUgKm1vZGUsCj4gKwkJCQkgICAgICAgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKmFk anVzdGVkX21vZGUpCj4gK3sKPiArCXJldHVybiB0cnVlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9p ZCB2aXJ0aW9fZ3B1X2NydGNfbW9kZV9zZXRfbm9mYihzdHJ1Y3QgZHJtX2NydGMgKmNydGMpCj4g K3sKPiArCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYgPSBjcnRjLT5kZXY7Cj4gKwlzdHJ1Y3Qgdmly dGlvX2dwdV9kZXZpY2UgKnZnZGV2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKPiArCXN0cnVjdCB2aXJ0 aW9fZ3B1X291dHB1dCAqb3V0cHV0ID0gZHJtX2NydGNfdG9fdmlydGlvX2dwdV9vdXRwdXQoY3J0 Yyk7Cj4gKwo+ICsJdmlydGlvX2dwdV9jbWRfc2V0X3NjYW5vdXQodmdkZXYsIG91dHB1dC0+aW5k ZXgsIDAsCj4gKwkJCQkgICBjcnRjLT5tb2RlLmhkaXNwbGF5LAo+ICsJCQkJICAgY3J0Yy0+bW9k ZS52ZGlzcGxheSwgMCwgMCk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfY3J0 Y19lbmFibGUoc3RydWN0IGRybV9jcnRjICpjcnRjKQo+ICt7Cj4gK30KPiArCj4gK3N0YXRpYyB2 b2lkIHZpcnRpb19ncHVfY3J0Y19kaXNhYmxlKHN0cnVjdCBkcm1fY3J0YyAqY3J0YykKPiArewo+ ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IGNydGMtPmRldjsKPiArCXN0cnVjdCB2aXJ0aW9f Z3B1X2RldmljZSAqdmdkZXYgPSBkZXYtPmRldl9wcml2YXRlOwo+ICsJc3RydWN0IHZpcnRpb19n cHVfb3V0cHV0ICpvdXRwdXQgPSBkcm1fY3J0Y190b192aXJ0aW9fZ3B1X291dHB1dChjcnRjKTsK PiArCj4gKwl2aXJ0aW9fZ3B1X2NtZF9zZXRfc2Nhbm91dCh2Z2Rldiwgb3V0cHV0LT5pbmRleCwg MCwgMCwgMCwgMCwgMCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdmlydGlvX2dwdV9jcnRjX2F0 b21pY19jaGVjayhzdHJ1Y3QgZHJtX2NydGMgKmNydGMsCj4gKwkJCQkJc3RydWN0IGRybV9jcnRj X3N0YXRlICpzdGF0ZSkKPiArewo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgZHJtX2NydGNfaGVscGVyX2Z1bmNzIHZpcnRpb19ncHVfY3J0Y19oZWxwZXJfZnVu Y3MgPSB7Cj4gKwkuZW5hYmxlICAgICAgICA9IHZpcnRpb19ncHVfY3J0Y19lbmFibGUsCj4gKwku ZGlzYWJsZSAgICAgICA9IHZpcnRpb19ncHVfY3J0Y19kaXNhYmxlLAo+ICsJLm1vZGVfZml4dXAg ICAgPSB2aXJ0aW9fZ3B1X2NydGNfbW9kZV9maXh1cCwKPiArCS5tb2RlX3NldF9ub2ZiID0gdmly dGlvX2dwdV9jcnRjX21vZGVfc2V0X25vZmIsCj4gKwkuYXRvbWljX2NoZWNrICA9IHZpcnRpb19n cHVfY3J0Y19hdG9taWNfY2hlY2ssCj4gK307Cj4gKwo+ICtzdGF0aWMgYm9vbCB2aXJ0aW9fZ3B1 X2VuY19tb2RlX2ZpeHVwKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKPiArCQkJCSAgICAg IGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlLAo+ICsJCQkJICAgICAgc3RydWN0 IGRybV9kaXNwbGF5X21vZGUgKmFkanVzdGVkX21vZGUpCj4gK3sKPiArCXJldHVybiB0cnVlOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X2VuY19tb2RlX3NldChzdHJ1Y3QgZHJt X2VuY29kZXIgKmVuY29kZXIsCj4gKwkJCQkgICAgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1v ZGUsCj4gKwkJCQkgICAgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKmFkanVzdGVkX21vZGUpCj4g K3sKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9lbmNfZW5hYmxlKHN0cnVjdCBk cm1fZW5jb2RlciAqZW5jb2RlcikKPiArewo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9f Z3B1X2VuY19kaXNhYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiArewo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IHZpcnRpb19ncHVfY29ubl9nZXRfbW9kZXMoc3RydWN0IGRybV9jb25u ZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfb3V0cHV0ICpvdXRw dXQgPQo+ICsJCWRybV9jb25uZWN0b3JfdG9fdmlydGlvX2dwdV9vdXRwdXQoY29ubmVjdG9yKTsK PiArCXN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlID0gTlVMTDsKPiArCWludCBjb3VudCwg d2lkdGgsIGhlaWdodDsKPiArCj4gKwl3aWR0aCAgPSBsZTMyX3RvX2NwdShvdXRwdXQtPmluZm8u ci53aWR0aCk7Cj4gKwloZWlnaHQgPSBsZTMyX3RvX2NwdShvdXRwdXQtPmluZm8uci5oZWlnaHQp Owo+ICsJY291bnQgPSBkcm1fYWRkX21vZGVzX25vZWRpZChjb25uZWN0b3IsIFhSRVNfTUFYLCBZ UkVTX01BWCk7Cj4gKwo+ICsJaWYgKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDApIHsKPiArCQl3 aWR0aCA9IFhSRVNfREVGOwo+ICsJCWhlaWdodCA9IFlSRVNfREVGOwo+ICsJCWRybV9zZXRfcHJl ZmVycmVkX21vZGUoY29ubmVjdG9yLCBYUkVTX0RFRiwgWVJFU19ERUYpOwo+ICsJfSBlbHNlIHsK PiArCQlEUk1fREVCVUcoImFkZCBtb2RlOiAlZHglZFxuIiwgd2lkdGgsIGhlaWdodCk7Cj4gKwkJ bW9kZSA9IGRybV9jdnRfbW9kZShjb25uZWN0b3ItPmRldiwgd2lkdGgsIGhlaWdodCwgNjAsCj4g KwkJCQkgICAgZmFsc2UsIGZhbHNlLCBmYWxzZSk7Cj4gKwkJbW9kZS0+dHlwZSB8PSBEUk1fTU9E RV9UWVBFX1BSRUZFUlJFRDsKPiArCQlkcm1fbW9kZV9wcm9iZWRfYWRkKGNvbm5lY3RvciwgbW9k ZSk7Cj4gKwkJY291bnQrKzsKPiArCX0KPiArCj4gKwlyZXR1cm4gY291bnQ7Cj4gK30KPiArCj4g K3N0YXRpYyBpbnQgdmlydGlvX2dwdV9jb25uX21vZGVfdmFsaWQoc3RydWN0IGRybV9jb25uZWN0 b3IgKmNvbm5lY3RvciwKPiArCQkJCSAgICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2Rl KQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgKm91dHB1dCA9Cj4gKwkJZHJtX2Nv bm5lY3Rvcl90b192aXJ0aW9fZ3B1X291dHB1dChjb25uZWN0b3IpOwo+ICsJaW50IHdpZHRoLCBo ZWlnaHQ7Cj4gKwo+ICsJd2lkdGggID0gbGUzMl90b19jcHUob3V0cHV0LT5pbmZvLnIud2lkdGgp Owo+ICsJaGVpZ2h0ID0gbGUzMl90b19jcHUob3V0cHV0LT5pbmZvLnIuaGVpZ2h0KTsKPiArCj4g KwlpZiAoIShtb2RlLT50eXBlICYgRFJNX01PREVfVFlQRV9QUkVGRVJSRUQpKQo+ICsJCXJldHVy biBNT0RFX09LOwo+ICsJaWYgKG1vZGUtPmhkaXNwbGF5ID09IFhSRVNfREVGICYmIG1vZGUtPnZk aXNwbGF5ID09IFlSRVNfREVGKQo+ICsJCXJldHVybiBNT0RFX09LOwo+ICsJaWYgKG1vZGUtPmhk aXNwbGF5IDw9IHdpZHRoICAmJiBtb2RlLT5oZGlzcGxheSA+PSB3aWR0aCAtIDE2ICYmCj4gKwkg ICAgbW9kZS0+dmRpc3BsYXkgPD0gaGVpZ2h0ICYmIG1vZGUtPnZkaXNwbGF5ID49IGhlaWdodCAt IDE2KQo+ICsJCXJldHVybiBNT0RFX09LOwo+ICsKPiArCURSTV9ERUJVRygiZGVsIG1vZGU6ICVk eCVkXG4iLCBtb2RlLT5oZGlzcGxheSwgbW9kZS0+dmRpc3BsYXkpOwo+ICsJcmV0dXJuIE1PREVf QkFEOwo+ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGRybV9lbmNvZGVyKgo+ICt2aXJ0aW9fZ3B1 X2Jlc3RfZW5jb2RlcihzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKQo+ICt7Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgKnZpcnRpb19ncHVfb3V0cHV0ID0KPiArCQlkcm1fY29u bmVjdG9yX3RvX3ZpcnRpb19ncHVfb3V0cHV0KGNvbm5lY3Rvcik7Cj4gKwo+ICsJcmV0dXJuICZ2 aXJ0aW9fZ3B1X291dHB1dC0+ZW5jOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRy bV9lbmNvZGVyX2hlbHBlcl9mdW5jcyB2aXJ0aW9fZ3B1X2VuY19oZWxwZXJfZnVuY3MgPSB7Cj4g KwkubW9kZV9maXh1cCA9IHZpcnRpb19ncHVfZW5jX21vZGVfZml4dXAsCj4gKwkubW9kZV9zZXQg ICA9IHZpcnRpb19ncHVfZW5jX21vZGVfc2V0LAo+ICsJLmVuYWJsZSAgICAgPSB2aXJ0aW9fZ3B1 X2VuY19lbmFibGUsCj4gKwkuZGlzYWJsZSAgICA9IHZpcnRpb19ncHVfZW5jX2Rpc2FibGUsCj4g K307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9jb25uZWN0b3JfaGVscGVyX2Z1bmNz IHZpcnRpb19ncHVfY29ubl9oZWxwZXJfZnVuY3MgPSB7Cj4gKwkuZ2V0X21vZGVzICAgID0gdmly dGlvX2dwdV9jb25uX2dldF9tb2RlcywKPiArCS5tb2RlX3ZhbGlkICAgPSB2aXJ0aW9fZ3B1X2Nv bm5fbW9kZV92YWxpZCwKPiArCS5iZXN0X2VuY29kZXIgPSB2aXJ0aW9fZ3B1X2Jlc3RfZW5jb2Rl ciwKPiArfTsKPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfY29ubl9zYXZlKHN0cnVjdCBk cm1fY29ubmVjdG9yICpjb25uZWN0b3IpCj4gK3sKPiArCURSTV9ERUJVRygiXG4iKTsKPiArfQo+ ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9jb25uX3Jlc3RvcmUoc3RydWN0IGRybV9jb25u ZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJRFJNX0RFQlVHKCJcbiIpOwo+ICt9Cj4gKwo+ICtz dGF0aWMgZW51bSBkcm1fY29ubmVjdG9yX3N0YXR1cyB2aXJ0aW9fZ3B1X2Nvbm5fZGV0ZWN0KAo+ ICsJCQlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLAo+ICsJCQlib29sIGZvcmNlKQo+ ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgKm91dHB1dCA9Cj4gKwkJZHJtX2Nvbm5l Y3Rvcl90b192aXJ0aW9fZ3B1X291dHB1dChjb25uZWN0b3IpOwo+ICsKPiArCWlmIChvdXRwdXQt PmluZm8uZW5hYmxlZCkKPiArCQlyZXR1cm4gY29ubmVjdG9yX3N0YXR1c19jb25uZWN0ZWQ7Cj4g KwllbHNlCj4gKwkJcmV0dXJuIGNvbm5lY3Rvcl9zdGF0dXNfZGlzY29ubmVjdGVkOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X2Nvbm5fZGVzdHJveShzdHJ1Y3QgZHJtX2Nvbm5l Y3RvciAqY29ubmVjdG9yKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgKnZpcnRp b19ncHVfb3V0cHV0ID0KPiArCQlkcm1fY29ubmVjdG9yX3RvX3ZpcnRpb19ncHVfb3V0cHV0KGNv bm5lY3Rvcik7Cj4gKwo+ICsJZHJtX2Nvbm5lY3Rvcl91bnJlZ2lzdGVyKGNvbm5lY3Rvcik7Cj4g Kwlkcm1fY29ubmVjdG9yX2NsZWFudXAoY29ubmVjdG9yKTsKPiArCWtmcmVlKHZpcnRpb19ncHVf b3V0cHV0KTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fY29ubmVjdG9yX2Z1 bmNzIHZpcnRpb19ncHVfY29ubmVjdG9yX2Z1bmNzID0gewo+ICsJLmRwbXMgPSBkcm1fYXRvbWlj X2hlbHBlcl9jb25uZWN0b3JfZHBtcywKPiArCS5zYXZlID0gdmlydGlvX2dwdV9jb25uX3NhdmUs Cj4gKwkucmVzdG9yZSA9IHZpcnRpb19ncHVfY29ubl9yZXN0b3JlLAo+ICsJLmRldGVjdCA9IHZp cnRpb19ncHVfY29ubl9kZXRlY3QsCj4gKwkuZmlsbF9tb2RlcyA9IGRybV9oZWxwZXJfcHJvYmVf c2luZ2xlX2Nvbm5lY3Rvcl9tb2RlcywKPiArCS5kZXN0cm95ID0gdmlydGlvX2dwdV9jb25uX2Rl c3Ryb3ksCj4gKwkucmVzZXQgPSBkcm1fYXRvbWljX2hlbHBlcl9jb25uZWN0b3JfcmVzZXQsCj4g KwkuYXRvbWljX2R1cGxpY2F0ZV9zdGF0ZSA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9k dXBsaWNhdGVfc3RhdGUsCj4gKwkuYXRvbWljX2Rlc3Ryb3lfc3RhdGUgPSBkcm1fYXRvbWljX2hl bHBlcl9jb25uZWN0b3JfZGVzdHJveV9zdGF0ZSwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgZHJtX2VuY29kZXJfZnVuY3MgdmlydGlvX2dwdV9lbmNfZnVuY3MgPSB7Cj4gKwkuZGVz dHJveSA9IGRybV9lbmNvZGVyX2NsZWFudXAsCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IHZnZGV2 X291dHB1dF9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsIGludCBpbmRleCkK PiArewo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IHZnZGV2LT5kZGV2Owo+ICsJc3RydWN0 IHZpcnRpb19ncHVfb3V0cHV0ICpvdXRwdXQgPSB2Z2Rldi0+b3V0cHV0cyArIGluZGV4Owo+ICsJ c3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciA9ICZvdXRwdXQtPmNvbm47Cj4gKwlzdHJ1 Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIgPSAmb3V0cHV0LT5lbmM7Cj4gKwlzdHJ1Y3QgZHJtX2Ny dGMgKmNydGMgPSAmb3V0cHV0LT5jcnRjOwo+ICsJc3RydWN0IGRybV9wbGFuZSAqcGxhbmU7Cj4g Kwo+ICsJb3V0cHV0LT5pbmRleCA9IGluZGV4Owo+ICsJaWYgKGluZGV4ID09IDApIHsKPiArCQlv dXRwdXQtPmluZm8uZW5hYmxlZCA9IGNwdV90b19sZTMyKHRydWUpOwo+ICsJCW91dHB1dC0+aW5m by5yLndpZHRoID0gY3B1X3RvX2xlMzIoWFJFU19ERUYpOwo+ICsJCW91dHB1dC0+aW5mby5yLmhl aWdodCA9IGNwdV90b19sZTMyKFlSRVNfREVGKTsKPiArCX0KPiArCj4gKwlwbGFuZSA9IHZpcnRp b19ncHVfcGxhbmVfaW5pdCh2Z2RldiwgaW5kZXgpOwo+ICsJaWYgKElTX0VSUihwbGFuZSkpCj4g KwkJcmV0dXJuIFBUUl9FUlIocGxhbmUpOwo+ICsJZHJtX2NydGNfaW5pdF93aXRoX3BsYW5lcyhk ZXYsIGNydGMsIHBsYW5lLCBOVUxMLAo+ICsJCQkJICAmdmlydGlvX2dwdV9jcnRjX2Z1bmNzKTsK PiArCWRybV9tb2RlX2NydGNfc2V0X2dhbW1hX3NpemUoY3J0YywgMjU2KTsKPiArCWRybV9jcnRj X2hlbHBlcl9hZGQoY3J0YywgJnZpcnRpb19ncHVfY3J0Y19oZWxwZXJfZnVuY3MpOwo+ICsJcGxh bmUtPmNydGMgPSBjcnRjOwo+ICsKPiArCWRybV9jb25uZWN0b3JfaW5pdChkZXYsIGNvbm5lY3Rv ciwgJnZpcnRpb19ncHVfY29ubmVjdG9yX2Z1bmNzLAo+ICsJCQkgICBEUk1fTU9ERV9DT05ORUNU T1JfVklSVFVBTCk7Cj4gKwlkcm1fY29ubmVjdG9yX2hlbHBlcl9hZGQoY29ubmVjdG9yLCAmdmly dGlvX2dwdV9jb25uX2hlbHBlcl9mdW5jcyk7Cj4gKwo+ICsJZHJtX2VuY29kZXJfaW5pdChkZXYs IGVuY29kZXIsICZ2aXJ0aW9fZ3B1X2VuY19mdW5jcywKPiArCQkJIERSTV9NT0RFX0VOQ09ERVJf VklSVFVBTCk7Cj4gKwlkcm1fZW5jb2Rlcl9oZWxwZXJfYWRkKGVuY29kZXIsICZ2aXJ0aW9fZ3B1 X2VuY19oZWxwZXJfZnVuY3MpOwo+ICsJZW5jb2Rlci0+cG9zc2libGVfY3J0Y3MgPSAxIDw8IGlu ZGV4Owo+ICsKPiArCWRybV9tb2RlX2Nvbm5lY3Rvcl9hdHRhY2hfZW5jb2Rlcihjb25uZWN0b3Is IGVuY29kZXIpOwo+ICsJZHJtX2Nvbm5lY3Rvcl9yZWdpc3Rlcihjb25uZWN0b3IpOwo+ICsJcmV0 dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICoKPiArdmly dGlvX2dwdV91c2VyX2ZyYW1lYnVmZmVyX2NyZWF0ZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ ICsJCQkJICAgc3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsCj4gKwkJCQkgICBzdHJ1Y3QgZHJt X21vZGVfZmJfY21kMiAqbW9kZV9jbWQpCj4gK3sKPiArCXN0cnVjdCBkcm1fZ2VtX29iamVjdCAq b2JqID0gTlVMTDsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZyYW1lYnVmZmVyICp2aXJ0aW9fZ3B1 X2ZiOwo+ICsJaW50IHJldDsKPiArCj4gKwkvKiBsb29rdXAgb2JqZWN0IGFzc29jaWF0ZWQgd2l0 aCByZXMgaGFuZGxlICovCj4gKwlvYmogPSBkcm1fZ2VtX29iamVjdF9sb29rdXAoZGV2LCBmaWxl X3ByaXYsIG1vZGVfY21kLT5oYW5kbGVzWzBdKTsKPiArCWlmICghb2JqKQo+ICsJCXJldHVybiBF UlJfUFRSKC1FSU5WQUwpOwo+ICsKPiArCXZpcnRpb19ncHVfZmIgPSBremFsbG9jKHNpemVvZigq dmlydGlvX2dwdV9mYiksIEdGUF9LRVJORUwpOwo+ICsJaWYgKHZpcnRpb19ncHVfZmIgPT0gTlVM TCkKPiArCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKPiArCj4gKwlyZXQgPSB2aXJ0aW9fZ3B1 X2ZyYW1lYnVmZmVyX2luaXQoZGV2LCB2aXJ0aW9fZ3B1X2ZiLCBtb2RlX2NtZCwgb2JqKTsKPiAr CWlmIChyZXQpIHsKPiArCQlrZnJlZSh2aXJ0aW9fZ3B1X2ZiKTsKPiArCQlpZiAob2JqKQo+ICsJ CQlkcm1fZ2VtX29iamVjdF91bnJlZmVyZW5jZV91bmxvY2tlZChvYmopOwo+ICsJCXJldHVybiBO VUxMOwo+ICsJfQo+ICsKPiArCXJldHVybiAmdmlydGlvX2dwdV9mYi0+YmFzZTsKPiArfQo+ICsK PiArc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fbW9kZV9jb25maWdfZnVuY3MgdmlydGlvX2dwdV9t b2RlX2Z1bmNzID0gewo+ICsJLmZiX2NyZWF0ZSA9IHZpcnRpb19ncHVfdXNlcl9mcmFtZWJ1ZmZl cl9jcmVhdGUsCj4gKwkuYXRvbWljX2NoZWNrID0gZHJtX2F0b21pY19oZWxwZXJfY2hlY2ssCj4g KwkuYXRvbWljX2NvbW1pdCA9IGRybV9hdG9taWNfaGVscGVyX2NvbW1pdCwKPiArfTsKPiArCj4g K2ludCB2aXJ0aW9fZ3B1X21vZGVzZXRfaW5pdChzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZn ZGV2KQo+ICt7Cj4gKwlpbnQgaSwgcmV0Owo+ICsKPiArCWRybV9tb2RlX2NvbmZpZ19pbml0KHZn ZGV2LT5kZGV2KTsKPiArCXZnZGV2LT5kZGV2LT5tb2RlX2NvbmZpZy5mdW5jcyA9ICh2b2lkICop JnZpcnRpb19ncHVfbW9kZV9mdW5jczsKPiArCj4gKwkvKiBtb2RlcyB3aWxsIGJlIHZhbGlkYXRl ZCBhZ2FpbnN0IHRoZSBmcmFtZWJ1ZmZlciBzaXplICovCj4gKwl2Z2Rldi0+ZGRldi0+bW9kZV9j b25maWcubWluX3dpZHRoID0gWFJFU19NSU47Cj4gKwl2Z2Rldi0+ZGRldi0+bW9kZV9jb25maWcu bWluX2hlaWdodCA9IFlSRVNfTUlOOwo+ICsJdmdkZXYtPmRkZXYtPm1vZGVfY29uZmlnLm1heF93 aWR0aCA9IFhSRVNfTUFYOwo+ICsJdmdkZXYtPmRkZXYtPm1vZGVfY29uZmlnLm1heF9oZWlnaHQg PSBZUkVTX01BWDsKPiArCj4gKwlmb3IgKGkgPSAwIDsgaSA8IHZnZGV2LT5udW1fc2Nhbm91dHM7 ICsraSkKPiArCQl2Z2Rldl9vdXRwdXRfaW5pdCh2Z2RldiwgaSk7Cj4gKwo+ICsgICAgICAgIGRy bV9tb2RlX2NvbmZpZ19yZXNldCh2Z2Rldi0+ZGRldik7Cj4gKwo+ICsJaWYgKHZpcnRpb19ncHVf ZmJkZXYpIHsKPiArCQlyZXQgPSB2aXJ0aW9fZ3B1X2ZiZGV2X2luaXQodmdkZXYpOwo+ICsJCWlm IChyZXQpCj4gKwkJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiAr Cj4gK3ZvaWQgdmlydGlvX2dwdV9tb2Rlc2V0X2Zpbmkoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNl ICp2Z2RldikKPiArewo+ICsJdmlydGlvX2dwdV9mYmRldl9maW5pKHZnZGV2KTsKPiArCWRybV9t b2RlX2NvbmZpZ19jbGVhbnVwKHZnZGV2LT5kZGV2KTsKPiArfQo+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJtX2J1cy5jIGIvZHJpdmVycy9ncHUvZHJtL3Zp cnRpby92aXJ0Z3B1X2RybV9idXMuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAw MDAwMC4uZjRlYzgxNgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdmly dGlvL3ZpcnRncHVfZHJtX2J1cy5jCj4gQEAgLTAsMCArMSw5MSBAQAo+ICsvKgo+ICsgKiBDb3B5 cmlnaHQgKEMpIDIwMTUgUmVkIEhhdCwgSW5jLgo+ICsgKiBBbGwgUmlnaHRzIFJlc2VydmVkLgo+ ICsgKgo+ICsgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwg dG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKPiArICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5k IGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCj4gKyAqICJTb2Z0d2FyZSIpLCB0 byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKPiAr ICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1l cmdlLCBwdWJsaXNoLAo+ICsgKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBj b3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KPiArICogcGVybWl0IHBlcnNvbnMgdG8gd2hv bSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCj4gKyAqIHRo ZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKPiArICoKPiArICogVGhlIGFib3ZlIGNvcHlyaWdodCBu b3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUKPiArICogbmV4 dCBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRp YWwKPiArICogcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgo+ICsgKgo+ICsgKiBUSEUgU09GVFdB UkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwKPiAr ICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBX QVJSQU5USUVTIE9GCj4gKyAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNV TEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KPiArICogSU4gTk8gRVZFTlQgU0hBTEwg VEhFIENPUFlSSUdIVCBPV05FUihTKSBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRQo+ICsgKiBMSUFC TEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4g QU4gQUNUSU9OCj4gKyAqIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBG Uk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgo+ICsgKiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBU SEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KPiArICovCj4gKwo+ICsj aW5jbHVkZSA8bGludXgvcGNpLmg+Cj4gKwo+ICsjaW5jbHVkZSAidmlydGdwdV9kcnYuaCIKPiAr Cj4gK2ludCBkcm1fdmlydGlvX3NldF9idXNpZChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCBzdHJ1 Y3QgZHJtX21hc3RlciAqbWFzdGVyKQo+ICt7Cj4gKwlzdHJ1Y3QgcGNpX2RldiAqcGRldiA9IGRl di0+cGRldjsKPiArCj4gKwlpZiAocGRldikgewo+ICsJCXJldHVybiBkcm1fcGNpX3NldF9idXNp ZChkZXYsIG1hc3Rlcik7Cj4gKwl9Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiAraW50IGRybV92 aXJ0aW9faW5pdChzdHJ1Y3QgZHJtX2RyaXZlciAqZHJpdmVyLCBzdHJ1Y3QgdmlydGlvX2Rldmlj ZSAqdmRldikKPiArewo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldjsKPiArCWludCByZXQ7Cj4g Kwo+ICsJZGV2ID0gZHJtX2Rldl9hbGxvYyhkcml2ZXIsICZ2ZGV2LT5kZXYpOwo+ICsJaWYgKCFk ZXYpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwlkZXYtPnZpcnRkZXYgPSB2ZGV2Owo+ICsJdmRl di0+cHJpdiA9IGRldjsKPiArCj4gKwlpZiAoc3RyY21wKHZkZXYtPmRldi5wYXJlbnQtPmJ1cy0+ bmFtZSwgInBjaSIpID09IDApIHsKPiArCQlzdHJ1Y3QgcGNpX2RldiAqcGRldiA9IHRvX3BjaV9k ZXYodmRldi0+ZGV2LnBhcmVudCk7Cj4gKwkJYm9vbCB2Z2EgPSAocGRldi0+Y2xhc3MgPj4gOCkg PT0gUENJX0NMQVNTX0RJU1BMQVlfVkdBOwo+ICsKPiArCQlpZiAodmdhKSB7Cj4gKwkJCS8qCj4g KwkJCSAqIE5lZWQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGhhdmUgdHdvIGRyaXZlcnMKPiArCQkJ ICogZm9yIHRoZSBzYW1lIGhhcmR3YXJlIGhlcmUuICBTb21lIGRheSB3ZQo+ICsJCQkgKiB3aWxs IHNpbXBseSBraWNrIG91dCB0aGUgZmlybXdhcmUKPiArCQkJICogKHZlc2EvZWZpKSBmcmFtZWJ1 ZmZlci4KPiArCQkJICoKPiArCQkJICogVmlydHVhbCBoYXJkd2FyZSBzcGVjcyBmb3IgdmlydGlv LXZnYSBhcmUKPiArCQkJICogbm90IGZpbmFsaXplZCB5ZXQsIHRoZXJlZm9yZSB3ZSBjYW4ndCBh ZGQKPiArCQkJICogY29kZSBmb3IgdGhhdCB5ZXQuCj4gKwkJCSAqCj4gKwkJCSAqIFNvIGlnbm9y ZSB0aGUgZGV2aWNlIGZvciB0aGUgdGltZSBiZWluZywKPiArCQkJICogYW5kIHN1Z2dlc3QgdG8g dGhlIHVzZXIgdXNlIHRoZSBkZXZpY2UKPiArCQkJICogdmFyaWFudCB3aXRob3V0IHZnYSBjb21w YXRpYmlsaXR5IG1vZGUuCj4gKwkJCSAqLwo+ICsJCQlEUk1fRVJST1IoInZpcnRpby12Z2Egbm90 ICh5ZXQpIHN1cHBvcnRlZFxuIik7Cj4gKwkJCURSTV9FUlJPUigicGxlYXNlIHVzZSB2aXJ0aW8t Z3B1LXBjaSBpbnN0ZWFkXG4iKTsKPiArCQkJcmV0ID0gLUVOT0RFVjsKPiArCQkJZ290byBlcnJf ZnJlZTsKPiArCQl9Cj4gKwkJZGV2LT5wZGV2ID0gcGRldjsKPiArCX0KPiArCj4gKwlyZXQgPSBk cm1fZGV2X3JlZ2lzdGVyKGRldiwgMCk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gZXJyX2ZyZWU7 Cj4gKwo+ICsJRFJNX0lORk8oIkluaXRpYWxpemVkICVzICVkLiVkLiVkICVzIG9uIG1pbm9yICVk XG4iLCBkcml2ZXItPm5hbWUsCj4gKwkJIGRyaXZlci0+bWFqb3IsIGRyaXZlci0+bWlub3IsIGRy aXZlci0+cGF0Y2hsZXZlbCwKPiArCQkgZHJpdmVyLT5kYXRlLCBkZXYtPnByaW1hcnktPmluZGV4 KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK2Vycl9mcmVlOgo+ICsJZHJtX2Rldl91bnJlZihk ZXYpOwo+ICsJcmV0dXJuIHJldDsKPiArfQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v dmlydGlvL3ZpcnRncHVfZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2 LmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjdkOTYxMGEKPiAtLS0g L2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2Rydi5jCj4g QEAgLTAsMCArMSwxMzYgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDE1IFJlZCBIYXQs IEluYy4KPiArICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPiArICoKPiArICogQXV0aG9yczoKPiAr ICogICAgRGF2ZSBBaXJsaWUgPGFpcmxpZWRAcmVkaGF0LmNvbT4KPiArICogICAgR2VyZCBIb2Zm bWFubiA8a3JheGVsQHJlZGhhdC5jb20+Cj4gKyAqCj4gKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5 IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCj4gKyAq IGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVz ICh0aGUgIlNvZnR3YXJlIiksCj4gKyAqIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQg cmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KPiArICogdGhlIHJpZ2h0 cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1Ymxp Y2Vuc2UsCj4gKyAqIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBw ZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQo+ICsgKiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8g ZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgo+ICsgKgo+ICsgKiBU aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5j bHVkaW5nIHRoZSBuZXh0Cj4gKyAqIHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxs IGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUKPiArICogU29mdHdhcmUuCj4g KyAqCj4gKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJB TlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCj4gKyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQg Tk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAo+ICsgKiBG SVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4g Tk8gRVZFTlQgU0hBTEwKPiArICogVkEgTElOVVggU1lTVEVNUyBBTkQvT1IgSVRTIFNVUFBMSUVS UyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUgo+ICsgKiBPVEhFUiBMSUFCSUxJ VFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwK PiArICogQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZU V0FSRSBPUiBUSEUgVVNFIE9SCj4gKyAqIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4K PiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9jb25zb2xlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wY2kuaD4KPiArI2luY2x1ZGUgImRybVAu aCIKPiArI2luY2x1ZGUgImRybS9kcm0uaCIKPiArCj4gKyNpbmNsdWRlICJ2aXJ0Z3B1X2Rydi5o Igo+ICtzdGF0aWMgc3RydWN0IGRybV9kcml2ZXIgZHJpdmVyOwo+ICsKPiArc3RhdGljIGludCB2 aXJ0aW9fZ3B1X21vZGVzZXQgPSAtMTsKPiArCj4gK01PRFVMRV9QQVJNX0RFU0MobW9kZXNldCwg IkRpc2FibGUvRW5hYmxlIG1vZGVzZXR0aW5nIik7Cj4gK21vZHVsZV9wYXJhbV9uYW1lZChtb2Rl c2V0LCB2aXJ0aW9fZ3B1X21vZGVzZXQsIGludCwgMDQwMCk7Cj4gKwo+ICtzdGF0aWMgaW50IHZp cnRpb19ncHVfcHJvYmUoc3RydWN0IHZpcnRpb19kZXZpY2UgKnZkZXYpCj4gK3sKPiArI2lmZGVm IENPTkZJR19WR0FfQ09OU09MRQo+ICsJaWYgKHZnYWNvbl90ZXh0X2ZvcmNlKCkgJiYgdmlydGlv X2dwdV9tb2Rlc2V0ID09IC0xKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsjZW5kaWYKPiArCj4g KwlpZiAodmlydGlvX2dwdV9tb2Rlc2V0ID09IDApCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ ICsJcmV0dXJuIGRybV92aXJ0aW9faW5pdCgmZHJpdmVyLCB2ZGV2KTsKPiArfQo+ICsKPiArc3Rh dGljIHZvaWQgdmlydGlvX2dwdV9yZW1vdmUoc3RydWN0IHZpcnRpb19kZXZpY2UgKnZkZXYpCj4g K3sKPiArCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYgPSB2ZGV2LT5wcml2Owo+ICsJZHJtX3B1dF9k ZXYoZGV2KTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9jb25maWdfY2hhbmdl ZChzdHJ1Y3QgdmlydGlvX2RldmljZSAqdmRldikKPiArewo+ICsJc3RydWN0IGRybV9kZXZpY2Ug KmRldiA9IHZkZXYtPnByaXY7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2ID0g ZGV2LT5kZXZfcHJpdmF0ZTsKPiArCj4gKwlzY2hlZHVsZV93b3JrKCZ2Z2Rldi0+Y29uZmlnX2No YW5nZWRfd29yayk7Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1Y3QgdmlydGlvX2RldmljZV9pZCBp ZF90YWJsZVtdID0gewo+ICsJeyBWSVJUSU9fSURfR1BVLCBWSVJUSU9fREVWX0FOWV9JRCB9LAo+ ICsJeyAwIH0sCj4gK307Cj4gKwo+ICtzdGF0aWMgdW5zaWduZWQgaW50IGZlYXR1cmVzW10gPSB7 Cj4gK307Cj4gK3N0YXRpYyBzdHJ1Y3QgdmlydGlvX2RyaXZlciB2aXJ0aW9fZ3B1X2RyaXZlciA9 IHsKPiArCS5mZWF0dXJlX3RhYmxlID0gZmVhdHVyZXMsCj4gKwkuZmVhdHVyZV90YWJsZV9zaXpl ID0gQVJSQVlfU0laRShmZWF0dXJlcyksCj4gKwkuZHJpdmVyLm5hbWUgPSBLQlVJTERfTU9ETkFN RSwKPiArCS5kcml2ZXIub3duZXIgPSBUSElTX01PRFVMRSwKPiArCS5pZF90YWJsZSA9IGlkX3Rh YmxlLAo+ICsJLnByb2JlID0gdmlydGlvX2dwdV9wcm9iZSwKPiArCS5yZW1vdmUgPSB2aXJ0aW9f Z3B1X3JlbW92ZSwKPiArCS5jb25maWdfY2hhbmdlZCA9IHZpcnRpb19ncHVfY29uZmlnX2NoYW5n ZWQKPiArfTsKPiArCj4gK21vZHVsZV92aXJ0aW9fZHJpdmVyKHZpcnRpb19ncHVfZHJpdmVyKTsK PiArCj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUodmlydGlvLCBpZF90YWJsZSk7Cj4gK01PRFVMRV9E RVNDUklQVElPTigiVmlydGlvIEdQVSBkcml2ZXIiKTsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCBh bmQgYWRkaXRpb25hbCByaWdodHMiKTsKPiArTU9EVUxFX0FVVEhPUigiRGF2ZSBBaXJsaWUgPGFp cmxpZWRAcmVkaGF0LmNvbT4iKTsKPiArTU9EVUxFX0FVVEhPUigiR2VyZCBIb2ZmbWFubiA8a3Jh eGVsQHJlZGhhdC5jb20+Iik7Cj4gK01PRFVMRV9BVVRIT1IoIkFsb24gTGV2eSIpOwo+ICsKPiAr c3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgdmlydGlvX2dwdV9kcml2ZXJfZm9w cyA9IHsKPiArCS5vd25lciA9IFRISVNfTU9EVUxFLAo+ICsJLm9wZW4gPSBkcm1fb3BlbiwKPiAr CS5tbWFwID0gdmlydGlvX2dwdV9tbWFwLAo+ICsJLnBvbGwgPSBkcm1fcG9sbCwKPiArCS5yZWFk ID0gZHJtX3JlYWQsCj4gKwkudW5sb2NrZWRfaW9jdGwJPSBkcm1faW9jdGwsCj4gKwkucmVsZWFz ZSA9IGRybV9yZWxlYXNlLAo+ICsjaWZkZWYgQ09ORklHX0NPTVBBVAo+ICsJLmNvbXBhdF9pb2N0 bCA9IGRybV9jb21wYXRfaW9jdGwsCj4gKyNlbmRpZgo+ICsJLmxsc2VlayA9IG5vb3BfbGxzZWVr LAo+ICt9Owo+ICsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgZHJtX2RyaXZlciBkcml2ZXIgPSB7Cj4g KwkuZHJpdmVyX2ZlYXR1cmVzID0gRFJJVkVSX01PREVTRVQgfCBEUklWRVJfR0VNLAo+ICsJLnNl dF9idXNpZCA9IGRybV92aXJ0aW9fc2V0X2J1c2lkLAo+ICsJLmxvYWQgPSB2aXJ0aW9fZ3B1X2Ry aXZlcl9sb2FkLAo+ICsJLnVubG9hZCA9IHZpcnRpb19ncHVfZHJpdmVyX3VubG9hZCwKPiArCj4g KwkuZHVtYl9jcmVhdGUgPSB2aXJ0aW9fZ3B1X21vZGVfZHVtYl9jcmVhdGUsCj4gKwkuZHVtYl9t YXBfb2Zmc2V0ID0gdmlydGlvX2dwdV9tb2RlX2R1bWJfbW1hcCwKPiArCS5kdW1iX2Rlc3Ryb3kg PSB2aXJ0aW9fZ3B1X21vZGVfZHVtYl9kZXN0cm95LAo+ICsKPiArI2lmIGRlZmluZWQoQ09ORklH X0RFQlVHX0ZTKQo+ICsJLmRlYnVnZnNfaW5pdCA9IHZpcnRpb19ncHVfZGVidWdmc19pbml0LAo+ ICsJLmRlYnVnZnNfY2xlYW51cCA9IHZpcnRpb19ncHVfZGVidWdmc190YWtlZG93biwKPiArI2Vu ZGlmCj4gKwo+ICsJLmdlbV9mcmVlX29iamVjdCA9IHZpcnRpb19ncHVfZ2VtX2ZyZWVfb2JqZWN0 LAo+ICsJLmZvcHMgPSAmdmlydGlvX2dwdV9kcml2ZXJfZm9wcywKPiArCj4gKwkubmFtZSA9IERS SVZFUl9OQU1FLAo+ICsJLmRlc2MgPSBEUklWRVJfREVTQywKPiArCS5kYXRlID0gRFJJVkVSX0RB VEUsCj4gKwkubWFqb3IgPSBEUklWRVJfTUFKT1IsCj4gKwkubWlub3IgPSBEUklWRVJfTUlOT1Is Cj4gKwkucGF0Y2hsZXZlbCA9IERSSVZFUl9QQVRDSExFVkVMLAo+ICt9Owo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmggYi9kcml2ZXJzL2dwdS9kcm0v dmlydGlvL3ZpcnRncHVfZHJ2LmgKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAw MDAuLmU1YTJjMDkKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRp by92aXJ0Z3B1X2Rydi5oCj4gQEAgLTAsMCArMSwzNTAgQEAKPiArLyoKPiArICogQ29weXJpZ2h0 IChDKSAyMDE1IFJlZCBIYXQsIEluYy4KPiArICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPiArICoK PiArICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFu eSBwZXJzb24gb2J0YWluaW5nCj4gKyAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3Nv Y2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQo+ICsgKiAiU29mdHdhcmUiKSwgdG8gZGVh bCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCj4gKyAqIHdp dGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwg cHVibGlzaCwKPiArICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVz IG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCj4gKyAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhl IFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwo+ICsgKiB0aGUgZm9s bG93aW5nIGNvbmRpdGlvbnM6Cj4gKyAqCj4gKyAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNl IGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCj4gKyAqIG5leHQgcGFy YWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsCj4g KyAqIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KPiArICoKPiArICogVEhFIFNPRlRXQVJFIElT IFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCj4gKyAqIEVY UFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFO VElFUyBPRgo+ICsgKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQ VVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCj4gKyAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBD T1BZUklHSFQgT1dORVIoUykgQU5EL09SIElUUyBTVVBQTElFUlMgQkUKPiArICogTElBQkxFIEZP UiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFD VElPTgo+ICsgKiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwg T1VUIE9GIE9SIElOIENPTk5FQ1RJT04KPiArICogV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVT RSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCj4gKyAqLwo+ICsKPiArI2lmbmRl ZiBWSVJUSU9fRFJWX0gKPiArI2RlZmluZSBWSVJUSU9fRFJWX0gKPiArCj4gKyNpbmNsdWRlIDxs aW51eC92aXJ0aW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L3ZpcnRpb19pZHMuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L3ZpcnRpb19jb25maWcuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3ZpcnRpb19ncHUu aD4KPiArCj4gKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9nZW0u aD4KPiArI2luY2x1ZGUgPGRybS9kcm1fY3J0Y19oZWxwZXIuaD4KPiArI2luY2x1ZGUgPHR0bS90 dG1fYm9fYXBpLmg+Cj4gKyNpbmNsdWRlIDx0dG0vdHRtX2JvX2RyaXZlci5oPgo+ICsjaW5jbHVk ZSA8dHRtL3R0bV9wbGFjZW1lbnQuaD4KPiArI2luY2x1ZGUgPHR0bS90dG1fbW9kdWxlLmg+Cj4g Kwo+ICsjZGVmaW5lIERSSVZFUl9OQU1FICJ2aXJ0aW9fZ3B1Igo+ICsjZGVmaW5lIERSSVZFUl9E RVNDICJ2aXJ0aW8gR1BVIgo+ICsjZGVmaW5lIERSSVZFUl9EQVRFICIwIgo+ICsKPiArI2RlZmlu ZSBEUklWRVJfTUFKT1IgMAo+ICsjZGVmaW5lIERSSVZFUl9NSU5PUiAwCj4gKyNkZWZpbmUgRFJJ VkVSX1BBVENITEVWRUwgMQo+ICsKPiArLyogdmlydGdwdV9kcm1fYnVzLmMgKi8KPiAraW50IGRy bV92aXJ0aW9fc2V0X2J1c2lkKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHN0cnVjdCBkcm1fbWFz dGVyICptYXN0ZXIpOwo+ICtpbnQgZHJtX3ZpcnRpb19pbml0KHN0cnVjdCBkcm1fZHJpdmVyICpk cml2ZXIsIHN0cnVjdCB2aXJ0aW9fZGV2aWNlICp2ZGV2KTsKPiArCj4gK3N0cnVjdCB2aXJ0aW9f Z3B1X29iamVjdCB7Cj4gKwlzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgZ2VtX2Jhc2U7Cj4gKwl1aW50 MzJfdCBod19yZXNfaGFuZGxlOwo+ICsKPiArCXN0cnVjdCBzZ190YWJsZSAqcGFnZXM7Cj4gKwl2 b2lkICp2bWFwOwo+ICsJYm9vbCBkdW1iOwo+ICsJc3RydWN0IHR0bV9wbGFjZSAgICAgICAgICAg ICAgICBwbGFjZW1lbnRfY29kZTsKPiArCXN0cnVjdCB0dG1fcGxhY2VtZW50CQlwbGFjZW1lbnQ7 Cj4gKwlzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QJdGJvOwo+ICsJc3RydWN0IHR0bV9ib19rbWFw X29iagkJa21hcDsKPiArfTsKPiArI2RlZmluZSBnZW1fdG9fdmlydGlvX2dwdV9vYmooZ29iaikg XAo+ICsJY29udGFpbmVyX29mKChnb2JqKSwgc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0LCBnZW1f YmFzZSkKPiArCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXI7Cj4gK3N0cnVjdCB2aXJ0aW9f Z3B1X2RldmljZTsKPiArCj4gK3R5cGVkZWYgdm9pZCAoKnZpcnRpb19ncHVfcmVzcF9jYikoc3Ry dWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCSAgIHN0cnVjdCB2aXJ0aW9fZ3B1 X3ZidWZmZXIgKnZidWYpOwo+ICsKPiArc3RydWN0IHZpcnRpb19ncHVfZmVuY2VfZHJpdmVyIHsK PiArCWF0b21pYzY0X3QgICAgICAgbGFzdF9zZXE7Cj4gKwl1aW50NjRfdCAgICAgICAgIHN5bmNf c2VxOwo+ICsJc3RydWN0IGxpc3RfaGVhZCBmZW5jZXM7Cj4gKwlzcGlubG9ja190ICAgICAgIGxv Y2s7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9mZW5jZSB7Cj4gKwlzdHJ1Y3QgZmVu Y2UgZjsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZlbmNlX2RyaXZlciAqZHJ2Owo+ICsJc3RydWN0 IGxpc3RfaGVhZCBub2RlOwo+ICsJdWludDY0X3Qgc2VxOwo+ICt9Owo+ICsjZGVmaW5lIHRvX3Zp cnRpb19mZW5jZSh4KSBcCj4gKwljb250YWluZXJfb2YoeCwgc3RydWN0IHZpcnRpb19ncHVfZmVu Y2UsIGYpCj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV92YnVmZmVyIHsKPiArCWNoYXIgKmJ1ZjsK PiArCWludCBzaXplOwo+ICsKPiArCXZvaWQgKmRhdGFfYnVmOwo+ICsJdWludDMyX3QgZGF0YV9z aXplOwo+ICsKPiArCWNoYXIgKnJlc3BfYnVmOwo+ICsJaW50IHJlc3Bfc2l6ZTsKPiArCj4gKwl2 aXJ0aW9fZ3B1X3Jlc3BfY2IgcmVzcF9jYjsKPiArCj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7 Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgewo+ICsJaW50IGluZGV4Owo+ ICsJc3RydWN0IGRybV9jcnRjIGNydGM7Cj4gKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciBjb25uOwo+ ICsJc3RydWN0IGRybV9lbmNvZGVyIGVuYzsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2Rpc3BsYXlf b25lIGluZm87Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV91cGRhdGVfY3Vyc29yIGN1cnNvcjsKPiAr CWludCBjdXJfeDsKPiArCWludCBjdXJfeTsKPiArfTsKPiArI2RlZmluZSBkcm1fY3J0Y190b192 aXJ0aW9fZ3B1X291dHB1dCh4KSBcCj4gKwljb250YWluZXJfb2YoeCwgc3RydWN0IHZpcnRpb19n cHVfb3V0cHV0LCBjcnRjKQo+ICsjZGVmaW5lIGRybV9jb25uZWN0b3JfdG9fdmlydGlvX2dwdV9v dXRwdXQoeCkgXAo+ICsJY29udGFpbmVyX29mKHgsIHN0cnVjdCB2aXJ0aW9fZ3B1X291dHB1dCwg Y29ubikKPiArI2RlZmluZSBkcm1fZW5jb2Rlcl90b192aXJ0aW9fZ3B1X291dHB1dCh4KSBcCj4g Kwljb250YWluZXJfb2YoeCwgc3RydWN0IHZpcnRpb19ncHVfb3V0cHV0LCBlbmMpCj4gKwo+ICtz dHJ1Y3QgdmlydGlvX2dwdV9mcmFtZWJ1ZmZlciB7Cj4gKwlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVy IGJhc2U7Cj4gKwlzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iajsKPiArCWludCB4MSwgeTEsIHgy LCB5MjsgLyogZGlydHkgcmVjdCAqLwo+ICsJc3BpbmxvY2tfdCBkaXJ0eV9sb2NrOwo+ICsJdWlu dDMyX3QgaHdfcmVzX2hhbmRsZTsKPiArfTsKPiArI2RlZmluZSB0b192aXJ0aW9fZ3B1X2ZyYW1l YnVmZmVyKHgpIFwKPiArCWNvbnRhaW5lcl9vZih4LCBzdHJ1Y3QgdmlydGlvX2dwdV9mcmFtZWJ1 ZmZlciwgYmFzZSkKPiArCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X21tYW4gewo+ICsJc3RydWN0IHR0 bV9ib19nbG9iYWxfcmVmICAgICAgICBib19nbG9iYWxfcmVmOwo+ICsJc3RydWN0IGRybV9nbG9i YWxfcmVmZXJlbmNlCW1lbV9nbG9iYWxfcmVmOwo+ICsJYm9vbAkJCQltZW1fZ2xvYmFsX3JlZmVy ZW5jZWQ7Cj4gKwlzdHJ1Y3QgdHRtX2JvX2RldmljZQkJYmRldjsKPiArfTsKPiArCj4gK3N0cnVj dCB2aXJ0aW9fZ3B1X2ZiZGV2Owo+ICsKPiArc3RydWN0IHZpcnRpb19ncHVfcXVldWUgewo+ICsJ c3RydWN0IHZpcnRxdWV1ZSAqdnE7Cj4gKwlzcGlubG9ja190IHFsb2NrOwo+ICsJd2FpdF9xdWV1 ZV9oZWFkX3QgYWNrX3F1ZXVlOwo+ICsJc3RydWN0IHdvcmtfc3RydWN0IGRlcXVldWVfd29yazsK PiArfTsKPiArCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSB7Cj4gKwlzdHJ1Y3QgZGV2aWNl ICpkZXY7Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGRldjsKPiArCj4gKwlzdHJ1Y3QgdmlydGlv X2RldmljZSAqdmRldjsKPiArCj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9tbWFuIG1tYW47Cj4gKwo+ ICsJLyogcG9pbnRlciB0byBmYmRldiBpbmZvIHN0cnVjdHVyZSAqLwo+ICsJc3RydWN0IHZpcnRp b19ncHVfZmJkZXYgKnZnZmJkZXY7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgb3V0cHV0 c1tWSVJUSU9fR1BVX01BWF9TQ0FOT1VUU107Cj4gKwl1aW50MzJfdCBudW1fc2Nhbm91dHM7Cj4g Kwo+ICsJc3RydWN0IHZpcnRpb19ncHVfcXVldWUgY3RybHE7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dw dV9xdWV1ZSBjdXJzb3JxOwo+ICsJc3RydWN0IGxpc3RfaGVhZCBmcmVlX3ZidWZzOwo+ICsJdm9p ZCAqdmJ1ZnM7Cj4gKwlib29sIHZxc19yZWFkeTsKPiArCj4gKwlzdHJ1Y3QgaWRyCXJlc291cmNl X2lkcjsKPiArCXNwaW5sb2NrX3QgcmVzb3VyY2VfaWRyX2xvY2s7Cj4gKwo+ICsJd2FpdF9xdWV1 ZV9oZWFkX3QgcmVzcF93cTsKPiArCS8qIGN1cnJlbnQgZGlzcGxheSBpbmZvICovCj4gKwlzcGlu bG9ja190IGRpc3BsYXlfaW5mb19sb2NrOwo+ICsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZlbmNl X2RyaXZlciBmZW5jZV9kcnY7Cj4gKwo+ICsJc3RydWN0IGlkcgljdHhfaWRfaWRyOwo+ICsJc3Bp bmxvY2tfdCBjdHhfaWRfaWRyX2xvY2s7Cj4gKwo+ICsJc3RydWN0IHdvcmtfc3RydWN0IGNvbmZp Z19jaGFuZ2VkX3dvcms7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9mcHJpdiB7Cj4g Kwl1aW50MzJfdCBjdHhfaWQ7Cj4gK307Cj4gKwo+ICsvKiB2aXJ0aW9faW9jdGwuYyAqLwo+ICsj ZGVmaW5lIERSTV9WSVJUSU9fTlVNX0lPQ1RMUyAxMAo+ICtleHRlcm4gc3RydWN0IGRybV9pb2N0 bF9kZXNjIHZpcnRpb19ncHVfaW9jdGxzW0RSTV9WSVJUSU9fTlVNX0lPQ1RMU107Cj4gKwo+ICsv KiB2aXJ0aW9fa21zLmMgKi8KPiAraW50IHZpcnRpb19ncHVfZHJpdmVyX2xvYWQoc3RydWN0IGRy bV9kZXZpY2UgKmRldiwgdW5zaWduZWQgbG9uZyBmbGFncyk7Cj4gK2ludCB2aXJ0aW9fZ3B1X2Ry aXZlcl91bmxvYWQoc3RydWN0IGRybV9kZXZpY2UgKmRldik7Cj4gKwo+ICsvKiB2aXJ0aW9fZ2Vt LmMgKi8KPiArdm9pZCB2aXJ0aW9fZ3B1X2dlbV9mcmVlX29iamVjdChzdHJ1Y3QgZHJtX2dlbV9v YmplY3QgKmdlbV9vYmopOwo+ICtpbnQgdmlydGlvX2dwdV9nZW1faW5pdChzdHJ1Y3QgdmlydGlv X2dwdV9kZXZpY2UgKnZnZGV2KTsKPiArdm9pZCB2aXJ0aW9fZ3B1X2dlbV9maW5pKHN0cnVjdCB2 aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYpOwo+ICtpbnQgdmlydGlvX2dwdV9nZW1fY3JlYXRlKHN0 cnVjdCBkcm1fZmlsZSAqZmlsZSwKPiArCQkJICBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJ CQkgIHVpbnQ2NF90IHNpemUsCj4gKwkJCSAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICoqb2JqX3As Cj4gKwkJCSAgdWludDMyX3QgKmhhbmRsZV9wKTsKPiArc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0 ICp2aXJ0aW9fZ3B1X2FsbG9jX29iamVjdChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJCQkJ CQkgIHNpemVfdCBzaXplLCBib29sIGtlcm5lbCwKPiArCQkJCQkJICBib29sIHBpbm5lZCk7Cj4g K2ludCB2aXJ0aW9fZ3B1X21vZGVfZHVtYl9jcmVhdGUoc3RydWN0IGRybV9maWxlICpmaWxlX3By aXYsCj4gKwkJCQlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJCQkJc3RydWN0IGRybV9tb2Rl X2NyZWF0ZV9kdW1iICphcmdzKTsKPiAraW50IHZpcnRpb19ncHVfbW9kZV9kdW1iX2Rlc3Ryb3ko c3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsCj4gKwkJCQkgc3RydWN0IGRybV9kZXZpY2UgKmRl diwKPiArCQkJCSB1aW50MzJfdCBoYW5kbGUpOwo+ICtpbnQgdmlydGlvX2dwdV9tb2RlX2R1bWJf bW1hcChzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVfcHJpdiwKPiArCQkJICAgICAgc3RydWN0IGRybV9k ZXZpY2UgKmRldiwKPiArCQkJICAgICAgdWludDMyX3QgaGFuZGxlLCB1aW50NjRfdCAqb2Zmc2V0 X3ApOwo+ICsKPiArLyogdmlydGlvX2ZiICovCj4gKyNkZWZpbmUgVklSVElPX0dQVUZCX0NPTk5f TElNSVQgMQo+ICtpbnQgdmlydGlvX2dwdV9mYmRldl9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2Rl dmljZSAqdmdkZXYpOwo+ICt2b2lkIHZpcnRpb19ncHVfZmJkZXZfZmluaShzdHJ1Y3QgdmlydGlv X2dwdV9kZXZpY2UgKnZnZGV2KTsKPiAraW50IHZpcnRpb19ncHVfc3VyZmFjZV9kaXJ0eShzdHJ1 Y3QgdmlydGlvX2dwdV9mcmFtZWJ1ZmZlciAqcWZiLAo+ICsJCQkgICAgIHN0cnVjdCBkcm1fY2xp cF9yZWN0ICpjbGlwcywKPiArCQkJICAgICB1bnNpZ25lZCBudW1fY2xpcHMpOwo+ICsvKiB2aXJ0 aW8gdmcgKi8KPiAraW50IHZpcnRpb19ncHVfYWxsb2NfdmJ1ZnMoc3RydWN0IHZpcnRpb19ncHVf ZGV2aWNlICp2Z2Rldik7Cj4gK3ZvaWQgdmlydGlvX2dwdV9mcmVlX3ZidWZzKHN0cnVjdCB2aXJ0 aW9fZ3B1X2RldmljZSAqdmdkZXYpOwo+ICt2b2lkIHZpcnRpb19ncHVfcmVzb3VyY2VfaWRfZ2V0 KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCSAgICAgICB1aW50MzJfdCAq cmVzaWQpOwo+ICt2b2lkIHZpcnRpb19ncHVfcmVzb3VyY2VfaWRfcHV0KHN0cnVjdCB2aXJ0aW9f Z3B1X2RldmljZSAqdmdkZXYsIHVpbnQzMl90IGlkKTsKPiArdm9pZCB2aXJ0aW9fZ3B1X2NtZF9j cmVhdGVfcmVzb3VyY2Uoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCSAg ICB1aW50MzJfdCByZXNvdXJjZV9pZCwKPiArCQkJCSAgICB1aW50MzJfdCBmb3JtYXQsCj4gKwkJ CQkgICAgdWludDMyX3Qgd2lkdGgsCj4gKwkJCQkgICAgdWludDMyX3QgaGVpZ2h0KTsKPiArdm9p ZCB2aXJ0aW9fZ3B1X2NtZF91bnJlZl9yZXNvdXJjZShzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2Ug KnZnZGV2LAo+ICsJCQkJICAgdWludDMyX3QgcmVzb3VyY2VfaWQpOwo+ICt2b2lkIHZpcnRpb19n cHVfY21kX3RyYW5zZmVyX3RvX2hvc3RfMmQoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2Rl diwKPiArCQkJCQl1aW50MzJfdCByZXNvdXJjZV9pZCwgdWludDY0X3Qgb2Zmc2V0LAo+ICsJCQkJ CV9fbGUzMiB3aWR0aCwgX19sZTMyIGhlaWdodCwKPiArCQkJCQlfX2xlMzIgeCwgX19sZTMyIHks Cj4gKwkJCQkJc3RydWN0IHZpcnRpb19ncHVfZmVuY2UgKipmZW5jZSk7Cj4gK3ZvaWQgdmlydGlv X2dwdV9jbWRfcmVzb3VyY2VfZmx1c2goc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwK PiArCQkJCSAgIHVpbnQzMl90IHJlc291cmNlX2lkLAo+ICsJCQkJICAgdWludDMyX3QgeCwgdWlu dDMyX3QgeSwKPiArCQkJCSAgIHVpbnQzMl90IHdpZHRoLCB1aW50MzJfdCBoZWlnaHQpOwo+ICt2 b2lkIHZpcnRpb19ncHVfY21kX3NldF9zY2Fub3V0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAq dmdkZXYsCj4gKwkJCQl1aW50MzJfdCBzY2Fub3V0X2lkLCB1aW50MzJfdCByZXNvdXJjZV9pZCwK PiArCQkJCXVpbnQzMl90IHdpZHRoLCB1aW50MzJfdCBoZWlnaHQsCj4gKwkJCQl1aW50MzJfdCB4 LCB1aW50MzJfdCB5KTsKPiAraW50IHZpcnRpb19ncHVfb2JqZWN0X2F0dGFjaChzdHJ1Y3Qgdmly dGlvX2dwdV9kZXZpY2UgKnZnZGV2LAo+ICsJCQkgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVj dCAqb2JqLAo+ICsJCQkgICAgIHVpbnQzMl90IHJlc291cmNlX2lkLAo+ICsJCQkgICAgIHN0cnVj dCB2aXJ0aW9fZ3B1X2ZlbmNlICoqZmVuY2UpOwo+ICtpbnQgdmlydGlvX2dwdV9hdHRhY2hfc3Rh dHVzX3BhZ2Uoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2Rldik7Cj4gK2ludCB2aXJ0aW9f Z3B1X2RldGFjaF9zdGF0dXNfcGFnZShzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2KTsK PiArdm9pZCB2aXJ0aW9fZ3B1X2N1cnNvcl9waW5nKHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAq dmdkZXYsCj4gKwkJCSAgICBzdHJ1Y3QgdmlydGlvX2dwdV9vdXRwdXQgKm91dHB1dCk7Cj4gK2lu dCB2aXJ0aW9fZ3B1X2NtZF9nZXRfZGlzcGxheV9pbmZvKHN0cnVjdCB2aXJ0aW9fZ3B1X2Rldmlj ZSAqdmdkZXYpOwo+ICt2b2lkIHZpcnRpb19ncHVfY21kX3Jlc291cmNlX2ludmFsX2JhY2tpbmco c3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCQkgICB1aW50MzJfdCByZXNv dXJjZV9pZCk7Cj4gK3ZvaWQgdmlydGlvX2dwdV9jdHJsX2FjayhzdHJ1Y3QgdmlydHF1ZXVlICp2 cSk7Cj4gK3ZvaWQgdmlydGlvX2dwdV9jdXJzb3JfYWNrKHN0cnVjdCB2aXJ0cXVldWUgKnZxKTsK PiArdm9pZCB2aXJ0aW9fZ3B1X2RlcXVldWVfY3RybF9mdW5jKHN0cnVjdCB3b3JrX3N0cnVjdCAq d29yayk7Cj4gK3ZvaWQgdmlydGlvX2dwdV9kZXF1ZXVlX2N1cnNvcl9mdW5jKHN0cnVjdCB3b3Jr X3N0cnVjdCAqd29yayk7Cj4gKwo+ICsvKiB2aXJ0aW9fZ3B1X2Rpc3BsYXkuYyAqLwo+ICtpbnQg dmlydGlvX2dwdV9mcmFtZWJ1ZmZlcl9pbml0KHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4gKwkJ CQlzdHJ1Y3QgdmlydGlvX2dwdV9mcmFtZWJ1ZmZlciAqdmdmYiwKPiArCQkJCXN0cnVjdCBkcm1f bW9kZV9mYl9jbWQyICptb2RlX2NtZCwKPiArCQkJCXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2Jq KTsKPiAraW50IHZpcnRpb19ncHVfbW9kZXNldF9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2Rldmlj ZSAqdmdkZXYpOwo+ICt2b2lkIHZpcnRpb19ncHVfbW9kZXNldF9maW5pKHN0cnVjdCB2aXJ0aW9f Z3B1X2RldmljZSAqdmdkZXYpOwo+ICsKPiArLyogdmlydGlvX2dwdV9wbGFuZS5jICovCj4gK3N0 cnVjdCBkcm1fcGxhbmUgKnZpcnRpb19ncHVfcGxhbmVfaW5pdChzdHJ1Y3QgdmlydGlvX2dwdV9k ZXZpY2UgKnZnZGV2LAo+ICsJCQkJCWludCBpbmRleCk7Cj4gKwo+ICsvKiB2aXJ0aW9fZ3B1X3R0 bS5jICovCj4gK2ludCB2aXJ0aW9fZ3B1X3R0bV9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2Rldmlj ZSAqdmdkZXYpOwo+ICt2b2lkIHZpcnRpb19ncHVfdHRtX2Zpbmkoc3RydWN0IHZpcnRpb19ncHVf ZGV2aWNlICp2Z2Rldik7Cj4gK2ludCB2aXJ0aW9fZ3B1X21tYXAoc3RydWN0IGZpbGUgKmZpbHAs IHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKTsKPiArCj4gKy8qIHZpcnRpb19ncHVfZmVuY2Uu YyAqLwo+ICtpbnQgdmlydGlvX2dwdV9mZW5jZV9lbWl0KHN0cnVjdCB2aXJ0aW9fZ3B1X2Rldmlj ZSAqdmdkZXYsCj4gKwkJCSAgc3RydWN0IHZpcnRpb19ncHVfY3RybF9oZHIgKmNtZF9oZHIsCj4g KwkJCSAgc3RydWN0IHZpcnRpb19ncHVfZmVuY2UgKipmZW5jZSk7Cj4gK3ZvaWQgdmlydGlvX2dw dV9mZW5jZV9ldmVudF9wcm9jZXNzKHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmRldiwKPiAr CQkJCSAgICB1NjQgbGFzdF9zZXEpOwo+ICsKPiArLyogdmlydGlvX2dwdV9vYmplY3QgKi8KPiAr aW50IHZpcnRpb19ncHVfb2JqZWN0X2NyZWF0ZShzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZn ZGV2LAo+ICsJCQkgICAgIHVuc2lnbmVkIGxvbmcgc2l6ZSwgYm9vbCBrZXJuZWwsIGJvb2wgcGlu bmVkLAo+ICsJCQkgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqKmJvX3B0cik7Cj4gK2lu dCB2aXJ0aW9fZ3B1X29iamVjdF9rbWFwKHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8sIHZv aWQgKipwdHIpOwo+ICtpbnQgdmlydGlvX2dwdV9vYmplY3RfZ2V0X3NnX3RhYmxlKHN0cnVjdCB2 aXJ0aW9fZ3B1X2RldmljZSAqcWRldiwKPiArCQkJCSAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVj dCAqYm8pOwo+ICt2b2lkIHZpcnRpb19ncHVfb2JqZWN0X2ZyZWVfc2dfdGFibGUoc3RydWN0IHZp cnRpb19ncHVfb2JqZWN0ICpibyk7Cj4gK2ludCB2aXJ0aW9fZ3B1X29iamVjdF93YWl0KHN0cnVj dCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8sIGJvb2wgbm9fd2FpdCk7Cj4gKwo+ICtzdGF0aWMgaW5s aW5lIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCoKPiArdmlydGlvX2dwdV9vYmplY3RfcmVmKHN0 cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8pCj4gK3sKPiArCXR0bV9ib19yZWZlcmVuY2UoJmJv LT50Ym8pOwo+ICsJcmV0dXJuIGJvOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW5saW5lIHZvaWQgdmly dGlvX2dwdV9vYmplY3RfdW5yZWYoc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0ICoqYm8pCj4gK3sK PiArCXN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqdGJvOwo+ICsKPiArCWlmICgoKmJvKSA9PSBO VUxMKQo+ICsJCXJldHVybjsKPiArCXRibyA9ICYoKCpibyktPnRibyk7Cj4gKwl0dG1fYm9fdW5y ZWYoJnRibyk7Cj4gKwlpZiAodGJvID09IE5VTEwpCj4gKwkJKmJvID0gTlVMTDsKPiArfQo+ICsK PiArc3RhdGljIGlubGluZSB1NjQgdmlydGlvX2dwdV9vYmplY3RfbW1hcF9vZmZzZXQoc3RydWN0 IHZpcnRpb19ncHVfb2JqZWN0ICpibykKPiArewo+ICsJcmV0dXJuIGRybV92bWFfbm9kZV9vZmZz ZXRfYWRkcigmYm8tPnRiby52bWFfbm9kZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgaW50 IHZpcnRpb19ncHVfb2JqZWN0X3Jlc2VydmUoc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0ICpibywK PiArCQkJCQkgYm9vbCBub193YWl0KQo+ICt7Cj4gKwlpbnQgcjsKPiArCj4gKwlyID0gdHRtX2Jv X3Jlc2VydmUoJmJvLT50Ym8sIHRydWUsIG5vX3dhaXQsIGZhbHNlLCBOVUxMKTsKPiArCWlmICh1 bmxpa2VseShyICE9IDApKSB7Cj4gKwkJaWYgKHIgIT0gLUVSRVNUQVJUU1lTKSB7Cj4gKwkJCXN0 cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqcWRldiA9Cj4gKwkJCQliby0+Z2VtX2Jhc2UuZGV2LT5k ZXZfcHJpdmF0ZTsKPiArCQkJZGV2X2VycihxZGV2LT5kZXYsICIlcCByZXNlcnZlIGZhaWxlZFxu IiwgYm8pOwo+ICsJCX0KPiArCQlyZXR1cm4gcjsKPiArCX0KPiArCXJldHVybiAwOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW5saW5lIHZvaWQgdmlydGlvX2dwdV9vYmplY3RfdW5yZXNlcnZlKHN0cnVj dCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8pCj4gK3sKPiArCXR0bV9ib191bnJlc2VydmUoJmJvLT50 Ym8pOwo+ICt9Cj4gKwo+ICsvKiB2aXJnbCBkZWJ1ZnMgKi8KPiAraW50IHZpcnRpb19ncHVfZGVi dWdmc19pbml0KHN0cnVjdCBkcm1fbWlub3IgKm1pbm9yKTsKPiArdm9pZCB2aXJ0aW9fZ3B1X2Rl YnVnZnNfdGFrZWRvd24oc3RydWN0IGRybV9taW5vciAqbWlub3IpOwo+ICsKPiArI2VuZGlmCj4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9mYi5jIGIvZHJpdmVy cy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2ZiLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGlu ZGV4IDAwMDAwMDAuLjI1YmYzMzMKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL3ZpcnRpby92aXJ0Z3B1X2ZiLmMKPiBAQCAtMCwwICsxLDQzMSBAQAo+ICsvKgo+ICsgKiBD b3B5cmlnaHQgKEMpIDIwMTUgUmVkIEhhdCwgSW5jLgo+ICsgKiBBbGwgUmlnaHRzIFJlc2VydmVk Lgo+ICsgKgo+ICsgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJn ZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKPiArICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUg YW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCj4gKyAqICJTb2Z0d2FyZSIp LCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcK PiArICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnks IG1lcmdlLCBwdWJsaXNoLAo+ICsgKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2Vs bCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KPiArICogcGVybWl0IHBlcnNvbnMgdG8g d2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCj4gKyAq IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKPiArICoKPiArICogVGhlIGFib3ZlIGNvcHlyaWdo dCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUKPiArICog bmV4dCBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3Rh bnRpYWwKPiArICogcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgo+ICsgKgo+ICsgKiBUSEUgU09G VFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwK PiArICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRI RSBXQVJSQU5USUVTIE9GCj4gKyAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJU SUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KPiArICogSU4gTk8gRVZFTlQgU0hB TEwgVEhFIENPUFlSSUdIVCBPV05FUihTKSBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRQo+ICsgKiBM SUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIg SU4gQU4gQUNUSU9OCj4gKyAqIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lO RyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgo+ICsgKiBXSVRIIFRIRSBTT0ZUV0FSRSBP UiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KPiArICovCj4gKwo+ ICsjaW5jbHVkZSA8ZHJtL2RybVAuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fZmJfaGVscGVyLmg+ Cj4gKyNpbmNsdWRlICJ2aXJ0Z3B1X2Rydi5oIgo+ICsKPiArI2RlZmluZSBWSVJUSU9fR1BVX0ZC Q09OX1BPTExfUEVSSU9EIChIWiAvIDYwKQo+ICsKPiArc3RydWN0IHZpcnRpb19ncHVfZmJkZXYg ewo+ICsJc3RydWN0IGRybV9mYl9oZWxwZXIgICAgICAgICAgIGhlbHBlcjsKPiArCXN0cnVjdCB2 aXJ0aW9fZ3B1X2ZyYW1lYnVmZmVyICB2Z2ZiOwo+ICsJc3RydWN0IGxpc3RfaGVhZAkgICAgICAg ZmJkZXZfbGlzdDsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAgICAgICAqdmdkZXY7Cj4g KwlzdHJ1Y3QgZGVsYXllZF93b3JrICAgICAgICAgICAgd29yazsKPiArfTsKPiArCj4gK3N0YXRp YyBpbnQgdmlydGlvX2dwdV9kaXJ0eV91cGRhdGUoc3RydWN0IHZpcnRpb19ncHVfZnJhbWVidWZm ZXIgKmZiLAo+ICsJCQkJICAgYm9vbCBzdG9yZSwgaW50IHgsIGludCB5LAo+ICsJCQkJICAgaW50 IHdpZHRoLCBpbnQgaGVpZ2h0KQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gZmIt PmJhc2UuZGV2Owo+ICsJc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiA9IGRldi0+ZGV2 X3ByaXZhdGU7Cj4gKwlib29sIHN0b3JlX2Zvcl9sYXRlciA9IGZhbHNlOwo+ICsJaW50IGJwcCA9 IGZiLT5iYXNlLmJpdHNfcGVyX3BpeGVsIC8gODsKPiArCWludCB4MiwgeTI7Cj4gKwl1bnNpZ25l ZCBsb25nIGZsYWdzOwo+ICsJc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0ICpvYmogPSBnZW1fdG9f dmlydGlvX2dwdV9vYmooZmItPm9iaik7Cj4gKwo+ICsJaWYgKCh3aWR0aCA8PSAwKSB8fAo+ICsJ ICAgICh4ICsgd2lkdGggPiBmYi0+YmFzZS53aWR0aCkgfHwKPiArCSAgICAoeSArIGhlaWdodCA+ IGZiLT5iYXNlLmhlaWdodCkpIHsKPiArCQlEUk1fREVCVUcoInZhbHVlcyBvdXQgb2YgcmFuZ2Ug JWR4JWQrJWQrJWQsIGZiICVkeCVkXG4iLAo+ICsJCQkgIHdpZHRoLCBoZWlnaHQsIHgsIHksCj4g KwkJCSAgZmItPmJhc2Uud2lkdGgsIGZiLT5iYXNlLmhlaWdodCk7Cj4gKwkJcmV0dXJuIC1FSU5W QUw7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAqIENhbiBiZSBjYWxsZWQgd2l0aCBwcmV0dHkgbXVj aCBhbnkgY29udGV4dCAoY29uc29sZSBvdXRwdXQKPiArCSAqIHBhdGgpLiAgSWYgd2UgYXJlIGlu IGF0b21pYyBqdXN0IHN0b3JlIHRoZSBkaXJ0eSByZWN0IGluZm8KPiArCSAqIHRvIHNlbmQgb3V0 IHRoZSB1cGRhdGUgbGF0ZXIuCj4gKwkgKgo+ICsJICogQ2FuJ3QgdGVzdCBpbnNpZGUgc3BpbiBs b2NrLgo+ICsJICovCj4gKwlpZiAoaW5fYXRvbWljKCkgfHwgc3RvcmUpCj4gKwkJc3RvcmVfZm9y X2xhdGVyID0gdHJ1ZTsKPiArCj4gKwl4MiA9IHggKyB3aWR0aCAtIDE7Cj4gKwl5MiA9IHkgKyBo ZWlnaHQgLSAxOwo+ICsKPiArCXNwaW5fbG9ja19pcnFzYXZlKCZmYi0+ZGlydHlfbG9jaywgZmxh Z3MpOwo+ICsKPiArCWlmIChmYi0+eTEgPCB5KQo+ICsJCXkgPSBmYi0+eTE7Cj4gKwlpZiAoZmIt PnkyID4geTIpCj4gKwkJeTIgPSBmYi0+eTI7Cj4gKwlpZiAoZmItPngxIDwgeCkKPiArCQl4ID0g ZmItPngxOwo+ICsJaWYgKGZiLT54MiA+IHgyKQo+ICsJCXgyID0gZmItPngyOwo+ICsKPiArCWlm IChzdG9yZV9mb3JfbGF0ZXIpIHsKPiArCQlmYi0+eDEgPSB4Owo+ICsJCWZiLT54MiA9IHgyOwo+ ICsJCWZiLT55MSA9IHk7Cj4gKwkJZmItPnkyID0geTI7Cj4gKwkJc3Bpbl91bmxvY2tfaXJxcmVz dG9yZSgmZmItPmRpcnR5X2xvY2ssIGZsYWdzKTsKPiArCQlyZXR1cm4gMDsKPiArCX0KPiArCj4g KwlmYi0+eDEgPSBmYi0+eTEgPSBJTlRfTUFYOwo+ICsJZmItPngyID0gZmItPnkyID0gMDsKPiAr Cj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZmYi0+ZGlydHlfbG9jaywgZmxhZ3MpOwo+ICsK PiArCXsKPiArCQl1aW50MzJfdCBvZmZzZXQ7Cj4gKwkJdWludDMyX3QgdyA9IHgyIC0geCArIDE7 Cj4gKwkJdWludDMyX3QgaCA9IHkyIC0geSArIDE7Cj4gKwo+ICsJCW9mZnNldCA9ICh5ICogZmIt PmJhc2UucGl0Y2hlc1swXSkgKyB4ICogYnBwOwo+ICsKPiArCQl2aXJ0aW9fZ3B1X2NtZF90cmFu c2Zlcl90b19ob3N0XzJkKHZnZGV2LCBvYmotPmh3X3Jlc19oYW5kbGUsCj4gKwkJCQkJCSAgIG9m ZnNldCwKPiArCQkJCQkJICAgY3B1X3RvX2xlMzIodyksCj4gKwkJCQkJCSAgIGNwdV90b19sZTMy KGgpLAo+ICsJCQkJCQkgICBjcHVfdG9fbGUzMih4KSwKPiArCQkJCQkJICAgY3B1X3RvX2xlMzIo eSksCj4gKwkJCQkJCSAgIE5VTEwpOwo+ICsKPiArCX0KPiArCXZpcnRpb19ncHVfY21kX3Jlc291 cmNlX2ZsdXNoKHZnZGV2LCBvYmotPmh3X3Jlc19oYW5kbGUsCj4gKwkJCQkgICAgICB4LCB5LCB4 MiAtIHggKyAxLCB5MiAtIHkgKyAxKTsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtpbnQgdmly dGlvX2dwdV9zdXJmYWNlX2RpcnR5KHN0cnVjdCB2aXJ0aW9fZ3B1X2ZyYW1lYnVmZmVyICp2Z2Zi LAo+ICsJCQkgICAgIHN0cnVjdCBkcm1fY2xpcF9yZWN0ICpjbGlwcywKPiArCQkJICAgICB1bnNp Z25lZCBudW1fY2xpcHMpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYg PSB2Z2ZiLT5iYXNlLmRldi0+ZGV2X3ByaXZhdGU7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vYmpl Y3QgKm9iaiA9IGdlbV90b192aXJ0aW9fZ3B1X29iaih2Z2ZiLT5vYmopOwo+ICsJc3RydWN0IGRy bV9jbGlwX3JlY3Qgbm9yZWN0Owo+ICsJc3RydWN0IGRybV9jbGlwX3JlY3QgKmNsaXBzX3B0cjsK PiArCWludCBsZWZ0LCByaWdodCwgdG9wLCBib3R0b207Cj4gKwlpbnQgaTsKPiArCWludCBpbmMg PSAxOwo+ICsJaWYgKCFudW1fY2xpcHMpIHsKPiArCQludW1fY2xpcHMgPSAxOwo+ICsJCWNsaXBz ID0gJm5vcmVjdDsKPiArCQlub3JlY3QueDEgPSBub3JlY3QueTEgPSAwOwo+ICsJCW5vcmVjdC54 MiA9IHZnZmItPmJhc2Uud2lkdGg7Cj4gKwkJbm9yZWN0LnkyID0gdmdmYi0+YmFzZS5oZWlnaHQ7 Cj4gKwl9Cj4gKwlsZWZ0ID0gY2xpcHMtPngxOwo+ICsJcmlnaHQgPSBjbGlwcy0+eDI7Cj4gKwl0 b3AgPSBjbGlwcy0+eTE7Cj4gKwlib3R0b20gPSBjbGlwcy0+eTI7Cj4gKwo+ICsJLyogc2tpcCB0 aGUgZmlyc3QgY2xpcCByZWN0ICovCj4gKwlmb3IgKGkgPSAxLCBjbGlwc19wdHIgPSBjbGlwcyAr IGluYzsKPiArCSAgICAgaSA8IG51bV9jbGlwczsgaSsrLCBjbGlwc19wdHIgKz0gaW5jKSB7Cj4g KwkJbGVmdCA9IG1pbl90KGludCwgbGVmdCwgKGludCljbGlwc19wdHItPngxKTsKPiArCQlyaWdo dCA9IG1heF90KGludCwgcmlnaHQsIChpbnQpY2xpcHNfcHRyLT54Mik7Cj4gKwkJdG9wID0gbWlu X3QoaW50LCB0b3AsIChpbnQpY2xpcHNfcHRyLT55MSk7Cj4gKwkJYm90dG9tID0gbWF4X3QoaW50 LCBib3R0b20sIChpbnQpY2xpcHNfcHRyLT55Mik7Cj4gKwl9Cj4gKwo+ICsJaWYgKG9iai0+ZHVt YikKPiArCQlyZXR1cm4gdmlydGlvX2dwdV9kaXJ0eV91cGRhdGUodmdmYiwgZmFsc2UsIGxlZnQs IHRvcCwKPiArCQkJCQkgICAgICAgcmlnaHQgLSBsZWZ0LCBib3R0b20gLSB0b3ApOwo+ICsKPiAr CXZpcnRpb19ncHVfY21kX3Jlc291cmNlX2ZsdXNoKHZnZGV2LCBvYmotPmh3X3Jlc19oYW5kbGUs Cj4gKwkJCQkgICAgICBsZWZ0LCB0b3AsIHJpZ2h0IC0gbGVmdCwgYm90dG9tIC0gdG9wKTsKPiAr CXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X2ZiX2RpcnR5X3dv cmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ICt7Cj4gKwlzdHJ1Y3QgZGVsYXllZF93b3Jr ICpkZWxheWVkX3dvcmsgPSB0b19kZWxheWVkX3dvcmsod29yayk7Cj4gKwlzdHJ1Y3QgdmlydGlv X2dwdV9mYmRldiAqdmZiZGV2ID0KPiArCQljb250YWluZXJfb2YoZGVsYXllZF93b3JrLCBzdHJ1 Y3QgdmlydGlvX2dwdV9mYmRldiwgd29yayk7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9mcmFtZWJ1 ZmZlciAqdmdmYiA9ICZ2ZmJkZXYtPnZnZmI7Cj4gKwo+ICsJdmlydGlvX2dwdV9kaXJ0eV91cGRh dGUoJnZmYmRldi0+dmdmYiwgZmFsc2UsIHZnZmItPngxLCB2Z2ZiLT55MSwKPiArCQkJCXZnZmIt PngyIC0gdmdmYi0+eDEsIHZnZmItPnkyIC0gdmdmYi0+eTEpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dm9pZCB2aXJ0aW9fZ3B1XzNkX2ZpbGxyZWN0KHN0cnVjdCBmYl9pbmZvICppbmZvLAo+ICsJCQkJ ICAgY29uc3Qgc3RydWN0IGZiX2ZpbGxyZWN0ICpyZWN0KQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlv X2dwdV9mYmRldiAqdmZiZGV2ID0gaW5mby0+cGFyOwo+ICsJc3lzX2ZpbGxyZWN0KGluZm8sIHJl Y3QpOwo+ICsJdmlydGlvX2dwdV9kaXJ0eV91cGRhdGUoJnZmYmRldi0+dmdmYiwgdHJ1ZSwgcmVj dC0+ZHgsIHJlY3QtPmR5LAo+ICsJCQkgICAgIHJlY3QtPndpZHRoLCByZWN0LT5oZWlnaHQpOwo+ ICsJc2NoZWR1bGVfZGVsYXllZF93b3JrKCZ2ZmJkZXYtPndvcmssIFZJUlRJT19HUFVfRkJDT05f UE9MTF9QRVJJT0QpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1XzNkX2NvcHlh cmVhKHN0cnVjdCBmYl9pbmZvICppbmZvLAo+ICsJCQkJICAgY29uc3Qgc3RydWN0IGZiX2NvcHlh cmVhICphcmVhKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9mYmRldiAqdmZiZGV2ID0gaW5m by0+cGFyOwo+ICsJc3lzX2NvcHlhcmVhKGluZm8sIGFyZWEpOwo+ICsJdmlydGlvX2dwdV9kaXJ0 eV91cGRhdGUoJnZmYmRldi0+dmdmYiwgdHJ1ZSwgYXJlYS0+ZHgsIGFyZWEtPmR5LAo+ICsJCQkg ICBhcmVhLT53aWR0aCwgYXJlYS0+aGVpZ2h0KTsKPiArCXNjaGVkdWxlX2RlbGF5ZWRfd29yaygm dmZiZGV2LT53b3JrLCBWSVJUSU9fR1BVX0ZCQ09OX1BPTExfUEVSSU9EKTsKPiArfQo+ICsKPiAr c3RhdGljIHZvaWQgdmlydGlvX2dwdV8zZF9pbWFnZWJsaXQoc3RydWN0IGZiX2luZm8gKmluZm8s Cj4gKwkJCQkgICAgY29uc3Qgc3RydWN0IGZiX2ltYWdlICppbWFnZSkKPiArewo+ICsJc3RydWN0 IHZpcnRpb19ncHVfZmJkZXYgKnZmYmRldiA9IGluZm8tPnBhcjsKPiArCXN5c19pbWFnZWJsaXQo aW5mbywgaW1hZ2UpOwo+ICsJdmlydGlvX2dwdV9kaXJ0eV91cGRhdGUoJnZmYmRldi0+dmdmYiwg dHJ1ZSwgaW1hZ2UtPmR4LCBpbWFnZS0+ZHksCj4gKwkJCSAgICAgaW1hZ2UtPndpZHRoLCBpbWFn ZS0+aGVpZ2h0KTsKPiArCXNjaGVkdWxlX2RlbGF5ZWRfd29yaygmdmZiZGV2LT53b3JrLCBWSVJU SU9fR1BVX0ZCQ09OX1BPTExfUEVSSU9EKTsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBmYl9v cHMgdmlydGlvX2dwdWZiX29wcyA9IHsKPiArCS5vd25lciA9IFRISVNfTU9EVUxFLAo+ICsJLmZi X2NoZWNrX3ZhciA9IGRybV9mYl9oZWxwZXJfY2hlY2tfdmFyLAo+ICsJLmZiX3NldF9wYXIgPSBk cm1fZmJfaGVscGVyX3NldF9wYXIsIC8qIFRPRE86IGNvcHkgdm13Z2Z4ICovCj4gKwkuZmJfZmls bHJlY3QgPSB2aXJ0aW9fZ3B1XzNkX2ZpbGxyZWN0LAo+ICsJLmZiX2NvcHlhcmVhID0gdmlydGlv X2dwdV8zZF9jb3B5YXJlYSwKPiArCS5mYl9pbWFnZWJsaXQgPSB2aXJ0aW9fZ3B1XzNkX2ltYWdl YmxpdCwKPiArCS5mYl9wYW5fZGlzcGxheSA9IGRybV9mYl9oZWxwZXJfcGFuX2Rpc3BsYXksCj4g KwkuZmJfYmxhbmsgPSBkcm1fZmJfaGVscGVyX2JsYW5rLAo+ICsJLmZiX3NldGNtYXAgPSBkcm1f ZmJfaGVscGVyX3NldGNtYXAsCj4gKwkuZmJfZGVidWdfZW50ZXIgPSBkcm1fZmJfaGVscGVyX2Rl YnVnX2VudGVyLAo+ICsJLmZiX2RlYnVnX2xlYXZlID0gZHJtX2ZiX2hlbHBlcl9kZWJ1Z19sZWF2 ZSwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgdmlydGlvX2dwdV92bWFwX2ZiKHN0cnVjdCB2aXJ0 aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCSAgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVj dCAqb2JqKQo+ICt7Cj4gKwlyZXR1cm4gdmlydGlvX2dwdV9vYmplY3Rfa21hcChvYmosIE5VTEwp Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHZpcnRpb19ncHVmYl9jcmVhdGUoc3RydWN0IGRybV9m Yl9oZWxwZXIgKmhlbHBlciwKPiArCQkJICAgICAgIHN0cnVjdCBkcm1fZmJfaGVscGVyX3N1cmZh Y2Vfc2l6ZSAqc2l6ZXMpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZiZGV2ICp2ZmJkZXYg PQo+ICsJCWNvbnRhaW5lcl9vZihoZWxwZXIsIHN0cnVjdCB2aXJ0aW9fZ3B1X2ZiZGV2LCBoZWxw ZXIpOwo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IGhlbHBlci0+ZGV2Owo+ICsJc3RydWN0 IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiA9IGRldi0+ZGV2X3ByaXZhdGU7Cj4gKwlzdHJ1Y3Qg ZmJfaW5mbyAqaW5mbzsKPiArCXN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiOwo+ICsJc3RydWN0 IGRybV9tb2RlX2ZiX2NtZDIgbW9kZV9jbWQgPSB7fTsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X29i amVjdCAqb2JqOwo+ICsJc3RydWN0IGRldmljZSAqZGV2aWNlID0gdmdkZXYtPmRldjsKPiArCXVp bnQzMl90IHJlc2lkLCBmb3JtYXQsIHNpemU7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCW1vZGVfY21k LndpZHRoID0gc2l6ZXMtPnN1cmZhY2Vfd2lkdGg7Cj4gKwltb2RlX2NtZC5oZWlnaHQgPSBzaXpl cy0+c3VyZmFjZV9oZWlnaHQ7Cj4gKwltb2RlX2NtZC5waXRjaGVzWzBdID0gbW9kZV9jbWQud2lk dGggKiA0Owo+ICsJbW9kZV9jbWQucGl4ZWxfZm9ybWF0ID0gZHJtX21vZGVfbGVnYWN5X2ZiX2Zv cm1hdCgzMiwgMjQpOwo+ICsKPiArCXN3aXRjaCAobW9kZV9jbWQucGl4ZWxfZm9ybWF0KSB7Cj4g KyNpZmRlZiBfX0JJR19FTkRJQU4KPiArCWNhc2UgRFJNX0ZPUk1BVF9YUkdCODg4ODoKPiArCQlm b3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9YOFI4RzhCOF9VTk9STTsKPiArCQlicmVhazsKPiAr CWNhc2UgRFJNX0ZPUk1BVF9BUkdCODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1B VF9BOFI4RzhCOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9CR1JYODg4 ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9COEc4UjhYOF9VTk9STTsKPiArCQli cmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9CR1JBODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9f R1BVX0ZPUk1BVF9COEc4UjhBOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1B VF9SR0JYODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9SOEc4QjhYOF9VTk9S TTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9SR0JBODg4ODoKPiArCQlmb3JtYXQg PSBWSVJUSU9fR1BVX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2Ug RFJNX0ZPUk1BVF9YQkdSODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9YOEI4 RzhSOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9BQkdSODg4ODoKPiAr CQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9BOEI4RzhSOF9VTk9STTsKPiArCQlicmVhazsK PiArI2Vsc2UKPiArCWNhc2UgRFJNX0ZPUk1BVF9YUkdCODg4ODoKPiArCQlmb3JtYXQgPSBWSVJU SU9fR1BVX0ZPUk1BVF9COEc4UjhYOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZP Uk1BVF9BUkdCODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9COEc4UjhBOF9V Tk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9CR1JYODg4ODoKPiArCQlmb3Jt YXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9YOFI4RzhCOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNh c2UgRFJNX0ZPUk1BVF9CR1JBODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9B OFI4RzhCOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9SR0JYODg4ODoK PiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9YOEI4RzhSOF9VTk9STTsKPiArCQlicmVh azsKPiArCWNhc2UgRFJNX0ZPUk1BVF9SR0JBODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BV X0ZPUk1BVF9BOEI4RzhSOF9VTk9STTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9Y QkdSODg4ODoKPiArCQlmb3JtYXQgPSBWSVJUSU9fR1BVX0ZPUk1BVF9SOEc4QjhYOF9VTk9STTsK PiArCQlicmVhazsKPiArCWNhc2UgRFJNX0ZPUk1BVF9BQkdSODg4ODoKPiArCQlmb3JtYXQgPSBW SVJUSU9fR1BVX0ZPUk1BVF9SOEc4QjhBOF9VTk9STTsKPiArCQlicmVhazsKPiArI2VuZGlmCj4g KwlkZWZhdWx0Ogo+ICsJCURSTV9FUlJPUigiZmFpbGVkIHRvIGZpbmQgdmlydGlvIGdwdSBmb3Jt YXQgZm9yICVkXG4iLAo+ICsJCQkgIG1vZGVfY21kLnBpeGVsX2Zvcm1hdCk7Cj4gKwkJcmV0dXJu IC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJc2l6ZSA9IG1vZGVfY21kLnBpdGNoZXNbMF0gKiBtb2Rl X2NtZC5oZWlnaHQ7Cj4gKwlvYmogPSB2aXJ0aW9fZ3B1X2FsbG9jX29iamVjdChkZXYsIHNpemUs IGZhbHNlLCB0cnVlKTsKPiArCWlmICghb2JqKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiAr CXZpcnRpb19ncHVfcmVzb3VyY2VfaWRfZ2V0KHZnZGV2LCAmcmVzaWQpOwo+ICsJdmlydGlvX2dw dV9jbWRfY3JlYXRlX3Jlc291cmNlKHZnZGV2LCByZXNpZCwgZm9ybWF0LAo+ICsJCQkJICAgICAg IG1vZGVfY21kLndpZHRoLCBtb2RlX2NtZC5oZWlnaHQpOwo+ICsKPiArCXJldCA9IHZpcnRpb19n cHVfdm1hcF9mYih2Z2Rldiwgb2JqKTsKPiArCWlmIChyZXQpIHsKPiArCQlEUk1fRVJST1IoImZh aWxlZCB0byB2bWFwIGZiICVkXG4iLCByZXQpOwo+ICsJCWdvdG8gZXJyX29ial92bWFwOwo+ICsJ fQo+ICsKPiArCS8qIGF0dGFjaCB0aGUgb2JqZWN0IHRvIHRoZSByZXNvdXJjZSAqLwo+ICsJcmV0 ID0gdmlydGlvX2dwdV9vYmplY3RfYXR0YWNoKHZnZGV2LCBvYmosIHJlc2lkLCBOVUxMKTsKPiAr CWlmIChyZXQpCj4gKwkJZ290byBlcnJfb2JqX2F0dGFjaDsKPiArCj4gKwlpbmZvID0gZnJhbWVi dWZmZXJfYWxsb2MoMCwgZGV2aWNlKTsKPiArCWlmICghaW5mbykgewo+ICsJCXJldCA9IC1FTk9N RU07Cj4gKwkJZ290byBlcnJfZmJfYWxsb2M7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gZmJfYWxsb2Nf Y21hcCgmaW5mby0+Y21hcCwgMjU2LCAwKTsKPiArCWlmIChyZXQpIHsKPiArCQlyZXQgPSAtRU5P TUVNOwo+ICsJCWdvdG8gZXJyX2ZiX2FsbG9jX2NtYXA7Cj4gKwl9Cj4gKwo+ICsJaW5mby0+cGFy ID0gaGVscGVyOwo+ICsKPiArCXJldCA9IHZpcnRpb19ncHVfZnJhbWVidWZmZXJfaW5pdChkZXYs ICZ2ZmJkZXYtPnZnZmIsCj4gKwkJCQkJICAmbW9kZV9jbWQsICZvYmotPmdlbV9iYXNlKTsKPiAr CWlmIChyZXQpCj4gKwkJZ290byBlcnJfZmJfaW5pdDsKPiArCj4gKwlmYiA9ICZ2ZmJkZXYtPnZn ZmIuYmFzZTsKPiArCj4gKwl2ZmJkZXYtPmhlbHBlci5mYiA9IGZiOwo+ICsJdmZiZGV2LT5oZWxw ZXIuZmJkZXYgPSBpbmZvOwo+ICsKPiArCXN0cmNweShpbmZvLT5maXguaWQsICJ2aXJ0aW9kcm1m YiIpOwo+ICsJaW5mby0+ZmxhZ3MgPSBGQklORk9fREVGQVVMVDsKPiArCWluZm8tPmZib3BzID0g JnZpcnRpb19ncHVmYl9vcHM7Cj4gKwlpbmZvLT5waXhtYXAuZmxhZ3MgPSBGQl9QSVhNQVBfU1lT VEVNOwo+ICsKPiArCWluZm8tPnNjcmVlbl9iYXNlID0gb2JqLT52bWFwOwo+ICsJaW5mby0+c2Ny ZWVuX3NpemUgPSBvYmotPmdlbV9iYXNlLnNpemU7Cj4gKwlkcm1fZmJfaGVscGVyX2ZpbGxfZml4 KGluZm8sIGZiLT5waXRjaGVzWzBdLCBmYi0+ZGVwdGgpOwo+ICsJZHJtX2ZiX2hlbHBlcl9maWxs X3ZhcihpbmZvLCAmdmZiZGV2LT5oZWxwZXIsCj4gKwkJCSAgICAgICBzaXplcy0+ZmJfd2lkdGgs IHNpemVzLT5mYl9oZWlnaHQpOwo+ICsKPiArCWluZm8tPmZpeC5tbWlvX3N0YXJ0ID0gMDsKPiAr CWluZm8tPmZpeC5tbWlvX2xlbiA9IDA7Cj4gKwlyZXR1cm4gMDsKPiArCj4gK2Vycl9mYl9pbml0 Ogo+ICsJZmJfZGVhbGxvY19jbWFwKCZpbmZvLT5jbWFwKTsKPiArZXJyX2ZiX2FsbG9jX2NtYXA6 Cj4gKwlmcmFtZWJ1ZmZlcl9yZWxlYXNlKGluZm8pOwo+ICtlcnJfZmJfYWxsb2M6Cj4gKwl2aXJ0 aW9fZ3B1X2NtZF9yZXNvdXJjZV9pbnZhbF9iYWNraW5nKHZnZGV2LCByZXNpZCk7Cj4gK2Vycl9v YmpfYXR0YWNoOgo+ICtlcnJfb2JqX3ZtYXA6Cj4gKwl2aXJ0aW9fZ3B1X2dlbV9mcmVlX29iamVj dCgmb2JqLT5nZW1fYmFzZSk7Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50 IHZpcnRpb19ncHVfZmJkZXZfZGVzdHJveShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJCQkJ ICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X2ZiZGV2ICp2Z2ZiZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgZmJf aW5mbyAqaW5mbzsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZyYW1lYnVmZmVyICp2Z2ZiID0gJnZn ZmJkZXYtPnZnZmI7Cj4gKwo+ICsJaWYgKHZnZmJkZXYtPmhlbHBlci5mYmRldikgewo+ICsJCWlu Zm8gPSB2Z2ZiZGV2LT5oZWxwZXIuZmJkZXY7Cj4gKwo+ICsJCXVucmVnaXN0ZXJfZnJhbWVidWZm ZXIoaW5mbyk7Cj4gKwkJZnJhbWVidWZmZXJfcmVsZWFzZShpbmZvKTsKPiArCX0KPiArCWlmICh2 Z2ZiLT5vYmopCj4gKwkJdmdmYi0+b2JqID0gTlVMTDsKPiArCWRybV9mYl9oZWxwZXJfZmluaSgm dmdmYmRldi0+aGVscGVyKTsKPiArCWRybV9mcmFtZWJ1ZmZlcl9jbGVhbnVwKCZ2Z2ZiLT5iYXNl KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICtzdGF0aWMgc3RydWN0IGRybV9mYl9oZWxwZXJf ZnVuY3MgdmlydGlvX2dwdV9mYl9oZWxwZXJfZnVuY3MgPSB7Cj4gKwkuZmJfcHJvYmUgPSB2aXJ0 aW9fZ3B1ZmJfY3JlYXRlLAo+ICt9Owo+ICsKPiAraW50IHZpcnRpb19ncHVfZmJkZXZfaW5pdChz dHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dw dV9mYmRldiAqdmdmYmRldjsKPiArCWludCBicHBfc2VsID0gMzI7IC8qIFRPRE86IHBhcmFtZXRl ciBmcm9tIHNvbWV3aGVyZT8gKi8KPiArCWludCByZXQ7Cj4gKwo+ICsJdmdmYmRldiA9IGt6YWxs b2Moc2l6ZW9mKHN0cnVjdCB2aXJ0aW9fZ3B1X2ZiZGV2KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAo IXZnZmJkZXYpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJdmdmYmRldi0+dmdkZXYgPSB2 Z2RldjsKPiArCXZnZGV2LT52Z2ZiZGV2ID0gdmdmYmRldjsKPiArCUlOSVRfREVMQVlFRF9XT1JL KCZ2Z2ZiZGV2LT53b3JrLCB2aXJ0aW9fZ3B1X2ZiX2RpcnR5X3dvcmspOwo+ICsKPiArCWRybV9m Yl9oZWxwZXJfcHJlcGFyZSh2Z2Rldi0+ZGRldiwgJnZnZmJkZXYtPmhlbHBlciwKPiArCQkJICAg ICAgJnZpcnRpb19ncHVfZmJfaGVscGVyX2Z1bmNzKTsKPiArCXJldCA9IGRybV9mYl9oZWxwZXJf aW5pdCh2Z2Rldi0+ZGRldiwgJnZnZmJkZXYtPmhlbHBlciwKPiArCQkJCSB2Z2Rldi0+bnVtX3Nj YW5vdXRzLAo+ICsJCQkJIFZJUlRJT19HUFVGQl9DT05OX0xJTUlUKTsKPiArCWlmIChyZXQpIHsK PiArCQlrZnJlZSh2Z2ZiZGV2KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsKPiArCWRybV9m Yl9oZWxwZXJfc2luZ2xlX2FkZF9hbGxfY29ubmVjdG9ycygmdmdmYmRldi0+aGVscGVyKTsKPiAr CWRybV9mYl9oZWxwZXJfaW5pdGlhbF9jb25maWcoJnZnZmJkZXYtPmhlbHBlciwgYnBwX3NlbCk7 Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9fZ3B1X2ZiZGV2X2Zpbmkoc3Ry dWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldikKPiArewo+ICsJaWYgKCF2Z2Rldi0+dmdmYmRl dikKPiArCQlyZXR1cm47Cj4gKwo+ICsJdmlydGlvX2dwdV9mYmRldl9kZXN0cm95KHZnZGV2LT5k ZGV2LCB2Z2Rldi0+dmdmYmRldik7Cj4gKwlrZnJlZSh2Z2Rldi0+dmdmYmRldik7Cj4gKwl2Z2Rl di0+dmdmYmRldiA9IE5VTEw7Cj4gK30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3Zp cnRpby92aXJ0Z3B1X2ZlbmNlLmMgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZmVu Y2UuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uMWRhNjMyNgo+IC0t LSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZmVuY2Uu Ywo+IEBAIC0wLDAgKzEsMTE5IEBACj4gKy8qCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNSBSZWQg SGF0LCBJbmMuCj4gKyAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCj4gKyAqCj4gKyAqIFBlcm1pc3Np b24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFp bmluZwo+ICsgKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVu dGF0aW9uIGZpbGVzICh0aGUKPiArICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3 YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwo+ICsgKiB3aXRob3V0IGxpbWl0YXRp b24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCj4gKyAq IGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdh cmUsIGFuZCB0bwo+ICsgKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBm dXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KPiArICogdGhlIGZvbGxvd2luZyBjb25kaXRp b25zOgo+ICsgKgo+ICsgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJt aXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZQo+ICsgKiBuZXh0IHBhcmFncmFwaCkgc2hhbGwg YmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbAo+ICsgKiBwb3J0aW9ucyBv ZiB0aGUgU29mdHdhcmUuCj4gKyAqCj4gKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMg SVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAo+ICsgKiBFWFBSRVNTIE9SIElNUExJ RUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKPiArICog TUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9O SU5GUklOR0VNRU5ULgo+ICsgKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIE9XTkVS KFMpIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFCj4gKyAqIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBE QU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KPiArICogT0Yg Q09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBD T05ORUNUSU9OCj4gKyAqIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVB TElOR1MgSU4gVEhFIFNPRlRXQVJFLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxkcm0vZHJtUC5o Pgo+ICsjaW5jbHVkZSAidmlydGdwdV9kcnYuaCIKPiArCj4gK3N0YXRpYyBjb25zdCBjaGFyICp2 aXJ0aW9fZ2V0X2RyaXZlcl9uYW1lKHN0cnVjdCBmZW5jZSAqZikKPiArewo+ICsJcmV0dXJuICJ2 aXJ0aW9fZ3B1IjsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IGNoYXIgKnZpcnRpb19nZXRfdGlt ZWxpbmVfbmFtZShzdHJ1Y3QgZmVuY2UgKmYpCj4gK3sKPiArCXJldHVybiAiY29udHJvbHEiOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCB2aXJ0aW9fZW5hYmxlX3NpZ25hbGluZyhzdHJ1Y3QgZmVu Y2UgKmYpCj4gK3sKPiArCXJldHVybiB0cnVlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCB2aXJ0 aW9fc2lnbmFsZWQoc3RydWN0IGZlbmNlICpmKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9m ZW5jZSAqZmVuY2UgPSB0b192aXJ0aW9fZmVuY2UoZik7Cj4gKwo+ICsJaWYgKGF0b21pYzY0X3Jl YWQoJmZlbmNlLT5kcnYtPmxhc3Rfc2VxKSA+PSBmZW5jZS0+c2VxKQo+ICsJCXJldHVybiB0cnVl Owo+ICsJcmV0dXJuIGZhbHNlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZmVuY2Vf dmFsdWVfc3RyKHN0cnVjdCBmZW5jZSAqZiwgY2hhciAqc3RyLCBpbnQgc2l6ZSkKPiArewo+ICsJ c3RydWN0IHZpcnRpb19ncHVfZmVuY2UgKmZlbmNlID0gdG9fdmlydGlvX2ZlbmNlKGYpOwo+ICsK PiArCXNucHJpbnRmKHN0ciwgc2l6ZSwgIiVsbHUiLCBmZW5jZS0+c2VxKTsKPiArfQo+ICsKPiAr c3RhdGljIHZvaWQgdmlydGlvX3RpbWVsaW5lX3ZhbHVlX3N0cihzdHJ1Y3QgZmVuY2UgKmYsIGNo YXIgKnN0ciwgaW50IHNpemUpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZlbmNlICpmZW5j ZSA9IHRvX3ZpcnRpb19mZW5jZShmKTsKPiArCj4gKwlzbnByaW50ZihzdHIsIHNpemUsICIlbHUi LCBhdG9taWM2NF9yZWFkKCZmZW5jZS0+ZHJ2LT5sYXN0X3NlcSkpOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgY29uc3Qgc3RydWN0IGZlbmNlX29wcyB2aXJ0aW9fZmVuY2Vfb3BzID0gewo+ICsJLmdldF9k cml2ZXJfbmFtZSAgICAgPSB2aXJ0aW9fZ2V0X2RyaXZlcl9uYW1lLAo+ICsJLmdldF90aW1lbGlu ZV9uYW1lICAgPSB2aXJ0aW9fZ2V0X3RpbWVsaW5lX25hbWUsCj4gKwkuZW5hYmxlX3NpZ25hbGlu ZyAgICA9IHZpcnRpb19lbmFibGVfc2lnbmFsaW5nLAo+ICsJLnNpZ25hbGVkICAgICAgICAgICAg PSB2aXJ0aW9fc2lnbmFsZWQsCj4gKwkud2FpdCAgICAgICAgICAgICAgICA9IGZlbmNlX2RlZmF1 bHRfd2FpdCwKPiArCS5mZW5jZV92YWx1ZV9zdHIgICAgID0gdmlydGlvX2ZlbmNlX3ZhbHVlX3N0 ciwKPiArCS50aW1lbGluZV92YWx1ZV9zdHIgID0gdmlydGlvX3RpbWVsaW5lX3ZhbHVlX3N0ciwK PiArfTsKPiArCj4gK2ludCB2aXJ0aW9fZ3B1X2ZlbmNlX2VtaXQoc3RydWN0IHZpcnRpb19ncHVf ZGV2aWNlICp2Z2RldiwKPiArCQkJICBzdHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hkciAqY21kX2hk ciwKPiArCQkJICBzdHJ1Y3QgdmlydGlvX2dwdV9mZW5jZSAqKmZlbmNlKQo+ICt7Cj4gKwlzdHJ1 Y3QgdmlydGlvX2dwdV9mZW5jZV9kcml2ZXIgKmRydiA9ICZ2Z2Rldi0+ZmVuY2VfZHJ2Owo+ICsJ dW5zaWduZWQgbG9uZyBpcnFfZmxhZ3M7Cj4gKwo+ICsJKmZlbmNlID0ga21hbGxvYyhzaXplb2Yo c3RydWN0IHZpcnRpb19ncHVfZmVuY2UpLCBHRlBfS0VSTkVMKTsKPiArCWlmICgoKmZlbmNlKSA9 PSBOVUxMKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXNwaW5fbG9ja19pcnFzYXZlKCZk cnYtPmxvY2ssIGlycV9mbGFncyk7Cj4gKwkoKmZlbmNlKS0+ZHJ2ID0gZHJ2Owo+ICsJKCpmZW5j ZSktPnNlcSA9ICsrZHJ2LT5zeW5jX3NlcTsKPiArCWZlbmNlX2luaXQoJigqZmVuY2UpLT5mLCAm dmlydGlvX2ZlbmNlX29wcywgJmRydi0+bG9jaywKPiArCQkgICAwLCAoKmZlbmNlKS0+c2VxKTsK PiArCWZlbmNlX2dldCgmKCpmZW5jZSktPmYpOwo+ICsJbGlzdF9hZGRfdGFpbCgmKCpmZW5jZSkt Pm5vZGUsICZkcnYtPmZlbmNlcyk7Cj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkcnYtPmxv Y2ssIGlycV9mbGFncyk7Cj4gKwo+ICsJY21kX2hkci0+ZmxhZ3MgfD0gY3B1X3RvX2xlMzIoVklS VElPX0dQVV9GTEFHX0ZFTkNFKTsKPiArCWNtZF9oZHItPmZlbmNlX2lkID0gY3B1X3RvX2xlNjQo KCpmZW5jZSktPnNlcSk7Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9fZ3B1 X2ZlbmNlX2V2ZW50X3Byb2Nlc3Moc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiAr CQkJCSAgICB1NjQgbGFzdF9zZXEpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2ZlbmNlX2Ry aXZlciAqZHJ2ID0gJnZnZGV2LT5mZW5jZV9kcnY7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9mZW5j ZSAqZmVuY2UsICp0bXA7Cj4gKwl1bnNpZ25lZCBsb25nIGlycV9mbGFnczsKPiArCj4gKwlzcGlu X2xvY2tfaXJxc2F2ZSgmZHJ2LT5sb2NrLCBpcnFfZmxhZ3MpOwo+ICsJYXRvbWljNjRfc2V0KCZ2 Z2Rldi0+ZmVuY2VfZHJ2Lmxhc3Rfc2VxLCBsYXN0X3NlcSk7Cj4gKwlsaXN0X2Zvcl9lYWNoX2Vu dHJ5X3NhZmUoZmVuY2UsIHRtcCwgJmRydi0+ZmVuY2VzLCBub2RlKSB7Cj4gKwkJaWYgKGxhc3Rf c2VxIDwgZmVuY2UtPnNlcSkKPiArCQkJY29udGludWU7Cj4gKwkJZmVuY2Vfc2lnbmFsX2xvY2tl ZCgmZmVuY2UtPmYpOwo+ICsJCWxpc3RfZGVsKCZmZW5jZS0+bm9kZSk7Cj4gKwkJZmVuY2VfcHV0 KCZmZW5jZS0+Zik7Cj4gKwl9Cj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkcnYtPmxvY2ss IGlycV9mbGFncyk7Cj4gK30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92 aXJ0Z3B1X2dlbS5jIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2dlbS5jCj4gbmV3 IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi5jZmEwZDI3Cj4gLS0tIC9kZXYvbnVs bAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9nZW0uYwo+IEBAIC0wLDAg KzEsMTQwIEBACj4gKy8qCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNSBSZWQgSGF0LCBJbmMuCj4g KyAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCj4gKyAqCj4gKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5 IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwo+ICsgKiBh IGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVz ICh0aGUKPiArICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQg cmVzdHJpY3Rpb24sIGluY2x1ZGluZwo+ICsgKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0 cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCj4gKyAqIGRpc3RyaWJ1dGUs IHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwo+ ICsgKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8g ZG8gc28sIHN1YmplY3QgdG8KPiArICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgo+ICsgKgo+ ICsgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGlj ZSAoaW5jbHVkaW5nIHRoZQo+ICsgKiBuZXh0IHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQg aW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbAo+ICsgKiBwb3J0aW9ucyBvZiB0aGUgU29mdHdh cmUuCj4gKyAqCj4gKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VU IFdBUlJBTlRZIE9GIEFOWSBLSU5ELAo+ICsgKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElO RyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKPiArICogTUVSQ0hBTlRBQklM SVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5U Lgo+ICsgKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIE9XTkVSKFMpIEFORC9PUiBJ VFMgU1VQUExJRVJTIEJFCj4gKyAqIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9U SEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04KPiArICogT0YgQ09OVFJBQ1QsIFRP UlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OCj4g KyAqIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhF IFNPRlRXQVJFLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgo+ICsjaW5jbHVk ZSAidmlydGdwdV9kcnYuaCIKPiArCj4gK3ZvaWQgdmlydGlvX2dwdV9nZW1fZnJlZV9vYmplY3Qo c3RydWN0IGRybV9nZW1fb2JqZWN0ICpnZW1fb2JqKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dw dV9vYmplY3QgKm9iaiA9IGdlbV90b192aXJ0aW9fZ3B1X29iaihnZW1fb2JqKTsKPiArCj4gKwlp ZiAob2JqKQo+ICsJCXZpcnRpb19ncHVfb2JqZWN0X3VucmVmKCZvYmopOwo+ICt9Cj4gKwo+ICtz dHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKnZpcnRpb19ncHVfYWxsb2Nfb2JqZWN0KHN0cnVjdCBk cm1fZGV2aWNlICpkZXYsCj4gKwkJCQkJCSAgc2l6ZV90IHNpemUsIGJvb2wga2VybmVsLAo+ICsJ CQkJCQkgIGJvb2wgcGlubmVkKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZn ZGV2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqb2Jq Owo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSB2aXJ0aW9fZ3B1X29iamVjdF9jcmVhdGUodmdk ZXYsIHNpemUsIGtlcm5lbCwgcGlubmVkLCAmb2JqKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJu IEVSUl9QVFIocmV0KTsKPiArCj4gKwlyZXR1cm4gb2JqOwo+ICt9Cj4gKwo+ICtpbnQgdmlydGlv X2dwdV9nZW1fY3JlYXRlKHN0cnVjdCBkcm1fZmlsZSAqZmlsZSwKPiArCQkJICBzdHJ1Y3QgZHJt X2RldmljZSAqZGV2LAo+ICsJCQkgIHVpbnQ2NF90IHNpemUsCj4gKwkJCSAgc3RydWN0IGRybV9n ZW1fb2JqZWN0ICoqb2JqX3AsCj4gKwkJCSAgdWludDMyX3QgKmhhbmRsZV9wKQo+ICt7Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKm9iajsKPiArCWludCByZXQ7Cj4gKwl1MzIgaGFuZGxl Owo+ICsKPiArCW9iaiA9IHZpcnRpb19ncHVfYWxsb2Nfb2JqZWN0KGRldiwgc2l6ZSwgZmFsc2Us IGZhbHNlKTsKPiArCWlmIChJU19FUlIob2JqKSkKPiArCQlyZXR1cm4gUFRSX0VSUihvYmopOwo+ ICsKPiArCXJldCA9IGRybV9nZW1faGFuZGxlX2NyZWF0ZShmaWxlLCAmb2JqLT5nZW1fYmFzZSwg JmhhbmRsZSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZHJtX2dlbV9vYmplY3RfcmVsZWFzZSgmb2Jq LT5nZW1fYmFzZSk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwkqb2JqX3AgPSAmb2Jq LT5nZW1fYmFzZTsKPiArCj4gKwkvKiBkcm9wIHJlZmVyZW5jZSBmcm9tIGFsbG9jYXRlIC0gaGFu ZGxlIGhvbGRzIGl0IG5vdyAqLwo+ICsJZHJtX2dlbV9vYmplY3RfdW5yZWZlcmVuY2VfdW5sb2Nr ZWQoJm9iai0+Z2VtX2Jhc2UpOwo+ICsKPiArCSpoYW5kbGVfcCA9IGhhbmRsZTsKPiArCXJldHVy biAwOwo+ICt9Cj4gKwo+ICtpbnQgdmlydGlvX2dwdV9tb2RlX2R1bWJfY3JlYXRlKHN0cnVjdCBk cm1fZmlsZSAqZmlsZV9wcml2LAo+ICsJCQkJc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPiArCQkJ CXN0cnVjdCBkcm1fbW9kZV9jcmVhdGVfZHVtYiAqYXJncykKPiArewo+ICsJc3RydWN0IHZpcnRp b19ncHVfZGV2aWNlICp2Z2RldiA9IGRldi0+ZGV2X3ByaXZhdGU7Cj4gKwlzdHJ1Y3QgZHJtX2dl bV9vYmplY3QgKmdvYmo7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKm9iajsKPiArCWlu dCByZXQ7Cj4gKwl1aW50MzJfdCBwaXRjaDsKPiArCXVpbnQzMl90IHJlc2lkOwo+ICsKPiArCXBp dGNoID0gYXJncy0+d2lkdGggKiAoKGFyZ3MtPmJwcCArIDEpIC8gOCk7Cj4gKwlhcmdzLT5zaXpl ID0gcGl0Y2ggKiBhcmdzLT5oZWlnaHQ7Cj4gKwlhcmdzLT5zaXplID0gQUxJR04oYXJncy0+c2l6 ZSwgUEFHRV9TSVpFKTsKPiArCj4gKwlyZXQgPSB2aXJ0aW9fZ3B1X2dlbV9jcmVhdGUoZmlsZV9w cml2LCBkZXYsIGFyZ3MtPnNpemUsICZnb2JqLAo+ICsJCQkJICAgICZhcmdzLT5oYW5kbGUpOwo+ ICsJaWYgKHJldCkKPiArCQlnb3RvIGZhaWw7Cj4gKwo+ICsJdmlydGlvX2dwdV9yZXNvdXJjZV9p ZF9nZXQodmdkZXYsICZyZXNpZCk7Cj4gKwl2aXJ0aW9fZ3B1X2NtZF9jcmVhdGVfcmVzb3VyY2Uo dmdkZXYsIHJlc2lkLAo+ICsJCQkJICAgICAgIDIsIGFyZ3MtPndpZHRoLCBhcmdzLT5oZWlnaHQp Owo+ICsKPiArCS8qIGF0dGFjaCB0aGUgb2JqZWN0IHRvIHRoZSByZXNvdXJjZSAqLwo+ICsJb2Jq ID0gZ2VtX3RvX3ZpcnRpb19ncHVfb2JqKGdvYmopOwo+ICsJcmV0ID0gdmlydGlvX2dwdV9vYmpl Y3RfYXR0YWNoKHZnZGV2LCBvYmosIHJlc2lkLCBOVUxMKTsKPiArCWlmIChyZXQpCj4gKwkJZ290 byBmYWlsOwo+ICsKPiArCW9iai0+ZHVtYiA9IHRydWU7Cj4gKwlhcmdzLT5waXRjaCA9IHBpdGNo Owo+ICsJcmV0dXJuIHJldDsKPiArCj4gK2ZhaWw6Cj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ ICtpbnQgdmlydGlvX2dwdV9tb2RlX2R1bWJfZGVzdHJveShzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVf cHJpdiwKPiArCQkJCSBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJCQkJIHVpbnQzMl90IGhh bmRsZSkKPiArewo+ICsJcmV0dXJuIGRybV9nZW1faGFuZGxlX2RlbGV0ZShmaWxlX3ByaXYsIGhh bmRsZSk7Cj4gK30KPiArCj4gK2ludCB2aXJ0aW9fZ3B1X21vZGVfZHVtYl9tbWFwKHN0cnVjdCBk cm1fZmlsZSAqZmlsZV9wcml2LAo+ICsJCQkgICAgICBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ ICsJCQkgICAgICB1aW50MzJfdCBoYW5kbGUsIHVpbnQ2NF90ICpvZmZzZXRfcCkKPiArewo+ICsJ c3RydWN0IGRybV9nZW1fb2JqZWN0ICpnb2JqOwo+ICsJc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0 ICpvYmo7Cj4gKwlCVUdfT04oIW9mZnNldF9wKTsKPiArCWdvYmogPSBkcm1fZ2VtX29iamVjdF9s b29rdXAoZGV2LCBmaWxlX3ByaXYsIGhhbmRsZSk7Cj4gKwlpZiAoZ29iaiA9PSBOVUxMKQo+ICsJ CXJldHVybiAtRU5PRU5UOwo+ICsJb2JqID0gZ2VtX3RvX3ZpcnRpb19ncHVfb2JqKGdvYmopOwo+ ICsJKm9mZnNldF9wID0gdmlydGlvX2dwdV9vYmplY3RfbW1hcF9vZmZzZXQob2JqKTsKPiArCWRy bV9nZW1fb2JqZWN0X3VucmVmZXJlbmNlX3VubG9ja2VkKGdvYmopOwo+ICsJcmV0dXJuIDA7Cj4g K30KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2ttcy5jIGIv ZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X2ttcy5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2 NDQKPiBpbmRleCAwMDAwMDAwLi5lNTAzZmZiCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZl cnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9rbXMuYwo+IEBAIC0wLDAgKzEsMTY0IEBACj4gKy8q Cj4gKyAqIENvcHlyaWdodCAoQykgMjAxNSBSZWQgSGF0LCBJbmMuCj4gKyAqIEFsbCBSaWdodHMg UmVzZXJ2ZWQuCj4gKyAqCj4gKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUg b2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwo+ICsgKiBhIGNvcHkgb2YgdGhpcyBz b2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKPiArICogIlNv ZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGlu Y2x1ZGluZwo+ICsgKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHks IG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCj4gKyAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFu ZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwo+ICsgKiBwZXJtaXQgcGVy c29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3Qg dG8KPiArICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgo+ICsgKgo+ICsgKiBUaGUgYWJvdmUg Y29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRo ZQo+ICsgKiBuZXh0IHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBv ciBzdWJzdGFudGlhbAo+ICsgKiBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCj4gKyAqCj4gKyAq IFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFO WSBLSU5ELAo+ICsgKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlU RUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKPiArICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZP UiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULgo+ICsgKiBJTiBOTyBF VkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIE9XTkVSKFMpIEFORC9PUiBJVFMgU1VQUExJRVJTIEJF Cj4gKyAqIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwg V0hFVEhFUiBJTiBBTiBBQ1RJT04KPiArICogT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNF LCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OCj4gKyAqIFdJVEggVEhFIFNP RlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgo+ICsg Ki8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC92aXJ0aW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Zp cnRpb19jb25maWcuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1QLmg+Cj4gKyNpbmNsdWRlICJ2aXJ0 Z3B1X2Rydi5oIgo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9jb25maWdfY2hhbmdlZF93 b3JrX2Z1bmMoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlv X2dwdV9kZXZpY2UgKnZnZGV2ID0KPiArCQljb250YWluZXJfb2Yod29yaywgc3RydWN0IHZpcnRp b19ncHVfZGV2aWNlLAo+ICsJCQkgICAgIGNvbmZpZ19jaGFuZ2VkX3dvcmspOwo+ICsJdTMyIGV2 ZW50c19yZWFkLCBldmVudHNfY2xlYXIgPSAwOwo+ICsKPiArCS8qIHJlYWQgdGhlIGNvbmZpZyBz cGFjZSAqLwo+ICsJdmlydGlvX2NyZWFkKHZnZGV2LT52ZGV2LCBzdHJ1Y3QgdmlydGlvX2dwdV9j b25maWcsCj4gKwkJICAgICBldmVudHNfcmVhZCwgJmV2ZW50c19yZWFkKTsKPiArCWlmIChldmVu dHNfcmVhZCAmIFZJUlRJT19HUFVfRVZFTlRfRElTUExBWSkgewo+ICsJCXZpcnRpb19ncHVfY21k X2dldF9kaXNwbGF5X2luZm8odmdkZXYpOwo+ICsJCWRybV9oZWxwZXJfaHBkX2lycV9ldmVudCh2 Z2Rldi0+ZGRldik7Cj4gKwkJZXZlbnRzX2NsZWFyIHw9IFZJUlRJT19HUFVfRVZFTlRfRElTUExB WTsKPiArCX0KPiArCXZpcnRpb19jd3JpdGUodmdkZXYtPnZkZXYsIHN0cnVjdCB2aXJ0aW9fZ3B1 X2NvbmZpZywKPiArCQkgICAgICBldmVudHNfY2xlYXIsICZldmVudHNfY2xlYXIpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X2luaXRfdnEoc3RydWN0IHZpcnRpb19ncHVfcXVl dWUgKnZndnEsCj4gKwkJCSAgICAgICB2b2lkICgqd29ya19mdW5jKShzdHJ1Y3Qgd29ya19zdHJ1 Y3QgKndvcmspKQo+ICt7Cj4gKwlzcGluX2xvY2tfaW5pdCgmdmd2cS0+cWxvY2spOwo+ICsJaW5p dF93YWl0cXVldWVfaGVhZCgmdmd2cS0+YWNrX3F1ZXVlKTsKPiArCUlOSVRfV09SSygmdmd2cS0+ ZGVxdWV1ZV93b3JrLCB3b3JrX2Z1bmMpOwo+ICt9Cj4gKwo+ICtpbnQgdmlydGlvX2dwdV9kcml2 ZXJfbG9hZChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCB1bnNpZ25lZCBsb25nIGZsYWdzKQo+ICt7 Cj4gKwlzdGF0aWMgdnFfY2FsbGJhY2tfdCAqY2FsbGJhY2tzW10gPSB7Cj4gKwkJdmlydGlvX2dw dV9jdHJsX2FjaywgdmlydGlvX2dwdV9jdXJzb3JfYWNrCj4gKwl9Owo+ICsJc3RhdGljIGNvbnN0 IGNoYXIgKm5hbWVzW10gPSB7ICJjb250cm9sIiwgImN1cnNvciIgfTsKPiArCj4gKwlzdHJ1Y3Qg dmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2Owo+ICsJLyogdGhpcyB3aWxsIGV4cGFuZCBsYXRlciAq Lwo+ICsJc3RydWN0IHZpcnRxdWV1ZSAqdnFzWzJdOwo+ICsJdTMyIG51bV9zY2Fub3V0czsKPiAr CWludCByZXQ7Cj4gKwo+ICsJaWYgKCF2aXJ0aW9faGFzX2ZlYXR1cmUoZGV2LT52aXJ0ZGV2LCBW SVJUSU9fRl9WRVJTSU9OXzEpKQo+ICsJCXJldHVybiAtRU5PREVWOwo+ICsKPiArCXZnZGV2ID0g a3phbGxvYyhzaXplb2Yoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlKSwgR0ZQX0tFUk5FTCk7Cj4g KwlpZiAoIXZnZGV2KQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXZnZGV2LT5kZGV2ID0g ZGV2Owo+ICsJZGV2LT5kZXZfcHJpdmF0ZSA9IHZnZGV2Owo+ICsJdmdkZXYtPnZkZXYgPSBkZXYt PnZpcnRkZXY7Cj4gKwl2Z2Rldi0+ZGV2ID0gZGV2LT5kZXY7Cj4gKwo+ICsJc3Bpbl9sb2NrX2lu aXQoJnZnZGV2LT5kaXNwbGF5X2luZm9fbG9jayk7Cj4gKwlzcGluX2xvY2tfaW5pdCgmdmdkZXYt PmN0eF9pZF9pZHJfbG9jayk7Cj4gKwlpZHJfaW5pdCgmdmdkZXYtPmN0eF9pZF9pZHIpOwo+ICsJ c3Bpbl9sb2NrX2luaXQoJnZnZGV2LT5yZXNvdXJjZV9pZHJfbG9jayk7Cj4gKwlpZHJfaW5pdCgm dmdkZXYtPnJlc291cmNlX2lkcik7Cj4gKwlpbml0X3dhaXRxdWV1ZV9oZWFkKCZ2Z2Rldi0+cmVz cF93cSk7Cj4gKwl2aXJ0aW9fZ3B1X2luaXRfdnEoJnZnZGV2LT5jdHJscSwgdmlydGlvX2dwdV9k ZXF1ZXVlX2N0cmxfZnVuYyk7Cj4gKwl2aXJ0aW9fZ3B1X2luaXRfdnEoJnZnZGV2LT5jdXJzb3Jx LCB2aXJ0aW9fZ3B1X2RlcXVldWVfY3Vyc29yX2Z1bmMpOwo+ICsKPiArCXNwaW5fbG9ja19pbml0 KCZ2Z2Rldi0+ZmVuY2VfZHJ2LmxvY2spOwo+ICsJSU5JVF9MSVNUX0hFQUQoJnZnZGV2LT5mZW5j ZV9kcnYuZmVuY2VzKTsKPiArCUlOSVRfV09SSygmdmdkZXYtPmNvbmZpZ19jaGFuZ2VkX3dvcmss Cj4gKwkJICB2aXJ0aW9fZ3B1X2NvbmZpZ19jaGFuZ2VkX3dvcmtfZnVuYyk7Cj4gKwo+ICsJcmV0 ID0gdmdkZXYtPnZkZXYtPmNvbmZpZy0+ZmluZF92cXModmdkZXYtPnZkZXYsIDIsIHZxcywKPiAr CQkJCQkgICAgY2FsbGJhY2tzLCBuYW1lcyk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9S KCJmYWlsZWQgdG8gZmluZCB2aXJ0IHF1ZXVlc1xuIik7Cj4gKwkJZ290byBlcnJfdnFzOwo+ICsJ fQo+ICsJdmdkZXYtPmN0cmxxLnZxID0gdnFzWzBdOwo+ICsJdmdkZXYtPmN1cnNvcnEudnEgPSB2 cXNbMV07Cj4gKwlyZXQgPSB2aXJ0aW9fZ3B1X2FsbG9jX3ZidWZzKHZnZGV2KTsKPiArCWlmIChy ZXQpIHsKPiArCQlEUk1fRVJST1IoImZhaWxlZCB0byBhbGxvYyB2YnVmc1xuIik7Cj4gKwkJZ290 byBlcnJfdmJ1ZnM7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gdmlydGlvX2dwdV90dG1faW5pdCh2Z2Rl dik7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gaW5pdCB0dG0gJWRc biIsIHJldCk7Cj4gKwkJZ290byBlcnJfdHRtOwo+ICsJfQo+ICsKPiArCS8qIGdldCBkaXNwbGF5 IGluZm8gKi8KPiArCXZpcnRpb19jcmVhZCh2Z2Rldi0+dmRldiwgc3RydWN0IHZpcnRpb19ncHVf Y29uZmlnLAo+ICsJCSAgICAgbnVtX3NjYW5vdXRzLCAmbnVtX3NjYW5vdXRzKTsKPiArCXZnZGV2 LT5udW1fc2Nhbm91dHMgPSBtaW5fdCh1aW50MzJfdCwgbnVtX3NjYW5vdXRzLAo+ICsJCQkJICAg IFZJUlRJT19HUFVfTUFYX1NDQU5PVVRTKTsKPiArCWlmICghdmdkZXYtPm51bV9zY2Fub3V0cykg ewo+ICsJCURSTV9FUlJPUigibnVtX3NjYW5vdXRzIGlzIHplcm9cbiIpOwo+ICsJCXJldCA9IC1F SU5WQUw7Cj4gKwkJZ290byBlcnJfc2Nhbm91dHM7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gdmlydGlv X2dwdV9tb2Rlc2V0X2luaXQodmdkZXYpOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIGVycl9tb2Rl c2V0Owo+ICsKPiArCXZpcnRpb19kZXZpY2VfcmVhZHkodmdkZXYtPnZkZXYpOwo+ICsJdmdkZXYt PnZxc19yZWFkeSA9IHRydWU7Cj4gKwl2aXJ0aW9fZ3B1X2NtZF9nZXRfZGlzcGxheV9pbmZvKHZn ZGV2KTsKPiArCXJldHVybiAwOwo+ICsKPiArZXJyX21vZGVzZXQ6Cj4gK2Vycl9zY2Fub3V0czoK PiArCXZpcnRpb19ncHVfdHRtX2ZpbmkodmdkZXYpOwo+ICtlcnJfdHRtOgo+ICsJdmlydGlvX2dw dV9mcmVlX3ZidWZzKHZnZGV2KTsKPiArZXJyX3ZidWZzOgo+ICsJdmdkZXYtPnZkZXYtPmNvbmZp Zy0+ZGVsX3Zxcyh2Z2Rldi0+dmRldik7Cj4gK2Vycl92cXM6Cj4gKwlrZnJlZSh2Z2Rldik7Cj4g KwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtpbnQgdmlydGlvX2dwdV9kcml2ZXJfdW5sb2FkKHN0 cnVjdCBkcm1fZGV2aWNlICpkZXYpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAq dmdkZXYgPSBkZXYtPmRldl9wcml2YXRlOwo+ICsKPiArCXZnZGV2LT52cXNfcmVhZHkgPSBmYWxz ZTsKPiArCWZsdXNoX3dvcmsoJnZnZGV2LT5jdHJscS5kZXF1ZXVlX3dvcmspOwo+ICsJZmx1c2hf d29yaygmdmdkZXYtPmN1cnNvcnEuZGVxdWV1ZV93b3JrKTsKPiArCWZsdXNoX3dvcmsoJnZnZGV2 LT5jb25maWdfY2hhbmdlZF93b3JrKTsKPiArCXZnZGV2LT52ZGV2LT5jb25maWctPmRlbF92cXMo dmdkZXYtPnZkZXYpOwo+ICsKPiArCXZpcnRpb19ncHVfbW9kZXNldF9maW5pKHZnZGV2KTsKPiAr CXZpcnRpb19ncHVfdHRtX2ZpbmkodmdkZXYpOwo+ICsJdmlydGlvX2dwdV9mcmVlX3ZidWZzKHZn ZGV2KTsKPiArCWtmcmVlKHZnZGV2KTsKPiArCXJldHVybiAwOwo+ICt9Cj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9vYmplY3QuYyBiL2RyaXZlcnMvZ3B1L2Ry bS92aXJ0aW8vdmlydGdwdV9vYmplY3QuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXgg MDAwMDAwMC4uMmM2MjRjNwo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0v dmlydGlvL3ZpcnRncHVfb2JqZWN0LmMKPiBAQCAtMCwwICsxLDE3MCBAQAo+ICsvKgo+ICsgKiBD b3B5cmlnaHQgKEMpIDIwMTUgUmVkIEhhdCwgSW5jLgo+ICsgKiBBbGwgUmlnaHRzIFJlc2VydmVk Lgo+ICsgKgo+ICsgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJn ZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKPiArICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUg YW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCj4gKyAqICJTb2Z0d2FyZSIp LCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcK PiArICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnks IG1lcmdlLCBwdWJsaXNoLAo+ICsgKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2Vs bCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KPiArICogcGVybWl0IHBlcnNvbnMgdG8g d2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCj4gKyAq IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKPiArICoKPiArICogVGhlIGFib3ZlIGNvcHlyaWdo dCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUKPiArICog bmV4dCBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3Rh bnRpYWwKPiArICogcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgo+ICsgKgo+ICsgKiBUSEUgU09G VFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwK PiArICogRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRI RSBXQVJSQU5USUVTIE9GCj4gKyAqIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJU SUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4KPiArICogSU4gTk8gRVZFTlQgU0hB TEwgVEhFIENPUFlSSUdIVCBPV05FUihTKSBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRQo+ICsgKiBM SUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIg SU4gQU4gQUNUSU9OCj4gKyAqIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lO RyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTgo+ICsgKiBXSVRIIFRIRSBTT0ZUV0FSRSBP UiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KPiArICovCj4gKwo+ ICsjaW5jbHVkZSAidmlydGdwdV9kcnYuaCIKPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVf dHRtX2JvX2Rlc3Ryb3koc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICp0Ym8pCj4gK3sKPiArCXN0 cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm87Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2Ug KnZnZGV2Owo+ICsKPiArCWJvID0gY29udGFpbmVyX29mKHRibywgc3RydWN0IHZpcnRpb19ncHVf b2JqZWN0LCB0Ym8pOwo+ICsJdmdkZXYgPSAoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICopYm8t PmdlbV9iYXNlLmRldi0+ZGV2X3ByaXZhdGU7Cj4gKwo+ICsJaWYgKGJvLT5od19yZXNfaGFuZGxl KQo+ICsJCXZpcnRpb19ncHVfY21kX3VucmVmX3Jlc291cmNlKHZnZGV2LCBiby0+aHdfcmVzX2hh bmRsZSk7Cj4gKwlpZiAoYm8tPnBhZ2VzKQo+ICsJCXZpcnRpb19ncHVfb2JqZWN0X2ZyZWVfc2df dGFibGUoYm8pOwo+ICsJZHJtX2dlbV9vYmplY3RfcmVsZWFzZSgmYm8tPmdlbV9iYXNlKTsKPiAr CWtmcmVlKGJvKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9pbml0X3R0bV9w bGFjZW1lbnQoc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0ICp2Z2JvLAo+ICsJCQkJCSAgYm9vbCBw aW5uZWQpCj4gK3sKPiArCXUzMiBjID0gMTsKPiArCXUzMiBwZmxhZyA9IHBpbm5lZCA/IFRUTV9Q TF9GTEFHX05PX0VWSUNUIDogMDsKPiArCj4gKwl2Z2JvLT5wbGFjZW1lbnQucGxhY2VtZW50ID0g JnZnYm8tPnBsYWNlbWVudF9jb2RlOwo+ICsJdmdiby0+cGxhY2VtZW50LmJ1c3lfcGxhY2VtZW50 ID0gJnZnYm8tPnBsYWNlbWVudF9jb2RlOwo+ICsJdmdiby0+cGxhY2VtZW50X2NvZGUuZnBmbiA9 IDA7Cj4gKwl2Z2JvLT5wbGFjZW1lbnRfY29kZS5scGZuID0gMDsKPiArCXZnYm8tPnBsYWNlbWVu dF9jb2RlLmZsYWdzID0KPiArCQlUVE1fUExfTUFTS19DQUNISU5HIHwgVFRNX1BMX0ZMQUdfVFQg fCBwZmxhZzsKPiArCXZnYm8tPnBsYWNlbWVudC5udW1fcGxhY2VtZW50ID0gYzsKPiArCXZnYm8t PnBsYWNlbWVudC5udW1fYnVzeV9wbGFjZW1lbnQgPSBjOwo+ICsKPiArfQo+ICsKPiAraW50IHZp cnRpb19ncHVfb2JqZWN0X2NyZWF0ZShzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2LAo+ ICsJCQkgICAgIHVuc2lnbmVkIGxvbmcgc2l6ZSwgYm9vbCBrZXJuZWwsIGJvb2wgcGlubmVkLAo+ ICsJCQkgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqKmJvX3B0cikKPiArewo+ICsJc3Ry dWN0IHZpcnRpb19ncHVfb2JqZWN0ICpibzsKPiArCWVudW0gdHRtX2JvX3R5cGUgdHlwZTsKPiAr CXNpemVfdCBhY2Nfc2l6ZTsKPiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKGtlcm5lbCkKPiArCQl0 eXBlID0gdHRtX2JvX3R5cGVfa2VybmVsOwo+ICsJZWxzZQo+ICsJCXR5cGUgPSB0dG1fYm9fdHlw ZV9kZXZpY2U7Cj4gKwkqYm9fcHRyID0gTlVMTDsKPiArCj4gKwlhY2Nfc2l6ZSA9IHR0bV9ib19k bWFfYWNjX3NpemUoJnZnZGV2LT5tbWFuLmJkZXYsIHNpemUsCj4gKwkJCQkgICAgICAgc2l6ZW9m KHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCkpOwo+ICsKPiArCWJvID0ga3phbGxvYyhzaXplb2Yo c3RydWN0IHZpcnRpb19ncHVfb2JqZWN0KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoYm8gPT0gTlVM TCkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCXNpemUgPSByb3VuZHVwKHNpemUsIFBBR0VfU0la RSk7Cj4gKwlyZXQgPSBkcm1fZ2VtX29iamVjdF9pbml0KHZnZGV2LT5kZGV2LCAmYm8tPmdlbV9i YXNlLCBzaXplKTsKPiArCWlmIChyZXQgIT0gMCkKPiArCQlnb3RvIGVycl9nZW1faW5pdDsKPiAr CWJvLT5kdW1iID0gZmFsc2U7Cj4gKwl2aXJ0aW9fZ3B1X2luaXRfdHRtX3BsYWNlbWVudChibywg cGlubmVkKTsKPiArCj4gKwlyZXQgPSB0dG1fYm9faW5pdCgmdmdkZXYtPm1tYW4uYmRldiwgJmJv LT50Ym8sIHNpemUsIHR5cGUsCj4gKwkJCSAgJmJvLT5wbGFjZW1lbnQsIDAsICFrZXJuZWwsIE5V TEwsIGFjY19zaXplLAo+ICsJCQkgIE5VTEwsIE5VTEwsICZ2aXJ0aW9fZ3B1X3R0bV9ib19kZXN0 cm95KTsKPiArCWlmIChyZXQgIT0gMCkKPiArCQlnb3RvIGVycl90dG1faW5pdDsKPiArCj4gKwkq Ym9fcHRyID0gYm87Cj4gKwlyZXR1cm4gMDsKPiArCj4gK2Vycl90dG1faW5pdDoKPiArCWRybV9n ZW1fb2JqZWN0X3JlbGVhc2UoJmJvLT5nZW1fYmFzZSk7Cj4gK2Vycl9nZW1faW5pdDoKPiArCWtm cmVlKGJvKTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK2ludCB2aXJ0aW9fZ3B1X29iamVj dF9rbWFwKHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8sIHZvaWQgKipwdHIpCj4gK3sKPiAr CWJvb2wgaXNfaW9tZW07Cj4gKwlpbnQgcjsKPiArCj4gKwlpZiAoYm8tPnZtYXApIHsKPiArCQlp ZiAocHRyKQo+ICsJCQkqcHRyID0gYm8tPnZtYXA7Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwly ID0gdHRtX2JvX2ttYXAoJmJvLT50Ym8sIDAsIGJvLT50Ym8ubnVtX3BhZ2VzLCAmYm8tPmttYXAp Owo+ICsJaWYgKHIpCj4gKwkJcmV0dXJuIHI7Cj4gKwliby0+dm1hcCA9IHR0bV9rbWFwX29ial92 aXJ0dWFsKCZiby0+a21hcCwgJmlzX2lvbWVtKTsKPiArCWlmIChwdHIpCj4gKwkJKnB0ciA9IGJv LT52bWFwOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK2ludCB2aXJ0aW9fZ3B1X29iamVjdF9n ZXRfc2dfdGFibGUoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICpxZGV2LAo+ICsJCQkJICAgc3Ry dWN0IHZpcnRpb19ncHVfb2JqZWN0ICpibykKPiArewo+ICsJaW50IHJldDsKPiArCXN0cnVjdCBw YWdlICoqcGFnZXMgPSBiby0+dGJvLnR0bS0+cGFnZXM7Cj4gKwlpbnQgbnJfcGFnZXMgPSBiby0+ dGJvLm51bV9wYWdlczsKPiArCj4gKwkvKiB3dGYgc3dhcHBpbmcgKi8KPiArCWlmIChiby0+cGFn ZXMpCj4gKwkJcmV0dXJuIDA7Cj4gKwo+ICsJaWYgKGJvLT50Ym8udHRtLT5zdGF0ZSA9PSB0dF91 bnBvcHVsYXRlZCkKPiArCQliby0+dGJvLnR0bS0+YmRldi0+ZHJpdmVyLT50dG1fdHRfcG9wdWxh dGUoYm8tPnRiby50dG0pOwo+ICsJYm8tPnBhZ2VzID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHNn X3RhYmxlKSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIWJvLT5wYWdlcykKPiArCQlnb3RvIG91dDsK PiArCj4gKwlyZXQgPSBzZ19hbGxvY190YWJsZV9mcm9tX3BhZ2VzKGJvLT5wYWdlcywgcGFnZXMs IG5yX3BhZ2VzLCAwLAo+ICsJCQkJCW5yX3BhZ2VzIDw8IFBBR0VfU0hJRlQsIEdGUF9LRVJORUwp Owo+ICsJaWYgKHJldCkKPiArCQlnb3RvIG91dDsKPiArCXJldHVybiAwOwo+ICtvdXQ6Cj4gKwlr ZnJlZShiby0+cGFnZXMpOwo+ICsJYm8tPnBhZ2VzID0gTlVMTDsKPiArCXJldHVybiAtRU5PTUVN Owo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVfb2JqZWN0X2ZyZWVfc2dfdGFibGUoc3RydWN0 IHZpcnRpb19ncHVfb2JqZWN0ICpibykKPiArewo+ICsJc2dfZnJlZV90YWJsZShiby0+cGFnZXMp Owo+ICsJa2ZyZWUoYm8tPnBhZ2VzKTsKPiArCWJvLT5wYWdlcyA9IE5VTEw7Cj4gK30KPiArCj4g K2ludCB2aXJ0aW9fZ3B1X29iamVjdF93YWl0KHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8s IGJvb2wgbm9fd2FpdCkKPiArewo+ICsJaW50IHI7Cj4gKwo+ICsJciA9IHR0bV9ib19yZXNlcnZl KCZiby0+dGJvLCB0cnVlLCBub193YWl0LCBmYWxzZSwgTlVMTCk7Cj4gKwlpZiAodW5saWtlbHko ciAhPSAwKSkKPiArCQlyZXR1cm4gcjsKPiArCXIgPSB0dG1fYm9fd2FpdCgmYm8tPnRibywgdHJ1 ZSwgdHJ1ZSwgbm9fd2FpdCk7Cj4gKwl0dG1fYm9fdW5yZXNlcnZlKCZiby0+dGJvKTsKPiArCXJl dHVybiByOwo+ICt9Cj4gKwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3Zp cnRncHVfcGxhbmUuYyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9wbGFuZS5jCj4g bmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi40YTc0MTI5Cj4gLS0tIC9kZXYv bnVsbAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9wbGFuZS5jCj4gQEAg LTAsMCArMSwxMjAgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDE1IFJlZCBIYXQsIElu Yy4KPiArICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPiArICoKPiArICogUGVybWlzc2lvbiBpcyBo ZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCj4g KyAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24g ZmlsZXMgKHRoZQo+ICsgKiAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0 aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCj4gKyAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUg cmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKPiArICogZGlzdHJp YnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5k IHRvCj4gKyAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hl ZCB0byBkbyBzbywgc3ViamVjdCB0bwo+ICsgKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6Cj4g KyAqCj4gKyAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24g bm90aWNlIChpbmNsdWRpbmcgdGhlCj4gKyAqIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNs dWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsCj4gKyAqIHBvcnRpb25zIG9mIHRoZSBT b2Z0d2FyZS4KPiArICoKPiArICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJ VEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCj4gKyAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5D TFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgo+ICsgKiBNRVJDSEFO VEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5H RU1FTlQuCj4gKyAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgT1dORVIoUykgQU5E L09SIElUUyBTVVBQTElFUlMgQkUKPiArICogTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMg T1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTgo+ICsgKiBPRiBDT05UUkFD VCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJ T04KPiArICogV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJ TiBUSEUgU09GVFdBUkUuCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgInZpcnRncHVfZHJ2LmgiCj4g KyNpbmNsdWRlIDxkcm0vZHJtX3BsYW5lX2hlbHBlci5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9h dG9taWNfaGVscGVyLmg+Cj4gKwo+ICtzdGF0aWMgY29uc3QgdWludDMyX3QgdmlydGlvX2dwdV9m b3JtYXRzW10gPSB7Cj4gKwlEUk1fRk9STUFUX1hSR0I4ODg4LAo+ICsJRFJNX0ZPUk1BVF9BUkdC ODg4OCwKPiArCURSTV9GT1JNQVRfQkdSWDg4ODgsCj4gKwlEUk1fRk9STUFUX0JHUkE4ODg4LAo+ ICsJRFJNX0ZPUk1BVF9SR0JYODg4OCwKPiArCURSTV9GT1JNQVRfUkdCQTg4ODgsCj4gKwlEUk1f Rk9STUFUX1hCR1I4ODg4LAo+ICsJRFJNX0ZPUk1BVF9BQkdSODg4OCwKPiArfTsKPiArCj4gK3N0 YXRpYyB2b2lkIHZpcnRpb19ncHVfcGxhbmVfZGVzdHJveShzdHJ1Y3QgZHJtX3BsYW5lICpwbGFu ZSkKPiArewo+ICsJa2ZyZWUocGxhbmUpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0 IGRybV9wbGFuZV9mdW5jcyB2aXJ0aW9fZ3B1X3BsYW5lX2Z1bmNzID0gewo+ICsJLnVwZGF0ZV9w bGFuZQkJPSBkcm1fYXRvbWljX2hlbHBlcl91cGRhdGVfcGxhbmUsCj4gKwkuZGlzYWJsZV9wbGFu ZQkJPSBkcm1fYXRvbWljX2hlbHBlcl9kaXNhYmxlX3BsYW5lLAo+ICsJLmRlc3Ryb3kJCT0gdmly dGlvX2dwdV9wbGFuZV9kZXN0cm95LAo+ICsJLnJlc2V0CQkJPSBkcm1fYXRvbWljX2hlbHBlcl9w bGFuZV9yZXNldCwKPiArCS5hdG9taWNfZHVwbGljYXRlX3N0YXRlID0gZHJtX2F0b21pY19oZWxw ZXJfcGxhbmVfZHVwbGljYXRlX3N0YXRlLAo+ICsJLmF0b21pY19kZXN0cm95X3N0YXRlCT0gZHJt X2F0b21pY19oZWxwZXJfcGxhbmVfZGVzdHJveV9zdGF0ZSwKPiArfTsKPiArCj4gK3N0YXRpYyBp bnQgdmlydGlvX2dwdV9wbGFuZV9hdG9taWNfY2hlY2soc3RydWN0IGRybV9wbGFuZSAqcGxhbmUs Cj4gKwkJCQkJIHN0cnVjdCBkcm1fcGxhbmVfc3RhdGUgKnN0YXRlKQo+ICt7Cj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9wbGFuZV9hdG9taWNfdXBkYXRl KHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAo+ICsJCQkJCSAgIHN0cnVjdCBkcm1fcGxhbmVfc3Rh dGUgKm9sZF9zdGF0ZSkKPiArewo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IHBsYW5lLT5k ZXY7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2ID0gZGV2LT5kZXZfcHJpdmF0 ZTsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X291dHB1dCAqb3V0cHV0ID0gZHJtX2NydGNfdG9fdmly dGlvX2dwdV9vdXRwdXQocGxhbmUtPmNydGMpOwo+ICsJc3RydWN0IHZpcnRpb19ncHVfZnJhbWVi dWZmZXIgKnZnZmI7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKmJvOwo+ICsJdWludDMy X3QgaGFuZGxlOwo+ICsKPiArCWlmIChwbGFuZS0+ZmIpIHsKPiArCQl2Z2ZiID0gdG9fdmlydGlv X2dwdV9mcmFtZWJ1ZmZlcihwbGFuZS0+ZmIpOwo+ICsJCWJvID0gZ2VtX3RvX3ZpcnRpb19ncHVf b2JqKHZnZmItPm9iaik7Cj4gKwkJaGFuZGxlID0gYm8tPmh3X3Jlc19oYW5kbGU7Cj4gKwl9IGVs c2Ugewo+ICsJCWhhbmRsZSA9IDA7Cj4gKwl9Cj4gKwo+ICsJRFJNX0RFQlVHKCJoYW5kbGUgMHgl eCwgY3J0YyAlZHglZCslZCslZFxuIiwgaGFuZGxlLAo+ICsJCSAgcGxhbmUtPnN0YXRlLT5jcnRj X3csIHBsYW5lLT5zdGF0ZS0+Y3J0Y19oLAo+ICsJCSAgcGxhbmUtPnN0YXRlLT5jcnRjX3gsIHBs YW5lLT5zdGF0ZS0+Y3J0Y195KTsKPiArCXZpcnRpb19ncHVfY21kX3NldF9zY2Fub3V0KHZnZGV2 LCBvdXRwdXQtPmluZGV4LCBoYW5kbGUsCj4gKwkJCQkgICBwbGFuZS0+c3RhdGUtPmNydGNfdywK PiArCQkJCSAgIHBsYW5lLT5zdGF0ZS0+Y3J0Y19oLAo+ICsJCQkJICAgcGxhbmUtPnN0YXRlLT5j cnRjX3gsCj4gKwkJCQkgICBwbGFuZS0+c3RhdGUtPmNydGNfeSk7Cj4gK30KPiArCj4gKwo+ICtz dGF0aWMgY29uc3Qgc3RydWN0IGRybV9wbGFuZV9oZWxwZXJfZnVuY3MgdmlydGlvX2dwdV9wbGFu ZV9oZWxwZXJfZnVuY3MgPSB7Cj4gKwkuYXRvbWljX2NoZWNrCQk9IHZpcnRpb19ncHVfcGxhbmVf YXRvbWljX2NoZWNrLAo+ICsJLmF0b21pY191cGRhdGUJCT0gdmlydGlvX2dwdV9wbGFuZV9hdG9t aWNfdXBkYXRlLAo+ICt9Owo+ICsKPiArc3RydWN0IGRybV9wbGFuZSAqdmlydGlvX2dwdV9wbGFu ZV9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCQkJaW50IGluZGV4 KQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gdmdkZXYtPmRkZXY7Cj4gKwlzdHJ1 Y3QgZHJtX3BsYW5lICpwbGFuZTsKPiArCWludCByZXQ7Cj4gKwo+ICsJcGxhbmUgPSBremFsbG9j KHNpemVvZigqcGxhbmUpLCBHRlBfS0VSTkVMKTsKPiArCWlmICghcGxhbmUpCj4gKwkJcmV0dXJu IEVSUl9QVFIoLUVOT01FTSk7Cj4gKwo+ICsJcmV0ID0gZHJtX3VuaXZlcnNhbF9wbGFuZV9pbml0 KGRldiwgcGxhbmUsIDEgPDwgaW5kZXgsCj4gKwkJCQkgICAgICAgJnZpcnRpb19ncHVfcGxhbmVf ZnVuY3MsCj4gKwkJCQkgICAgICAgdmlydGlvX2dwdV9mb3JtYXRzLAo+ICsJCQkJICAgICAgIEFS UkFZX1NJWkUodmlydGlvX2dwdV9mb3JtYXRzKSwKPiArCQkJCSAgICAgICBEUk1fUExBTkVfVFlQ RV9QUklNQVJZKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBlcnJfcGxhbmVfaW5pdDsKPiArCj4g Kwlkcm1fcGxhbmVfaGVscGVyX2FkZChwbGFuZSwgJnZpcnRpb19ncHVfcGxhbmVfaGVscGVyX2Z1 bmNzKTsKPiArCXJldHVybiBwbGFuZTsKPiArCj4gK2Vycl9wbGFuZV9pbml0Ogo+ICsJa2ZyZWUo cGxhbmUpOwo+ICsJcmV0dXJuIEVSUl9QVFIocmV0KTsKPiArfQo+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfdHRtLmMgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlv L3ZpcnRncHVfdHRtLmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLmUw ZTc0YzYKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0 Z3B1X3R0bS5jCj4gQEAgLTAsMCArMSw0NjkgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAy MDE1IFJlZCBIYXQsIEluYy4KPiArICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KPiArICoKPiArICog QXV0aG9yczoKPiArICogICAgRGF2ZSBBaXJsaWUKPiArICogICAgQWxvbiBMZXZ5Cj4gKyAqCj4g KyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkg cGVyc29uIG9idGFpbmluZyBhCj4gKyAqIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2Np YXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCj4gKyAqIHRvIGRlYWwg aW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxp bWl0YXRpb24KPiArICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1 Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCj4gKyAqIGFuZC9vciBzZWxsIGNvcGllcyBv ZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQo+ICsgKiBT b2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBj b25kaXRpb25zOgo+ICsgKgo+ICsgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhp cyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgo+ICsgKiBhbGwgY29waWVz IG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KPiArICoKPiArICogVEhF IFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJ TkQsIEVYUFJFU1MgT1IKPiArICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBU TyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCj4gKyAqIEZJVE5FU1MgRk9SIEEg UEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFM TAo+ICsgKiBUSEUgQ09QWVJJR0hUIEhPTERFUihTKSBPUiBBVVRIT1IoUykgQkUgTElBQkxFIEZP UiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IKPiArICogT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElO IEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsCj4gKyAqIEFSSVNJTkcg RlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVT RSBPUgo+ICsgKiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCj4gKyAqLwo+ICsKPiAr I2luY2x1ZGUgPHR0bS90dG1fYm9fYXBpLmg+Cj4gKyNpbmNsdWRlIDx0dG0vdHRtX2JvX2RyaXZl ci5oPgo+ICsjaW5jbHVkZSA8dHRtL3R0bV9wbGFjZW1lbnQuaD4KPiArI2luY2x1ZGUgPHR0bS90 dG1fcGFnZV9hbGxvYy5oPgo+ICsjaW5jbHVkZSA8dHRtL3R0bV9tb2R1bGUuaD4KPiArI2luY2x1 ZGUgPGRybS9kcm1QLmg+Cj4gKyNpbmNsdWRlIDxkcm0vZHJtLmg+Cj4gKyNpbmNsdWRlICJ2aXJ0 Z3B1X2Rydi5oIgo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4gKwo+ICsjZGVmaW5l IERSTV9GSUxFX1BBR0VfT0ZGU0VUICgweDEwMDAwMDAwMFVMTCA+PiBQQUdFX1NISUZUKQo+ICsK PiArc3RhdGljIHN0cnVjdAo+ICt2aXJ0aW9fZ3B1X2RldmljZSAqdmlydGlvX2dwdV9nZXRfdmdk ZXYoc3RydWN0IHR0bV9ib19kZXZpY2UgKmJkZXYpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1 X21tYW4gKm1tYW47Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2Owo+ICsKPiAr CW1tYW4gPSBjb250YWluZXJfb2YoYmRldiwgc3RydWN0IHZpcnRpb19ncHVfbW1hbiwgYmRldik7 Cj4gKwl2Z2RldiA9IGNvbnRhaW5lcl9vZihtbWFuLCBzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2Us IG1tYW4pOwo+ICsJcmV0dXJuIHZnZGV2Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHZpcnRpb19n cHVfdHRtX21lbV9nbG9iYWxfaW5pdChzdHJ1Y3QgZHJtX2dsb2JhbF9yZWZlcmVuY2UgKnJlZikK PiArewo+ICsJcmV0dXJuIHR0bV9tZW1fZ2xvYmFsX2luaXQocmVmLT5vYmplY3QpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X3R0bV9tZW1fZ2xvYmFsX3JlbGVhc2Uoc3RydWN0 IGRybV9nbG9iYWxfcmVmZXJlbmNlICpyZWYpCj4gK3sKPiArCXR0bV9tZW1fZ2xvYmFsX3JlbGVh c2UocmVmLT5vYmplY3QpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHZpcnRpb19ncHVfdHRtX2ds b2JhbF9pbml0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYpCj4gK3sKPiArCXN0cnVj dCBkcm1fZ2xvYmFsX3JlZmVyZW5jZSAqZ2xvYmFsX3JlZjsKPiArCWludCByOwo+ICsKPiArCXZn ZGV2LT5tbWFuLm1lbV9nbG9iYWxfcmVmZXJlbmNlZCA9IGZhbHNlOwo+ICsJZ2xvYmFsX3JlZiA9 ICZ2Z2Rldi0+bW1hbi5tZW1fZ2xvYmFsX3JlZjsKPiArCWdsb2JhbF9yZWYtPmdsb2JhbF90eXBl ID0gRFJNX0dMT0JBTF9UVE1fTUVNOwo+ICsJZ2xvYmFsX3JlZi0+c2l6ZSA9IHNpemVvZihzdHJ1 Y3QgdHRtX21lbV9nbG9iYWwpOwo+ICsJZ2xvYmFsX3JlZi0+aW5pdCA9ICZ2aXJ0aW9fZ3B1X3R0 bV9tZW1fZ2xvYmFsX2luaXQ7Cj4gKwlnbG9iYWxfcmVmLT5yZWxlYXNlID0gJnZpcnRpb19ncHVf dHRtX21lbV9nbG9iYWxfcmVsZWFzZTsKPiArCj4gKwlyID0gZHJtX2dsb2JhbF9pdGVtX3JlZihn bG9iYWxfcmVmKTsKPiArCWlmIChyICE9IDApIHsKPiArCQlEUk1fRVJST1IoIkZhaWxlZCBzZXR0 aW5nIHVwIFRUTSBtZW1vcnkgYWNjb3VudGluZyAiCj4gKwkJCSAgInN1YnN5c3RlbS5cbiIpOwo+ ICsJCXJldHVybiByOwo+ICsJfQo+ICsKPiArCXZnZGV2LT5tbWFuLmJvX2dsb2JhbF9yZWYubWVt X2dsb2IgPQo+ICsJCXZnZGV2LT5tbWFuLm1lbV9nbG9iYWxfcmVmLm9iamVjdDsKPiArCWdsb2Jh bF9yZWYgPSAmdmdkZXYtPm1tYW4uYm9fZ2xvYmFsX3JlZi5yZWY7Cj4gKwlnbG9iYWxfcmVmLT5n bG9iYWxfdHlwZSA9IERSTV9HTE9CQUxfVFRNX0JPOwo+ICsJZ2xvYmFsX3JlZi0+c2l6ZSA9IHNp emVvZihzdHJ1Y3QgdHRtX2JvX2dsb2JhbCk7Cj4gKwlnbG9iYWxfcmVmLT5pbml0ID0gJnR0bV9i b19nbG9iYWxfaW5pdDsKPiArCWdsb2JhbF9yZWYtPnJlbGVhc2UgPSAmdHRtX2JvX2dsb2JhbF9y ZWxlYXNlOwo+ICsJciA9IGRybV9nbG9iYWxfaXRlbV9yZWYoZ2xvYmFsX3JlZik7Cj4gKwlpZiAo ciAhPSAwKSB7Cj4gKwkJRFJNX0VSUk9SKCJGYWlsZWQgc2V0dGluZyB1cCBUVE0gQk8gc3Vic3lz dGVtLlxuIik7Cj4gKwkJZHJtX2dsb2JhbF9pdGVtX3VucmVmKCZ2Z2Rldi0+bW1hbi5tZW1fZ2xv YmFsX3JlZik7Cj4gKwkJcmV0dXJuIHI7Cj4gKwl9Cj4gKwo+ICsJdmdkZXYtPm1tYW4ubWVtX2ds b2JhbF9yZWZlcmVuY2VkID0gdHJ1ZTsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dm9pZCB2aXJ0aW9fZ3B1X3R0bV9nbG9iYWxfZmluaShzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2Ug KnZnZGV2KQo+ICt7Cj4gKwlpZiAodmdkZXYtPm1tYW4ubWVtX2dsb2JhbF9yZWZlcmVuY2VkKSB7 Cj4gKwkJZHJtX2dsb2JhbF9pdGVtX3VucmVmKCZ2Z2Rldi0+bW1hbi5ib19nbG9iYWxfcmVmLnJl Zik7Cj4gKwkJZHJtX2dsb2JhbF9pdGVtX3VucmVmKCZ2Z2Rldi0+bW1hbi5tZW1fZ2xvYmFsX3Jl Zik7Cj4gKwkJdmdkZXYtPm1tYW4ubWVtX2dsb2JhbF9yZWZlcmVuY2VkID0gZmFsc2U7Cj4gKwl9 Cj4gK30KPiArCj4gKyNpZiAwCj4gKy8qCj4gKyAqIEhtbSwgc2VlbXMgdG8gbm90IGRvIGFueXRo aW5nIHVzZWZ1bC4gIExlZnRvdmVyIGRlYnVnIGhhY2s/Cj4gKyAqIFNvbWV0aGluZyBsaWtlIHBy aW50aW5nIHBhZ2VmYXVsdHMgdG8ga2VybmVsIGxvZz8KPiArICovCj4gK3N0YXRpYyBzdHJ1Y3Qg dm1fb3BlcmF0aW9uc19zdHJ1Y3QgdmlydGlvX2dwdV90dG1fdm1fb3BzOwo+ICtzdGF0aWMgY29u c3Qgc3RydWN0IHZtX29wZXJhdGlvbnNfc3RydWN0ICp0dG1fdm1fb3BzOwo+ICsKPiArc3RhdGlj IGludCB2aXJ0aW9fZ3B1X3R0bV9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwKPiAr CQkJCXN0cnVjdCB2bV9mYXVsdCAqdm1mKQo+ICt7Cj4gKwlzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmpl Y3QgKmJvOwo+ICsJc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldjsKPiArCWludCByOwo+ ICsKPiArCWJvID0gKHN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqKXZtYS0+dm1fcHJpdmF0ZV9k YXRhOwo+ICsJaWYgKGJvID09IE5VTEwpCj4gKwkJcmV0dXJuIFZNX0ZBVUxUX05PUEFHRTsKPiAr CXZnZGV2ID0gdmlydGlvX2dwdV9nZXRfdmdkZXYoYm8tPmJkZXYpOwo+ICsJciA9IHR0bV92bV9v cHMtPmZhdWx0KHZtYSwgdm1mKTsKPiArCXJldHVybiByOwo+ICt9Cj4gKyNlbmRpZgo+ICsKPiAr aW50IHZpcnRpb19ncHVfbW1hcChzdHJ1Y3QgZmlsZSAqZmlscCwgc3RydWN0IHZtX2FyZWFfc3Ry dWN0ICp2bWEpCj4gK3sKPiArCXN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2Owo+ICsJc3RydWN0 IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldjsKPiArCWludCByOwo+ICsKPiArCWZpbGVfcHJpdiA9 IGZpbHAtPnByaXZhdGVfZGF0YTsKPiArCXZnZGV2ID0gZmlsZV9wcml2LT5taW5vci0+ZGV2LT5k ZXZfcHJpdmF0ZTsKPiArCWlmICh2Z2RldiA9PSBOVUxMKSB7Cj4gKwkJRFJNX0VSUk9SKAo+ICsJ CSAiZmlscC0+cHJpdmF0ZV9kYXRhLT5taW5vci0+ZGV2LT5kZXZfcHJpdmF0ZSA9PSBOVUxMXG4i KTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCXIgPSB0dG1fYm9fbW1hcChmaWxwLCB2 bWEsICZ2Z2Rldi0+bW1hbi5iZGV2KTsKPiArI2lmIDAKPiArCWlmICh1bmxpa2VseShyICE9IDAp KQo+ICsJCXJldHVybiByOwo+ICsJaWYgKHVubGlrZWx5KHR0bV92bV9vcHMgPT0gTlVMTCkpIHsK PiArCQl0dG1fdm1fb3BzID0gdm1hLT52bV9vcHM7Cj4gKwkJdmlydGlvX2dwdV90dG1fdm1fb3Bz ID0gKnR0bV92bV9vcHM7Cj4gKwkJdmlydGlvX2dwdV90dG1fdm1fb3BzLmZhdWx0ID0gJnZpcnRp b19ncHVfdHRtX2ZhdWx0Owo+ICsJfQo+ICsJdm1hLT52bV9vcHMgPSAmdmlydGlvX2dwdV90dG1f dm1fb3BzOwo+ICsJcmV0dXJuIDA7Cj4gKyNlbHNlCj4gKwlyZXR1cm4gcjsKPiArI2VuZGlmCj4g K30KPiArCj4gK3N0YXRpYyBpbnQgdmlydGlvX2dwdV9pbnZhbGlkYXRlX2NhY2hlcyhzdHJ1Y3Qg dHRtX2JvX2RldmljZSAqYmRldiwKPiArCQkJCQl1aW50MzJfdCBmbGFncykKPiArewo+ICsJcmV0 dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdHRtX2JvX21hbl9nZXRfbm9kZShzdHJ1Y3Qg dHRtX21lbV90eXBlX21hbmFnZXIgKm1hbiwKPiArCQkJICAgICAgIHN0cnVjdCB0dG1fYnVmZmVy X29iamVjdCAqYm8sCj4gKwkJCSAgICAgICBjb25zdCBzdHJ1Y3QgdHRtX3BsYWNlICpwbGFjZSwK PiArCQkJICAgICAgIHN0cnVjdCB0dG1fbWVtX3JlZyAqbWVtKQo+ICt7Cj4gKwltZW0tPm1tX25v ZGUgPSAodm9pZCAqKTE7Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdHRt X2JvX21hbl9wdXRfbm9kZShzdHJ1Y3QgdHRtX21lbV90eXBlX21hbmFnZXIgKm1hbiwKPiArCQkJ CXN0cnVjdCB0dG1fbWVtX3JlZyAqbWVtKQo+ICt7Cj4gKwltZW0tPm1tX25vZGUgPSAodm9pZCAq KU5VTEw7Cj4gKwlyZXR1cm47Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdHRtX2JvX21hbl9pbml0 KHN0cnVjdCB0dG1fbWVtX3R5cGVfbWFuYWdlciAqbWFuLAo+ICsJCQkgICB1bnNpZ25lZCBsb25n IHBfc2l6ZSkKPiArewo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdHRtX2Jv X21hbl90YWtlZG93bihzdHJ1Y3QgdHRtX21lbV90eXBlX21hbmFnZXIgKm1hbikKPiArewo+ICsJ cmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHR0bV9ib19tYW5fZGVidWcoc3RydWN0 IHR0bV9tZW1fdHlwZV9tYW5hZ2VyICptYW4sCj4gKwkJCSAgICAgY29uc3QgY2hhciAqcHJlZml4 KQo+ICt7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdHRtX21lbV90eXBlX21hbmFn ZXJfZnVuYyB2aXJ0aW9fZ3B1X2JvX21hbmFnZXJfZnVuYyA9IHsKPiArCXR0bV9ib19tYW5faW5p dCwKPiArCXR0bV9ib19tYW5fdGFrZWRvd24sCj4gKwl0dG1fYm9fbWFuX2dldF9ub2RlLAo+ICsJ dHRtX2JvX21hbl9wdXRfbm9kZSwKPiArCXR0bV9ib19tYW5fZGVidWcKPiArfTsKPiArCj4gK3N0 YXRpYyBpbnQgdmlydGlvX2dwdV9pbml0X21lbV90eXBlKHN0cnVjdCB0dG1fYm9fZGV2aWNlICpi ZGV2LCB1aW50MzJfdCB0eXBlLAo+ICsJCQkJICAgIHN0cnVjdCB0dG1fbWVtX3R5cGVfbWFuYWdl ciAqbWFuKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2Owo+ICsKPiAr CXZnZGV2ID0gdmlydGlvX2dwdV9nZXRfdmdkZXYoYmRldik7Cj4gKwo+ICsJc3dpdGNoICh0eXBl KSB7Cj4gKwljYXNlIFRUTV9QTF9TWVNURU06Cj4gKwkJLyogU3lzdGVtIG1lbW9yeSAqLwo+ICsJ CW1hbi0+ZmxhZ3MgPSBUVE1fTUVNVFlQRV9GTEFHX01BUFBBQkxFOwo+ICsJCW1hbi0+YXZhaWxh YmxlX2NhY2hpbmcgPSBUVE1fUExfTUFTS19DQUNISU5HOwo+ICsJCW1hbi0+ZGVmYXVsdF9jYWNo aW5nID0gVFRNX1BMX0ZMQUdfQ0FDSEVEOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBUVE1fUExfVFQ6 Cj4gKwkJbWFuLT5mdW5jID0gJnZpcnRpb19ncHVfYm9fbWFuYWdlcl9mdW5jOwo+ICsJCW1hbi0+ ZmxhZ3MgPSBUVE1fTUVNVFlQRV9GTEFHX01BUFBBQkxFOwo+ICsJCW1hbi0+YXZhaWxhYmxlX2Nh Y2hpbmcgPSBUVE1fUExfTUFTS19DQUNISU5HOwo+ICsJCW1hbi0+ZGVmYXVsdF9jYWNoaW5nID0g VFRNX1BMX0ZMQUdfQ0FDSEVEOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlEUk1fRVJS T1IoIlVuc3VwcG9ydGVkIG1lbW9yeSB0eXBlICV1XG4iLCAodW5zaWduZWQpdHlwZSk7Cj4gKwkJ cmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZv aWQgdmlydGlvX2dwdV9ldmljdF9mbGFncyhzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QgKmJvLAo+ ICsJCQkJc3RydWN0IHR0bV9wbGFjZW1lbnQgKnBsYWNlbWVudCkKPiArewo+ICsJc3RhdGljIHN0 cnVjdCB0dG1fcGxhY2UgcGxhY2VtZW50cyA9IHsKPiArCQkuZnBmbiAgPSAwLAo+ICsJCS5scGZu ICA9IDAsCj4gKwkJLmZsYWdzID0gVFRNX1BMX01BU0tfQ0FDSElORyB8IFRUTV9QTF9GTEFHX1NZ U1RFTSwKPiArCX07Cj4gKwo+ICsJcGxhY2VtZW50LT5wbGFjZW1lbnQgPSAmcGxhY2VtZW50czsK PiArCXBsYWNlbWVudC0+YnVzeV9wbGFjZW1lbnQgPSAmcGxhY2VtZW50czsKPiArCXBsYWNlbWVu dC0+bnVtX3BsYWNlbWVudCA9IDE7Cj4gKwlwbGFjZW1lbnQtPm51bV9idXN5X3BsYWNlbWVudCA9 IDE7Cj4gKwlyZXR1cm47Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdmlydGlvX2dwdV92ZXJpZnlf YWNjZXNzKHN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqYm8sCj4gKwkJCQkgICAgc3RydWN0IGZp bGUgKmZpbHApCj4gK3sKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHZpcnRp b19ncHVfdHRtX2lvX21lbV9yZXNlcnZlKHN0cnVjdCB0dG1fYm9fZGV2aWNlICpiZGV2LAo+ICsJ CQkJCSBzdHJ1Y3QgdHRtX21lbV9yZWcgKm1lbSkKPiArewo+ICsJc3RydWN0IHR0bV9tZW1fdHlw ZV9tYW5hZ2VyICptYW4gPSAmYmRldi0+bWFuW21lbS0+bWVtX3R5cGVdOwo+ICsKPiArCW1lbS0+ YnVzLmFkZHIgPSBOVUxMOwo+ICsJbWVtLT5idXMub2Zmc2V0ID0gMDsKPiArCW1lbS0+YnVzLnNp emUgPSBtZW0tPm51bV9wYWdlcyA8PCBQQUdFX1NISUZUOwo+ICsJbWVtLT5idXMuYmFzZSA9IDA7 Cj4gKwltZW0tPmJ1cy5pc19pb21lbSA9IGZhbHNlOwo+ICsJaWYgKCEobWFuLT5mbGFncyAmIFRU TV9NRU1UWVBFX0ZMQUdfTUFQUEFCTEUpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJc3dpdGNo IChtZW0tPm1lbV90eXBlKSB7Cj4gKwljYXNlIFRUTV9QTF9TWVNURU06Cj4gKwljYXNlIFRUTV9Q TF9UVDoKPiArCQkvKiBzeXN0ZW0gbWVtb3J5ICovCj4gKwkJcmV0dXJuIDA7Cj4gKwlkZWZhdWx0 Ogo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0 YXRpYyB2b2lkIHZpcnRpb19ncHVfdHRtX2lvX21lbV9mcmVlKHN0cnVjdCB0dG1fYm9fZGV2aWNl ICpiZGV2LAo+ICsJCQkJICAgICAgIHN0cnVjdCB0dG1fbWVtX3JlZyAqbWVtKQo+ICt7Cj4gK30K PiArCj4gKy8qCj4gKyAqIFRUTSBiYWNrZW5kIGZ1bmN0aW9ucy4KPiArICovCj4gK3N0cnVjdCB2 aXJ0aW9fZ3B1X3R0bV90dCB7Cj4gKwlzdHJ1Y3QgdHRtX2RtYV90dAkJdHRtOwo+ICsJc3RydWN0 IHZpcnRpb19ncHVfZGV2aWNlCSp2Z2RldjsKPiArCXU2NAkJCQlvZmZzZXQ7Cj4gK307Cj4gKwo+ ICtzdGF0aWMgaW50IHZpcnRpb19ncHVfdHRtX2JhY2tlbmRfYmluZChzdHJ1Y3QgdHRtX3R0ICp0 dG0sCj4gKwkJCQkgICAgICAgc3RydWN0IHR0bV9tZW1fcmVnICpib19tZW0pCj4gK3sKPiArCXN0 cnVjdCB2aXJ0aW9fZ3B1X3R0bV90dCAqZ3R0ID0gKHZvaWQgKil0dG07Cj4gKwo+ICsJZ3R0LT5v ZmZzZXQgPSAodW5zaWduZWQgbG9uZykoYm9fbWVtLT5zdGFydCA8PCBQQUdFX1NISUZUKTsKPiAr CWlmICghdHRtLT5udW1fcGFnZXMpCj4gKwkJV0FSTigxLCAibm90aGluZyB0byBiaW5kICVsdSBw YWdlcyBmb3IgbXJlZyAlcCBiYWNrICVwIVxuIiwKPiArCQkgICAgIHR0bS0+bnVtX3BhZ2VzLCBi b19tZW0sIHR0bSk7Cj4gKwo+ICsJLyogTm90IGltcGxlbWVudGVkICovCj4gKwlyZXR1cm4gMDsK PiArfQo+ICsKPiArc3RhdGljIGludCB2aXJ0aW9fZ3B1X3R0bV9iYWNrZW5kX3VuYmluZChzdHJ1 Y3QgdHRtX3R0ICp0dG0pCj4gK3sKPiArCS8qIE5vdCBpbXBsZW1lbnRlZCAqLwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfdHRtX2JhY2tlbmRfZGVzdHJv eShzdHJ1Y3QgdHRtX3R0ICp0dG0pCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3R0bV90dCAq Z3R0ID0gKHZvaWQgKil0dG07Cj4gKwo+ICsJdHRtX2RtYV90dF9maW5pKCZndHQtPnR0bSk7Cj4g KwlrZnJlZShndHQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHR0bV9iYWNrZW5kX2Z1bmMg dmlydGlvX2dwdV9iYWNrZW5kX2Z1bmMgPSB7Cj4gKwkuYmluZCA9ICZ2aXJ0aW9fZ3B1X3R0bV9i YWNrZW5kX2JpbmQsCj4gKwkudW5iaW5kID0gJnZpcnRpb19ncHVfdHRtX2JhY2tlbmRfdW5iaW5k LAo+ICsJLmRlc3Ryb3kgPSAmdmlydGlvX2dwdV90dG1fYmFja2VuZF9kZXN0cm95LAo+ICt9Owo+ ICsKPiArc3RhdGljIGludCB2aXJ0aW9fZ3B1X3R0bV90dF9wb3B1bGF0ZShzdHJ1Y3QgdHRtX3R0 ICp0dG0pCj4gK3sKPiArCWlmICh0dG0tPnN0YXRlICE9IHR0X3VucG9wdWxhdGVkKQo+ICsJCXJl dHVybiAwOwo+ICsKPiArCXJldHVybiB0dG1fcG9vbF9wb3B1bGF0ZSh0dG0pOwo+ICt9Cj4gKwo+ ICtzdGF0aWMgdm9pZCB2aXJ0aW9fZ3B1X3R0bV90dF91bnBvcHVsYXRlKHN0cnVjdCB0dG1fdHQg KnR0bSkKPiArewo+ICsJdHRtX3Bvb2xfdW5wb3B1bGF0ZSh0dG0pOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgc3RydWN0IHR0bV90dCAqdmlydGlvX2dwdV90dG1fdHRfY3JlYXRlKHN0cnVjdCB0dG1fYm9f ZGV2aWNlICpiZGV2LAo+ICsJCQkJCSAgICAgICB1bnNpZ25lZCBsb25nIHNpemUsCj4gKwkJCQkJ ICAgICAgIHVpbnQzMl90IHBhZ2VfZmxhZ3MsCj4gKwkJCQkJICAgICAgIHN0cnVjdCBwYWdlICpk dW1teV9yZWFkX3BhZ2UpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXY7 Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV90dG1fdHQgKmd0dDsKPiArCj4gKwl2Z2RldiA9IHZpcnRp b19ncHVfZ2V0X3ZnZGV2KGJkZXYpOwo+ICsJZ3R0ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHZp cnRpb19ncHVfdHRtX3R0KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoZ3R0ID09IE5VTEwpCj4gKwkJ cmV0dXJuIE5VTEw7Cj4gKwlndHQtPnR0bS50dG0uZnVuYyA9ICZ2aXJ0aW9fZ3B1X2JhY2tlbmRf ZnVuYzsKPiArCWd0dC0+dmdkZXYgPSB2Z2RldjsKPiArCWlmICh0dG1fZG1hX3R0X2luaXQoJmd0 dC0+dHRtLCBiZGV2LCBzaXplLCBwYWdlX2ZsYWdzLAo+ICsJCQkgICAgZHVtbXlfcmVhZF9wYWdl KSkgewo+ICsJCWtmcmVlKGd0dCk7Cj4gKwkJcmV0dXJuIE5VTEw7Cj4gKwl9Cj4gKwlyZXR1cm4g Jmd0dC0+dHRtLnR0bTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmlydGlvX2dwdV9tb3ZlX251 bGwoc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICpibywKPiArCQkJCSBzdHJ1Y3QgdHRtX21lbV9y ZWcgKm5ld19tZW0pCj4gK3sKPiArCXN0cnVjdCB0dG1fbWVtX3JlZyAqb2xkX21lbSA9ICZiby0+ bWVtOwo+ICsKPiArCUJVR19PTihvbGRfbWVtLT5tbV9ub2RlICE9IE5VTEwpOwo+ICsJKm9sZF9t ZW0gPSAqbmV3X21lbTsKPiArCW5ld19tZW0tPm1tX25vZGUgPSBOVUxMOwo+ICt9Cj4gKwo+ICtz dGF0aWMgaW50IHZpcnRpb19ncHVfYm9fbW92ZShzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QgKmJv LAo+ICsJCQkgICAgICBib29sIGV2aWN0LCBib29sIGludGVycnVwdGlibGUsCj4gKwkJCSAgICAg IGJvb2wgbm9fd2FpdF9ncHUsCj4gKwkJCSAgICAgIHN0cnVjdCB0dG1fbWVtX3JlZyAqbmV3X21l bSkKPiArewo+ICsJdmlydGlvX2dwdV9tb3ZlX251bGwoYm8sIG5ld19tZW0pOwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfYm9fbW92ZV9ub3RpZnkoc3Ry dWN0IHR0bV9idWZmZXJfb2JqZWN0ICp0Ym8sCj4gKwkJCQkgICAgICBzdHJ1Y3QgdHRtX21lbV9y ZWcgKm5ld19tZW0pCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm87Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2Owo+ICsKPiArCWJvID0gY29udGFpbmVyX29m KHRibywgc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0LCB0Ym8pOwo+ICsJdmdkZXYgPSAoc3RydWN0 IHZpcnRpb19ncHVfZGV2aWNlICopYm8tPmdlbV9iYXNlLmRldi0+ZGV2X3ByaXZhdGU7Cj4gKwo+ ICsJaWYgKCFuZXdfbWVtIHx8IChuZXdfbWVtLT5wbGFjZW1lbnQgJiBUVE1fUExfRkxBR19TWVNU RU0pKSB7Cj4gKwkJaWYgKGJvLT5od19yZXNfaGFuZGxlKQo+ICsJCQl2aXJ0aW9fZ3B1X2NtZF9y ZXNvdXJjZV9pbnZhbF9iYWNraW5nKHZnZGV2LAo+ICsJCQkJCQkJICAgYm8tPmh3X3Jlc19oYW5k bGUpOwo+ICsKPiArCX0gZWxzZSBpZiAobmV3X21lbS0+cGxhY2VtZW50ICYgVFRNX1BMX0ZMQUdf VFQpIHsKPiArCQlpZiAoYm8tPmh3X3Jlc19oYW5kbGUpIHsKPiArCQkJdmlydGlvX2dwdV9vYmpl Y3RfYXR0YWNoKHZnZGV2LCBibywgYm8tPmh3X3Jlc19oYW5kbGUsCj4gKwkJCQkJCSBOVUxMKTsK PiArCQl9Cj4gKwl9Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfYm9fc3dhcF9u b3RpZnkoc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICp0Ym8pCj4gK3sKPiArCXN0cnVjdCB2aXJ0 aW9fZ3B1X29iamVjdCAqYm87Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2Owo+ ICsKPiArCWJvID0gY29udGFpbmVyX29mKHRibywgc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0LCB0 Ym8pOwo+ICsJdmdkZXYgPSAoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICopYm8tPmdlbV9iYXNl LmRldi0+ZGV2X3ByaXZhdGU7Cj4gKwo+ICsJaWYgKGJvLT5wYWdlcykKPiArCQl2aXJ0aW9fZ3B1 X29iamVjdF9mcmVlX3NnX3RhYmxlKGJvKTsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCB0dG1f Ym9fZHJpdmVyIHZpcnRpb19ncHVfYm9fZHJpdmVyID0gewo+ICsJLnR0bV90dF9jcmVhdGUgPSAm dmlydGlvX2dwdV90dG1fdHRfY3JlYXRlLAo+ICsJLnR0bV90dF9wb3B1bGF0ZSA9ICZ2aXJ0aW9f Z3B1X3R0bV90dF9wb3B1bGF0ZSwKPiArCS50dG1fdHRfdW5wb3B1bGF0ZSA9ICZ2aXJ0aW9fZ3B1 X3R0bV90dF91bnBvcHVsYXRlLAo+ICsJLmludmFsaWRhdGVfY2FjaGVzID0gJnZpcnRpb19ncHVf aW52YWxpZGF0ZV9jYWNoZXMsCj4gKwkuaW5pdF9tZW1fdHlwZSA9ICZ2aXJ0aW9fZ3B1X2luaXRf bWVtX3R5cGUsCj4gKwkuZXZpY3RfZmxhZ3MgPSAmdmlydGlvX2dwdV9ldmljdF9mbGFncywKPiAr CS5tb3ZlID0gJnZpcnRpb19ncHVfYm9fbW92ZSwKPiArCS52ZXJpZnlfYWNjZXNzID0gJnZpcnRp b19ncHVfdmVyaWZ5X2FjY2VzcywKPiArCS5pb19tZW1fcmVzZXJ2ZSA9ICZ2aXJ0aW9fZ3B1X3R0 bV9pb19tZW1fcmVzZXJ2ZSwKPiArCS5pb19tZW1fZnJlZSA9ICZ2aXJ0aW9fZ3B1X3R0bV9pb19t ZW1fZnJlZSwKPiArCS5tb3ZlX25vdGlmeSA9ICZ2aXJ0aW9fZ3B1X2JvX21vdmVfbm90aWZ5LAo+ ICsJLnN3YXBfbm90aWZ5ID0gJnZpcnRpb19ncHVfYm9fc3dhcF9ub3RpZnksCj4gK307Cj4gKwo+ ICtpbnQgdmlydGlvX2dwdV90dG1faW5pdChzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2 KQo+ICt7Cj4gKwlpbnQgcjsKPiArCj4gKwlyID0gdmlydGlvX2dwdV90dG1fZ2xvYmFsX2luaXQo dmdkZXYpOwo+ICsJaWYgKHIpCj4gKwkJcmV0dXJuIHI7Cj4gKwkvKiBObyBvdGhlcnMgdXNlciBv ZiBhZGRyZXNzIHNwYWNlIHNvIHNldCBpdCB0byAwICovCj4gKwlyID0gdHRtX2JvX2RldmljZV9p bml0KCZ2Z2Rldi0+bW1hbi5iZGV2LAo+ICsJCQkgICAgICAgdmdkZXYtPm1tYW4uYm9fZ2xvYmFs X3JlZi5yZWYub2JqZWN0LAo+ICsJCQkgICAgICAgJnZpcnRpb19ncHVfYm9fZHJpdmVyLAo+ICsJ CQkgICAgICAgdmdkZXYtPmRkZXYtPmFub25faW5vZGUtPmlfbWFwcGluZywKPiArCQkJICAgICAg IERSTV9GSUxFX1BBR0VfT0ZGU0VULCAwKTsKPiArCWlmIChyKSB7Cj4gKwkJRFJNX0VSUk9SKCJm YWlsZWQgaW5pdGlhbGl6aW5nIGJ1ZmZlciBvYmplY3QgZHJpdmVyKCVkKS5cbiIsIHIpOwo+ICsJ CWdvdG8gZXJyX2Rldl9pbml0Owo+ICsJCXJldHVybiByOwo+ICsJfQo+ICsKPiArCXIgPSB0dG1f Ym9faW5pdF9tbSgmdmdkZXYtPm1tYW4uYmRldiwgVFRNX1BMX1RULCAwKTsKPiArCWlmIChyKSB7 Cj4gKwkJRFJNX0VSUk9SKCJGYWlsZWQgaW5pdGlhbGl6aW5nIEdUVCBoZWFwLlxuIik7Cj4gKwkJ Z290byBlcnJfbW1faW5pdDsKPiArCQlyZXR1cm4gcjsKPiArCX0KPiArCXJldHVybiAwOwo+ICsK PiArZXJyX21tX2luaXQ6Cj4gKwl0dG1fYm9fZGV2aWNlX3JlbGVhc2UoJnZnZGV2LT5tbWFuLmJk ZXYpOwo+ICtlcnJfZGV2X2luaXQ6Cj4gKwl2aXJ0aW9fZ3B1X3R0bV9nbG9iYWxfZmluaSh2Z2Rl dik7Cj4gKwlyZXR1cm4gcjsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9fZ3B1X3R0bV9maW5pKHN0 cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYpCj4gK3sKPiArCXR0bV9ib19kZXZpY2VfcmVs ZWFzZSgmdmdkZXYtPm1tYW4uYmRldik7Cj4gKwl2aXJ0aW9fZ3B1X3R0bV9nbG9iYWxfZmluaSh2 Z2Rldik7Cj4gKwlEUk1fSU5GTygidmlydGlvX2dwdTogdHRtIGZpbmFsaXplZFxuIik7Cj4gK30K PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X3ZxLmMgYi9kcml2 ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfdnEuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4g aW5kZXggMDAwMDAwMC4uOGZhNjUxM2UKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL3ZpcnRpby92aXJ0Z3B1X3ZxLmMKPiBAQCAtMCwwICsxLDYxNCBAQAo+ICsvKgo+ICsg KiBDb3B5cmlnaHQgKEMpIDIwMTUgUmVkIEhhdCwgSW5jLgo+ICsgKiBBbGwgUmlnaHRzIFJlc2Vy dmVkLgo+ICsgKgo+ICsgKiBBdXRob3JzOgo+ICsgKiAgICBEYXZlIEFpcmxpZSA8YWlybGllZEBy ZWRoYXQuY29tPgo+ICsgKiAgICBHZXJkIEhvZmZtYW5uIDxrcmF4ZWxAcmVkaGF0LmNvbT4KPiAr ICoKPiArICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRv IGFueSBwZXJzb24gb2J0YWluaW5nIGEKPiArICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBh c3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKPiArICogdG8g ZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhv dXQgbGltaXRhdGlvbgo+ICsgKiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJn ZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKPiArICogYW5kL29yIHNlbGwgY29w aWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlCj4g KyAqIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93 aW5nIGNvbmRpdGlvbnM6Cj4gKyAqCj4gKyAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFu ZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlIG5leHQKPiArICogcGFyYWdy YXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRp b25zIG9mIHRoZQo+ICsgKiBTb2Z0d2FyZS4KPiArICoKPiArICogVEhFIFNPRlRXQVJFIElTIFBS T1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IK PiArICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElF UyBPRiBNRVJDSEFOVEFCSUxJVFksCj4gKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQ T1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTAo+ICsgKiBWQSBMSU5V WCBTWVNURU1TIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBE QU1BR0VTIE9SCj4gKyAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0Yg Q09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAo+ICsgKiBBUklTSU5HIEZST00sIE9VVCBPRiBP UiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IKPiArICogT1RI RVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxkcm0v ZHJtUC5oPgo+ICsjaW5jbHVkZSAidmlydGdwdV9kcnYuaCIKPiArI2luY2x1ZGUgPGxpbnV4L3Zp cnRpby5oPgo+ICsjaW5jbHVkZSA8bGludXgvdmlydGlvX2NvbmZpZy5oPgo+ICsjaW5jbHVkZSA8 bGludXgvdmlydGlvX3JpbmcuaD4KPiArCj4gKyNkZWZpbmUgTUFYX0lOTElORV9DTURfU0laRSAg IDk2Cj4gKyNkZWZpbmUgTUFYX0lOTElORV9SRVNQX1NJWkUgIDI0Cj4gKyNkZWZpbmUgVkJVRkZF Ul9TSVpFICAgICAgICAgIChzaXplb2Yoc3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZlcikgXAo+ICsJ CQkgICAgICAgKyBNQVhfSU5MSU5FX0NNRF9TSVpFCQkgXAo+ICsJCQkgICAgICAgKyBNQVhfSU5M SU5FX1JFU1BfU0laRSkKPiArCj4gK3ZvaWQgdmlydGlvX2dwdV9yZXNvdXJjZV9pZF9nZXQoc3Ry dWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCXVpbnQzMl90ICpyZXNpZCkKPiAr ewo+ICsJaW50IGhhbmRsZTsKPiArCj4gKwlpZHJfcHJlbG9hZChHRlBfS0VSTkVMKTsKPiArCXNw aW5fbG9jaygmdmdkZXYtPnJlc291cmNlX2lkcl9sb2NrKTsKPiArCWhhbmRsZSA9IGlkcl9hbGxv YygmdmdkZXYtPnJlc291cmNlX2lkciwgTlVMTCwgMSwgMCwgR0ZQX05PV0FJVCk7Cj4gKwlzcGlu X3VubG9jaygmdmdkZXYtPnJlc291cmNlX2lkcl9sb2NrKTsKPiArCWlkcl9wcmVsb2FkX2VuZCgp Owo+ICsJKnJlc2lkID0gaGFuZGxlOwo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVfcmVzb3Vy Y2VfaWRfcHV0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsIHVpbnQzMl90IGlkKQo+ ICt7Cj4gKwlzcGluX2xvY2soJnZnZGV2LT5yZXNvdXJjZV9pZHJfbG9jayk7Cj4gKwlpZHJfcmVt b3ZlKCZ2Z2Rldi0+cmVzb3VyY2VfaWRyLCBpZCk7Cj4gKwlzcGluX3VubG9jaygmdmdkZXYtPnJl c291cmNlX2lkcl9sb2NrKTsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9fZ3B1X2N0cmxfYWNrKHN0 cnVjdCB2aXJ0cXVldWUgKnZxKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gdnEt PnZkZXYtPnByaXY7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2ID0gZGV2LT5k ZXZfcHJpdmF0ZTsKPiArCXNjaGVkdWxlX3dvcmsoJnZnZGV2LT5jdHJscS5kZXF1ZXVlX3dvcmsp Owo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVfY3Vyc29yX2FjayhzdHJ1Y3QgdmlydHF1ZXVl ICp2cSkKPiArewo+ICsJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9IHZxLT52ZGV2LT5wcml2Owo+ ICsJc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiA9IGRldi0+ZGV2X3ByaXZhdGU7Cj4g KwlzY2hlZHVsZV93b3JrKCZ2Z2Rldi0+Y3Vyc29ycS5kZXF1ZXVlX3dvcmspOwo+ICt9Cj4gKwo+ ICtpbnQgdmlydGlvX2dwdV9hbGxvY192YnVmcyhzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZn ZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV92YnVmZmVyICp2YnVmOwo+ICsJaW50IGks IHNpemUsIGNvdW50ID0gMDsKPiArCXZvaWQgKnB0cjsKPiArCj4gKwlJTklUX0xJU1RfSEVBRCgm dmdkZXYtPmZyZWVfdmJ1ZnMpOwo+ICsJY291bnQgKz0gdmlydHF1ZXVlX2dldF92cmluZ19zaXpl KHZnZGV2LT5jdHJscS52cSk7Cj4gKwljb3VudCArPSB2aXJ0cXVldWVfZ2V0X3ZyaW5nX3NpemUo dmdkZXYtPmN1cnNvcnEudnEpOwo+ICsJc2l6ZSA9IGNvdW50ICogVkJVRkZFUl9TSVpFOwo+ICsJ RFJNX0lORk8oInZpcnRpbyB2YnVmZmVyczogJWQgYnVmcywgJXpkQiBlYWNoLCAlZGtCIHRvdGFs LlxuIiwKPiArCQkgY291bnQsIFZCVUZGRVJfU0laRSwgc2l6ZSAvIDEwMjQpOwo+ICsKPiArCXZn ZGV2LT52YnVmcyA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXZnZGV2LT52 YnVmcykKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlmb3IgKGkgPSAwLCBwdHIgPSB2Z2Rl di0+dmJ1ZnM7Cj4gKwkgICAgIGkgPCBjb3VudDsKPiArCSAgICAgaSsrLCBwdHIgKz0gVkJVRkZF Ul9TSVpFKSB7Cj4gKwkJdmJ1ZiA9IHB0cjsKPiArCQlsaXN0X2FkZCgmdmJ1Zi0+bGlzdCwgJnZn ZGV2LT5mcmVlX3ZidWZzKTsKPiArCX0KPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICt2b2lkIHZp cnRpb19ncHVfZnJlZV92YnVmcyhzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2KQo+ICt7 Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV92YnVmZmVyICp2YnVmOwo+ICsJaW50IGksIGNvdW50ID0g MDsKPiArCj4gKwljb3VudCArPSB2aXJ0cXVldWVfZ2V0X3ZyaW5nX3NpemUodmdkZXYtPmN0cmxx LnZxKTsKPiArCWNvdW50ICs9IHZpcnRxdWV1ZV9nZXRfdnJpbmdfc2l6ZSh2Z2Rldi0+Y3Vyc29y cS52cSk7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKPiArCQlpZiAoV0FS Tl9PTihsaXN0X2VtcHR5KCZ2Z2Rldi0+ZnJlZV92YnVmcykpKQo+ICsJCQlyZXR1cm47Cj4gKwkJ dmJ1ZiA9IGxpc3RfZmlyc3RfZW50cnkoJnZnZGV2LT5mcmVlX3ZidWZzLAo+ICsJCQkJCXN0cnVj dCB2aXJ0aW9fZ3B1X3ZidWZmZXIsIGxpc3QpOwo+ICsJCWxpc3RfZGVsKCZ2YnVmLT5saXN0KTsK PiArCX0KPiArCWtmcmVlKHZnZGV2LT52YnVmcyk7Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1Y3Qg dmlydGlvX2dwdV92YnVmZmVyKgo+ICt2aXJ0aW9fZ3B1X2dldF92YnVmKHN0cnVjdCB2aXJ0aW9f Z3B1X2RldmljZSAqdmdkZXYsCj4gKwkJICAgIGludCBzaXplLCBpbnQgcmVzcF9zaXplLCB2b2lk ICpyZXNwX2J1ZiwKPiArCQkgICAgdmlydGlvX2dwdV9yZXNwX2NiIHJlc3BfY2IpCj4gK3sKPiAr CXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWY7Cj4gKwo+ICsJQlVHX09OKGxpc3RfZW1w dHkoJnZnZGV2LT5mcmVlX3ZidWZzKSk7Cj4gKwl2YnVmID0gbGlzdF9maXJzdF9lbnRyeSgmdmdk ZXYtPmZyZWVfdmJ1ZnMsCj4gKwkJCQlzdHJ1Y3QgdmlydGlvX2dwdV92YnVmZmVyLCBsaXN0KTsK PiArCWxpc3RfZGVsKCZ2YnVmLT5saXN0KTsKPiArCW1lbXNldCh2YnVmLCAwLCBWQlVGRkVSX1NJ WkUpOwo+ICsKPiArCUJVR19PTihzaXplID4gTUFYX0lOTElORV9DTURfU0laRSk7Cj4gKwl2YnVm LT5idWYgPSAodm9pZCAqKXZidWYgKyBzaXplb2YoKnZidWYpOwo+ICsJdmJ1Zi0+c2l6ZSA9IHNp emU7Cj4gKwo+ICsJdmJ1Zi0+cmVzcF9jYiA9IHJlc3BfY2I7Cj4gKwl2YnVmLT5yZXNwX3NpemUg PSByZXNwX3NpemU7Cj4gKwlpZiAocmVzcF9zaXplIDw9IE1BWF9JTkxJTkVfUkVTUF9TSVpFKQo+ ICsJCXZidWYtPnJlc3BfYnVmID0gKHZvaWQgKil2YnVmLT5idWYgKyBzaXplOwo+ICsJZWxzZQo+ ICsJCXZidWYtPnJlc3BfYnVmID0gcmVzcF9idWY7Cj4gKwlCVUdfT04oIXZidWYtPnJlc3BfYnVm KTsKPiArCXJldHVybiB2YnVmOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCAqdmlydGlvX2dwdV9h bGxvY19jbWQoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCSAgc3RydWN0 IHZpcnRpb19ncHVfdmJ1ZmZlciAqKnZidWZmZXJfcCwKPiArCQkJCSAgaW50IHNpemUpCj4gK3sK PiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWY7Cj4gKwo+ICsJdmJ1ZiA9IHZpcnRp b19ncHVfZ2V0X3ZidWYodmdkZXYsIHNpemUsCj4gKwkJCQkgICBzaXplb2Yoc3RydWN0IHZpcnRp b19ncHVfY3RybF9oZHIpLAo+ICsJCQkJICAgTlVMTCwgTlVMTCk7Cj4gKwlpZiAoSVNfRVJSKHZi dWYpKSB7Cj4gKwkJKnZidWZmZXJfcCA9IE5VTEw7Cj4gKwkJcmV0dXJuIEVSUl9DQVNUKHZidWYp Owo+ICsJfQo+ICsJKnZidWZmZXJfcCA9IHZidWY7Cj4gKwlyZXR1cm4gdmJ1Zi0+YnVmOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHZpcnRpb19ncHVfdXBkYXRlX2N1cnNvcioKPiArdmlydGlv X2dwdV9hbGxvY19jdXJzb3Ioc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJ c3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZlciAqKnZidWZmZXJfcCkKPiArewo+ICsJc3RydWN0IHZp cnRpb19ncHVfdmJ1ZmZlciAqdmJ1ZjsKPiArCj4gKwl2YnVmID0gdmlydGlvX2dwdV9nZXRfdmJ1 Zgo+ICsJCSh2Z2Rldiwgc2l6ZW9mKHN0cnVjdCB2aXJ0aW9fZ3B1X3VwZGF0ZV9jdXJzb3IpLAo+ ICsJCSAwLCBOVUxMLCBOVUxMKTsKPiArCWlmIChJU19FUlIodmJ1ZikpIHsKPiArCQkqdmJ1ZmZl cl9wID0gTlVMTDsKPiArCQlyZXR1cm4gRVJSX0NBU1QodmJ1Zik7Cj4gKwl9Cj4gKwkqdmJ1ZmZl cl9wID0gdmJ1ZjsKPiArCXJldHVybiAoc3RydWN0IHZpcnRpb19ncHVfdXBkYXRlX2N1cnNvciAq KXZidWYtPmJ1ZjsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgKnZpcnRpb19ncHVfYWxsb2NfY21k X3Jlc3Aoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCSAgICAgICB2aXJ0 aW9fZ3B1X3Jlc3BfY2IgY2IsCj4gKwkJCQkgICAgICAgc3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZl ciAqKnZidWZmZXJfcCwKPiArCQkJCSAgICAgICBpbnQgY21kX3NpemUsIGludCByZXNwX3NpemUs Cj4gKwkJCQkgICAgICAgdm9pZCAqcmVzcF9idWYpCj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1 X3ZidWZmZXIgKnZidWY7Cj4gKwo+ICsJdmJ1ZiA9IHZpcnRpb19ncHVfZ2V0X3ZidWYodmdkZXYs IGNtZF9zaXplLAo+ICsJCQkJICAgcmVzcF9zaXplLCByZXNwX2J1ZiwgY2IpOwo+ICsJaWYgKElT X0VSUih2YnVmKSkgewo+ICsJCSp2YnVmZmVyX3AgPSBOVUxMOwo+ICsJCXJldHVybiBFUlJfQ0FT VCh2YnVmKTsKPiArCX0KPiArCSp2YnVmZmVyX3AgPSB2YnVmOwo+ICsJcmV0dXJuIChzdHJ1Y3Qg dmlydGlvX2dwdV9jb21tYW5kICopdmJ1Zi0+YnVmOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBm cmVlX3ZidWYoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkgICAgICBzdHJ1 Y3QgdmlydGlvX2dwdV92YnVmZmVyICp2YnVmKQo+ICt7Cj4gKwlpZiAodmJ1Zi0+cmVzcF9zaXpl ID4gTUFYX0lOTElORV9SRVNQX1NJWkUpCj4gKwkJa2ZyZWUodmJ1Zi0+cmVzcF9idWYpOwo+ICsJ a2ZyZWUodmJ1Zi0+ZGF0YV9idWYpOwo+ICsJbGlzdF9hZGQoJnZidWYtPmxpc3QsICZ2Z2Rldi0+ ZnJlZV92YnVmcyk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHJlY2xhaW1fdmJ1ZnMoc3RydWN0 IHZpcnRxdWV1ZSAqdnEsIHN0cnVjdCBsaXN0X2hlYWQgKnJlY2xhaW1fbGlzdCkKPiArewo+ICsJ c3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZlciAqdmJ1ZjsKPiArCXVuc2lnbmVkIGludCBsZW47Cj4g KwlpbnQgZnJlZWQgPSAwOwo+ICsKPiArCXdoaWxlICgodmJ1ZiA9IHZpcnRxdWV1ZV9nZXRfYnVm KHZxLCAmbGVuKSkpIHsKPiArCQlsaXN0X2FkZF90YWlsKCZ2YnVmLT5saXN0LCByZWNsYWltX2xp c3QpOwo+ICsJCWZyZWVkKys7Cj4gKwl9Cj4gKwlpZiAoZnJlZWQgPT0gMCkKPiArCQlEUk1fREVC VUcoIkh1aD8gemVybyB2YnVmcyByZWNsYWltZWQiKTsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9f Z3B1X2RlcXVldWVfY3RybF9mdW5jKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKPiArewo+ICsJ c3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiA9Cj4gKwkJY29udGFpbmVyX29mKHdvcmss IHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSwKPiArCQkJICAgICBjdHJscS5kZXF1ZXVlX3dvcmsp Owo+ICsJc3RydWN0IGxpc3RfaGVhZCByZWNsYWltX2xpc3Q7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dw dV92YnVmZmVyICplbnRyeSwgKnRtcDsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2N0cmxfaGRyICpy ZXNwOwo+ICsJdTY0IGZlbmNlX2lkID0gMDsKPiArCj4gKwlJTklUX0xJU1RfSEVBRCgmcmVjbGFp bV9saXN0KTsKPiArCXNwaW5fbG9jaygmdmdkZXYtPmN0cmxxLnFsb2NrKTsKPiArCWRvIHsKPiAr CQl2aXJ0cXVldWVfZGlzYWJsZV9jYih2Z2Rldi0+Y3RybHEudnEpOwo+ICsJCXJlY2xhaW1fdmJ1 ZnModmdkZXYtPmN0cmxxLnZxLCAmcmVjbGFpbV9saXN0KTsKPiArCj4gKwl9IHdoaWxlICghdmly dHF1ZXVlX2VuYWJsZV9jYih2Z2Rldi0+Y3RybHEudnEpKTsKPiArCXNwaW5fdW5sb2NrKCZ2Z2Rl di0+Y3RybHEucWxvY2spOwo+ICsKPiArCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShlbnRyeSwg dG1wLCAmcmVjbGFpbV9saXN0LCBsaXN0KSB7Cj4gKwkJcmVzcCA9IChzdHJ1Y3QgdmlydGlvX2dw dV9jdHJsX2hkciAqKWVudHJ5LT5yZXNwX2J1ZjsKPiArCQlpZiAocmVzcC0+dHlwZSAhPSBjcHVf dG9fbGUzMihWSVJUSU9fR1BVX1JFU1BfT0tfTk9EQVRBKSkKPiArCQkJRFJNX0RFQlVHKCJyZXNw b25zZSAweCV4XG4iLCBsZTMyX3RvX2NwdShyZXNwLT50eXBlKSk7Cj4gKwkJaWYgKHJlc3AtPmZs YWdzICYgY3B1X3RvX2xlMzIoVklSVElPX0dQVV9GTEFHX0ZFTkNFKSkgewo+ICsJCQl1NjQgZiA9 IGxlNjRfdG9fY3B1KHJlc3AtPmZlbmNlX2lkKTsKPiArCj4gKwkJCWlmIChmZW5jZV9pZCA+IGYp IHsKPiArCQkJCURSTV9FUlJPUigiJXM6IE9vcHM6IGZlbmNlICVsbHggLT4gJWxseFxuIiwKPiAr CQkJCQkgIF9fZnVuY19fLCBmZW5jZV9pZCwgZik7Cj4gKwkJCX0gZWxzZSB7Cj4gKwkJCQlmZW5j ZV9pZCA9IGY7Cj4gKwkJCX0KPiArCQl9Cj4gKwkJaWYgKGVudHJ5LT5yZXNwX2NiKQo+ICsJCQll bnRyeS0+cmVzcF9jYih2Z2RldiwgZW50cnkpOwo+ICsKPiArCQlsaXN0X2RlbCgmZW50cnktPmxp c3QpOwo+ICsJCWZyZWVfdmJ1Zih2Z2RldiwgZW50cnkpOwo+ICsJfQo+ICsJd2FrZV91cCgmdmdk ZXYtPmN0cmxxLmFja19xdWV1ZSk7Cj4gKwo+ICsJaWYgKGZlbmNlX2lkKQo+ICsJCXZpcnRpb19n cHVfZmVuY2VfZXZlbnRfcHJvY2Vzcyh2Z2RldiwgZmVuY2VfaWQpOwo+ICt9Cj4gKwo+ICt2b2lk IHZpcnRpb19ncHVfZGVxdWV1ZV9jdXJzb3JfZnVuYyhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmsp Cj4gK3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYgPQo+ICsJCWNvbnRhaW5l cl9vZih3b3JrLCBzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UsCj4gKwkJCSAgICAgY3Vyc29ycS5k ZXF1ZXVlX3dvcmspOwo+ICsJc3RydWN0IGxpc3RfaGVhZCByZWNsYWltX2xpc3Q7Cj4gKwlzdHJ1 Y3QgdmlydGlvX2dwdV92YnVmZmVyICplbnRyeSwgKnRtcDsKPiArCj4gKwlJTklUX0xJU1RfSEVB RCgmcmVjbGFpbV9saXN0KTsKPiArCXNwaW5fbG9jaygmdmdkZXYtPmN1cnNvcnEucWxvY2spOwo+ ICsJZG8gewo+ICsJCXZpcnRxdWV1ZV9kaXNhYmxlX2NiKHZnZGV2LT5jdXJzb3JxLnZxKTsKPiAr CQlyZWNsYWltX3ZidWZzKHZnZGV2LT5jdXJzb3JxLnZxLCAmcmVjbGFpbV9saXN0KTsKPiArCX0g d2hpbGUgKCF2aXJ0cXVldWVfZW5hYmxlX2NiKHZnZGV2LT5jdXJzb3JxLnZxKSk7Cj4gKwlzcGlu X3VubG9jaygmdmdkZXYtPmN1cnNvcnEucWxvY2spOwo+ICsKPiArCWxpc3RfZm9yX2VhY2hfZW50 cnlfc2FmZShlbnRyeSwgdG1wLCAmcmVjbGFpbV9saXN0LCBsaXN0KSB7Cj4gKwkJbGlzdF9kZWwo JmVudHJ5LT5saXN0KTsKPiArCQlmcmVlX3ZidWYodmdkZXYsIGVudHJ5KTsKPiArCX0KPiArCXdh a2VfdXAoJnZnZGV2LT5jdXJzb3JxLmFja19xdWV1ZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQg dmlydGlvX2dwdV9xdWV1ZV9jdHJsX2J1ZmZlcihzdHJ1Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZn ZGV2LAo+ICsJCQkJCXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWYpCj4gK3sKPiArCXN0 cnVjdCB2aXJ0cXVldWUgKnZxID0gdmdkZXYtPmN0cmxxLnZxOwo+ICsJc3RydWN0IHNjYXR0ZXJs aXN0ICpzZ3NbM10sIHZjbWQsIHZvdXQsIHZyZXNwOwo+ICsJaW50IG91dGNudCA9IDAsIGluY250 ID0gMDsKPiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKCF2Z2Rldi0+dnFzX3JlYWR5KQo+ICsJCXJl dHVybiAtRU5PREVWOwo+ICsKPiArCXNnX2luaXRfb25lKCZ2Y21kLCB2YnVmLT5idWYsIHZidWYt PnNpemUpOwo+ICsJc2dzW291dGNudCtpbmNudF0gPSAmdmNtZDsKPiArCW91dGNudCsrOwo+ICsK PiArCWlmICh2YnVmLT5kYXRhX3NpemUpIHsKPiArCQlzZ19pbml0X29uZSgmdm91dCwgdmJ1Zi0+ ZGF0YV9idWYsIHZidWYtPmRhdGFfc2l6ZSk7Cj4gKwkJc2dzW291dGNudCArIGluY250XSA9ICZ2 b3V0Owo+ICsJCW91dGNudCsrOwo+ICsJfQo+ICsKPiArCWlmICh2YnVmLT5yZXNwX3NpemUpIHsK PiArCQlzZ19pbml0X29uZSgmdnJlc3AsIHZidWYtPnJlc3BfYnVmLCB2YnVmLT5yZXNwX3NpemUp Owo+ICsJCXNnc1tvdXRjbnQgKyBpbmNudF0gPSAmdnJlc3A7Cj4gKwkJaW5jbnQrKzsKPiArCX0K PiArCj4gKwlzcGluX2xvY2soJnZnZGV2LT5jdHJscS5xbG9jayk7Cj4gK3JldHJ5Ogo+ICsJcmV0 ID0gdmlydHF1ZXVlX2FkZF9zZ3ModnEsIHNncywgb3V0Y250LCBpbmNudCwgdmJ1ZiwgR0ZQX0FU T01JQyk7Cj4gKwlpZiAocmV0ID09IC1FTk9TUEMpIHsKPiArCQlzcGluX3VubG9jaygmdmdkZXYt PmN0cmxxLnFsb2NrKTsKPiArCQl3YWl0X2V2ZW50KHZnZGV2LT5jdHJscS5hY2tfcXVldWUsIHZx LT5udW1fZnJlZSk7Cj4gKwkJc3Bpbl9sb2NrKCZ2Z2Rldi0+Y3RybHEucWxvY2spOwo+ICsJCWdv dG8gcmV0cnk7Cj4gKwl9IGVsc2Ugewo+ICsJCXZpcnRxdWV1ZV9raWNrKHZxKTsKPiArCX0KPiAr CXNwaW5fdW5sb2NrKCZ2Z2Rldi0+Y3RybHEucWxvY2spOwo+ICsKPiArCWlmICghcmV0KQo+ICsJ CXJldCA9IHZxLT5udW1fZnJlZTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBp bnQgdmlydGlvX2dwdV9xdWV1ZV9jdXJzb3Ioc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2Rl diwKPiArCQkJCSAgIHN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWYpCj4gK3sKPiArCXN0 cnVjdCB2aXJ0cXVldWUgKnZxID0gdmdkZXYtPmN1cnNvcnEudnE7Cj4gKwlzdHJ1Y3Qgc2NhdHRl cmxpc3QgKnNnc1sxXSwgY2NtZDsKPiArCWludCByZXQ7Cj4gKwlpbnQgb3V0Y250Owo+ICsKPiAr CWlmICghdmdkZXYtPnZxc19yZWFkeSkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwlzZ19p bml0X29uZSgmY2NtZCwgdmJ1Zi0+YnVmLCB2YnVmLT5zaXplKTsKPiArCXNnc1swXSA9ICZjY21k Owo+ICsJb3V0Y250ID0gMTsKPiArCj4gKwlzcGluX2xvY2soJnZnZGV2LT5jdXJzb3JxLnFsb2Nr KTsKPiArcmV0cnk6Cj4gKwlyZXQgPSB2aXJ0cXVldWVfYWRkX3Nncyh2cSwgc2dzLCBvdXRjbnQs IDAsIHZidWYsIEdGUF9BVE9NSUMpOwo+ICsJaWYgKHJldCA9PSAtRU5PU1BDKSB7Cj4gKwkJc3Bp bl91bmxvY2soJnZnZGV2LT5jdXJzb3JxLnFsb2NrKTsKPiArCQl3YWl0X2V2ZW50KHZnZGV2LT5j dXJzb3JxLmFja19xdWV1ZSwgdnEtPm51bV9mcmVlKTsKPiArCQlzcGluX2xvY2soJnZnZGV2LT5j dXJzb3JxLnFsb2NrKTsKPiArCQlnb3RvIHJldHJ5Owo+ICsJfSBlbHNlIHsKPiArCQl2aXJ0cXVl dWVfa2ljayh2cSk7Cj4gKwl9Cj4gKwo+ICsJc3Bpbl91bmxvY2soJnZnZGV2LT5jdXJzb3JxLnFs b2NrKTsKPiArCj4gKwlpZiAoIXJldCkKPiArCQlyZXQgPSB2cS0+bnVtX2ZyZWU7Cj4gKwlyZXR1 cm4gcmV0Owo+ICt9Cj4gKwo+ICsvKiBqdXN0IGNyZWF0ZSBnZW0gb2JqZWN0cyBmb3IgdXNlcnNw YWNlIGFuZCBsb25nIGxpdmVkIG9iamVjdHMsCj4gKyAgIGp1c3QgdXNlIGRtYV9hbGxvY2VkIHBh Z2VzIGZvciB0aGUgcXVldWUgb2JqZWN0cz8gKi8KPiArCj4gKy8qIGNyZWF0ZSBhIGJhc2ljIHJl c291cmNlICovCj4gK3ZvaWQgdmlydGlvX2dwdV9jbWRfY3JlYXRlX3Jlc291cmNlKHN0cnVjdCB2 aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCQkgICAgdWludDMyX3QgcmVzb3VyY2VfaWQs Cj4gKwkJCQkgICAgdWludDMyX3QgZm9ybWF0LAo+ICsJCQkJICAgIHVpbnQzMl90IHdpZHRoLAo+ ICsJCQkJICAgIHVpbnQzMl90IGhlaWdodCkKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfcmVz b3VyY2VfY3JlYXRlXzJkICpjbWRfcDsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZi dWY7Cj4gKwo+ICsJY21kX3AgPSB2aXJ0aW9fZ3B1X2FsbG9jX2NtZCh2Z2RldiwgJnZidWYsIHNp emVvZigqY21kX3ApKTsKPiArCW1lbXNldChjbWRfcCwgMCwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsK PiArCWNtZF9wLT5oZHIudHlwZSA9IGNwdV90b19sZTMyKFZJUlRJT19HUFVfQ01EX1JFU09VUkNF X0NSRUFURV8yRCk7Cj4gKwljbWRfcC0+cmVzb3VyY2VfaWQgPSBjcHVfdG9fbGUzMihyZXNvdXJj ZV9pZCk7Cj4gKwljbWRfcC0+Zm9ybWF0ID0gY3B1X3RvX2xlMzIoZm9ybWF0KTsKPiArCWNtZF9w LT53aWR0aCA9IGNwdV90b19sZTMyKHdpZHRoKTsKPiArCWNtZF9wLT5oZWlnaHQgPSBjcHVfdG9f bGUzMihoZWlnaHQpOwo+ICsKPiArCXZpcnRpb19ncHVfcXVldWVfY3RybF9idWZmZXIodmdkZXYs IHZidWYpOwo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVfY21kX3VucmVmX3Jlc291cmNlKHN0 cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCQkgICB1aW50MzJfdCByZXNvdXJj ZV9pZCkKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfcmVzb3VyY2VfdW5yZWYgKmNtZF9wOwo+ ICsJc3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZlciAqdmJ1ZjsKPiArCj4gKwljbWRfcCA9IHZpcnRp b19ncHVfYWxsb2NfY21kKHZnZGV2LCAmdmJ1Ziwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsJbWVtc2V0 KGNtZF9wLCAwLCBzaXplb2YoKmNtZF9wKSk7Cj4gKwo+ICsJY21kX3AtPmhkci50eXBlID0gY3B1 X3RvX2xlMzIoVklSVElPX0dQVV9DTURfUkVTT1VSQ0VfVU5SRUYpOwo+ICsJY21kX3AtPnJlc291 cmNlX2lkID0gY3B1X3RvX2xlMzIocmVzb3VyY2VfaWQpOwo+ICsKPiArCXZpcnRpb19ncHVfcXVl dWVfY3RybF9idWZmZXIodmdkZXYsIHZidWYpOwo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVf Y21kX3Jlc291cmNlX2ludmFsX2JhY2tpbmcoc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2Rl diwKPiArCQkJCQkgICB1aW50MzJfdCByZXNvdXJjZV9pZCkKPiArewo+ICsJc3RydWN0IHZpcnRp b19ncHVfcmVzb3VyY2VfZGV0YWNoX2JhY2tpbmcgKmNtZF9wOwo+ICsJc3RydWN0IHZpcnRpb19n cHVfdmJ1ZmZlciAqdmJ1ZjsKPiArCj4gKwljbWRfcCA9IHZpcnRpb19ncHVfYWxsb2NfY21kKHZn ZGV2LCAmdmJ1Ziwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsJbWVtc2V0KGNtZF9wLCAwLCBzaXplb2Yo KmNtZF9wKSk7Cj4gKwo+ICsJY21kX3AtPmhkci50eXBlID0gY3B1X3RvX2xlMzIoVklSVElPX0dQ VV9DTURfUkVTT1VSQ0VfREVUQUNIX0JBQ0tJTkcpOwo+ICsJY21kX3AtPnJlc291cmNlX2lkID0g Y3B1X3RvX2xlMzIocmVzb3VyY2VfaWQpOwo+ICsKPiArCXZpcnRpb19ncHVfcXVldWVfY3RybF9i dWZmZXIodmdkZXYsIHZidWYpOwo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRpb19ncHVfY21kX3NldF9z Y2Fub3V0KHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCQl1aW50MzJfdCBz Y2Fub3V0X2lkLCB1aW50MzJfdCByZXNvdXJjZV9pZCwKPiArCQkJCXVpbnQzMl90IHdpZHRoLCB1 aW50MzJfdCBoZWlnaHQsCj4gKwkJCQl1aW50MzJfdCB4LCB1aW50MzJfdCB5KQo+ICt7Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9zZXRfc2Nhbm91dCAqY21kX3A7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dw dV92YnVmZmVyICp2YnVmOwo+ICsKPiArCWNtZF9wID0gdmlydGlvX2dwdV9hbGxvY19jbWQodmdk ZXYsICZ2YnVmLCBzaXplb2YoKmNtZF9wKSk7Cj4gKwltZW1zZXQoY21kX3AsIDAsIHNpemVvZigq Y21kX3ApKTsKPiArCj4gKwljbWRfcC0+aGRyLnR5cGUgPSBjcHVfdG9fbGUzMihWSVJUSU9fR1BV X0NNRF9TRVRfU0NBTk9VVCk7Cj4gKwljbWRfcC0+cmVzb3VyY2VfaWQgPSBjcHVfdG9fbGUzMihy ZXNvdXJjZV9pZCk7Cj4gKwljbWRfcC0+c2Nhbm91dF9pZCA9IGNwdV90b19sZTMyKHNjYW5vdXRf aWQpOwo+ICsJY21kX3AtPnIud2lkdGggPSBjcHVfdG9fbGUzMih3aWR0aCk7Cj4gKwljbWRfcC0+ ci5oZWlnaHQgPSBjcHVfdG9fbGUzMihoZWlnaHQpOwo+ICsJY21kX3AtPnIueCA9IGNwdV90b19s ZTMyKHgpOwo+ICsJY21kX3AtPnIueSA9IGNwdV90b19sZTMyKHkpOwo+ICsKPiArCXZpcnRpb19n cHVfcXVldWVfY3RybF9idWZmZXIodmdkZXYsIHZidWYpOwo+ICt9Cj4gKwo+ICt2b2lkIHZpcnRp b19ncHVfY21kX3Jlc291cmNlX2ZsdXNoKHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYs Cj4gKwkJCQkgICB1aW50MzJfdCByZXNvdXJjZV9pZCwKPiArCQkJCSAgIHVpbnQzMl90IHgsIHVp bnQzMl90IHksCj4gKwkJCQkgICB1aW50MzJfdCB3aWR0aCwgdWludDMyX3QgaGVpZ2h0KQo+ICt7 Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9yZXNvdXJjZV9mbHVzaCAqY21kX3A7Cj4gKwlzdHJ1Y3Qg dmlydGlvX2dwdV92YnVmZmVyICp2YnVmOwo+ICsKPiArCWNtZF9wID0gdmlydGlvX2dwdV9hbGxv Y19jbWQodmdkZXYsICZ2YnVmLCBzaXplb2YoKmNtZF9wKSk7Cj4gKwltZW1zZXQoY21kX3AsIDAs IHNpemVvZigqY21kX3ApKTsKPiArCj4gKwljbWRfcC0+aGRyLnR5cGUgPSBjcHVfdG9fbGUzMihW SVJUSU9fR1BVX0NNRF9SRVNPVVJDRV9GTFVTSCk7Cj4gKwljbWRfcC0+cmVzb3VyY2VfaWQgPSBj cHVfdG9fbGUzMihyZXNvdXJjZV9pZCk7Cj4gKwljbWRfcC0+ci53aWR0aCA9IGNwdV90b19sZTMy KHdpZHRoKTsKPiArCWNtZF9wLT5yLmhlaWdodCA9IGNwdV90b19sZTMyKGhlaWdodCk7Cj4gKwlj bWRfcC0+ci54ID0gY3B1X3RvX2xlMzIoeCk7Cj4gKwljbWRfcC0+ci55ID0gY3B1X3RvX2xlMzIo eSk7Cj4gKwo+ICsJdmlydGlvX2dwdV9xdWV1ZV9jdHJsX2J1ZmZlcih2Z2RldiwgdmJ1Zik7Cj4g K30KPiArCj4gK3ZvaWQgdmlydGlvX2dwdV9jbWRfdHJhbnNmZXJfdG9faG9zdF8yZChzdHJ1Y3Qg dmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2LAo+ICsJCQkJCXVpbnQzMl90IHJlc291cmNlX2lkLCB1 aW50NjRfdCBvZmZzZXQsCj4gKwkJCQkJX19sZTMyIHdpZHRoLCBfX2xlMzIgaGVpZ2h0LAo+ICsJ CQkJCV9fbGUzMiB4LCBfX2xlMzIgeSwKPiArCQkJCQlzdHJ1Y3QgdmlydGlvX2dwdV9mZW5jZSAq KmZlbmNlKQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV90cmFuc2Zlcl90b19ob3N0XzJkICpj bWRfcDsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWY7Cj4gKwo+ICsJY21kX3Ag PSB2aXJ0aW9fZ3B1X2FsbG9jX2NtZCh2Z2RldiwgJnZidWYsIHNpemVvZigqY21kX3ApKTsKPiAr CW1lbXNldChjbWRfcCwgMCwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsKPiArCWNtZF9wLT5oZHIudHlw ZSA9IGNwdV90b19sZTMyKFZJUlRJT19HUFVfQ01EX1RSQU5TRkVSX1RPX0hPU1RfMkQpOwo+ICsJ Y21kX3AtPnJlc291cmNlX2lkID0gY3B1X3RvX2xlMzIocmVzb3VyY2VfaWQpOwo+ICsJY21kX3At Pm9mZnNldCA9IGNwdV90b19sZTY0KG9mZnNldCk7Cj4gKwljbWRfcC0+ci53aWR0aCA9IHdpZHRo Owo+ICsJY21kX3AtPnIuaGVpZ2h0ID0gaGVpZ2h0Owo+ICsJY21kX3AtPnIueCA9IHg7Cj4gKwlj bWRfcC0+ci55ID0geTsKPiArCj4gKwlpZiAoZmVuY2UpCj4gKwkJdmlydGlvX2dwdV9mZW5jZV9l bWl0KHZnZGV2LCAmY21kX3AtPmhkciwgZmVuY2UpOwo+ICsJdmlydGlvX2dwdV9xdWV1ZV9jdHJs X2J1ZmZlcih2Z2RldiwgdmJ1Zik7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkCj4gK3ZpcnRpb19n cHVfY21kX3Jlc291cmNlX2F0dGFjaF9iYWNraW5nKHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAq dmdkZXYsCj4gKwkJCQkgICAgICAgdWludDMyX3QgcmVzb3VyY2VfaWQsCj4gKwkJCQkgICAgICAg c3RydWN0IHZpcnRpb19ncHVfbWVtX2VudHJ5ICplbnRzLAo+ICsJCQkJICAgICAgIHVpbnQzMl90 IG5lbnRzLAo+ICsJCQkJICAgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X2ZlbmNlICoqZmVuY2UpCj4g K3sKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3Jlc291cmNlX2F0dGFjaF9iYWNraW5nICpjbWRfcDsK PiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3ZidWZmZXIgKnZidWY7Cj4gKwo+ICsJY21kX3AgPSB2aXJ0 aW9fZ3B1X2FsbG9jX2NtZCh2Z2RldiwgJnZidWYsIHNpemVvZigqY21kX3ApKTsKPiArCW1lbXNl dChjbWRfcCwgMCwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsKPiArCWNtZF9wLT5oZHIudHlwZSA9IGNw dV90b19sZTMyKFZJUlRJT19HUFVfQ01EX1JFU09VUkNFX0FUVEFDSF9CQUNLSU5HKTsKPiArCWNt ZF9wLT5yZXNvdXJjZV9pZCA9IGNwdV90b19sZTMyKHJlc291cmNlX2lkKTsKPiArCWNtZF9wLT5u cl9lbnRyaWVzID0gY3B1X3RvX2xlMzIobmVudHMpOwo+ICsKPiArCXZidWYtPmRhdGFfYnVmID0g ZW50czsKPiArCXZidWYtPmRhdGFfc2l6ZSA9IHNpemVvZigqZW50cykgKiBuZW50czsKPiArCj4g KwlpZiAoZmVuY2UpCj4gKwkJdmlydGlvX2dwdV9mZW5jZV9lbWl0KHZnZGV2LCAmY21kX3AtPmhk ciwgZmVuY2UpOwo+ICsJdmlydGlvX2dwdV9xdWV1ZV9jdHJsX2J1ZmZlcih2Z2RldiwgdmJ1Zik7 Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZpcnRpb19ncHVfY21kX2dldF9kaXNwbGF5X2luZm9f Y2Ioc3RydWN0IHZpcnRpb19ncHVfZGV2aWNlICp2Z2RldiwKPiArCQkJCQkgICAgICAgc3RydWN0 IHZpcnRpb19ncHVfdmJ1ZmZlciAqdmJ1ZikKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfcmVz cF9kaXNwbGF5X2luZm8gKnJlc3AgPQo+ICsJCShzdHJ1Y3QgdmlydGlvX2dwdV9yZXNwX2Rpc3Bs YXlfaW5mbyAqKXZidWYtPnJlc3BfYnVmOwo+ICsJaW50IGk7Cj4gKwo+ICsJc3Bpbl9sb2NrKCZ2 Z2Rldi0+ZGlzcGxheV9pbmZvX2xvY2spOwo+ICsJZm9yIChpID0gMDsgaSA8IHZnZGV2LT5udW1f c2Nhbm91dHM7IGkrKykgewo+ICsJCXZnZGV2LT5vdXRwdXRzW2ldLmluZm8gPSByZXNwLT5wbW9k ZXNbaV07Cj4gKwkJaWYgKHJlc3AtPnBtb2Rlc1tpXS5lbmFibGVkKSB7Cj4gKwkJCURSTV9ERUJV Rygib3V0cHV0ICVkOiAlZHglZCslZCslZCIsIGksCj4gKwkJCQkgIGxlMzJfdG9fY3B1KHJlc3At PnBtb2Rlc1tpXS5yLndpZHRoKSwKPiArCQkJCSAgbGUzMl90b19jcHUocmVzcC0+cG1vZGVzW2ld LnIuaGVpZ2h0KSwKPiArCQkJCSAgbGUzMl90b19jcHUocmVzcC0+cG1vZGVzW2ldLnIueCksCj4g KwkJCQkgIGxlMzJfdG9fY3B1KHJlc3AtPnBtb2Rlc1tpXS5yLnkpKTsKPiArCQl9IGVsc2Ugewo+ ICsJCQlEUk1fREVCVUcoIm91dHB1dCAlZDogZGlzYWJsZWQiLCBpKTsKPiArCQl9Cj4gKwl9Cj4g Kwo+ICsJc3Bpbl91bmxvY2soJnZnZGV2LT5kaXNwbGF5X2luZm9fbG9jayk7Cj4gKwl3YWtlX3Vw KCZ2Z2Rldi0+cmVzcF93cSk7Cj4gKwo+ICsJaWYgKCFkcm1faGVscGVyX2hwZF9pcnFfZXZlbnQo dmdkZXYtPmRkZXYpKQo+ICsJCWRybV9rbXNfaGVscGVyX2hvdHBsdWdfZXZlbnQodmdkZXYtPmRk ZXYpOwo+ICt9Cj4gKwo+ICtpbnQgdmlydGlvX2dwdV9jbWRfZ2V0X2Rpc3BsYXlfaW5mbyhzdHJ1 Y3QgdmlydGlvX2dwdV9kZXZpY2UgKnZnZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9j dHJsX2hkciAqY21kX3A7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV92YnVmZmVyICp2YnVmOwo+ICsJ dm9pZCAqcmVzcF9idWY7Cj4gKwo+ICsJcmVzcF9idWYgPSBremFsbG9jKHNpemVvZihzdHJ1Y3Qg dmlydGlvX2dwdV9yZXNwX2Rpc3BsYXlfaW5mbyksCj4gKwkJCSAgIEdGUF9LRVJORUwpOwo+ICsJ aWYgKCFyZXNwX2J1ZikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwljbWRfcCA9IHZpcnRp b19ncHVfYWxsb2NfY21kX3Jlc3AKPiArCQkodmdkZXYsICZ2aXJ0aW9fZ3B1X2NtZF9nZXRfZGlz cGxheV9pbmZvX2NiLCAmdmJ1ZiwKPiArCQkgc2l6ZW9mKCpjbWRfcCksIHNpemVvZihzdHJ1Y3Qg dmlydGlvX2dwdV9yZXNwX2Rpc3BsYXlfaW5mbyksCj4gKwkJIHJlc3BfYnVmKTsKPiArCW1lbXNl dChjbWRfcCwgMCwgc2l6ZW9mKCpjbWRfcCkpOwo+ICsKPiArCWNtZF9wLT50eXBlID0gY3B1X3Rv X2xlMzIoVklSVElPX0dQVV9DTURfR0VUX0RJU1BMQVlfSU5GTyk7Cj4gKwl2aXJ0aW9fZ3B1X3F1 ZXVlX2N0cmxfYnVmZmVyKHZnZGV2LCB2YnVmKTsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtp bnQgdmlydGlvX2dwdV9vYmplY3RfYXR0YWNoKHN0cnVjdCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdk ZXYsCj4gKwkJCSAgICAgc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0ICpvYmosCj4gKwkJCSAgICAg dWludDMyX3QgcmVzb3VyY2VfaWQsCj4gKwkJCSAgICAgc3RydWN0IHZpcnRpb19ncHVfZmVuY2Ug KipmZW5jZSkKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfbWVtX2VudHJ5ICplbnRzOwo+ICsJ c3RydWN0IHNjYXR0ZXJsaXN0ICpzZzsKPiArCWludCBzaTsKPiArCj4gKwlpZiAoIW9iai0+cGFn ZXMpIHsKPiArCQlpbnQgcmV0Owo+ICsJCXJldCA9IHZpcnRpb19ncHVfb2JqZWN0X2dldF9zZ190 YWJsZSh2Z2Rldiwgb2JqKTsKPiArCQlpZiAocmV0KQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJfQo+ ICsKPiArCS8qIGdldHMgZnJlZWQgd2hlbiB0aGUgcmluZyBoYXMgY29uc3VtZWQgaXQgKi8KPiAr CWVudHMgPSBrbWFsbG9jX2FycmF5KG9iai0+cGFnZXMtPm5lbnRzLAo+ICsJCQkgICAgIHNpemVv ZihzdHJ1Y3QgdmlydGlvX2dwdV9tZW1fZW50cnkpLAo+ICsJCQkgICAgIEdGUF9LRVJORUwpOwo+ ICsJaWYgKCFlbnRzKSB7Cj4gKwkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gYWxsb2NhdGUgZW50IGxp c3RcbiIpOwo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsJfQo+ICsKPiArCWZvcl9lYWNoX3NnKG9i ai0+cGFnZXMtPnNnbCwgc2csIG9iai0+cGFnZXMtPm5lbnRzLCBzaSkgewo+ICsJCWVudHNbc2ld LmFkZHIgPSBjcHVfdG9fbGU2NChzZ19waHlzKHNnKSk7Cj4gKwkJZW50c1tzaV0ubGVuZ3RoID0g Y3B1X3RvX2xlMzIoc2ctPmxlbmd0aCk7Cj4gKwkJZW50c1tzaV0ucGFkZGluZyA9IDA7Cj4gKwl9 Cj4gKwo+ICsJdmlydGlvX2dwdV9jbWRfcmVzb3VyY2VfYXR0YWNoX2JhY2tpbmcodmdkZXYsIHJl c291cmNlX2lkLAo+ICsJCQkJCSAgICAgICBlbnRzLCBvYmotPnBhZ2VzLT5uZW50cywKPiArCQkJ CQkgICAgICAgZmVuY2UpOwo+ICsJb2JqLT5od19yZXNfaGFuZGxlID0gcmVzb3VyY2VfaWQ7Cj4g KwlyZXR1cm4gMDsKPiArfQo+ICsKPiArdm9pZCB2aXJ0aW9fZ3B1X2N1cnNvcl9waW5nKHN0cnVj dCB2aXJ0aW9fZ3B1X2RldmljZSAqdmdkZXYsCj4gKwkJCSAgICBzdHJ1Y3QgdmlydGlvX2dwdV9v dXRwdXQgKm91dHB1dCkKPiArewo+ICsJc3RydWN0IHZpcnRpb19ncHVfdmJ1ZmZlciAqdmJ1ZjsK PiArCXN0cnVjdCB2aXJ0aW9fZ3B1X3VwZGF0ZV9jdXJzb3IgKmN1cl9wOwo+ICsKPiArCW91dHB1 dC0+Y3Vyc29yLnBvcy5zY2Fub3V0X2lkID0gY3B1X3RvX2xlMzIob3V0cHV0LT5pbmRleCk7Cj4g KwljdXJfcCA9IHZpcnRpb19ncHVfYWxsb2NfY3Vyc29yKHZnZGV2LCAmdmJ1Zik7Cj4gKwltZW1j cHkoY3VyX3AsICZvdXRwdXQtPmN1cnNvciwgc2l6ZW9mKG91dHB1dC0+Y3Vyc29yKSk7Cj4gKwl2 aXJ0aW9fZ3B1X3F1ZXVlX2N1cnNvcih2Z2RldiwgdmJ1Zik7Cj4gK30KPiBkaWZmIC0tZ2l0IGEv aW5jbHVkZS9kcm0vZHJtUC5oIGIvaW5jbHVkZS9kcm0vZHJtUC5oCj4gaW5kZXggNjJjNDA3Nzcu LjE1NDRiYjEgMTAwNjQ0Cj4gLS0tIGEvaW5jbHVkZS9kcm0vZHJtUC5oCj4gKysrIGIvaW5jbHVk ZS9kcm0vZHJtUC5oCj4gQEAgLTgxMiw2ICs4MTIsNyBAQCBzdHJ1Y3QgZHJtX2RldmljZSB7Cj4g ICNlbmRpZgo+ICAKPiAgCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBsYXRmb3JtZGV2OyAvKio8 IFBsYXRmb3JtIGRldmljZSBzdHJ1dHVyZSAqLwo+ICsJc3RydWN0IHZpcnRpb19kZXZpY2UgKnZp cnRkZXY7Cj4gIAo+ICAJc3RydWN0IGRybV9zZ19tZW0gKnNnOwkvKio8IFNjYXR0ZXIgZ2F0aGVy IG1lbW9yeSAqLwo+ICAJdW5zaWduZWQgaW50IG51bV9jcnRjczsgICAgICAgICAgICAgICAgICAv Kio8IE51bWJlciBvZiBDUlRDcyBvbiB0aGlzIGRldmljZSAqLwo+IGRpZmYgLS1naXQgYS9pbmNs dWRlL3VhcGkvbGludXgvS2J1aWxkIGIvaW5jbHVkZS91YXBpL2xpbnV4L0tidWlsZAo+IGluZGV4 IDFhMDAwNmEuLjQ0NjBlNTggMTAwNjQ0Cj4gLS0tIGEvaW5jbHVkZS91YXBpL2xpbnV4L0tidWls ZAo+ICsrKyBiL2luY2x1ZGUvdWFwaS9saW51eC9LYnVpbGQKPiBAQCAtNDMwLDYgKzQzMCw3IEBA IGhlYWRlci15ICs9IHZpcnRpb19iYWxsb29uLmgKPiAgaGVhZGVyLXkgKz0gdmlydGlvX2Jsay5o Cj4gIGhlYWRlci15ICs9IHZpcnRpb19jb25maWcuaAo+ICBoZWFkZXIteSArPSB2aXJ0aW9fY29u c29sZS5oCj4gK2hlYWRlci15ICs9IHZpcnRpb19ncHUuaAo+ICBoZWFkZXIteSArPSB2aXJ0aW9f aWRzLmgKPiAgaGVhZGVyLXkgKz0gdmlydGlvX2lucHV0LmgKPiAgaGVhZGVyLXkgKz0gdmlydGlv X25ldC5oCj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9fZ3B1LmggYi9p bmNsdWRlL3VhcGkvbGludXgvdmlydGlvX2dwdS5oCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBp bmRleCAwMDAwMDAwLi41NzFjNGNiCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2luY2x1ZGUvdWFw aS9saW51eC92aXJ0aW9fZ3B1LmgKPiBAQCAtMCwwICsxLDIwNCBAQAo+ICsvKgo+ICsgKiBWaXJ0 aW8gR1BVIERldmljZQo+ICsgKgo+ICsgKiBDb3B5cmlnaHQgUmVkIEhhdCwgSW5jLiAyMDEzLTIw MTQKPiArICoKPiArICogQXV0aG9yczoKPiArICogICAgIERhdmUgQWlybGllIDxhaXJsaWVkQHJl ZGhhdC5jb20+Cj4gKyAqICAgICBHZXJkIEhvZmZtYW5uIDxrcmF4ZWxAcmVkaGF0LmNvbT4KPiAr ICoKPiArICogVGhpcyBoZWFkZXIgaXMgQlNEIGxpY2Vuc2VkIHNvIGFueW9uZSBjYW4gdXNlIHRo ZSBkZWZpbml0aW9ucwo+ICsgKiB0byBpbXBsZW1lbnQgY29tcGF0aWJsZSBkcml2ZXJzL3NlcnZl cnM6Cj4gKyAqCj4gKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5h cnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAo+ICsgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0 ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKPiArICogYXJlIG1ldDoK PiArICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBh Ym92ZSBjb3B5cmlnaHQKPiArICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBh bmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgo+ICsgKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4g YmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAo+ICsgKiAgICBu b3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWlt ZXIgaW4gdGhlCj4gKyAqICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBw cm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCj4gKyAqIDMuIE5laXRoZXIgdGhlIG5hbWUg b2YgSUJNIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwo+ICsgKiAgICBtYXkgYmUg dXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29m dHdhcmUKPiArICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24u Cj4gKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJT IEFORCBDT05UUklCVVRPUlMKPiArICogYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBM SUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAo+ICsgKiBMSU1JVEVEIFRPLCBUSEUg SU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwo+ICsgKiBG T1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFM TCBJQk0gT1IKPiArICogQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5E SVJFQ1QsIElOQ0lERU5UQUwsCj4gKyAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVO VElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKPiArICogTElNSVRFRCBUTywgUFJPQ1VS RU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgo+ICsgKiBVU0Us IERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVT RUQgQU5ECj4gKyAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRS QUNULCBTVFJJQ1QgTElBQklMSVRZLAo+ICsgKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5D RSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKPiArICogT0YgVEhFIFVTRSBP RiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCj4g KyAqIFNVQ0ggREFNQUdFLgo+ICsgKi8KPiArCj4gKyNpZm5kZWYgVklSVElPX0dQVV9IV19ICj4g KyNkZWZpbmUgVklSVElPX0dQVV9IV19ICj4gKwo+ICtlbnVtIHZpcnRpb19ncHVfY3RybF90eXBl IHsKPiArCVZJUlRJT19HUFVfVU5ERUZJTkVEID0gMCwKPiArCj4gKwkvKiAyZCBjb21tYW5kcyAq Lwo+ICsJVklSVElPX0dQVV9DTURfR0VUX0RJU1BMQVlfSU5GTyA9IDB4MDEwMCwKPiArCVZJUlRJ T19HUFVfQ01EX1JFU09VUkNFX0NSRUFURV8yRCwKPiArCVZJUlRJT19HUFVfQ01EX1JFU09VUkNF X1VOUkVGLAo+ICsJVklSVElPX0dQVV9DTURfU0VUX1NDQU5PVVQsCj4gKwlWSVJUSU9fR1BVX0NN RF9SRVNPVVJDRV9GTFVTSCwKPiArCVZJUlRJT19HUFVfQ01EX1RSQU5TRkVSX1RPX0hPU1RfMkQs Cj4gKwlWSVJUSU9fR1BVX0NNRF9SRVNPVVJDRV9BVFRBQ0hfQkFDS0lORywKPiArCVZJUlRJT19H UFVfQ01EX1JFU09VUkNFX0RFVEFDSF9CQUNLSU5HLAo+ICsKPiArCS8qIGN1cnNvciBjb21tYW5k cyAqLwo+ICsJVklSVElPX0dQVV9DTURfVVBEQVRFX0NVUlNPUiA9IDB4MDMwMCwKPiArCVZJUlRJ T19HUFVfQ01EX01PVkVfQ1VSU09SLAo+ICsKPiArCS8qIHN1Y2Nlc3MgcmVzcG9uc2VzICovCj4g KwlWSVJUSU9fR1BVX1JFU1BfT0tfTk9EQVRBID0gMHgxMTAwLAo+ICsJVklSVElPX0dQVV9SRVNQ X09LX0RJU1BMQVlfSU5GTywKPiArCj4gKwkvKiBlcnJvciByZXNwb25zZXMgKi8KPiArCVZJUlRJ T19HUFVfUkVTUF9FUlJfVU5TUEVDID0gMHgxMjAwLAo+ICsJVklSVElPX0dQVV9SRVNQX0VSUl9P VVRfT0ZfTUVNT1JZLAo+ICsJVklSVElPX0dQVV9SRVNQX0VSUl9JTlZBTElEX1NDQU5PVVRfSUQs Cj4gKwlWSVJUSU9fR1BVX1JFU1BfRVJSX0lOVkFMSURfUkVTT1VSQ0VfSUQsCj4gKwlWSVJUSU9f R1BVX1JFU1BfRVJSX0lOVkFMSURfQ09OVEVYVF9JRCwKPiArCVZJUlRJT19HUFVfUkVTUF9FUlJf SU5WQUxJRF9QQVJBTUVURVIsCj4gK307Cj4gKwo+ICsjZGVmaW5lIFZJUlRJT19HUFVfRkxBR19G RU5DRSAoMSA8PCAwKQo+ICsKPiArc3RydWN0IHZpcnRpb19ncHVfY3RybF9oZHIgewo+ICsJX19s ZTMyIHR5cGU7Cj4gKwlfX2xlMzIgZmxhZ3M7Cj4gKwlfX2xlNjQgZmVuY2VfaWQ7Cj4gKwlfX2xl MzIgY3R4X2lkOwo+ICsJX19sZTMyIHBhZGRpbmc7Cj4gK307Cj4gKwo+ICsvKiBkYXRhIHBhc3Nl ZCBpbiB0aGUgY3Vyc29yIHZxICovCj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9jdXJzb3JfcG9z IHsKPiArCV9fbGUzMiBzY2Fub3V0X2lkOwo+ICsJX19sZTMyIHg7Cj4gKwlfX2xlMzIgeTsKPiAr CV9fbGUzMiBwYWRkaW5nOwo+ICt9Owo+ICsKPiArLyogVklSVElPX0dQVV9DTURfVVBEQVRFX0NV UlNPUiwgVklSVElPX0dQVV9DTURfTU9WRV9DVVJTT1IgKi8KPiArc3RydWN0IHZpcnRpb19ncHVf dXBkYXRlX2N1cnNvciB7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hkciBoZHI7Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9jdXJzb3JfcG9zIHBvczsgIC8qIHVwZGF0ZSAmIG1vdmUgKi8KPiAr CV9fbGUzMiByZXNvdXJjZV9pZDsgICAgICAgICAgIC8qIHVwZGF0ZSBvbmx5ICovCj4gKwlfX2xl MzIgaG90X3g7ICAgICAgICAgICAgICAgICAvKiB1cGRhdGUgb25seSAqLwo+ICsJX19sZTMyIGhv dF95OyAgICAgICAgICAgICAgICAgLyogdXBkYXRlIG9ubHkgKi8KPiArCV9fbGUzMiBwYWRkaW5n Owo+ICt9Owo+ICsKPiArLyogZGF0YSBwYXNzZWQgaW4gdGhlIGNvbnRyb2wgdnEsIDJkIHJlbGF0 ZWQgKi8KPiArCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X3JlY3Qgewo+ICsJX19sZTMyIHg7Cj4gKwlf X2xlMzIgeTsKPiArCV9fbGUzMiB3aWR0aDsKPiArCV9fbGUzMiBoZWlnaHQ7Cj4gK307Cj4gKwo+ ICsvKiBWSVJUSU9fR1BVX0NNRF9SRVNPVVJDRV9VTlJFRiAqLwo+ICtzdHJ1Y3QgdmlydGlvX2dw dV9yZXNvdXJjZV91bnJlZiB7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hkciBoZHI7Cj4g KwlfX2xlMzIgcmVzb3VyY2VfaWQ7Cj4gKwlfX2xlMzIgcGFkZGluZzsKPiArfTsKPiArCj4gKy8q IFZJUlRJT19HUFVfQ01EX1JFU09VUkNFX0NSRUFURV8yRDogY3JlYXRlIGEgMmQgcmVzb3VyY2Ug d2l0aCBhIGZvcm1hdCAqLwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9yZXNvdXJjZV9jcmVhdGVfMmQg ewo+ICsJc3RydWN0IHZpcnRpb19ncHVfY3RybF9oZHIgaGRyOwo+ICsJX19sZTMyIHJlc291cmNl X2lkOwo+ICsJX19sZTMyIGZvcm1hdDsKPiArCV9fbGUzMiB3aWR0aDsKPiArCV9fbGUzMiBoZWln aHQ7Cj4gK307Cj4gKwo+ICsvKiBWSVJUSU9fR1BVX0NNRF9TRVRfU0NBTk9VVCAqLwo+ICtzdHJ1 Y3QgdmlydGlvX2dwdV9zZXRfc2Nhbm91dCB7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hk ciBoZHI7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9yZWN0IHI7Cj4gKwlfX2xlMzIgc2Nhbm91dF9p ZDsKPiArCV9fbGUzMiByZXNvdXJjZV9pZDsKPiArfTsKPiArCj4gKy8qIFZJUlRJT19HUFVfQ01E X1JFU09VUkNFX0ZMVVNIICovCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X3Jlc291cmNlX2ZsdXNoIHsK PiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2N0cmxfaGRyIGhkcjsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1 X3JlY3QgcjsKPiArCV9fbGUzMiByZXNvdXJjZV9pZDsKPiArCV9fbGUzMiBwYWRkaW5nOwo+ICt9 Owo+ICsKPiArLyogVklSVElPX0dQVV9DTURfVFJBTlNGRVJfVE9fSE9TVF8yRDogc2ltcGxlIHRy YW5zZmVyIHRvX2hvc3QgKi8KPiArc3RydWN0IHZpcnRpb19ncHVfdHJhbnNmZXJfdG9faG9zdF8y ZCB7Cj4gKwlzdHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hkciBoZHI7Cj4gKwlzdHJ1Y3QgdmlydGlv X2dwdV9yZWN0IHI7Cj4gKwlfX2xlNjQgb2Zmc2V0Owo+ICsJX19sZTMyIHJlc291cmNlX2lkOwo+ ICsJX19sZTMyIHBhZGRpbmc7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9tZW1fZW50 cnkgewo+ICsJX19sZTY0IGFkZHI7Cj4gKwlfX2xlMzIgbGVuZ3RoOwo+ICsJX19sZTMyIHBhZGRp bmc7Cj4gK307Cj4gKwo+ICsvKiBWSVJUSU9fR1BVX0NNRF9SRVNPVVJDRV9BVFRBQ0hfQkFDS0lO RyAqLwo+ICtzdHJ1Y3QgdmlydGlvX2dwdV9yZXNvdXJjZV9hdHRhY2hfYmFja2luZyB7Cj4gKwlz dHJ1Y3QgdmlydGlvX2dwdV9jdHJsX2hkciBoZHI7Cj4gKwlfX2xlMzIgcmVzb3VyY2VfaWQ7Cj4g KwlfX2xlMzIgbnJfZW50cmllczsKPiArfTsKPiArCj4gKy8qIFZJUlRJT19HUFVfQ01EX1JFU09V UkNFX0RFVEFDSF9CQUNLSU5HICovCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X3Jlc291cmNlX2RldGFj aF9iYWNraW5nIHsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2N0cmxfaGRyIGhkcjsKPiArCV9fbGUz MiByZXNvdXJjZV9pZDsKPiArCV9fbGUzMiBwYWRkaW5nOwo+ICt9Owo+ICsKPiArLyogVklSVElP X0dQVV9SRVNQX09LX0RJU1BMQVlfSU5GTyAqLwo+ICsjZGVmaW5lIFZJUlRJT19HUFVfTUFYX1ND QU5PVVRTIDE2Cj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X3Jlc3BfZGlzcGxheV9pbmZvIHsKPiArCXN0 cnVjdCB2aXJ0aW9fZ3B1X2N0cmxfaGRyIGhkcjsKPiArCXN0cnVjdCB2aXJ0aW9fZ3B1X2Rpc3Bs YXlfb25lIHsKPiArCQlzdHJ1Y3QgdmlydGlvX2dwdV9yZWN0IHI7Cj4gKwkJX19sZTMyIGVuYWJs ZWQ7Cj4gKwkJX19sZTMyIGZsYWdzOwo+ICsJfSBwbW9kZXNbVklSVElPX0dQVV9NQVhfU0NBTk9V VFNdOwo+ICt9Owo+ICsKPiArI2RlZmluZSBWSVJUSU9fR1BVX0VWRU5UX0RJU1BMQVkgKDEgPDwg MCkKPiArCj4gK3N0cnVjdCB2aXJ0aW9fZ3B1X2NvbmZpZyB7Cj4gKwlfX3UzMiBldmVudHNfcmVh ZDsKPiArCV9fdTMyIGV2ZW50c19jbGVhcjsKPiArCV9fdTMyIG51bV9zY2Fub3V0czsKPiArCV9f dTMyIHJlc2VydmVkOwo+ICt9Owo+ICsKPiArLyogc2ltcGxlIGZvcm1hdHMgZm9yIGZiY29uL1gg dXNlICovCj4gK2VudW0gdmlydGlvX2dwdV9mb3JtYXRzIHsKPiArCVZJUlRJT19HUFVfRk9STUFU X0I4RzhSOEE4X1VOT1JNICA9IDEsCj4gKwlWSVJUSU9fR1BVX0ZPUk1BVF9COEc4UjhYOF9VTk9S TSAgPSAyLAo+ICsJVklSVElPX0dQVV9GT1JNQVRfQThSOEc4QjhfVU5PUk0gID0gMywKPiArCVZJ UlRJT19HUFVfRk9STUFUX1g4UjhHOEI4X1VOT1JNICA9IDQsCj4gKwo+ICsJVklSVElPX0dQVV9G T1JNQVRfUjhHOEI4QThfVU5PUk0gID0gNjcsCj4gKwlWSVJUSU9fR1BVX0ZPUk1BVF9YOEI4RzhS OF9VTk9STSAgPSA2OCwKPiArCj4gKwlWSVJUSU9fR1BVX0ZPUk1BVF9BOEI4RzhSOF9VTk9STSAg PSAxMjEsCj4gKwlWSVJUSU9fR1BVX0ZPUk1BVF9SOEc4QjhYOF9VTk9STSAgPSAxMzQsCj4gK307 Cj4gKwo+ICsjZW5kaWYKPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS91YXBpL2xpbnV4L3ZpcnRpb19p ZHMuaCBiL2luY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9faWRzLmgKPiBpbmRleCA1ZjYwYWE0Li43 NzkyNWY1IDEwMDY0NAo+IC0tLSBhL2luY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9faWRzLmgKPiAr KysgYi9pbmNsdWRlL3VhcGkvbGludXgvdmlydGlvX2lkcy5oCj4gQEAgLTM5LDYgKzM5LDcgQEAK PiAgI2RlZmluZSBWSVJUSU9fSURfOVAJCTkgLyogOXAgdmlydGlvIGNvbnNvbGUgKi8KPiAgI2Rl ZmluZSBWSVJUSU9fSURfUlBST0NfU0VSSUFMIDExIC8qIHZpcnRpbyByZW1vdGVwcm9jIHNlcmlh bCBsaW5rICovCj4gICNkZWZpbmUgVklSVElPX0lEX0NBSUYJICAgICAgIDEyIC8qIFZpcnRpbyBj YWlmICovCj4gKyNkZWZpbmUgVklSVElPX0lEX0dQVSAgICAgICAgICAxNiAvKiB2aXJ0aW8gR1BV ICovCj4gICNkZWZpbmUgVklSVElPX0lEX0lOUFVUICAgICAgICAxOCAvKiB2aXJ0aW8gaW5wdXQg Ki8KPiAgCj4gICNlbmRpZiAvKiBfTElOVVhfVklSVElPX0lEU19IICovCj4gLS0gCj4gMS44LjMu MQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2 ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDovL2xp c3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754924AbbFBIdk (ORCPT ); Tue, 2 Jun 2015 04:33:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57382 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752854AbbFBIdc (ORCPT ); Tue, 2 Jun 2015 04:33:32 -0400 Date: Tue, 2 Jun 2015 10:33:26 +0200 From: "Michael S. Tsirkin" To: Gerd Hoffmann Cc: dri-devel@lists.freedesktop.org, airlied@redhat.com, Dave Airlie , David Airlie , open list , "open list:ABI/API" , "open list:VIRTIO CORE, NET..." Subject: Re: [PATCH v3 4/4] Add virtio gpu driver. Message-ID: <20150602102929-mutt-send-email-mst@redhat.com> References: <1432300312-24792-1-git-send-email-kraxel@redhat.com> <1432300312-24792-5-git-send-email-kraxel@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1432300312-24792-5-git-send-email-kraxel@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 22, 2015 at 03:11:52PM +0200, Gerd Hoffmann wrote: > From: Dave Airlie > > This patch adds a kms driver for the virtio gpu. The xorg modesetting > driver can handle the device just fine, the framebuffer for fbcon is > there too. > > Qemu patches for the host side are under review currently. > > The pci version of the device comes in two variants: with and without > vga compatibility. The former has a extra memory bar for the vga > framebuffer, the later is a pure virtio device. The only concern for > this driver is that in the virtio-vga case we have to kick out the > firmware framebuffer. > > Initial revision has only 2d support, 3d (virgl) support requires > some more work on the qemu side and will be added later. > > Signed-off-by: Dave Airlie > Signed-off-by: Gerd Hoffmann I think it's ok to merge this through the dri tree. Acked-by: Michael S. Tsirkin > --- > drivers/gpu/drm/Kconfig | 2 + > drivers/gpu/drm/Makefile | 1 + > drivers/gpu/drm/virtio/Kconfig | 14 + > drivers/gpu/drm/virtio/Makefile | 11 + > drivers/gpu/drm/virtio/virtgpu_debugfs.c | 64 ++++ > drivers/gpu/drm/virtio/virtgpu_display.c | 485 ++++++++++++++++++++++++ > drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 91 +++++ > drivers/gpu/drm/virtio/virtgpu_drv.c | 136 +++++++ > drivers/gpu/drm/virtio/virtgpu_drv.h | 350 ++++++++++++++++++ > drivers/gpu/drm/virtio/virtgpu_fb.c | 431 ++++++++++++++++++++++ > drivers/gpu/drm/virtio/virtgpu_fence.c | 119 ++++++ > drivers/gpu/drm/virtio/virtgpu_gem.c | 140 +++++++ > drivers/gpu/drm/virtio/virtgpu_kms.c | 164 +++++++++ > drivers/gpu/drm/virtio/virtgpu_object.c | 170 +++++++++ > drivers/gpu/drm/virtio/virtgpu_plane.c | 120 ++++++ > drivers/gpu/drm/virtio/virtgpu_ttm.c | 469 +++++++++++++++++++++++ > drivers/gpu/drm/virtio/virtgpu_vq.c | 614 +++++++++++++++++++++++++++++++ > include/drm/drmP.h | 1 + > include/uapi/linux/Kbuild | 1 + > include/uapi/linux/virtio_gpu.h | 204 ++++++++++ > include/uapi/linux/virtio_ids.h | 1 + > 21 files changed, 3588 insertions(+) > create mode 100644 drivers/gpu/drm/virtio/Kconfig > create mode 100644 drivers/gpu/drm/virtio/Makefile > create mode 100644 drivers/gpu/drm/virtio/virtgpu_debugfs.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_display.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_drm_bus.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_drv.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_drv.h > create mode 100644 drivers/gpu/drm/virtio/virtgpu_fb.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_fence.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_gem.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_kms.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_object.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_plane.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_ttm.c > create mode 100644 drivers/gpu/drm/virtio/virtgpu_vq.c > create mode 100644 include/uapi/linux/virtio_gpu.h > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 47f2ce8..d4b6545 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -206,6 +206,8 @@ source "drivers/gpu/drm/qxl/Kconfig" > > source "drivers/gpu/drm/bochs/Kconfig" > > +source "drivers/gpu/drm/virtio/Kconfig" > + > source "drivers/gpu/drm/msm/Kconfig" > > source "drivers/gpu/drm/tegra/Kconfig" > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile > index 7d4944e..dbbc101 100644 > --- a/drivers/gpu/drm/Makefile > +++ b/drivers/gpu/drm/Makefile > @@ -63,6 +63,7 @@ obj-$(CONFIG_DRM_OMAP) += omapdrm/ > obj-$(CONFIG_DRM_TILCDC) += tilcdc/ > obj-$(CONFIG_DRM_QXL) += qxl/ > obj-$(CONFIG_DRM_BOCHS) += bochs/ > +obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/ > obj-$(CONFIG_DRM_MSM) += msm/ > obj-$(CONFIG_DRM_TEGRA) += tegra/ > obj-$(CONFIG_DRM_STI) += sti/ > diff --git a/drivers/gpu/drm/virtio/Kconfig b/drivers/gpu/drm/virtio/Kconfig > new file mode 100644 > index 0000000..9983ead > --- /dev/null > +++ b/drivers/gpu/drm/virtio/Kconfig > @@ -0,0 +1,14 @@ > +config DRM_VIRTIO_GPU > + tristate "Virtio GPU driver" > + depends on DRM && VIRTIO > + select FB_SYS_FILLRECT > + select FB_SYS_COPYAREA > + select FB_SYS_IMAGEBLIT > + select DRM_KMS_HELPER > + select DRM_KMS_FB_HELPER > + select DRM_TTM > + help > + This is the virtual GPU driver for virtio. It can be used with > + QEMU based VMMs (like KVM or Xen). > + > + If unsure say M. > diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile > new file mode 100644 > index 0000000..2ee1602 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/Makefile > @@ -0,0 +1,11 @@ > +# > +# Makefile for the drm device driver. This driver provides support for the > +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. > + > +ccflags-y := -Iinclude/drm > + > +virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ > + virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ > + virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o > + > +obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio-gpu.o > diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c b/drivers/gpu/drm/virtio/virtgpu_debugfs.c > new file mode 100644 > index 0000000..db8b491 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c > @@ -0,0 +1,64 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > + > +#include "drmP.h" > +#include "virtgpu_drv.h" > + > +static int > +virtio_gpu_debugfs_irq_info(struct seq_file *m, void *data) > +{ > + struct drm_info_node *node = (struct drm_info_node *) m->private; > + struct virtio_gpu_device *vgdev = node->minor->dev->dev_private; > + > + seq_printf(m, "fence %ld %lld\n", > + atomic64_read(&vgdev->fence_drv.last_seq), > + vgdev->fence_drv.sync_seq); > + return 0; > +} > + > +static struct drm_info_list virtio_gpu_debugfs_list[] = { > + { "irq_fence", virtio_gpu_debugfs_irq_info, 0, NULL }, > +}; > + > +#define VIRTIO_GPU_DEBUGFS_ENTRIES ARRAY_SIZE(virtio_gpu_debugfs_list) > + > +int > +virtio_gpu_debugfs_init(struct drm_minor *minor) > +{ > + drm_debugfs_create_files(virtio_gpu_debugfs_list, > + VIRTIO_GPU_DEBUGFS_ENTRIES, > + minor->debugfs_root, minor); > + return 0; > +} > + > +void > +virtio_gpu_debugfs_takedown(struct drm_minor *minor) > +{ > + drm_debugfs_remove_files(virtio_gpu_debugfs_list, > + VIRTIO_GPU_DEBUGFS_ENTRIES, > + minor); > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c > new file mode 100644 > index 0000000..a2eca5f > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_display.c > @@ -0,0 +1,485 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Authors: > + * Dave Airlie > + * Alon Levy > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include "virtgpu_drv.h" > +#include > +#include > + > +#define XRES_MIN 320 > +#define YRES_MIN 200 > + > +#define XRES_DEF 1024 > +#define YRES_DEF 768 > + > +#define XRES_MAX 8192 > +#define YRES_MAX 8192 > + > +static int virtio_gpu_fbdev = 1; > + > +MODULE_PARM_DESC(fbdev, "Disable/Enable framebuffer device & console"); > +module_param_named(fbdev, virtio_gpu_fbdev, int, 0400); > + > +static void virtio_gpu_crtc_gamma_set(struct drm_crtc *crtc, > + u16 *red, u16 *green, u16 *blue, > + uint32_t start, uint32_t size) > +{ > + /* TODO */ > +} > + > +static void > +virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_output *output) > +{ > + output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); > + output->cursor.resource_id = 0; > + virtio_gpu_cursor_ping(vgdev, output); > +} > + > +static int virtio_gpu_crtc_cursor_set(struct drm_crtc *crtc, > + struct drm_file *file_priv, > + uint32_t handle, > + uint32_t width, > + uint32_t height, > + int32_t hot_x, int32_t hot_y) > +{ > + struct virtio_gpu_device *vgdev = crtc->dev->dev_private; > + struct virtio_gpu_output *output = > + container_of(crtc, struct virtio_gpu_output, crtc); > + struct drm_gem_object *gobj = NULL; > + struct virtio_gpu_object *qobj = NULL; > + struct virtio_gpu_fence *fence = NULL; > + int ret = 0; > + > + if (handle == 0) { > + virtio_gpu_hide_cursor(vgdev, output); > + return 0; > + } > + > + /* lookup the cursor */ > + gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle); > + if (gobj == NULL) > + return -ENOENT; > + > + qobj = gem_to_virtio_gpu_obj(gobj); > + > + if (!qobj->hw_res_handle) { > + ret = -EINVAL; > + goto out; > + } > + > + virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0, > + cpu_to_le32(64), > + cpu_to_le32(64), > + 0, 0, &fence); > + > + output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); > + output->cursor.resource_id = cpu_to_le32(qobj->hw_res_handle); > + output->cursor.hot_x = cpu_to_le32(hot_x); > + output->cursor.hot_y = cpu_to_le32(hot_y); > + virtio_gpu_cursor_ping(vgdev, output); > + ret = 0; > + > +out: > + drm_gem_object_unreference_unlocked(gobj); > + return ret; > +} > + > +static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc, > + int x, int y) > +{ > + struct virtio_gpu_device *vgdev = crtc->dev->dev_private; > + struct virtio_gpu_output *output = > + container_of(crtc, struct virtio_gpu_output, crtc); > + > + output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR); > + output->cursor.pos.x = cpu_to_le32(x); > + output->cursor.pos.y = cpu_to_le32(y); > + virtio_gpu_cursor_ping(vgdev, output); > + return 0; > +} > + > +static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { > + .cursor_set2 = virtio_gpu_crtc_cursor_set, > + .cursor_move = virtio_gpu_crtc_cursor_move, > + .gamma_set = virtio_gpu_crtc_gamma_set, > + .set_config = drm_atomic_helper_set_config, > + .destroy = drm_crtc_cleanup, > + > +#if 0 /* not (yet) working without vblank support according to docs */ > + .page_flip = drm_atomic_helper_page_flip, > +#endif > + .reset = drm_atomic_helper_crtc_reset, > + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, > +}; > + > +static void virtio_gpu_user_framebuffer_destroy(struct drm_framebuffer *fb) > +{ > + struct virtio_gpu_framebuffer *virtio_gpu_fb > + = to_virtio_gpu_framebuffer(fb); > + > + if (virtio_gpu_fb->obj) > + drm_gem_object_unreference_unlocked(virtio_gpu_fb->obj); > + drm_framebuffer_cleanup(fb); > + kfree(virtio_gpu_fb); > +} > + > +static int > +virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb, > + struct drm_file *file_priv, > + unsigned flags, unsigned color, > + struct drm_clip_rect *clips, > + unsigned num_clips) > +{ > + struct virtio_gpu_framebuffer *virtio_gpu_fb > + = to_virtio_gpu_framebuffer(fb); > + > + return virtio_gpu_surface_dirty(virtio_gpu_fb, clips, num_clips); > +} > + > +static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { > + .destroy = virtio_gpu_user_framebuffer_destroy, > + .dirty = virtio_gpu_framebuffer_surface_dirty, > +}; > + > +int > +virtio_gpu_framebuffer_init(struct drm_device *dev, > + struct virtio_gpu_framebuffer *vgfb, > + struct drm_mode_fb_cmd2 *mode_cmd, > + struct drm_gem_object *obj) > +{ > + int ret; > + struct virtio_gpu_object *bo; > + vgfb->obj = obj; > + > + bo = gem_to_virtio_gpu_obj(obj); > + > + ret = drm_framebuffer_init(dev, &vgfb->base, &virtio_gpu_fb_funcs); > + if (ret) { > + vgfb->obj = NULL; > + return ret; > + } > + drm_helper_mode_fill_fb_struct(&vgfb->base, mode_cmd); > + > + spin_lock_init(&vgfb->dirty_lock); > + vgfb->x1 = vgfb->y1 = INT_MAX; > + vgfb->x2 = vgfb->y2 = 0; > + return 0; > +} > + > +static bool virtio_gpu_crtc_mode_fixup(struct drm_crtc *crtc, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + return true; > +} > + > +static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) > +{ > + struct drm_device *dev = crtc->dev; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); > + > + virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, > + crtc->mode.hdisplay, > + crtc->mode.vdisplay, 0, 0); > +} > + > +static void virtio_gpu_crtc_enable(struct drm_crtc *crtc) > +{ > +} > + > +static void virtio_gpu_crtc_disable(struct drm_crtc *crtc) > +{ > + struct drm_device *dev = crtc->dev; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); > + > + virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); > +} > + > +static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, > + struct drm_crtc_state *state) > +{ > + return 0; > +} > + > +static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = { > + .enable = virtio_gpu_crtc_enable, > + .disable = virtio_gpu_crtc_disable, > + .mode_fixup = virtio_gpu_crtc_mode_fixup, > + .mode_set_nofb = virtio_gpu_crtc_mode_set_nofb, > + .atomic_check = virtio_gpu_crtc_atomic_check, > +}; > + > +static bool virtio_gpu_enc_mode_fixup(struct drm_encoder *encoder, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + return true; > +} > + > +static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > +} > + > +static void virtio_gpu_enc_enable(struct drm_encoder *encoder) > +{ > +} > + > +static void virtio_gpu_enc_disable(struct drm_encoder *encoder) > +{ > +} > + > +static int virtio_gpu_conn_get_modes(struct drm_connector *connector) > +{ > + struct virtio_gpu_output *output = > + drm_connector_to_virtio_gpu_output(connector); > + struct drm_display_mode *mode = NULL; > + int count, width, height; > + > + width = le32_to_cpu(output->info.r.width); > + height = le32_to_cpu(output->info.r.height); > + count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); > + > + if (width == 0 || height == 0) { > + width = XRES_DEF; > + height = YRES_DEF; > + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); > + } else { > + DRM_DEBUG("add mode: %dx%d\n", width, height); > + mode = drm_cvt_mode(connector->dev, width, height, 60, > + false, false, false); > + mode->type |= DRM_MODE_TYPE_PREFERRED; > + drm_mode_probed_add(connector, mode); > + count++; > + } > + > + return count; > +} > + > +static int virtio_gpu_conn_mode_valid(struct drm_connector *connector, > + struct drm_display_mode *mode) > +{ > + struct virtio_gpu_output *output = > + drm_connector_to_virtio_gpu_output(connector); > + int width, height; > + > + width = le32_to_cpu(output->info.r.width); > + height = le32_to_cpu(output->info.r.height); > + > + if (!(mode->type & DRM_MODE_TYPE_PREFERRED)) > + return MODE_OK; > + if (mode->hdisplay == XRES_DEF && mode->vdisplay == YRES_DEF) > + return MODE_OK; > + if (mode->hdisplay <= width && mode->hdisplay >= width - 16 && > + mode->vdisplay <= height && mode->vdisplay >= height - 16) > + return MODE_OK; > + > + DRM_DEBUG("del mode: %dx%d\n", mode->hdisplay, mode->vdisplay); > + return MODE_BAD; > +} > + > +static struct drm_encoder* > +virtio_gpu_best_encoder(struct drm_connector *connector) > +{ > + struct virtio_gpu_output *virtio_gpu_output = > + drm_connector_to_virtio_gpu_output(connector); > + > + return &virtio_gpu_output->enc; > +} > + > +static const struct drm_encoder_helper_funcs virtio_gpu_enc_helper_funcs = { > + .mode_fixup = virtio_gpu_enc_mode_fixup, > + .mode_set = virtio_gpu_enc_mode_set, > + .enable = virtio_gpu_enc_enable, > + .disable = virtio_gpu_enc_disable, > +}; > + > +static const struct drm_connector_helper_funcs virtio_gpu_conn_helper_funcs = { > + .get_modes = virtio_gpu_conn_get_modes, > + .mode_valid = virtio_gpu_conn_mode_valid, > + .best_encoder = virtio_gpu_best_encoder, > +}; > + > +static void virtio_gpu_conn_save(struct drm_connector *connector) > +{ > + DRM_DEBUG("\n"); > +} > + > +static void virtio_gpu_conn_restore(struct drm_connector *connector) > +{ > + DRM_DEBUG("\n"); > +} > + > +static enum drm_connector_status virtio_gpu_conn_detect( > + struct drm_connector *connector, > + bool force) > +{ > + struct virtio_gpu_output *output = > + drm_connector_to_virtio_gpu_output(connector); > + > + if (output->info.enabled) > + return connector_status_connected; > + else > + return connector_status_disconnected; > +} > + > +static void virtio_gpu_conn_destroy(struct drm_connector *connector) > +{ > + struct virtio_gpu_output *virtio_gpu_output = > + drm_connector_to_virtio_gpu_output(connector); > + > + drm_connector_unregister(connector); > + drm_connector_cleanup(connector); > + kfree(virtio_gpu_output); > +} > + > +static const struct drm_connector_funcs virtio_gpu_connector_funcs = { > + .dpms = drm_atomic_helper_connector_dpms, > + .save = virtio_gpu_conn_save, > + .restore = virtio_gpu_conn_restore, > + .detect = virtio_gpu_conn_detect, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .destroy = virtio_gpu_conn_destroy, > + .reset = drm_atomic_helper_connector_reset, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > +}; > + > +static const struct drm_encoder_funcs virtio_gpu_enc_funcs = { > + .destroy = drm_encoder_cleanup, > +}; > + > +static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) > +{ > + struct drm_device *dev = vgdev->ddev; > + struct virtio_gpu_output *output = vgdev->outputs + index; > + struct drm_connector *connector = &output->conn; > + struct drm_encoder *encoder = &output->enc; > + struct drm_crtc *crtc = &output->crtc; > + struct drm_plane *plane; > + > + output->index = index; > + if (index == 0) { > + output->info.enabled = cpu_to_le32(true); > + output->info.r.width = cpu_to_le32(XRES_DEF); > + output->info.r.height = cpu_to_le32(YRES_DEF); > + } > + > + plane = virtio_gpu_plane_init(vgdev, index); > + if (IS_ERR(plane)) > + return PTR_ERR(plane); > + drm_crtc_init_with_planes(dev, crtc, plane, NULL, > + &virtio_gpu_crtc_funcs); > + drm_mode_crtc_set_gamma_size(crtc, 256); > + drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs); > + plane->crtc = crtc; > + > + drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, > + DRM_MODE_CONNECTOR_VIRTUAL); > + drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs); > + > + drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs, > + DRM_MODE_ENCODER_VIRTUAL); > + drm_encoder_helper_add(encoder, &virtio_gpu_enc_helper_funcs); > + encoder->possible_crtcs = 1 << index; > + > + drm_mode_connector_attach_encoder(connector, encoder); > + drm_connector_register(connector); > + return 0; > +} > + > +static struct drm_framebuffer * > +virtio_gpu_user_framebuffer_create(struct drm_device *dev, > + struct drm_file *file_priv, > + struct drm_mode_fb_cmd2 *mode_cmd) > +{ > + struct drm_gem_object *obj = NULL; > + struct virtio_gpu_framebuffer *virtio_gpu_fb; > + int ret; > + > + /* lookup object associated with res handle */ > + obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); > + if (!obj) > + return ERR_PTR(-EINVAL); > + > + virtio_gpu_fb = kzalloc(sizeof(*virtio_gpu_fb), GFP_KERNEL); > + if (virtio_gpu_fb == NULL) > + return ERR_PTR(-ENOMEM); > + > + ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj); > + if (ret) { > + kfree(virtio_gpu_fb); > + if (obj) > + drm_gem_object_unreference_unlocked(obj); > + return NULL; > + } > + > + return &virtio_gpu_fb->base; > +} > + > +static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { > + .fb_create = virtio_gpu_user_framebuffer_create, > + .atomic_check = drm_atomic_helper_check, > + .atomic_commit = drm_atomic_helper_commit, > +}; > + > +int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) > +{ > + int i, ret; > + > + drm_mode_config_init(vgdev->ddev); > + vgdev->ddev->mode_config.funcs = (void *)&virtio_gpu_mode_funcs; > + > + /* modes will be validated against the framebuffer size */ > + vgdev->ddev->mode_config.min_width = XRES_MIN; > + vgdev->ddev->mode_config.min_height = YRES_MIN; > + vgdev->ddev->mode_config.max_width = XRES_MAX; > + vgdev->ddev->mode_config.max_height = YRES_MAX; > + > + for (i = 0 ; i < vgdev->num_scanouts; ++i) > + vgdev_output_init(vgdev, i); > + > + drm_mode_config_reset(vgdev->ddev); > + > + if (virtio_gpu_fbdev) { > + ret = virtio_gpu_fbdev_init(vgdev); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) > +{ > + virtio_gpu_fbdev_fini(vgdev); > + drm_mode_config_cleanup(vgdev->ddev); > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c > new file mode 100644 > index 0000000..f4ec816 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c > @@ -0,0 +1,91 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > + > +#include "virtgpu_drv.h" > + > +int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master) > +{ > + struct pci_dev *pdev = dev->pdev; > + > + if (pdev) { > + return drm_pci_set_busid(dev, master); > + } > + return 0; > +} > + > +int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev) > +{ > + struct drm_device *dev; > + int ret; > + > + dev = drm_dev_alloc(driver, &vdev->dev); > + if (!dev) > + return -ENOMEM; > + dev->virtdev = vdev; > + vdev->priv = dev; > + > + if (strcmp(vdev->dev.parent->bus->name, "pci") == 0) { > + struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); > + bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; > + > + if (vga) { > + /* > + * Need to make sure we don't have two drivers > + * for the same hardware here. Some day we > + * will simply kick out the firmware > + * (vesa/efi) framebuffer. > + * > + * Virtual hardware specs for virtio-vga are > + * not finalized yet, therefore we can't add > + * code for that yet. > + * > + * So ignore the device for the time being, > + * and suggest to the user use the device > + * variant without vga compatibility mode. > + */ > + DRM_ERROR("virtio-vga not (yet) supported\n"); > + DRM_ERROR("please use virtio-gpu-pci instead\n"); > + ret = -ENODEV; > + goto err_free; > + } > + dev->pdev = pdev; > + } > + > + ret = drm_dev_register(dev, 0); > + if (ret) > + goto err_free; > + > + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, > + driver->major, driver->minor, driver->patchlevel, > + driver->date, dev->primary->index); > + > + return 0; > + > +err_free: > + drm_dev_unref(dev); > + return ret; > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c > new file mode 100644 > index 0000000..7d9610a > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c > @@ -0,0 +1,136 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Authors: > + * Dave Airlie > + * Gerd Hoffmann > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include > +#include > +#include "drmP.h" > +#include "drm/drm.h" > + > +#include "virtgpu_drv.h" > +static struct drm_driver driver; > + > +static int virtio_gpu_modeset = -1; > + > +MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); > +module_param_named(modeset, virtio_gpu_modeset, int, 0400); > + > +static int virtio_gpu_probe(struct virtio_device *vdev) > +{ > +#ifdef CONFIG_VGA_CONSOLE > + if (vgacon_text_force() && virtio_gpu_modeset == -1) > + return -EINVAL; > +#endif > + > + if (virtio_gpu_modeset == 0) > + return -EINVAL; > + > + return drm_virtio_init(&driver, vdev); > +} > + > +static void virtio_gpu_remove(struct virtio_device *vdev) > +{ > + struct drm_device *dev = vdev->priv; > + drm_put_dev(dev); > +} > + > +static void virtio_gpu_config_changed(struct virtio_device *vdev) > +{ > + struct drm_device *dev = vdev->priv; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + > + schedule_work(&vgdev->config_changed_work); > +} > + > +static struct virtio_device_id id_table[] = { > + { VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID }, > + { 0 }, > +}; > + > +static unsigned int features[] = { > +}; > +static struct virtio_driver virtio_gpu_driver = { > + .feature_table = features, > + .feature_table_size = ARRAY_SIZE(features), > + .driver.name = KBUILD_MODNAME, > + .driver.owner = THIS_MODULE, > + .id_table = id_table, > + .probe = virtio_gpu_probe, > + .remove = virtio_gpu_remove, > + .config_changed = virtio_gpu_config_changed > +}; > + > +module_virtio_driver(virtio_gpu_driver); > + > +MODULE_DEVICE_TABLE(virtio, id_table); > +MODULE_DESCRIPTION("Virtio GPU driver"); > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Dave Airlie "); > +MODULE_AUTHOR("Gerd Hoffmann "); > +MODULE_AUTHOR("Alon Levy"); > + > +static const struct file_operations virtio_gpu_driver_fops = { > + .owner = THIS_MODULE, > + .open = drm_open, > + .mmap = virtio_gpu_mmap, > + .poll = drm_poll, > + .read = drm_read, > + .unlocked_ioctl = drm_ioctl, > + .release = drm_release, > +#ifdef CONFIG_COMPAT > + .compat_ioctl = drm_compat_ioctl, > +#endif > + .llseek = noop_llseek, > +}; > + > + > +static struct drm_driver driver = { > + .driver_features = DRIVER_MODESET | DRIVER_GEM, > + .set_busid = drm_virtio_set_busid, > + .load = virtio_gpu_driver_load, > + .unload = virtio_gpu_driver_unload, > + > + .dumb_create = virtio_gpu_mode_dumb_create, > + .dumb_map_offset = virtio_gpu_mode_dumb_mmap, > + .dumb_destroy = virtio_gpu_mode_dumb_destroy, > + > +#if defined(CONFIG_DEBUG_FS) > + .debugfs_init = virtio_gpu_debugfs_init, > + .debugfs_cleanup = virtio_gpu_debugfs_takedown, > +#endif > + > + .gem_free_object = virtio_gpu_gem_free_object, > + .fops = &virtio_gpu_driver_fops, > + > + .name = DRIVER_NAME, > + .desc = DRIVER_DESC, > + .date = DRIVER_DATE, > + .major = DRIVER_MAJOR, > + .minor = DRIVER_MINOR, > + .patchlevel = DRIVER_PATCHLEVEL, > +}; > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h > new file mode 100644 > index 0000000..e5a2c09 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h > @@ -0,0 +1,350 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#ifndef VIRTIO_DRV_H > +#define VIRTIO_DRV_H > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define DRIVER_NAME "virtio_gpu" > +#define DRIVER_DESC "virtio GPU" > +#define DRIVER_DATE "0" > + > +#define DRIVER_MAJOR 0 > +#define DRIVER_MINOR 0 > +#define DRIVER_PATCHLEVEL 1 > + > +/* virtgpu_drm_bus.c */ > +int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master); > +int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); > + > +struct virtio_gpu_object { > + struct drm_gem_object gem_base; > + uint32_t hw_res_handle; > + > + struct sg_table *pages; > + void *vmap; > + bool dumb; > + struct ttm_place placement_code; > + struct ttm_placement placement; > + struct ttm_buffer_object tbo; > + struct ttm_bo_kmap_obj kmap; > +}; > +#define gem_to_virtio_gpu_obj(gobj) \ > + container_of((gobj), struct virtio_gpu_object, gem_base) > + > +struct virtio_gpu_vbuffer; > +struct virtio_gpu_device; > + > +typedef void (*virtio_gpu_resp_cb)(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer *vbuf); > + > +struct virtio_gpu_fence_driver { > + atomic64_t last_seq; > + uint64_t sync_seq; > + struct list_head fences; > + spinlock_t lock; > +}; > + > +struct virtio_gpu_fence { > + struct fence f; > + struct virtio_gpu_fence_driver *drv; > + struct list_head node; > + uint64_t seq; > +}; > +#define to_virtio_fence(x) \ > + container_of(x, struct virtio_gpu_fence, f) > + > +struct virtio_gpu_vbuffer { > + char *buf; > + int size; > + > + void *data_buf; > + uint32_t data_size; > + > + char *resp_buf; > + int resp_size; > + > + virtio_gpu_resp_cb resp_cb; > + > + struct list_head list; > +}; > + > +struct virtio_gpu_output { > + int index; > + struct drm_crtc crtc; > + struct drm_connector conn; > + struct drm_encoder enc; > + struct virtio_gpu_display_one info; > + struct virtio_gpu_update_cursor cursor; > + int cur_x; > + int cur_y; > +}; > +#define drm_crtc_to_virtio_gpu_output(x) \ > + container_of(x, struct virtio_gpu_output, crtc) > +#define drm_connector_to_virtio_gpu_output(x) \ > + container_of(x, struct virtio_gpu_output, conn) > +#define drm_encoder_to_virtio_gpu_output(x) \ > + container_of(x, struct virtio_gpu_output, enc) > + > +struct virtio_gpu_framebuffer { > + struct drm_framebuffer base; > + struct drm_gem_object *obj; > + int x1, y1, x2, y2; /* dirty rect */ > + spinlock_t dirty_lock; > + uint32_t hw_res_handle; > +}; > +#define to_virtio_gpu_framebuffer(x) \ > + container_of(x, struct virtio_gpu_framebuffer, base) > + > +struct virtio_gpu_mman { > + struct ttm_bo_global_ref bo_global_ref; > + struct drm_global_reference mem_global_ref; > + bool mem_global_referenced; > + struct ttm_bo_device bdev; > +}; > + > +struct virtio_gpu_fbdev; > + > +struct virtio_gpu_queue { > + struct virtqueue *vq; > + spinlock_t qlock; > + wait_queue_head_t ack_queue; > + struct work_struct dequeue_work; > +}; > + > +struct virtio_gpu_device { > + struct device *dev; > + struct drm_device *ddev; > + > + struct virtio_device *vdev; > + > + struct virtio_gpu_mman mman; > + > + /* pointer to fbdev info structure */ > + struct virtio_gpu_fbdev *vgfbdev; > + struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; > + uint32_t num_scanouts; > + > + struct virtio_gpu_queue ctrlq; > + struct virtio_gpu_queue cursorq; > + struct list_head free_vbufs; > + void *vbufs; > + bool vqs_ready; > + > + struct idr resource_idr; > + spinlock_t resource_idr_lock; > + > + wait_queue_head_t resp_wq; > + /* current display info */ > + spinlock_t display_info_lock; > + > + struct virtio_gpu_fence_driver fence_drv; > + > + struct idr ctx_id_idr; > + spinlock_t ctx_id_idr_lock; > + > + struct work_struct config_changed_work; > +}; > + > +struct virtio_gpu_fpriv { > + uint32_t ctx_id; > +}; > + > +/* virtio_ioctl.c */ > +#define DRM_VIRTIO_NUM_IOCTLS 10 > +extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; > + > +/* virtio_kms.c */ > +int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); > +int virtio_gpu_driver_unload(struct drm_device *dev); > + > +/* virtio_gem.c */ > +void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj); > +int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev); > +void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev); > +int virtio_gpu_gem_create(struct drm_file *file, > + struct drm_device *dev, > + uint64_t size, > + struct drm_gem_object **obj_p, > + uint32_t *handle_p); > +struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, > + size_t size, bool kernel, > + bool pinned); > +int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, > + struct drm_device *dev, > + struct drm_mode_create_dumb *args); > +int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv, > + struct drm_device *dev, > + uint32_t handle); > +int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, > + struct drm_device *dev, > + uint32_t handle, uint64_t *offset_p); > + > +/* virtio_fb */ > +#define VIRTIO_GPUFB_CONN_LIMIT 1 > +int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev); > +void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev); > +int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb, > + struct drm_clip_rect *clips, > + unsigned num_clips); > +/* virtio vg */ > +int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); > +void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); > +void virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, > + uint32_t *resid); > +void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id); > +void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, > + uint32_t format, > + uint32_t width, > + uint32_t height); > +void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, > + uint32_t resource_id); > +void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, uint64_t offset, > + __le32 width, __le32 height, > + __le32 x, __le32 y, > + struct virtio_gpu_fence **fence); > +void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, > + uint32_t x, uint32_t y, > + uint32_t width, uint32_t height); > +void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, > + uint32_t scanout_id, uint32_t resource_id, > + uint32_t width, uint32_t height, > + uint32_t x, uint32_t y); > +int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_object *obj, > + uint32_t resource_id, > + struct virtio_gpu_fence **fence); > +int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev); > +int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev); > +void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_output *output); > +int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev); > +void virtio_gpu_cmd_resource_inval_backing(struct virtio_gpu_device *vgdev, > + uint32_t resource_id); > +void virtio_gpu_ctrl_ack(struct virtqueue *vq); > +void virtio_gpu_cursor_ack(struct virtqueue *vq); > +void virtio_gpu_dequeue_ctrl_func(struct work_struct *work); > +void virtio_gpu_dequeue_cursor_func(struct work_struct *work); > + > +/* virtio_gpu_display.c */ > +int virtio_gpu_framebuffer_init(struct drm_device *dev, > + struct virtio_gpu_framebuffer *vgfb, > + struct drm_mode_fb_cmd2 *mode_cmd, > + struct drm_gem_object *obj); > +int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); > +void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); > + > +/* virtio_gpu_plane.c */ > +struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, > + int index); > + > +/* virtio_gpu_ttm.c */ > +int virtio_gpu_ttm_init(struct virtio_gpu_device *vgdev); > +void virtio_gpu_ttm_fini(struct virtio_gpu_device *vgdev); > +int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma); > + > +/* virtio_gpu_fence.c */ > +int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_ctrl_hdr *cmd_hdr, > + struct virtio_gpu_fence **fence); > +void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, > + u64 last_seq); > + > +/* virtio_gpu_object */ > +int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, > + unsigned long size, bool kernel, bool pinned, > + struct virtio_gpu_object **bo_ptr); > +int virtio_gpu_object_kmap(struct virtio_gpu_object *bo, void **ptr); > +int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev, > + struct virtio_gpu_object *bo); > +void virtio_gpu_object_free_sg_table(struct virtio_gpu_object *bo); > +int virtio_gpu_object_wait(struct virtio_gpu_object *bo, bool no_wait); > + > +static inline struct virtio_gpu_object* > +virtio_gpu_object_ref(struct virtio_gpu_object *bo) > +{ > + ttm_bo_reference(&bo->tbo); > + return bo; > +} > + > +static inline void virtio_gpu_object_unref(struct virtio_gpu_object **bo) > +{ > + struct ttm_buffer_object *tbo; > + > + if ((*bo) == NULL) > + return; > + tbo = &((*bo)->tbo); > + ttm_bo_unref(&tbo); > + if (tbo == NULL) > + *bo = NULL; > +} > + > +static inline u64 virtio_gpu_object_mmap_offset(struct virtio_gpu_object *bo) > +{ > + return drm_vma_node_offset_addr(&bo->tbo.vma_node); > +} > + > +static inline int virtio_gpu_object_reserve(struct virtio_gpu_object *bo, > + bool no_wait) > +{ > + int r; > + > + r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, NULL); > + if (unlikely(r != 0)) { > + if (r != -ERESTARTSYS) { > + struct virtio_gpu_device *qdev = > + bo->gem_base.dev->dev_private; > + dev_err(qdev->dev, "%p reserve failed\n", bo); > + } > + return r; > + } > + return 0; > +} > + > +static inline void virtio_gpu_object_unreserve(struct virtio_gpu_object *bo) > +{ > + ttm_bo_unreserve(&bo->tbo); > +} > + > +/* virgl debufs */ > +int virtio_gpu_debugfs_init(struct drm_minor *minor); > +void virtio_gpu_debugfs_takedown(struct drm_minor *minor); > + > +#endif > diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c > new file mode 100644 > index 0000000..25bf333 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c > @@ -0,0 +1,431 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include > +#include "virtgpu_drv.h" > + > +#define VIRTIO_GPU_FBCON_POLL_PERIOD (HZ / 60) > + > +struct virtio_gpu_fbdev { > + struct drm_fb_helper helper; > + struct virtio_gpu_framebuffer vgfb; > + struct list_head fbdev_list; > + struct virtio_gpu_device *vgdev; > + struct delayed_work work; > +}; > + > +static int virtio_gpu_dirty_update(struct virtio_gpu_framebuffer *fb, > + bool store, int x, int y, > + int width, int height) > +{ > + struct drm_device *dev = fb->base.dev; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + bool store_for_later = false; > + int bpp = fb->base.bits_per_pixel / 8; > + int x2, y2; > + unsigned long flags; > + struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(fb->obj); > + > + if ((width <= 0) || > + (x + width > fb->base.width) || > + (y + height > fb->base.height)) { > + DRM_DEBUG("values out of range %dx%d+%d+%d, fb %dx%d\n", > + width, height, x, y, > + fb->base.width, fb->base.height); > + return -EINVAL; > + } > + > + /* > + * Can be called with pretty much any context (console output > + * path). If we are in atomic just store the dirty rect info > + * to send out the update later. > + * > + * Can't test inside spin lock. > + */ > + if (in_atomic() || store) > + store_for_later = true; > + > + x2 = x + width - 1; > + y2 = y + height - 1; > + > + spin_lock_irqsave(&fb->dirty_lock, flags); > + > + if (fb->y1 < y) > + y = fb->y1; > + if (fb->y2 > y2) > + y2 = fb->y2; > + if (fb->x1 < x) > + x = fb->x1; > + if (fb->x2 > x2) > + x2 = fb->x2; > + > + if (store_for_later) { > + fb->x1 = x; > + fb->x2 = x2; > + fb->y1 = y; > + fb->y2 = y2; > + spin_unlock_irqrestore(&fb->dirty_lock, flags); > + return 0; > + } > + > + fb->x1 = fb->y1 = INT_MAX; > + fb->x2 = fb->y2 = 0; > + > + spin_unlock_irqrestore(&fb->dirty_lock, flags); > + > + { > + uint32_t offset; > + uint32_t w = x2 - x + 1; > + uint32_t h = y2 - y + 1; > + > + offset = (y * fb->base.pitches[0]) + x * bpp; > + > + virtio_gpu_cmd_transfer_to_host_2d(vgdev, obj->hw_res_handle, > + offset, > + cpu_to_le32(w), > + cpu_to_le32(h), > + cpu_to_le32(x), > + cpu_to_le32(y), > + NULL); > + > + } > + virtio_gpu_cmd_resource_flush(vgdev, obj->hw_res_handle, > + x, y, x2 - x + 1, y2 - y + 1); > + return 0; > +} > + > +int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb, > + struct drm_clip_rect *clips, > + unsigned num_clips) > +{ > + struct virtio_gpu_device *vgdev = vgfb->base.dev->dev_private; > + struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(vgfb->obj); > + struct drm_clip_rect norect; > + struct drm_clip_rect *clips_ptr; > + int left, right, top, bottom; > + int i; > + int inc = 1; > + if (!num_clips) { > + num_clips = 1; > + clips = &norect; > + norect.x1 = norect.y1 = 0; > + norect.x2 = vgfb->base.width; > + norect.y2 = vgfb->base.height; > + } > + left = clips->x1; > + right = clips->x2; > + top = clips->y1; > + bottom = clips->y2; > + > + /* skip the first clip rect */ > + for (i = 1, clips_ptr = clips + inc; > + i < num_clips; i++, clips_ptr += inc) { > + left = min_t(int, left, (int)clips_ptr->x1); > + right = max_t(int, right, (int)clips_ptr->x2); > + top = min_t(int, top, (int)clips_ptr->y1); > + bottom = max_t(int, bottom, (int)clips_ptr->y2); > + } > + > + if (obj->dumb) > + return virtio_gpu_dirty_update(vgfb, false, left, top, > + right - left, bottom - top); > + > + virtio_gpu_cmd_resource_flush(vgdev, obj->hw_res_handle, > + left, top, right - left, bottom - top); > + return 0; > +} > + > +static void virtio_gpu_fb_dirty_work(struct work_struct *work) > +{ > + struct delayed_work *delayed_work = to_delayed_work(work); > + struct virtio_gpu_fbdev *vfbdev = > + container_of(delayed_work, struct virtio_gpu_fbdev, work); > + struct virtio_gpu_framebuffer *vgfb = &vfbdev->vgfb; > + > + virtio_gpu_dirty_update(&vfbdev->vgfb, false, vgfb->x1, vgfb->y1, > + vgfb->x2 - vgfb->x1, vgfb->y2 - vgfb->y1); > +} > + > +static void virtio_gpu_3d_fillrect(struct fb_info *info, > + const struct fb_fillrect *rect) > +{ > + struct virtio_gpu_fbdev *vfbdev = info->par; > + sys_fillrect(info, rect); > + virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy, > + rect->width, rect->height); > + schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); > +} > + > +static void virtio_gpu_3d_copyarea(struct fb_info *info, > + const struct fb_copyarea *area) > +{ > + struct virtio_gpu_fbdev *vfbdev = info->par; > + sys_copyarea(info, area); > + virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy, > + area->width, area->height); > + schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); > +} > + > +static void virtio_gpu_3d_imageblit(struct fb_info *info, > + const struct fb_image *image) > +{ > + struct virtio_gpu_fbdev *vfbdev = info->par; > + sys_imageblit(info, image); > + virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy, > + image->width, image->height); > + schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); > +} > + > +static struct fb_ops virtio_gpufb_ops = { > + .owner = THIS_MODULE, > + .fb_check_var = drm_fb_helper_check_var, > + .fb_set_par = drm_fb_helper_set_par, /* TODO: copy vmwgfx */ > + .fb_fillrect = virtio_gpu_3d_fillrect, > + .fb_copyarea = virtio_gpu_3d_copyarea, > + .fb_imageblit = virtio_gpu_3d_imageblit, > + .fb_pan_display = drm_fb_helper_pan_display, > + .fb_blank = drm_fb_helper_blank, > + .fb_setcmap = drm_fb_helper_setcmap, > + .fb_debug_enter = drm_fb_helper_debug_enter, > + .fb_debug_leave = drm_fb_helper_debug_leave, > +}; > + > +static int virtio_gpu_vmap_fb(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_object *obj) > +{ > + return virtio_gpu_object_kmap(obj, NULL); > +} > + > +static int virtio_gpufb_create(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes) > +{ > + struct virtio_gpu_fbdev *vfbdev = > + container_of(helper, struct virtio_gpu_fbdev, helper); > + struct drm_device *dev = helper->dev; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct fb_info *info; > + struct drm_framebuffer *fb; > + struct drm_mode_fb_cmd2 mode_cmd = {}; > + struct virtio_gpu_object *obj; > + struct device *device = vgdev->dev; > + uint32_t resid, format, size; > + int ret; > + > + mode_cmd.width = sizes->surface_width; > + mode_cmd.height = sizes->surface_height; > + mode_cmd.pitches[0] = mode_cmd.width * 4; > + mode_cmd.pixel_format = drm_mode_legacy_fb_format(32, 24); > + > + switch (mode_cmd.pixel_format) { > +#ifdef __BIG_ENDIAN > + case DRM_FORMAT_XRGB8888: > + format = VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM; > + break; > + case DRM_FORMAT_ARGB8888: > + format = VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM; > + break; > + case DRM_FORMAT_BGRX8888: > + format = VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM; > + break; > + case DRM_FORMAT_BGRA8888: > + format = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM; > + break; > + case DRM_FORMAT_RGBX8888: > + format = VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM; > + break; > + case DRM_FORMAT_RGBA8888: > + format = VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM; > + break; > + case DRM_FORMAT_XBGR8888: > + format = VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM; > + break; > + case DRM_FORMAT_ABGR8888: > + format = VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM; > + break; > +#else > + case DRM_FORMAT_XRGB8888: > + format = VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM; > + break; > + case DRM_FORMAT_ARGB8888: > + format = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM; > + break; > + case DRM_FORMAT_BGRX8888: > + format = VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM; > + break; > + case DRM_FORMAT_BGRA8888: > + format = VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM; > + break; > + case DRM_FORMAT_RGBX8888: > + format = VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM; > + break; > + case DRM_FORMAT_RGBA8888: > + format = VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM; > + break; > + case DRM_FORMAT_XBGR8888: > + format = VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM; > + break; > + case DRM_FORMAT_ABGR8888: > + format = VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM; > + break; > +#endif > + default: > + DRM_ERROR("failed to find virtio gpu format for %d\n", > + mode_cmd.pixel_format); > + return -EINVAL; > + } > + > + size = mode_cmd.pitches[0] * mode_cmd.height; > + obj = virtio_gpu_alloc_object(dev, size, false, true); > + if (!obj) > + return -ENOMEM; > + > + virtio_gpu_resource_id_get(vgdev, &resid); > + virtio_gpu_cmd_create_resource(vgdev, resid, format, > + mode_cmd.width, mode_cmd.height); > + > + ret = virtio_gpu_vmap_fb(vgdev, obj); > + if (ret) { > + DRM_ERROR("failed to vmap fb %d\n", ret); > + goto err_obj_vmap; > + } > + > + /* attach the object to the resource */ > + ret = virtio_gpu_object_attach(vgdev, obj, resid, NULL); > + if (ret) > + goto err_obj_attach; > + > + info = framebuffer_alloc(0, device); > + if (!info) { > + ret = -ENOMEM; > + goto err_fb_alloc; > + } > + > + ret = fb_alloc_cmap(&info->cmap, 256, 0); > + if (ret) { > + ret = -ENOMEM; > + goto err_fb_alloc_cmap; > + } > + > + info->par = helper; > + > + ret = virtio_gpu_framebuffer_init(dev, &vfbdev->vgfb, > + &mode_cmd, &obj->gem_base); > + if (ret) > + goto err_fb_init; > + > + fb = &vfbdev->vgfb.base; > + > + vfbdev->helper.fb = fb; > + vfbdev->helper.fbdev = info; > + > + strcpy(info->fix.id, "virtiodrmfb"); > + info->flags = FBINFO_DEFAULT; > + info->fbops = &virtio_gpufb_ops; > + info->pixmap.flags = FB_PIXMAP_SYSTEM; > + > + info->screen_base = obj->vmap; > + info->screen_size = obj->gem_base.size; > + drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); > + drm_fb_helper_fill_var(info, &vfbdev->helper, > + sizes->fb_width, sizes->fb_height); > + > + info->fix.mmio_start = 0; > + info->fix.mmio_len = 0; > + return 0; > + > +err_fb_init: > + fb_dealloc_cmap(&info->cmap); > +err_fb_alloc_cmap: > + framebuffer_release(info); > +err_fb_alloc: > + virtio_gpu_cmd_resource_inval_backing(vgdev, resid); > +err_obj_attach: > +err_obj_vmap: > + virtio_gpu_gem_free_object(&obj->gem_base); > + return ret; > +} > + > +static int virtio_gpu_fbdev_destroy(struct drm_device *dev, > + struct virtio_gpu_fbdev *vgfbdev) > +{ > + struct fb_info *info; > + struct virtio_gpu_framebuffer *vgfb = &vgfbdev->vgfb; > + > + if (vgfbdev->helper.fbdev) { > + info = vgfbdev->helper.fbdev; > + > + unregister_framebuffer(info); > + framebuffer_release(info); > + } > + if (vgfb->obj) > + vgfb->obj = NULL; > + drm_fb_helper_fini(&vgfbdev->helper); > + drm_framebuffer_cleanup(&vgfb->base); > + > + return 0; > +} > +static struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = { > + .fb_probe = virtio_gpufb_create, > +}; > + > +int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev) > +{ > + struct virtio_gpu_fbdev *vgfbdev; > + int bpp_sel = 32; /* TODO: parameter from somewhere? */ > + int ret; > + > + vgfbdev = kzalloc(sizeof(struct virtio_gpu_fbdev), GFP_KERNEL); > + if (!vgfbdev) > + return -ENOMEM; > + > + vgfbdev->vgdev = vgdev; > + vgdev->vgfbdev = vgfbdev; > + INIT_DELAYED_WORK(&vgfbdev->work, virtio_gpu_fb_dirty_work); > + > + drm_fb_helper_prepare(vgdev->ddev, &vgfbdev->helper, > + &virtio_gpu_fb_helper_funcs); > + ret = drm_fb_helper_init(vgdev->ddev, &vgfbdev->helper, > + vgdev->num_scanouts, > + VIRTIO_GPUFB_CONN_LIMIT); > + if (ret) { > + kfree(vgfbdev); > + return ret; > + } > + > + drm_fb_helper_single_add_all_connectors(&vgfbdev->helper); > + drm_fb_helper_initial_config(&vgfbdev->helper, bpp_sel); > + return 0; > +} > + > +void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev) > +{ > + if (!vgdev->vgfbdev) > + return; > + > + virtio_gpu_fbdev_destroy(vgdev->ddev, vgdev->vgfbdev); > + kfree(vgdev->vgfbdev); > + vgdev->vgfbdev = NULL; > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c > new file mode 100644 > index 0000000..1da6326 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c > @@ -0,0 +1,119 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include "virtgpu_drv.h" > + > +static const char *virtio_get_driver_name(struct fence *f) > +{ > + return "virtio_gpu"; > +} > + > +static const char *virtio_get_timeline_name(struct fence *f) > +{ > + return "controlq"; > +} > + > +static bool virtio_enable_signaling(struct fence *f) > +{ > + return true; > +} > + > +static bool virtio_signaled(struct fence *f) > +{ > + struct virtio_gpu_fence *fence = to_virtio_fence(f); > + > + if (atomic64_read(&fence->drv->last_seq) >= fence->seq) > + return true; > + return false; > +} > + > +static void virtio_fence_value_str(struct fence *f, char *str, int size) > +{ > + struct virtio_gpu_fence *fence = to_virtio_fence(f); > + > + snprintf(str, size, "%llu", fence->seq); > +} > + > +static void virtio_timeline_value_str(struct fence *f, char *str, int size) > +{ > + struct virtio_gpu_fence *fence = to_virtio_fence(f); > + > + snprintf(str, size, "%lu", atomic64_read(&fence->drv->last_seq)); > +} > + > +static const struct fence_ops virtio_fence_ops = { > + .get_driver_name = virtio_get_driver_name, > + .get_timeline_name = virtio_get_timeline_name, > + .enable_signaling = virtio_enable_signaling, > + .signaled = virtio_signaled, > + .wait = fence_default_wait, > + .fence_value_str = virtio_fence_value_str, > + .timeline_value_str = virtio_timeline_value_str, > +}; > + > +int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_ctrl_hdr *cmd_hdr, > + struct virtio_gpu_fence **fence) > +{ > + struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; > + unsigned long irq_flags; > + > + *fence = kmalloc(sizeof(struct virtio_gpu_fence), GFP_KERNEL); > + if ((*fence) == NULL) > + return -ENOMEM; > + > + spin_lock_irqsave(&drv->lock, irq_flags); > + (*fence)->drv = drv; > + (*fence)->seq = ++drv->sync_seq; > + fence_init(&(*fence)->f, &virtio_fence_ops, &drv->lock, > + 0, (*fence)->seq); > + fence_get(&(*fence)->f); > + list_add_tail(&(*fence)->node, &drv->fences); > + spin_unlock_irqrestore(&drv->lock, irq_flags); > + > + cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); > + cmd_hdr->fence_id = cpu_to_le64((*fence)->seq); > + return 0; > +} > + > +void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, > + u64 last_seq) > +{ > + struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; > + struct virtio_gpu_fence *fence, *tmp; > + unsigned long irq_flags; > + > + spin_lock_irqsave(&drv->lock, irq_flags); > + atomic64_set(&vgdev->fence_drv.last_seq, last_seq); > + list_for_each_entry_safe(fence, tmp, &drv->fences, node) { > + if (last_seq < fence->seq) > + continue; > + fence_signal_locked(&fence->f); > + list_del(&fence->node); > + fence_put(&fence->f); > + } > + spin_unlock_irqrestore(&drv->lock, irq_flags); > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c > new file mode 100644 > index 0000000..cfa0d27 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c > @@ -0,0 +1,140 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include "virtgpu_drv.h" > + > +void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj) > +{ > + struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(gem_obj); > + > + if (obj) > + virtio_gpu_object_unref(&obj); > +} > + > +struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, > + size_t size, bool kernel, > + bool pinned) > +{ > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct virtio_gpu_object *obj; > + int ret; > + > + ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj); > + if (ret) > + return ERR_PTR(ret); > + > + return obj; > +} > + > +int virtio_gpu_gem_create(struct drm_file *file, > + struct drm_device *dev, > + uint64_t size, > + struct drm_gem_object **obj_p, > + uint32_t *handle_p) > +{ > + struct virtio_gpu_object *obj; > + int ret; > + u32 handle; > + > + obj = virtio_gpu_alloc_object(dev, size, false, false); > + if (IS_ERR(obj)) > + return PTR_ERR(obj); > + > + ret = drm_gem_handle_create(file, &obj->gem_base, &handle); > + if (ret) { > + drm_gem_object_release(&obj->gem_base); > + return ret; > + } > + > + *obj_p = &obj->gem_base; > + > + /* drop reference from allocate - handle holds it now */ > + drm_gem_object_unreference_unlocked(&obj->gem_base); > + > + *handle_p = handle; > + return 0; > +} > + > +int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, > + struct drm_device *dev, > + struct drm_mode_create_dumb *args) > +{ > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct drm_gem_object *gobj; > + struct virtio_gpu_object *obj; > + int ret; > + uint32_t pitch; > + uint32_t resid; > + > + pitch = args->width * ((args->bpp + 1) / 8); > + args->size = pitch * args->height; > + args->size = ALIGN(args->size, PAGE_SIZE); > + > + ret = virtio_gpu_gem_create(file_priv, dev, args->size, &gobj, > + &args->handle); > + if (ret) > + goto fail; > + > + virtio_gpu_resource_id_get(vgdev, &resid); > + virtio_gpu_cmd_create_resource(vgdev, resid, > + 2, args->width, args->height); > + > + /* attach the object to the resource */ > + obj = gem_to_virtio_gpu_obj(gobj); > + ret = virtio_gpu_object_attach(vgdev, obj, resid, NULL); > + if (ret) > + goto fail; > + > + obj->dumb = true; > + args->pitch = pitch; > + return ret; > + > +fail: > + return ret; > +} > + > +int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv, > + struct drm_device *dev, > + uint32_t handle) > +{ > + return drm_gem_handle_delete(file_priv, handle); > +} > + > +int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, > + struct drm_device *dev, > + uint32_t handle, uint64_t *offset_p) > +{ > + struct drm_gem_object *gobj; > + struct virtio_gpu_object *obj; > + BUG_ON(!offset_p); > + gobj = drm_gem_object_lookup(dev, file_priv, handle); > + if (gobj == NULL) > + return -ENOENT; > + obj = gem_to_virtio_gpu_obj(gobj); > + *offset_p = virtio_gpu_object_mmap_offset(obj); > + drm_gem_object_unreference_unlocked(gobj); > + return 0; > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c > new file mode 100644 > index 0000000..e503ffb > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c > @@ -0,0 +1,164 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include > +#include > +#include "virtgpu_drv.h" > + > +static void virtio_gpu_config_changed_work_func(struct work_struct *work) > +{ > + struct virtio_gpu_device *vgdev = > + container_of(work, struct virtio_gpu_device, > + config_changed_work); > + u32 events_read, events_clear = 0; > + > + /* read the config space */ > + virtio_cread(vgdev->vdev, struct virtio_gpu_config, > + events_read, &events_read); > + if (events_read & VIRTIO_GPU_EVENT_DISPLAY) { > + virtio_gpu_cmd_get_display_info(vgdev); > + drm_helper_hpd_irq_event(vgdev->ddev); > + events_clear |= VIRTIO_GPU_EVENT_DISPLAY; > + } > + virtio_cwrite(vgdev->vdev, struct virtio_gpu_config, > + events_clear, &events_clear); > +} > + > +static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, > + void (*work_func)(struct work_struct *work)) > +{ > + spin_lock_init(&vgvq->qlock); > + init_waitqueue_head(&vgvq->ack_queue); > + INIT_WORK(&vgvq->dequeue_work, work_func); > +} > + > +int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) > +{ > + static vq_callback_t *callbacks[] = { > + virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack > + }; > + static const char *names[] = { "control", "cursor" }; > + > + struct virtio_gpu_device *vgdev; > + /* this will expand later */ > + struct virtqueue *vqs[2]; > + u32 num_scanouts; > + int ret; > + > + if (!virtio_has_feature(dev->virtdev, VIRTIO_F_VERSION_1)) > + return -ENODEV; > + > + vgdev = kzalloc(sizeof(struct virtio_gpu_device), GFP_KERNEL); > + if (!vgdev) > + return -ENOMEM; > + > + vgdev->ddev = dev; > + dev->dev_private = vgdev; > + vgdev->vdev = dev->virtdev; > + vgdev->dev = dev->dev; > + > + spin_lock_init(&vgdev->display_info_lock); > + spin_lock_init(&vgdev->ctx_id_idr_lock); > + idr_init(&vgdev->ctx_id_idr); > + spin_lock_init(&vgdev->resource_idr_lock); > + idr_init(&vgdev->resource_idr); > + init_waitqueue_head(&vgdev->resp_wq); > + virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func); > + virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func); > + > + spin_lock_init(&vgdev->fence_drv.lock); > + INIT_LIST_HEAD(&vgdev->fence_drv.fences); > + INIT_WORK(&vgdev->config_changed_work, > + virtio_gpu_config_changed_work_func); > + > + ret = vgdev->vdev->config->find_vqs(vgdev->vdev, 2, vqs, > + callbacks, names); > + if (ret) { > + DRM_ERROR("failed to find virt queues\n"); > + goto err_vqs; > + } > + vgdev->ctrlq.vq = vqs[0]; > + vgdev->cursorq.vq = vqs[1]; > + ret = virtio_gpu_alloc_vbufs(vgdev); > + if (ret) { > + DRM_ERROR("failed to alloc vbufs\n"); > + goto err_vbufs; > + } > + > + ret = virtio_gpu_ttm_init(vgdev); > + if (ret) { > + DRM_ERROR("failed to init ttm %d\n", ret); > + goto err_ttm; > + } > + > + /* get display info */ > + virtio_cread(vgdev->vdev, struct virtio_gpu_config, > + num_scanouts, &num_scanouts); > + vgdev->num_scanouts = min_t(uint32_t, num_scanouts, > + VIRTIO_GPU_MAX_SCANOUTS); > + if (!vgdev->num_scanouts) { > + DRM_ERROR("num_scanouts is zero\n"); > + ret = -EINVAL; > + goto err_scanouts; > + } > + > + ret = virtio_gpu_modeset_init(vgdev); > + if (ret) > + goto err_modeset; > + > + virtio_device_ready(vgdev->vdev); > + vgdev->vqs_ready = true; > + virtio_gpu_cmd_get_display_info(vgdev); > + return 0; > + > +err_modeset: > +err_scanouts: > + virtio_gpu_ttm_fini(vgdev); > +err_ttm: > + virtio_gpu_free_vbufs(vgdev); > +err_vbufs: > + vgdev->vdev->config->del_vqs(vgdev->vdev); > +err_vqs: > + kfree(vgdev); > + return ret; > +} > + > +int virtio_gpu_driver_unload(struct drm_device *dev) > +{ > + struct virtio_gpu_device *vgdev = dev->dev_private; > + > + vgdev->vqs_ready = false; > + flush_work(&vgdev->ctrlq.dequeue_work); > + flush_work(&vgdev->cursorq.dequeue_work); > + flush_work(&vgdev->config_changed_work); > + vgdev->vdev->config->del_vqs(vgdev->vdev); > + > + virtio_gpu_modeset_fini(vgdev); > + virtio_gpu_ttm_fini(vgdev); > + virtio_gpu_free_vbufs(vgdev); > + kfree(vgdev); > + return 0; > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c > new file mode 100644 > index 0000000..2c624c7 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_object.c > @@ -0,0 +1,170 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include "virtgpu_drv.h" > + > +static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) > +{ > + struct virtio_gpu_object *bo; > + struct virtio_gpu_device *vgdev; > + > + bo = container_of(tbo, struct virtio_gpu_object, tbo); > + vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; > + > + if (bo->hw_res_handle) > + virtio_gpu_cmd_unref_resource(vgdev, bo->hw_res_handle); > + if (bo->pages) > + virtio_gpu_object_free_sg_table(bo); > + drm_gem_object_release(&bo->gem_base); > + kfree(bo); > +} > + > +static void virtio_gpu_init_ttm_placement(struct virtio_gpu_object *vgbo, > + bool pinned) > +{ > + u32 c = 1; > + u32 pflag = pinned ? TTM_PL_FLAG_NO_EVICT : 0; > + > + vgbo->placement.placement = &vgbo->placement_code; > + vgbo->placement.busy_placement = &vgbo->placement_code; > + vgbo->placement_code.fpfn = 0; > + vgbo->placement_code.lpfn = 0; > + vgbo->placement_code.flags = > + TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT | pflag; > + vgbo->placement.num_placement = c; > + vgbo->placement.num_busy_placement = c; > + > +} > + > +int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, > + unsigned long size, bool kernel, bool pinned, > + struct virtio_gpu_object **bo_ptr) > +{ > + struct virtio_gpu_object *bo; > + enum ttm_bo_type type; > + size_t acc_size; > + int ret; > + > + if (kernel) > + type = ttm_bo_type_kernel; > + else > + type = ttm_bo_type_device; > + *bo_ptr = NULL; > + > + acc_size = ttm_bo_dma_acc_size(&vgdev->mman.bdev, size, > + sizeof(struct virtio_gpu_object)); > + > + bo = kzalloc(sizeof(struct virtio_gpu_object), GFP_KERNEL); > + if (bo == NULL) > + return -ENOMEM; > + size = roundup(size, PAGE_SIZE); > + ret = drm_gem_object_init(vgdev->ddev, &bo->gem_base, size); > + if (ret != 0) > + goto err_gem_init; > + bo->dumb = false; > + virtio_gpu_init_ttm_placement(bo, pinned); > + > + ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, size, type, > + &bo->placement, 0, !kernel, NULL, acc_size, > + NULL, NULL, &virtio_gpu_ttm_bo_destroy); > + if (ret != 0) > + goto err_ttm_init; > + > + *bo_ptr = bo; > + return 0; > + > +err_ttm_init: > + drm_gem_object_release(&bo->gem_base); > +err_gem_init: > + kfree(bo); > + return ret; > +} > + > +int virtio_gpu_object_kmap(struct virtio_gpu_object *bo, void **ptr) > +{ > + bool is_iomem; > + int r; > + > + if (bo->vmap) { > + if (ptr) > + *ptr = bo->vmap; > + return 0; > + } > + r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); > + if (r) > + return r; > + bo->vmap = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); > + if (ptr) > + *ptr = bo->vmap; > + return 0; > +} > + > +int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev, > + struct virtio_gpu_object *bo) > +{ > + int ret; > + struct page **pages = bo->tbo.ttm->pages; > + int nr_pages = bo->tbo.num_pages; > + > + /* wtf swapping */ > + if (bo->pages) > + return 0; > + > + if (bo->tbo.ttm->state == tt_unpopulated) > + bo->tbo.ttm->bdev->driver->ttm_tt_populate(bo->tbo.ttm); > + bo->pages = kmalloc(sizeof(struct sg_table), GFP_KERNEL); > + if (!bo->pages) > + goto out; > + > + ret = sg_alloc_table_from_pages(bo->pages, pages, nr_pages, 0, > + nr_pages << PAGE_SHIFT, GFP_KERNEL); > + if (ret) > + goto out; > + return 0; > +out: > + kfree(bo->pages); > + bo->pages = NULL; > + return -ENOMEM; > +} > + > +void virtio_gpu_object_free_sg_table(struct virtio_gpu_object *bo) > +{ > + sg_free_table(bo->pages); > + kfree(bo->pages); > + bo->pages = NULL; > +} > + > +int virtio_gpu_object_wait(struct virtio_gpu_object *bo, bool no_wait) > +{ > + int r; > + > + r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, NULL); > + if (unlikely(r != 0)) > + return r; > + r = ttm_bo_wait(&bo->tbo, true, true, no_wait); > + ttm_bo_unreserve(&bo->tbo); > + return r; > +} > + > diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c > new file mode 100644 > index 0000000..4a74129 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c > @@ -0,0 +1,120 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining > + * a copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sublicense, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial > + * portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. > + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE > + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include "virtgpu_drv.h" > +#include > +#include > + > +static const uint32_t virtio_gpu_formats[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_BGRX8888, > + DRM_FORMAT_BGRA8888, > + DRM_FORMAT_RGBX8888, > + DRM_FORMAT_RGBA8888, > + DRM_FORMAT_XBGR8888, > + DRM_FORMAT_ABGR8888, > +}; > + > +static void virtio_gpu_plane_destroy(struct drm_plane *plane) > +{ > + kfree(plane); > +} > + > +static const struct drm_plane_funcs virtio_gpu_plane_funcs = { > + .update_plane = drm_atomic_helper_update_plane, > + .disable_plane = drm_atomic_helper_disable_plane, > + .destroy = virtio_gpu_plane_destroy, > + .reset = drm_atomic_helper_plane_reset, > + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, > +}; > + > +static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, > + struct drm_plane_state *state) > +{ > + return 0; > +} > + > +static void virtio_gpu_plane_atomic_update(struct drm_plane *plane, > + struct drm_plane_state *old_state) > +{ > + struct drm_device *dev = plane->dev; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(plane->crtc); > + struct virtio_gpu_framebuffer *vgfb; > + struct virtio_gpu_object *bo; > + uint32_t handle; > + > + if (plane->fb) { > + vgfb = to_virtio_gpu_framebuffer(plane->fb); > + bo = gem_to_virtio_gpu_obj(vgfb->obj); > + handle = bo->hw_res_handle; > + } else { > + handle = 0; > + } > + > + DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d\n", handle, > + plane->state->crtc_w, plane->state->crtc_h, > + plane->state->crtc_x, plane->state->crtc_y); > + virtio_gpu_cmd_set_scanout(vgdev, output->index, handle, > + plane->state->crtc_w, > + plane->state->crtc_h, > + plane->state->crtc_x, > + plane->state->crtc_y); > +} > + > + > +static const struct drm_plane_helper_funcs virtio_gpu_plane_helper_funcs = { > + .atomic_check = virtio_gpu_plane_atomic_check, > + .atomic_update = virtio_gpu_plane_atomic_update, > +}; > + > +struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, > + int index) > +{ > + struct drm_device *dev = vgdev->ddev; > + struct drm_plane *plane; > + int ret; > + > + plane = kzalloc(sizeof(*plane), GFP_KERNEL); > + if (!plane) > + return ERR_PTR(-ENOMEM); > + > + ret = drm_universal_plane_init(dev, plane, 1 << index, > + &virtio_gpu_plane_funcs, > + virtio_gpu_formats, > + ARRAY_SIZE(virtio_gpu_formats), > + DRM_PLANE_TYPE_PRIMARY); > + if (ret) > + goto err_plane_init; > + > + drm_plane_helper_add(plane, &virtio_gpu_plane_helper_funcs); > + return plane; > + > +err_plane_init: > + kfree(plane); > + return ERR_PTR(ret); > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c > new file mode 100644 > index 0000000..e0e74c6 > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c > @@ -0,0 +1,469 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Authors: > + * Dave Airlie > + * Alon Levy > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "virtgpu_drv.h" > + > +#include > + > +#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) > + > +static struct > +virtio_gpu_device *virtio_gpu_get_vgdev(struct ttm_bo_device *bdev) > +{ > + struct virtio_gpu_mman *mman; > + struct virtio_gpu_device *vgdev; > + > + mman = container_of(bdev, struct virtio_gpu_mman, bdev); > + vgdev = container_of(mman, struct virtio_gpu_device, mman); > + return vgdev; > +} > + > +static int virtio_gpu_ttm_mem_global_init(struct drm_global_reference *ref) > +{ > + return ttm_mem_global_init(ref->object); > +} > + > +static void virtio_gpu_ttm_mem_global_release(struct drm_global_reference *ref) > +{ > + ttm_mem_global_release(ref->object); > +} > + > +static int virtio_gpu_ttm_global_init(struct virtio_gpu_device *vgdev) > +{ > + struct drm_global_reference *global_ref; > + int r; > + > + vgdev->mman.mem_global_referenced = false; > + global_ref = &vgdev->mman.mem_global_ref; > + global_ref->global_type = DRM_GLOBAL_TTM_MEM; > + global_ref->size = sizeof(struct ttm_mem_global); > + global_ref->init = &virtio_gpu_ttm_mem_global_init; > + global_ref->release = &virtio_gpu_ttm_mem_global_release; > + > + r = drm_global_item_ref(global_ref); > + if (r != 0) { > + DRM_ERROR("Failed setting up TTM memory accounting " > + "subsystem.\n"); > + return r; > + } > + > + vgdev->mman.bo_global_ref.mem_glob = > + vgdev->mman.mem_global_ref.object; > + global_ref = &vgdev->mman.bo_global_ref.ref; > + global_ref->global_type = DRM_GLOBAL_TTM_BO; > + global_ref->size = sizeof(struct ttm_bo_global); > + global_ref->init = &ttm_bo_global_init; > + global_ref->release = &ttm_bo_global_release; > + r = drm_global_item_ref(global_ref); > + if (r != 0) { > + DRM_ERROR("Failed setting up TTM BO subsystem.\n"); > + drm_global_item_unref(&vgdev->mman.mem_global_ref); > + return r; > + } > + > + vgdev->mman.mem_global_referenced = true; > + return 0; > +} > + > +static void virtio_gpu_ttm_global_fini(struct virtio_gpu_device *vgdev) > +{ > + if (vgdev->mman.mem_global_referenced) { > + drm_global_item_unref(&vgdev->mman.bo_global_ref.ref); > + drm_global_item_unref(&vgdev->mman.mem_global_ref); > + vgdev->mman.mem_global_referenced = false; > + } > +} > + > +#if 0 > +/* > + * Hmm, seems to not do anything useful. Leftover debug hack? > + * Something like printing pagefaults to kernel log? > + */ > +static struct vm_operations_struct virtio_gpu_ttm_vm_ops; > +static const struct vm_operations_struct *ttm_vm_ops; > + > +static int virtio_gpu_ttm_fault(struct vm_area_struct *vma, > + struct vm_fault *vmf) > +{ > + struct ttm_buffer_object *bo; > + struct virtio_gpu_device *vgdev; > + int r; > + > + bo = (struct ttm_buffer_object *)vma->vm_private_data; > + if (bo == NULL) > + return VM_FAULT_NOPAGE; > + vgdev = virtio_gpu_get_vgdev(bo->bdev); > + r = ttm_vm_ops->fault(vma, vmf); > + return r; > +} > +#endif > + > +int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma) > +{ > + struct drm_file *file_priv; > + struct virtio_gpu_device *vgdev; > + int r; > + > + file_priv = filp->private_data; > + vgdev = file_priv->minor->dev->dev_private; > + if (vgdev == NULL) { > + DRM_ERROR( > + "filp->private_data->minor->dev->dev_private == NULL\n"); > + return -EINVAL; > + } > + r = ttm_bo_mmap(filp, vma, &vgdev->mman.bdev); > +#if 0 > + if (unlikely(r != 0)) > + return r; > + if (unlikely(ttm_vm_ops == NULL)) { > + ttm_vm_ops = vma->vm_ops; > + virtio_gpu_ttm_vm_ops = *ttm_vm_ops; > + virtio_gpu_ttm_vm_ops.fault = &virtio_gpu_ttm_fault; > + } > + vma->vm_ops = &virtio_gpu_ttm_vm_ops; > + return 0; > +#else > + return r; > +#endif > +} > + > +static int virtio_gpu_invalidate_caches(struct ttm_bo_device *bdev, > + uint32_t flags) > +{ > + return 0; > +} > + > +static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, > + struct ttm_buffer_object *bo, > + const struct ttm_place *place, > + struct ttm_mem_reg *mem) > +{ > + mem->mm_node = (void *)1; > + return 0; > +} > + > +static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, > + struct ttm_mem_reg *mem) > +{ > + mem->mm_node = (void *)NULL; > + return; > +} > + > +static int ttm_bo_man_init(struct ttm_mem_type_manager *man, > + unsigned long p_size) > +{ > + return 0; > +} > + > +static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) > +{ > + return 0; > +} > + > +static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, > + const char *prefix) > +{ > +} > + > +static const struct ttm_mem_type_manager_func virtio_gpu_bo_manager_func = { > + ttm_bo_man_init, > + ttm_bo_man_takedown, > + ttm_bo_man_get_node, > + ttm_bo_man_put_node, > + ttm_bo_man_debug > +}; > + > +static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, > + struct ttm_mem_type_manager *man) > +{ > + struct virtio_gpu_device *vgdev; > + > + vgdev = virtio_gpu_get_vgdev(bdev); > + > + switch (type) { > + case TTM_PL_SYSTEM: > + /* System memory */ > + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; > + man->available_caching = TTM_PL_MASK_CACHING; > + man->default_caching = TTM_PL_FLAG_CACHED; > + break; > + case TTM_PL_TT: > + man->func = &virtio_gpu_bo_manager_func; > + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; > + man->available_caching = TTM_PL_MASK_CACHING; > + man->default_caching = TTM_PL_FLAG_CACHED; > + break; > + default: > + DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); > + return -EINVAL; > + } > + return 0; > +} > + > +static void virtio_gpu_evict_flags(struct ttm_buffer_object *bo, > + struct ttm_placement *placement) > +{ > + static struct ttm_place placements = { > + .fpfn = 0, > + .lpfn = 0, > + .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM, > + }; > + > + placement->placement = &placements; > + placement->busy_placement = &placements; > + placement->num_placement = 1; > + placement->num_busy_placement = 1; > + return; > +} > + > +static int virtio_gpu_verify_access(struct ttm_buffer_object *bo, > + struct file *filp) > +{ > + return 0; > +} > + > +static int virtio_gpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, > + struct ttm_mem_reg *mem) > +{ > + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; > + > + mem->bus.addr = NULL; > + mem->bus.offset = 0; > + mem->bus.size = mem->num_pages << PAGE_SHIFT; > + mem->bus.base = 0; > + mem->bus.is_iomem = false; > + if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) > + return -EINVAL; > + switch (mem->mem_type) { > + case TTM_PL_SYSTEM: > + case TTM_PL_TT: > + /* system memory */ > + return 0; > + default: > + return -EINVAL; > + } > + return 0; > +} > + > +static void virtio_gpu_ttm_io_mem_free(struct ttm_bo_device *bdev, > + struct ttm_mem_reg *mem) > +{ > +} > + > +/* > + * TTM backend functions. > + */ > +struct virtio_gpu_ttm_tt { > + struct ttm_dma_tt ttm; > + struct virtio_gpu_device *vgdev; > + u64 offset; > +}; > + > +static int virtio_gpu_ttm_backend_bind(struct ttm_tt *ttm, > + struct ttm_mem_reg *bo_mem) > +{ > + struct virtio_gpu_ttm_tt *gtt = (void *)ttm; > + > + gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); > + if (!ttm->num_pages) > + WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", > + ttm->num_pages, bo_mem, ttm); > + > + /* Not implemented */ > + return 0; > +} > + > +static int virtio_gpu_ttm_backend_unbind(struct ttm_tt *ttm) > +{ > + /* Not implemented */ > + return 0; > +} > + > +static void virtio_gpu_ttm_backend_destroy(struct ttm_tt *ttm) > +{ > + struct virtio_gpu_ttm_tt *gtt = (void *)ttm; > + > + ttm_dma_tt_fini(>t->ttm); > + kfree(gtt); > +} > + > +static struct ttm_backend_func virtio_gpu_backend_func = { > + .bind = &virtio_gpu_ttm_backend_bind, > + .unbind = &virtio_gpu_ttm_backend_unbind, > + .destroy = &virtio_gpu_ttm_backend_destroy, > +}; > + > +static int virtio_gpu_ttm_tt_populate(struct ttm_tt *ttm) > +{ > + if (ttm->state != tt_unpopulated) > + return 0; > + > + return ttm_pool_populate(ttm); > +} > + > +static void virtio_gpu_ttm_tt_unpopulate(struct ttm_tt *ttm) > +{ > + ttm_pool_unpopulate(ttm); > +} > + > +static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_bo_device *bdev, > + unsigned long size, > + uint32_t page_flags, > + struct page *dummy_read_page) > +{ > + struct virtio_gpu_device *vgdev; > + struct virtio_gpu_ttm_tt *gtt; > + > + vgdev = virtio_gpu_get_vgdev(bdev); > + gtt = kzalloc(sizeof(struct virtio_gpu_ttm_tt), GFP_KERNEL); > + if (gtt == NULL) > + return NULL; > + gtt->ttm.ttm.func = &virtio_gpu_backend_func; > + gtt->vgdev = vgdev; > + if (ttm_dma_tt_init(>t->ttm, bdev, size, page_flags, > + dummy_read_page)) { > + kfree(gtt); > + return NULL; > + } > + return >t->ttm.ttm; > +} > + > +static void virtio_gpu_move_null(struct ttm_buffer_object *bo, > + struct ttm_mem_reg *new_mem) > +{ > + struct ttm_mem_reg *old_mem = &bo->mem; > + > + BUG_ON(old_mem->mm_node != NULL); > + *old_mem = *new_mem; > + new_mem->mm_node = NULL; > +} > + > +static int virtio_gpu_bo_move(struct ttm_buffer_object *bo, > + bool evict, bool interruptible, > + bool no_wait_gpu, > + struct ttm_mem_reg *new_mem) > +{ > + virtio_gpu_move_null(bo, new_mem); > + return 0; > +} > + > +static void virtio_gpu_bo_move_notify(struct ttm_buffer_object *tbo, > + struct ttm_mem_reg *new_mem) > +{ > + struct virtio_gpu_object *bo; > + struct virtio_gpu_device *vgdev; > + > + bo = container_of(tbo, struct virtio_gpu_object, tbo); > + vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; > + > + if (!new_mem || (new_mem->placement & TTM_PL_FLAG_SYSTEM)) { > + if (bo->hw_res_handle) > + virtio_gpu_cmd_resource_inval_backing(vgdev, > + bo->hw_res_handle); > + > + } else if (new_mem->placement & TTM_PL_FLAG_TT) { > + if (bo->hw_res_handle) { > + virtio_gpu_object_attach(vgdev, bo, bo->hw_res_handle, > + NULL); > + } > + } > +} > + > +static void virtio_gpu_bo_swap_notify(struct ttm_buffer_object *tbo) > +{ > + struct virtio_gpu_object *bo; > + struct virtio_gpu_device *vgdev; > + > + bo = container_of(tbo, struct virtio_gpu_object, tbo); > + vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; > + > + if (bo->pages) > + virtio_gpu_object_free_sg_table(bo); > +} > + > +static struct ttm_bo_driver virtio_gpu_bo_driver = { > + .ttm_tt_create = &virtio_gpu_ttm_tt_create, > + .ttm_tt_populate = &virtio_gpu_ttm_tt_populate, > + .ttm_tt_unpopulate = &virtio_gpu_ttm_tt_unpopulate, > + .invalidate_caches = &virtio_gpu_invalidate_caches, > + .init_mem_type = &virtio_gpu_init_mem_type, > + .evict_flags = &virtio_gpu_evict_flags, > + .move = &virtio_gpu_bo_move, > + .verify_access = &virtio_gpu_verify_access, > + .io_mem_reserve = &virtio_gpu_ttm_io_mem_reserve, > + .io_mem_free = &virtio_gpu_ttm_io_mem_free, > + .move_notify = &virtio_gpu_bo_move_notify, > + .swap_notify = &virtio_gpu_bo_swap_notify, > +}; > + > +int virtio_gpu_ttm_init(struct virtio_gpu_device *vgdev) > +{ > + int r; > + > + r = virtio_gpu_ttm_global_init(vgdev); > + if (r) > + return r; > + /* No others user of address space so set it to 0 */ > + r = ttm_bo_device_init(&vgdev->mman.bdev, > + vgdev->mman.bo_global_ref.ref.object, > + &virtio_gpu_bo_driver, > + vgdev->ddev->anon_inode->i_mapping, > + DRM_FILE_PAGE_OFFSET, 0); > + if (r) { > + DRM_ERROR("failed initializing buffer object driver(%d).\n", r); > + goto err_dev_init; > + return r; > + } > + > + r = ttm_bo_init_mm(&vgdev->mman.bdev, TTM_PL_TT, 0); > + if (r) { > + DRM_ERROR("Failed initializing GTT heap.\n"); > + goto err_mm_init; > + return r; > + } > + return 0; > + > +err_mm_init: > + ttm_bo_device_release(&vgdev->mman.bdev); > +err_dev_init: > + virtio_gpu_ttm_global_fini(vgdev); > + return r; > +} > + > +void virtio_gpu_ttm_fini(struct virtio_gpu_device *vgdev) > +{ > + ttm_bo_device_release(&vgdev->mman.bdev); > + virtio_gpu_ttm_global_fini(vgdev); > + DRM_INFO("virtio_gpu: ttm finalized\n"); > +} > diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c > new file mode 100644 > index 0000000..8fa6513e > --- /dev/null > +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c > @@ -0,0 +1,614 @@ > +/* > + * Copyright (C) 2015 Red Hat, Inc. > + * All Rights Reserved. > + * > + * Authors: > + * Dave Airlie > + * Gerd Hoffmann > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include > +#include "virtgpu_drv.h" > +#include > +#include > +#include > + > +#define MAX_INLINE_CMD_SIZE 96 > +#define MAX_INLINE_RESP_SIZE 24 > +#define VBUFFER_SIZE (sizeof(struct virtio_gpu_vbuffer) \ > + + MAX_INLINE_CMD_SIZE \ > + + MAX_INLINE_RESP_SIZE) > + > +void virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, > + uint32_t *resid) > +{ > + int handle; > + > + idr_preload(GFP_KERNEL); > + spin_lock(&vgdev->resource_idr_lock); > + handle = idr_alloc(&vgdev->resource_idr, NULL, 1, 0, GFP_NOWAIT); > + spin_unlock(&vgdev->resource_idr_lock); > + idr_preload_end(); > + *resid = handle; > +} > + > +void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) > +{ > + spin_lock(&vgdev->resource_idr_lock); > + idr_remove(&vgdev->resource_idr, id); > + spin_unlock(&vgdev->resource_idr_lock); > +} > + > +void virtio_gpu_ctrl_ack(struct virtqueue *vq) > +{ > + struct drm_device *dev = vq->vdev->priv; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + schedule_work(&vgdev->ctrlq.dequeue_work); > +} > + > +void virtio_gpu_cursor_ack(struct virtqueue *vq) > +{ > + struct drm_device *dev = vq->vdev->priv; > + struct virtio_gpu_device *vgdev = dev->dev_private; > + schedule_work(&vgdev->cursorq.dequeue_work); > +} > + > +int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + int i, size, count = 0; > + void *ptr; > + > + INIT_LIST_HEAD(&vgdev->free_vbufs); > + count += virtqueue_get_vring_size(vgdev->ctrlq.vq); > + count += virtqueue_get_vring_size(vgdev->cursorq.vq); > + size = count * VBUFFER_SIZE; > + DRM_INFO("virtio vbuffers: %d bufs, %zdB each, %dkB total.\n", > + count, VBUFFER_SIZE, size / 1024); > + > + vgdev->vbufs = kzalloc(size, GFP_KERNEL); > + if (!vgdev->vbufs) > + return -ENOMEM; > + > + for (i = 0, ptr = vgdev->vbufs; > + i < count; > + i++, ptr += VBUFFER_SIZE) { > + vbuf = ptr; > + list_add(&vbuf->list, &vgdev->free_vbufs); > + } > + return 0; > +} > + > +void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + int i, count = 0; > + > + count += virtqueue_get_vring_size(vgdev->ctrlq.vq); > + count += virtqueue_get_vring_size(vgdev->cursorq.vq); > + > + for (i = 0; i < count; i++) { > + if (WARN_ON(list_empty(&vgdev->free_vbufs))) > + return; > + vbuf = list_first_entry(&vgdev->free_vbufs, > + struct virtio_gpu_vbuffer, list); > + list_del(&vbuf->list); > + } > + kfree(vgdev->vbufs); > +} > + > +static struct virtio_gpu_vbuffer* > +virtio_gpu_get_vbuf(struct virtio_gpu_device *vgdev, > + int size, int resp_size, void *resp_buf, > + virtio_gpu_resp_cb resp_cb) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + > + BUG_ON(list_empty(&vgdev->free_vbufs)); > + vbuf = list_first_entry(&vgdev->free_vbufs, > + struct virtio_gpu_vbuffer, list); > + list_del(&vbuf->list); > + memset(vbuf, 0, VBUFFER_SIZE); > + > + BUG_ON(size > MAX_INLINE_CMD_SIZE); > + vbuf->buf = (void *)vbuf + sizeof(*vbuf); > + vbuf->size = size; > + > + vbuf->resp_cb = resp_cb; > + vbuf->resp_size = resp_size; > + if (resp_size <= MAX_INLINE_RESP_SIZE) > + vbuf->resp_buf = (void *)vbuf->buf + size; > + else > + vbuf->resp_buf = resp_buf; > + BUG_ON(!vbuf->resp_buf); > + return vbuf; > +} > + > +static void *virtio_gpu_alloc_cmd(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer **vbuffer_p, > + int size) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + > + vbuf = virtio_gpu_get_vbuf(vgdev, size, > + sizeof(struct virtio_gpu_ctrl_hdr), > + NULL, NULL); > + if (IS_ERR(vbuf)) { > + *vbuffer_p = NULL; > + return ERR_CAST(vbuf); > + } > + *vbuffer_p = vbuf; > + return vbuf->buf; > +} > + > +static struct virtio_gpu_update_cursor* > +virtio_gpu_alloc_cursor(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer **vbuffer_p) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + > + vbuf = virtio_gpu_get_vbuf > + (vgdev, sizeof(struct virtio_gpu_update_cursor), > + 0, NULL, NULL); > + if (IS_ERR(vbuf)) { > + *vbuffer_p = NULL; > + return ERR_CAST(vbuf); > + } > + *vbuffer_p = vbuf; > + return (struct virtio_gpu_update_cursor *)vbuf->buf; > +} > + > +static void *virtio_gpu_alloc_cmd_resp(struct virtio_gpu_device *vgdev, > + virtio_gpu_resp_cb cb, > + struct virtio_gpu_vbuffer **vbuffer_p, > + int cmd_size, int resp_size, > + void *resp_buf) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + > + vbuf = virtio_gpu_get_vbuf(vgdev, cmd_size, > + resp_size, resp_buf, cb); > + if (IS_ERR(vbuf)) { > + *vbuffer_p = NULL; > + return ERR_CAST(vbuf); > + } > + *vbuffer_p = vbuf; > + return (struct virtio_gpu_command *)vbuf->buf; > +} > + > +static void free_vbuf(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer *vbuf) > +{ > + if (vbuf->resp_size > MAX_INLINE_RESP_SIZE) > + kfree(vbuf->resp_buf); > + kfree(vbuf->data_buf); > + list_add(&vbuf->list, &vgdev->free_vbufs); > +} > + > +static void reclaim_vbufs(struct virtqueue *vq, struct list_head *reclaim_list) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + unsigned int len; > + int freed = 0; > + > + while ((vbuf = virtqueue_get_buf(vq, &len))) { > + list_add_tail(&vbuf->list, reclaim_list); > + freed++; > + } > + if (freed == 0) > + DRM_DEBUG("Huh? zero vbufs reclaimed"); > +} > + > +void virtio_gpu_dequeue_ctrl_func(struct work_struct *work) > +{ > + struct virtio_gpu_device *vgdev = > + container_of(work, struct virtio_gpu_device, > + ctrlq.dequeue_work); > + struct list_head reclaim_list; > + struct virtio_gpu_vbuffer *entry, *tmp; > + struct virtio_gpu_ctrl_hdr *resp; > + u64 fence_id = 0; > + > + INIT_LIST_HEAD(&reclaim_list); > + spin_lock(&vgdev->ctrlq.qlock); > + do { > + virtqueue_disable_cb(vgdev->ctrlq.vq); > + reclaim_vbufs(vgdev->ctrlq.vq, &reclaim_list); > + > + } while (!virtqueue_enable_cb(vgdev->ctrlq.vq)); > + spin_unlock(&vgdev->ctrlq.qlock); > + > + list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { > + resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf; > + if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) > + DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); > + if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) { > + u64 f = le64_to_cpu(resp->fence_id); > + > + if (fence_id > f) { > + DRM_ERROR("%s: Oops: fence %llx -> %llx\n", > + __func__, fence_id, f); > + } else { > + fence_id = f; > + } > + } > + if (entry->resp_cb) > + entry->resp_cb(vgdev, entry); > + > + list_del(&entry->list); > + free_vbuf(vgdev, entry); > + } > + wake_up(&vgdev->ctrlq.ack_queue); > + > + if (fence_id) > + virtio_gpu_fence_event_process(vgdev, fence_id); > +} > + > +void virtio_gpu_dequeue_cursor_func(struct work_struct *work) > +{ > + struct virtio_gpu_device *vgdev = > + container_of(work, struct virtio_gpu_device, > + cursorq.dequeue_work); > + struct list_head reclaim_list; > + struct virtio_gpu_vbuffer *entry, *tmp; > + > + INIT_LIST_HEAD(&reclaim_list); > + spin_lock(&vgdev->cursorq.qlock); > + do { > + virtqueue_disable_cb(vgdev->cursorq.vq); > + reclaim_vbufs(vgdev->cursorq.vq, &reclaim_list); > + } while (!virtqueue_enable_cb(vgdev->cursorq.vq)); > + spin_unlock(&vgdev->cursorq.qlock); > + > + list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { > + list_del(&entry->list); > + free_vbuf(vgdev, entry); > + } > + wake_up(&vgdev->cursorq.ack_queue); > +} > + > +static int virtio_gpu_queue_ctrl_buffer(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer *vbuf) > +{ > + struct virtqueue *vq = vgdev->ctrlq.vq; > + struct scatterlist *sgs[3], vcmd, vout, vresp; > + int outcnt = 0, incnt = 0; > + int ret; > + > + if (!vgdev->vqs_ready) > + return -ENODEV; > + > + sg_init_one(&vcmd, vbuf->buf, vbuf->size); > + sgs[outcnt+incnt] = &vcmd; > + outcnt++; > + > + if (vbuf->data_size) { > + sg_init_one(&vout, vbuf->data_buf, vbuf->data_size); > + sgs[outcnt + incnt] = &vout; > + outcnt++; > + } > + > + if (vbuf->resp_size) { > + sg_init_one(&vresp, vbuf->resp_buf, vbuf->resp_size); > + sgs[outcnt + incnt] = &vresp; > + incnt++; > + } > + > + spin_lock(&vgdev->ctrlq.qlock); > +retry: > + ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); > + if (ret == -ENOSPC) { > + spin_unlock(&vgdev->ctrlq.qlock); > + wait_event(vgdev->ctrlq.ack_queue, vq->num_free); > + spin_lock(&vgdev->ctrlq.qlock); > + goto retry; > + } else { > + virtqueue_kick(vq); > + } > + spin_unlock(&vgdev->ctrlq.qlock); > + > + if (!ret) > + ret = vq->num_free; > + return ret; > +} > + > +static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer *vbuf) > +{ > + struct virtqueue *vq = vgdev->cursorq.vq; > + struct scatterlist *sgs[1], ccmd; > + int ret; > + int outcnt; > + > + if (!vgdev->vqs_ready) > + return -ENODEV; > + > + sg_init_one(&ccmd, vbuf->buf, vbuf->size); > + sgs[0] = &ccmd; > + outcnt = 1; > + > + spin_lock(&vgdev->cursorq.qlock); > +retry: > + ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); > + if (ret == -ENOSPC) { > + spin_unlock(&vgdev->cursorq.qlock); > + wait_event(vgdev->cursorq.ack_queue, vq->num_free); > + spin_lock(&vgdev->cursorq.qlock); > + goto retry; > + } else { > + virtqueue_kick(vq); > + } > + > + spin_unlock(&vgdev->cursorq.qlock); > + > + if (!ret) > + ret = vq->num_free; > + return ret; > +} > + > +/* just create gem objects for userspace and long lived objects, > + just use dma_alloced pages for the queue objects? */ > + > +/* create a basic resource */ > +void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, > + uint32_t format, > + uint32_t width, > + uint32_t height) > +{ > + struct virtio_gpu_resource_create_2d *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_2D); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + cmd_p->format = cpu_to_le32(format); > + cmd_p->width = cpu_to_le32(width); > + cmd_p->height = cpu_to_le32(height); > + > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, > + uint32_t resource_id) > +{ > + struct virtio_gpu_resource_unref *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_UNREF); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +void virtio_gpu_cmd_resource_inval_backing(struct virtio_gpu_device *vgdev, > + uint32_t resource_id) > +{ > + struct virtio_gpu_resource_detach_backing *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev, > + uint32_t scanout_id, uint32_t resource_id, > + uint32_t width, uint32_t height, > + uint32_t x, uint32_t y) > +{ > + struct virtio_gpu_set_scanout *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_SET_SCANOUT); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + cmd_p->scanout_id = cpu_to_le32(scanout_id); > + cmd_p->r.width = cpu_to_le32(width); > + cmd_p->r.height = cpu_to_le32(height); > + cmd_p->r.x = cpu_to_le32(x); > + cmd_p->r.y = cpu_to_le32(y); > + > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +void virtio_gpu_cmd_resource_flush(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, > + uint32_t x, uint32_t y, > + uint32_t width, uint32_t height) > +{ > + struct virtio_gpu_resource_flush *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_FLUSH); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + cmd_p->r.width = cpu_to_le32(width); > + cmd_p->r.height = cpu_to_le32(height); > + cmd_p->r.x = cpu_to_le32(x); > + cmd_p->r.y = cpu_to_le32(y); > + > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, uint64_t offset, > + __le32 width, __le32 height, > + __le32 x, __le32 y, > + struct virtio_gpu_fence **fence) > +{ > + struct virtio_gpu_transfer_to_host_2d *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + cmd_p->offset = cpu_to_le64(offset); > + cmd_p->r.width = width; > + cmd_p->r.height = height; > + cmd_p->r.x = x; > + cmd_p->r.y = y; > + > + if (fence) > + virtio_gpu_fence_emit(vgdev, &cmd_p->hdr, fence); > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +static void > +virtio_gpu_cmd_resource_attach_backing(struct virtio_gpu_device *vgdev, > + uint32_t resource_id, > + struct virtio_gpu_mem_entry *ents, > + uint32_t nents, > + struct virtio_gpu_fence **fence) > +{ > + struct virtio_gpu_resource_attach_backing *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + > + cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING); > + cmd_p->resource_id = cpu_to_le32(resource_id); > + cmd_p->nr_entries = cpu_to_le32(nents); > + > + vbuf->data_buf = ents; > + vbuf->data_size = sizeof(*ents) * nents; > + > + if (fence) > + virtio_gpu_fence_emit(vgdev, &cmd_p->hdr, fence); > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > +} > + > +static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_vbuffer *vbuf) > +{ > + struct virtio_gpu_resp_display_info *resp = > + (struct virtio_gpu_resp_display_info *)vbuf->resp_buf; > + int i; > + > + spin_lock(&vgdev->display_info_lock); > + for (i = 0; i < vgdev->num_scanouts; i++) { > + vgdev->outputs[i].info = resp->pmodes[i]; > + if (resp->pmodes[i].enabled) { > + DRM_DEBUG("output %d: %dx%d+%d+%d", i, > + le32_to_cpu(resp->pmodes[i].r.width), > + le32_to_cpu(resp->pmodes[i].r.height), > + le32_to_cpu(resp->pmodes[i].r.x), > + le32_to_cpu(resp->pmodes[i].r.y)); > + } else { > + DRM_DEBUG("output %d: disabled", i); > + } > + } > + > + spin_unlock(&vgdev->display_info_lock); > + wake_up(&vgdev->resp_wq); > + > + if (!drm_helper_hpd_irq_event(vgdev->ddev)) > + drm_kms_helper_hotplug_event(vgdev->ddev); > +} > + > +int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) > +{ > + struct virtio_gpu_ctrl_hdr *cmd_p; > + struct virtio_gpu_vbuffer *vbuf; > + void *resp_buf; > + > + resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_display_info), > + GFP_KERNEL); > + if (!resp_buf) > + return -ENOMEM; > + > + cmd_p = virtio_gpu_alloc_cmd_resp > + (vgdev, &virtio_gpu_cmd_get_display_info_cb, &vbuf, > + sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_display_info), > + resp_buf); > + memset(cmd_p, 0, sizeof(*cmd_p)); > + > + cmd_p->type = cpu_to_le32(VIRTIO_GPU_CMD_GET_DISPLAY_INFO); > + virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); > + return 0; > +} > + > +int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_object *obj, > + uint32_t resource_id, > + struct virtio_gpu_fence **fence) > +{ > + struct virtio_gpu_mem_entry *ents; > + struct scatterlist *sg; > + int si; > + > + if (!obj->pages) { > + int ret; > + ret = virtio_gpu_object_get_sg_table(vgdev, obj); > + if (ret) > + return ret; > + } > + > + /* gets freed when the ring has consumed it */ > + ents = kmalloc_array(obj->pages->nents, > + sizeof(struct virtio_gpu_mem_entry), > + GFP_KERNEL); > + if (!ents) { > + DRM_ERROR("failed to allocate ent list\n"); > + return -ENOMEM; > + } > + > + for_each_sg(obj->pages->sgl, sg, obj->pages->nents, si) { > + ents[si].addr = cpu_to_le64(sg_phys(sg)); > + ents[si].length = cpu_to_le32(sg->length); > + ents[si].padding = 0; > + } > + > + virtio_gpu_cmd_resource_attach_backing(vgdev, resource_id, > + ents, obj->pages->nents, > + fence); > + obj->hw_res_handle = resource_id; > + return 0; > +} > + > +void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, > + struct virtio_gpu_output *output) > +{ > + struct virtio_gpu_vbuffer *vbuf; > + struct virtio_gpu_update_cursor *cur_p; > + > + output->cursor.pos.scanout_id = cpu_to_le32(output->index); > + cur_p = virtio_gpu_alloc_cursor(vgdev, &vbuf); > + memcpy(cur_p, &output->cursor, sizeof(output->cursor)); > + virtio_gpu_queue_cursor(vgdev, vbuf); > +} > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 62c40777..1544bb1 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -812,6 +812,7 @@ struct drm_device { > #endif > > struct platform_device *platformdev; /**< Platform device struture */ > + struct virtio_device *virtdev; > > struct drm_sg_mem *sg; /**< Scatter gather memory */ > unsigned int num_crtcs; /**< Number of CRTCs on this device */ > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild > index 1a0006a..4460e58 100644 > --- a/include/uapi/linux/Kbuild > +++ b/include/uapi/linux/Kbuild > @@ -430,6 +430,7 @@ header-y += virtio_balloon.h > header-y += virtio_blk.h > header-y += virtio_config.h > header-y += virtio_console.h > +header-y += virtio_gpu.h > header-y += virtio_ids.h > header-y += virtio_input.h > header-y += virtio_net.h > diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h > new file mode 100644 > index 0000000..571c4cb > --- /dev/null > +++ b/include/uapi/linux/virtio_gpu.h > @@ -0,0 +1,204 @@ > +/* > + * Virtio GPU Device > + * > + * Copyright Red Hat, Inc. 2013-2014 > + * > + * Authors: > + * Dave Airlie > + * Gerd Hoffmann > + * > + * This header is BSD licensed so anyone can use the definitions > + * to implement compatible drivers/servers: > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of IBM nor the names of its contributors > + * may be used to endorse or promote products derived from this software > + * without specific prior written permission. > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS > + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, > + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT > + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF > + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND > + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > + > +#ifndef VIRTIO_GPU_HW_H > +#define VIRTIO_GPU_HW_H > + > +enum virtio_gpu_ctrl_type { > + VIRTIO_GPU_UNDEFINED = 0, > + > + /* 2d commands */ > + VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, > + VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, > + VIRTIO_GPU_CMD_RESOURCE_UNREF, > + VIRTIO_GPU_CMD_SET_SCANOUT, > + VIRTIO_GPU_CMD_RESOURCE_FLUSH, > + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, > + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, > + VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, > + > + /* cursor commands */ > + VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, > + VIRTIO_GPU_CMD_MOVE_CURSOR, > + > + /* success responses */ > + VIRTIO_GPU_RESP_OK_NODATA = 0x1100, > + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, > + > + /* error responses */ > + VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, > + VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, > + VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, > + VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, > +}; > + > +#define VIRTIO_GPU_FLAG_FENCE (1 << 0) > + > +struct virtio_gpu_ctrl_hdr { > + __le32 type; > + __le32 flags; > + __le64 fence_id; > + __le32 ctx_id; > + __le32 padding; > +}; > + > +/* data passed in the cursor vq */ > + > +struct virtio_gpu_cursor_pos { > + __le32 scanout_id; > + __le32 x; > + __le32 y; > + __le32 padding; > +}; > + > +/* VIRTIO_GPU_CMD_UPDATE_CURSOR, VIRTIO_GPU_CMD_MOVE_CURSOR */ > +struct virtio_gpu_update_cursor { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_cursor_pos pos; /* update & move */ > + __le32 resource_id; /* update only */ > + __le32 hot_x; /* update only */ > + __le32 hot_y; /* update only */ > + __le32 padding; > +}; > + > +/* data passed in the control vq, 2d related */ > + > +struct virtio_gpu_rect { > + __le32 x; > + __le32 y; > + __le32 width; > + __le32 height; > +}; > + > +/* VIRTIO_GPU_CMD_RESOURCE_UNREF */ > +struct virtio_gpu_resource_unref { > + struct virtio_gpu_ctrl_hdr hdr; > + __le32 resource_id; > + __le32 padding; > +}; > + > +/* VIRTIO_GPU_CMD_RESOURCE_CREATE_2D: create a 2d resource with a format */ > +struct virtio_gpu_resource_create_2d { > + struct virtio_gpu_ctrl_hdr hdr; > + __le32 resource_id; > + __le32 format; > + __le32 width; > + __le32 height; > +}; > + > +/* VIRTIO_GPU_CMD_SET_SCANOUT */ > +struct virtio_gpu_set_scanout { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + __le32 scanout_id; > + __le32 resource_id; > +}; > + > +/* VIRTIO_GPU_CMD_RESOURCE_FLUSH */ > +struct virtio_gpu_resource_flush { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + __le32 resource_id; > + __le32 padding; > +}; > + > +/* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D: simple transfer to_host */ > +struct virtio_gpu_transfer_to_host_2d { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_rect r; > + __le64 offset; > + __le32 resource_id; > + __le32 padding; > +}; > + > +struct virtio_gpu_mem_entry { > + __le64 addr; > + __le32 length; > + __le32 padding; > +}; > + > +/* VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING */ > +struct virtio_gpu_resource_attach_backing { > + struct virtio_gpu_ctrl_hdr hdr; > + __le32 resource_id; > + __le32 nr_entries; > +}; > + > +/* VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING */ > +struct virtio_gpu_resource_detach_backing { > + struct virtio_gpu_ctrl_hdr hdr; > + __le32 resource_id; > + __le32 padding; > +}; > + > +/* VIRTIO_GPU_RESP_OK_DISPLAY_INFO */ > +#define VIRTIO_GPU_MAX_SCANOUTS 16 > +struct virtio_gpu_resp_display_info { > + struct virtio_gpu_ctrl_hdr hdr; > + struct virtio_gpu_display_one { > + struct virtio_gpu_rect r; > + __le32 enabled; > + __le32 flags; > + } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; > +}; > + > +#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) > + > +struct virtio_gpu_config { > + __u32 events_read; > + __u32 events_clear; > + __u32 num_scanouts; > + __u32 reserved; > +}; > + > +/* simple formats for fbcon/X use */ > +enum virtio_gpu_formats { > + VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, > + VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, > + VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, > + VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, > + > + VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, > + VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, > + > + VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, > + VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, > +}; > + > +#endif > diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h > index 5f60aa4..77925f5 100644 > --- a/include/uapi/linux/virtio_ids.h > +++ b/include/uapi/linux/virtio_ids.h > @@ -39,6 +39,7 @@ > #define VIRTIO_ID_9P 9 /* 9p virtio console */ > #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ > #define VIRTIO_ID_CAIF 12 /* Virtio caif */ > +#define VIRTIO_ID_GPU 16 /* virtio GPU */ > #define VIRTIO_ID_INPUT 18 /* virtio input */ > > #endif /* _LINUX_VIRTIO_IDS_H */ > -- > 1.8.3.1