From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: EDAC, {skx|i10nm}_edac: Fix randconfig build error From: "Luck, Tony" Message-Id: <20190314215952.GA303@agluck-desk> Date: Thu, 14 Mar 2019 14:59:52 -0700 To: Borislav Petkov Cc: Arnd Bergmann , Mauro Carvalho Chehab , James Morse , Qiuxu Zhuo , linux-edac@vger.kernel.org, Linux Kernel Mailing List List-ID: T24gVGh1LCBNYXIgMTQsIDIwMTkgYXQgMTI6MDQ6MTNQTSArMDEwMCwgQm9yaXNsYXYgUGV0a292 IHdyb3RlOgo+IE9uIFRodSwgTWFyIDE0LCAyMDE5IGF0IDA4OjA5OjA2QU0gKzAxMDAsIEFybmQg QmVyZ21hbm4gd3JvdGU6Cj4gPiA+IFNvIHdoZXJlIHNob3VsZCB3ZSBnby4gUHJvcG9zZWQgc29s dXRpb25zIGFyZSBwaWxpbmcgdXA6Cj4gPiA+Cj4gPiA+IDEpIE1ha2Ugc2t4X2NvbW1vbiBhIG1v ZHVsZQo+ID4gPiAgICAgICAgIFtkb3duc2lkZTogaGF2ZSB0byBFWFBPUlQgZXZlcnl0aGluZyBp biBpdF0KPiA+ID4gMikgTW92ZSBtb2R1bGUtaXNoIGJpdHMgb3V0IG9mIHNreF9jb21tb24KPiA+ ID4gICAgICAgICBbZG93bnNpZGU6IHBlcmhhcHMgZnJhZ2lsZV0KPiA+ID4gMykgI2luY2x1ZGUg c2t4X2NvbW1vbi5jIGludG8ge3NreCxpMTBubX1fZWRhYy5jCj4gPiA+ICAgICAgICAgW2Rvd25z aWRlOiBubyBwYXRjaCB5ZXQsIGJpZ2dlciBjb2RlIHNpemVdCj4gPiAKPiA+IFNvcnJ5IHRvIGFk ZCBvbiB0byB0aGUgYWxyZWFkeSBsb25nIGxpc3QsIGJ1dCBvbmUgbW9yZSBpZGVhIGFmdGVyCj4g PiBsb29raW5nIGF0IHRoZSB0d28gZmlsZXM6Cj4gPiAKPiA+IDQpIEhhdmUgYSBzaW5nbGUgZHJp dmVyIG1vZHVsZSwgd2l0aCB0aGUgc2t4X2NvbW1vbi5jIGNvbnRhaW5pbmcKPiA+ICAgICB0aGUg dG9wLWxldmVsIG1vZHVsZV9pbml0L21vZHVsZV9leGl0IGZ1bmN0aW9ucyB0aGF0IGNhbGwgaW50 byB0aGUKPiA+ICAgICBoYXJkd2FyZSBzcGVjaWZpYyB2ZXJzaW9ucy4KPiA+IAo+ID4gVGhpcyBp cyB0aGUgb3Bwb3NpdGUgb2YgdGhlIHVzdWFsIHJlY29tbWVuZGF0aW9uICh0aGUgZHJpdmVyCj4g PiBpcyBhbHJlYWR5IHN0cnVjdHVyZWQgbmljZWx5IG90aGVyd2lzZSksIGJ1dCBpdCB3b3VsZCBi ZSBjaGVhcAo+ID4gd2F5IG91dCBoZXJlLgo+IAo+IFRoaXMgaXMgd2hhdCBJIHRoaW5rIHJpZ2h0 IG5vdzogaWYgdGhpcyBpcyBnb2luZyB0byBiZWNvbWUgc3VjaCBhIHBhaW4sCj4gdGhlbiB3ZSBi ZXR0ZXIga2VlcCB0aG9zZSB0d28gZHJpdmVycyBjb21wbGV0ZWx5IHNlcGFyYXRlLiBXaG8gY2Fy ZXMgaWYKPiB0aGVyZSdzIHNvbWUgY29kZSBkdXBsaWNhdGlvbj8hIEJldHRlciB0aGF0IHRoYW4g c29tZSBvYnNjdXJlIHJhbmRjb25maWcKPiBidWlsZCBicmVha2FnZXMgYW5kIGZpeGVzIGludHJv ZHVjaW5nIG1vcmUgdWdsaW5lc3MuIElPVywgd2Ugc2hvdWxkIGtlZXAKPiBpdCBzaW1wbGUuCj4g Cj4gVW5sZXNzLCBUb255LCB5b3Ugd2FudCB0byBiZSBhYmxlIHRvIG1ha2UgY2hhbmdlcyB0byB0 aGUgY29tbW9uIGNvZGUgaW4KPiBvbmUgcGxhY2UgYW5kIGRvbid0IHdhbnQgdG8gcGF0Y2ggYm90 aC4gVGhlbiBJJ2QgbGlicmFyaXplIHRoZSBjb21tb24KPiBmdW5jdGlvbmFsaXR5LCBpLmUuLCBk byBzb21ldGhpbmcgYWxvbmcgdGhlIGxpbmVzIG9mIDIpLgoKVGhlcmUncyBhIGxvdCBvZiBjb21t b24gY29kZS4gUGF0Y2hpbmcgdGhlIHNhbWUgdGhpbmcgaW4gdHdvCmRpZmZlcmVudCBmaWxlcyBz ZWVtcyBsaWtlIG1ha2Utd29yayAoYW5kIGEgcmVjaXBlIGZvciB0aGluZ3MKdG8gYmUgZm9yZ290 dGVuL21pc3NlZCkuCgpJIG1hZGUgYSBwYXRjaCBiYXNlZCBvbiBvcHRpb24gIzMuIFJvdWdoIHN0 ZXBzIHdlcmU6CgokIGNhdCBza3hfY29tbW9uLmMgPj4gc2t4X2NvbW1vbi5oCiQgZ2l0IHJtIHNr eF9jb21tb24uYwokIGdpdCBtdiBza3hfYmFzZS5jIHNreF9lZGFjLmMKJCBnaXQgbXYgaTEwbm1f YmFzZS5jIGkxMG5tX2VkYWMuYwokIGVkaXQgTWFrZWZpbGUgZm9yIGNoYW5nZXMgb2YgbmFtZXMK JCBlZGl0IHNreF9jb21tb24uaCB0byBhZGQgInN0YXRpYyIgZXZlcnl3aGVyZQokIGVkaXQgdG8g Zml4IHRoZSBidWlsZCBpc3N1ZXMKCk5vdCBlbnRpcmVseSBoYXBweSB3aXRoIHNvbWUgb2YgdGhl IGJpdHMgaW4gdGhhdCBsYXN0IHN0ZXAuCgpQYXRjaCBsb29rcyBsaWtlIHRoaXM6CgoKRnJvbSBi OWU5NzIzYzk1YjY2N2QyOGQ4MWVhNTNiMzU0NDdlMWNlOGYzMjQ0IE1vbiBTZXAgMTcgMDA6MDA6 MDAgMjAwMQpGcm9tOiBUb255IEx1Y2sgPHRvbnkubHVja0BpbnRlbC5jb20+CkRhdGU6IFRodSwg MTQgTWFyIDIwMTkgMTA6NDU6MzQgLTA3MDAKU3ViamVjdDogW1BBVENIXSBmaXggY29ybmVyIGNh c2VzIGZvciByYW5kY29uZmlnCi0tLQogZHJpdmVycy9lZGFjL01ha2VmaWxlICAgICAgICAgICAg ICAgICAgICAgICB8ICAgMiAtCiBkcml2ZXJzL2VkYWMve2kxMG5tX2Jhc2UuYyA9PiBpMTBubV9l ZGFjLmN9IHwgICA1ICsKIGRyaXZlcnMvZWRhYy9za3hfY29tbW9uLmMgICAgICAgICAgICAgICAg ICAgfCA2OTEgLS0tLS0tLS0tLS0tLS0tLS0tLS0KIGRyaXZlcnMvZWRhYy9za3hfY29tbW9uLmgg ICAgICAgICAgICAgICAgICAgfCA2ODUgKysrKysrKysrKysrKysrKysrLQogZHJpdmVycy9lZGFj L3tza3hfYmFzZS5jID0+IHNreF9lZGFjLmN9ICAgICB8ICAgOSArLQogNSBmaWxlcyBjaGFuZ2Vk LCA2NzYgaW5zZXJ0aW9ucygrKSwgNzE2IGRlbGV0aW9ucygtKQogcmVuYW1lIGRyaXZlcnMvZWRh Yy97aTEwbm1fYmFzZS5jID0+IGkxMG5tX2VkYWMuY30gKDk4JSkKIGRlbGV0ZSBtb2RlIDEwMDY0 NCBkcml2ZXJzL2VkYWMvc2t4X2NvbW1vbi5jCiByZW5hbWUgZHJpdmVycy9lZGFjL3tza3hfYmFz ZS5jID0+IHNreF9lZGFjLmN9ICg5OCUpCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9lZGFjL01ha2Vm aWxlIGIvZHJpdmVycy9lZGFjL01ha2VmaWxlCmluZGV4IDg5YWQ0YTg0YTBmNi4uNWQ4ZDg4NTc0 ZDNjIDEwMDY0NAotLS0gYS9kcml2ZXJzL2VkYWMvTWFrZWZpbGUKKysrIGIvZHJpdmVycy9lZGFj L01ha2VmaWxlCkBAIC01NywxMCArNTcsOCBAQCBvYmotJChDT05GSUdfRURBQ19NUEM4NVhYKQkJ Kz0gbXBjODV4eF9lZGFjX21vZC5vCiBsYXllcnNjYXBlX2VkYWNfbW9kLXkJCQk6PSBmc2xfZGRy X2VkYWMubyBsYXllcnNjYXBlX2VkYWMubwogb2JqLSQoQ09ORklHX0VEQUNfTEFZRVJTQ0FQRSkJ CSs9IGxheWVyc2NhcGVfZWRhY19tb2QubwogCi1za3hfZWRhYy15CQkJCTo9IHNreF9jb21tb24u byBza3hfYmFzZS5vCiBvYmotJChDT05GSUdfRURBQ19TS1gpCQkJKz0gc2t4X2VkYWMubwogCi1p MTBubV9lZGFjLXkJCQkJOj0gc2t4X2NvbW1vbi5vIGkxMG5tX2Jhc2Uubwogb2JqLSQoQ09ORklH X0VEQUNfSTEwTk0pCQkrPSBpMTBubV9lZGFjLm8KIAogb2JqLSQoQ09ORklHX0VEQUNfTVY2NFg2 MCkJCSs9IG12NjR4NjBfZWRhYy5vCmRpZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvaTEwbm1fYmFz ZS5jIGIvZHJpdmVycy9lZGFjL2kxMG5tX2VkYWMuYwpzaW1pbGFyaXR5IGluZGV4IDk4JQpyZW5h bWUgZnJvbSBkcml2ZXJzL2VkYWMvaTEwbm1fYmFzZS5jCnJlbmFtZSB0byBkcml2ZXJzL2VkYWMv aTEwbm1fZWRhYy5jCmluZGV4IGMzMzRmYjdjNjNkZi4uNDVjNjQ5N2YzNWM1IDEwMDY0NAotLS0g YS9kcml2ZXJzL2VkYWMvaTEwbm1fYmFzZS5jCisrKyBiL2RyaXZlcnMvZWRhYy9pMTBubV9lZGFj LmMKQEAgLTEwLDYgKzEwLDExIEBACiAjaW5jbHVkZSA8YXNtL2ludGVsLWZhbWlseS5oPgogI2lu Y2x1ZGUgPGFzbS9tY2UuaD4KICNpbmNsdWRlICJlZGFjX21vZHVsZS5oIgorCitzdHJ1Y3QgZGVj b2RlZF9hZGRyOwordHlwZWRlZiBib29sICgqc2t4X2RlY29kZV9mKShzdHJ1Y3QgZGVjb2RlZF9h ZGRyICpyZXMpOworc3RhdGljIHNreF9kZWNvZGVfZiBza3hfZGVjb2RlOworCiAjaW5jbHVkZSAi c2t4X2NvbW1vbi5oIgogCiAjZGVmaW5lIEkxME5NX1JFVklTSU9OCSJ2MC4wLjMiCmRpZmYgLS1n aXQgYS9kcml2ZXJzL2VkYWMvc2t4X2NvbW1vbi5jIGIvZHJpdmVycy9lZGFjL3NreF9jb21tb24u YwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMGU5NmU3YjViMGE3Li4wMDAwMDAwMDAw MDAKLS0tIGEvZHJpdmVycy9lZGFjL3NreF9jb21tb24uYworKysgL2Rldi9udWxsCkBAIC0xLDY5 MSArMCwwIEBACi0vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAotLyoKLSAqIENv bW1vbiBjb2RlcyBmb3IgYm90aCB0aGUgc2t4X2VkYWMgZHJpdmVyIGFuZCBJbnRlbCAxMG5tIHNl cnZlciBFREFDIGRyaXZlci4KLSAqIE9yaWdpbmFsbHkgc3BsaXQgb3V0IGZyb20gdGhlIHNreF9l ZGFjIGRyaXZlci4KLSAqCi0gKiBDb3B5cmlnaHQgKGMpIDIwMTgsIEludGVsIENvcnBvcmF0aW9u LgotICovCi0KLSNpbmNsdWRlIDxsaW51eC9hY3BpLmg+Ci0jaW5jbHVkZSA8bGludXgvZG1pLmg+ Ci0jaW5jbHVkZSA8bGludXgvYWR4bC5oPgotI2luY2x1ZGUgPGFjcGkvbmZpdC5oPgotI2luY2x1 ZGUgPGFzbS9tY2UuaD4KLSNpbmNsdWRlICJlZGFjX21vZHVsZS5oIgotI2luY2x1ZGUgInNreF9j b21tb24uaCIKLQotc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBjb21wb25lbnRfbmFtZXNbXSA9 IHsKLQlbSU5ERVhfU09DS0VUXQk9ICJQcm9jZXNzb3JTb2NrZXRJZCIsCi0JW0lOREVYX01FTUNU UkxdCT0gIk1lbW9yeUNvbnRyb2xsZXJJZCIsCi0JW0lOREVYX0NIQU5ORUxdCT0gIkNoYW5uZWxJ ZCIsCi0JW0lOREVYX0RJTU1dCT0gIkRpbW1TbG90SWQiLAotfTsKLQotc3RhdGljIGludCBjb21w b25lbnRfaW5kaWNlc1tBUlJBWV9TSVpFKGNvbXBvbmVudF9uYW1lcyldOwotc3RhdGljIGludCBh ZHhsX2NvbXBvbmVudF9jb3VudDsKLXN0YXRpYyBjb25zdCBjaGFyICogY29uc3QgKmFkeGxfY29t cG9uZW50X25hbWVzOwotc3RhdGljIHU2NCAqYWR4bF92YWx1ZXM7Ci1zdGF0aWMgY2hhciAqYWR4 bF9tc2c7Ci0KLXN0YXRpYyBjaGFyIHNreF9tc2dbTVNHX1NJWkVdOwotc3RhdGljIHNreF9kZWNv ZGVfZiBza3hfZGVjb2RlOwotc3RhdGljIHU2NCBza3hfdG9sbSwgc2t4X3RvaG07Ci1zdGF0aWMg TElTVF9IRUFEKGRldl9lZGFjX2xpc3QpOwotCi1pbnQgX19pbml0IHNreF9hZHhsX2dldCh2b2lk KQotewotCWNvbnN0IGNoYXIgKiBjb25zdCAqbmFtZXM7Ci0JaW50IGksIGo7Ci0KLQluYW1lcyA9 IGFkeGxfZ2V0X2NvbXBvbmVudF9uYW1lcygpOwotCWlmICghbmFtZXMpIHsKLQkJc2t4X3ByaW50 ayhLRVJOX05PVElDRSwgIk5vIGZpcm13YXJlIHN1cHBvcnQgZm9yIGFkZHJlc3MgdHJhbnNsYXRp b24uXG4iKTsKLQkJcmV0dXJuIC1FTk9ERVY7Ci0JfQotCi0JZm9yIChpID0gMDsgaSA8IElOREVY X01BWDsgaSsrKSB7Ci0JCWZvciAoaiA9IDA7IG5hbWVzW2pdOyBqKyspIHsKLQkJCWlmICghc3Ry Y21wKGNvbXBvbmVudF9uYW1lc1tpXSwgbmFtZXNbal0pKSB7Ci0JCQkJY29tcG9uZW50X2luZGlj ZXNbaV0gPSBqOwotCQkJCWJyZWFrOwotCQkJfQotCQl9Ci0KLQkJaWYgKCFuYW1lc1tqXSkKLQkJ CWdvdG8gZXJyOwotCX0KLQotCWFkeGxfY29tcG9uZW50X25hbWVzID0gbmFtZXM7Ci0Jd2hpbGUg KCpuYW1lcysrKQotCQlhZHhsX2NvbXBvbmVudF9jb3VudCsrOwotCi0JYWR4bF92YWx1ZXMgPSBr Y2FsbG9jKGFkeGxfY29tcG9uZW50X2NvdW50LCBzaXplb2YoKmFkeGxfdmFsdWVzKSwKLQkJCSAg ICAgIEdGUF9LRVJORUwpOwotCWlmICghYWR4bF92YWx1ZXMpIHsKLQkJYWR4bF9jb21wb25lbnRf Y291bnQgPSAwOwotCQlyZXR1cm4gLUVOT01FTTsKLQl9Ci0KLQlhZHhsX21zZyA9IGt6YWxsb2Mo TVNHX1NJWkUsIEdGUF9LRVJORUwpOwotCWlmICghYWR4bF9tc2cpIHsKLQkJYWR4bF9jb21wb25l bnRfY291bnQgPSAwOwotCQlrZnJlZShhZHhsX3ZhbHVlcyk7Ci0JCXJldHVybiAtRU5PTUVNOwot CX0KLQotCXJldHVybiAwOwotZXJyOgotCXNreF9wcmludGsoS0VSTl9FUlIsICInJXMnIGlzIG5v dCBtYXRjaGVkIGZyb20gRFNNIHBhcmFtZXRlcnM6ICIsCi0JCSAgIGNvbXBvbmVudF9uYW1lc1tp XSk7Ci0JZm9yIChqID0gMDsgbmFtZXNbal07IGorKykKLQkJc2t4X3ByaW50ayhLRVJOX0NPTlQs ICIlcyAiLCBuYW1lc1tqXSk7Ci0Jc2t4X3ByaW50ayhLRVJOX0NPTlQsICJcbiIpOwotCi0JcmV0 dXJuIC1FTk9ERVY7Ci19Ci0KLXZvaWQgX19leGl0IHNreF9hZHhsX3B1dCh2b2lkKQotewotCWtm cmVlKGFkeGxfdmFsdWVzKTsKLQlrZnJlZShhZHhsX21zZyk7Ci19Ci0KLXN0YXRpYyBib29sIHNr eF9hZHhsX2RlY29kZShzdHJ1Y3QgZGVjb2RlZF9hZGRyICpyZXMpCi17Ci0JaW50IGksIGxlbiA9 IDA7Ci0KLQlpZiAocmVzLT5hZGRyID49IHNreF90b2htIHx8IChyZXMtPmFkZHIgPj0gc2t4X3Rv bG0gJiYKLQkJCQkgICAgICByZXMtPmFkZHIgPCBCSVRfVUxMKDMyKSkpIHsKLQkJZWRhY19kYmco MCwgIkFkZHJlc3MgMHglbGx4IG91dCBvZiByYW5nZVxuIiwgcmVzLT5hZGRyKTsKLQkJcmV0dXJu IGZhbHNlOwotCX0KLQotCWlmIChhZHhsX2RlY29kZShyZXMtPmFkZHIsIGFkeGxfdmFsdWVzKSkg ewotCQllZGFjX2RiZygwLCAiRmFpbGVkIHRvIGRlY29kZSAweCVsbHhcbiIsIHJlcy0+YWRkcik7 Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQlyZXMtPnNvY2tldCAgPSAoaW50KWFkeGxfdmFsdWVz W2NvbXBvbmVudF9pbmRpY2VzW0lOREVYX1NPQ0tFVF1dOwotCXJlcy0+aW1jICAgICA9IChpbnQp YWR4bF92YWx1ZXNbY29tcG9uZW50X2luZGljZXNbSU5ERVhfTUVNQ1RSTF1dOwotCXJlcy0+Y2hh bm5lbCA9IChpbnQpYWR4bF92YWx1ZXNbY29tcG9uZW50X2luZGljZXNbSU5ERVhfQ0hBTk5FTF1d OwotCXJlcy0+ZGltbSAgICA9IChpbnQpYWR4bF92YWx1ZXNbY29tcG9uZW50X2luZGljZXNbSU5E RVhfRElNTV1dOwotCi0JZm9yIChpID0gMDsgaSA8IGFkeGxfY29tcG9uZW50X2NvdW50OyBpKysp IHsKLQkJaWYgKGFkeGxfdmFsdWVzW2ldID09IH4weDB1bGwpCi0JCQljb250aW51ZTsKLQotCQls ZW4gKz0gc25wcmludGYoYWR4bF9tc2cgKyBsZW4sIE1TR19TSVpFIC0gbGVuLCAiICVzOjB4JWxs eCIsCi0JCQkJYWR4bF9jb21wb25lbnRfbmFtZXNbaV0sIGFkeGxfdmFsdWVzW2ldKTsKLQkJaWYg KE1TR19TSVpFIC0gbGVuIDw9IDApCi0JCQlicmVhazsKLQl9Ci0KLQlyZXR1cm4gdHJ1ZTsKLX0K LQotdm9pZCBza3hfc2V0X2RlY29kZShza3hfZGVjb2RlX2YgZGVjb2RlKQotewotCXNreF9kZWNv ZGUgPSBkZWNvZGU7Ci19Ci0KLWludCBza3hfZ2V0X3NyY19pZChzdHJ1Y3Qgc2t4X2RldiAqZCwg dTggKmlkKQotewotCXUzMiByZWc7Ci0KLQlpZiAocGNpX3JlYWRfY29uZmlnX2R3b3JkKGQtPnV0 aWxfYWxsLCAweGYwLCAmcmVnKSkgewotCQlza3hfcHJpbnRrKEtFUk5fRVJSLCAiRmFpbGVkIHRv IHJlYWQgc3JjIGlkXG4iKTsKLQkJcmV0dXJuIC1FTk9ERVY7Ci0JfQotCi0JKmlkID0gR0VUX0JJ VEZJRUxEKHJlZywgMTIsIDE0KTsKLQlyZXR1cm4gMDsKLX0KLQotaW50IHNreF9nZXRfbm9kZV9p ZChzdHJ1Y3Qgc2t4X2RldiAqZCwgdTggKmlkKQotewotCXUzMiByZWc7Ci0KLQlpZiAocGNpX3Jl YWRfY29uZmlnX2R3b3JkKGQtPnV0aWxfYWxsLCAweGY0LCAmcmVnKSkgewotCQlza3hfcHJpbnRr KEtFUk5fRVJSLCAiRmFpbGVkIHRvIHJlYWQgbm9kZSBpZFxuIik7Ci0JCXJldHVybiAtRU5PREVW OwotCX0KLQotCSppZCA9IEdFVF9CSVRGSUVMRChyZWcsIDAsIDIpOwotCXJldHVybiAwOwotfQot Ci1zdGF0aWMgaW50IGdldF93aWR0aCh1MzIgbXRyKQotewotCXN3aXRjaCAoR0VUX0JJVEZJRUxE KG10ciwgOCwgOSkpIHsKLQljYXNlIDA6Ci0JCXJldHVybiBERVZfWDQ7Ci0JY2FzZSAxOgotCQly ZXR1cm4gREVWX1g4OwotCWNhc2UgMjoKLQkJcmV0dXJuIERFVl9YMTY7Ci0JfQotCXJldHVybiBE RVZfVU5LTk9XTjsKLX0KLQotLyoKLSAqIFdlIHVzZSB0aGUgcGVyLXNvY2tldCBkZXZpY2UgQGRp ZCB0byBjb3VudCBob3cgbWFueSBzb2NrZXRzIGFyZSBwcmVzZW50LAotICogYW5kIHRvIGRldGVt aW5lIHdoaWNoIFBDSSBidXNlcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGVhY2ggc29ja2V0LiBBbGxv Y2F0ZQotICogYW5kIGJ1aWxkIHRoZSBmdWxsIGxpc3Qgb2YgYWxsIHRoZSBza3hfZGV2IHN0cnVj dHVyZXMgdGhhdCB3ZSBuZWVkIGhlcmUuCi0gKi8KLWludCBza3hfZ2V0X2FsbF9idXNfbWFwcGlu Z3ModW5zaWduZWQgaW50IGRpZCwgaW50IG9mZiwgZW51bSB0eXBlIHR5cGUsCi0JCQkgICAgIHN0 cnVjdCBsaXN0X2hlYWQgKipsaXN0KQotewotCXN0cnVjdCBwY2lfZGV2ICpwZGV2LCAqcHJldjsK LQlzdHJ1Y3Qgc2t4X2RldiAqZDsKLQl1MzIgcmVnOwotCWludCBuZGV2ID0gMDsKLQotCXByZXYg PSBOVUxMOwotCWZvciAoOzspIHsKLQkJcGRldiA9IHBjaV9nZXRfZGV2aWNlKFBDSV9WRU5ET1Jf SURfSU5URUwsIGRpZCwgcHJldik7Ci0JCWlmICghcGRldikKLQkJCWJyZWFrOwotCQluZGV2Kys7 Ci0JCWQgPSBremFsbG9jKHNpemVvZigqZCksIEdGUF9LRVJORUwpOwotCQlpZiAoIWQpIHsKLQkJ CXBjaV9kZXZfcHV0KHBkZXYpOwotCQkJcmV0dXJuIC1FTk9NRU07Ci0JCX0KLQotCQlpZiAocGNp X3JlYWRfY29uZmlnX2R3b3JkKHBkZXYsIG9mZiwgJnJlZykpIHsKLQkJCWtmcmVlKGQpOwotCQkJ cGNpX2Rldl9wdXQocGRldik7Ci0JCQlza3hfcHJpbnRrKEtFUk5fRVJSLCAiRmFpbGVkIHRvIHJl YWQgYnVzIGlkeFxuIik7Ci0JCQlyZXR1cm4gLUVOT0RFVjsKLQkJfQotCi0JCWQtPmJ1c1swXSA9 IEdFVF9CSVRGSUVMRChyZWcsIDAsIDcpOwotCQlkLT5idXNbMV0gPSBHRVRfQklURklFTEQocmVn LCA4LCAxNSk7Ci0JCWlmICh0eXBlID09IFNLWCkgewotCQkJZC0+c2VnID0gcGNpX2RvbWFpbl9u cihwZGV2LT5idXMpOwotCQkJZC0+YnVzWzJdID0gR0VUX0JJVEZJRUxEKHJlZywgMTYsIDIzKTsK LQkJCWQtPmJ1c1szXSA9IEdFVF9CSVRGSUVMRChyZWcsIDI0LCAzMSk7Ci0JCX0gZWxzZSB7Ci0J CQlkLT5zZWcgPSBHRVRfQklURklFTEQocmVnLCAxNiwgMjMpOwotCQl9Ci0KLQkJZWRhY19kYmco MiwgImJ1c3NlczogMHgleCwgMHgleCwgMHgleCwgMHgleFxuIiwKLQkJCSBkLT5idXNbMF0sIGQt PmJ1c1sxXSwgZC0+YnVzWzJdLCBkLT5idXNbM10pOwotCQlsaXN0X2FkZF90YWlsKCZkLT5saXN0 LCAmZGV2X2VkYWNfbGlzdCk7Ci0JCXByZXYgPSBwZGV2OwotCX0KLQotCWlmIChsaXN0KQotCQkq bGlzdCA9ICZkZXZfZWRhY19saXN0OwotCXJldHVybiBuZGV2OwotfQotCi1pbnQgc2t4X2dldF9o aV9sbyh1bnNpZ25lZCBpbnQgZGlkLCBpbnQgb2ZmW10sIHU2NCAqdG9sbSwgdTY0ICp0b2htKQot ewotCXN0cnVjdCBwY2lfZGV2ICpwZGV2OwotCXUzMiByZWc7Ci0KLQlwZGV2ID0gcGNpX2dldF9k ZXZpY2UoUENJX1ZFTkRPUl9JRF9JTlRFTCwgZGlkLCBOVUxMKTsKLQlpZiAoIXBkZXYpIHsKLQkJ c2t4X3ByaW50ayhLRVJOX0VSUiwgIkNhbid0IGdldCB0b2xtL3RvaG1cbiIpOwotCQlyZXR1cm4g LUVOT0RFVjsKLQl9Ci0KLQlpZiAocGNpX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYsIG9mZlswXSwg JnJlZykpIHsKLQkJc2t4X3ByaW50ayhLRVJOX0VSUiwgIkZhaWxlZCB0byByZWFkIHRvbG1cbiIp OwotCQlnb3RvIGZhaWw7Ci0JfQotCXNreF90b2xtID0gcmVnOwotCi0JaWYgKHBjaV9yZWFkX2Nv bmZpZ19kd29yZChwZGV2LCBvZmZbMV0sICZyZWcpKSB7Ci0JCXNreF9wcmludGsoS0VSTl9FUlIs ICJGYWlsZWQgdG8gcmVhZCBsb3dlciB0b2htXG4iKTsKLQkJZ290byBmYWlsOwotCX0KLQlza3hf dG9obSA9IHJlZzsKLQotCWlmIChwY2lfcmVhZF9jb25maWdfZHdvcmQocGRldiwgb2ZmWzJdLCAm cmVnKSkgewotCQlza3hfcHJpbnRrKEtFUk5fRVJSLCAiRmFpbGVkIHRvIHJlYWQgdXBwZXIgdG9o bVxuIik7Ci0JCWdvdG8gZmFpbDsKLQl9Ci0Jc2t4X3RvaG0gfD0gKHU2NClyZWcgPDwgMzI7Ci0K LQlwY2lfZGV2X3B1dChwZGV2KTsKLQkqdG9sbSA9IHNreF90b2xtOwotCSp0b2htID0gc2t4X3Rv aG07Ci0JZWRhY19kYmcoMiwgInRvbG0gPSAweCVsbHggdG9obSA9IDB4JWxseFxuIiwgc2t4X3Rv bG0sIHNreF90b2htKTsKLQlyZXR1cm4gMDsKLWZhaWw6Ci0JcGNpX2Rldl9wdXQocGRldik7Ci0J cmV0dXJuIC1FTk9ERVY7Ci19Ci0KLXN0YXRpYyBpbnQgc2t4X2dldF9kaW1tX2F0dHIodTMyIHJl ZywgaW50IGxvYml0LCBpbnQgaGliaXQsIGludCBhZGQsCi0JCQkgICAgIGludCBtaW52YWwsIGlu dCBtYXh2YWwsIGNvbnN0IGNoYXIgKm5hbWUpCi17Ci0JdTMyIHZhbCA9IEdFVF9CSVRGSUVMRChy ZWcsIGxvYml0LCBoaWJpdCk7Ci0KLQlpZiAodmFsIDwgbWludmFsIHx8IHZhbCA+IG1heHZhbCkg ewotCQllZGFjX2RiZygyLCAiYmFkICVzID0gJWQgKHJhdz0weCV4KVxuIiwgbmFtZSwgdmFsLCBy ZWcpOwotCQlyZXR1cm4gLUVJTlZBTDsKLQl9Ci0JcmV0dXJuIHZhbCArIGFkZDsKLX0KLQotI2Rl ZmluZSBudW1yYW5rKHJlZykJc2t4X2dldF9kaW1tX2F0dHIocmVnLCAxMiwgMTMsIDAsIDAsIDIs ICJyYW5rcyIpCi0jZGVmaW5lIG51bXJvdyhyZWcpCXNreF9nZXRfZGltbV9hdHRyKHJlZywgMiwg NCwgMTIsIDEsIDYsICJyb3dzIikKLSNkZWZpbmUgbnVtY29sKHJlZykJc2t4X2dldF9kaW1tX2F0 dHIocmVnLCAwLCAxLCAxMCwgMCwgMiwgImNvbHMiKQotCi1pbnQgc2t4X2dldF9kaW1tX2luZm8o dTMyIG10ciwgdTMyIGFtYXAsIHN0cnVjdCBkaW1tX2luZm8gKmRpbW0sCi0JCSAgICAgIHN0cnVj dCBza3hfaW1jICppbWMsIGludCBjaGFuLCBpbnQgZGltbW5vKQotewotCWludCAgYmFua3MgPSAx NiwgcmFua3MsIHJvd3MsIGNvbHMsIG5wYWdlczsKLQl1NjQgc2l6ZTsKLQotCXJhbmtzID0gbnVt cmFuayhtdHIpOwotCXJvd3MgPSBudW1yb3cobXRyKTsKLQljb2xzID0gbnVtY29sKG10cik7Ci0K LQkvKgotCSAqIENvbXB1dGUgc2l6ZSBpbiA4LWJ5dGUgKDJeMykgd29yZHMsIHRoZW4gc2hpZnQg dG8gTWlCICgyXjIwKQotCSAqLwotCXNpemUgPSAoKDF1bGwgPDwgKHJvd3MgKyBjb2xzICsgcmFu a3MpKSAqIGJhbmtzKSA+PiAoMjAgLSAzKTsKLQlucGFnZXMgPSBNaUJfVE9fUEFHRVMoc2l6ZSk7 Ci0KLQllZGFjX2RiZygwLCAibWMjJWQ6IGNoYW5uZWwgJWQsIGRpbW0gJWQsICVsbGQgTWlCICgl ZCBwYWdlcykgYmFuazogJWQsIHJhbms6ICVkLCByb3c6IDB4JXgsIGNvbDogMHgleFxuIiwKLQkJ IGltYy0+bWMsIGNoYW4sIGRpbW1ubywgc2l6ZSwgbnBhZ2VzLAotCQkgYmFua3MsIDEgPDwgcmFu a3MsIHJvd3MsIGNvbHMpOwotCi0JaW1jLT5jaGFuW2NoYW5dLmRpbW1zW2RpbW1ub10uY2xvc2Vf cGcgPSBHRVRfQklURklFTEQobXRyLCAwLCAwKTsKLQlpbWMtPmNoYW5bY2hhbl0uZGltbXNbZGlt bW5vXS5iYW5rX3hvcl9lbmFibGUgPSBHRVRfQklURklFTEQobXRyLCA5LCA5KTsKLQlpbWMtPmNo YW5bY2hhbl0uZGltbXNbZGltbW5vXS5maW5lX2dyYWluX2JhbmsgPSBHRVRfQklURklFTEQoYW1h cCwgMCwgMCk7Ci0JaW1jLT5jaGFuW2NoYW5dLmRpbW1zW2RpbW1ub10ucm93Yml0cyA9IHJvd3M7 Ci0JaW1jLT5jaGFuW2NoYW5dLmRpbW1zW2RpbW1ub10uY29sYml0cyA9IGNvbHM7Ci0KLQlkaW1t LT5ucl9wYWdlcyA9IG5wYWdlczsKLQlkaW1tLT5ncmFpbiA9IDMyOwotCWRpbW0tPmR0eXBlID0g Z2V0X3dpZHRoKG10cik7Ci0JZGltbS0+bXR5cGUgPSBNRU1fRERSNDsKLQlkaW1tLT5lZGFjX21v ZGUgPSBFREFDX1NFQ0RFRDsgLyogbGlrZWx5IGJldHRlciB0aGFuIHRoaXMgKi8KLQlzbnByaW50 ZihkaW1tLT5sYWJlbCwgc2l6ZW9mKGRpbW0tPmxhYmVsKSwgIkNQVV9TcmNJRCMldV9NQyMldV9D aGFuIyV1X0RJTU0jJXUiLAotCQkgaW1jLT5zcmNfaWQsIGltYy0+bG1jLCBjaGFuLCBkaW1tbm8p OwotCi0JcmV0dXJuIDE7Ci19Ci0KLWludCBza3hfZ2V0X252ZGltbV9pbmZvKHN0cnVjdCBkaW1t X2luZm8gKmRpbW0sIHN0cnVjdCBza3hfaW1jICppbWMsCi0JCQlpbnQgY2hhbiwgaW50IGRpbW1u bywgY29uc3QgY2hhciAqbW9kX3N0cikKLXsKLQlpbnQgc21iaW9zX2hhbmRsZTsKLQl1MzIgZGV2 X2hhbmRsZTsKLQl1MTYgZmxhZ3M7Ci0JdTY0IHNpemUgPSAwOwotCi0JZGV2X2hhbmRsZSA9IEFD UElfTkZJVF9CVUlMRF9ERVZJQ0VfSEFORExFKGRpbW1ubywgY2hhbiwgaW1jLT5sbWMsCi0JCQkJ CQkgICBpbWMtPnNyY19pZCwgMCk7Ci0KLQlzbWJpb3NfaGFuZGxlID0gbmZpdF9nZXRfc21iaW9z X2lkKGRldl9oYW5kbGUsICZmbGFncyk7Ci0JaWYgKHNtYmlvc19oYW5kbGUgPT0gLUVPUE5PVFNV UFApIHsKLQkJcHJfd2Fybl9vbmNlKCIlczogQ2FuJ3QgZmluZCBzaXplIG9mIE5WRElNTS4gVHJ5 IGVuYWJsaW5nIENPTkZJR19BQ1BJX05GSVRcbiIsIG1vZF9zdHIpOwotCQlnb3RvIHVua25vd25f c2l6ZTsKLQl9Ci0KLQlpZiAoc21iaW9zX2hhbmRsZSA8IDApIHsKLQkJc2t4X3ByaW50ayhLRVJO X0VSUiwgIkNhbid0IGZpbmQgaGFuZGxlIGZvciBOVkRJTU0gQURSPTB4JXhcbiIsIGRldl9oYW5k bGUpOwotCQlnb3RvIHVua25vd25fc2l6ZTsKLQl9Ci0KLQlpZiAoZmxhZ3MgJiBBQ1BJX05GSVRf TUVNX01BUF9GQUlMRUQpIHsKLQkJc2t4X3ByaW50ayhLRVJOX0VSUiwgIk5WRElNTSBBRFI9MHgl eCBpcyBub3QgbWFwcGVkXG4iLCBkZXZfaGFuZGxlKTsKLQkJZ290byB1bmtub3duX3NpemU7Ci0J fQotCi0Jc2l6ZSA9IGRtaV9tZW1kZXZfc2l6ZShzbWJpb3NfaGFuZGxlKTsKLQlpZiAoc2l6ZSA9 PSB+MHVsbCkKLQkJc2t4X3ByaW50ayhLRVJOX0VSUiwgIkNhbid0IGZpbmQgc2l6ZSBmb3IgTlZE SU1NIEFEUj0weCV4L1NNQklPUz0weCV4XG4iLAotCQkJICAgZGV2X2hhbmRsZSwgc21iaW9zX2hh bmRsZSk7Ci0KLXVua25vd25fc2l6ZToKLQlkaW1tLT5ucl9wYWdlcyA9IHNpemUgPj4gUEFHRV9T SElGVDsKLQlkaW1tLT5ncmFpbiA9IDMyOwotCWRpbW0tPmR0eXBlID0gREVWX1VOS05PV047Ci0J ZGltbS0+bXR5cGUgPSBNRU1fTlZESU1NOwotCWRpbW0tPmVkYWNfbW9kZSA9IEVEQUNfU0VDREVE OyAvKiBsaWtlbHkgYmV0dGVyIHRoYW4gdGhpcyAqLwotCi0JZWRhY19kYmcoMCwgIm1jIyVkOiBj aGFubmVsICVkLCBkaW1tICVkLCAlbGx1IE1pQiAoJXUgcGFnZXMpXG4iLAotCQkgaW1jLT5tYywg Y2hhbiwgZGltbW5vLCBzaXplID4+IDIwLCBkaW1tLT5ucl9wYWdlcyk7Ci0KLQlzbnByaW50Zihk aW1tLT5sYWJlbCwgc2l6ZW9mKGRpbW0tPmxhYmVsKSwgIkNQVV9TcmNJRCMldV9NQyMldV9DaGFu IyV1X0RJTU0jJXUiLAotCQkgaW1jLT5zcmNfaWQsIGltYy0+bG1jLCBjaGFuLCBkaW1tbm8pOwot Ci0JcmV0dXJuIChzaXplID09IDAgfHwgc2l6ZSA9PSB+MHVsbCkgPyAwIDogMTsKLX0KLQotaW50 IHNreF9yZWdpc3Rlcl9tY2koc3RydWN0IHNreF9pbWMgKmltYywgc3RydWN0IHBjaV9kZXYgKnBk ZXYsCi0JCSAgICAgY29uc3QgY2hhciAqY3RsX25hbWUsIGNvbnN0IGNoYXIgKm1vZF9zdHIsCi0J CSAgICAgZ2V0X2RpbW1fY29uZmlnX2YgZ2V0X2RpbW1fY29uZmlnKQotewotCXN0cnVjdCBtZW1f Y3RsX2luZm8gKm1jaTsKLQlzdHJ1Y3QgZWRhY19tY19sYXllciBsYXllcnNbMl07Ci0Jc3RydWN0 IHNreF9wdnQgKnB2dDsKLQlpbnQgcmM7Ci0KLQkvKiBBbGxvY2F0ZSBhIG5ldyBNQyBjb250cm9s IHN0cnVjdHVyZSAqLwotCWxheWVyc1swXS50eXBlID0gRURBQ19NQ19MQVlFUl9DSEFOTkVMOwot CWxheWVyc1swXS5zaXplID0gTlVNX0NIQU5ORUxTOwotCWxheWVyc1swXS5pc192aXJ0X2Nzcm93 ID0gZmFsc2U7Ci0JbGF5ZXJzWzFdLnR5cGUgPSBFREFDX01DX0xBWUVSX1NMT1Q7Ci0JbGF5ZXJz WzFdLnNpemUgPSBOVU1fRElNTVM7Ci0JbGF5ZXJzWzFdLmlzX3ZpcnRfY3Nyb3cgPSB0cnVlOwot CW1jaSA9IGVkYWNfbWNfYWxsb2MoaW1jLT5tYywgQVJSQVlfU0laRShsYXllcnMpLCBsYXllcnMs Ci0JCQkgICAgc2l6ZW9mKHN0cnVjdCBza3hfcHZ0KSk7Ci0KLQlpZiAodW5saWtlbHkoIW1jaSkp Ci0JCXJldHVybiAtRU5PTUVNOwotCi0JZWRhY19kYmcoMCwgIk1DIyVkOiBtY2kgPSAlcFxuIiwg aW1jLT5tYywgbWNpKTsKLQotCS8qIEFzc29jaWF0ZSBza3hfZGV2IGFuZCBtY2kgZm9yIGZ1dHVy ZSB1c2FnZSAqLwotCWltYy0+bWNpID0gbWNpOwotCXB2dCA9IG1jaS0+cHZ0X2luZm87Ci0JcHZ0 LT5pbWMgPSBpbWM7Ci0KLQltY2ktPmN0bF9uYW1lID0ga2FzcHJpbnRmKEdGUF9LRVJORUwsICIl cyMlZCBJTUMjJWQiLCBjdGxfbmFtZSwKLQkJCQkgIGltYy0+bm9kZV9pZCwgaW1jLT5sbWMpOwot CWlmICghbWNpLT5jdGxfbmFtZSkgewotCQlyYyA9IC1FTk9NRU07Ci0JCWdvdG8gZmFpbDA7Ci0J fQotCi0JbWNpLT5tdHlwZV9jYXAgPSBNRU1fRkxBR19ERFI0IHwgTUVNX0ZMQUdfTlZESU1NOwot CW1jaS0+ZWRhY19jdGxfY2FwID0gRURBQ19GTEFHX05PTkU7Ci0JbWNpLT5lZGFjX2NhcCA9IEVE QUNfRkxBR19OT05FOwotCW1jaS0+bW9kX25hbWUgPSBtb2Rfc3RyOwotCW1jaS0+ZGV2X25hbWUg PSBwY2lfbmFtZShwZGV2KTsKLQltY2ktPmN0bF9wYWdlX3RvX3BoeXMgPSBOVUxMOwotCi0JcmMg PSBnZXRfZGltbV9jb25maWcobWNpKTsKLQlpZiAocmMgPCAwKQotCQlnb3RvIGZhaWw7Ci0KLQkv KiBSZWNvcmQgcHRyIHRvIHRoZSBnZW5lcmljIGRldmljZSAqLwotCW1jaS0+cGRldiA9ICZwZGV2 LT5kZXY7Ci0KLQkvKiBBZGQgdGhpcyBuZXcgTUMgY29udHJvbCBzdHJ1Y3R1cmUgdG8gRURBQydz IGxpc3Qgb2YgTUNzICovCi0JaWYgKHVubGlrZWx5KGVkYWNfbWNfYWRkX21jKG1jaSkpKSB7Ci0J CWVkYWNfZGJnKDAsICJNQzogZmFpbGVkIGVkYWNfbWNfYWRkX21jKClcbiIpOwotCQlyYyA9IC1F SU5WQUw7Ci0JCWdvdG8gZmFpbDsKLQl9Ci0KLQlyZXR1cm4gMDsKLQotZmFpbDoKLQlrZnJlZSht Y2ktPmN0bF9uYW1lKTsKLWZhaWwwOgotCWVkYWNfbWNfZnJlZShtY2kpOwotCWltYy0+bWNpID0g TlVMTDsKLQlyZXR1cm4gcmM7Ci19Ci0KLXN0YXRpYyB2b2lkIHNreF91bnJlZ2lzdGVyX21jaShz dHJ1Y3Qgc2t4X2ltYyAqaW1jKQotewotCXN0cnVjdCBtZW1fY3RsX2luZm8gKm1jaSA9IGltYy0+ bWNpOwotCi0JaWYgKCFtY2kpCi0JCXJldHVybjsKLQotCWVkYWNfZGJnKDAsICJNQyVkOiBtY2kg PSAlcFxuIiwgaW1jLT5tYywgbWNpKTsKLQotCS8qIFJlbW92ZSBNQyBzeXNmcyBub2RlcyAqLwot CWVkYWNfbWNfZGVsX21jKG1jaS0+cGRldik7Ci0KLQllZGFjX2RiZygxLCAiJXM6IGZyZWUgbWNp IHN0cnVjdFxuIiwgbWNpLT5jdGxfbmFtZSk7Ci0Ja2ZyZWUobWNpLT5jdGxfbmFtZSk7Ci0JZWRh Y19tY19mcmVlKG1jaSk7Ci19Ci0KLXN0YXRpYyBzdHJ1Y3QgbWVtX2N0bF9pbmZvICpnZXRfbWNp KGludCBzcmNfaWQsIGludCBsbWMpCi17Ci0Jc3RydWN0IHNreF9kZXYgKmQ7Ci0KLQlpZiAobG1j ID4gTlVNX0lNQyAtIDEpIHsKLQkJc2t4X3ByaW50ayhLRVJOX0VSUiwgIkJhZCBsbWMgJWRcbiIs IGxtYyk7Ci0JCXJldHVybiBOVUxMOwotCX0KLQotCWxpc3RfZm9yX2VhY2hfZW50cnkoZCwgJmRl dl9lZGFjX2xpc3QsIGxpc3QpIHsKLQkJaWYgKGQtPmltY1swXS5zcmNfaWQgPT0gc3JjX2lkKQot CQkJcmV0dXJuIGQtPmltY1tsbWNdLm1jaTsKLQl9Ci0KLQlza3hfcHJpbnRrKEtFUk5fRVJSLCAi Tm8gbWNpIGZvciBzcmNfaWQgJWQgbG1jICVkXG4iLCBzcmNfaWQsIGxtYyk7Ci0JcmV0dXJuIE5V TEw7Ci19Ci0KLXN0YXRpYyB2b2lkIHNreF9tY2Vfb3V0cHV0X2Vycm9yKHN0cnVjdCBtZW1fY3Rs X2luZm8gKm1jaSwKLQkJCQkgY29uc3Qgc3RydWN0IG1jZSAqbSwKLQkJCQkgc3RydWN0IGRlY29k ZWRfYWRkciAqcmVzKQotewotCWVudW0gaHdfZXZlbnRfbWNfZXJyX3R5cGUgdHBfZXZlbnQ7Ci0J Y2hhciAqdHlwZSwgKm9wdHlwZTsKLQlib29sIHJpcHYgPSBHRVRfQklURklFTEQobS0+bWNnc3Rh dHVzLCAwLCAwKTsKLQlib29sIG92ZXJmbG93ID0gR0VUX0JJVEZJRUxEKG0tPnN0YXR1cywgNjIs IDYyKTsKLQlib29sIHVuY29ycmVjdGVkX2Vycm9yID0gR0VUX0JJVEZJRUxEKG0tPnN0YXR1cywg NjEsIDYxKTsKLQlib29sIHJlY292ZXJhYmxlOwotCXUzMiBjb3JlX2Vycl9jbnQgPSBHRVRfQklU RklFTEQobS0+c3RhdHVzLCAzOCwgNTIpOwotCXUzMiBtc2NvZCA9IEdFVF9CSVRGSUVMRChtLT5z dGF0dXMsIDE2LCAzMSk7Ci0JdTMyIGVycmNvZGUgPSBHRVRfQklURklFTEQobS0+c3RhdHVzLCAw LCAxNSk7Ci0JdTMyIG9wdHlwZW51bSA9IEdFVF9CSVRGSUVMRChtLT5zdGF0dXMsIDQsIDYpOwot Ci0JcmVjb3ZlcmFibGUgPSBHRVRfQklURklFTEQobS0+c3RhdHVzLCA1NiwgNTYpOwotCi0JaWYg KHVuY29ycmVjdGVkX2Vycm9yKSB7Ci0JCWNvcmVfZXJyX2NudCA9IDE7Ci0JCWlmIChyaXB2KSB7 Ci0JCQl0eXBlID0gIkZBVEFMIjsKLQkJCXRwX2V2ZW50ID0gSFdfRVZFTlRfRVJSX0ZBVEFMOwot CQl9IGVsc2UgewotCQkJdHlwZSA9ICJOT05fRkFUQUwiOwotCQkJdHBfZXZlbnQgPSBIV19FVkVO VF9FUlJfVU5DT1JSRUNURUQ7Ci0JCX0KLQl9IGVsc2UgewotCQl0eXBlID0gIkNPUlJFQ1RFRCI7 Ci0JCXRwX2V2ZW50ID0gSFdfRVZFTlRfRVJSX0NPUlJFQ1RFRDsKLQl9Ci0KLQkvKgotCSAqIEFj Y29yZGluZyB0byBJbnRlbCBBcmNoaXRlY3R1cmUgc3BlYyB2b2wgM0IsCi0JICogVGFibGUgMTUt MTAgIklBMzJfTUNpX1N0YXR1cyBbMTU6MF0gQ29tcG91bmQgRXJyb3IgQ29kZSBFbmNvZGluZyIK LQkgKiBtZW1vcnkgZXJyb3JzIHNob3VsZCBmaXQgb25lIG9mIHRoZXNlIG1hc2tzOgotCSAqCTAw MGYgMDAwMCAxbW1tIGNjY2MgKGJpbmFyeSkKLQkgKgkwMDBmIDAwMTAgMW1tbSBjY2NjIChiaW5h cnkpCVtSQU0gdXNlZCBhcyBjYWNoZV0KLQkgKiB3aGVyZToKLQkgKglmID0gQ29ycmVjdGlvbiBS ZXBvcnQgRmlsdGVyaW5nIEJpdC4gSWYgMSwgc3Vic2VxdWVudCBlcnJvcnMKLQkgKgkgICAgd29u J3QgYmUgc2hvd24KLQkgKgltbW0gPSBlcnJvciB0eXBlCi0JICoJY2NjYyA9IGNoYW5uZWwKLQkg KiBJZiB0aGUgbWFzayBkb2Vzbid0IG1hdGNoLCByZXBvcnQgYW4gZXJyb3IgdG8gdGhlIHBhcnNp bmcgbG9naWMKLQkgKi8KLQlpZiAoISgoZXJyY29kZSAmIDB4ZWY4MCkgPT0gMHg4MCB8fCAoZXJy Y29kZSAmIDB4ZWY4MCkgPT0gMHgyODApKSB7Ci0JCW9wdHlwZSA9ICJDYW4ndCBwYXJzZTogaXQg aXMgbm90IGEgbWVtIjsKLQl9IGVsc2UgewotCQlzd2l0Y2ggKG9wdHlwZW51bSkgewotCQljYXNl IDA6Ci0JCQlvcHR5cGUgPSAiZ2VuZXJpYyB1bmRlZiByZXF1ZXN0IGVycm9yIjsKLQkJCWJyZWFr OwotCQljYXNlIDE6Ci0JCQlvcHR5cGUgPSAibWVtb3J5IHJlYWQgZXJyb3IiOwotCQkJYnJlYWs7 Ci0JCWNhc2UgMjoKLQkJCW9wdHlwZSA9ICJtZW1vcnkgd3JpdGUgZXJyb3IiOwotCQkJYnJlYWs7 Ci0JCWNhc2UgMzoKLQkJCW9wdHlwZSA9ICJhZGRyL2NtZCBlcnJvciI7Ci0JCQlicmVhazsKLQkJ Y2FzZSA0OgotCQkJb3B0eXBlID0gIm1lbW9yeSBzY3J1YmJpbmcgZXJyb3IiOwotCQkJYnJlYWs7 Ci0JCWRlZmF1bHQ6Ci0JCQlvcHR5cGUgPSAicmVzZXJ2ZWQiOwotCQkJYnJlYWs7Ci0JCX0KLQl9 Ci0JaWYgKGFkeGxfY29tcG9uZW50X2NvdW50KSB7Ci0JCXNucHJpbnRmKHNreF9tc2csIE1TR19T SVpFLCAiJXMlcyBlcnJfY29kZToweCUwNHg6MHglMDR4ICVzIiwKLQkJCSBvdmVyZmxvdyA/ICIg T1ZFUkZMT1ciIDogIiIsCi0JCQkgKHVuY29ycmVjdGVkX2Vycm9yICYmIHJlY292ZXJhYmxlKSA/ ICIgcmVjb3ZlcmFibGUiIDogIiIsCi0JCQkgbXNjb2QsIGVycmNvZGUsIGFkeGxfbXNnKTsKLQl9 IGVsc2UgewotCQlzbnByaW50Zihza3hfbXNnLCBNU0dfU0laRSwKLQkJCSAiJXMlcyBlcnJfY29k ZToweCUwNHg6MHglMDR4IHNvY2tldDolZCBpbWM6JWQgcmFuazolZCBiZzolZCBiYTolZCByb3c6 MHgleCBjb2w6MHgleCIsCi0JCQkgb3ZlcmZsb3cgPyAiIE9WRVJGTE9XIiA6ICIiLAotCQkJICh1 bmNvcnJlY3RlZF9lcnJvciAmJiByZWNvdmVyYWJsZSkgPyAiIHJlY292ZXJhYmxlIiA6ICIiLAot CQkJIG1zY29kLCBlcnJjb2RlLAotCQkJIHJlcy0+c29ja2V0LCByZXMtPmltYywgcmVzLT5yYW5r LAotCQkJIHJlcy0+YmFua19ncm91cCwgcmVzLT5iYW5rX2FkZHJlc3MsIHJlcy0+cm93LCByZXMt PmNvbHVtbik7Ci0JfQotCi0JZWRhY19kYmcoMCwgIiVzXG4iLCBza3hfbXNnKTsKLQotCS8qIENh bGwgdGhlIGhlbHBlciB0byBvdXRwdXQgbWVzc2FnZSAqLwotCWVkYWNfbWNfaGFuZGxlX2Vycm9y KHRwX2V2ZW50LCBtY2ksIGNvcmVfZXJyX2NudCwKLQkJCSAgICAgbS0+YWRkciA+PiBQQUdFX1NI SUZULCBtLT5hZGRyICYgflBBR0VfTUFTSywgMCwKLQkJCSAgICAgcmVzLT5jaGFubmVsLCByZXMt PmRpbW0sIC0xLAotCQkJICAgICBvcHR5cGUsIHNreF9tc2cpOwotfQotCi1pbnQgc2t4X21jZV9j aGVja19lcnJvcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm5iLCB1bnNpZ25lZCBsb25nIHZhbCwK LQkJCXZvaWQgKmRhdGEpCi17Ci0Jc3RydWN0IG1jZSAqbWNlID0gKHN0cnVjdCBtY2UgKilkYXRh OwotCXN0cnVjdCBkZWNvZGVkX2FkZHIgcmVzOwotCXN0cnVjdCBtZW1fY3RsX2luZm8gKm1jaTsK LQljaGFyICp0eXBlOwotCi0JaWYgKGVkYWNfZ2V0X3JlcG9ydF9zdGF0dXMoKSA9PSBFREFDX1JF UE9SVElOR19ESVNBQkxFRCkKLQkJcmV0dXJuIE5PVElGWV9ET05FOwotCi0JLyogaWdub3JlIHVu bGVzcyB0aGlzIGlzIG1lbW9yeSByZWxhdGVkIHdpdGggYW4gYWRkcmVzcyAqLwotCWlmICgobWNl LT5zdGF0dXMgJiAweGVmZmYpID4+IDcgIT0gMSB8fCAhKG1jZS0+c3RhdHVzICYgTUNJX1NUQVRV U19BRERSVikpCi0JCXJldHVybiBOT1RJRllfRE9ORTsKLQotCW1lbXNldCgmcmVzLCAwLCBzaXpl b2YocmVzKSk7Ci0JcmVzLmFkZHIgPSBtY2UtPmFkZHI7Ci0KLQlpZiAoYWR4bF9jb21wb25lbnRf Y291bnQpIHsKLQkJaWYgKCFza3hfYWR4bF9kZWNvZGUoJnJlcykpCi0JCQlyZXR1cm4gTk9USUZZ X0RPTkU7Ci0KLQkJbWNpID0gZ2V0X21jaShyZXMuc29ja2V0LCByZXMuaW1jKTsKLQl9IGVsc2Ug ewotCQlpZiAoIXNreF9kZWNvZGUgfHwgIXNreF9kZWNvZGUoJnJlcykpCi0JCQlyZXR1cm4gTk9U SUZZX0RPTkU7Ci0KLQkJbWNpID0gcmVzLmRldi0+aW1jW3Jlcy5pbWNdLm1jaTsKLQl9Ci0KLQlp ZiAoIW1jaSkKLQkJcmV0dXJuIE5PVElGWV9ET05FOwotCi0JaWYgKG1jZS0+bWNnc3RhdHVzICYg TUNHX1NUQVRVU19NQ0lQKQotCQl0eXBlID0gIkV4Y2VwdGlvbiI7Ci0JZWxzZQotCQl0eXBlID0g IkV2ZW50IjsKLQotCXNreF9tY19wcmludGsobWNpLCBLRVJOX0RFQlVHLCAiSEFORExJTkcgTUNF IE1FTU9SWSBFUlJPUlxuIik7Ci0KLQlza3hfbWNfcHJpbnRrKG1jaSwgS0VSTl9ERUJVRywgIkNQ VSAlZDogTWFjaGluZSBDaGVjayAlczogMHglbGx4ICIKLQkJCSAgICJCYW5rICVkOiAweCVsbHhc biIsIG1jZS0+ZXh0Y3B1LCB0eXBlLAotCQkJICAgbWNlLT5tY2dzdGF0dXMsIG1jZS0+YmFuaywg bWNlLT5zdGF0dXMpOwotCXNreF9tY19wcmludGsobWNpLCBLRVJOX0RFQlVHLCAiVFNDIDB4JWxs eCAiLCBtY2UtPnRzYyk7Ci0Jc2t4X21jX3ByaW50ayhtY2ksIEtFUk5fREVCVUcsICJBRERSIDB4 JWxseCAiLCBtY2UtPmFkZHIpOwotCXNreF9tY19wcmludGsobWNpLCBLRVJOX0RFQlVHLCAiTUlT QyAweCVsbHggIiwgbWNlLT5taXNjKTsKLQotCXNreF9tY19wcmludGsobWNpLCBLRVJOX0RFQlVH LCAiUFJPQ0VTU09SICV1OjB4JXggVElNRSAlbGx1IFNPQ0tFVCAiCi0JCQkgICAiJXUgQVBJQyAw eCV4XG4iLCBtY2UtPmNwdXZlbmRvciwgbWNlLT5jcHVpZCwKLQkJCSAgIG1jZS0+dGltZSwgbWNl LT5zb2NrZXRpZCwgbWNlLT5hcGljaWQpOwotCi0Jc2t4X21jZV9vdXRwdXRfZXJyb3IobWNpLCBt Y2UsICZyZXMpOwotCi0JcmV0dXJuIE5PVElGWV9ET05FOwotfQotCi12b2lkIHNreF9yZW1vdmUo dm9pZCkKLXsKLQlpbnQgaSwgajsKLQlzdHJ1Y3Qgc2t4X2RldiAqZCwgKnRtcDsKLQotCWVkYWNf ZGJnKDAsICJcbiIpOwotCi0JbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGQsIHRtcCwgJmRldl9l ZGFjX2xpc3QsIGxpc3QpIHsKLQkJbGlzdF9kZWwoJmQtPmxpc3QpOwotCQlmb3IgKGkgPSAwOyBp IDwgTlVNX0lNQzsgaSsrKSB7Ci0JCQlpZiAoZC0+aW1jW2ldLm1jaSkKLQkJCQlza3hfdW5yZWdp c3Rlcl9tY2koJmQtPmltY1tpXSk7Ci0KLQkJCWlmIChkLT5pbWNbaV0ubWRldikKLQkJCQlwY2lf ZGV2X3B1dChkLT5pbWNbaV0ubWRldik7Ci0KLQkJCWlmIChkLT5pbWNbaV0ubWJhc2UpCi0JCQkJ aW91bm1hcChkLT5pbWNbaV0ubWJhc2UpOwotCi0JCQlmb3IgKGogPSAwOyBqIDwgTlVNX0NIQU5O RUxTOyBqKyspIHsKLQkJCQlpZiAoZC0+aW1jW2ldLmNoYW5bal0uY2RldikKLQkJCQkJcGNpX2Rl dl9wdXQoZC0+aW1jW2ldLmNoYW5bal0uY2Rldik7Ci0JCQl9Ci0JCX0KLQkJaWYgKGQtPnV0aWxf YWxsKQotCQkJcGNpX2Rldl9wdXQoZC0+dXRpbF9hbGwpOwotCQlpZiAoZC0+c2FkX2FsbCkKLQkJ CXBjaV9kZXZfcHV0KGQtPnNhZF9hbGwpOwotCQlpZiAoZC0+dXJhY3UpCi0JCQlwY2lfZGV2X3B1 dChkLT51cmFjdSk7Ci0KLQkJa2ZyZWUoZCk7Ci0JfQotfQotCi0jaWZkZWYgQ09ORklHX0VEQUNf REVCVUcKLS8qCi0gKiBEZWJ1ZyBmZWF0dXJlLgotICogRXhlcmNpc2UgdGhlIGFkZHJlc3MgZGVj b2RlIGxvZ2ljIGJ5IHdyaXRpbmcgYW4gYWRkcmVzcyB0bwotICogL3N5cy9rZXJuZWwvZGVidWcv ZWRhYy9kaXJuYW1lL2FkZHIuCi0gKi8KLXN0YXRpYyBzdHJ1Y3QgZGVudHJ5ICpza3hfdGVzdDsK LQotc3RhdGljIGludCBkZWJ1Z2ZzX3U2NF9zZXQodm9pZCAqZGF0YSwgdTY0IHZhbCkKLXsKLQlz dHJ1Y3QgbWNlIG07Ci0KLQlwcl93YXJuX29uY2UoIkZha2UgZXJyb3IgdG8gMHglbGx4IGluamVj dGVkIHZpYSBkZWJ1Z2ZzXG4iLCB2YWwpOwotCi0JbWVtc2V0KCZtLCAwLCBzaXplb2YobSkpOwot CS8qIEFERFJWICsgTWVtUmQgKyBVbmtub3duIGNoYW5uZWwgKi8KLQltLnN0YXR1cyA9IE1DSV9T VEFUVVNfQUREUlYgKyAweDkwOwotCS8qIE9uZSBjb3JyZWN0ZWQgZXJyb3IgKi8KLQltLnN0YXR1 cyB8PSBCSVRfVUxMKE1DSV9TVEFUVVNfQ0VDX1NISUZUKTsKLQltLmFkZHIgPSB2YWw7Ci0Jc2t4 X21jZV9jaGVja19lcnJvcihOVUxMLCAwLCAmbSk7Ci0KLQlyZXR1cm4gMDsKLX0KLURFRklORV9T SU1QTEVfQVRUUklCVVRFKGZvcHNfdTY0X3dvLCBOVUxMLCBkZWJ1Z2ZzX3U2NF9zZXQsICIlbGx1 XG4iKTsKLQotdm9pZCBzZXR1cF9za3hfZGVidWcoY29uc3QgY2hhciAqZGlybmFtZSkKLXsKLQlz a3hfdGVzdCA9IGVkYWNfZGVidWdmc19jcmVhdGVfZGlyKGRpcm5hbWUpOwotCWlmICghc2t4X3Rl c3QpCi0JCXJldHVybjsKLQotCWlmICghZWRhY19kZWJ1Z2ZzX2NyZWF0ZV9maWxlKCJhZGRyIiwg MDIwMCwgc2t4X3Rlc3QsCi0JCQkJICAgICAgTlVMTCwgJmZvcHNfdTY0X3dvKSkgewotCQlkZWJ1 Z2ZzX3JlbW92ZShza3hfdGVzdCk7Ci0JCXNreF90ZXN0ID0gTlVMTDsKLQl9Ci19Ci0KLXZvaWQg dGVhcmRvd25fc2t4X2RlYnVnKHZvaWQpCi17Ci0JZGVidWdmc19yZW1vdmVfcmVjdXJzaXZlKHNr eF90ZXN0KTsKLX0KLSNlbmRpZiAvKkNPTkZJR19FREFDX0RFQlVHKi8KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZWRhYy9za3hfY29tbW9uLmggYi9kcml2ZXJzL2VkYWMvc2t4X2NvbW1vbi5oCmluZGV4 IGQyNTM3NGUzNGQ0Zi4uNmRhM2RlZjA5ZWExIDEwMDY0NAotLS0gYS9kcml2ZXJzL2VkYWMvc2t4 X2NvbW1vbi5oCisrKyBiL2RyaXZlcnMvZWRhYy9za3hfY29tbW9uLmgKQEAgLTksNiArOSwxMyBA QAogI2lmbmRlZiBfU0tYX0NPTU1fRURBQ19ICiAjZGVmaW5lIF9TS1hfQ09NTV9FREFDX0gKIAor I2luY2x1ZGUgPGxpbnV4L2FjcGkuaD4KKyNpbmNsdWRlIDxsaW51eC9kbWkuaD4KKyNpbmNsdWRl IDxsaW51eC9hZHhsLmg+CisjaW5jbHVkZSA8YWNwaS9uZml0Lmg+CisjaW5jbHVkZSA8YXNtL21j ZS5oPgorI2luY2x1ZGUgImVkYWNfbW9kdWxlLmgiCisKICNkZWZpbmUgTVNHX1NJWkUJCTEwMjQK IAogLyoKQEAgLTExMiw0MSArMTE5LDY3NyBAQCBzdHJ1Y3QgZGVjb2RlZF9hZGRyIHsKIH07CiAK IHR5cGVkZWYgaW50ICgqZ2V0X2RpbW1fY29uZmlnX2YpKHN0cnVjdCBtZW1fY3RsX2luZm8gKm1j aSk7Ci10eXBlZGVmIGJvb2wgKCpza3hfZGVjb2RlX2YpKHN0cnVjdCBkZWNvZGVkX2FkZHIgKnJl cyk7CiAKLWludCBfX2luaXQgc2t4X2FkeGxfZ2V0KHZvaWQpOwotdm9pZCBfX2V4aXQgc2t4X2Fk eGxfcHV0KHZvaWQpOwotdm9pZCBza3hfc2V0X2RlY29kZShza3hfZGVjb2RlX2YgZGVjb2RlKTsK K3N0YXRpYyBjb25zdCBjaGFyICogY29uc3QgY29tcG9uZW50X25hbWVzW10gPSB7CisJW0lOREVY X1NPQ0tFVF0JPSAiUHJvY2Vzc29yU29ja2V0SWQiLAorCVtJTkRFWF9NRU1DVFJMXQk9ICJNZW1v cnlDb250cm9sbGVySWQiLAorCVtJTkRFWF9DSEFOTkVMXQk9ICJDaGFubmVsSWQiLAorCVtJTkRF WF9ESU1NXQk9ICJEaW1tU2xvdElkIiwKK307CisKK3N0YXRpYyBpbnQgY29tcG9uZW50X2luZGlj ZXNbQVJSQVlfU0laRShjb21wb25lbnRfbmFtZXMpXTsKK3N0YXRpYyBpbnQgYWR4bF9jb21wb25l bnRfY291bnQ7CitzdGF0aWMgY29uc3QgY2hhciAqIGNvbnN0ICphZHhsX2NvbXBvbmVudF9uYW1l czsKK3N0YXRpYyB1NjQgKmFkeGxfdmFsdWVzOworc3RhdGljIGNoYXIgKmFkeGxfbXNnOworCitz dGF0aWMgY2hhciBza3hfbXNnW01TR19TSVpFXTsKK3N0YXRpYyB1NjQgc2t4X3RvbG0sIHNreF90 b2htOworc3RhdGljIExJU1RfSEVBRChkZXZfZWRhY19saXN0KTsKKworc3RhdGljIGludCBfX2lu aXQgc2t4X2FkeGxfZ2V0KHZvaWQpCit7CisJY29uc3QgY2hhciAqIGNvbnN0ICpuYW1lczsKKwlp bnQgaSwgajsKKworCW5hbWVzID0gYWR4bF9nZXRfY29tcG9uZW50X25hbWVzKCk7CisJaWYgKCFu YW1lcykgeworCQlza3hfcHJpbnRrKEtFUk5fTk9USUNFLCAiTm8gZmlybXdhcmUgc3VwcG9ydCBm b3IgYWRkcmVzcyB0cmFuc2xhdGlvbi5cbiIpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwlm b3IgKGkgPSAwOyBpIDwgSU5ERVhfTUFYOyBpKyspIHsKKwkJZm9yIChqID0gMDsgbmFtZXNbal07 IGorKykgeworCQkJaWYgKCFzdHJjbXAoY29tcG9uZW50X25hbWVzW2ldLCBuYW1lc1tqXSkpIHsK KwkJCQljb21wb25lbnRfaW5kaWNlc1tpXSA9IGo7CisJCQkJYnJlYWs7CisJCQl9CisJCX0KKwor CQlpZiAoIW5hbWVzW2pdKQorCQkJZ290byBlcnI7CisJfQorCisJYWR4bF9jb21wb25lbnRfbmFt ZXMgPSBuYW1lczsKKwl3aGlsZSAoKm5hbWVzKyspCisJCWFkeGxfY29tcG9uZW50X2NvdW50Kys7 CisKKwlhZHhsX3ZhbHVlcyA9IGtjYWxsb2MoYWR4bF9jb21wb25lbnRfY291bnQsIHNpemVvZigq YWR4bF92YWx1ZXMpLAorCQkJICAgICAgR0ZQX0tFUk5FTCk7CisJaWYgKCFhZHhsX3ZhbHVlcykg eworCQlhZHhsX2NvbXBvbmVudF9jb3VudCA9IDA7CisJCXJldHVybiAtRU5PTUVNOworCX0KKwor CWFkeGxfbXNnID0ga3phbGxvYyhNU0dfU0laRSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFhZHhsX21z ZykgeworCQlhZHhsX2NvbXBvbmVudF9jb3VudCA9IDA7CisJCWtmcmVlKGFkeGxfdmFsdWVzKTsK KwkJcmV0dXJuIC1FTk9NRU07CisJfQorCisJcmV0dXJuIDA7CitlcnI6CisJc2t4X3ByaW50ayhL RVJOX0VSUiwgIiclcycgaXMgbm90IG1hdGNoZWQgZnJvbSBEU00gcGFyYW1ldGVyczogIiwKKwkJ ICAgY29tcG9uZW50X25hbWVzW2ldKTsKKwlmb3IgKGogPSAwOyBuYW1lc1tqXTsgaisrKQorCQlz a3hfcHJpbnRrKEtFUk5fQ09OVCwgIiVzICIsIG5hbWVzW2pdKTsKKwlza3hfcHJpbnRrKEtFUk5f Q09OVCwgIlxuIik7CisKKwlyZXR1cm4gLUVOT0RFVjsKK30KKworc3RhdGljIHZvaWQgX19leGl0 IHNreF9hZHhsX3B1dCh2b2lkKQoreworCWtmcmVlKGFkeGxfdmFsdWVzKTsKKwlrZnJlZShhZHhs X21zZyk7Cit9CisKK3N0YXRpYyBib29sIHNreF9hZHhsX2RlY29kZShzdHJ1Y3QgZGVjb2RlZF9h ZGRyICpyZXMpCit7CisJaW50IGksIGxlbiA9IDA7CisKKwlpZiAocmVzLT5hZGRyID49IHNreF90 b2htIHx8IChyZXMtPmFkZHIgPj0gc2t4X3RvbG0gJiYKKwkJCQkgICAgICByZXMtPmFkZHIgPCBC SVRfVUxMKDMyKSkpIHsKKwkJZWRhY19kYmcoMCwgIkFkZHJlc3MgMHglbGx4IG91dCBvZiByYW5n ZVxuIiwgcmVzLT5hZGRyKTsKKwkJcmV0dXJuIGZhbHNlOworCX0KKworCWlmIChhZHhsX2RlY29k ZShyZXMtPmFkZHIsIGFkeGxfdmFsdWVzKSkgeworCQllZGFjX2RiZygwLCAiRmFpbGVkIHRvIGRl Y29kZSAweCVsbHhcbiIsIHJlcy0+YWRkcik7CisJCXJldHVybiBmYWxzZTsKKwl9CisKKwlyZXMt PnNvY2tldCAgPSAoaW50KWFkeGxfdmFsdWVzW2NvbXBvbmVudF9pbmRpY2VzW0lOREVYX1NPQ0tF VF1dOworCXJlcy0+aW1jICAgICA9IChpbnQpYWR4bF92YWx1ZXNbY29tcG9uZW50X2luZGljZXNb SU5ERVhfTUVNQ1RSTF1dOworCXJlcy0+Y2hhbm5lbCA9IChpbnQpYWR4bF92YWx1ZXNbY29tcG9u ZW50X2luZGljZXNbSU5ERVhfQ0hBTk5FTF1dOworCXJlcy0+ZGltbSAgICA9IChpbnQpYWR4bF92 YWx1ZXNbY29tcG9uZW50X2luZGljZXNbSU5ERVhfRElNTV1dOworCisJZm9yIChpID0gMDsgaSA8 IGFkeGxfY29tcG9uZW50X2NvdW50OyBpKyspIHsKKwkJaWYgKGFkeGxfdmFsdWVzW2ldID09IH4w eDB1bGwpCisJCQljb250aW51ZTsKKworCQlsZW4gKz0gc25wcmludGYoYWR4bF9tc2cgKyBsZW4s IE1TR19TSVpFIC0gbGVuLCAiICVzOjB4JWxseCIsCisJCQkJYWR4bF9jb21wb25lbnRfbmFtZXNb aV0sIGFkeGxfdmFsdWVzW2ldKTsKKwkJaWYgKE1TR19TSVpFIC0gbGVuIDw9IDApCisJCQlicmVh azsKKwl9CisKKwlyZXR1cm4gdHJ1ZTsKK30KKworc3RhdGljIGludCBza3hfZ2V0X3NyY19pZChz dHJ1Y3Qgc2t4X2RldiAqZCwgdTggKmlkKQoreworCXUzMiByZWc7CisKKwlpZiAocGNpX3JlYWRf Y29uZmlnX2R3b3JkKGQtPnV0aWxfYWxsLCAweGYwLCAmcmVnKSkgeworCQlza3hfcHJpbnRrKEtF Uk5fRVJSLCAiRmFpbGVkIHRvIHJlYWQgc3JjIGlkXG4iKTsKKwkJcmV0dXJuIC1FTk9ERVY7CisJ fQorCisJKmlkID0gR0VUX0JJVEZJRUxEKHJlZywgMTIsIDE0KTsKKwlyZXR1cm4gMDsKK30KKwor c3RhdGljIGludCBza3hfZ2V0X25vZGVfaWQoc3RydWN0IHNreF9kZXYgKmQsIHU4ICppZCkKK3sK Kwl1MzIgcmVnOworCisJaWYgKHBjaV9yZWFkX2NvbmZpZ19kd29yZChkLT51dGlsX2FsbCwgMHhm NCwgJnJlZykpIHsKKwkJc2t4X3ByaW50ayhLRVJOX0VSUiwgIkZhaWxlZCB0byByZWFkIG5vZGUg aWRcbiIpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwkqaWQgPSBHRVRfQklURklFTEQocmVn LCAwLCAyKTsKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBnZXRfd2lkdGgodTMyIG10cikK K3sKKwlzd2l0Y2ggKEdFVF9CSVRGSUVMRChtdHIsIDgsIDkpKSB7CisJY2FzZSAwOgorCQlyZXR1 cm4gREVWX1g0OworCWNhc2UgMToKKwkJcmV0dXJuIERFVl9YODsKKwljYXNlIDI6CisJCXJldHVy biBERVZfWDE2OworCX0KKwlyZXR1cm4gREVWX1VOS05PV047Cit9CisKKy8qCisgKiBXZSB1c2Ug dGhlIHBlci1zb2NrZXQgZGV2aWNlIEBkaWQgdG8gY291bnQgaG93IG1hbnkgc29ja2V0cyBhcmUg cHJlc2VudCwKKyAqIGFuZCB0byBkZXRlbWluZSB3aGljaCBQQ0kgYnVzZXMgYXJlIGFzc29jaWF0 ZWQgd2l0aCBlYWNoIHNvY2tldC4gQWxsb2NhdGUKKyAqIGFuZCBidWlsZCB0aGUgZnVsbCBsaXN0 IG9mIGFsbCB0aGUgc2t4X2RldiBzdHJ1Y3R1cmVzIHRoYXQgd2UgbmVlZCBoZXJlLgorICovCitz dGF0aWMgaW50IHNreF9nZXRfYWxsX2J1c19tYXBwaW5ncyh1bnNpZ25lZCBpbnQgZGlkLCBpbnQg b2ZmLCBlbnVtIHR5cGUgdHlwZSwKKwkJCSAgICAgc3RydWN0IGxpc3RfaGVhZCAqKmxpc3QpCit7 CisJc3RydWN0IHBjaV9kZXYgKnBkZXYsICpwcmV2OworCXN0cnVjdCBza3hfZGV2ICpkOworCXUz MiByZWc7CisJaW50IG5kZXYgPSAwOworCisJcHJldiA9IE5VTEw7CisJZm9yICg7OykgeworCQlw ZGV2ID0gcGNpX2dldF9kZXZpY2UoUENJX1ZFTkRPUl9JRF9JTlRFTCwgZGlkLCBwcmV2KTsKKwkJ aWYgKCFwZGV2KQorCQkJYnJlYWs7CisJCW5kZXYrKzsKKwkJZCA9IGt6YWxsb2Moc2l6ZW9mKCpk KSwgR0ZQX0tFUk5FTCk7CisJCWlmICghZCkgeworCQkJcGNpX2Rldl9wdXQocGRldik7CisJCQly ZXR1cm4gLUVOT01FTTsKKwkJfQorCisJCWlmIChwY2lfcmVhZF9jb25maWdfZHdvcmQocGRldiwg b2ZmLCAmcmVnKSkgeworCQkJa2ZyZWUoZCk7CisJCQlwY2lfZGV2X3B1dChwZGV2KTsKKwkJCXNr eF9wcmludGsoS0VSTl9FUlIsICJGYWlsZWQgdG8gcmVhZCBidXMgaWR4XG4iKTsKKwkJCXJldHVy biAtRU5PREVWOworCQl9CisKKwkJZC0+YnVzWzBdID0gR0VUX0JJVEZJRUxEKHJlZywgMCwgNyk7 CisJCWQtPmJ1c1sxXSA9IEdFVF9CSVRGSUVMRChyZWcsIDgsIDE1KTsKKwkJaWYgKHR5cGUgPT0g U0tYKSB7CisJCQlkLT5zZWcgPSBwY2lfZG9tYWluX25yKHBkZXYtPmJ1cyk7CisJCQlkLT5idXNb Ml0gPSBHRVRfQklURklFTEQocmVnLCAxNiwgMjMpOworCQkJZC0+YnVzWzNdID0gR0VUX0JJVEZJ RUxEKHJlZywgMjQsIDMxKTsKKwkJfSBlbHNlIHsKKwkJCWQtPnNlZyA9IEdFVF9CSVRGSUVMRChy ZWcsIDE2LCAyMyk7CisJCX0KKworCQllZGFjX2RiZygyLCAiYnVzc2VzOiAweCV4LCAweCV4LCAw eCV4LCAweCV4XG4iLAorCQkJIGQtPmJ1c1swXSwgZC0+YnVzWzFdLCBkLT5idXNbMl0sIGQtPmJ1 c1szXSk7CisJCWxpc3RfYWRkX3RhaWwoJmQtPmxpc3QsICZkZXZfZWRhY19saXN0KTsKKwkJcHJl diA9IHBkZXY7CisJfQorCisJaWYgKGxpc3QpCisJCSpsaXN0ID0gJmRldl9lZGFjX2xpc3Q7CisJ cmV0dXJuIG5kZXY7Cit9CisKK3N0YXRpYyBpbnQgc2t4X2dldF9oaV9sbyh1bnNpZ25lZCBpbnQg ZGlkLCBpbnQgb2ZmW10sIHU2NCAqdG9sbSwgdTY0ICp0b2htKQoreworCXN0cnVjdCBwY2lfZGV2 ICpwZGV2OworCXUzMiByZWc7CisKKwlwZGV2ID0gcGNpX2dldF9kZXZpY2UoUENJX1ZFTkRPUl9J RF9JTlRFTCwgZGlkLCBOVUxMKTsKKwlpZiAoIXBkZXYpIHsKKwkJc2t4X3ByaW50ayhLRVJOX0VS UiwgIkNhbid0IGdldCB0b2xtL3RvaG1cbiIpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwlp ZiAocGNpX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYsIG9mZlswXSwgJnJlZykpIHsKKwkJc2t4X3By aW50ayhLRVJOX0VSUiwgIkZhaWxlZCB0byByZWFkIHRvbG1cbiIpOworCQlnb3RvIGZhaWw7CisJ fQorCXNreF90b2xtID0gcmVnOworCisJaWYgKHBjaV9yZWFkX2NvbmZpZ19kd29yZChwZGV2LCBv ZmZbMV0sICZyZWcpKSB7CisJCXNreF9wcmludGsoS0VSTl9FUlIsICJGYWlsZWQgdG8gcmVhZCBs b3dlciB0b2htXG4iKTsKKwkJZ290byBmYWlsOworCX0KKwlza3hfdG9obSA9IHJlZzsKKworCWlm IChwY2lfcmVhZF9jb25maWdfZHdvcmQocGRldiwgb2ZmWzJdLCAmcmVnKSkgeworCQlza3hfcHJp bnRrKEtFUk5fRVJSLCAiRmFpbGVkIHRvIHJlYWQgdXBwZXIgdG9obVxuIik7CisJCWdvdG8gZmFp bDsKKwl9CisJc2t4X3RvaG0gfD0gKHU2NClyZWcgPDwgMzI7CisKKwlwY2lfZGV2X3B1dChwZGV2 KTsKKwkqdG9sbSA9IHNreF90b2xtOworCSp0b2htID0gc2t4X3RvaG07CisJZWRhY19kYmcoMiwg InRvbG0gPSAweCVsbHggdG9obSA9IDB4JWxseFxuIiwgc2t4X3RvbG0sIHNreF90b2htKTsKKwly ZXR1cm4gMDsKK2ZhaWw6CisJcGNpX2Rldl9wdXQocGRldik7CisJcmV0dXJuIC1FTk9ERVY7Cit9 CisKK3N0YXRpYyBpbnQgc2t4X2dldF9kaW1tX2F0dHIodTMyIHJlZywgaW50IGxvYml0LCBpbnQg aGliaXQsIGludCBhZGQsCisJCQkgICAgIGludCBtaW52YWwsIGludCBtYXh2YWwsIGNvbnN0IGNo YXIgKm5hbWUpCit7CisJdTMyIHZhbCA9IEdFVF9CSVRGSUVMRChyZWcsIGxvYml0LCBoaWJpdCk7 CisKKwlpZiAodmFsIDwgbWludmFsIHx8IHZhbCA+IG1heHZhbCkgeworCQllZGFjX2RiZygyLCAi YmFkICVzID0gJWQgKHJhdz0weCV4KVxuIiwgbmFtZSwgdmFsLCByZWcpOworCQlyZXR1cm4gLUVJ TlZBTDsKKwl9CisJcmV0dXJuIHZhbCArIGFkZDsKK30KKworI2RlZmluZSBudW1yYW5rKHJlZykJ c2t4X2dldF9kaW1tX2F0dHIocmVnLCAxMiwgMTMsIDAsIDAsIDIsICJyYW5rcyIpCisjZGVmaW5l IG51bXJvdyhyZWcpCXNreF9nZXRfZGltbV9hdHRyKHJlZywgMiwgNCwgMTIsIDEsIDYsICJyb3dz IikKKyNkZWZpbmUgbnVtY29sKHJlZykJc2t4X2dldF9kaW1tX2F0dHIocmVnLCAwLCAxLCAxMCwg MCwgMiwgImNvbHMiKQorCitzdGF0aWMgaW50IHNreF9nZXRfZGltbV9pbmZvKHUzMiBtdHIsIHUz MiBhbWFwLCBzdHJ1Y3QgZGltbV9pbmZvICpkaW1tLAorCQkgICAgICBzdHJ1Y3Qgc2t4X2ltYyAq aW1jLCBpbnQgY2hhbiwgaW50IGRpbW1ubykKK3sKKwlpbnQgIGJhbmtzID0gMTYsIHJhbmtzLCBy b3dzLCBjb2xzLCBucGFnZXM7CisJdTY0IHNpemU7CisKKwlyYW5rcyA9IG51bXJhbmsobXRyKTsK Kwlyb3dzID0gbnVtcm93KG10cik7CisJY29scyA9IG51bWNvbChtdHIpOworCisJLyoKKwkgKiBD b21wdXRlIHNpemUgaW4gOC1ieXRlICgyXjMpIHdvcmRzLCB0aGVuIHNoaWZ0IHRvIE1pQiAoMl4y MCkKKwkgKi8KKwlzaXplID0gKCgxdWxsIDw8IChyb3dzICsgY29scyArIHJhbmtzKSkgKiBiYW5r cykgPj4gKDIwIC0gMyk7CisJbnBhZ2VzID0gTWlCX1RPX1BBR0VTKHNpemUpOworCisJZWRhY19k YmcoMCwgIm1jIyVkOiBjaGFubmVsICVkLCBkaW1tICVkLCAlbGxkIE1pQiAoJWQgcGFnZXMpIGJh bms6ICVkLCByYW5rOiAlZCwgcm93OiAweCV4LCBjb2w6IDB4JXhcbiIsCisJCSBpbWMtPm1jLCBj aGFuLCBkaW1tbm8sIHNpemUsIG5wYWdlcywKKwkJIGJhbmtzLCAxIDw8IHJhbmtzLCByb3dzLCBj b2xzKTsKKworCWltYy0+Y2hhbltjaGFuXS5kaW1tc1tkaW1tbm9dLmNsb3NlX3BnID0gR0VUX0JJ VEZJRUxEKG10ciwgMCwgMCk7CisJaW1jLT5jaGFuW2NoYW5dLmRpbW1zW2RpbW1ub10uYmFua194 b3JfZW5hYmxlID0gR0VUX0JJVEZJRUxEKG10ciwgOSwgOSk7CisJaW1jLT5jaGFuW2NoYW5dLmRp bW1zW2RpbW1ub10uZmluZV9ncmFpbl9iYW5rID0gR0VUX0JJVEZJRUxEKGFtYXAsIDAsIDApOwor CWltYy0+Y2hhbltjaGFuXS5kaW1tc1tkaW1tbm9dLnJvd2JpdHMgPSByb3dzOworCWltYy0+Y2hh bltjaGFuXS5kaW1tc1tkaW1tbm9dLmNvbGJpdHMgPSBjb2xzOworCisJZGltbS0+bnJfcGFnZXMg PSBucGFnZXM7CisJZGltbS0+Z3JhaW4gPSAzMjsKKwlkaW1tLT5kdHlwZSA9IGdldF93aWR0aCht dHIpOworCWRpbW0tPm10eXBlID0gTUVNX0REUjQ7CisJZGltbS0+ZWRhY19tb2RlID0gRURBQ19T RUNERUQ7IC8qIGxpa2VseSBiZXR0ZXIgdGhhbiB0aGlzICovCisJc25wcmludGYoZGltbS0+bGFi ZWwsIHNpemVvZihkaW1tLT5sYWJlbCksICJDUFVfU3JjSUQjJXVfTUMjJXVfQ2hhbiMldV9ESU1N IyV1IiwKKwkJIGltYy0+c3JjX2lkLCBpbWMtPmxtYywgY2hhbiwgZGltbW5vKTsKKworCXJldHVy biAxOworfQorCitzdGF0aWMgaW50IHNreF9nZXRfbnZkaW1tX2luZm8oc3RydWN0IGRpbW1faW5m byAqZGltbSwgc3RydWN0IHNreF9pbWMgKmltYywKKwkJCWludCBjaGFuLCBpbnQgZGltbW5vLCBj b25zdCBjaGFyICptb2Rfc3RyKQoreworCWludCBzbWJpb3NfaGFuZGxlOworCXUzMiBkZXZfaGFu ZGxlOworCXUxNiBmbGFnczsKKwl1NjQgc2l6ZSA9IDA7CisKKwlkZXZfaGFuZGxlID0gQUNQSV9O RklUX0JVSUxEX0RFVklDRV9IQU5ETEUoZGltbW5vLCBjaGFuLCBpbWMtPmxtYywKKwkJCQkJCSAg IGltYy0+c3JjX2lkLCAwKTsKKworCXNtYmlvc19oYW5kbGUgPSBuZml0X2dldF9zbWJpb3NfaWQo ZGV2X2hhbmRsZSwgJmZsYWdzKTsKKwlpZiAoc21iaW9zX2hhbmRsZSA9PSAtRU9QTk9UU1VQUCkg eworCQlwcl93YXJuX29uY2UoIiVzOiBDYW4ndCBmaW5kIHNpemUgb2YgTlZESU1NLiBUcnkgZW5h YmxpbmcgQ09ORklHX0FDUElfTkZJVFxuIiwgbW9kX3N0cik7CisJCWdvdG8gdW5rbm93bl9zaXpl OworCX0KKworCWlmIChzbWJpb3NfaGFuZGxlIDwgMCkgeworCQlza3hfcHJpbnRrKEtFUk5fRVJS LCAiQ2FuJ3QgZmluZCBoYW5kbGUgZm9yIE5WRElNTSBBRFI9MHgleFxuIiwgZGV2X2hhbmRsZSk7 CisJCWdvdG8gdW5rbm93bl9zaXplOworCX0KIAotaW50IHNreF9nZXRfc3JjX2lkKHN0cnVjdCBz a3hfZGV2ICpkLCB1OCAqaWQpOwotaW50IHNreF9nZXRfbm9kZV9pZChzdHJ1Y3Qgc2t4X2RldiAq ZCwgdTggKmlkKTsKKwlpZiAoZmxhZ3MgJiBBQ1BJX05GSVRfTUVNX01BUF9GQUlMRUQpIHsKKwkJ c2t4X3ByaW50ayhLRVJOX0VSUiwgIk5WRElNTSBBRFI9MHgleCBpcyBub3QgbWFwcGVkXG4iLCBk ZXZfaGFuZGxlKTsKKwkJZ290byB1bmtub3duX3NpemU7CisJfQogCi1pbnQgc2t4X2dldF9hbGxf YnVzX21hcHBpbmdzKHVuc2lnbmVkIGludCBkaWQsIGludCBvZmYsIGVudW0gdHlwZSwKLQkJCSAg ICAgc3RydWN0IGxpc3RfaGVhZCAqKmxpc3QpOworCXNpemUgPSBkbWlfbWVtZGV2X3NpemUoc21i aW9zX2hhbmRsZSk7CisJaWYgKHNpemUgPT0gfjB1bGwpCisJCXNreF9wcmludGsoS0VSTl9FUlIs ICJDYW4ndCBmaW5kIHNpemUgZm9yIE5WRElNTSBBRFI9MHgleC9TTUJJT1M9MHgleFxuIiwKKwkJ CSAgIGRldl9oYW5kbGUsIHNtYmlvc19oYW5kbGUpOwogCi1pbnQgc2t4X2dldF9oaV9sbyh1bnNp Z25lZCBpbnQgZGlkLCBpbnQgb2ZmW10sIHU2NCAqdG9sbSwgdTY0ICp0b2htKTsKK3Vua25vd25f c2l6ZToKKwlkaW1tLT5ucl9wYWdlcyA9IHNpemUgPj4gUEFHRV9TSElGVDsKKwlkaW1tLT5ncmFp biA9IDMyOworCWRpbW0tPmR0eXBlID0gREVWX1VOS05PV047CisJZGltbS0+bXR5cGUgPSBNRU1f TlZESU1NOworCWRpbW0tPmVkYWNfbW9kZSA9IEVEQUNfU0VDREVEOyAvKiBsaWtlbHkgYmV0dGVy IHRoYW4gdGhpcyAqLwogCi1pbnQgc2t4X2dldF9kaW1tX2luZm8odTMyIG10ciwgdTMyIGFtYXAs IHN0cnVjdCBkaW1tX2luZm8gKmRpbW0sCi0JCSAgICAgIHN0cnVjdCBza3hfaW1jICppbWMsIGlu dCBjaGFuLCBpbnQgZGltbW5vKTsKKwllZGFjX2RiZygwLCAibWMjJWQ6IGNoYW5uZWwgJWQsIGRp bW0gJWQsICVsbHUgTWlCICgldSBwYWdlcylcbiIsCisJCSBpbWMtPm1jLCBjaGFuLCBkaW1tbm8s IHNpemUgPj4gMjAsIGRpbW0tPm5yX3BhZ2VzKTsKIAotaW50IHNreF9nZXRfbnZkaW1tX2luZm8o c3RydWN0IGRpbW1faW5mbyAqZGltbSwgc3RydWN0IHNreF9pbWMgKmltYywKLQkJCWludCBjaGFu LCBpbnQgZGltbW5vLCBjb25zdCBjaGFyICptb2Rfc3RyKTsKKwlzbnByaW50ZihkaW1tLT5sYWJl bCwgc2l6ZW9mKGRpbW0tPmxhYmVsKSwgIkNQVV9TcmNJRCMldV9NQyMldV9DaGFuIyV1X0RJTU0j JXUiLAorCQkgaW1jLT5zcmNfaWQsIGltYy0+bG1jLCBjaGFuLCBkaW1tbm8pOwogCi1pbnQgc2t4 X3JlZ2lzdGVyX21jaShzdHJ1Y3Qgc2t4X2ltYyAqaW1jLCBzdHJ1Y3QgcGNpX2RldiAqcGRldiwK KwlyZXR1cm4gKHNpemUgPT0gMCB8fCBzaXplID09IH4wdWxsKSA/IDAgOiAxOworfQorCitzdGF0 aWMgaW50IHNreF9yZWdpc3Rlcl9tY2koc3RydWN0IHNreF9pbWMgKmltYywgc3RydWN0IHBjaV9k ZXYgKnBkZXYsCiAJCSAgICAgY29uc3QgY2hhciAqY3RsX25hbWUsIGNvbnN0IGNoYXIgKm1vZF9z dHIsCi0JCSAgICAgZ2V0X2RpbW1fY29uZmlnX2YgZ2V0X2RpbW1fY29uZmlnKTsKKwkJICAgICBn ZXRfZGltbV9jb25maWdfZiBnZXRfZGltbV9jb25maWcpCit7CisJc3RydWN0IG1lbV9jdGxfaW5m byAqbWNpOworCXN0cnVjdCBlZGFjX21jX2xheWVyIGxheWVyc1syXTsKKwlzdHJ1Y3Qgc2t4X3B2 dCAqcHZ0OworCWludCByYzsKKworCS8qIEFsbG9jYXRlIGEgbmV3IE1DIGNvbnRyb2wgc3RydWN0 dXJlICovCisJbGF5ZXJzWzBdLnR5cGUgPSBFREFDX01DX0xBWUVSX0NIQU5ORUw7CisJbGF5ZXJz WzBdLnNpemUgPSBOVU1fQ0hBTk5FTFM7CisJbGF5ZXJzWzBdLmlzX3ZpcnRfY3Nyb3cgPSBmYWxz ZTsKKwlsYXllcnNbMV0udHlwZSA9IEVEQUNfTUNfTEFZRVJfU0xPVDsKKwlsYXllcnNbMV0uc2l6 ZSA9IE5VTV9ESU1NUzsKKwlsYXllcnNbMV0uaXNfdmlydF9jc3JvdyA9IHRydWU7CisJbWNpID0g ZWRhY19tY19hbGxvYyhpbWMtPm1jLCBBUlJBWV9TSVpFKGxheWVycyksIGxheWVycywKKwkJCSAg ICBzaXplb2Yoc3RydWN0IHNreF9wdnQpKTsKKworCWlmICh1bmxpa2VseSghbWNpKSkKKwkJcmV0 dXJuIC1FTk9NRU07CisKKwllZGFjX2RiZygwLCAiTUMjJWQ6IG1jaSA9ICVwXG4iLCBpbWMtPm1j LCBtY2kpOworCisJLyogQXNzb2NpYXRlIHNreF9kZXYgYW5kIG1jaSBmb3IgZnV0dXJlIHVzYWdl ICovCisJaW1jLT5tY2kgPSBtY2k7CisJcHZ0ID0gbWNpLT5wdnRfaW5mbzsKKwlwdnQtPmltYyA9 IGltYzsKKworCW1jaS0+Y3RsX25hbWUgPSBrYXNwcmludGYoR0ZQX0tFUk5FTCwgIiVzIyVkIElN QyMlZCIsIGN0bF9uYW1lLAorCQkJCSAgaW1jLT5ub2RlX2lkLCBpbWMtPmxtYyk7CisJaWYgKCFt Y2ktPmN0bF9uYW1lKSB7CisJCXJjID0gLUVOT01FTTsKKwkJZ290byBmYWlsMDsKKwl9CisKKwlt Y2ktPm10eXBlX2NhcCA9IE1FTV9GTEFHX0REUjQgfCBNRU1fRkxBR19OVkRJTU07CisJbWNpLT5l ZGFjX2N0bF9jYXAgPSBFREFDX0ZMQUdfTk9ORTsKKwltY2ktPmVkYWNfY2FwID0gRURBQ19GTEFH X05PTkU7CisJbWNpLT5tb2RfbmFtZSA9IG1vZF9zdHI7CisJbWNpLT5kZXZfbmFtZSA9IHBjaV9u YW1lKHBkZXYpOworCW1jaS0+Y3RsX3BhZ2VfdG9fcGh5cyA9IE5VTEw7CisKKwlyYyA9IGdldF9k aW1tX2NvbmZpZyhtY2kpOworCWlmIChyYyA8IDApCisJCWdvdG8gZmFpbDsKKworCS8qIFJlY29y ZCBwdHIgdG8gdGhlIGdlbmVyaWMgZGV2aWNlICovCisJbWNpLT5wZGV2ID0gJnBkZXYtPmRldjsK KworCS8qIEFkZCB0aGlzIG5ldyBNQyBjb250cm9sIHN0cnVjdHVyZSB0byBFREFDJ3MgbGlzdCBv ZiBNQ3MgKi8KKwlpZiAodW5saWtlbHkoZWRhY19tY19hZGRfbWMobWNpKSkpIHsKKwkJZWRhY19k YmcoMCwgIk1DOiBmYWlsZWQgZWRhY19tY19hZGRfbWMoKVxuIik7CisJCXJjID0gLUVJTlZBTDsK KwkJZ290byBmYWlsOworCX0KKworCXJldHVybiAwOworCitmYWlsOgorCWtmcmVlKG1jaS0+Y3Rs X25hbWUpOworZmFpbDA6CisJZWRhY19tY19mcmVlKG1jaSk7CisJaW1jLT5tY2kgPSBOVUxMOwor CXJldHVybiByYzsKK30KKworc3RhdGljIHZvaWQgc2t4X3VucmVnaXN0ZXJfbWNpKHN0cnVjdCBz a3hfaW1jICppbWMpCit7CisJc3RydWN0IG1lbV9jdGxfaW5mbyAqbWNpID0gaW1jLT5tY2k7CisK KwlpZiAoIW1jaSkKKwkJcmV0dXJuOworCisJZWRhY19kYmcoMCwgIk1DJWQ6IG1jaSA9ICVwXG4i LCBpbWMtPm1jLCBtY2kpOworCisJLyogUmVtb3ZlIE1DIHN5c2ZzIG5vZGVzICovCisJZWRhY19t Y19kZWxfbWMobWNpLT5wZGV2KTsKKworCWVkYWNfZGJnKDEsICIlczogZnJlZSBtY2kgc3RydWN0 XG4iLCBtY2ktPmN0bF9uYW1lKTsKKwlrZnJlZShtY2ktPmN0bF9uYW1lKTsKKwllZGFjX21jX2Zy ZWUobWNpKTsKK30KKworc3RhdGljIHN0cnVjdCBtZW1fY3RsX2luZm8gKmdldF9tY2koaW50IHNy Y19pZCwgaW50IGxtYykKK3sKKwlzdHJ1Y3Qgc2t4X2RldiAqZDsKKworCWlmIChsbWMgPiBOVU1f SU1DIC0gMSkgeworCQlza3hfcHJpbnRrKEtFUk5fRVJSLCAiQmFkIGxtYyAlZFxuIiwgbG1jKTsK KwkJcmV0dXJuIE5VTEw7CisJfQorCisJbGlzdF9mb3JfZWFjaF9lbnRyeShkLCAmZGV2X2VkYWNf bGlzdCwgbGlzdCkgeworCQlpZiAoZC0+aW1jWzBdLnNyY19pZCA9PSBzcmNfaWQpCisJCQlyZXR1 cm4gZC0+aW1jW2xtY10ubWNpOworCX0KKworCXNreF9wcmludGsoS0VSTl9FUlIsICJObyBtY2kg Zm9yIHNyY19pZCAlZCBsbWMgJWRcbiIsIHNyY19pZCwgbG1jKTsKKwlyZXR1cm4gTlVMTDsKK30K Kworc3RhdGljIHZvaWQgc2t4X21jZV9vdXRwdXRfZXJyb3Ioc3RydWN0IG1lbV9jdGxfaW5mbyAq bWNpLAorCQkJCSBjb25zdCBzdHJ1Y3QgbWNlICptLAorCQkJCSBzdHJ1Y3QgZGVjb2RlZF9hZGRy ICpyZXMpCit7CisJZW51bSBod19ldmVudF9tY19lcnJfdHlwZSB0cF9ldmVudDsKKwljaGFyICp0 eXBlLCAqb3B0eXBlOworCWJvb2wgcmlwdiA9IEdFVF9CSVRGSUVMRChtLT5tY2dzdGF0dXMsIDAs IDApOworCWJvb2wgb3ZlcmZsb3cgPSBHRVRfQklURklFTEQobS0+c3RhdHVzLCA2MiwgNjIpOwor CWJvb2wgdW5jb3JyZWN0ZWRfZXJyb3IgPSBHRVRfQklURklFTEQobS0+c3RhdHVzLCA2MSwgNjEp OworCWJvb2wgcmVjb3ZlcmFibGU7CisJdTMyIGNvcmVfZXJyX2NudCA9IEdFVF9CSVRGSUVMRCht LT5zdGF0dXMsIDM4LCA1Mik7CisJdTMyIG1zY29kID0gR0VUX0JJVEZJRUxEKG0tPnN0YXR1cywg MTYsIDMxKTsKKwl1MzIgZXJyY29kZSA9IEdFVF9CSVRGSUVMRChtLT5zdGF0dXMsIDAsIDE1KTsK Kwl1MzIgb3B0eXBlbnVtID0gR0VUX0JJVEZJRUxEKG0tPnN0YXR1cywgNCwgNik7CisKKwlyZWNv dmVyYWJsZSA9IEdFVF9CSVRGSUVMRChtLT5zdGF0dXMsIDU2LCA1Nik7CisKKwlpZiAodW5jb3Jy ZWN0ZWRfZXJyb3IpIHsKKwkJY29yZV9lcnJfY250ID0gMTsKKwkJaWYgKHJpcHYpIHsKKwkJCXR5 cGUgPSAiRkFUQUwiOworCQkJdHBfZXZlbnQgPSBIV19FVkVOVF9FUlJfRkFUQUw7CisJCX0gZWxz ZSB7CisJCQl0eXBlID0gIk5PTl9GQVRBTCI7CisJCQl0cF9ldmVudCA9IEhXX0VWRU5UX0VSUl9V TkNPUlJFQ1RFRDsKKwkJfQorCX0gZWxzZSB7CisJCXR5cGUgPSAiQ09SUkVDVEVEIjsKKwkJdHBf ZXZlbnQgPSBIV19FVkVOVF9FUlJfQ09SUkVDVEVEOworCX0KKworCS8qCisJICogQWNjb3JkaW5n IHRvIEludGVsIEFyY2hpdGVjdHVyZSBzcGVjIHZvbCAzQiwKKwkgKiBUYWJsZSAxNS0xMCAiSUEz Ml9NQ2lfU3RhdHVzIFsxNTowXSBDb21wb3VuZCBFcnJvciBDb2RlIEVuY29kaW5nIgorCSAqIG1l bW9yeSBlcnJvcnMgc2hvdWxkIGZpdCBvbmUgb2YgdGhlc2UgbWFza3M6CisJICoJMDAwZiAwMDAw IDFtbW0gY2NjYyAoYmluYXJ5KQorCSAqCTAwMGYgMDAxMCAxbW1tIGNjY2MgKGJpbmFyeSkJW1JB TSB1c2VkIGFzIGNhY2hlXQorCSAqIHdoZXJlOgorCSAqCWYgPSBDb3JyZWN0aW9uIFJlcG9ydCBG aWx0ZXJpbmcgQml0LiBJZiAxLCBzdWJzZXF1ZW50IGVycm9ycworCSAqCSAgICB3b24ndCBiZSBz aG93bgorCSAqCW1tbSA9IGVycm9yIHR5cGUKKwkgKgljY2NjID0gY2hhbm5lbAorCSAqIElmIHRo ZSBtYXNrIGRvZXNuJ3QgbWF0Y2gsIHJlcG9ydCBhbiBlcnJvciB0byB0aGUgcGFyc2luZyBsb2dp YworCSAqLworCWlmICghKChlcnJjb2RlICYgMHhlZjgwKSA9PSAweDgwIHx8IChlcnJjb2RlICYg MHhlZjgwKSA9PSAweDI4MCkpIHsKKwkJb3B0eXBlID0gIkNhbid0IHBhcnNlOiBpdCBpcyBub3Qg YSBtZW0iOworCX0gZWxzZSB7CisJCXN3aXRjaCAob3B0eXBlbnVtKSB7CisJCWNhc2UgMDoKKwkJ CW9wdHlwZSA9ICJnZW5lcmljIHVuZGVmIHJlcXVlc3QgZXJyb3IiOworCQkJYnJlYWs7CisJCWNh c2UgMToKKwkJCW9wdHlwZSA9ICJtZW1vcnkgcmVhZCBlcnJvciI7CisJCQlicmVhazsKKwkJY2Fz ZSAyOgorCQkJb3B0eXBlID0gIm1lbW9yeSB3cml0ZSBlcnJvciI7CisJCQlicmVhazsKKwkJY2Fz ZSAzOgorCQkJb3B0eXBlID0gImFkZHIvY21kIGVycm9yIjsKKwkJCWJyZWFrOworCQljYXNlIDQ6 CisJCQlvcHR5cGUgPSAibWVtb3J5IHNjcnViYmluZyBlcnJvciI7CisJCQlicmVhazsKKwkJZGVm YXVsdDoKKwkJCW9wdHlwZSA9ICJyZXNlcnZlZCI7CisJCQlicmVhazsKKwkJfQorCX0KKwlpZiAo YWR4bF9jb21wb25lbnRfY291bnQpIHsKKwkJc25wcmludGYoc2t4X21zZywgTVNHX1NJWkUsICIl cyVzIGVycl9jb2RlOjB4JTA0eDoweCUwNHggJXMiLAorCQkJIG92ZXJmbG93ID8gIiBPVkVSRkxP VyIgOiAiIiwKKwkJCSAodW5jb3JyZWN0ZWRfZXJyb3IgJiYgcmVjb3ZlcmFibGUpID8gIiByZWNv dmVyYWJsZSIgOiAiIiwKKwkJCSBtc2NvZCwgZXJyY29kZSwgYWR4bF9tc2cpOworCX0gZWxzZSB7 CisJCXNucHJpbnRmKHNreF9tc2csIE1TR19TSVpFLAorCQkJICIlcyVzIGVycl9jb2RlOjB4JTA0 eDoweCUwNHggc29ja2V0OiVkIGltYzolZCByYW5rOiVkIGJnOiVkIGJhOiVkIHJvdzoweCV4IGNv bDoweCV4IiwKKwkJCSBvdmVyZmxvdyA/ICIgT1ZFUkZMT1ciIDogIiIsCisJCQkgKHVuY29ycmVj dGVkX2Vycm9yICYmIHJlY292ZXJhYmxlKSA/ICIgcmVjb3ZlcmFibGUiIDogIiIsCisJCQkgbXNj b2QsIGVycmNvZGUsCisJCQkgcmVzLT5zb2NrZXQsIHJlcy0+aW1jLCByZXMtPnJhbmssCisJCQkg cmVzLT5iYW5rX2dyb3VwLCByZXMtPmJhbmtfYWRkcmVzcywgcmVzLT5yb3csIHJlcy0+Y29sdW1u KTsKKwl9CisKKwllZGFjX2RiZygwLCAiJXNcbiIsIHNreF9tc2cpOworCisJLyogQ2FsbCB0aGUg aGVscGVyIHRvIG91dHB1dCBtZXNzYWdlICovCisJZWRhY19tY19oYW5kbGVfZXJyb3IodHBfZXZl bnQsIG1jaSwgY29yZV9lcnJfY250LAorCQkJICAgICBtLT5hZGRyID4+IFBBR0VfU0hJRlQsIG0t PmFkZHIgJiB+UEFHRV9NQVNLLCAwLAorCQkJICAgICByZXMtPmNoYW5uZWwsIHJlcy0+ZGltbSwg LTEsCisJCQkgICAgIG9wdHlwZSwgc2t4X21zZyk7Cit9CisKK3N0YXRpYyBpbnQgc2t4X21jZV9j aGVja19lcnJvcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm5iLCB1bnNpZ25lZCBsb25nIHZhbCwK KwkJCXZvaWQgKmRhdGEpCit7CisJc3RydWN0IG1jZSAqbWNlID0gKHN0cnVjdCBtY2UgKilkYXRh OworCXN0cnVjdCBkZWNvZGVkX2FkZHIgcmVzOworCXN0cnVjdCBtZW1fY3RsX2luZm8gKm1jaTsK KwljaGFyICp0eXBlOwogCi1pbnQgc2t4X21jZV9jaGVja19lcnJvcihzdHJ1Y3Qgbm90aWZpZXJf YmxvY2sgKm5iLCB1bnNpZ25lZCBsb25nIHZhbCwKLQkJCXZvaWQgKmRhdGEpOworCWlmIChlZGFj X2dldF9yZXBvcnRfc3RhdHVzKCkgPT0gRURBQ19SRVBPUlRJTkdfRElTQUJMRUQpCisJCXJldHVy biBOT1RJRllfRE9ORTsKIAotdm9pZCBza3hfcmVtb3ZlKHZvaWQpOworCS8qIGlnbm9yZSB1bmxl c3MgdGhpcyBpcyBtZW1vcnkgcmVsYXRlZCB3aXRoIGFuIGFkZHJlc3MgKi8KKwlpZiAoKG1jZS0+ c3RhdHVzICYgMHhlZmZmKSA+PiA3ICE9IDEgfHwgIShtY2UtPnN0YXR1cyAmIE1DSV9TVEFUVVNf QUREUlYpKQorCQlyZXR1cm4gTk9USUZZX0RPTkU7CisKKwltZW1zZXQoJnJlcywgMCwgc2l6ZW9m KHJlcykpOworCXJlcy5hZGRyID0gbWNlLT5hZGRyOworCisJaWYgKGFkeGxfY29tcG9uZW50X2Nv dW50KSB7CisJCWlmICghc2t4X2FkeGxfZGVjb2RlKCZyZXMpKQorCQkJcmV0dXJuIE5PVElGWV9E T05FOworCisJCW1jaSA9IGdldF9tY2kocmVzLnNvY2tldCwgcmVzLmltYyk7CisJfSBlbHNlIHsK KwkJaWYgKCFza3hfZGVjb2RlIHx8ICFza3hfZGVjb2RlKCZyZXMpKQorCQkJcmV0dXJuIE5PVElG WV9ET05FOworCisJCW1jaSA9IHJlcy5kZXYtPmltY1tyZXMuaW1jXS5tY2k7CisJfQorCisJaWYg KCFtY2kpCisJCXJldHVybiBOT1RJRllfRE9ORTsKKworCWlmIChtY2UtPm1jZ3N0YXR1cyAmIE1D R19TVEFUVVNfTUNJUCkKKwkJdHlwZSA9ICJFeGNlcHRpb24iOworCWVsc2UKKwkJdHlwZSA9ICJF dmVudCI7CisKKwlza3hfbWNfcHJpbnRrKG1jaSwgS0VSTl9ERUJVRywgIkhBTkRMSU5HIE1DRSBN RU1PUlkgRVJST1JcbiIpOworCisJc2t4X21jX3ByaW50ayhtY2ksIEtFUk5fREVCVUcsICJDUFUg JWQ6IE1hY2hpbmUgQ2hlY2sgJXM6IDB4JWxseCAiCisJCQkgICAiQmFuayAlZDogMHglbGx4XG4i LCBtY2UtPmV4dGNwdSwgdHlwZSwKKwkJCSAgIG1jZS0+bWNnc3RhdHVzLCBtY2UtPmJhbmssIG1j ZS0+c3RhdHVzKTsKKwlza3hfbWNfcHJpbnRrKG1jaSwgS0VSTl9ERUJVRywgIlRTQyAweCVsbHgg IiwgbWNlLT50c2MpOworCXNreF9tY19wcmludGsobWNpLCBLRVJOX0RFQlVHLCAiQUREUiAweCVs bHggIiwgbWNlLT5hZGRyKTsKKwlza3hfbWNfcHJpbnRrKG1jaSwgS0VSTl9ERUJVRywgIk1JU0Mg MHglbGx4ICIsIG1jZS0+bWlzYyk7CisKKwlza3hfbWNfcHJpbnRrKG1jaSwgS0VSTl9ERUJVRywg IlBST0NFU1NPUiAldToweCV4IFRJTUUgJWxsdSBTT0NLRVQgIgorCQkJICAgIiV1IEFQSUMgMHgl eFxuIiwgbWNlLT5jcHV2ZW5kb3IsIG1jZS0+Y3B1aWQsCisJCQkgICBtY2UtPnRpbWUsIG1jZS0+ c29ja2V0aWQsIG1jZS0+YXBpY2lkKTsKKworCXNreF9tY2Vfb3V0cHV0X2Vycm9yKG1jaSwgbWNl LCAmcmVzKTsKKworCXJldHVybiBOT1RJRllfRE9ORTsKK30KKworc3RhdGljIHZvaWQgc2t4X3Jl bW92ZSh2b2lkKQoreworCWludCBpLCBqOworCXN0cnVjdCBza3hfZGV2ICpkLCAqdG1wOworCisJ ZWRhY19kYmcoMCwgIlxuIik7CisKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZCwgdG1wLCAm ZGV2X2VkYWNfbGlzdCwgbGlzdCkgeworCQlsaXN0X2RlbCgmZC0+bGlzdCk7CisJCWZvciAoaSA9 IDA7IGkgPCBOVU1fSU1DOyBpKyspIHsKKwkJCWlmIChkLT5pbWNbaV0ubWNpKQorCQkJCXNreF91 bnJlZ2lzdGVyX21jaSgmZC0+aW1jW2ldKTsKKworCQkJaWYgKGQtPmltY1tpXS5tZGV2KQorCQkJ CXBjaV9kZXZfcHV0KGQtPmltY1tpXS5tZGV2KTsKKworCQkJaWYgKGQtPmltY1tpXS5tYmFzZSkK KwkJCQlpb3VubWFwKGQtPmltY1tpXS5tYmFzZSk7CisKKwkJCWZvciAoaiA9IDA7IGogPCBOVU1f Q0hBTk5FTFM7IGorKykgeworCQkJCWlmIChkLT5pbWNbaV0uY2hhbltqXS5jZGV2KQorCQkJCQlw Y2lfZGV2X3B1dChkLT5pbWNbaV0uY2hhbltqXS5jZGV2KTsKKwkJCX0KKwkJfQorCQlpZiAoZC0+ dXRpbF9hbGwpCisJCQlwY2lfZGV2X3B1dChkLT51dGlsX2FsbCk7CisJCWlmIChkLT5zYWRfYWxs KQorCQkJcGNpX2Rldl9wdXQoZC0+c2FkX2FsbCk7CisJCWlmIChkLT51cmFjdSkKKwkJCXBjaV9k ZXZfcHV0KGQtPnVyYWN1KTsKKworCQlrZnJlZShkKTsKKwl9Cit9CiAKICNpZmRlZiBDT05GSUdf RURBQ19ERUJVRwotdm9pZCBzZXR1cF9za3hfZGVidWcoY29uc3QgY2hhciAqZGlybmFtZSk7Ci12 b2lkIHRlYXJkb3duX3NreF9kZWJ1Zyh2b2lkKTsKKy8qCisgKiBEZWJ1ZyBmZWF0dXJlLgorICog RXhlcmNpc2UgdGhlIGFkZHJlc3MgZGVjb2RlIGxvZ2ljIGJ5IHdyaXRpbmcgYW4gYWRkcmVzcyB0 bworICogL3N5cy9rZXJuZWwvZGVidWcvZWRhYy9kaXJuYW1lL2FkZHIuCisgKi8KK3N0YXRpYyBz dHJ1Y3QgZGVudHJ5ICpza3hfdGVzdDsKKworc3RhdGljIGludCBkZWJ1Z2ZzX3U2NF9zZXQodm9p ZCAqZGF0YSwgdTY0IHZhbCkKK3sKKwlzdHJ1Y3QgbWNlIG07CisKKwlwcl93YXJuX29uY2UoIkZh a2UgZXJyb3IgdG8gMHglbGx4IGluamVjdGVkIHZpYSBkZWJ1Z2ZzXG4iLCB2YWwpOworCisJbWVt c2V0KCZtLCAwLCBzaXplb2YobSkpOworCS8qIEFERFJWICsgTWVtUmQgKyBVbmtub3duIGNoYW5u ZWwgKi8KKwltLnN0YXR1cyA9IE1DSV9TVEFUVVNfQUREUlYgKyAweDkwOworCS8qIE9uZSBjb3Jy ZWN0ZWQgZXJyb3IgKi8KKwltLnN0YXR1cyB8PSBCSVRfVUxMKE1DSV9TVEFUVVNfQ0VDX1NISUZU KTsKKwltLmFkZHIgPSB2YWw7CisJc2t4X21jZV9jaGVja19lcnJvcihOVUxMLCAwLCAmbSk7CisK KwlyZXR1cm4gMDsKK30KK0RFRklORV9TSU1QTEVfQVRUUklCVVRFKGZvcHNfdTY0X3dvLCBOVUxM LCBkZWJ1Z2ZzX3U2NF9zZXQsICIlbGx1XG4iKTsKKworc3RhdGljIHZvaWQgc2V0dXBfc2t4X2Rl YnVnKGNvbnN0IGNoYXIgKmRpcm5hbWUpCit7CisJc2t4X3Rlc3QgPSBlZGFjX2RlYnVnZnNfY3Jl YXRlX2RpcihkaXJuYW1lKTsKKwlpZiAoIXNreF90ZXN0KQorCQlyZXR1cm47CisKKwlpZiAoIWVk YWNfZGVidWdmc19jcmVhdGVfZmlsZSgiYWRkciIsIDAyMDAsIHNreF90ZXN0LAorCQkJCSAgICAg IE5VTEwsICZmb3BzX3U2NF93bykpIHsKKwkJZGVidWdmc19yZW1vdmUoc2t4X3Rlc3QpOworCQlz a3hfdGVzdCA9IE5VTEw7CisJfQorfQorCitzdGF0aWMgdm9pZCB0ZWFyZG93bl9za3hfZGVidWco dm9pZCkKK3sKKwlkZWJ1Z2ZzX3JlbW92ZV9yZWN1cnNpdmUoc2t4X3Rlc3QpOworfQogI2Vsc2UK IHN0YXRpYyBpbmxpbmUgdm9pZCBzZXR1cF9za3hfZGVidWcoY29uc3QgY2hhciAqZGlybmFtZSkg e30KIHN0YXRpYyBpbmxpbmUgdm9pZCB0ZWFyZG93bl9za3hfZGVidWcodm9pZCkge30KICNlbmRp ZiAvKkNPTkZJR19FREFDX0RFQlVHKi8KLQogI2VuZGlmIC8qIF9TS1hfQ09NTV9FREFDX0ggKi8K ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZWRhYy9za3hfYmFzZS5jIGIvZHJpdmVycy9lZGFjL3NreF9l ZGFjLmMKc2ltaWxhcml0eSBpbmRleCA5OCUKcmVuYW1lIGZyb20gZHJpdmVycy9lZGFjL3NreF9i YXNlLmMKcmVuYW1lIHRvIGRyaXZlcnMvZWRhYy9za3hfZWRhYy5jCmluZGV4IGFkYWU0Yzg0OGNh MS4uMjc2OWQ5ZDM0MGM0IDEwMDY0NAotLS0gYS9kcml2ZXJzL2VkYWMvc2t4X2Jhc2UuYworKysg Yi9kcml2ZXJzL2VkYWMvc2t4X2VkYWMuYwpAQCAtMTEsNiArMTEsMTEgQEAKICNpbmNsdWRlIDxh c20vbWNlLmg+CiAKICNpbmNsdWRlICJlZGFjX21vZHVsZS5oIgorCitzdHJ1Y3QgZGVjb2RlZF9h ZGRyOwordHlwZWRlZiBib29sICgqc2t4X2RlY29kZV9mKShzdHJ1Y3QgZGVjb2RlZF9hZGRyICpy ZXMpOworc3RhdGljIHNreF9kZWNvZGVfZiBza3hfZGVjb2RlOworCiAjaW5jbHVkZSAic2t4X2Nv bW1vbi5oIgogCiAjZGVmaW5lIEVEQUNfTU9EX1NUUiAgICAic2t4X2VkYWMiCkBAIC01MjksNyAr NTM0LDcgQEAgc3RhdGljIGJvb2wgc2t4X21hZF9kZWNvZGUoc3RydWN0IGRlY29kZWRfYWRkciAq cikKIAlyZXR1cm4gdHJ1ZTsKIH0KIAotc3RhdGljIGJvb2wgc2t4X2RlY29kZShzdHJ1Y3QgZGVj b2RlZF9hZGRyICpyZXMpCitzdGF0aWMgYm9vbCBza3hfaW1jX2RlY29kZShzdHJ1Y3QgZGVjb2Rl ZF9hZGRyICpyZXMpCiB7CiAJcmV0dXJuIHNreF9zYWRfZGVjb2RlKHJlcykgJiYgc2t4X3RhZF9k ZWNvZGUocmVzKSAmJgogCQlza3hfcmlyX2RlY29kZShyZXMpICYmIHNreF9tYWRfZGVjb2RlKHJl cyk7CkBAIC02MTEsNyArNjE2LDcgQEAgc3RhdGljIGludCBfX2luaXQgc2t4X2luaXQodm9pZCkK IAkJfQogCX0KIAotCXNreF9zZXRfZGVjb2RlKHNreF9kZWNvZGUpOworCXNreF9kZWNvZGUgPSBz a3hfaW1jX2RlY29kZTsKIAogCWlmIChudmRpbW1fY291bnQgJiYgc2t4X2FkeGxfZ2V0KCkgPT0g LUVOT0RFVikKIAkJc2t4X3ByaW50ayhLRVJOX05PVElDRSwgIk9ubHkgZGVjb2RpbmcgRERSNCBh ZGRyZXNzIVxuIik7Cg== 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=-5.5 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,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 B6813C43381 for ; Thu, 14 Mar 2019 21:59:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5137D20854 for ; Thu, 14 Mar 2019 21:59:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727899AbfCNV7z (ORCPT ); Thu, 14 Mar 2019 17:59:55 -0400 Received: from mga12.intel.com ([192.55.52.136]:35993 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726633AbfCNV7z (ORCPT ); Thu, 14 Mar 2019 17:59:55 -0400 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Mar 2019 14:59:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,479,1544515200"; d="scan'208";a="127057941" Received: from agluck-desk.sc.intel.com (HELO agluck-desk) ([10.3.52.160]) by orsmga006.jf.intel.com with ESMTP; 14 Mar 2019 14:59:52 -0700 Date: Thu, 14 Mar 2019 14:59:52 -0700 From: "Luck, Tony" To: Borislav Petkov Cc: Arnd Bergmann , Mauro Carvalho Chehab , James Morse , Qiuxu Zhuo , linux-edac@vger.kernel.org, Linux Kernel Mailing List Subject: Re: [PATCH] EDAC, {skx|i10nm}_edac: Fix randconfig build error Message-ID: <20190314215952.GA303@agluck-desk> References: <20190305132147.3739133-1-arnd@arndb.de> <20190305143453.GC8256@zn.tnic> <20190306175808.GA30016@agluck-desk> <20190313230137.GA12529@agluck-desk> <20190314110413.GA32277@zn.tnic> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190314110413.GA32277@zn.tnic> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Mar 14, 2019 at 12:04:13PM +0100, Borislav Petkov wrote: > On Thu, Mar 14, 2019 at 08:09:06AM +0100, Arnd Bergmann wrote: > > > So where should we go. Proposed solutions are piling up: > > > > > > 1) Make skx_common a module > > > [downside: have to EXPORT everything in it] > > > 2) Move module-ish bits out of skx_common > > > [downside: perhaps fragile] > > > 3) #include skx_common.c into {skx,i10nm}_edac.c > > > [downside: no patch yet, bigger code size] > > > > Sorry to add on to the already long list, but one more idea after > > looking at the two files: > > > > 4) Have a single driver module, with the skx_common.c containing > > the top-level module_init/module_exit functions that call into the > > hardware specific versions. > > > > This is the opposite of the usual recommendation (the driver > > is already structured nicely otherwise), but it would be cheap > > way out here. > > This is what I think right now: if this is going to become such a pain, > then we better keep those two drivers completely separate. Who cares if > there's some code duplication?! Better that than some obscure randconfig > build breakages and fixes introducing more ugliness. IOW, we should keep > it simple. > > Unless, Tony, you want to be able to make changes to the common code in > one place and don't want to patch both. Then I'd librarize the common > functionality, i.e., do something along the lines of 2). There's a lot of common code. Patching the same thing in two different files seems like make-work (and a recipe for things to be forgotten/missed). I made a patch based on option #3. Rough steps were: $ cat skx_common.c >> skx_common.h $ git rm skx_common.c $ git mv skx_base.c skx_edac.c $ git mv i10nm_base.c i10nm_edac.c $ edit Makefile for changes of names $ edit skx_common.h to add "static" everywhere $ edit to fix the build issues Not entirely happy with some of the bits in that last step. Patch looks like this: >From b9e9723c95b667d28d81ea53b35447e1ce8f3244 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 14 Mar 2019 10:45:34 -0700 Subject: [PATCH] fix corner cases for randconfig --- drivers/edac/Makefile | 2 - drivers/edac/{i10nm_base.c => i10nm_edac.c} | 5 + drivers/edac/skx_common.c | 691 -------------------- drivers/edac/skx_common.h | 685 ++++++++++++++++++- drivers/edac/{skx_base.c => skx_edac.c} | 9 +- 5 files changed, 676 insertions(+), 716 deletions(-) rename drivers/edac/{i10nm_base.c => i10nm_edac.c} (98%) delete mode 100644 drivers/edac/skx_common.c rename drivers/edac/{skx_base.c => skx_edac.c} (98%) diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 89ad4a84a0f6..5d8d88574d3c 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -57,10 +57,8 @@ obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac_mod.o layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o -skx_edac-y := skx_common.o skx_base.o obj-$(CONFIG_EDAC_SKX) += skx_edac.o -i10nm_edac-y := skx_common.o i10nm_base.o obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_edac.c similarity index 98% rename from drivers/edac/i10nm_base.c rename to drivers/edac/i10nm_edac.c index c334fb7c63df..45c6497f35c5 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_edac.c @@ -10,6 +10,11 @@ #include #include #include "edac_module.h" + +struct decoded_addr; +typedef bool (*skx_decode_f)(struct decoded_addr *res); +static skx_decode_f skx_decode; + #include "skx_common.h" #define I10NM_REVISION "v0.0.3" diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c deleted file mode 100644 index 0e96e7b5b0a7..000000000000 --- a/drivers/edac/skx_common.c +++ /dev/null @@ -1,691 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Common codes for both the skx_edac driver and Intel 10nm server EDAC driver. - * Originally split out from the skx_edac driver. - * - * Copyright (c) 2018, Intel Corporation. - */ - -#include -#include -#include -#include -#include -#include "edac_module.h" -#include "skx_common.h" - -static const char * const component_names[] = { - [INDEX_SOCKET] = "ProcessorSocketId", - [INDEX_MEMCTRL] = "MemoryControllerId", - [INDEX_CHANNEL] = "ChannelId", - [INDEX_DIMM] = "DimmSlotId", -}; - -static int component_indices[ARRAY_SIZE(component_names)]; -static int adxl_component_count; -static const char * const *adxl_component_names; -static u64 *adxl_values; -static char *adxl_msg; - -static char skx_msg[MSG_SIZE]; -static skx_decode_f skx_decode; -static u64 skx_tolm, skx_tohm; -static LIST_HEAD(dev_edac_list); - -int __init skx_adxl_get(void) -{ - const char * const *names; - int i, j; - - names = adxl_get_component_names(); - if (!names) { - skx_printk(KERN_NOTICE, "No firmware support for address translation.\n"); - return -ENODEV; - } - - for (i = 0; i < INDEX_MAX; i++) { - for (j = 0; names[j]; j++) { - if (!strcmp(component_names[i], names[j])) { - component_indices[i] = j; - break; - } - } - - if (!names[j]) - goto err; - } - - adxl_component_names = names; - while (*names++) - adxl_component_count++; - - adxl_values = kcalloc(adxl_component_count, sizeof(*adxl_values), - GFP_KERNEL); - if (!adxl_values) { - adxl_component_count = 0; - return -ENOMEM; - } - - adxl_msg = kzalloc(MSG_SIZE, GFP_KERNEL); - if (!adxl_msg) { - adxl_component_count = 0; - kfree(adxl_values); - return -ENOMEM; - } - - return 0; -err: - skx_printk(KERN_ERR, "'%s' is not matched from DSM parameters: ", - component_names[i]); - for (j = 0; names[j]; j++) - skx_printk(KERN_CONT, "%s ", names[j]); - skx_printk(KERN_CONT, "\n"); - - return -ENODEV; -} - -void __exit skx_adxl_put(void) -{ - kfree(adxl_values); - kfree(adxl_msg); -} - -static bool skx_adxl_decode(struct decoded_addr *res) -{ - int i, len = 0; - - if (res->addr >= skx_tohm || (res->addr >= skx_tolm && - res->addr < BIT_ULL(32))) { - edac_dbg(0, "Address 0x%llx out of range\n", res->addr); - return false; - } - - if (adxl_decode(res->addr, adxl_values)) { - edac_dbg(0, "Failed to decode 0x%llx\n", res->addr); - return false; - } - - res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]]; - res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; - res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]]; - res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]]; - - for (i = 0; i < adxl_component_count; i++) { - if (adxl_values[i] == ~0x0ull) - continue; - - len += snprintf(adxl_msg + len, MSG_SIZE - len, " %s:0x%llx", - adxl_component_names[i], adxl_values[i]); - if (MSG_SIZE - len <= 0) - break; - } - - return true; -} - -void skx_set_decode(skx_decode_f decode) -{ - skx_decode = decode; -} - -int skx_get_src_id(struct skx_dev *d, u8 *id) -{ - u32 reg; - - if (pci_read_config_dword(d->util_all, 0xf0, ®)) { - skx_printk(KERN_ERR, "Failed to read src id\n"); - return -ENODEV; - } - - *id = GET_BITFIELD(reg, 12, 14); - return 0; -} - -int skx_get_node_id(struct skx_dev *d, u8 *id) -{ - u32 reg; - - if (pci_read_config_dword(d->util_all, 0xf4, ®)) { - skx_printk(KERN_ERR, "Failed to read node id\n"); - return -ENODEV; - } - - *id = GET_BITFIELD(reg, 0, 2); - return 0; -} - -static int get_width(u32 mtr) -{ - switch (GET_BITFIELD(mtr, 8, 9)) { - case 0: - return DEV_X4; - case 1: - return DEV_X8; - case 2: - return DEV_X16; - } - return DEV_UNKNOWN; -} - -/* - * We use the per-socket device @did to count how many sockets are present, - * and to detemine which PCI buses are associated with each socket. Allocate - * and build the full list of all the skx_dev structures that we need here. - */ -int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, - struct list_head **list) -{ - struct pci_dev *pdev, *prev; - struct skx_dev *d; - u32 reg; - int ndev = 0; - - prev = NULL; - for (;;) { - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev); - if (!pdev) - break; - ndev++; - d = kzalloc(sizeof(*d), GFP_KERNEL); - if (!d) { - pci_dev_put(pdev); - return -ENOMEM; - } - - if (pci_read_config_dword(pdev, off, ®)) { - kfree(d); - pci_dev_put(pdev); - skx_printk(KERN_ERR, "Failed to read bus idx\n"); - return -ENODEV; - } - - d->bus[0] = GET_BITFIELD(reg, 0, 7); - d->bus[1] = GET_BITFIELD(reg, 8, 15); - if (type == SKX) { - d->seg = pci_domain_nr(pdev->bus); - d->bus[2] = GET_BITFIELD(reg, 16, 23); - d->bus[3] = GET_BITFIELD(reg, 24, 31); - } else { - d->seg = GET_BITFIELD(reg, 16, 23); - } - - edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x\n", - d->bus[0], d->bus[1], d->bus[2], d->bus[3]); - list_add_tail(&d->list, &dev_edac_list); - prev = pdev; - } - - if (list) - *list = &dev_edac_list; - return ndev; -} - -int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) -{ - struct pci_dev *pdev; - u32 reg; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL); - if (!pdev) { - skx_printk(KERN_ERR, "Can't get tolm/tohm\n"); - return -ENODEV; - } - - if (pci_read_config_dword(pdev, off[0], ®)) { - skx_printk(KERN_ERR, "Failed to read tolm\n"); - goto fail; - } - skx_tolm = reg; - - if (pci_read_config_dword(pdev, off[1], ®)) { - skx_printk(KERN_ERR, "Failed to read lower tohm\n"); - goto fail; - } - skx_tohm = reg; - - if (pci_read_config_dword(pdev, off[2], ®)) { - skx_printk(KERN_ERR, "Failed to read upper tohm\n"); - goto fail; - } - skx_tohm |= (u64)reg << 32; - - pci_dev_put(pdev); - *tolm = skx_tolm; - *tohm = skx_tohm; - edac_dbg(2, "tolm = 0x%llx tohm = 0x%llx\n", skx_tolm, skx_tohm); - return 0; -fail: - pci_dev_put(pdev); - return -ENODEV; -} - -static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, - int minval, int maxval, const char *name) -{ - u32 val = GET_BITFIELD(reg, lobit, hibit); - - if (val < minval || val > maxval) { - edac_dbg(2, "bad %s = %d (raw=0x%x)\n", name, val, reg); - return -EINVAL; - } - return val + add; -} - -#define numrank(reg) skx_get_dimm_attr(reg, 12, 13, 0, 0, 2, "ranks") -#define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows") -#define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols") - -int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, - struct skx_imc *imc, int chan, int dimmno) -{ - int banks = 16, ranks, rows, cols, npages; - u64 size; - - ranks = numrank(mtr); - rows = numrow(mtr); - cols = numcol(mtr); - - /* - * Compute size in 8-byte (2^3) words, then shift to MiB (2^20) - */ - size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3); - npages = MiB_TO_PAGES(size); - - edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld MiB (%d pages) bank: %d, rank: %d, row: 0x%x, col: 0x%x\n", - imc->mc, chan, dimmno, size, npages, - banks, 1 << ranks, rows, cols); - - imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mtr, 0, 0); - imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mtr, 9, 9); - imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0); - imc->chan[chan].dimms[dimmno].rowbits = rows; - imc->chan[chan].dimms[dimmno].colbits = cols; - - dimm->nr_pages = npages; - dimm->grain = 32; - dimm->dtype = get_width(mtr); - dimm->mtype = MEM_DDR4; - dimm->edac_mode = EDAC_SECDED; /* likely better than this */ - snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u", - imc->src_id, imc->lmc, chan, dimmno); - - return 1; -} - -int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, - int chan, int dimmno, const char *mod_str) -{ - int smbios_handle; - u32 dev_handle; - u16 flags; - u64 size = 0; - - dev_handle = ACPI_NFIT_BUILD_DEVICE_HANDLE(dimmno, chan, imc->lmc, - imc->src_id, 0); - - smbios_handle = nfit_get_smbios_id(dev_handle, &flags); - if (smbios_handle == -EOPNOTSUPP) { - pr_warn_once("%s: Can't find size of NVDIMM. Try enabling CONFIG_ACPI_NFIT\n", mod_str); - goto unknown_size; - } - - if (smbios_handle < 0) { - skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=0x%x\n", dev_handle); - goto unknown_size; - } - - if (flags & ACPI_NFIT_MEM_MAP_FAILED) { - skx_printk(KERN_ERR, "NVDIMM ADR=0x%x is not mapped\n", dev_handle); - goto unknown_size; - } - - size = dmi_memdev_size(smbios_handle); - if (size == ~0ull) - skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=0x%x/SMBIOS=0x%x\n", - dev_handle, smbios_handle); - -unknown_size: - dimm->nr_pages = size >> PAGE_SHIFT; - dimm->grain = 32; - dimm->dtype = DEV_UNKNOWN; - dimm->mtype = MEM_NVDIMM; - dimm->edac_mode = EDAC_SECDED; /* likely better than this */ - - edac_dbg(0, "mc#%d: channel %d, dimm %d, %llu MiB (%u pages)\n", - imc->mc, chan, dimmno, size >> 20, dimm->nr_pages); - - snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u", - imc->src_id, imc->lmc, chan, dimmno); - - return (size == 0 || size == ~0ull) ? 0 : 1; -} - -int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, - const char *ctl_name, const char *mod_str, - get_dimm_config_f get_dimm_config) -{ - struct mem_ctl_info *mci; - struct edac_mc_layer layers[2]; - struct skx_pvt *pvt; - int rc; - - /* Allocate a new MC control structure */ - layers[0].type = EDAC_MC_LAYER_CHANNEL; - layers[0].size = NUM_CHANNELS; - layers[0].is_virt_csrow = false; - layers[1].type = EDAC_MC_LAYER_SLOT; - layers[1].size = NUM_DIMMS; - layers[1].is_virt_csrow = true; - mci = edac_mc_alloc(imc->mc, ARRAY_SIZE(layers), layers, - sizeof(struct skx_pvt)); - - if (unlikely(!mci)) - return -ENOMEM; - - edac_dbg(0, "MC#%d: mci = %p\n", imc->mc, mci); - - /* Associate skx_dev and mci for future usage */ - imc->mci = mci; - pvt = mci->pvt_info; - pvt->imc = imc; - - mci->ctl_name = kasprintf(GFP_KERNEL, "%s#%d IMC#%d", ctl_name, - imc->node_id, imc->lmc); - if (!mci->ctl_name) { - rc = -ENOMEM; - goto fail0; - } - - mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM; - mci->edac_ctl_cap = EDAC_FLAG_NONE; - mci->edac_cap = EDAC_FLAG_NONE; - mci->mod_name = mod_str; - mci->dev_name = pci_name(pdev); - mci->ctl_page_to_phys = NULL; - - rc = get_dimm_config(mci); - if (rc < 0) - goto fail; - - /* Record ptr to the generic device */ - mci->pdev = &pdev->dev; - - /* Add this new MC control structure to EDAC's list of MCs */ - if (unlikely(edac_mc_add_mc(mci))) { - edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); - rc = -EINVAL; - goto fail; - } - - return 0; - -fail: - kfree(mci->ctl_name); -fail0: - edac_mc_free(mci); - imc->mci = NULL; - return rc; -} - -static void skx_unregister_mci(struct skx_imc *imc) -{ - struct mem_ctl_info *mci = imc->mci; - - if (!mci) - return; - - edac_dbg(0, "MC%d: mci = %p\n", imc->mc, mci); - - /* Remove MC sysfs nodes */ - edac_mc_del_mc(mci->pdev); - - edac_dbg(1, "%s: free mci struct\n", mci->ctl_name); - kfree(mci->ctl_name); - edac_mc_free(mci); -} - -static struct mem_ctl_info *get_mci(int src_id, int lmc) -{ - struct skx_dev *d; - - if (lmc > NUM_IMC - 1) { - skx_printk(KERN_ERR, "Bad lmc %d\n", lmc); - return NULL; - } - - list_for_each_entry(d, &dev_edac_list, list) { - if (d->imc[0].src_id == src_id) - return d->imc[lmc].mci; - } - - skx_printk(KERN_ERR, "No mci for src_id %d lmc %d\n", src_id, lmc); - return NULL; -} - -static void skx_mce_output_error(struct mem_ctl_info *mci, - const struct mce *m, - struct decoded_addr *res) -{ - enum hw_event_mc_err_type tp_event; - char *type, *optype; - bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0); - bool overflow = GET_BITFIELD(m->status, 62, 62); - bool uncorrected_error = GET_BITFIELD(m->status, 61, 61); - bool recoverable; - u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52); - u32 mscod = GET_BITFIELD(m->status, 16, 31); - u32 errcode = GET_BITFIELD(m->status, 0, 15); - u32 optypenum = GET_BITFIELD(m->status, 4, 6); - - recoverable = GET_BITFIELD(m->status, 56, 56); - - if (uncorrected_error) { - core_err_cnt = 1; - if (ripv) { - type = "FATAL"; - tp_event = HW_EVENT_ERR_FATAL; - } else { - type = "NON_FATAL"; - tp_event = HW_EVENT_ERR_UNCORRECTED; - } - } else { - type = "CORRECTED"; - tp_event = HW_EVENT_ERR_CORRECTED; - } - - /* - * According to Intel Architecture spec vol 3B, - * Table 15-10 "IA32_MCi_Status [15:0] Compound Error Code Encoding" - * memory errors should fit one of these masks: - * 000f 0000 1mmm cccc (binary) - * 000f 0010 1mmm cccc (binary) [RAM used as cache] - * where: - * f = Correction Report Filtering Bit. If 1, subsequent errors - * won't be shown - * mmm = error type - * cccc = channel - * If the mask doesn't match, report an error to the parsing logic - */ - if (!((errcode & 0xef80) == 0x80 || (errcode & 0xef80) == 0x280)) { - optype = "Can't parse: it is not a mem"; - } else { - switch (optypenum) { - case 0: - optype = "generic undef request error"; - break; - case 1: - optype = "memory read error"; - break; - case 2: - optype = "memory write error"; - break; - case 3: - optype = "addr/cmd error"; - break; - case 4: - optype = "memory scrubbing error"; - break; - default: - optype = "reserved"; - break; - } - } - if (adxl_component_count) { - snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s", - overflow ? " OVERFLOW" : "", - (uncorrected_error && recoverable) ? " recoverable" : "", - mscod, errcode, adxl_msg); - } else { - snprintf(skx_msg, MSG_SIZE, - "%s%s err_code:0x%04x:0x%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:0x%x col:0x%x", - overflow ? " OVERFLOW" : "", - (uncorrected_error && recoverable) ? " recoverable" : "", - mscod, errcode, - res->socket, res->imc, res->rank, - res->bank_group, res->bank_address, res->row, res->column); - } - - edac_dbg(0, "%s\n", skx_msg); - - /* Call the helper to output message */ - edac_mc_handle_error(tp_event, mci, core_err_cnt, - m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0, - res->channel, res->dimm, -1, - optype, skx_msg); -} - -int skx_mce_check_error(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct mce *mce = (struct mce *)data; - struct decoded_addr res; - struct mem_ctl_info *mci; - char *type; - - if (edac_get_report_status() == EDAC_REPORTING_DISABLED) - return NOTIFY_DONE; - - /* ignore unless this is memory related with an address */ - if ((mce->status & 0xefff) >> 7 != 1 || !(mce->status & MCI_STATUS_ADDRV)) - return NOTIFY_DONE; - - memset(&res, 0, sizeof(res)); - res.addr = mce->addr; - - if (adxl_component_count) { - if (!skx_adxl_decode(&res)) - return NOTIFY_DONE; - - mci = get_mci(res.socket, res.imc); - } else { - if (!skx_decode || !skx_decode(&res)) - return NOTIFY_DONE; - - mci = res.dev->imc[res.imc].mci; - } - - if (!mci) - return NOTIFY_DONE; - - if (mce->mcgstatus & MCG_STATUS_MCIP) - type = "Exception"; - else - type = "Event"; - - skx_mc_printk(mci, KERN_DEBUG, "HANDLING MCE MEMORY ERROR\n"); - - skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: 0x%llx " - "Bank %d: 0x%llx\n", mce->extcpu, type, - mce->mcgstatus, mce->bank, mce->status); - skx_mc_printk(mci, KERN_DEBUG, "TSC 0x%llx ", mce->tsc); - skx_mc_printk(mci, KERN_DEBUG, "ADDR 0x%llx ", mce->addr); - skx_mc_printk(mci, KERN_DEBUG, "MISC 0x%llx ", mce->misc); - - skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:0x%x TIME %llu SOCKET " - "%u APIC 0x%x\n", mce->cpuvendor, mce->cpuid, - mce->time, mce->socketid, mce->apicid); - - skx_mce_output_error(mci, mce, &res); - - return NOTIFY_DONE; -} - -void skx_remove(void) -{ - int i, j; - struct skx_dev *d, *tmp; - - edac_dbg(0, "\n"); - - list_for_each_entry_safe(d, tmp, &dev_edac_list, list) { - list_del(&d->list); - for (i = 0; i < NUM_IMC; i++) { - if (d->imc[i].mci) - skx_unregister_mci(&d->imc[i]); - - if (d->imc[i].mdev) - pci_dev_put(d->imc[i].mdev); - - if (d->imc[i].mbase) - iounmap(d->imc[i].mbase); - - for (j = 0; j < NUM_CHANNELS; j++) { - if (d->imc[i].chan[j].cdev) - pci_dev_put(d->imc[i].chan[j].cdev); - } - } - if (d->util_all) - pci_dev_put(d->util_all); - if (d->sad_all) - pci_dev_put(d->sad_all); - if (d->uracu) - pci_dev_put(d->uracu); - - kfree(d); - } -} - -#ifdef CONFIG_EDAC_DEBUG -/* - * Debug feature. - * Exercise the address decode logic by writing an address to - * /sys/kernel/debug/edac/dirname/addr. - */ -static struct dentry *skx_test; - -static int debugfs_u64_set(void *data, u64 val) -{ - struct mce m; - - pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); - - memset(&m, 0, sizeof(m)); - /* ADDRV + MemRd + Unknown channel */ - m.status = MCI_STATUS_ADDRV + 0x90; - /* One corrected error */ - m.status |= BIT_ULL(MCI_STATUS_CEC_SHIFT); - m.addr = val; - skx_mce_check_error(NULL, 0, &m); - - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); - -void setup_skx_debug(const char *dirname) -{ - skx_test = edac_debugfs_create_dir(dirname); - if (!skx_test) - return; - - if (!edac_debugfs_create_file("addr", 0200, skx_test, - NULL, &fops_u64_wo)) { - debugfs_remove(skx_test); - skx_test = NULL; - } -} - -void teardown_skx_debug(void) -{ - debugfs_remove_recursive(skx_test); -} -#endif /*CONFIG_EDAC_DEBUG*/ diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index d25374e34d4f..6da3def09ea1 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -9,6 +9,13 @@ #ifndef _SKX_COMM_EDAC_H #define _SKX_COMM_EDAC_H +#include +#include +#include +#include +#include +#include "edac_module.h" + #define MSG_SIZE 1024 /* @@ -112,41 +119,677 @@ struct decoded_addr { }; typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); -typedef bool (*skx_decode_f)(struct decoded_addr *res); -int __init skx_adxl_get(void); -void __exit skx_adxl_put(void); -void skx_set_decode(skx_decode_f decode); +static const char * const component_names[] = { + [INDEX_SOCKET] = "ProcessorSocketId", + [INDEX_MEMCTRL] = "MemoryControllerId", + [INDEX_CHANNEL] = "ChannelId", + [INDEX_DIMM] = "DimmSlotId", +}; + +static int component_indices[ARRAY_SIZE(component_names)]; +static int adxl_component_count; +static const char * const *adxl_component_names; +static u64 *adxl_values; +static char *adxl_msg; + +static char skx_msg[MSG_SIZE]; +static u64 skx_tolm, skx_tohm; +static LIST_HEAD(dev_edac_list); + +static int __init skx_adxl_get(void) +{ + const char * const *names; + int i, j; + + names = adxl_get_component_names(); + if (!names) { + skx_printk(KERN_NOTICE, "No firmware support for address translation.\n"); + return -ENODEV; + } + + for (i = 0; i < INDEX_MAX; i++) { + for (j = 0; names[j]; j++) { + if (!strcmp(component_names[i], names[j])) { + component_indices[i] = j; + break; + } + } + + if (!names[j]) + goto err; + } + + adxl_component_names = names; + while (*names++) + adxl_component_count++; + + adxl_values = kcalloc(adxl_component_count, sizeof(*adxl_values), + GFP_KERNEL); + if (!adxl_values) { + adxl_component_count = 0; + return -ENOMEM; + } + + adxl_msg = kzalloc(MSG_SIZE, GFP_KERNEL); + if (!adxl_msg) { + adxl_component_count = 0; + kfree(adxl_values); + return -ENOMEM; + } + + return 0; +err: + skx_printk(KERN_ERR, "'%s' is not matched from DSM parameters: ", + component_names[i]); + for (j = 0; names[j]; j++) + skx_printk(KERN_CONT, "%s ", names[j]); + skx_printk(KERN_CONT, "\n"); + + return -ENODEV; +} + +static void __exit skx_adxl_put(void) +{ + kfree(adxl_values); + kfree(adxl_msg); +} + +static bool skx_adxl_decode(struct decoded_addr *res) +{ + int i, len = 0; + + if (res->addr >= skx_tohm || (res->addr >= skx_tolm && + res->addr < BIT_ULL(32))) { + edac_dbg(0, "Address 0x%llx out of range\n", res->addr); + return false; + } + + if (adxl_decode(res->addr, adxl_values)) { + edac_dbg(0, "Failed to decode 0x%llx\n", res->addr); + return false; + } + + res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]]; + res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; + res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]]; + res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]]; + + for (i = 0; i < adxl_component_count; i++) { + if (adxl_values[i] == ~0x0ull) + continue; + + len += snprintf(adxl_msg + len, MSG_SIZE - len, " %s:0x%llx", + adxl_component_names[i], adxl_values[i]); + if (MSG_SIZE - len <= 0) + break; + } + + return true; +} + +static int skx_get_src_id(struct skx_dev *d, u8 *id) +{ + u32 reg; + + if (pci_read_config_dword(d->util_all, 0xf0, ®)) { + skx_printk(KERN_ERR, "Failed to read src id\n"); + return -ENODEV; + } + + *id = GET_BITFIELD(reg, 12, 14); + return 0; +} + +static int skx_get_node_id(struct skx_dev *d, u8 *id) +{ + u32 reg; + + if (pci_read_config_dword(d->util_all, 0xf4, ®)) { + skx_printk(KERN_ERR, "Failed to read node id\n"); + return -ENODEV; + } + + *id = GET_BITFIELD(reg, 0, 2); + return 0; +} + +static int get_width(u32 mtr) +{ + switch (GET_BITFIELD(mtr, 8, 9)) { + case 0: + return DEV_X4; + case 1: + return DEV_X8; + case 2: + return DEV_X16; + } + return DEV_UNKNOWN; +} + +/* + * We use the per-socket device @did to count how many sockets are present, + * and to detemine which PCI buses are associated with each socket. Allocate + * and build the full list of all the skx_dev structures that we need here. + */ +static int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, + struct list_head **list) +{ + struct pci_dev *pdev, *prev; + struct skx_dev *d; + u32 reg; + int ndev = 0; + + prev = NULL; + for (;;) { + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev); + if (!pdev) + break; + ndev++; + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (!d) { + pci_dev_put(pdev); + return -ENOMEM; + } + + if (pci_read_config_dword(pdev, off, ®)) { + kfree(d); + pci_dev_put(pdev); + skx_printk(KERN_ERR, "Failed to read bus idx\n"); + return -ENODEV; + } + + d->bus[0] = GET_BITFIELD(reg, 0, 7); + d->bus[1] = GET_BITFIELD(reg, 8, 15); + if (type == SKX) { + d->seg = pci_domain_nr(pdev->bus); + d->bus[2] = GET_BITFIELD(reg, 16, 23); + d->bus[3] = GET_BITFIELD(reg, 24, 31); + } else { + d->seg = GET_BITFIELD(reg, 16, 23); + } + + edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x\n", + d->bus[0], d->bus[1], d->bus[2], d->bus[3]); + list_add_tail(&d->list, &dev_edac_list); + prev = pdev; + } + + if (list) + *list = &dev_edac_list; + return ndev; +} + +static int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) +{ + struct pci_dev *pdev; + u32 reg; + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL); + if (!pdev) { + skx_printk(KERN_ERR, "Can't get tolm/tohm\n"); + return -ENODEV; + } + + if (pci_read_config_dword(pdev, off[0], ®)) { + skx_printk(KERN_ERR, "Failed to read tolm\n"); + goto fail; + } + skx_tolm = reg; + + if (pci_read_config_dword(pdev, off[1], ®)) { + skx_printk(KERN_ERR, "Failed to read lower tohm\n"); + goto fail; + } + skx_tohm = reg; + + if (pci_read_config_dword(pdev, off[2], ®)) { + skx_printk(KERN_ERR, "Failed to read upper tohm\n"); + goto fail; + } + skx_tohm |= (u64)reg << 32; + + pci_dev_put(pdev); + *tolm = skx_tolm; + *tohm = skx_tohm; + edac_dbg(2, "tolm = 0x%llx tohm = 0x%llx\n", skx_tolm, skx_tohm); + return 0; +fail: + pci_dev_put(pdev); + return -ENODEV; +} + +static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, + int minval, int maxval, const char *name) +{ + u32 val = GET_BITFIELD(reg, lobit, hibit); + + if (val < minval || val > maxval) { + edac_dbg(2, "bad %s = %d (raw=0x%x)\n", name, val, reg); + return -EINVAL; + } + return val + add; +} + +#define numrank(reg) skx_get_dimm_attr(reg, 12, 13, 0, 0, 2, "ranks") +#define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows") +#define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols") + +static int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, + struct skx_imc *imc, int chan, int dimmno) +{ + int banks = 16, ranks, rows, cols, npages; + u64 size; + + ranks = numrank(mtr); + rows = numrow(mtr); + cols = numcol(mtr); + + /* + * Compute size in 8-byte (2^3) words, then shift to MiB (2^20) + */ + size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3); + npages = MiB_TO_PAGES(size); + + edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld MiB (%d pages) bank: %d, rank: %d, row: 0x%x, col: 0x%x\n", + imc->mc, chan, dimmno, size, npages, + banks, 1 << ranks, rows, cols); + + imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mtr, 0, 0); + imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mtr, 9, 9); + imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0); + imc->chan[chan].dimms[dimmno].rowbits = rows; + imc->chan[chan].dimms[dimmno].colbits = cols; + + dimm->nr_pages = npages; + dimm->grain = 32; + dimm->dtype = get_width(mtr); + dimm->mtype = MEM_DDR4; + dimm->edac_mode = EDAC_SECDED; /* likely better than this */ + snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u", + imc->src_id, imc->lmc, chan, dimmno); + + return 1; +} + +static int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, + int chan, int dimmno, const char *mod_str) +{ + int smbios_handle; + u32 dev_handle; + u16 flags; + u64 size = 0; + + dev_handle = ACPI_NFIT_BUILD_DEVICE_HANDLE(dimmno, chan, imc->lmc, + imc->src_id, 0); + + smbios_handle = nfit_get_smbios_id(dev_handle, &flags); + if (smbios_handle == -EOPNOTSUPP) { + pr_warn_once("%s: Can't find size of NVDIMM. Try enabling CONFIG_ACPI_NFIT\n", mod_str); + goto unknown_size; + } + + if (smbios_handle < 0) { + skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=0x%x\n", dev_handle); + goto unknown_size; + } -int skx_get_src_id(struct skx_dev *d, u8 *id); -int skx_get_node_id(struct skx_dev *d, u8 *id); + if (flags & ACPI_NFIT_MEM_MAP_FAILED) { + skx_printk(KERN_ERR, "NVDIMM ADR=0x%x is not mapped\n", dev_handle); + goto unknown_size; + } -int skx_get_all_bus_mappings(unsigned int did, int off, enum type, - struct list_head **list); + size = dmi_memdev_size(smbios_handle); + if (size == ~0ull) + skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=0x%x/SMBIOS=0x%x\n", + dev_handle, smbios_handle); -int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); +unknown_size: + dimm->nr_pages = size >> PAGE_SHIFT; + dimm->grain = 32; + dimm->dtype = DEV_UNKNOWN; + dimm->mtype = MEM_NVDIMM; + dimm->edac_mode = EDAC_SECDED; /* likely better than this */ -int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, - struct skx_imc *imc, int chan, int dimmno); + edac_dbg(0, "mc#%d: channel %d, dimm %d, %llu MiB (%u pages)\n", + imc->mc, chan, dimmno, size >> 20, dimm->nr_pages); -int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, - int chan, int dimmno, const char *mod_str); + snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u", + imc->src_id, imc->lmc, chan, dimmno); -int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, + return (size == 0 || size == ~0ull) ? 0 : 1; +} + +static int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, const char *ctl_name, const char *mod_str, - get_dimm_config_f get_dimm_config); + get_dimm_config_f get_dimm_config) +{ + struct mem_ctl_info *mci; + struct edac_mc_layer layers[2]; + struct skx_pvt *pvt; + int rc; + + /* Allocate a new MC control structure */ + layers[0].type = EDAC_MC_LAYER_CHANNEL; + layers[0].size = NUM_CHANNELS; + layers[0].is_virt_csrow = false; + layers[1].type = EDAC_MC_LAYER_SLOT; + layers[1].size = NUM_DIMMS; + layers[1].is_virt_csrow = true; + mci = edac_mc_alloc(imc->mc, ARRAY_SIZE(layers), layers, + sizeof(struct skx_pvt)); + + if (unlikely(!mci)) + return -ENOMEM; + + edac_dbg(0, "MC#%d: mci = %p\n", imc->mc, mci); + + /* Associate skx_dev and mci for future usage */ + imc->mci = mci; + pvt = mci->pvt_info; + pvt->imc = imc; + + mci->ctl_name = kasprintf(GFP_KERNEL, "%s#%d IMC#%d", ctl_name, + imc->node_id, imc->lmc); + if (!mci->ctl_name) { + rc = -ENOMEM; + goto fail0; + } + + mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM; + mci->edac_ctl_cap = EDAC_FLAG_NONE; + mci->edac_cap = EDAC_FLAG_NONE; + mci->mod_name = mod_str; + mci->dev_name = pci_name(pdev); + mci->ctl_page_to_phys = NULL; + + rc = get_dimm_config(mci); + if (rc < 0) + goto fail; + + /* Record ptr to the generic device */ + mci->pdev = &pdev->dev; + + /* Add this new MC control structure to EDAC's list of MCs */ + if (unlikely(edac_mc_add_mc(mci))) { + edac_dbg(0, "MC: failed edac_mc_add_mc()\n"); + rc = -EINVAL; + goto fail; + } + + return 0; + +fail: + kfree(mci->ctl_name); +fail0: + edac_mc_free(mci); + imc->mci = NULL; + return rc; +} + +static void skx_unregister_mci(struct skx_imc *imc) +{ + struct mem_ctl_info *mci = imc->mci; + + if (!mci) + return; + + edac_dbg(0, "MC%d: mci = %p\n", imc->mc, mci); + + /* Remove MC sysfs nodes */ + edac_mc_del_mc(mci->pdev); + + edac_dbg(1, "%s: free mci struct\n", mci->ctl_name); + kfree(mci->ctl_name); + edac_mc_free(mci); +} + +static struct mem_ctl_info *get_mci(int src_id, int lmc) +{ + struct skx_dev *d; + + if (lmc > NUM_IMC - 1) { + skx_printk(KERN_ERR, "Bad lmc %d\n", lmc); + return NULL; + } + + list_for_each_entry(d, &dev_edac_list, list) { + if (d->imc[0].src_id == src_id) + return d->imc[lmc].mci; + } + + skx_printk(KERN_ERR, "No mci for src_id %d lmc %d\n", src_id, lmc); + return NULL; +} + +static void skx_mce_output_error(struct mem_ctl_info *mci, + const struct mce *m, + struct decoded_addr *res) +{ + enum hw_event_mc_err_type tp_event; + char *type, *optype; + bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0); + bool overflow = GET_BITFIELD(m->status, 62, 62); + bool uncorrected_error = GET_BITFIELD(m->status, 61, 61); + bool recoverable; + u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52); + u32 mscod = GET_BITFIELD(m->status, 16, 31); + u32 errcode = GET_BITFIELD(m->status, 0, 15); + u32 optypenum = GET_BITFIELD(m->status, 4, 6); + + recoverable = GET_BITFIELD(m->status, 56, 56); + + if (uncorrected_error) { + core_err_cnt = 1; + if (ripv) { + type = "FATAL"; + tp_event = HW_EVENT_ERR_FATAL; + } else { + type = "NON_FATAL"; + tp_event = HW_EVENT_ERR_UNCORRECTED; + } + } else { + type = "CORRECTED"; + tp_event = HW_EVENT_ERR_CORRECTED; + } + + /* + * According to Intel Architecture spec vol 3B, + * Table 15-10 "IA32_MCi_Status [15:0] Compound Error Code Encoding" + * memory errors should fit one of these masks: + * 000f 0000 1mmm cccc (binary) + * 000f 0010 1mmm cccc (binary) [RAM used as cache] + * where: + * f = Correction Report Filtering Bit. If 1, subsequent errors + * won't be shown + * mmm = error type + * cccc = channel + * If the mask doesn't match, report an error to the parsing logic + */ + if (!((errcode & 0xef80) == 0x80 || (errcode & 0xef80) == 0x280)) { + optype = "Can't parse: it is not a mem"; + } else { + switch (optypenum) { + case 0: + optype = "generic undef request error"; + break; + case 1: + optype = "memory read error"; + break; + case 2: + optype = "memory write error"; + break; + case 3: + optype = "addr/cmd error"; + break; + case 4: + optype = "memory scrubbing error"; + break; + default: + optype = "reserved"; + break; + } + } + if (adxl_component_count) { + snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s", + overflow ? " OVERFLOW" : "", + (uncorrected_error && recoverable) ? " recoverable" : "", + mscod, errcode, adxl_msg); + } else { + snprintf(skx_msg, MSG_SIZE, + "%s%s err_code:0x%04x:0x%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:0x%x col:0x%x", + overflow ? " OVERFLOW" : "", + (uncorrected_error && recoverable) ? " recoverable" : "", + mscod, errcode, + res->socket, res->imc, res->rank, + res->bank_group, res->bank_address, res->row, res->column); + } + + edac_dbg(0, "%s\n", skx_msg); + + /* Call the helper to output message */ + edac_mc_handle_error(tp_event, mci, core_err_cnt, + m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0, + res->channel, res->dimm, -1, + optype, skx_msg); +} + +static int skx_mce_check_error(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct mce *mce = (struct mce *)data; + struct decoded_addr res; + struct mem_ctl_info *mci; + char *type; -int skx_mce_check_error(struct notifier_block *nb, unsigned long val, - void *data); + if (edac_get_report_status() == EDAC_REPORTING_DISABLED) + return NOTIFY_DONE; -void skx_remove(void); + /* ignore unless this is memory related with an address */ + if ((mce->status & 0xefff) >> 7 != 1 || !(mce->status & MCI_STATUS_ADDRV)) + return NOTIFY_DONE; + + memset(&res, 0, sizeof(res)); + res.addr = mce->addr; + + if (adxl_component_count) { + if (!skx_adxl_decode(&res)) + return NOTIFY_DONE; + + mci = get_mci(res.socket, res.imc); + } else { + if (!skx_decode || !skx_decode(&res)) + return NOTIFY_DONE; + + mci = res.dev->imc[res.imc].mci; + } + + if (!mci) + return NOTIFY_DONE; + + if (mce->mcgstatus & MCG_STATUS_MCIP) + type = "Exception"; + else + type = "Event"; + + skx_mc_printk(mci, KERN_DEBUG, "HANDLING MCE MEMORY ERROR\n"); + + skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: 0x%llx " + "Bank %d: 0x%llx\n", mce->extcpu, type, + mce->mcgstatus, mce->bank, mce->status); + skx_mc_printk(mci, KERN_DEBUG, "TSC 0x%llx ", mce->tsc); + skx_mc_printk(mci, KERN_DEBUG, "ADDR 0x%llx ", mce->addr); + skx_mc_printk(mci, KERN_DEBUG, "MISC 0x%llx ", mce->misc); + + skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:0x%x TIME %llu SOCKET " + "%u APIC 0x%x\n", mce->cpuvendor, mce->cpuid, + mce->time, mce->socketid, mce->apicid); + + skx_mce_output_error(mci, mce, &res); + + return NOTIFY_DONE; +} + +static void skx_remove(void) +{ + int i, j; + struct skx_dev *d, *tmp; + + edac_dbg(0, "\n"); + + list_for_each_entry_safe(d, tmp, &dev_edac_list, list) { + list_del(&d->list); + for (i = 0; i < NUM_IMC; i++) { + if (d->imc[i].mci) + skx_unregister_mci(&d->imc[i]); + + if (d->imc[i].mdev) + pci_dev_put(d->imc[i].mdev); + + if (d->imc[i].mbase) + iounmap(d->imc[i].mbase); + + for (j = 0; j < NUM_CHANNELS; j++) { + if (d->imc[i].chan[j].cdev) + pci_dev_put(d->imc[i].chan[j].cdev); + } + } + if (d->util_all) + pci_dev_put(d->util_all); + if (d->sad_all) + pci_dev_put(d->sad_all); + if (d->uracu) + pci_dev_put(d->uracu); + + kfree(d); + } +} #ifdef CONFIG_EDAC_DEBUG -void setup_skx_debug(const char *dirname); -void teardown_skx_debug(void); +/* + * Debug feature. + * Exercise the address decode logic by writing an address to + * /sys/kernel/debug/edac/dirname/addr. + */ +static struct dentry *skx_test; + +static int debugfs_u64_set(void *data, u64 val) +{ + struct mce m; + + pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); + + memset(&m, 0, sizeof(m)); + /* ADDRV + MemRd + Unknown channel */ + m.status = MCI_STATUS_ADDRV + 0x90; + /* One corrected error */ + m.status |= BIT_ULL(MCI_STATUS_CEC_SHIFT); + m.addr = val; + skx_mce_check_error(NULL, 0, &m); + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); + +static void setup_skx_debug(const char *dirname) +{ + skx_test = edac_debugfs_create_dir(dirname); + if (!skx_test) + return; + + if (!edac_debugfs_create_file("addr", 0200, skx_test, + NULL, &fops_u64_wo)) { + debugfs_remove(skx_test); + skx_test = NULL; + } +} + +static void teardown_skx_debug(void) +{ + debugfs_remove_recursive(skx_test); +} #else static inline void setup_skx_debug(const char *dirname) {} static inline void teardown_skx_debug(void) {} #endif /*CONFIG_EDAC_DEBUG*/ - #endif /* _SKX_COMM_EDAC_H */ diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_edac.c similarity index 98% rename from drivers/edac/skx_base.c rename to drivers/edac/skx_edac.c index adae4c848ca1..2769d9d340c4 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_edac.c @@ -11,6 +11,11 @@ #include #include "edac_module.h" + +struct decoded_addr; +typedef bool (*skx_decode_f)(struct decoded_addr *res); +static skx_decode_f skx_decode; + #include "skx_common.h" #define EDAC_MOD_STR "skx_edac" @@ -529,7 +534,7 @@ static bool skx_mad_decode(struct decoded_addr *r) return true; } -static bool skx_decode(struct decoded_addr *res) +static bool skx_imc_decode(struct decoded_addr *res) { return skx_sad_decode(res) && skx_tad_decode(res) && skx_rir_decode(res) && skx_mad_decode(res); @@ -611,7 +616,7 @@ static int __init skx_init(void) } } - skx_set_decode(skx_decode); + skx_decode = skx_imc_decode; if (nvdimm_count && skx_adxl_get() == -ENODEV) skx_printk(KERN_NOTICE, "Only decoding DDR4 address!\n"); -- 2.19.1