From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kenneth Lee Subject: Re: [RFC PATCH 3/7] vfio: add spimdev support Date: Thu, 2 Aug 2018 11:47:27 +0800 Message-ID: <20180802034727.GK160746@Turing-Arch-b> References: <20180801102221.5308-1-nek.in.cn@gmail.com> <20180801102221.5308-4-nek.in.cn@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: Kenneth Lee , Herbert Xu , "kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , Jonathan Corbet , Greg Kroah-Hartman , "linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , "Kumar, Sanjay K" , Hao Fang , "iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org" , "linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , "linuxarm-hv44wF8Li93QT0dZR+AlfA@public.gmane.org" , Alex Williamson , Thomas Gleixner , "linux-crypto-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , Philippe Ombredanne , Zaibo Xu , "David S . Miller" , "linux-accelerators-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org" To: "Tian, Kevin" Return-path: Content-Disposition: inline In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org List-Id: linux-crypto.vger.kernel.org T24gVGh1LCBBdWcgMDIsIDIwMTggYXQgMDM6MjE6MjVBTSArMDAwMCwgVGlhbiwgS2V2aW4gd3Jv dGU6Cj4gRGF0ZTogVGh1LCAyIEF1ZyAyMDE4IDAzOjIxOjI1ICswMDAwCj4gRnJvbTogIlRpYW4s IEtldmluIiA8a2V2aW4udGlhbkBpbnRlbC5jb20+Cj4gVG86IEtlbm5ldGggTGVlIDxuZWsuaW4u Y25AZ21haWwuY29tPiwgSm9uYXRoYW4gQ29yYmV0IDxjb3JiZXRAbHduLm5ldD4sCj4gIEhlcmJl cnQgWHUgPGhlcmJlcnRAZ29uZG9yLmFwYW5hLm9yZy5hdT4sICJEYXZpZCBTIC4gTWlsbGVyIgo+ ICA8ZGF2ZW1AZGF2ZW1sb2Z0Lm5ldD4sIEpvZXJnIFJvZWRlbCA8am9yb0A4Ynl0ZXMub3JnPiwg QWxleCBXaWxsaWFtc29uCj4gIDxhbGV4LndpbGxpYW1zb25AcmVkaGF0LmNvbT4sIEtlbm5ldGgg TGVlIDxsaWd1b3podUBoaXNpbGljb24uY29tPiwgSGFvCj4gIEZhbmcgPGZhbmdoYW8xMUBodWF3 ZWkuY29tPiwgWmhvdSBXYW5nIDx3YW5nemhvdTFAaGlzaWxpY29uLmNvbT4sIFphaWJvIFh1Cj4g IDx4dXphaWJvQGh1YXdlaS5jb20+LCBQaGlsaXBwZSBPbWJyZWRhbm5lIDxwb21icmVkYW5uZUBu ZXhiLmNvbT4sIEdyZWcKPiAgS3JvYWgtSGFydG1hbiA8Z3JlZ2toQGxpbnV4Zm91bmRhdGlvbi5v cmc+LCBUaG9tYXMgR2xlaXhuZXIKPiAgPHRnbHhAbGludXRyb25peC5kZT4sICJsaW51eC1kb2NA dmdlci5rZXJuZWwub3JnIgo+ICA8bGludXgtZG9jQHZnZXIua2VybmVsLm9yZz4sICJsaW51eC1r ZXJuZWxAdmdlci5rZXJuZWwub3JnIgo+ICA8bGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZz4s ICJsaW51eC1jcnlwdG9Admdlci5rZXJuZWwub3JnIgo+ICA8bGludXgtY3J5cHRvQHZnZXIua2Vy bmVsLm9yZz4sICJpb21tdUBsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZyIKPiAgPGlvbW11QGxp c3RzLmxpbnV4LWZvdW5kYXRpb24ub3JnPiwgImt2bUB2Z2VyLmtlcm5lbC5vcmciCj4gIDxrdm1A dmdlci5rZXJuZWwub3JnPiwgImxpbnV4LWFjY2VsZXJhdG9yc0BsaXN0cy5vemxhYnMub3JnIgo+ ICA8bGludXgtYWNjZWxlcmF0b3JzQGxpc3RzLm96bGFicy5vcmc+LCBMdSBCYW9sdQo+ICA8YmFv bHUubHVAbGludXguaW50ZWwuY29tPiwgIkt1bWFyLCBTYW5qYXkgSyIgPHNhbmpheS5rLmt1bWFy QGludGVsLmNvbT4KPiBDQzogImxpbnV4YXJtQGh1YXdlaS5jb20iIDxsaW51eGFybUBodWF3ZWku Y29tPgo+IFN1YmplY3Q6IFJFOiBbUkZDIFBBVENIIDMvN10gdmZpbzogYWRkIHNwaW1kZXYgc3Vw cG9ydAo+IE1lc3NhZ2UtSUQ6IDxBQURGQzQxQUZFNTQ2ODRBQjlFRTZDQkMwMjc0QTVEMTkxMjkw RjdCQFNIU01TWDEwMS5jY3IuY29ycC5pbnRlbC5jb20+Cj4gCj4gPiBGcm9tOiBLZW5uZXRoIExl ZQo+ID4gU2VudDogV2VkbmVzZGF5LCBBdWd1c3QgMSwgMjAxOCA2OjIyIFBNCj4gPiAKPiA+IEZy b206IEtlbm5ldGggTGVlIDxsaWd1b3podUBoaXNpbGljb24uY29tPgo+ID4gCj4gPiBTUElNREVW IGlzICJTaGFyZSBQYXJlbnQgSU9NTVUgTWRldiIuIEl0IGlzIGEgdmZpby1tZGV2LiBCdXQgZGlm ZmVyIGZyb20KPiA+IHRoZSBnZW5lcmFsIHZmaW8tbWRldjoKPiA+IAo+ID4gMS4gSXQgc2hhcmVz IGl0cyBwYXJlbnQncyBJT01NVS4KPiA+IDIuIFRoZXJlIGlzIG5vIGhhcmR3YXJlIHJlc291cmNl IGF0dGFjaGVkIHRvIHRoZSBtZGV2IGlzIGNyZWF0ZWQuIFRoZQo+ID4gaGFyZHdhcmUgcmVzb3Vy Y2UgKEEgYHF1ZXVlJykgaXMgYWxsb2NhdGVkIG9ubHkgd2hlbiB0aGUgbWRldiBpcwo+ID4gb3Bl bmVkLgo+IAo+IEFsZXggaGFzIGNvbmNlcm4gb24gZG9pbmcgc28sIGFzIHBvaW50ZWQgb3V0IGlu Ogo+IAo+IAlodHRwczovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9rdm0vbXNnMTcyNjUyLmh0bWwK PiAKPiByZXNvdXJjZSBhbGxvY2F0aW9uIHNob3VsZCBiZSByZXNlcnZlZCBhdCBjcmVhdGlvbiB0 aW1lLgoKWWVzLiBUaGF0IGlzIHdoeSBJIGtlZXAgdGVsbGluZyB0aGF0IFNQSU1ERVYgaXMgbm90 IGZvciAiVk0iLCBpdCBpcyBmb3IgIm1hbnkKcHJvY2Vzc2VzIiwgaXQgaXMganVzdCBhbiBhY2Nl c3MgcG9pbnQgdG8gdGhlIHByb2Nlc3MuIE5vdCBhIGRldmljZSB0byBWTS4gSSBob3BlCkFsZXgg Y2FuIGFjY2VwdCBpdDopCgo+IAo+ID4gCj4gPiBDdXJyZW50bHkgb25seSB0aGUgdmZpbyB0eXBl LTEgZHJpdmVyIGlzIHVwZGF0ZWQgdG8gbWFrZSBpdCB0byBiZSBhd2FyZQo+ID4gb2YuCj4gPiAK PiA+IFNpZ25lZC1vZmYtYnk6IEtlbm5ldGggTGVlIDxsaWd1b3podUBoaXNpbGljb24uY29tPgo+ ID4gU2lnbmVkLW9mZi1ieTogWmFpYm8gWHUgPHh1emFpYm9AaHVhd2VpLmNvbT4KPiA+IFNpZ25l ZC1vZmYtYnk6IFpob3UgV2FuZyA8d2FuZ3pob3UxQGhpc2lsaWNvbi5jb20+Cj4gPiAtLS0KPiA+ ICBkcml2ZXJzL3ZmaW8vS2NvbmZpZyAgICAgICAgICAgICAgICB8ICAgMSArCj4gPiAgZHJpdmVy cy92ZmlvL01ha2VmaWxlICAgICAgICAgICAgICAgfCAgIDEgKwo+ID4gIGRyaXZlcnMvdmZpby9z cGltZGV2L0tjb25maWcgICAgICAgIHwgIDEwICsKPiA+ICBkcml2ZXJzL3ZmaW8vc3BpbWRldi9N YWtlZmlsZSAgICAgICB8ICAgMyArCj4gPiAgZHJpdmVycy92ZmlvL3NwaW1kZXYvdmZpb19zcGlt ZGV2LmMgfCA0MjEKPiA+ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiA+ICBkcml2ZXJz L3ZmaW8vdmZpb19pb21tdV90eXBlMS5jICAgICB8IDEzNiArKysrKysrKy0KPiA+ICBpbmNsdWRl L2xpbnV4L3ZmaW9fc3BpbWRldi5oICAgICAgICB8ICA5NSArKysrKysrCj4gPiAgaW5jbHVkZS91 YXBpL2xpbnV4L3ZmaW9fc3BpbWRldi5oICAgfCAgMjggKysKPiA+ICA4IGZpbGVzIGNoYW5nZWQs IDY4OSBpbnNlcnRpb25zKCspLCA2IGRlbGV0aW9ucygtKQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0 NCBkcml2ZXJzL3ZmaW8vc3BpbWRldi9LY29uZmlnCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRy aXZlcnMvdmZpby9zcGltZGV2L01ha2VmaWxlCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvdmZpby9zcGltZGV2L3ZmaW9fc3BpbWRldi5jCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGlu Y2x1ZGUvbGludXgvdmZpb19zcGltZGV2LmgKPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgaW5jbHVk ZS91YXBpL2xpbnV4L3ZmaW9fc3BpbWRldi5oCj4gPiAKPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJz L3ZmaW8vS2NvbmZpZyBiL2RyaXZlcnMvdmZpby9LY29uZmlnCj4gPiBpbmRleCBjODQzMzNlYjVl YjUuLjM3MTllYmE3MmVmMSAxMDA2NDQKPiA+IC0tLSBhL2RyaXZlcnMvdmZpby9LY29uZmlnCj4g PiArKysgYi9kcml2ZXJzL3ZmaW8vS2NvbmZpZwo+ID4gQEAgLTQ3LDQgKzQ3LDUgQEAgbWVudWNv bmZpZyBWRklPX05PSU9NTVUKPiA+ICBzb3VyY2UgImRyaXZlcnMvdmZpby9wY2kvS2NvbmZpZyIK PiA+ICBzb3VyY2UgImRyaXZlcnMvdmZpby9wbGF0Zm9ybS9LY29uZmlnIgo+ID4gIHNvdXJjZSAi ZHJpdmVycy92ZmlvL21kZXYvS2NvbmZpZyIKPiA+ICtzb3VyY2UgImRyaXZlcnMvdmZpby9zcGlt ZGV2L0tjb25maWciCj4gPiAgc291cmNlICJ2aXJ0L2xpYi9LY29uZmlnIgo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvdmZpby9NYWtlZmlsZSBiL2RyaXZlcnMvdmZpby9NYWtlZmlsZQo+ID4gaW5k ZXggZGU2N2M0NzI1Y2NlLi4yOGYzZWYwY2RjZTEgMTAwNjQ0Cj4gPiAtLS0gYS9kcml2ZXJzL3Zm aW8vTWFrZWZpbGUKPiA+ICsrKyBiL2RyaXZlcnMvdmZpby9NYWtlZmlsZQo+ID4gQEAgLTksMyAr OSw0IEBAIG9iai0kKENPTkZJR19WRklPX1NQQVBSX0VFSCkgKz0gdmZpb19zcGFwcl9lZWgubwo+ ID4gIG9iai0kKENPTkZJR19WRklPX1BDSSkgKz0gcGNpLwo+ID4gIG9iai0kKENPTkZJR19WRklP X1BMQVRGT1JNKSArPSBwbGF0Zm9ybS8KPiA+ICBvYmotJChDT05GSUdfVkZJT19NREVWKSArPSBt ZGV2Lwo+ID4gK29iai0kKENPTkZJR19WRklPX1NQSU1ERVYpICs9IHNwaW1kZXYvCj4gPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy92ZmlvL3NwaW1kZXYvS2NvbmZpZyBiL2RyaXZlcnMvdmZpby9zcGlt ZGV2L0tjb25maWcKPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gPiBpbmRleCAwMDAwMDAwMDAw MDAuLjEyMjYzMDFmOWQwZQo+ID4gLS0tIC9kZXYvbnVsbAo+ID4gKysrIGIvZHJpdmVycy92Zmlv L3NwaW1kZXYvS2NvbmZpZwo+ID4gQEAgLTAsMCArMSwxMCBAQAo+ID4gKyMgU1BEWC1MaWNlbnNl LUlkZW50aWZpZXI6IEdQTC0yLjAKPiA+ICtjb25maWcgVkZJT19TUElNREVWCj4gPiArCXRyaXN0 YXRlICJTdXBwb3J0IGZvciBTaGFyZSBQYXJlbnQgSU9NTVUgTURFViIKPiA+ICsJZGVwZW5kcyBv biBWRklPX01ERVZfREVWSUNFCj4gPiArCWhlbHAKPiA+ICsJICBTdXBwb3J0IGZvciBWRklPIFNo YXJlIFBhcmVudCBJT01NVSBNREVWLCB3aGljaCBlbmFibGUgdGhlCj4gPiBrZXJuZWwgdG8KPiA+ ICsJICBzdXBwb3J0IGZvciB0aGUgbGlnaHQgd2VpZ2h0IGhhcmR3YXJlIGFjY2VsZXJhdG9yIGZy YW1ld29yaywKPiA+IFdyYXBEcml2ZS4KPiA+ICsKPiA+ICsJICBUbyBjb21waWxlIHRoaXMgYXMg YSBtb2R1bGUsIGNob29zZSBNIGhlcmU6IHRoZSBtb2R1bGUgd2lsbCBiZQo+ID4gY2FsbGVkCj4g PiArCSAgc3BpbWRldi4KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3ZmaW8vc3BpbWRldi9NYWtl ZmlsZSBiL2RyaXZlcnMvdmZpby9zcGltZGV2L01ha2VmaWxlCj4gPiBuZXcgZmlsZSBtb2RlIDEw MDY0NAo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi5kMDJmYjY5YzM3ZTQKPiA+IC0tLSAvZGV2L251 bGwKPiA+ICsrKyBiL2RyaXZlcnMvdmZpby9zcGltZGV2L01ha2VmaWxlCj4gPiBAQCAtMCwwICsx LDMgQEAKPiA+ICsjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCj4gPiArc3BpbWRl di15IDo9IHNwaW1kZXYubwo+ID4gK29iai0kKENPTkZJR19WRklPX1NQSU1ERVYpICs9IHZmaW9f c3BpbWRldi5vCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy92ZmlvL3NwaW1kZXYvdmZpb19zcGlt ZGV2LmMKPiA+IGIvZHJpdmVycy92ZmlvL3NwaW1kZXYvdmZpb19zcGltZGV2LmMKPiA+IG5ldyBm aWxlIG1vZGUgMTAwNjQ0Cj4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLjFiNjkxMGM5ZDI3ZAo+ID4g LS0tIC9kZXYvbnVsbAo+ID4gKysrIGIvZHJpdmVycy92ZmlvL3NwaW1kZXYvdmZpb19zcGltZGV2 LmMKPiA+IEBAIC0wLDAgKzEsNDIxIEBACj4gPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6 IEdQTC0yLjArCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Fub25faW5vZGVzLmg+Cj4gPiArI2luY2x1 ZGUgPGxpbnV4L2lkci5oPgo+ID4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiA+ICsjaW5j bHVkZSA8bGludXgvcG9sbC5oPgo+ID4gKyNpbmNsdWRlIDxsaW51eC92ZmlvX3NwaW1kZXYuaD4K PiA+ICsKPiA+ICtzdHJ1Y3Qgc3BpbWRldl9tZGV2X3N0YXRlIHsKPiA+ICsJc3RydWN0IHZmaW9f c3BpbWRldiAqc3BpbWRldjsKPiA+ICt9Owo+ID4gKwo+ID4gK3N0YXRpYyBzdHJ1Y3QgY2xhc3Mg KnNwaW1kZXZfY2xhc3M7Cj4gPiArc3RhdGljIERFRklORV9JRFIoc3BpbWRldl9pZHIpOwo+ID4g Kwo+ID4gK3N0YXRpYyBpbnQgdmZpb19zcGltZGV2X2Rldl9leGlzdChzdHJ1Y3QgZGV2aWNlICpk ZXYsIHZvaWQgKmRhdGEpCj4gPiArewo+ID4gKwlyZXR1cm4gIXN0cmNtcChkZXZfbmFtZShkZXYp LCBkZXZfbmFtZSgoc3RydWN0IGRldmljZSAqKWRhdGEpKTsKPiA+ICt9Cj4gPiArCj4gPiArI2lm ZGVmIENPTkZJR19JT01NVV9TVkEKPiA+ICtzdGF0aWMgYm9vbCB2ZmlvX3NwaW1kZXZfaXNfdmFs aWRfcGFzaWQoaW50IHBhc2lkKQo+ID4gK3sKPiA+ICsJc3RydWN0IG1tX3N0cnVjdCAqbW07Cj4g PiArCj4gPiArCW1tID0gaW9tbXVfc3ZhX2ZpbmQocGFzaWQpOwo+ID4gKwlpZiAobW0pIHsKPiA+ ICsJCW1tcHV0KG1tKTsKPiA+ICsJCXJldHVybiBtbSA9PSBjdXJyZW50LT5tbTsKPiA+ICsJfQo+ ID4gKwo+ID4gKwlyZXR1cm4gZmFsc2U7Cj4gPiArfQo+ID4gKyNlbmRpZgo+ID4gKwo+ID4gKy8q IENoZWNrIGlmIHRoZSBkZXZpY2UgaXMgYSBtZWRpYXRlZCBkZXZpY2UgYmVsb25ncyB0byB2Zmlv X3NwaW1kZXYgKi8KPiA+ICtpbnQgdmZpb19zcGltZGV2X2lzX3NwaW1kZXYoc3RydWN0IGRldmlj ZSAqZGV2KQo+ID4gK3sKPiA+ICsJc3RydWN0IG1kZXZfZGV2aWNlICptZGV2Owo+ID4gKwlzdHJ1 Y3QgZGV2aWNlICpwZGV2Owo+ID4gKwo+ID4gKwltZGV2ID0gbWRldl9mcm9tX2RldihkZXYpOwo+ ID4gKwlpZiAoIW1kZXYpCj4gPiArCQlyZXR1cm4gMDsKPiA+ICsKPiA+ICsJcGRldiA9IG1kZXZf cGFyZW50X2RldihtZGV2KTsKPiA+ICsJaWYgKCFwZGV2KQo+ID4gKwkJcmV0dXJuIDA7Cj4gPiAr Cj4gPiArCXJldHVybiBjbGFzc19mb3JfZWFjaF9kZXZpY2Uoc3BpbWRldl9jbGFzcywgTlVMTCwg cGRldiwKPiA+ICsJCQl2ZmlvX3NwaW1kZXZfZGV2X2V4aXN0KTsKPiA+ICt9Cj4gPiArRVhQT1JU X1NZTUJPTF9HUEwodmZpb19zcGltZGV2X2lzX3NwaW1kZXYpOwo+ID4gKwo+ID4gK3N0cnVjdCB2 ZmlvX3NwaW1kZXYgKnZmaW9fc3BpbWRldl9wZGV2X3NwaW1kZXYoc3RydWN0IGRldmljZSAqZGV2 KQo+ID4gK3sKPiA+ICsJc3RydWN0IGRldmljZSAqY2xhc3NfZGV2Owo+ID4gKwo+ID4gKwlpZiAo IWRldikKPiA+ICsJCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOwo+ID4gKwo+ID4gKwljbGFzc19k ZXYgPSBjbGFzc19maW5kX2RldmljZShzcGltZGV2X2NsYXNzLCBOVUxMLCBkZXYsCj4gPiArCQko aW50KCopKHN0cnVjdCBkZXZpY2UgKiwgY29uc3Qgdm9pZAo+ID4gKikpdmZpb19zcGltZGV2X2Rl dl9leGlzdCk7Cj4gPiArCWlmICghY2xhc3NfZGV2KQo+ID4gKwkJcmV0dXJuIEVSUl9QVFIoLUVO T0RFVik7Cj4gPiArCj4gPiArCXJldHVybiBjb250YWluZXJfb2YoY2xhc3NfZGV2LCBzdHJ1Y3Qg dmZpb19zcGltZGV2LCBjbHNfZGV2KTsKPiA+ICt9Cj4gPiArRVhQT1JUX1NZTUJPTF9HUEwodmZp b19zcGltZGV2X3BkZXZfc3BpbWRldik7Cj4gPiArCj4gPiArc3RydWN0IHZmaW9fc3BpbWRldiAq bWRldl9zcGltZGV2KHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiA+ICt7Cj4gPiArCXN0cnVj dCBkZXZpY2UgKnBkZXYgPSBtZGV2X3BhcmVudF9kZXYobWRldik7Cj4gPiArCj4gPiArCXJldHVy biB2ZmlvX3NwaW1kZXZfcGRldl9zcGltZGV2KHBkZXYpOwo+ID4gK30KPiA+ICtFWFBPUlRfU1lN Qk9MX0dQTChtZGV2X3NwaW1kZXYpOwo+ID4gKwo+ID4gK3N0YXRpYyBzc2l6ZV90IGlvbW11X3R5 cGVfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gPiArCQkJICAgICAgIHN0cnVjdCBkZXZpY2Vf YXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCj4gPiArewo+ID4gKwlzdHJ1Y3QgdmZpb19zcGlt ZGV2ICpzcGltZGV2ID0gdmZpb19zcGltZGV2X3BkZXZfc3BpbWRldihkZXYpOwo+ID4gKwo+ID4g KwlpZiAoIXNwaW1kZXYpCj4gPiArCQlyZXR1cm4gLUVOT0RFVjsKPiA+ICsKPiA+ICsJcmV0dXJu IHNwcmludGYoYnVmLCAiJWRcbiIsIHNwaW1kZXYtPmlvbW11X3R5cGUpOwo+ID4gK30KPiA+ICsK PiA+ICtzdGF0aWMgREVWSUNFX0FUVFJfUk8oaW9tbXVfdHlwZSk7Cj4gPiArCj4gPiArc3RhdGlj IHNzaXplX3QgZG1hX2ZsYWdfc2hvdyhzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gPiArCQkJICAgICBz dHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQo+ID4gK3sKPiA+ICsJc3Ry dWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldiA9IHZmaW9fc3BpbWRldl9wZGV2X3NwaW1kZXYoZGV2 KTsKPiA+ICsKPiA+ICsJaWYgKCFzcGltZGV2KQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gPiAr Cj4gPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCBzcGltZGV2LT5kbWFfZmxhZyk7Cj4g PiArfQo+ID4gKwo+ID4gK3N0YXRpYyBERVZJQ0VfQVRUUl9STyhkbWFfZmxhZyk7Cj4gPiArCj4g PiArLyogbWRldi0+ZGV2X2F0dHJfZ3JvdXBzICovCj4gPiArc3RhdGljIHN0cnVjdCBhdHRyaWJ1 dGUgKnZmaW9fc3BpbWRldl9hdHRyc1tdID0gewo+ID4gKwkmZGV2X2F0dHJfaW9tbXVfdHlwZS5h dHRyLAo+ID4gKwkmZGV2X2F0dHJfZG1hX2ZsYWcuYXR0ciwKPiA+ICsJTlVMTCwKPiA+ICt9Owo+ ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIHZmaW9fc3BpbWRldl9ncm91 cCA9IHsKPiA+ICsJLm5hbWUgID0gVkZJT19TUElNREVWX1BERVZfQVRUUlNfR1JQX05BTUUsCj4g PiArCS5hdHRycyA9IHZmaW9fc3BpbWRldl9hdHRycywKPiA+ICt9Owo+ID4gK2NvbnN0IHN0cnVj dCBhdHRyaWJ1dGVfZ3JvdXAgKnZmaW9fc3BpbWRldl9ncm91cHNbXSA9IHsKPiA+ICsJJnZmaW9f c3BpbWRldl9ncm91cCwKPiA+ICsJTlVMTCwKPiA+ICt9Owo+ID4gKwo+ID4gKy8qIGRlZmF1bHQg YXR0cmlidXRlcyBmb3IgbWRldi0+c3VwcG9ydGVkX3R5cGVfZ3JvdXBzLCB1c2VkIGJ5Cj4gPiBy ZWdpc3RlcmVyKi8KPiA+ICsjZGVmaW5lIE1ERVZfVFlQRV9BVFRSX1JPX0VYUE9SVChuYW1lKSBc Cj4gPiArCQlNREVWX1RZUEVfQVRUUl9STyhuYW1lKTsgXAo+ID4gKwkJRVhQT1JUX1NZTUJPTF9H UEwobWRldl90eXBlX2F0dHJfIyNuYW1lKTsKPiA+ICsKPiA+ICsjZGVmaW5lIERFRl9TSU1QTEVf U1BJTURFVl9BVFRSKF9uYW1lLCBzcGltZGV2X21lbWJlciwgZm9ybWF0KQo+ID4gXAo+ID4gK3N0 YXRpYyBzc2l6ZV90IF9uYW1lIyNfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGRl dmljZSAqZGV2LCBcCj4gPiArCQkJICAgIGNoYXIgKmJ1ZikgXAo+ID4gK3sgXAo+ID4gKwlzdHJ1 Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2ID0gdmZpb19zcGltZGV2X3BkZXZfc3BpbWRldihkZXYp Owo+ID4gXAo+ID4gKwlpZiAoIXNwaW1kZXYpIFwKPiA+ICsJCXJldHVybiAtRU5PREVWOyBcCj4g PiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgZm9ybWF0LCBzcGltZGV2LT5zcGltZGV2X21lbWJlcik7 IFwKPiA+ICt9IFwKPiA+ICtNREVWX1RZUEVfQVRUUl9ST19FWFBPUlQoX25hbWUpCj4gPiArCj4g PiArREVGX1NJTVBMRV9TUElNREVWX0FUVFIoZmxhZ3MsIGZsYWdzLCAiJWQiKTsKPiA+ICtERUZf U0lNUExFX1NQSU1ERVZfQVRUUihuYW1lLCBuYW1lLCAiJXMiKTsgLyogdGhpcyBzaG91bGQgYmUK PiA+IGFsZ29yaXRobSBuYW1lLCAqLwo+ID4gKwkJLyogYnV0IHlvdSB3b3VsZCBub3QgY2FyZSBp ZiB5b3UgaGF2ZSBvbmx5IG9uZSBhbGdvcml0aG0gKi8KPiA+ICtERUZfU0lNUExFX1NQSU1ERVZf QVRUUihkZXZpY2VfYXBpLCBhcGlfdmVyLCAiJXMiKTsKPiA+ICsKPiA+ICsvKiB0aGlzIHJldHVy biB0b3RhbCBxdWV1ZSBsZWZ0LCBub3QgbWRldiBsZWZ0ICovCj4gPiArc3RhdGljIHNzaXplX3QK PiA+ICthdmFpbGFibGVfaW5zdGFuY2VzX3Nob3coc3RydWN0IGtvYmplY3QgKmtvYmosIHN0cnVj dCBkZXZpY2UgKmRldiwgY2hhcgo+ID4gKmJ1ZikKPiA+ICt7Cj4gPiArCXN0cnVjdCB2ZmlvX3Nw aW1kZXYgKnNwaW1kZXYgPSB2ZmlvX3NwaW1kZXZfcGRldl9zcGltZGV2KGRldik7Cj4gPiArCj4g PiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkIiwKPiA+ICsJCQlzcGltZGV2LT5vcHMtPmdldF9h dmFpbGFibGVfaW5zdGFuY2VzKHNwaW1kZXYpKTsKPiA+ICt9Cj4gPiArTURFVl9UWVBFX0FUVFJf Uk9fRVhQT1JUKGF2YWlsYWJsZV9pbnN0YW5jZXMpOwo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgdmZp b19zcGltZGV2X21kZXZfY3JlYXRlKHN0cnVjdCBrb2JqZWN0ICprb2JqLAo+ID4gKwlzdHJ1Y3Qg bWRldl9kZXZpY2UgKm1kZXYpCj4gPiArewo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBtZGV2 X2RldihtZGV2KTsKPiA+ICsJc3RydWN0IGRldmljZSAqcGRldiA9IG1kZXZfcGFyZW50X2Rldiht ZGV2KTsKPiA+ICsJc3RydWN0IHNwaW1kZXZfbWRldl9zdGF0ZSAqbWRldl9zdGF0ZTsKPiA+ICsJ c3RydWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldiA9IG1kZXZfc3BpbWRldihtZGV2KTsKPiA+ICsK PiA+ICsJaWYgKCFzcGltZGV2LT5vcHMtPmdldF9xdWV1ZSkKPiA+ICsJCXJldHVybiAtRU5PREVW Owo+ID4gKwo+ID4gKwltZGV2X3N0YXRlID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKHN0cnVj dAo+ID4gc3BpbWRldl9tZGV2X3N0YXRlKSwKPiA+ICsJCQkJICBHRlBfS0VSTkVMKTsKPiA+ICsJ aWYgKCFtZGV2X3N0YXRlKQo+ID4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gPiArCW1kZXZfc2V0X2Ry dmRhdGEobWRldiwgbWRldl9zdGF0ZSk7Cj4gPiArCW1kZXZfc3RhdGUtPnNwaW1kZXYgPSBzcGlt ZGV2Owo+ID4gKwlkZXYtPmlvbW11X2Z3c3BlYyA9IHBkZXYtPmlvbW11X2Z3c3BlYzsKPiA+ICsJ Z2V0X2RldmljZShwZGV2KTsKPiA+ICsJX19tb2R1bGVfZ2V0KHNwaW1kZXYtPm93bmVyKTsKPiA+ ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgdmZpb19zcGlt ZGV2X21kZXZfcmVtb3ZlKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiA+ICt7Cj4gPiArCXN0 cnVjdCBkZXZpY2UgKmRldiA9IG1kZXZfZGV2KG1kZXYpOwo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpw ZGV2ID0gbWRldl9wYXJlbnRfZGV2KG1kZXYpOwo+ID4gKwlzdHJ1Y3QgdmZpb19zcGltZGV2ICpz cGltZGV2ID0gbWRldl9zcGltZGV2KG1kZXYpOwo+ID4gKwo+ID4gKwlwdXRfZGV2aWNlKHBkZXYp Owo+ID4gKwltb2R1bGVfcHV0KHNwaW1kZXYtPm93bmVyKTsKPiA+ICsJZGV2LT5pb21tdV9md3Nw ZWMgPSBOVUxMOwo+ID4gKwltZGV2X3NldF9kcnZkYXRhKG1kZXYsIE5VTEwpOwo+ID4gKwo+ID4g KwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArLyogV2FrZSB1cCB0aGUgcHJvY2VzcyB3aG8g aXMgd2FpdGluZyB0aGlzIHF1ZXVlICovCj4gPiArdm9pZCB2ZmlvX3NwaW1kZXZfd2FrZV91cChz dHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVlICpxKQo+ID4gK3sKPiA+ICsJd2FrZV91cCgmcS0+d2Fp dCk7Cj4gPiArfQo+ID4gK0VYUE9SVF9TWU1CT0xfR1BMKHZmaW9fc3BpbWRldl93YWtlX3VwKTsK PiA+ICsKPiA+ICtzdGF0aWMgaW50IHZmaW9fc3BpbWRldl9xX2ZpbGVfb3BlbihzdHJ1Y3QgaW5v ZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKPiA+ICt7Cj4gPiArCXJldHVybiAwOwo+ID4g K30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IHZmaW9fc3BpbWRldl9xX2ZpbGVfcmVsZWFzZShzdHJ1 Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKPiA+ICt7Cj4gPiArCXN0cnVjdCB2 ZmlvX3NwaW1kZXZfcXVldWUgKnEgPQo+ID4gKwkJKHN0cnVjdCB2ZmlvX3NwaW1kZXZfcXVldWUg KilmaWxlLT5wcml2YXRlX2RhdGE7Cj4gPiArCXN0cnVjdCB2ZmlvX3NwaW1kZXYgKnNwaW1kZXYg PSBxLT5zcGltZGV2Owo+ID4gKwlpbnQgcmV0Owo+ID4gKwo+ID4gKwlyZXQgPSBzcGltZGV2LT5v cHMtPnB1dF9xdWV1ZShxKTsKPiA+ICsJaWYgKHJldCkgewo+ID4gKwkJZGV2X2VycihzcGltZGV2 LT5kZXYsICJkcnYgcHV0IHF1ZXVlIGZhaWwgKCVkKSFcbiIsIHJldCk7Cj4gPiArCQlyZXR1cm4g cmV0Owo+ID4gKwl9Cj4gPiArCj4gPiArCXB1dF9kZXZpY2UobWRldl9kZXYocS0+bWRldikpOwo+ ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGxvbmcgdmZpb19z cGltZGV2X3FfZmlsZV9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwK PiA+ICsJdW5zaWduZWQgbG9uZyBhcmcpCj4gPiArewo+ID4gKwlzdHJ1Y3QgdmZpb19zcGltZGV2 X3F1ZXVlICpxID0KPiA+ICsJCShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVlICopZmlsZS0+cHJp dmF0ZV9kYXRhOwo+ID4gKwlzdHJ1Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2ID0gcS0+c3BpbWRl djsKPiA+ICsKPiA+ICsJaWYgKHNwaW1kZXYtPm9wcy0+aW9jdGwpCj4gPiArCQlyZXR1cm4gc3Bp bWRldi0+b3BzLT5pb2N0bChxLCBjbWQsIGFyZyk7Cj4gPiArCj4gPiArCWRldl9lcnIoc3BpbWRl di0+ZGV2LCAiaW9jdGwgY21kICglZCkgaXMgbm90IHN1cHBvcnRlZCFcbiIsIGNtZCk7Cj4gPiAr Cj4gPiArCXJldHVybiAtRUlOVkFMOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IHZmaW9f c3BpbWRldl9xX2ZpbGVfbW1hcChzdHJ1Y3QgZmlsZSAqZmlsZSwKPiA+ICsJCXN0cnVjdCB2bV9h cmVhX3N0cnVjdCAqdm1hKQo+ID4gK3sKPiA+ICsJc3RydWN0IHZmaW9fc3BpbWRldl9xdWV1ZSAq cSA9Cj4gPiArCQkoc3RydWN0IHZmaW9fc3BpbWRldl9xdWV1ZSAqKWZpbGUtPnByaXZhdGVfZGF0 YTsKPiA+ICsJc3RydWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldiA9IHEtPnNwaW1kZXY7Cj4gPiAr Cj4gPiArCWlmIChzcGltZGV2LT5vcHMtPm1tYXApCj4gPiArCQlyZXR1cm4gc3BpbWRldi0+b3Bz LT5tbWFwKHEsIHZtYSk7Cj4gPiArCj4gPiArCWRldl9lcnIoc3BpbWRldi0+ZGV2LCAibm8gZHJp dmVyIG1tYXAhXG4iKTsKPiA+ICsJcmV0dXJuIC1FSU5WQUw7Cj4gPiArfQo+ID4gKwo+ID4gK3N0 YXRpYyBfX3BvbGxfdCB2ZmlvX3NwaW1kZXZfcV9maWxlX3BvbGwoc3RydWN0IGZpbGUgKmZpbGUs IHBvbGxfdGFibGUgKndhaXQpCj4gPiArewo+ID4gKwlzdHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVl ICpxID0KPiA+ICsJCShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVlICopZmlsZS0+cHJpdmF0ZV9k YXRhOwo+ID4gKwlzdHJ1Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2ID0gcS0+c3BpbWRldjsKPiA+ ICsKPiA+ICsJcG9sbF93YWl0KGZpbGUsICZxLT53YWl0LCB3YWl0KTsKPiA+ICsJaWYgKHNwaW1k ZXYtPm9wcy0+aXNfcV91cGRhdGVkKHEpKQo+ID4gKwkJcmV0dXJuIEVQT0xMSU4gfCBFUE9MTFJE Tk9STTsKPiA+ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHNwaW1kZXZfcV9maWxlX29wcyA9IHsKPiA+ICsJLm93 bmVyID0gVEhJU19NT0RVTEUsCj4gPiArCS5vcGVuID0gdmZpb19zcGltZGV2X3FfZmlsZV9vcGVu LAo+ID4gKwkudW5sb2NrZWRfaW9jdGwgPSB2ZmlvX3NwaW1kZXZfcV9maWxlX2lvY3RsLAo+ID4g KwkucmVsZWFzZSA9IHZmaW9fc3BpbWRldl9xX2ZpbGVfcmVsZWFzZSwKPiA+ICsJLnBvbGwgPSB2 ZmlvX3NwaW1kZXZfcV9maWxlX3BvbGwsCj4gPiArCS5tbWFwID0gdmZpb19zcGltZGV2X3FfZmls ZV9tbWFwLAo+ID4gK307Cj4gPiArCj4gPiArc3RhdGljIGxvbmcgdmZpb19zcGltZGV2X21kZXZf Z2V0X3F1ZXVlKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwKPiA+ICsJCXN0cnVjdCB2ZmlvX3Nw aW1kZXYgKnNwaW1kZXYsIHVuc2lnbmVkIGxvbmcgYXJnKQo+ID4gK3sKPiA+ICsJc3RydWN0IHZm aW9fc3BpbWRldl9xdWV1ZSAqcTsKPiA+ICsJaW50IHJldDsKPiA+ICsKPiA+ICsjaWZkZWYgQ09O RklHX0lPTU1VX1NWQQo+ID4gKwlpbnQgcGFzaWQgPSBhcmc7Cj4gPiArCj4gPiArCWlmICghdmZp b19zcGltZGV2X2lzX3ZhbGlkX3Bhc2lkKHBhc2lkKSkKPiA+ICsJCXJldHVybiAtRUlOVkFMOwo+ ID4gKyNlbmRpZgo+ID4gKwo+ID4gKwlpZiAoIXNwaW1kZXYtPm9wcy0+Z2V0X3F1ZXVlKQo+ID4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4gPiArCj4gPiArCXJldCA9IHNwaW1kZXYtPm9wcy0+Z2V0X3F1 ZXVlKHNwaW1kZXYsIGFyZywgJnEpOwo+ID4gKwlpZiAocmV0IDwgMCkgewo+ID4gKwkJZGV2X2Vy cihzcGltZGV2LT5kZXYsICJnZXRfcXVldWUgZmFpbGVkXG4iKTsKPiA+ICsJCXJldHVybiAtRU5P REVWOwo+ID4gKwl9Cj4gPiArCj4gPiArCXJldCA9IGFub25faW5vZGVfZ2V0ZmQoInNwaW1kZXZf cSIsICZzcGltZGV2X3FfZmlsZV9vcHMsCj4gPiArCQkJcSwgT19DTE9FWEVDIHwgT19SRFdSKTsK PiA+ICsJaWYgKHJldCA8IDApIHsKPiA+ICsJCWRldl9lcnIoc3BpbWRldi0+ZGV2LCAiZ2V0ZmQg ZmFpbCAlZFxuIiwgcmV0KTsKPiA+ICsJCWdvdG8gZXJyX3dpdGhfcXVldWU7Cj4gPiArCX0KPiA+ ICsKPiA+ICsJcS0+ZmQgPSByZXQ7Cj4gPiArCXEtPnNwaW1kZXYgPSBzcGltZGV2Owo+ID4gKwlx LT5tZGV2ID0gbWRldjsKPiA+ICsJcS0+Y29udGFpbmVyID0gYXJnOwo+ID4gKwlpbml0X3dhaXRx dWV1ZV9oZWFkKCZxLT53YWl0KTsKPiA+ICsJZ2V0X2RldmljZShtZGV2X2RldihtZGV2KSk7Cj4g PiArCj4gPiArCXJldHVybiByZXQ7Cj4gPiArCj4gPiArZXJyX3dpdGhfcXVldWU6Cj4gPiArCXNw aW1kZXYtPm9wcy0+cHV0X3F1ZXVlKHEpOwo+ID4gKwlyZXR1cm4gcmV0Owo+ID4gK30KPiA+ICsK PiA+ICtzdGF0aWMgbG9uZyB2ZmlvX3NwaW1kZXZfbWRldl9pb2N0bChzdHJ1Y3QgbWRldl9kZXZp Y2UgKm1kZXYsIHVuc2lnbmVkCj4gPiBpbnQgY21kLAo+ID4gKwkJCSAgICAgICB1bnNpZ25lZCBs b25nIGFyZykKPiA+ICt7Cj4gPiArCXN0cnVjdCBzcGltZGV2X21kZXZfc3RhdGUgKm1kZXZfc3Rh dGU7Cj4gPiArCXN0cnVjdCB2ZmlvX3NwaW1kZXYgKnNwaW1kZXY7Cj4gPiArCj4gPiArCWlmICgh bWRldikKPiA+ICsJCXJldHVybiAtRU5PREVWOwo+ID4gKwo+ID4gKwltZGV2X3N0YXRlID0gbWRl dl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiA+ICsJaWYgKCFtZGV2X3N0YXRlKQo+ID4gKwkJcmV0dXJu IC1FTk9ERVY7Cj4gPiArCj4gPiArCXNwaW1kZXYgPSBtZGV2X3N0YXRlLT5zcGltZGV2Owo+ID4g KwlpZiAoIXNwaW1kZXYpCj4gPiArCQlyZXR1cm4gLUVOT0RFVjsKPiA+ICsKPiA+ICsJaWYgKGNt ZCA9PSBWRklPX1NQSU1ERVZfQ01EX0dFVF9RKQo+ID4gKwkJcmV0dXJuIHZmaW9fc3BpbWRldl9t ZGV2X2dldF9xdWV1ZShtZGV2LCBzcGltZGV2LCBhcmcpOwo+ID4gKwo+ID4gKwlkZXZfZXJyKHNw aW1kZXYtPmRldiwKPiA+ICsJCSIlcywgaW9jdGwgY21kICgweCV4KSBpcyBub3Qgc3VwcG9ydGVk IVxuIiwgX19mdW5jX18sIGNtZCk7Cj4gPiArCXJldHVybiAtRUlOVkFMOwo+ID4gK30KPiA+ICsK PiA+ICtzdGF0aWMgdm9pZCB2ZmlvX3NwaW1kZXZfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYp IHsgfQo+ID4gK3N0YXRpYyB2b2lkIHZmaW9fc3BpbWRldl9tZGV2X3JlbGVhc2Uoc3RydWN0IG1k ZXZfZGV2aWNlICptZGV2KSB7IH0KPiA+ICtzdGF0aWMgaW50IHZmaW9fc3BpbWRldl9tZGV2X29w ZW4oc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KSB7IHJldHVybgo+ID4gMDsgfQo+ID4gKwo+ID4g Ky8qKgo+ID4gKyAqCXZmaW9fc3BpbWRldl9yZWdpc3RlciAtIHJlZ2lzdGVyIGEgc3BpbWRldgo+ ID4gKyAqCUBzcGltZGV2OiBkZXZpY2Ugc3RydWN0dXJlCj4gPiArICovCj4gPiAraW50IHZmaW9f c3BpbWRldl9yZWdpc3RlcihzdHJ1Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2KQo+ID4gK3sKPiA+ ICsJaW50IHJldDsKPiA+ICsJY29uc3QgY2hhciAqZHJ2X25hbWU7Cj4gPiArCj4gPiArCWlmICgh c3BpbWRldi0+ZGV2KQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gPiArCj4gPiArCWRydl9uYW1l ID0gZGV2X2RyaXZlcl9zdHJpbmcoc3BpbWRldi0+ZGV2KTsKPiA+ICsJaWYgKHN0cnN0cihkcnZf bmFtZSwgIi0iKSkgewo+ID4gKwkJcHJfZXJyKCJzcGltZGV2OiBwYXJlbnQgZHJpdmVyIG5hbWUg Y2Fubm90IGluY2x1ZGUgJy0nIVxuIik7Cj4gPiArCQlyZXR1cm4gLUVJTlZBTDsKPiA+ICsJfQo+ ID4gKwo+ID4gKwlzcGltZGV2LT5kZXZfaWQgPSBpZHJfYWxsb2MoJnNwaW1kZXZfaWRyLCBzcGlt ZGV2LCAwLCAwLAo+ID4gR0ZQX0tFUk5FTCk7Cj4gPiArCWlmIChzcGltZGV2LT5kZXZfaWQgPCAw KQo+ID4gKwkJcmV0dXJuIHNwaW1kZXYtPmRldl9pZDsKPiA+ICsKPiA+ICsJYXRvbWljX3NldCgm c3BpbWRldi0+cmVmLCAwKTsKPiA+ICsJc3BpbWRldi0+Y2xzX2Rldi5wYXJlbnQgPSBzcGltZGV2 LT5kZXY7Cj4gPiArCXNwaW1kZXYtPmNsc19kZXYuY2xhc3MgPSBzcGltZGV2X2NsYXNzOwo+ID4g KwlzcGltZGV2LT5jbHNfZGV2LnJlbGVhc2UgPSB2ZmlvX3NwaW1kZXZfcmVsZWFzZTsKPiA+ICsJ ZGV2X3NldF9uYW1lKCZzcGltZGV2LT5jbHNfZGV2LCAiJXMiLCBkZXZfbmFtZShzcGltZGV2LQo+ ID4gPmRldikpOwo+ID4gKwlyZXQgPSBkZXZpY2VfcmVnaXN0ZXIoJnNwaW1kZXYtPmNsc19kZXYp Owo+ID4gKwlpZiAocmV0KQo+ID4gKwkJcmV0dXJuIHJldDsKPiA+ICsKPiA+ICsJc3BpbWRldi0+ bWRldl9mb3BzLm93bmVyCQk9IHNwaW1kZXYtPm93bmVyOwo+ID4gKwlzcGltZGV2LT5tZGV2X2Zv cHMuZGV2X2F0dHJfZ3JvdXBzCT0KPiA+IHZmaW9fc3BpbWRldl9ncm91cHM7Cj4gPiArCVdBUk5f T04oIXNwaW1kZXYtPm1kZXZfZm9wcy5zdXBwb3J0ZWRfdHlwZV9ncm91cHMpOwo+ID4gKwlzcGlt ZGV2LT5tZGV2X2ZvcHMuY3JlYXRlCQk9Cj4gPiB2ZmlvX3NwaW1kZXZfbWRldl9jcmVhdGU7Cj4g PiArCXNwaW1kZXYtPm1kZXZfZm9wcy5yZW1vdmUJCT0KPiA+IHZmaW9fc3BpbWRldl9tZGV2X3Jl bW92ZTsKPiA+ICsJc3BpbWRldi0+bWRldl9mb3BzLmlvY3RsCQk9IHZmaW9fc3BpbWRldl9tZGV2 X2lvY3RsOwo+ID4gKwlzcGltZGV2LT5tZGV2X2ZvcHMub3BlbgkJCT0KPiA+IHZmaW9fc3BpbWRl dl9tZGV2X29wZW47Cj4gPiArCXNwaW1kZXYtPm1kZXZfZm9wcy5yZWxlYXNlCQk9Cj4gPiB2Zmlv X3NwaW1kZXZfbWRldl9yZWxlYXNlOwo+ID4gKwo+ID4gKwlyZXQgPSBtZGV2X3JlZ2lzdGVyX2Rl dmljZShzcGltZGV2LT5kZXYsICZzcGltZGV2LT5tZGV2X2ZvcHMpOwo+ID4gKwlpZiAocmV0KQo+ ID4gKwkJZGV2aWNlX3VucmVnaXN0ZXIoJnNwaW1kZXYtPmNsc19kZXYpOwo+ID4gKwo+ID4gKwly ZXR1cm4gcmV0Owo+ID4gK30KPiA+ICtFWFBPUlRfU1lNQk9MX0dQTCh2ZmlvX3NwaW1kZXZfcmVn aXN0ZXIpOwo+ID4gKwo+ID4gKy8qKgo+ID4gKyAqIHZmaW9fc3BpbWRldl91bnJlZ2lzdGVyIC0g dW5yZWdpc3RlcnMgYSBzcGltZGV2Cj4gPiArICogQHNwaW1kZXY6IGRldmljZSB0byB1bnJlZ2lz dGVyCj4gPiArICoKPiA+ICsgKiBVbnJlZ2lzdGVyIGEgbWlzY2VsbGFuZW91cyBkZXZpY2UgdGhh dCB3YXQgcHJldmlvdXNseSBzdWNjZXNzdWxseQo+ID4gcmVnaXN0ZXJlZAo+ID4gKyAqIHdpdGgg dmZpb19zcGltZGV2X3JlZ2lzdGVyKCkuCj4gPiArICovCj4gPiArdm9pZCB2ZmlvX3NwaW1kZXZf dW5yZWdpc3RlcihzdHJ1Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2KQo+ID4gK3sKPiA+ICsJbWRl dl91bnJlZ2lzdGVyX2RldmljZShzcGltZGV2LT5kZXYpOwo+ID4gKwlkZXZpY2VfdW5yZWdpc3Rl cigmc3BpbWRldi0+Y2xzX2Rldik7Cj4gPiArfQo+ID4gK0VYUE9SVF9TWU1CT0xfR1BMKHZmaW9f c3BpbWRldl91bnJlZ2lzdGVyKTsKPiA+ICsKPiA+ICtzdGF0aWMgaW50IF9faW5pdCB2ZmlvX3Nw aW1kZXZfaW5pdCh2b2lkKQo+ID4gK3sKPiA+ICsJc3BpbWRldl9jbGFzcyA9IGNsYXNzX2NyZWF0 ZShUSElTX01PRFVMRSwKPiA+IFZGSU9fU1BJTURFVl9DTEFTU19OQU1FKTsKPiA+ICsJcmV0dXJu IFBUUl9FUlJfT1JfWkVSTyhzcGltZGV2X2NsYXNzKTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGlj IF9fZXhpdCB2b2lkIHZmaW9fc3BpbWRldl9leGl0KHZvaWQpCj4gPiArewo+ID4gKwljbGFzc19k ZXN0cm95KHNwaW1kZXZfY2xhc3MpOwo+ID4gKwlpZHJfZGVzdHJveSgmc3BpbWRldl9pZHIpOwo+ ID4gK30KPiA+ICsKPiA+ICttb2R1bGVfaW5pdCh2ZmlvX3NwaW1kZXZfaW5pdCk7Cj4gPiArbW9k dWxlX2V4aXQodmZpb19zcGltZGV2X2V4aXQpOwo+ID4gKwo+ID4gK01PRFVMRV9MSUNFTlNFKCJH UEwiKTsKPiA+ICtNT0RVTEVfQVVUSE9SKCJIaXNpbGljb24gVGVjaC4gQ28uLCBMdGQuIik7Cj4g PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJWRklPIFNoYXJlIFBhcmVudCdzIElPTU1VIE1lZGlhdGVk IERldmljZSIpOwo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdmZpby92ZmlvX2lvbW11X3R5cGUx LmMKPiA+IGIvZHJpdmVycy92ZmlvL3ZmaW9faW9tbXVfdHlwZTEuYwo+ID4gaW5kZXggM2U1YjE3 NzEwYTRmLi4wZWMzOGExN2M5OGMgMTAwNjQ0Cj4gPiAtLS0gYS9kcml2ZXJzL3ZmaW8vdmZpb19p b21tdV90eXBlMS5jCj4gPiArKysgYi9kcml2ZXJzL3ZmaW8vdmZpb19pb21tdV90eXBlMS5jCj4g PiBAQCAtNDEsNiArNDEsNyBAQAo+ID4gICNpbmNsdWRlIDxsaW51eC9ub3RpZmllci5oPgo+ID4g ICNpbmNsdWRlIDxsaW51eC9kbWEtaW9tbXUuaD4KPiA+ICAjaW5jbHVkZSA8bGludXgvaXJxZG9t YWluLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3ZmaW9fc3BpbWRldi5oPgo+ID4gCj4gPiAgI2Rl ZmluZSBEUklWRVJfVkVSU0lPTiAgIjAuMiIKPiA+ICAjZGVmaW5lIERSSVZFUl9BVVRIT1IgICAi QWxleCBXaWxsaWFtc29uCj4gPiA8YWxleC53aWxsaWFtc29uQHJlZGhhdC5jb20+Igo+ID4gQEAg LTg5LDYgKzkwLDggQEAgc3RydWN0IHZmaW9fZG1hIHsKPiA+ICB9Owo+ID4gCj4gPiAgc3RydWN0 IHZmaW9fZ3JvdXAgewo+ID4gKwkvKiBpb21tdV9ncm91cCBvZiBtZGV2J3MgcGFyZW50IGRldmlj ZSAqLwo+ID4gKwlzdHJ1Y3QgaW9tbXVfZ3JvdXAJKnBhcmVudF9ncm91cDsKPiA+ICAJc3RydWN0 IGlvbW11X2dyb3VwCSppb21tdV9ncm91cDsKPiA+ICAJc3RydWN0IGxpc3RfaGVhZAluZXh0Owo+ ID4gIH07Cj4gPiBAQCAtMTMyNyw2ICsxMzMwLDEwOSBAQCBzdGF0aWMgYm9vbCB2ZmlvX2lvbW11 X2hhc19zd19tc2koc3RydWN0Cj4gPiBpb21tdV9ncm91cCAqZ3JvdXAsIHBoeXNfYWRkcl90ICpi YXNlKQo+ID4gIAlyZXR1cm4gcmV0Owo+ID4gIH0KPiA+IAo+ID4gKy8qIHJldHVybiAwIGlmIHRo ZSBkZXZpY2UgaXMgbm90IHNwaW1kZXYuCj4gPiArICogcmV0dXJuIDEgaWYgdGhlIGRldmljZSBp cyBzcGltZGV2LCB0aGUgZGF0YSB3aWxsIGJlIHVwZGF0ZWQgd2l0aCBwYXJlbnQKPiA+ICsgKiAJ ZGV2aWNlJ3MgZ3JvdXAuCj4gPiArICogcmV0dXJuIC1lcnJubyBpZiBvdGhlciBlcnJvci4KPiA+ ICsgKi8KPiA+ICtzdGF0aWMgaW50IHZmaW9fc3BpbWRldl90eXBlKHN0cnVjdCBkZXZpY2UgKmRl diwgdm9pZCAqZGF0YSkKPiA+ICt7Cj4gPiArCXN0cnVjdCBpb21tdV9ncm91cCAqKmdyb3VwID0g ZGF0YTsKPiA+ICsJc3RydWN0IGlvbW11X2dyb3VwICpwZ3JvdXA7Cj4gPiArCWludCAoKnNwaW1k ZXZfbWRldikoc3RydWN0IGRldmljZSAqZGV2KTsKPiA+ICsJc3RydWN0IGRldmljZSAqcGRldjsK PiA+ICsJaW50IHJldCA9IDE7Cj4gPiArCj4gPiArCS8qIHZmaW9fc3BpbWRldiBtb2R1bGUgaXMg bm90IGNvbmZpZ3VyYXRlZCAqLwo+ID4gKwlzcGltZGV2X21kZXYgPSBzeW1ib2xfZ2V0KHZmaW9f c3BpbWRldl9pc19zcGltZGV2KTsKPiA+ICsJaWYgKCFzcGltZGV2X21kZXYpCj4gPiArCQlyZXR1 cm4gMDsKPiA+ICsKPiA+ICsJLyogY2hlY2sgaWYgaXQgYmVsb25ncyB0byB2ZmlvX3NwaW1kZXYg ZGV2aWNlICovCj4gPiArCWlmICghc3BpbWRldl9tZGV2KGRldikpIHsKPiA+ICsJCXJldCA9IDA7 Cj4gPiArCQlnb3RvIGdldF9leGl0Owo+ID4gKwl9Cj4gPiArCj4gPiArCXBkZXYgPSBkZXYtPnBh cmVudDsKPiA+ICsJcGdyb3VwID0gaW9tbXVfZ3JvdXBfZ2V0KHBkZXYpOwo+ID4gKwlpZiAoIXBn cm91cCkgewo+ID4gKwkJcmV0ID0gLUVOT0RFVjsKPiA+ICsJCWdvdG8gZ2V0X2V4aXQ7Cj4gPiAr CX0KPiA+ICsKPiA+ICsJaWYgKGdyb3VwKSB7Cj4gPiArCQkvKiBjaGVjayBpZiBhbGwgcGFyZW50 IGRldmljZXMgaXMgdGhlIHNhbWUgKi8KPiA+ICsJCWlmICgqZ3JvdXAgJiYgKmdyb3VwICE9IHBn cm91cCkKPiA+ICsJCQlyZXQgPSAtRU5PREVWOwo+ID4gKwkJZWxzZQo+ID4gKwkJCSpncm91cCA9 IHBncm91cDsKPiA+ICsJfQo+ID4gKwo+ID4gKwlpb21tdV9ncm91cF9wdXQocGdyb3VwKTsKPiA+ ICsKPiA+ICtnZXRfZXhpdDoKPiA+ICsJc3ltYm9sX3B1dCh2ZmlvX3NwaW1kZXZfaXNfc3BpbWRl dik7Cj4gPiArCj4gPiArCXJldHVybiByZXQ7Cj4gPiArfQo+ID4gKwo+ID4gKy8qIHJldHVybiAw IG9yIC1lcnJubyAqLwo+ID4gK3N0YXRpYyBpbnQgdmZpb19zcGltZGV2X2J1cyhzdHJ1Y3QgZGV2 aWNlICpkZXYsIHZvaWQgKmRhdGEpCj4gPiArewo+ID4gKwlzdHJ1Y3QgYnVzX3R5cGUgKipidXMg PSBkYXRhOwo+ID4gKwo+ID4gKwlpZiAoIWRldi0+YnVzKQo+ID4gKwkJcmV0dXJuIC1FTk9ERVY7 Cj4gPiArCj4gPiArCS8qIGVuc3VyZSBhbGwgZGV2aWNlcyBoYXMgdGhlIHNhbWUgYnVzX3R5cGUg Ki8KPiA+ICsJaWYgKCpidXMgJiYgKmJ1cyAhPSBkZXYtPmJ1cykKPiA+ICsJCXJldHVybiAtRUlO VkFMOwo+ID4gKwo+ID4gKwkqYnVzID0gZGV2LT5idXM7Cj4gPiArCXJldHVybiAwOwo+ID4gK30K PiA+ICsKPiA+ICsvKiByZXR1cm4gMCBtZWFucyBpdCBpcyBub3Qgc3BpIGdyb3VwLCAxIG1lYW5z IGl0IGlzLCBvciAtRVhYWCBmb3IgZXJyb3IgKi8KPiA+ICtzdGF0aWMgaW50IHZmaW9faW9tbXVf dHlwZTFfYXR0YWNoX3NwaWdyb3VwKHN0cnVjdCB2ZmlvX2RvbWFpbiAqZG9tYWluLAo+ID4gKwkJ CQkJICAgIHN0cnVjdCB2ZmlvX2dyb3VwICpncm91cCwKPiA+ICsJCQkJCSAgICBzdHJ1Y3QgaW9t bXVfZ3JvdXAKPiA+ICppb21tdV9ncm91cCkKPiA+ICt7Cj4gPiArCWludCByZXQ7Cj4gPiArCXN0 cnVjdCBidXNfdHlwZSAqcGJ1cyA9IE5VTEw7Cj4gPiArCXN0cnVjdCBpb21tdV9ncm91cCAqcGdy b3VwID0gTlVMTDsKPiA+ICsKPiA+ICsJcmV0ID0gaW9tbXVfZ3JvdXBfZm9yX2VhY2hfZGV2KGlv bW11X2dyb3VwLCAmcGdyb3VwLAo+ID4gKwkJCQkgICAgICAgdmZpb19zcGltZGV2X3R5cGUpOwo+ ID4gKwlpZiAocmV0IDwgMCkKPiA+ICsJCWdvdG8gb3V0Owo+ID4gKwllbHNlIGlmIChyZXQgPiAw KSB7Cj4gPiArCQlkb21haW4tPmRvbWFpbiA9IGlvbW11X2dyb3VwX3NoYXJlX2RvbWFpbihwZ3Jv dXApOwo+ID4gKwkJaWYgKElTX0VSUihkb21haW4tPmRvbWFpbikpCj4gPiArCQkJZ290byBvdXQ7 Cj4gPiArCQlyZXQgPSBpb21tdV9ncm91cF9mb3JfZWFjaF9kZXYocGdyb3VwLCAmcGJ1cywKPiA+ ICsJCQkJICAgICAgIHZmaW9fc3BpbWRldl9idXMpOwo+ID4gKwkJaWYgKHJldCA8IDApCj4gPiAr CQkJZ290byBlcnJfd2l0aF9zaGFyZV9kb21haW47Cj4gPiArCj4gPiArCQlpZiAocGJ1cyAmJiBp b21tdV9jYXBhYmxlKHBidXMsCj4gPiBJT01NVV9DQVBfQ0FDSEVfQ09IRVJFTkNZKSkKPiA+ICsJ CQlkb21haW4tPnByb3QgfD0gSU9NTVVfQ0FDSEU7Cj4gPiArCj4gPiArCQlncm91cC0+cGFyZW50 X2dyb3VwID0gcGdyb3VwOwo+ID4gKwkJSU5JVF9MSVNUX0hFQUQoJmRvbWFpbi0+Z3JvdXBfbGlz dCk7Cj4gPiArCQlsaXN0X2FkZCgmZ3JvdXAtPm5leHQsICZkb21haW4tPmdyb3VwX2xpc3QpOwo+ ID4gKwo+ID4gKwkJcmV0dXJuIDE7Cj4gPiArCX0KPiA+ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiAr Cj4gPiArZXJyX3dpdGhfc2hhcmVfZG9tYWluOgo+ID4gKwlpb21tdV9ncm91cF91bnNoYXJlX2Rv bWFpbihwZ3JvdXApOwo+ID4gK291dDoKPiA+ICsJcmV0dXJuIHJldDsKPiA+ICt9Cj4gPiArCj4g PiAgc3RhdGljIGludCB2ZmlvX2lvbW11X3R5cGUxX2F0dGFjaF9ncm91cCh2b2lkICppb21tdV9k YXRhLAo+ID4gIAkJCQkJIHN0cnVjdCBpb21tdV9ncm91cAo+ID4gKmlvbW11X2dyb3VwKQo+ID4g IHsKPiA+IEBAIC0xMzM1LDggKzE0NDEsOCBAQCBzdGF0aWMgaW50IHZmaW9faW9tbXVfdHlwZTFf YXR0YWNoX2dyb3VwKHZvaWQKPiA+ICppb21tdV9kYXRhLAo+ID4gIAlzdHJ1Y3QgdmZpb19kb21h aW4gKmRvbWFpbiwgKmQ7Cj4gPiAgCXN0cnVjdCBidXNfdHlwZSAqYnVzID0gTlVMTCwgKm1kZXZf YnVzOwo+ID4gIAlpbnQgcmV0Owo+ID4gLQlib29sIHJlc3ZfbXNpLCBtc2lfcmVtYXA7Cj4gPiAt CXBoeXNfYWRkcl90IHJlc3ZfbXNpX2Jhc2U7Cj4gPiArCWJvb2wgcmVzdl9tc2kgPSBmYWxzZSwg bXNpX3JlbWFwOwo+ID4gKwlwaHlzX2FkZHJfdCByZXN2X21zaV9iYXNlID0gMDsKPiA+IAo+ID4g IAltdXRleF9sb2NrKCZpb21tdS0+bG9jayk7Cj4gPiAKPiA+IEBAIC0xMzczLDYgKzE0NzksMTQg QEAgc3RhdGljIGludCB2ZmlvX2lvbW11X3R5cGUxX2F0dGFjaF9ncm91cCh2b2lkCj4gPiAqaW9t bXVfZGF0YSwKPiA+ICAJaWYgKG1kZXZfYnVzKSB7Cj4gPiAgCQlpZiAoKGJ1cyA9PSBtZGV2X2J1 cykgJiYgIWlvbW11X3ByZXNlbnQoYnVzKSkgewo+ID4gIAkJCXN5bWJvbF9wdXQobWRldl9idXNf dHlwZSk7Cj4gPiArCj4gPiArCQkJcmV0ID0gdmZpb19pb21tdV90eXBlMV9hdHRhY2hfc3BpZ3Jv dXAoZG9tYWluLAo+ID4gZ3JvdXAsCj4gPiArCQkJCQlpb21tdV9ncm91cCk7Cj4gPiArCQkJaWYg KHJldCA8IDApCj4gPiArCQkJCWdvdG8gb3V0X2ZyZWU7Cj4gPiArCQkJZWxzZSBpZiAocmV0ID4g MCkKPiA+ICsJCQkJZ290byByZXBsYXlfY2hlY2s7Cj4gPiArCj4gPiAgCQkJaWYgKCFpb21tdS0+ ZXh0ZXJuYWxfZG9tYWluKSB7Cj4gPiAgCQkJCUlOSVRfTElTVF9IRUFEKCZkb21haW4tPmdyb3Vw X2xpc3QpOwo+ID4gIAkJCQlpb21tdS0+ZXh0ZXJuYWxfZG9tYWluID0gZG9tYWluOwo+ID4gQEAg LTE0NTEsMTIgKzE1NjUsMTMgQEAgc3RhdGljIGludAo+ID4gdmZpb19pb21tdV90eXBlMV9hdHRh Y2hfZ3JvdXAodm9pZCAqaW9tbXVfZGF0YSwKPiA+IAo+ID4gIAl2ZmlvX3Rlc3RfZG9tYWluX2Zn c3AoZG9tYWluKTsKPiA+IAo+ID4gK3JlcGxheV9jaGVjazoKPiA+ICAJLyogcmVwbGF5IG1hcHBp bmdzIG9uIG5ldyBkb21haW5zICovCj4gPiAgCXJldCA9IHZmaW9faW9tbXVfcmVwbGF5KGlvbW11 LCBkb21haW4pOwo+ID4gIAlpZiAocmV0KQo+ID4gIAkJZ290byBvdXRfZGV0YWNoOwo+ID4gCj4g PiAtCWlmIChyZXN2X21zaSkgewo+ID4gKwlpZiAoIWdyb3VwLT5wYXJlbnRfZ3JvdXAgJiYgcmVz dl9tc2kpIHsKPiA+ICAJCXJldCA9IGlvbW11X2dldF9tc2lfY29va2llKGRvbWFpbi0+ZG9tYWlu LAo+ID4gcmVzdl9tc2lfYmFzZSk7Cj4gPiAgCQlpZiAocmV0KQo+ID4gIAkJCWdvdG8gb3V0X2Rl dGFjaDsKPiA+IEBAIC0xNDcxLDcgKzE1ODYsMTAgQEAgc3RhdGljIGludCB2ZmlvX2lvbW11X3R5 cGUxX2F0dGFjaF9ncm91cCh2b2lkCj4gPiAqaW9tbXVfZGF0YSwKPiA+ICBvdXRfZGV0YWNoOgo+ ID4gIAlpb21tdV9kZXRhY2hfZ3JvdXAoZG9tYWluLT5kb21haW4sIGlvbW11X2dyb3VwKTsKPiA+ ICBvdXRfZG9tYWluOgo+ID4gLQlpb21tdV9kb21haW5fZnJlZShkb21haW4tPmRvbWFpbik7Cj4g PiArCWlmIChncm91cC0+cGFyZW50X2dyb3VwKQo+ID4gKwkJaW9tbXVfZ3JvdXBfdW5zaGFyZV9k b21haW4oZ3JvdXAtPnBhcmVudF9ncm91cCk7Cj4gPiArCWVsc2UKPiA+ICsJCWlvbW11X2RvbWFp bl9mcmVlKGRvbWFpbi0+ZG9tYWluKTsKPiA+ICBvdXRfZnJlZToKPiA+ICAJa2ZyZWUoZG9tYWlu KTsKPiA+ICAJa2ZyZWUoZ3JvdXApOwo+ID4gQEAgLTE1MzMsNiArMTY1MSw3IEBAIHN0YXRpYyB2 b2lkCj4gPiB2ZmlvX2lvbW11X3R5cGUxX2RldGFjaF9ncm91cCh2b2lkICppb21tdV9kYXRhLAo+ ID4gIAlzdHJ1Y3QgdmZpb19pb21tdSAqaW9tbXUgPSBpb21tdV9kYXRhOwo+ID4gIAlzdHJ1Y3Qg dmZpb19kb21haW4gKmRvbWFpbjsKPiA+ICAJc3RydWN0IHZmaW9fZ3JvdXAgKmdyb3VwOwo+ID4g KwlpbnQgcmV0Owo+ID4gCj4gPiAgCW11dGV4X2xvY2soJmlvbW11LT5sb2NrKTsKPiA+IAo+ID4g QEAgLTE1NjAsNyArMTY3OSwxMSBAQCBzdGF0aWMgdm9pZAo+ID4gdmZpb19pb21tdV90eXBlMV9k ZXRhY2hfZ3JvdXAodm9pZCAqaW9tbXVfZGF0YSwKPiA+ICAJCWlmICghZ3JvdXApCj4gPiAgCQkJ Y29udGludWU7Cj4gPiAKPiA+IC0JCWlvbW11X2RldGFjaF9ncm91cChkb21haW4tPmRvbWFpbiwg aW9tbXVfZ3JvdXApOwo+ID4gKwkJaWYgKGdyb3VwLT5wYXJlbnRfZ3JvdXApCj4gPiArCQkJaW9t bXVfZ3JvdXBfdW5zaGFyZV9kb21haW4oZ3JvdXAtCj4gPiA+cGFyZW50X2dyb3VwKTsKPiA+ICsJ CWVsc2UKPiA+ICsJCQlpb21tdV9kZXRhY2hfZ3JvdXAoZG9tYWluLT5kb21haW4sCj4gPiBpb21t dV9ncm91cCk7Cj4gPiArCj4gPiAgCQlsaXN0X2RlbCgmZ3JvdXAtPm5leHQpOwo+ID4gIAkJa2Zy ZWUoZ3JvdXApOwo+ID4gIAkJLyoKPiA+IEBAIC0xNTc3LDcgKzE3MDAsOCBAQCBzdGF0aWMgdm9p ZAo+ID4gdmZpb19pb21tdV90eXBlMV9kZXRhY2hfZ3JvdXAodm9pZCAqaW9tbXVfZGF0YSwKPiA+ ICAJCQkJZWxzZQo+ID4gCj4gPiAJdmZpb19pb21tdV91bm1hcF91bnBpbl9yZWFjY291bnQoaW9t bXUpOwo+ID4gIAkJCX0KPiA+IC0JCQlpb21tdV9kb21haW5fZnJlZShkb21haW4tPmRvbWFpbik7 Cj4gPiArCQkJaWYgKCFyZXQpCj4gPiArCQkJCWlvbW11X2RvbWFpbl9mcmVlKGRvbWFpbi0+ZG9t YWluKTsKPiA+ICAJCQlsaXN0X2RlbCgmZG9tYWluLT5uZXh0KTsKPiA+ICAJCQlrZnJlZShkb21h aW4pOwo+ID4gIAkJfQo+ID4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvdmZpb19zcGltZGV2 LmggYi9pbmNsdWRlL2xpbnV4L3ZmaW9fc3BpbWRldi5oCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0 NAo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi5mN2U3ZDkwMDEzZTEKPiA+IC0tLSAvZGV2L251bGwK PiA+ICsrKyBiL2luY2x1ZGUvbGludXgvdmZpb19zcGltZGV2LmgKPiA+IEBAIC0wLDAgKzEsOTUg QEAKPiA+ICsvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsgKi8KPiA+ICsjaWZu ZGVmIF9fVkZJT19TUElNREVWX0gKPiA+ICsjZGVmaW5lIF9fVkZJT19TUElNREVWX0gKPiA+ICsK PiA+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L2lvbW11 Lmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L21kZXYuaD4KPiA+ICsjaW5jbHVkZSA8bGludXgvdmZp by5oPgo+ID4gKyNpbmNsdWRlIDx1YXBpL2xpbnV4L3ZmaW9fc3BpbWRldi5oPgo+ID4gKwo+ID4g K3N0cnVjdCB2ZmlvX3NwaW1kZXZfcXVldWU7Cj4gPiArc3RydWN0IHZmaW9fc3BpbWRldjsKPiA+ ICsKPiA+ICsvKioKPiA+ICsgKiBzdHJ1Y3QgdmZpb19zcGltZGV2X29wcyAtIFdEIGRldmljZSBv cGVyYXRpb25zCj4gPiArICogQGdldF9xdWV1ZTogZ2V0IGEgcXVldWUgZnJvbSB0aGUgZGV2aWNl IGFjY29yZGluZyB0byBhbGdvcml0aG0KPiA+ICsgKiBAcHV0X3F1ZXVlOiBmcmVlIGEgcXVldWUg dG8gdGhlIGRldmljZQo+ID4gKyAqIEBpc19xX3VwZGF0ZWQ6IGNoZWNrIHdoZXRoZXIgdGhlIHRh c2sgaXMgZmluaXNoZWQKPiA+ICsgKiBAbWFza19ub3RpZnk6IG1hc2sgdGhlIHRhc2sgaXJxIG9m IHF1ZXVlCj4gPiArICogQG1tYXA6IG1tYXAgYWRkcmVzc2VzIG9mIHF1ZXVlIHRvIHVzZXIgc3Bh Y2UKPiA+ICsgKiBAcmVzZXQ6IHJlc2V0IHRoZSBXRCBkZXZpY2UKPiA+ICsgKiBAcmVzZXRfcXVl dWU6IHJlc2V0IHRoZSBxdWV1ZQo+ID4gKyAqIEBpb2N0bDogICBpb2N0bCBmb3IgdXNlciBzcGFj ZSB1c2VycyBvZiB0aGUgcXVldWUKPiA+ICsgKiBAZ2V0X2F2YWlsYWJsZV9pbnN0YW5jZXM6IGdl dCBudW1iZXJzIG9mIHRoZSBxdWV1ZSByZW1haW5lZAo+ID4gKyAqLwo+ID4gK3N0cnVjdCB2Zmlv X3NwaW1kZXZfb3BzIHsKPiA+ICsJaW50ICgqZ2V0X3F1ZXVlKShzdHJ1Y3QgdmZpb19zcGltZGV2 ICpzcGltZGV2LCB1bnNpZ25lZCBsb25nIGFyZywKPiA+ICsJCXN0cnVjdCB2ZmlvX3NwaW1kZXZf cXVldWUgKipxKTsKPiA+ICsJaW50ICgqcHV0X3F1ZXVlKShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1 ZXVlICpxKTsKPiA+ICsJaW50ICgqaXNfcV91cGRhdGVkKShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1 ZXVlICpxKTsKPiA+ICsJdm9pZCAoKm1hc2tfbm90aWZ5KShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1 ZXVlICpxLCBpbnQKPiA+IGV2ZW50X21hc2spOwo+ID4gKwlpbnQgKCptbWFwKShzdHJ1Y3QgdmZp b19zcGltZGV2X3F1ZXVlICpxLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QKPiA+ICp2bWEpOwo+ID4g KwlpbnQgKCpyZXNldCkoc3RydWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldik7Cj4gPiArCWludCAo KnJlc2V0X3F1ZXVlKShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVlICpxKTsKPiA+ICsJbG9uZyAo KmlvY3RsKShzdHJ1Y3QgdmZpb19zcGltZGV2X3F1ZXVlICpxLCB1bnNpZ25lZCBpbnQgY21kLAo+ ID4gKwkJCXVuc2lnbmVkIGxvbmcgYXJnKTsKPiA+ICsJaW50ICgqZ2V0X2F2YWlsYWJsZV9pbnN0 YW5jZXMpKHN0cnVjdCB2ZmlvX3NwaW1kZXYgKnNwaW1kZXYpOwo+ID4gK307Cj4gPiArCj4gPiAr c3RydWN0IHZmaW9fc3BpbWRldl9xdWV1ZSB7Cj4gPiArCXN0cnVjdCBtdXRleCBtdXRleDsKPiA+ ICsJc3RydWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldjsKPiA+ICsJaW50IHFpZDsKPiA+ICsJX191 MzIgZmxhZ3M7Cj4gPiArCXZvaWQgKnByaXY7Cj4gPiArCXdhaXRfcXVldWVfaGVhZF90IHdhaXQ7 Cj4gPiArCXN0cnVjdCBtZGV2X2RldmljZSAqbWRldjsKPiA+ICsJaW50IGZkOwo+ID4gKwlpbnQg Y29udGFpbmVyOwo+ID4gKyNpZmRlZiBDT05GSUdfSU9NTVVfU1ZBCj4gPiArCWludCBwYXNpZDsK PiA+ICsjZW5kaWYKPiA+ICt9Owo+ID4gKwo+ID4gK3N0cnVjdCB2ZmlvX3NwaW1kZXYgewo+ID4g Kwljb25zdCBjaGFyICpuYW1lOwo+ID4gKwlpbnQgc3RhdHVzOwo+ID4gKwlhdG9taWNfdCByZWY7 Cj4gPiArCXN0cnVjdCBtb2R1bGUgKm93bmVyOwo+ID4gKwljb25zdCBzdHJ1Y3QgdmZpb19zcGlt ZGV2X29wcyAqb3BzOwo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gPiArCXN0cnVjdCBkZXZp Y2UgY2xzX2RldjsKPiA+ICsJYm9vbCBpc192ZjsKPiA+ICsJdTMyIGlvbW11X3R5cGU7Cj4gPiAr CXUzMiBkbWFfZmxhZzsKPiA+ICsJdTMyIGRldl9pZDsKPiA+ICsJdm9pZCAqcHJpdjsKPiA+ICsJ aW50IGZsYWdzOwo+ID4gKwljb25zdCBjaGFyICphcGlfdmVyOwo+ID4gKwlzdHJ1Y3QgbWRldl9w YXJlbnRfb3BzIG1kZXZfZm9wczsKPiA+ICt9Owo+ID4gKwo+ID4gK2ludCB2ZmlvX3NwaW1kZXZf cmVnaXN0ZXIoc3RydWN0IHZmaW9fc3BpbWRldiAqc3BpbWRldik7Cj4gPiArdm9pZCB2ZmlvX3Nw aW1kZXZfdW5yZWdpc3RlcihzdHJ1Y3QgdmZpb19zcGltZGV2ICpzcGltZGV2KTsKPiA+ICt2b2lk IHZmaW9fc3BpbWRldl93YWtlX3VwKHN0cnVjdCB2ZmlvX3NwaW1kZXZfcXVldWUgKnEpOwo+ID4g K2ludCB2ZmlvX3NwaW1kZXZfaXNfc3BpbWRldihzdHJ1Y3QgZGV2aWNlICpkZXYpOwo+ID4gK3N0 cnVjdCB2ZmlvX3NwaW1kZXYgKnZmaW9fc3BpbWRldl9wZGV2X3NwaW1kZXYoc3RydWN0IGRldmlj ZSAqZGV2KTsKPiA+ICtpbnQgdmZpb19zcGltZGV2X3Bhc2lkX3ByaV9jaGVjayhpbnQgcGFzaWQp Owo+ID4gK2ludCB2ZmlvX3NwaW1kZXZfZ2V0KHN0cnVjdCBkZXZpY2UgKmRldik7Cj4gPiAraW50 IHZmaW9fc3BpbWRldl9wdXQoc3RydWN0IGRldmljZSAqZGV2KTsKPiA+ICtzdHJ1Y3QgdmZpb19z cGltZGV2ICptZGV2X3NwaW1kZXYoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KTsKPiA+ICsKPiA+ ICtleHRlcm4gc3RydWN0IG1kZXZfdHlwZV9hdHRyaWJ1dGUgbWRldl90eXBlX2F0dHJfZmxhZ3M7 Cj4gPiArZXh0ZXJuIHN0cnVjdCBtZGV2X3R5cGVfYXR0cmlidXRlIG1kZXZfdHlwZV9hdHRyX25h bWU7Cj4gPiArZXh0ZXJuIHN0cnVjdCBtZGV2X3R5cGVfYXR0cmlidXRlIG1kZXZfdHlwZV9hdHRy X2RldmljZV9hcGk7Cj4gPiArZXh0ZXJuIHN0cnVjdCBtZGV2X3R5cGVfYXR0cmlidXRlIG1kZXZf dHlwZV9hdHRyX2F2YWlsYWJsZV9pbnN0YW5jZXM7Cj4gPiArI2RlZmluZSBWRklPX1NQSU1ERVZf REVGQVVMVF9NREVWX1RZUEVfQVRUUlMgXAo+ID4gKwkmbWRldl90eXBlX2F0dHJfbmFtZS5hdHRy LCBcCj4gPiArCSZtZGV2X3R5cGVfYXR0cl9kZXZpY2VfYXBpLmF0dHIsIFwKPiA+ICsJJm1kZXZf dHlwZV9hdHRyX2F2YWlsYWJsZV9pbnN0YW5jZXMuYXR0ciwgXAo+ID4gKwkmbWRldl90eXBlX2F0 dHJfZmxhZ3MuYXR0cgo+ID4gKwo+ID4gKyNkZWZpbmUgX1ZGSU9fU1BJTURFVl9SRUdJT04odm1f cGdvZmYpCSh2bV9wZ29mZiAmIDB4ZikKPiA+ICsKPiA+ICsjZW5kaWYKPiA+IGRpZmYgLS1naXQg YS9pbmNsdWRlL3VhcGkvbGludXgvdmZpb19zcGltZGV2LmgKPiA+IGIvaW5jbHVkZS91YXBpL2xp bnV4L3ZmaW9fc3BpbWRldi5oCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ID4gaW5kZXggMDAw MDAwMDAwMDAwLi4zNDM1ZTVjMzQ1YjQKPiA+IC0tLSAvZGV2L251bGwKPiA+ICsrKyBiL2luY2x1 ZGUvdWFwaS9saW51eC92ZmlvX3NwaW1kZXYuaAo+ID4gQEAgLTAsMCArMSwyOCBAQAo+ID4gKy8q IFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKyAqLwo+ID4gKyNpZm5kZWYgX1VBUElW RklPX1NQSU1ERVZfSAo+ID4gKyNkZWZpbmUgX1VBUElWRklPX1NQSU1ERVZfSAo+ID4gKwo+ID4g KyNpbmNsdWRlIDxsaW51eC9pb2N0bC5oPgo+ID4gKwo+ID4gKyNkZWZpbmUgVkZJT19TUElNREVW X0NMQVNTX05BTUUJCSJzcGltZGV2Igo+ID4gKwo+ID4gKy8qIERldmljZSBBVFRScyBpbiBwYXJl bnQgZGV2IFNZU0ZTIERJUiAqLwo+ID4gKyNkZWZpbmUgVkZJT19TUElNREVWX1BERVZfQVRUUlNf R1JQX05BTUUJInBhcmFtcyIKPiA+ICsKPiA+ICsvKiBQYXJlbnQgZGV2aWNlIGF0dHJpYnV0ZXMg Ki8KPiA+ICsjZGVmaW5lIFNQSU1ERVZfSU9NTVVfVFlQRQkiaW9tbXVfdHlwZSIKPiA+ICsjZGVm aW5lIFNQSU1ERVZfRE1BX0ZMQUcJImRtYV9mbGFnIgo+ID4gKwo+ID4gKy8qIE1heGltdW0gbGVu Z3RoIG9mIGFsZ29yaXRobSBuYW1lIHN0cmluZyAqLwo+ID4gKyNkZWZpbmUgVkZJT19TUElNREVW X0FMR19OQU1FX1NJWkUJCTY0Cj4gPiArCj4gPiArLyogdGhlIGJpdHMgdXNlZCBpbiBTUElNREVW X0RNQV9GTEFHIGF0dHJpYnV0ZXMgKi8KPiA+ICsjZGVmaW5lIFZGSU9fU1BJTURFVl9ETUFfSU5W QUxJRAkJMAo+ID4gKyNkZWZpbmUJVkZJT19TUElNREVWX0RNQV9TSU5HTEVfUFJPQ19NQVAJMQo+ ID4gKyNkZWZpbmUJVkZJT19TUElNREVWX0RNQV9NVUxUSV9QUk9DX01BUAkJMgo+ID4gKyNkZWZp bmUJVkZJT19TUElNREVWX0RNQV9TVk0JCQk0Cj4gPiArI2RlZmluZQlWRklPX1NQSU1ERVZfRE1B X1NWTV9OT19GQVVMVAkJOAo+ID4gKyNkZWZpbmUJVkZJT19TUElNREVWX0RNQV9QSFkJCQkxNgo+ ID4gKwo+ID4gKyNkZWZpbmUgVkZJT19TUElNREVWX0NNRF9HRVRfUQlfSU8oJ1cnLCAxKQo+ID4g KyNlbmRpZgo+ID4gLS0KPiA+IDIuMTcuMQoKLS0gCgkJCS1LZW5uZXRoKEhpc2lsaWNvbikKCj09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09CuacrOmCruS7tuWPiuWFtumZhOS7tuWQq+acieWNjuS4uuWF rOWPuOeahOS/neWvhuS/oeaBr++8jOS7hemZkOS6juWPkemAgee7meS4iumdouWcsOWdgOS4reWI l+WHuueahOS4quS6uuaIlue+pOe7hOOAguemgQrmraLku7vkvZXlhbbku5bkurrku6Xku7vkvZXl vaLlvI/kvb/nlKjvvIjljIXmi6zkvYbkuI3pmZDkuo7lhajpg6jmiJbpg6jliIblnLDms4TpnLLj gIHlpI3liLbjgIHmiJbmlaPlj5HvvInmnKzpgq7ku7bkuK0K55qE5L+h5oGv44CC5aaC5p6c5oKo 6ZSZ5pS25LqG5pys6YKu5Lu277yM6K+35oKo56uL5Y2z55S16K+d5oiW6YKu5Lu26YCa55+l5Y+R 5Lu25Lq65bm25Yig6Zmk5pys6YKu5Lu277yBClRoaXMgZS1tYWlsIGFuZCBpdHMgYXR0YWNobWVu dHMgY29udGFpbiBjb25maWRlbnRpYWwgaW5mb3JtYXRpb24gZnJvbSBIVUFXRUksCndoaWNoIGlz IGludGVuZGVkIG9ubHkgZm9yIHRoZSBwZXJzb24gb3IgZW50aXR5IHdob3NlIGFkZHJlc3MgaXMg bGlzdGVkIGFib3ZlLgpBbnkgdXNlIG9mIHRoZSAKaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVp biBpbiBhbnkgd2F5IChpbmNsdWRpbmcsIGJ1dCBub3QgbGltaXRlZCB0bywgdG90YWwgb3IKcGFy dGlhbCBkaXNjbG9zdXJlLCByZXByb2R1Y3Rpb24sIG9yIGRpc3NlbWluYXRpb24pIGJ5IHBlcnNv bnMgb3RoZXIgdGhhbiB0aGUKaW50ZW5kZWQgCnJlY2lwaWVudChzKSBpcyBwcm9oaWJpdGVkLiBJ ZiB5b3UgcmVjZWl2ZSB0aGlzIGUtbWFpbCBpbiBlcnJvciwgcGxlYXNlIG5vdGlmeQp0aGUgc2Vu ZGVyIGJ5IHBob25lIG9yIGVtYWlsIGltbWVkaWF0ZWx5IGFuZCBkZWxldGUgaXQhCgpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwppb21tdSBtYWlsaW5nIGxp c3QKaW9tbXVAbGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0cy5saW51eGZv dW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vaW9tbXU= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on archive.lwn.net X-Spam-Level: X-Spam-Status: No, score=-6.0 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable autolearn_force=no version=3.4.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by archive.lwn.net (Postfix) with ESMTP id 2B7F97E3B2 for ; Thu, 2 Aug 2018 03:49:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726192AbeHBFiB (ORCPT ); Thu, 2 Aug 2018 01:38:01 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:10214 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726042AbeHBFiB (ORCPT ); Thu, 2 Aug 2018 01:38:01 -0400 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 0B0FC81117F8F; Thu, 2 Aug 2018 11:48:51 +0800 (CST) Received: from localhost (10.67.212.75) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server (TLS) id 14.3.399.0; Thu, 2 Aug 2018 11:48:46 +0800 Date: Thu, 2 Aug 2018 11:47:27 +0800 From: Kenneth Lee To: "Tian, Kevin" CC: Kenneth Lee , Jonathan Corbet , Herbert Xu , "David S . Miller" , Joerg Roedel , Alex Williamson , Hao Fang , Zhou Wang , Zaibo Xu , Philippe Ombredanne , Greg Kroah-Hartman , Thomas Gleixner , "linux-doc@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "linux-crypto@vger.kernel.org" , "iommu@lists.linux-foundation.org" , "kvm@vger.kernel.org" , "linux-accelerators@lists.ozlabs.org" , Lu Baolu , "Kumar, Sanjay K" , "linuxarm@huawei.com" Subject: Re: [RFC PATCH 3/7] vfio: add spimdev support Message-ID: <20180802034727.GK160746@Turing-Arch-b> References: <20180801102221.5308-1-nek.in.cn@gmail.com> <20180801102221.5308-4-nek.in.cn@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: linux-doc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-doc@vger.kernel.org On Thu, Aug 02, 2018 at 03:21:25AM +0000, Tian, Kevin wrote: > Date: Thu, 2 Aug 2018 03:21:25 +0000 > From: "Tian, Kevin" > To: Kenneth Lee , Jonathan Corbet , > Herbert Xu , "David S . Miller" > , Joerg Roedel , Alex Williamson > , Kenneth Lee , Hao > Fang , Zhou Wang , Zaibo Xu > , Philippe Ombredanne , Greg > Kroah-Hartman , Thomas Gleixner > , "linux-doc@vger.kernel.org" > , "linux-kernel@vger.kernel.org" > , "linux-crypto@vger.kernel.org" > , "iommu@lists.linux-foundation.org" > , "kvm@vger.kernel.org" > , "linux-accelerators@lists.ozlabs.org" > , Lu Baolu > , "Kumar, Sanjay K" > CC: "linuxarm@huawei.com" > Subject: RE: [RFC PATCH 3/7] vfio: add spimdev support > Message-ID: > > > From: Kenneth Lee > > Sent: Wednesday, August 1, 2018 6:22 PM > > > > From: Kenneth Lee > > > > SPIMDEV is "Share Parent IOMMU Mdev". It is a vfio-mdev. But differ from > > the general vfio-mdev: > > > > 1. It shares its parent's IOMMU. > > 2. There is no hardware resource attached to the mdev is created. The > > hardware resource (A `queue') is allocated only when the mdev is > > opened. > > Alex has concern on doing so, as pointed out in: > > https://www.spinics.net/lists/kvm/msg172652.html > > resource allocation should be reserved at creation time. Yes. That is why I keep telling that SPIMDEV is not for "VM", it is for "many processes", it is just an access point to the process. Not a device to VM. I hope Alex can accept it:) > > > > > Currently only the vfio type-1 driver is updated to make it to be aware > > of. > > > > Signed-off-by: Kenneth Lee > > Signed-off-by: Zaibo Xu > > Signed-off-by: Zhou Wang > > --- > > drivers/vfio/Kconfig | 1 + > > drivers/vfio/Makefile | 1 + > > drivers/vfio/spimdev/Kconfig | 10 + > > drivers/vfio/spimdev/Makefile | 3 + > > drivers/vfio/spimdev/vfio_spimdev.c | 421 > > ++++++++++++++++++++++++++++ > > drivers/vfio/vfio_iommu_type1.c | 136 ++++++++- > > include/linux/vfio_spimdev.h | 95 +++++++ > > include/uapi/linux/vfio_spimdev.h | 28 ++ > > 8 files changed, 689 insertions(+), 6 deletions(-) > > create mode 100644 drivers/vfio/spimdev/Kconfig > > create mode 100644 drivers/vfio/spimdev/Makefile > > create mode 100644 drivers/vfio/spimdev/vfio_spimdev.c > > create mode 100644 include/linux/vfio_spimdev.h > > create mode 100644 include/uapi/linux/vfio_spimdev.h > > > > diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig > > index c84333eb5eb5..3719eba72ef1 100644 > > --- a/drivers/vfio/Kconfig > > +++ b/drivers/vfio/Kconfig > > @@ -47,4 +47,5 @@ menuconfig VFIO_NOIOMMU > > source "drivers/vfio/pci/Kconfig" > > source "drivers/vfio/platform/Kconfig" > > source "drivers/vfio/mdev/Kconfig" > > +source "drivers/vfio/spimdev/Kconfig" > > source "virt/lib/Kconfig" > > diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile > > index de67c4725cce..28f3ef0cdce1 100644 > > --- a/drivers/vfio/Makefile > > +++ b/drivers/vfio/Makefile > > @@ -9,3 +9,4 @@ obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o > > obj-$(CONFIG_VFIO_PCI) += pci/ > > obj-$(CONFIG_VFIO_PLATFORM) += platform/ > > obj-$(CONFIG_VFIO_MDEV) += mdev/ > > +obj-$(CONFIG_VFIO_SPIMDEV) += spimdev/ > > diff --git a/drivers/vfio/spimdev/Kconfig b/drivers/vfio/spimdev/Kconfig > > new file mode 100644 > > index 000000000000..1226301f9d0e > > --- /dev/null > > +++ b/drivers/vfio/spimdev/Kconfig > > @@ -0,0 +1,10 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +config VFIO_SPIMDEV > > + tristate "Support for Share Parent IOMMU MDEV" > > + depends on VFIO_MDEV_DEVICE > > + help > > + Support for VFIO Share Parent IOMMU MDEV, which enable the > > kernel to > > + support for the light weight hardware accelerator framework, > > WrapDrive. > > + > > + To compile this as a module, choose M here: the module will be > > called > > + spimdev. > > diff --git a/drivers/vfio/spimdev/Makefile b/drivers/vfio/spimdev/Makefile > > new file mode 100644 > > index 000000000000..d02fb69c37e4 > > --- /dev/null > > +++ b/drivers/vfio/spimdev/Makefile > > @@ -0,0 +1,3 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +spimdev-y := spimdev.o > > +obj-$(CONFIG_VFIO_SPIMDEV) += vfio_spimdev.o > > diff --git a/drivers/vfio/spimdev/vfio_spimdev.c > > b/drivers/vfio/spimdev/vfio_spimdev.c > > new file mode 100644 > > index 000000000000..1b6910c9d27d > > --- /dev/null > > +++ b/drivers/vfio/spimdev/vfio_spimdev.c > > @@ -0,0 +1,421 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +struct spimdev_mdev_state { > > + struct vfio_spimdev *spimdev; > > +}; > > + > > +static struct class *spimdev_class; > > +static DEFINE_IDR(spimdev_idr); > > + > > +static int vfio_spimdev_dev_exist(struct device *dev, void *data) > > +{ > > + return !strcmp(dev_name(dev), dev_name((struct device *)data)); > > +} > > + > > +#ifdef CONFIG_IOMMU_SVA > > +static bool vfio_spimdev_is_valid_pasid(int pasid) > > +{ > > + struct mm_struct *mm; > > + > > + mm = iommu_sva_find(pasid); > > + if (mm) { > > + mmput(mm); > > + return mm == current->mm; > > + } > > + > > + return false; > > +} > > +#endif > > + > > +/* Check if the device is a mediated device belongs to vfio_spimdev */ > > +int vfio_spimdev_is_spimdev(struct device *dev) > > +{ > > + struct mdev_device *mdev; > > + struct device *pdev; > > + > > + mdev = mdev_from_dev(dev); > > + if (!mdev) > > + return 0; > > + > > + pdev = mdev_parent_dev(mdev); > > + if (!pdev) > > + return 0; > > + > > + return class_for_each_device(spimdev_class, NULL, pdev, > > + vfio_spimdev_dev_exist); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_is_spimdev); > > + > > +struct vfio_spimdev *vfio_spimdev_pdev_spimdev(struct device *dev) > > +{ > > + struct device *class_dev; > > + > > + if (!dev) > > + return ERR_PTR(-EINVAL); > > + > > + class_dev = class_find_device(spimdev_class, NULL, dev, > > + (int(*)(struct device *, const void > > *))vfio_spimdev_dev_exist); > > + if (!class_dev) > > + return ERR_PTR(-ENODEV); > > + > > + return container_of(class_dev, struct vfio_spimdev, cls_dev); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_pdev_spimdev); > > + > > +struct vfio_spimdev *mdev_spimdev(struct mdev_device *mdev) > > +{ > > + struct device *pdev = mdev_parent_dev(mdev); > > + > > + return vfio_spimdev_pdev_spimdev(pdev); > > +} > > +EXPORT_SYMBOL_GPL(mdev_spimdev); > > + > > +static ssize_t iommu_type_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + if (!spimdev) > > + return -ENODEV; > > + > > + return sprintf(buf, "%d\n", spimdev->iommu_type); > > +} > > + > > +static DEVICE_ATTR_RO(iommu_type); > > + > > +static ssize_t dma_flag_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + if (!spimdev) > > + return -ENODEV; > > + > > + return sprintf(buf, "%d\n", spimdev->dma_flag); > > +} > > + > > +static DEVICE_ATTR_RO(dma_flag); > > + > > +/* mdev->dev_attr_groups */ > > +static struct attribute *vfio_spimdev_attrs[] = { > > + &dev_attr_iommu_type.attr, > > + &dev_attr_dma_flag.attr, > > + NULL, > > +}; > > +static const struct attribute_group vfio_spimdev_group = { > > + .name = VFIO_SPIMDEV_PDEV_ATTRS_GRP_NAME, > > + .attrs = vfio_spimdev_attrs, > > +}; > > +const struct attribute_group *vfio_spimdev_groups[] = { > > + &vfio_spimdev_group, > > + NULL, > > +}; > > + > > +/* default attributes for mdev->supported_type_groups, used by > > registerer*/ > > +#define MDEV_TYPE_ATTR_RO_EXPORT(name) \ > > + MDEV_TYPE_ATTR_RO(name); \ > > + EXPORT_SYMBOL_GPL(mdev_type_attr_##name); > > + > > +#define DEF_SIMPLE_SPIMDEV_ATTR(_name, spimdev_member, format) > > \ > > +static ssize_t _name##_show(struct kobject *kobj, struct device *dev, \ > > + char *buf) \ > > +{ \ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > \ > > + if (!spimdev) \ > > + return -ENODEV; \ > > + return sprintf(buf, format, spimdev->spimdev_member); \ > > +} \ > > +MDEV_TYPE_ATTR_RO_EXPORT(_name) > > + > > +DEF_SIMPLE_SPIMDEV_ATTR(flags, flags, "%d"); > > +DEF_SIMPLE_SPIMDEV_ATTR(name, name, "%s"); /* this should be > > algorithm name, */ > > + /* but you would not care if you have only one algorithm */ > > +DEF_SIMPLE_SPIMDEV_ATTR(device_api, api_ver, "%s"); > > + > > +/* this return total queue left, not mdev left */ > > +static ssize_t > > +available_instances_show(struct kobject *kobj, struct device *dev, char > > *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + return sprintf(buf, "%d", > > + spimdev->ops->get_available_instances(spimdev)); > > +} > > +MDEV_TYPE_ATTR_RO_EXPORT(available_instances); > > + > > +static int vfio_spimdev_mdev_create(struct kobject *kobj, > > + struct mdev_device *mdev) > > +{ > > + struct device *dev = mdev_dev(mdev); > > + struct device *pdev = mdev_parent_dev(mdev); > > + struct spimdev_mdev_state *mdev_state; > > + struct vfio_spimdev *spimdev = mdev_spimdev(mdev); > > + > > + if (!spimdev->ops->get_queue) > > + return -ENODEV; > > + > > + mdev_state = devm_kzalloc(dev, sizeof(struct > > spimdev_mdev_state), > > + GFP_KERNEL); > > + if (!mdev_state) > > + return -ENOMEM; > > + mdev_set_drvdata(mdev, mdev_state); > > + mdev_state->spimdev = spimdev; > > + dev->iommu_fwspec = pdev->iommu_fwspec; > > + get_device(pdev); > > + __module_get(spimdev->owner); > > + > > + return 0; > > +} > > + > > +static int vfio_spimdev_mdev_remove(struct mdev_device *mdev) > > +{ > > + struct device *dev = mdev_dev(mdev); > > + struct device *pdev = mdev_parent_dev(mdev); > > + struct vfio_spimdev *spimdev = mdev_spimdev(mdev); > > + > > + put_device(pdev); > > + module_put(spimdev->owner); > > + dev->iommu_fwspec = NULL; > > + mdev_set_drvdata(mdev, NULL); > > + > > + return 0; > > +} > > + > > +/* Wake up the process who is waiting this queue */ > > +void vfio_spimdev_wake_up(struct vfio_spimdev_queue *q) > > +{ > > + wake_up(&q->wait); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_wake_up); > > + > > +static int vfio_spimdev_q_file_open(struct inode *inode, struct file *file) > > +{ > > + return 0; > > +} > > + > > +static int vfio_spimdev_q_file_release(struct inode *inode, struct file *file) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + int ret; > > + > > + ret = spimdev->ops->put_queue(q); > > + if (ret) { > > + dev_err(spimdev->dev, "drv put queue fail (%d)!\n", ret); > > + return ret; > > + } > > + > > + put_device(mdev_dev(q->mdev)); > > + > > + return 0; > > +} > > + > > +static long vfio_spimdev_q_file_ioctl(struct file *file, unsigned int cmd, > > + unsigned long arg) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + if (spimdev->ops->ioctl) > > + return spimdev->ops->ioctl(q, cmd, arg); > > + > > + dev_err(spimdev->dev, "ioctl cmd (%d) is not supported!\n", cmd); > > + > > + return -EINVAL; > > +} > > + > > +static int vfio_spimdev_q_file_mmap(struct file *file, > > + struct vm_area_struct *vma) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + if (spimdev->ops->mmap) > > + return spimdev->ops->mmap(q, vma); > > + > > + dev_err(spimdev->dev, "no driver mmap!\n"); > > + return -EINVAL; > > +} > > + > > +static __poll_t vfio_spimdev_q_file_poll(struct file *file, poll_table *wait) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + poll_wait(file, &q->wait, wait); > > + if (spimdev->ops->is_q_updated(q)) > > + return EPOLLIN | EPOLLRDNORM; > > + > > + return 0; > > +} > > + > > +static const struct file_operations spimdev_q_file_ops = { > > + .owner = THIS_MODULE, > > + .open = vfio_spimdev_q_file_open, > > + .unlocked_ioctl = vfio_spimdev_q_file_ioctl, > > + .release = vfio_spimdev_q_file_release, > > + .poll = vfio_spimdev_q_file_poll, > > + .mmap = vfio_spimdev_q_file_mmap, > > +}; > > + > > +static long vfio_spimdev_mdev_get_queue(struct mdev_device *mdev, > > + struct vfio_spimdev *spimdev, unsigned long arg) > > +{ > > + struct vfio_spimdev_queue *q; > > + int ret; > > + > > +#ifdef CONFIG_IOMMU_SVA > > + int pasid = arg; > > + > > + if (!vfio_spimdev_is_valid_pasid(pasid)) > > + return -EINVAL; > > +#endif > > + > > + if (!spimdev->ops->get_queue) > > + return -EINVAL; > > + > > + ret = spimdev->ops->get_queue(spimdev, arg, &q); > > + if (ret < 0) { > > + dev_err(spimdev->dev, "get_queue failed\n"); > > + return -ENODEV; > > + } > > + > > + ret = anon_inode_getfd("spimdev_q", &spimdev_q_file_ops, > > + q, O_CLOEXEC | O_RDWR); > > + if (ret < 0) { > > + dev_err(spimdev->dev, "getfd fail %d\n", ret); > > + goto err_with_queue; > > + } > > + > > + q->fd = ret; > > + q->spimdev = spimdev; > > + q->mdev = mdev; > > + q->container = arg; > > + init_waitqueue_head(&q->wait); > > + get_device(mdev_dev(mdev)); > > + > > + return ret; > > + > > +err_with_queue: > > + spimdev->ops->put_queue(q); > > + return ret; > > +} > > + > > +static long vfio_spimdev_mdev_ioctl(struct mdev_device *mdev, unsigned > > int cmd, > > + unsigned long arg) > > +{ > > + struct spimdev_mdev_state *mdev_state; > > + struct vfio_spimdev *spimdev; > > + > > + if (!mdev) > > + return -ENODEV; > > + > > + mdev_state = mdev_get_drvdata(mdev); > > + if (!mdev_state) > > + return -ENODEV; > > + > > + spimdev = mdev_state->spimdev; > > + if (!spimdev) > > + return -ENODEV; > > + > > + if (cmd == VFIO_SPIMDEV_CMD_GET_Q) > > + return vfio_spimdev_mdev_get_queue(mdev, spimdev, arg); > > + > > + dev_err(spimdev->dev, > > + "%s, ioctl cmd (0x%x) is not supported!\n", __func__, cmd); > > + return -EINVAL; > > +} > > + > > +static void vfio_spimdev_release(struct device *dev) { } > > +static void vfio_spimdev_mdev_release(struct mdev_device *mdev) { } > > +static int vfio_spimdev_mdev_open(struct mdev_device *mdev) { return > > 0; } > > + > > +/** > > + * vfio_spimdev_register - register a spimdev > > + * @spimdev: device structure > > + */ > > +int vfio_spimdev_register(struct vfio_spimdev *spimdev) > > +{ > > + int ret; > > + const char *drv_name; > > + > > + if (!spimdev->dev) > > + return -ENODEV; > > + > > + drv_name = dev_driver_string(spimdev->dev); > > + if (strstr(drv_name, "-")) { > > + pr_err("spimdev: parent driver name cannot include '-'!\n"); > > + return -EINVAL; > > + } > > + > > + spimdev->dev_id = idr_alloc(&spimdev_idr, spimdev, 0, 0, > > GFP_KERNEL); > > + if (spimdev->dev_id < 0) > > + return spimdev->dev_id; > > + > > + atomic_set(&spimdev->ref, 0); > > + spimdev->cls_dev.parent = spimdev->dev; > > + spimdev->cls_dev.class = spimdev_class; > > + spimdev->cls_dev.release = vfio_spimdev_release; > > + dev_set_name(&spimdev->cls_dev, "%s", dev_name(spimdev- > > >dev)); > > + ret = device_register(&spimdev->cls_dev); > > + if (ret) > > + return ret; > > + > > + spimdev->mdev_fops.owner = spimdev->owner; > > + spimdev->mdev_fops.dev_attr_groups = > > vfio_spimdev_groups; > > + WARN_ON(!spimdev->mdev_fops.supported_type_groups); > > + spimdev->mdev_fops.create = > > vfio_spimdev_mdev_create; > > + spimdev->mdev_fops.remove = > > vfio_spimdev_mdev_remove; > > + spimdev->mdev_fops.ioctl = vfio_spimdev_mdev_ioctl; > > + spimdev->mdev_fops.open = > > vfio_spimdev_mdev_open; > > + spimdev->mdev_fops.release = > > vfio_spimdev_mdev_release; > > + > > + ret = mdev_register_device(spimdev->dev, &spimdev->mdev_fops); > > + if (ret) > > + device_unregister(&spimdev->cls_dev); > > + > > + return ret; > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_register); > > + > > +/** > > + * vfio_spimdev_unregister - unregisters a spimdev > > + * @spimdev: device to unregister > > + * > > + * Unregister a miscellaneous device that wat previously successully > > registered > > + * with vfio_spimdev_register(). > > + */ > > +void vfio_spimdev_unregister(struct vfio_spimdev *spimdev) > > +{ > > + mdev_unregister_device(spimdev->dev); > > + device_unregister(&spimdev->cls_dev); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_unregister); > > + > > +static int __init vfio_spimdev_init(void) > > +{ > > + spimdev_class = class_create(THIS_MODULE, > > VFIO_SPIMDEV_CLASS_NAME); > > + return PTR_ERR_OR_ZERO(spimdev_class); > > +} > > + > > +static __exit void vfio_spimdev_exit(void) > > +{ > > + class_destroy(spimdev_class); > > + idr_destroy(&spimdev_idr); > > +} > > + > > +module_init(vfio_spimdev_init); > > +module_exit(vfio_spimdev_exit); > > + > > +MODULE_LICENSE("GPL"); > > +MODULE_AUTHOR("Hisilicon Tech. Co., Ltd."); > > +MODULE_DESCRIPTION("VFIO Share Parent's IOMMU Mediated Device"); > > diff --git a/drivers/vfio/vfio_iommu_type1.c > > b/drivers/vfio/vfio_iommu_type1.c > > index 3e5b17710a4f..0ec38a17c98c 100644 > > --- a/drivers/vfio/vfio_iommu_type1.c > > +++ b/drivers/vfio/vfio_iommu_type1.c > > @@ -41,6 +41,7 @@ > > #include > > #include > > #include > > +#include > > > > #define DRIVER_VERSION "0.2" > > #define DRIVER_AUTHOR "Alex Williamson > > " > > @@ -89,6 +90,8 @@ struct vfio_dma { > > }; > > > > struct vfio_group { > > + /* iommu_group of mdev's parent device */ > > + struct iommu_group *parent_group; > > struct iommu_group *iommu_group; > > struct list_head next; > > }; > > @@ -1327,6 +1330,109 @@ static bool vfio_iommu_has_sw_msi(struct > > iommu_group *group, phys_addr_t *base) > > return ret; > > } > > > > +/* return 0 if the device is not spimdev. > > + * return 1 if the device is spimdev, the data will be updated with parent > > + * device's group. > > + * return -errno if other error. > > + */ > > +static int vfio_spimdev_type(struct device *dev, void *data) > > +{ > > + struct iommu_group **group = data; > > + struct iommu_group *pgroup; > > + int (*spimdev_mdev)(struct device *dev); > > + struct device *pdev; > > + int ret = 1; > > + > > + /* vfio_spimdev module is not configurated */ > > + spimdev_mdev = symbol_get(vfio_spimdev_is_spimdev); > > + if (!spimdev_mdev) > > + return 0; > > + > > + /* check if it belongs to vfio_spimdev device */ > > + if (!spimdev_mdev(dev)) { > > + ret = 0; > > + goto get_exit; > > + } > > + > > + pdev = dev->parent; > > + pgroup = iommu_group_get(pdev); > > + if (!pgroup) { > > + ret = -ENODEV; > > + goto get_exit; > > + } > > + > > + if (group) { > > + /* check if all parent devices is the same */ > > + if (*group && *group != pgroup) > > + ret = -ENODEV; > > + else > > + *group = pgroup; > > + } > > + > > + iommu_group_put(pgroup); > > + > > +get_exit: > > + symbol_put(vfio_spimdev_is_spimdev); > > + > > + return ret; > > +} > > + > > +/* return 0 or -errno */ > > +static int vfio_spimdev_bus(struct device *dev, void *data) > > +{ > > + struct bus_type **bus = data; > > + > > + if (!dev->bus) > > + return -ENODEV; > > + > > + /* ensure all devices has the same bus_type */ > > + if (*bus && *bus != dev->bus) > > + return -EINVAL; > > + > > + *bus = dev->bus; > > + return 0; > > +} > > + > > +/* return 0 means it is not spi group, 1 means it is, or -EXXX for error */ > > +static int vfio_iommu_type1_attach_spigroup(struct vfio_domain *domain, > > + struct vfio_group *group, > > + struct iommu_group > > *iommu_group) > > +{ > > + int ret; > > + struct bus_type *pbus = NULL; > > + struct iommu_group *pgroup = NULL; > > + > > + ret = iommu_group_for_each_dev(iommu_group, &pgroup, > > + vfio_spimdev_type); > > + if (ret < 0) > > + goto out; > > + else if (ret > 0) { > > + domain->domain = iommu_group_share_domain(pgroup); > > + if (IS_ERR(domain->domain)) > > + goto out; > > + ret = iommu_group_for_each_dev(pgroup, &pbus, > > + vfio_spimdev_bus); > > + if (ret < 0) > > + goto err_with_share_domain; > > + > > + if (pbus && iommu_capable(pbus, > > IOMMU_CAP_CACHE_COHERENCY)) > > + domain->prot |= IOMMU_CACHE; > > + > > + group->parent_group = pgroup; > > + INIT_LIST_HEAD(&domain->group_list); > > + list_add(&group->next, &domain->group_list); > > + > > + return 1; > > + } > > + > > + return 0; > > + > > +err_with_share_domain: > > + iommu_group_unshare_domain(pgroup); > > +out: > > + return ret; > > +} > > + > > static int vfio_iommu_type1_attach_group(void *iommu_data, > > struct iommu_group > > *iommu_group) > > { > > @@ -1335,8 +1441,8 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > struct vfio_domain *domain, *d; > > struct bus_type *bus = NULL, *mdev_bus; > > int ret; > > - bool resv_msi, msi_remap; > > - phys_addr_t resv_msi_base; > > + bool resv_msi = false, msi_remap; > > + phys_addr_t resv_msi_base = 0; > > > > mutex_lock(&iommu->lock); > > > > @@ -1373,6 +1479,14 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > if (mdev_bus) { > > if ((bus == mdev_bus) && !iommu_present(bus)) { > > symbol_put(mdev_bus_type); > > + > > + ret = vfio_iommu_type1_attach_spigroup(domain, > > group, > > + iommu_group); > > + if (ret < 0) > > + goto out_free; > > + else if (ret > 0) > > + goto replay_check; > > + > > if (!iommu->external_domain) { > > INIT_LIST_HEAD(&domain->group_list); > > iommu->external_domain = domain; > > @@ -1451,12 +1565,13 @@ static int > > vfio_iommu_type1_attach_group(void *iommu_data, > > > > vfio_test_domain_fgsp(domain); > > > > +replay_check: > > /* replay mappings on new domains */ > > ret = vfio_iommu_replay(iommu, domain); > > if (ret) > > goto out_detach; > > > > - if (resv_msi) { > > + if (!group->parent_group && resv_msi) { > > ret = iommu_get_msi_cookie(domain->domain, > > resv_msi_base); > > if (ret) > > goto out_detach; > > @@ -1471,7 +1586,10 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > out_detach: > > iommu_detach_group(domain->domain, iommu_group); > > out_domain: > > - iommu_domain_free(domain->domain); > > + if (group->parent_group) > > + iommu_group_unshare_domain(group->parent_group); > > + else > > + iommu_domain_free(domain->domain); > > out_free: > > kfree(domain); > > kfree(group); > > @@ -1533,6 +1651,7 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > struct vfio_iommu *iommu = iommu_data; > > struct vfio_domain *domain; > > struct vfio_group *group; > > + int ret; > > > > mutex_lock(&iommu->lock); > > > > @@ -1560,7 +1679,11 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > if (!group) > > continue; > > > > - iommu_detach_group(domain->domain, iommu_group); > > + if (group->parent_group) > > + iommu_group_unshare_domain(group- > > >parent_group); > > + else > > + iommu_detach_group(domain->domain, > > iommu_group); > > + > > list_del(&group->next); > > kfree(group); > > /* > > @@ -1577,7 +1700,8 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > else > > > > vfio_iommu_unmap_unpin_reaccount(iommu); > > } > > - iommu_domain_free(domain->domain); > > + if (!ret) > > + iommu_domain_free(domain->domain); > > list_del(&domain->next); > > kfree(domain); > > } > > diff --git a/include/linux/vfio_spimdev.h b/include/linux/vfio_spimdev.h > > new file mode 100644 > > index 000000000000..f7e7d90013e1 > > --- /dev/null > > +++ b/include/linux/vfio_spimdev.h > > @@ -0,0 +1,95 @@ > > +/* SPDX-License-Identifier: GPL-2.0+ */ > > +#ifndef __VFIO_SPIMDEV_H > > +#define __VFIO_SPIMDEV_H > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +struct vfio_spimdev_queue; > > +struct vfio_spimdev; > > + > > +/** > > + * struct vfio_spimdev_ops - WD device operations > > + * @get_queue: get a queue from the device according to algorithm > > + * @put_queue: free a queue to the device > > + * @is_q_updated: check whether the task is finished > > + * @mask_notify: mask the task irq of queue > > + * @mmap: mmap addresses of queue to user space > > + * @reset: reset the WD device > > + * @reset_queue: reset the queue > > + * @ioctl: ioctl for user space users of the queue > > + * @get_available_instances: get numbers of the queue remained > > + */ > > +struct vfio_spimdev_ops { > > + int (*get_queue)(struct vfio_spimdev *spimdev, unsigned long arg, > > + struct vfio_spimdev_queue **q); > > + int (*put_queue)(struct vfio_spimdev_queue *q); > > + int (*is_q_updated)(struct vfio_spimdev_queue *q); > > + void (*mask_notify)(struct vfio_spimdev_queue *q, int > > event_mask); > > + int (*mmap)(struct vfio_spimdev_queue *q, struct vm_area_struct > > *vma); > > + int (*reset)(struct vfio_spimdev *spimdev); > > + int (*reset_queue)(struct vfio_spimdev_queue *q); > > + long (*ioctl)(struct vfio_spimdev_queue *q, unsigned int cmd, > > + unsigned long arg); > > + int (*get_available_instances)(struct vfio_spimdev *spimdev); > > +}; > > + > > +struct vfio_spimdev_queue { > > + struct mutex mutex; > > + struct vfio_spimdev *spimdev; > > + int qid; > > + __u32 flags; > > + void *priv; > > + wait_queue_head_t wait; > > + struct mdev_device *mdev; > > + int fd; > > + int container; > > +#ifdef CONFIG_IOMMU_SVA > > + int pasid; > > +#endif > > +}; > > + > > +struct vfio_spimdev { > > + const char *name; > > + int status; > > + atomic_t ref; > > + struct module *owner; > > + const struct vfio_spimdev_ops *ops; > > + struct device *dev; > > + struct device cls_dev; > > + bool is_vf; > > + u32 iommu_type; > > + u32 dma_flag; > > + u32 dev_id; > > + void *priv; > > + int flags; > > + const char *api_ver; > > + struct mdev_parent_ops mdev_fops; > > +}; > > + > > +int vfio_spimdev_register(struct vfio_spimdev *spimdev); > > +void vfio_spimdev_unregister(struct vfio_spimdev *spimdev); > > +void vfio_spimdev_wake_up(struct vfio_spimdev_queue *q); > > +int vfio_spimdev_is_spimdev(struct device *dev); > > +struct vfio_spimdev *vfio_spimdev_pdev_spimdev(struct device *dev); > > +int vfio_spimdev_pasid_pri_check(int pasid); > > +int vfio_spimdev_get(struct device *dev); > > +int vfio_spimdev_put(struct device *dev); > > +struct vfio_spimdev *mdev_spimdev(struct mdev_device *mdev); > > + > > +extern struct mdev_type_attribute mdev_type_attr_flags; > > +extern struct mdev_type_attribute mdev_type_attr_name; > > +extern struct mdev_type_attribute mdev_type_attr_device_api; > > +extern struct mdev_type_attribute mdev_type_attr_available_instances; > > +#define VFIO_SPIMDEV_DEFAULT_MDEV_TYPE_ATTRS \ > > + &mdev_type_attr_name.attr, \ > > + &mdev_type_attr_device_api.attr, \ > > + &mdev_type_attr_available_instances.attr, \ > > + &mdev_type_attr_flags.attr > > + > > +#define _VFIO_SPIMDEV_REGION(vm_pgoff) (vm_pgoff & 0xf) > > + > > +#endif > > diff --git a/include/uapi/linux/vfio_spimdev.h > > b/include/uapi/linux/vfio_spimdev.h > > new file mode 100644 > > index 000000000000..3435e5c345b4 > > --- /dev/null > > +++ b/include/uapi/linux/vfio_spimdev.h > > @@ -0,0 +1,28 @@ > > +/* SPDX-License-Identifier: GPL-2.0+ */ > > +#ifndef _UAPIVFIO_SPIMDEV_H > > +#define _UAPIVFIO_SPIMDEV_H > > + > > +#include > > + > > +#define VFIO_SPIMDEV_CLASS_NAME "spimdev" > > + > > +/* Device ATTRs in parent dev SYSFS DIR */ > > +#define VFIO_SPIMDEV_PDEV_ATTRS_GRP_NAME "params" > > + > > +/* Parent device attributes */ > > +#define SPIMDEV_IOMMU_TYPE "iommu_type" > > +#define SPIMDEV_DMA_FLAG "dma_flag" > > + > > +/* Maximum length of algorithm name string */ > > +#define VFIO_SPIMDEV_ALG_NAME_SIZE 64 > > + > > +/* the bits used in SPIMDEV_DMA_FLAG attributes */ > > +#define VFIO_SPIMDEV_DMA_INVALID 0 > > +#define VFIO_SPIMDEV_DMA_SINGLE_PROC_MAP 1 > > +#define VFIO_SPIMDEV_DMA_MULTI_PROC_MAP 2 > > +#define VFIO_SPIMDEV_DMA_SVM 4 > > +#define VFIO_SPIMDEV_DMA_SVM_NO_FAULT 8 > > +#define VFIO_SPIMDEV_DMA_PHY 16 > > + > > +#define VFIO_SPIMDEV_CMD_GET_Q _IO('W', 1) > > +#endif > > -- > > 2.17.1 -- -Kenneth(Hisilicon) ================================================================================ 本邮件及其附件含有华为公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁 止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中 的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from HUAWEI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it! -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS,URIBL_BLOCKED,USER_AGENT_MUTT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4AB96C43142 for ; Thu, 2 Aug 2018 03:49:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B55602083D for ; Thu, 2 Aug 2018 03:48:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B55602083D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=hisilicon.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726932AbeHBFiB (ORCPT ); Thu, 2 Aug 2018 01:38:01 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:10214 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726042AbeHBFiB (ORCPT ); Thu, 2 Aug 2018 01:38:01 -0400 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 0B0FC81117F8F; Thu, 2 Aug 2018 11:48:51 +0800 (CST) Received: from localhost (10.67.212.75) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server (TLS) id 14.3.399.0; Thu, 2 Aug 2018 11:48:46 +0800 Date: Thu, 2 Aug 2018 11:47:27 +0800 From: Kenneth Lee To: "Tian, Kevin" CC: Kenneth Lee , Jonathan Corbet , Herbert Xu , "David S . Miller" , Joerg Roedel , Alex Williamson , Hao Fang , Zhou Wang , Zaibo Xu , Philippe Ombredanne , Greg Kroah-Hartman , Thomas Gleixner , "linux-doc@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "linux-crypto@vger.kernel.org" , "iommu@lists.linux-foundation.org" , "kvm@vger.kernel.org" , "linux-accelerators@lists.ozlabs.org" , Lu Baolu , "Kumar, Sanjay K" , "linuxarm@huawei.com" Subject: Re: [RFC PATCH 3/7] vfio: add spimdev support Message-ID: <20180802034727.GK160746@Turing-Arch-b> References: <20180801102221.5308-1-nek.in.cn@gmail.com> <20180801102221.5308-4-nek.in.cn@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 02, 2018 at 03:21:25AM +0000, Tian, Kevin wrote: > Date: Thu, 2 Aug 2018 03:21:25 +0000 > From: "Tian, Kevin" > To: Kenneth Lee , Jonathan Corbet , > Herbert Xu , "David S . Miller" > , Joerg Roedel , Alex Williamson > , Kenneth Lee , Hao > Fang , Zhou Wang , Zaibo Xu > , Philippe Ombredanne , Greg > Kroah-Hartman , Thomas Gleixner > , "linux-doc@vger.kernel.org" > , "linux-kernel@vger.kernel.org" > , "linux-crypto@vger.kernel.org" > , "iommu@lists.linux-foundation.org" > , "kvm@vger.kernel.org" > , "linux-accelerators@lists.ozlabs.org" > , Lu Baolu > , "Kumar, Sanjay K" > CC: "linuxarm@huawei.com" > Subject: RE: [RFC PATCH 3/7] vfio: add spimdev support > Message-ID: > > > From: Kenneth Lee > > Sent: Wednesday, August 1, 2018 6:22 PM > > > > From: Kenneth Lee > > > > SPIMDEV is "Share Parent IOMMU Mdev". It is a vfio-mdev. But differ from > > the general vfio-mdev: > > > > 1. It shares its parent's IOMMU. > > 2. There is no hardware resource attached to the mdev is created. The > > hardware resource (A `queue') is allocated only when the mdev is > > opened. > > Alex has concern on doing so, as pointed out in: > > https://www.spinics.net/lists/kvm/msg172652.html > > resource allocation should be reserved at creation time. Yes. That is why I keep telling that SPIMDEV is not for "VM", it is for "many processes", it is just an access point to the process. Not a device to VM. I hope Alex can accept it:) > > > > > Currently only the vfio type-1 driver is updated to make it to be aware > > of. > > > > Signed-off-by: Kenneth Lee > > Signed-off-by: Zaibo Xu > > Signed-off-by: Zhou Wang > > --- > > drivers/vfio/Kconfig | 1 + > > drivers/vfio/Makefile | 1 + > > drivers/vfio/spimdev/Kconfig | 10 + > > drivers/vfio/spimdev/Makefile | 3 + > > drivers/vfio/spimdev/vfio_spimdev.c | 421 > > ++++++++++++++++++++++++++++ > > drivers/vfio/vfio_iommu_type1.c | 136 ++++++++- > > include/linux/vfio_spimdev.h | 95 +++++++ > > include/uapi/linux/vfio_spimdev.h | 28 ++ > > 8 files changed, 689 insertions(+), 6 deletions(-) > > create mode 100644 drivers/vfio/spimdev/Kconfig > > create mode 100644 drivers/vfio/spimdev/Makefile > > create mode 100644 drivers/vfio/spimdev/vfio_spimdev.c > > create mode 100644 include/linux/vfio_spimdev.h > > create mode 100644 include/uapi/linux/vfio_spimdev.h > > > > diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig > > index c84333eb5eb5..3719eba72ef1 100644 > > --- a/drivers/vfio/Kconfig > > +++ b/drivers/vfio/Kconfig > > @@ -47,4 +47,5 @@ menuconfig VFIO_NOIOMMU > > source "drivers/vfio/pci/Kconfig" > > source "drivers/vfio/platform/Kconfig" > > source "drivers/vfio/mdev/Kconfig" > > +source "drivers/vfio/spimdev/Kconfig" > > source "virt/lib/Kconfig" > > diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile > > index de67c4725cce..28f3ef0cdce1 100644 > > --- a/drivers/vfio/Makefile > > +++ b/drivers/vfio/Makefile > > @@ -9,3 +9,4 @@ obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o > > obj-$(CONFIG_VFIO_PCI) += pci/ > > obj-$(CONFIG_VFIO_PLATFORM) += platform/ > > obj-$(CONFIG_VFIO_MDEV) += mdev/ > > +obj-$(CONFIG_VFIO_SPIMDEV) += spimdev/ > > diff --git a/drivers/vfio/spimdev/Kconfig b/drivers/vfio/spimdev/Kconfig > > new file mode 100644 > > index 000000000000..1226301f9d0e > > --- /dev/null > > +++ b/drivers/vfio/spimdev/Kconfig > > @@ -0,0 +1,10 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +config VFIO_SPIMDEV > > + tristate "Support for Share Parent IOMMU MDEV" > > + depends on VFIO_MDEV_DEVICE > > + help > > + Support for VFIO Share Parent IOMMU MDEV, which enable the > > kernel to > > + support for the light weight hardware accelerator framework, > > WrapDrive. > > + > > + To compile this as a module, choose M here: the module will be > > called > > + spimdev. > > diff --git a/drivers/vfio/spimdev/Makefile b/drivers/vfio/spimdev/Makefile > > new file mode 100644 > > index 000000000000..d02fb69c37e4 > > --- /dev/null > > +++ b/drivers/vfio/spimdev/Makefile > > @@ -0,0 +1,3 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +spimdev-y := spimdev.o > > +obj-$(CONFIG_VFIO_SPIMDEV) += vfio_spimdev.o > > diff --git a/drivers/vfio/spimdev/vfio_spimdev.c > > b/drivers/vfio/spimdev/vfio_spimdev.c > > new file mode 100644 > > index 000000000000..1b6910c9d27d > > --- /dev/null > > +++ b/drivers/vfio/spimdev/vfio_spimdev.c > > @@ -0,0 +1,421 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +struct spimdev_mdev_state { > > + struct vfio_spimdev *spimdev; > > +}; > > + > > +static struct class *spimdev_class; > > +static DEFINE_IDR(spimdev_idr); > > + > > +static int vfio_spimdev_dev_exist(struct device *dev, void *data) > > +{ > > + return !strcmp(dev_name(dev), dev_name((struct device *)data)); > > +} > > + > > +#ifdef CONFIG_IOMMU_SVA > > +static bool vfio_spimdev_is_valid_pasid(int pasid) > > +{ > > + struct mm_struct *mm; > > + > > + mm = iommu_sva_find(pasid); > > + if (mm) { > > + mmput(mm); > > + return mm == current->mm; > > + } > > + > > + return false; > > +} > > +#endif > > + > > +/* Check if the device is a mediated device belongs to vfio_spimdev */ > > +int vfio_spimdev_is_spimdev(struct device *dev) > > +{ > > + struct mdev_device *mdev; > > + struct device *pdev; > > + > > + mdev = mdev_from_dev(dev); > > + if (!mdev) > > + return 0; > > + > > + pdev = mdev_parent_dev(mdev); > > + if (!pdev) > > + return 0; > > + > > + return class_for_each_device(spimdev_class, NULL, pdev, > > + vfio_spimdev_dev_exist); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_is_spimdev); > > + > > +struct vfio_spimdev *vfio_spimdev_pdev_spimdev(struct device *dev) > > +{ > > + struct device *class_dev; > > + > > + if (!dev) > > + return ERR_PTR(-EINVAL); > > + > > + class_dev = class_find_device(spimdev_class, NULL, dev, > > + (int(*)(struct device *, const void > > *))vfio_spimdev_dev_exist); > > + if (!class_dev) > > + return ERR_PTR(-ENODEV); > > + > > + return container_of(class_dev, struct vfio_spimdev, cls_dev); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_pdev_spimdev); > > + > > +struct vfio_spimdev *mdev_spimdev(struct mdev_device *mdev) > > +{ > > + struct device *pdev = mdev_parent_dev(mdev); > > + > > + return vfio_spimdev_pdev_spimdev(pdev); > > +} > > +EXPORT_SYMBOL_GPL(mdev_spimdev); > > + > > +static ssize_t iommu_type_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + if (!spimdev) > > + return -ENODEV; > > + > > + return sprintf(buf, "%d\n", spimdev->iommu_type); > > +} > > + > > +static DEVICE_ATTR_RO(iommu_type); > > + > > +static ssize_t dma_flag_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + if (!spimdev) > > + return -ENODEV; > > + > > + return sprintf(buf, "%d\n", spimdev->dma_flag); > > +} > > + > > +static DEVICE_ATTR_RO(dma_flag); > > + > > +/* mdev->dev_attr_groups */ > > +static struct attribute *vfio_spimdev_attrs[] = { > > + &dev_attr_iommu_type.attr, > > + &dev_attr_dma_flag.attr, > > + NULL, > > +}; > > +static const struct attribute_group vfio_spimdev_group = { > > + .name = VFIO_SPIMDEV_PDEV_ATTRS_GRP_NAME, > > + .attrs = vfio_spimdev_attrs, > > +}; > > +const struct attribute_group *vfio_spimdev_groups[] = { > > + &vfio_spimdev_group, > > + NULL, > > +}; > > + > > +/* default attributes for mdev->supported_type_groups, used by > > registerer*/ > > +#define MDEV_TYPE_ATTR_RO_EXPORT(name) \ > > + MDEV_TYPE_ATTR_RO(name); \ > > + EXPORT_SYMBOL_GPL(mdev_type_attr_##name); > > + > > +#define DEF_SIMPLE_SPIMDEV_ATTR(_name, spimdev_member, format) > > \ > > +static ssize_t _name##_show(struct kobject *kobj, struct device *dev, \ > > + char *buf) \ > > +{ \ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > \ > > + if (!spimdev) \ > > + return -ENODEV; \ > > + return sprintf(buf, format, spimdev->spimdev_member); \ > > +} \ > > +MDEV_TYPE_ATTR_RO_EXPORT(_name) > > + > > +DEF_SIMPLE_SPIMDEV_ATTR(flags, flags, "%d"); > > +DEF_SIMPLE_SPIMDEV_ATTR(name, name, "%s"); /* this should be > > algorithm name, */ > > + /* but you would not care if you have only one algorithm */ > > +DEF_SIMPLE_SPIMDEV_ATTR(device_api, api_ver, "%s"); > > + > > +/* this return total queue left, not mdev left */ > > +static ssize_t > > +available_instances_show(struct kobject *kobj, struct device *dev, char > > *buf) > > +{ > > + struct vfio_spimdev *spimdev = vfio_spimdev_pdev_spimdev(dev); > > + > > + return sprintf(buf, "%d", > > + spimdev->ops->get_available_instances(spimdev)); > > +} > > +MDEV_TYPE_ATTR_RO_EXPORT(available_instances); > > + > > +static int vfio_spimdev_mdev_create(struct kobject *kobj, > > + struct mdev_device *mdev) > > +{ > > + struct device *dev = mdev_dev(mdev); > > + struct device *pdev = mdev_parent_dev(mdev); > > + struct spimdev_mdev_state *mdev_state; > > + struct vfio_spimdev *spimdev = mdev_spimdev(mdev); > > + > > + if (!spimdev->ops->get_queue) > > + return -ENODEV; > > + > > + mdev_state = devm_kzalloc(dev, sizeof(struct > > spimdev_mdev_state), > > + GFP_KERNEL); > > + if (!mdev_state) > > + return -ENOMEM; > > + mdev_set_drvdata(mdev, mdev_state); > > + mdev_state->spimdev = spimdev; > > + dev->iommu_fwspec = pdev->iommu_fwspec; > > + get_device(pdev); > > + __module_get(spimdev->owner); > > + > > + return 0; > > +} > > + > > +static int vfio_spimdev_mdev_remove(struct mdev_device *mdev) > > +{ > > + struct device *dev = mdev_dev(mdev); > > + struct device *pdev = mdev_parent_dev(mdev); > > + struct vfio_spimdev *spimdev = mdev_spimdev(mdev); > > + > > + put_device(pdev); > > + module_put(spimdev->owner); > > + dev->iommu_fwspec = NULL; > > + mdev_set_drvdata(mdev, NULL); > > + > > + return 0; > > +} > > + > > +/* Wake up the process who is waiting this queue */ > > +void vfio_spimdev_wake_up(struct vfio_spimdev_queue *q) > > +{ > > + wake_up(&q->wait); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_wake_up); > > + > > +static int vfio_spimdev_q_file_open(struct inode *inode, struct file *file) > > +{ > > + return 0; > > +} > > + > > +static int vfio_spimdev_q_file_release(struct inode *inode, struct file *file) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + int ret; > > + > > + ret = spimdev->ops->put_queue(q); > > + if (ret) { > > + dev_err(spimdev->dev, "drv put queue fail (%d)!\n", ret); > > + return ret; > > + } > > + > > + put_device(mdev_dev(q->mdev)); > > + > > + return 0; > > +} > > + > > +static long vfio_spimdev_q_file_ioctl(struct file *file, unsigned int cmd, > > + unsigned long arg) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + if (spimdev->ops->ioctl) > > + return spimdev->ops->ioctl(q, cmd, arg); > > + > > + dev_err(spimdev->dev, "ioctl cmd (%d) is not supported!\n", cmd); > > + > > + return -EINVAL; > > +} > > + > > +static int vfio_spimdev_q_file_mmap(struct file *file, > > + struct vm_area_struct *vma) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + if (spimdev->ops->mmap) > > + return spimdev->ops->mmap(q, vma); > > + > > + dev_err(spimdev->dev, "no driver mmap!\n"); > > + return -EINVAL; > > +} > > + > > +static __poll_t vfio_spimdev_q_file_poll(struct file *file, poll_table *wait) > > +{ > > + struct vfio_spimdev_queue *q = > > + (struct vfio_spimdev_queue *)file->private_data; > > + struct vfio_spimdev *spimdev = q->spimdev; > > + > > + poll_wait(file, &q->wait, wait); > > + if (spimdev->ops->is_q_updated(q)) > > + return EPOLLIN | EPOLLRDNORM; > > + > > + return 0; > > +} > > + > > +static const struct file_operations spimdev_q_file_ops = { > > + .owner = THIS_MODULE, > > + .open = vfio_spimdev_q_file_open, > > + .unlocked_ioctl = vfio_spimdev_q_file_ioctl, > > + .release = vfio_spimdev_q_file_release, > > + .poll = vfio_spimdev_q_file_poll, > > + .mmap = vfio_spimdev_q_file_mmap, > > +}; > > + > > +static long vfio_spimdev_mdev_get_queue(struct mdev_device *mdev, > > + struct vfio_spimdev *spimdev, unsigned long arg) > > +{ > > + struct vfio_spimdev_queue *q; > > + int ret; > > + > > +#ifdef CONFIG_IOMMU_SVA > > + int pasid = arg; > > + > > + if (!vfio_spimdev_is_valid_pasid(pasid)) > > + return -EINVAL; > > +#endif > > + > > + if (!spimdev->ops->get_queue) > > + return -EINVAL; > > + > > + ret = spimdev->ops->get_queue(spimdev, arg, &q); > > + if (ret < 0) { > > + dev_err(spimdev->dev, "get_queue failed\n"); > > + return -ENODEV; > > + } > > + > > + ret = anon_inode_getfd("spimdev_q", &spimdev_q_file_ops, > > + q, O_CLOEXEC | O_RDWR); > > + if (ret < 0) { > > + dev_err(spimdev->dev, "getfd fail %d\n", ret); > > + goto err_with_queue; > > + } > > + > > + q->fd = ret; > > + q->spimdev = spimdev; > > + q->mdev = mdev; > > + q->container = arg; > > + init_waitqueue_head(&q->wait); > > + get_device(mdev_dev(mdev)); > > + > > + return ret; > > + > > +err_with_queue: > > + spimdev->ops->put_queue(q); > > + return ret; > > +} > > + > > +static long vfio_spimdev_mdev_ioctl(struct mdev_device *mdev, unsigned > > int cmd, > > + unsigned long arg) > > +{ > > + struct spimdev_mdev_state *mdev_state; > > + struct vfio_spimdev *spimdev; > > + > > + if (!mdev) > > + return -ENODEV; > > + > > + mdev_state = mdev_get_drvdata(mdev); > > + if (!mdev_state) > > + return -ENODEV; > > + > > + spimdev = mdev_state->spimdev; > > + if (!spimdev) > > + return -ENODEV; > > + > > + if (cmd == VFIO_SPIMDEV_CMD_GET_Q) > > + return vfio_spimdev_mdev_get_queue(mdev, spimdev, arg); > > + > > + dev_err(spimdev->dev, > > + "%s, ioctl cmd (0x%x) is not supported!\n", __func__, cmd); > > + return -EINVAL; > > +} > > + > > +static void vfio_spimdev_release(struct device *dev) { } > > +static void vfio_spimdev_mdev_release(struct mdev_device *mdev) { } > > +static int vfio_spimdev_mdev_open(struct mdev_device *mdev) { return > > 0; } > > + > > +/** > > + * vfio_spimdev_register - register a spimdev > > + * @spimdev: device structure > > + */ > > +int vfio_spimdev_register(struct vfio_spimdev *spimdev) > > +{ > > + int ret; > > + const char *drv_name; > > + > > + if (!spimdev->dev) > > + return -ENODEV; > > + > > + drv_name = dev_driver_string(spimdev->dev); > > + if (strstr(drv_name, "-")) { > > + pr_err("spimdev: parent driver name cannot include '-'!\n"); > > + return -EINVAL; > > + } > > + > > + spimdev->dev_id = idr_alloc(&spimdev_idr, spimdev, 0, 0, > > GFP_KERNEL); > > + if (spimdev->dev_id < 0) > > + return spimdev->dev_id; > > + > > + atomic_set(&spimdev->ref, 0); > > + spimdev->cls_dev.parent = spimdev->dev; > > + spimdev->cls_dev.class = spimdev_class; > > + spimdev->cls_dev.release = vfio_spimdev_release; > > + dev_set_name(&spimdev->cls_dev, "%s", dev_name(spimdev- > > >dev)); > > + ret = device_register(&spimdev->cls_dev); > > + if (ret) > > + return ret; > > + > > + spimdev->mdev_fops.owner = spimdev->owner; > > + spimdev->mdev_fops.dev_attr_groups = > > vfio_spimdev_groups; > > + WARN_ON(!spimdev->mdev_fops.supported_type_groups); > > + spimdev->mdev_fops.create = > > vfio_spimdev_mdev_create; > > + spimdev->mdev_fops.remove = > > vfio_spimdev_mdev_remove; > > + spimdev->mdev_fops.ioctl = vfio_spimdev_mdev_ioctl; > > + spimdev->mdev_fops.open = > > vfio_spimdev_mdev_open; > > + spimdev->mdev_fops.release = > > vfio_spimdev_mdev_release; > > + > > + ret = mdev_register_device(spimdev->dev, &spimdev->mdev_fops); > > + if (ret) > > + device_unregister(&spimdev->cls_dev); > > + > > + return ret; > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_register); > > + > > +/** > > + * vfio_spimdev_unregister - unregisters a spimdev > > + * @spimdev: device to unregister > > + * > > + * Unregister a miscellaneous device that wat previously successully > > registered > > + * with vfio_spimdev_register(). > > + */ > > +void vfio_spimdev_unregister(struct vfio_spimdev *spimdev) > > +{ > > + mdev_unregister_device(spimdev->dev); > > + device_unregister(&spimdev->cls_dev); > > +} > > +EXPORT_SYMBOL_GPL(vfio_spimdev_unregister); > > + > > +static int __init vfio_spimdev_init(void) > > +{ > > + spimdev_class = class_create(THIS_MODULE, > > VFIO_SPIMDEV_CLASS_NAME); > > + return PTR_ERR_OR_ZERO(spimdev_class); > > +} > > + > > +static __exit void vfio_spimdev_exit(void) > > +{ > > + class_destroy(spimdev_class); > > + idr_destroy(&spimdev_idr); > > +} > > + > > +module_init(vfio_spimdev_init); > > +module_exit(vfio_spimdev_exit); > > + > > +MODULE_LICENSE("GPL"); > > +MODULE_AUTHOR("Hisilicon Tech. Co., Ltd."); > > +MODULE_DESCRIPTION("VFIO Share Parent's IOMMU Mediated Device"); > > diff --git a/drivers/vfio/vfio_iommu_type1.c > > b/drivers/vfio/vfio_iommu_type1.c > > index 3e5b17710a4f..0ec38a17c98c 100644 > > --- a/drivers/vfio/vfio_iommu_type1.c > > +++ b/drivers/vfio/vfio_iommu_type1.c > > @@ -41,6 +41,7 @@ > > #include > > #include > > #include > > +#include > > > > #define DRIVER_VERSION "0.2" > > #define DRIVER_AUTHOR "Alex Williamson > > " > > @@ -89,6 +90,8 @@ struct vfio_dma { > > }; > > > > struct vfio_group { > > + /* iommu_group of mdev's parent device */ > > + struct iommu_group *parent_group; > > struct iommu_group *iommu_group; > > struct list_head next; > > }; > > @@ -1327,6 +1330,109 @@ static bool vfio_iommu_has_sw_msi(struct > > iommu_group *group, phys_addr_t *base) > > return ret; > > } > > > > +/* return 0 if the device is not spimdev. > > + * return 1 if the device is spimdev, the data will be updated with parent > > + * device's group. > > + * return -errno if other error. > > + */ > > +static int vfio_spimdev_type(struct device *dev, void *data) > > +{ > > + struct iommu_group **group = data; > > + struct iommu_group *pgroup; > > + int (*spimdev_mdev)(struct device *dev); > > + struct device *pdev; > > + int ret = 1; > > + > > + /* vfio_spimdev module is not configurated */ > > + spimdev_mdev = symbol_get(vfio_spimdev_is_spimdev); > > + if (!spimdev_mdev) > > + return 0; > > + > > + /* check if it belongs to vfio_spimdev device */ > > + if (!spimdev_mdev(dev)) { > > + ret = 0; > > + goto get_exit; > > + } > > + > > + pdev = dev->parent; > > + pgroup = iommu_group_get(pdev); > > + if (!pgroup) { > > + ret = -ENODEV; > > + goto get_exit; > > + } > > + > > + if (group) { > > + /* check if all parent devices is the same */ > > + if (*group && *group != pgroup) > > + ret = -ENODEV; > > + else > > + *group = pgroup; > > + } > > + > > + iommu_group_put(pgroup); > > + > > +get_exit: > > + symbol_put(vfio_spimdev_is_spimdev); > > + > > + return ret; > > +} > > + > > +/* return 0 or -errno */ > > +static int vfio_spimdev_bus(struct device *dev, void *data) > > +{ > > + struct bus_type **bus = data; > > + > > + if (!dev->bus) > > + return -ENODEV; > > + > > + /* ensure all devices has the same bus_type */ > > + if (*bus && *bus != dev->bus) > > + return -EINVAL; > > + > > + *bus = dev->bus; > > + return 0; > > +} > > + > > +/* return 0 means it is not spi group, 1 means it is, or -EXXX for error */ > > +static int vfio_iommu_type1_attach_spigroup(struct vfio_domain *domain, > > + struct vfio_group *group, > > + struct iommu_group > > *iommu_group) > > +{ > > + int ret; > > + struct bus_type *pbus = NULL; > > + struct iommu_group *pgroup = NULL; > > + > > + ret = iommu_group_for_each_dev(iommu_group, &pgroup, > > + vfio_spimdev_type); > > + if (ret < 0) > > + goto out; > > + else if (ret > 0) { > > + domain->domain = iommu_group_share_domain(pgroup); > > + if (IS_ERR(domain->domain)) > > + goto out; > > + ret = iommu_group_for_each_dev(pgroup, &pbus, > > + vfio_spimdev_bus); > > + if (ret < 0) > > + goto err_with_share_domain; > > + > > + if (pbus && iommu_capable(pbus, > > IOMMU_CAP_CACHE_COHERENCY)) > > + domain->prot |= IOMMU_CACHE; > > + > > + group->parent_group = pgroup; > > + INIT_LIST_HEAD(&domain->group_list); > > + list_add(&group->next, &domain->group_list); > > + > > + return 1; > > + } > > + > > + return 0; > > + > > +err_with_share_domain: > > + iommu_group_unshare_domain(pgroup); > > +out: > > + return ret; > > +} > > + > > static int vfio_iommu_type1_attach_group(void *iommu_data, > > struct iommu_group > > *iommu_group) > > { > > @@ -1335,8 +1441,8 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > struct vfio_domain *domain, *d; > > struct bus_type *bus = NULL, *mdev_bus; > > int ret; > > - bool resv_msi, msi_remap; > > - phys_addr_t resv_msi_base; > > + bool resv_msi = false, msi_remap; > > + phys_addr_t resv_msi_base = 0; > > > > mutex_lock(&iommu->lock); > > > > @@ -1373,6 +1479,14 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > if (mdev_bus) { > > if ((bus == mdev_bus) && !iommu_present(bus)) { > > symbol_put(mdev_bus_type); > > + > > + ret = vfio_iommu_type1_attach_spigroup(domain, > > group, > > + iommu_group); > > + if (ret < 0) > > + goto out_free; > > + else if (ret > 0) > > + goto replay_check; > > + > > if (!iommu->external_domain) { > > INIT_LIST_HEAD(&domain->group_list); > > iommu->external_domain = domain; > > @@ -1451,12 +1565,13 @@ static int > > vfio_iommu_type1_attach_group(void *iommu_data, > > > > vfio_test_domain_fgsp(domain); > > > > +replay_check: > > /* replay mappings on new domains */ > > ret = vfio_iommu_replay(iommu, domain); > > if (ret) > > goto out_detach; > > > > - if (resv_msi) { > > + if (!group->parent_group && resv_msi) { > > ret = iommu_get_msi_cookie(domain->domain, > > resv_msi_base); > > if (ret) > > goto out_detach; > > @@ -1471,7 +1586,10 @@ static int vfio_iommu_type1_attach_group(void > > *iommu_data, > > out_detach: > > iommu_detach_group(domain->domain, iommu_group); > > out_domain: > > - iommu_domain_free(domain->domain); > > + if (group->parent_group) > > + iommu_group_unshare_domain(group->parent_group); > > + else > > + iommu_domain_free(domain->domain); > > out_free: > > kfree(domain); > > kfree(group); > > @@ -1533,6 +1651,7 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > struct vfio_iommu *iommu = iommu_data; > > struct vfio_domain *domain; > > struct vfio_group *group; > > + int ret; > > > > mutex_lock(&iommu->lock); > > > > @@ -1560,7 +1679,11 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > if (!group) > > continue; > > > > - iommu_detach_group(domain->domain, iommu_group); > > + if (group->parent_group) > > + iommu_group_unshare_domain(group- > > >parent_group); > > + else > > + iommu_detach_group(domain->domain, > > iommu_group); > > + > > list_del(&group->next); > > kfree(group); > > /* > > @@ -1577,7 +1700,8 @@ static void > > vfio_iommu_type1_detach_group(void *iommu_data, > > else > > > > vfio_iommu_unmap_unpin_reaccount(iommu); > > } > > - iommu_domain_free(domain->domain); > > + if (!ret) > > + iommu_domain_free(domain->domain); > > list_del(&domain->next); > > kfree(domain); > > } > > diff --git a/include/linux/vfio_spimdev.h b/include/linux/vfio_spimdev.h > > new file mode 100644 > > index 000000000000..f7e7d90013e1 > > --- /dev/null > > +++ b/include/linux/vfio_spimdev.h > > @@ -0,0 +1,95 @@ > > +/* SPDX-License-Identifier: GPL-2.0+ */ > > +#ifndef __VFIO_SPIMDEV_H > > +#define __VFIO_SPIMDEV_H > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +struct vfio_spimdev_queue; > > +struct vfio_spimdev; > > + > > +/** > > + * struct vfio_spimdev_ops - WD device operations > > + * @get_queue: get a queue from the device according to algorithm > > + * @put_queue: free a queue to the device > > + * @is_q_updated: check whether the task is finished > > + * @mask_notify: mask the task irq of queue > > + * @mmap: mmap addresses of queue to user space > > + * @reset: reset the WD device > > + * @reset_queue: reset the queue > > + * @ioctl: ioctl for user space users of the queue > > + * @get_available_instances: get numbers of the queue remained > > + */ > > +struct vfio_spimdev_ops { > > + int (*get_queue)(struct vfio_spimdev *spimdev, unsigned long arg, > > + struct vfio_spimdev_queue **q); > > + int (*put_queue)(struct vfio_spimdev_queue *q); > > + int (*is_q_updated)(struct vfio_spimdev_queue *q); > > + void (*mask_notify)(struct vfio_spimdev_queue *q, int > > event_mask); > > + int (*mmap)(struct vfio_spimdev_queue *q, struct vm_area_struct > > *vma); > > + int (*reset)(struct vfio_spimdev *spimdev); > > + int (*reset_queue)(struct vfio_spimdev_queue *q); > > + long (*ioctl)(struct vfio_spimdev_queue *q, unsigned int cmd, > > + unsigned long arg); > > + int (*get_available_instances)(struct vfio_spimdev *spimdev); > > +}; > > + > > +struct vfio_spimdev_queue { > > + struct mutex mutex; > > + struct vfio_spimdev *spimdev; > > + int qid; > > + __u32 flags; > > + void *priv; > > + wait_queue_head_t wait; > > + struct mdev_device *mdev; > > + int fd; > > + int container; > > +#ifdef CONFIG_IOMMU_SVA > > + int pasid; > > +#endif > > +}; > > + > > +struct vfio_spimdev { > > + const char *name; > > + int status; > > + atomic_t ref; > > + struct module *owner; > > + const struct vfio_spimdev_ops *ops; > > + struct device *dev; > > + struct device cls_dev; > > + bool is_vf; > > + u32 iommu_type; > > + u32 dma_flag; > > + u32 dev_id; > > + void *priv; > > + int flags; > > + const char *api_ver; > > + struct mdev_parent_ops mdev_fops; > > +}; > > + > > +int vfio_spimdev_register(struct vfio_spimdev *spimdev); > > +void vfio_spimdev_unregister(struct vfio_spimdev *spimdev); > > +void vfio_spimdev_wake_up(struct vfio_spimdev_queue *q); > > +int vfio_spimdev_is_spimdev(struct device *dev); > > +struct vfio_spimdev *vfio_spimdev_pdev_spimdev(struct device *dev); > > +int vfio_spimdev_pasid_pri_check(int pasid); > > +int vfio_spimdev_get(struct device *dev); > > +int vfio_spimdev_put(struct device *dev); > > +struct vfio_spimdev *mdev_spimdev(struct mdev_device *mdev); > > + > > +extern struct mdev_type_attribute mdev_type_attr_flags; > > +extern struct mdev_type_attribute mdev_type_attr_name; > > +extern struct mdev_type_attribute mdev_type_attr_device_api; > > +extern struct mdev_type_attribute mdev_type_attr_available_instances; > > +#define VFIO_SPIMDEV_DEFAULT_MDEV_TYPE_ATTRS \ > > + &mdev_type_attr_name.attr, \ > > + &mdev_type_attr_device_api.attr, \ > > + &mdev_type_attr_available_instances.attr, \ > > + &mdev_type_attr_flags.attr > > + > > +#define _VFIO_SPIMDEV_REGION(vm_pgoff) (vm_pgoff & 0xf) > > + > > +#endif > > diff --git a/include/uapi/linux/vfio_spimdev.h > > b/include/uapi/linux/vfio_spimdev.h > > new file mode 100644 > > index 000000000000..3435e5c345b4 > > --- /dev/null > > +++ b/include/uapi/linux/vfio_spimdev.h > > @@ -0,0 +1,28 @@ > > +/* SPDX-License-Identifier: GPL-2.0+ */ > > +#ifndef _UAPIVFIO_SPIMDEV_H > > +#define _UAPIVFIO_SPIMDEV_H > > + > > +#include > > + > > +#define VFIO_SPIMDEV_CLASS_NAME "spimdev" > > + > > +/* Device ATTRs in parent dev SYSFS DIR */ > > +#define VFIO_SPIMDEV_PDEV_ATTRS_GRP_NAME "params" > > + > > +/* Parent device attributes */ > > +#define SPIMDEV_IOMMU_TYPE "iommu_type" > > +#define SPIMDEV_DMA_FLAG "dma_flag" > > + > > +/* Maximum length of algorithm name string */ > > +#define VFIO_SPIMDEV_ALG_NAME_SIZE 64 > > + > > +/* the bits used in SPIMDEV_DMA_FLAG attributes */ > > +#define VFIO_SPIMDEV_DMA_INVALID 0 > > +#define VFIO_SPIMDEV_DMA_SINGLE_PROC_MAP 1 > > +#define VFIO_SPIMDEV_DMA_MULTI_PROC_MAP 2 > > +#define VFIO_SPIMDEV_DMA_SVM 4 > > +#define VFIO_SPIMDEV_DMA_SVM_NO_FAULT 8 > > +#define VFIO_SPIMDEV_DMA_PHY 16 > > + > > +#define VFIO_SPIMDEV_CMD_GET_Q _IO('W', 1) > > +#endif > > -- > > 2.17.1 -- -Kenneth(Hisilicon) ================================================================================ 本邮件及其附件含有华为公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁 止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中 的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from HUAWEI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!