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: [v1] EDAC, armv8: Add Cache Error Reporting driver for ARMv8 processors From: Kyle Yan Message-Id: <3d3da849d32b1a674d1bcd560eeba261@codeaurora.org> Date: Mon, 15 Jan 2018 17:00:08 -0800 To: Mark Rutland Cc: suzuki.poulose@arm.com, james.morse@arm.com, bp@alien8.de, mchehab@kernel.org, linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org List-ID: T24gMjAxOC0wMS0xNSAwNjo0NCwgTWFyayBSdXRsYW5kIHdyb3RlOgo+IEhpLAo+IAo+IE9uIEZy aSwgSmFuIDEyLCAyMDE4IGF0IDA0OjUwOjI2UE0gLTA4MDAsIEt5bGUgWWFuIHdyb3RlOgo+PiBJ bnRlcnJ1cHQgYmFzZWQgRURBQyBkcml2ZXIgZm9yIEFSTXY4IHByb2Nlc3NvcnMgdGhhdCBpbXBs ZW1lbnQKPj4gUkFTIGZvciBlcnJvciBkZXRlY3Rpb24gb2YgQ1BVIGNhY2hlcyBhbmQgbHNvIGFs bG93cyBvcHRpb25hbCBwb2xsaW5nCj4+IG9mIGVycm9yIHN5bmRyb21lIHJlZ2lzdGVycyBpZiBp bnRlcnJ1cHRzIGFyZSBub3Qgc3VwcG9ydGVkLgo+IAo+IElzIHRoaXMgdXNpbmcgdGhlIGFyY2hp dGVjdHVyYWwgUkFTIGV4dGVuc2lvbnMsIG9yIHNvbWV0aGluZyBzcGVjaWZpYyAKPiB0bwo+IFFD IENQVXM/IEl0IHdvdWxkIGJlIGdvb2QgdG8gY2FsbCB0aGlzIG91dCBleHBsaWNpdGx5Lgo+IAo+ IElmIGl0J3MgdGhlIGxhdHRlciwgdGhpcyBuZWVkcyByZXdvcmRpbmcgdG8gYmUgY2xlYXIgdGhh dCB0aGlzIGlzCj4gc3BlY2lmaWMgdG8gUUMgQ1BVcywgYW5kIGlzIG5vdCBhIGdlbmVyaWMgQVJN djggZmVhdHVyZS4KPiAKVGhpcyBpcyBub3Qgc3BlY2lmaWMgdG8gUUMgQ1BVcyBhbmQgbG9va3Mg YXQgdGhlIHN5c3RlbSByZWdpc3RlcnMgCmRlZmluZWQgYnkgdGhlIFJBUyBleHRlbnNpb25zLgoK PiBJcyB0aGVyZSBhbnkgaW50ZXJhY3Rpb24gd2l0aCBTREVJIHRoYXQgd2UgbmVlZCB0byBiZSBh d2FyZSBvZj8KSSBkbyBub3QgYmVsaWV2ZSBzby4gSW5zdGVhZCBvZiBiZWluZyBmaXJtd2FyZS1m aXJzdCwgdGhpcyBpcyBtb3JlIG1lYW50IAp0byBiZSBrZXJuZWwtZmlyc3QgaW1wbGVtZW50YXRp b24uCgo+PiAKPj4gU2lnbmVkLW9mZi1ieTogS3lsZSBZYW4gPGt5YW5AY29kZWF1cm9yYS5vcmc+ Cj4+IC0tLQo+PiAgZHJpdmVycy9lZGFjL0tjb25maWcgICAgICB8ICAyMSArKwo+PiAgZHJpdmVy cy9lZGFjL01ha2VmaWxlICAgICB8ICAgMSArCj4+ICBkcml2ZXJzL2VkYWMvYXJtdjhfZWRhYy5j IHwgNDg5IAo+PiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr Cj4gCj4gSSBzZWUgdGhhdCB0aGVyZSdzIERUIHBhcnNpbmcgY29kZSwgYnV0IG5vIGJpbmRpbmcu IFBsZWFzZSBhZGQgb25lLCBhcwo+IHBlciBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGlu Z3Mvc3VibWl0dGluZy1wYXRjaGVzLnR4dC4KPiAKV2lsbCBkby4KPiBJZiB0aGlzIGlzIGFyY2hp dGVjdHVyYWwsIGhvdyBpcyB0aGlzIGV4cGVjdGVkIHRvIHdvcmsgb24gQUNQSSBzeXN0ZW1zPwo+ IApUaGUgY3VycmVudCBkZXNpZ24gb2YgdGhpcyBkcml2ZXIgaGFzIG9ubHkgYmVlbiB0ZXN0ZWQv dXNlZCBvbiBtb2JpbGUgCmRldmljZXMgc28gSSBkbyBub3QgeWV0IGtub3cgaG93IGl0IHdpbGwg d29yayBvbiBBQ1BJIHN5c3RlbXMuCgo+PiAgMyBmaWxlcyBjaGFuZ2VkLCA1MTEgaW5zZXJ0aW9u cygrKQo+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZWRhYy9hcm12OF9lZGFjLmMKPj4g Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvS2NvbmZpZyBiL2RyaXZlcnMvZWRhYy9LY29u ZmlnCj4+IGluZGV4IDk2YWZiMmEuLjQ3YTY4ZTMgMTAwNjQ0Cj4+IC0tLSBhL2RyaXZlcnMvZWRh Yy9LY29uZmlnCj4+ICsrKyBiL2RyaXZlcnMvZWRhYy9LY29uZmlnCj4+IEBAIC00NTcsNCArNDU3 LDI1IEBAIGNvbmZpZyBFREFDX1hHRU5FCj4+ICAJICBTdXBwb3J0IGZvciBlcnJvciBkZXRlY3Rp b24gYW5kIGNvcnJlY3Rpb24gb24gdGhlCj4+ICAJICBBUE0gWC1HZW5lIGZhbWlseSBvZiBTT0Nz Lgo+PiAKPj4gK2NvbmZpZyBFREFDX0FSTVY4Cj4+ICsJZGVwZW5kcyBvbiAoQVJNIHx8IEFSTTY0 KQo+PiArCXRyaXN0YXRlICJBUk12OCBMMS9MMi9MMy9TQ1UgQ2FjaGVzIEVDQyIKPj4gKwloZWxw Cj4+ICsJICAgU3VwcG9ydCBmb3IgZXJyb3IgZGV0ZWN0aW9uIGFuZCBjb3JyZWN0aW9uIG9uIEFS TXY4IGNvcmVzCj4+ICsJICAgc3VwcG9ydGluZyBSQVMgZmVhdHVyZXMuIFJlcG9ydHMgZXJyb3Jz IGNhdWdodCBieSBBUk12OAo+PiArCSAgIEVDQyBtZWNoYW5pc20uCj4+ICsJICAgRm9yIGRlYnVn Z2luZyBpc3N1ZXMgaGF2aW5nIHRvIGRvIHdpdGggc3RhYmlsaXR5IGFuZCBvdmVyYWxsIAo+PiBz eXN0ZW0KPj4gKwkgICBoZWFsdGgsIHlvdSBzaG91bGQgcHJvYmFibHkgc2F5ICdZJyBoZXJlLgo+ PiArCj4+ICtjb25maWcgRURBQ19BUk1WOF9QT0xMCj4+ICsJZGVwZW5kcyBvbiBFREFDX0FSTVY4 Cj4+ICsJYm9vbCAiUG9sbCBvbiBBUk12OCBFQ0MgcmVnaXN0ZXJzIgo+PiArCWhlbHAKPj4gKwkg ICBUaGlzIG9wdGlvbiBjaG9vc2VzIHdoZXRoZXIgb3Igbm90IHlvdSB3YW50IHRvIHBvbGwgb24g dGhlIAo+PiBLcnlvM3h4Cj4+ICsJICAgRUNDIHJlZ2lzdGVycy4KPiAKPiBBcmUgdGhlc2UgcmVn aXN0ZXJzIHNwZWNpZmljIHRvIEtyeW8zeHggKGkuZS4gSU1QTEVNRU5UQVRJT04gREVGSU5FRCks Cj4gb3IgYXJlIHRoZXkgZGVmaW5lZCBieSB0aGUgUkFTIGV4dGVuc2lvbnM/Cj4gCk9vcHMhIFR5 cG8gaGVyZS4gVGhlIHJlZ2lzdGVycyBhcmUgZGVmaW5lZCBieSBSQVMgZXh0ZW5zaW9ucy4KCj4+ ICAgICAgICAgIFdoZW4gdGhpcyBpcyBlbmFibGVkLCB0aGUgcG9sbGluZyByYXRlIGNhbiBiZSBz ZXQgYXMKPj4gKwkgICBhIG1vZHVsZSBwYXJhbWV0ZXIuIEJ5IGRlZmF1bHQsIGl0IHdpbGwgY2Fs bCB0aGUgcG9sbGluZyBmdW5jdGlvbgo+PiArCSAgIGV2ZXJ5IHNlY29uZC4KPj4gKwkgICBUaGlz IG9wdGlvbiBzaG91bGQgb25seSBiZSB1c2VkIGlmIHRoZSBhc3NvY2lhdGVkIGludGVycnVwdCBs aW5lcwo+PiArCSAgIGFyZSBub3QgZW5hYmxlZC4KPj4gKwo+PiAgZW5kaWYgIyBFREFDCj4+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2VkYWMvTWFrZWZpbGUgYi9kcml2ZXJzL2VkYWMvTWFrZWZpbGUK Pj4gaW5kZXggMGZkOWZmYS4uNTcxMTNiYSAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9lZGFjL01h a2VmaWxlCj4+ICsrKyBiL2RyaXZlcnMvZWRhYy9NYWtlZmlsZQo+PiBAQCAtNDMsNiArNDMsNyBA QCBvYmotJChDT05GSUdfRURBQ19JRTMxMjAwKQkJKz0gaWUzMTIwMF9lZGFjLm8KPj4gIG9iai0k KENPTkZJR19FREFDX1gzOCkJCQkrPSB4MzhfZWRhYy5vCj4+ICBvYmotJChDT05GSUdfRURBQ19J ODI4NjApCQkrPSBpODI4NjBfZWRhYy5vCj4+ICBvYmotJChDT05GSUdfRURBQ19SODI2MDApCQkr PSByODI2MDBfZWRhYy5vCj4+ICtvYmotJChDT05GSUdfRURBQ19BUk1WOCkJCSs9IGFybXY4X2Vk YWMubwo+PiAKPj4gIGFtZDY0X2VkYWNfbW9kLXkgOj0gYW1kNjRfZWRhYy5vCj4+ICBhbWQ2NF9l ZGFjX21vZC0kKENPTkZJR19FREFDX0RFQlVHKSArPSBhbWQ2NF9lZGFjX2RiZy5vCj4+IGRpZmYg LS1naXQgYS9kcml2ZXJzL2VkYWMvYXJtdjhfZWRhYy5jIGIvZHJpdmVycy9lZGFjL2FybXY4X2Vk YWMuYwo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwLi5kOTg2YzQ3Cj4+ IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9lZGFjL2FybXY4X2VkYWMuYwo+PiBAQCAt MCwwICsxLDQ4OSBAQAo+PiArLyogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTgsIFRoZSBMaW51eCBG b3VuZGF0aW9uLiBBbGwgcmlnaHRzIAo+PiByZXNlcnZlZC4KPj4gKyAqCj4+ICsgKiBUaGlzIHBy b2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIAo+ PiBtb2RpZnkKPj4gKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVi bGljIExpY2Vuc2UgdmVyc2lvbiAyIGFuZAo+PiArICogb25seSB2ZXJzaW9uIDIgYXMgcHVibGlz aGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCj4+ICsgKgo+PiArICogVGhpcyBw cm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWws Cj4+ICsgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGll ZCB3YXJyYW50eSBvZgo+PiArICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFS VElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQo+PiArICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vu c2UgZm9yIG1vcmUgZGV0YWlscy4KPj4gKyAqLwo+PiArCj4+ICsjaW5jbHVkZSA8bGludXgva2Vy bmVsLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvZWRhYy5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L29m X2RldmljZS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+PiArI2lu Y2x1ZGUgPGxpbnV4L3NtcC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2NwdS5oPgo+PiArI2luY2x1 ZGUgPGxpbnV4L2NwdV9wbS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+PiAr I2luY2x1ZGUgPGxpbnV4L29mX2lycS5oPgo+PiArCj4+ICsjaW5jbHVkZSAiZWRhY19tYy5oIgo+ PiArI2luY2x1ZGUgImVkYWNfZGV2aWNlLmgiCj4+ICsKPj4gK3N0YXRpYyBpbnQgcG9sbF9tc2Vj ID0gMTAwMDsKPj4gK21vZHVsZV9wYXJhbShwb2xsX21zZWMsIGludCwgMDQ0NCk7Cj4+ICsKPj4g K3N0YXRpYyBib29sIHBhbmljX29uX3VlID0gMDsKPj4gK21vZHVsZV9wYXJhbV9uYW1lZChwYW5p Y19vbl91ZSwgcGFuaWNfb25fdWUsIGJvb2wsIDA2NjQpOwo+PiArCj4+ICsjZGVmaW5lIEwxIDB4 MAo+PiArI2RlZmluZSBMMiAweDEKPj4gKyNkZWZpbmUgTDMgMHgyCj4+ICsKPj4gKyNkZWZpbmUg RURBQ19DUFUJImFybXY4X2VkYWMiCj4+ICsKPj4gKyNkZWZpbmUgRVJSWFNUQVRVU19WQUxJRChh KQkoKGEgPj4gMzApICYgMHgxKQo+PiArI2RlZmluZSBFUlJYU1RBVFVTX1VFKGEpCSgoYSA+PiAy OSkgJiAweDEpCj4+ICsjZGVmaW5lIEVSUlhTVEFUVVNfU0VSUihhKQkoYSAmIDB4RkYpCj4+ICsK Pj4gKyNkZWZpbmUgRVJSWE1JU0NfTFZMKGEpCQkoKGEgPj4gMSkgJiAweDcpCj4+ICsjZGVmaW5l IEVSUlhNSVNDX1dBWShhKQkJKChhID4+IDI4KSAmIDB4RikKPj4gKwo+PiArI2RlZmluZSBFUlJY Q1RMUl9FTkFCTEUJCTB4MTBmCj4+ICsjZGVmaW5lIEVSUlhNSVNDX09WRVJGTE9XCTB4N0Y3RjAw MDAwMDAwVUxMCj4+ICsKPj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBzZXRfZXJyeGN0bHJfZWwxKHZv aWQpCj4+ICt7Cj4+ICsJYXNtIHZvbGF0aWxlKCJtc3IgczNfMF9jNV9jNF8xLCAlMCIgOiA6ICJy IiAoRVJSWENUTFJfRU5BQkxFKSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBz ZXRfZXJyeG1pc2Nfb3ZlcmZsb3codm9pZCkKPj4gK3sKPj4gKwlhc20gdm9sYXRpbGUoIm1zciBz M18wX2M1X2M1XzAsICUwIiA6IDogInIiIChFUlJYTUlTQ19PVkVSRkxPVykpOwo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgaW5saW5lIHZvaWQgd3JpdGVfZXJyc2Vscl9lbDEodTY0IHZhbCkKPj4gK3sK Pj4gKwlhc20gdm9sYXRpbGUoIm1zciBzM18wX2M1X2MzXzEsICUwIiA6IDogInIiICh2YWwpKTsK Pj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSB1NjQgcmVhZF9lcnJ4c3RhdHVzX2VsMSh2b2lk KQo+PiArewo+PiArCXU2NCB2YWw7Cj4+ICsKPj4gKwlhc20gdm9sYXRpbGUoIm1ycyAlMCwgczNf MF9jNV9jNF8yIiA6ICI9ciIgKHZhbCkpOwo+PiArCXJldHVybiB2YWw7Cj4+ICt9Cj4+ICsKPj4g K3N0YXRpYyBpbmxpbmUgdTY0IHJlYWRfZXJyeG1pc2NfZWwxKHZvaWQpCj4+ICt7Cj4+ICsJdTY0 IHZhbDsKPj4gKwo+PiArCWFzbSB2b2xhdGlsZSgibXJzICUwLCBzM18wX2M1X2M1XzAiIDogIj1y IiAodmFsKSk7Cj4+ICsJcmV0dXJuIHZhbDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGlubGluZSB2 b2lkIGNsZWFyX2VycnhzdGF0dXNfdmFsaWQodTY0IHZhbCkKPj4gK3sKPj4gKwlhc20gdm9sYXRp bGUoIm1zciBzM18wX2M1X2M0XzIsICUwIiA6IDogInIiICh2YWwpKTsKPj4gK30KPiAKPiBQbGVh c2UgdXNlIHtyZWFkLHdyaXRlfV9zeXNyZWcoKS4KPiAKPiBJZiB0aGVzZSByZWdpc3RlcnMgYXJl IGRlZmluZWQgYnkgQVJNdjgsIHBsZWFzZSBwbGFjZSBkZWZpbml0aW9ucyBpbgo+IGFybTY0J3Mg PGFzbS9zeXNyZWcuaD4uCj4gCldpbGwgZG8uCj4+ICsKPj4gK3N0cnVjdCBlcnJvcnNfZWRhYyB7 Cj4+ICsJY29uc3QgY2hhciAqIGNvbnN0IG1zZzsKPj4gKwl2b2lkICgqZnVuYykoc3RydWN0IGVk YWNfZGV2aWNlX2N0bF9pbmZvICplZGFjX2RldiwKPj4gKwkJCWludCBpbnN0X25yLCBpbnQgYmxv Y2tfbnIsIGNvbnN0IGNoYXIgKm1zZyk7Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3Ry dWN0IGVycm9yc19lZGFjIGVycm9yc1tdID0gewo+PiArCXsgIkwxIENvcnJlY3RhYmxlIEVycm9y IiwgZWRhY19kZXZpY2VfaGFuZGxlX2NlIH0sCj4+ICsJeyAiTDEgVW5jb3JyZWN0YWJsZSBFcnJv ciIsIGVkYWNfZGV2aWNlX2hhbmRsZV91ZSB9LAo+PiArCXsgIkwyIENvcnJlY3RhYmxlIEVycm9y IiwgZWRhY19kZXZpY2VfaGFuZGxlX2NlIH0sCj4+ICsJeyAiTDIgVW5jb3JyZWN0YWJsZSBFcnJv ciIsIGVkYWNfZGV2aWNlX2hhbmRsZV91ZSB9LAo+PiArCXsgIkwzIENvcnJlY3RhYmxlIEVycm9y IiwgZWRhY19kZXZpY2VfaGFuZGxlX2NlIH0sCj4+ICsJeyAiTDMgVW5jb3JyZWN0YWJsZSBFcnJv ciIsIGVkYWNfZGV2aWNlX2hhbmRsZV91ZSB9LAo+PiArfTsKPj4gKwo+PiArI2RlZmluZSBMMV9D RSAwCj4+ICsjZGVmaW5lIEwxX1VFIDEKPj4gKyNkZWZpbmUgTDJfQ0UgMgo+PiArI2RlZmluZSBM Ml9VRSAzCj4+ICsjZGVmaW5lIEwzX0NFIDQKPj4gKyNkZWZpbmUgTDNfVUUgNQo+PiArCj4+ICsj ZGVmaW5lIERBVEFfQlVGX0VSUgkJMHgyCj4+ICsjZGVmaW5lIENBQ0hFX0RBVEFfRVJSCQkweDYK Pj4gKyNkZWZpbmUgQ0FDSEVfVEFHX0RJUlRZX0VSUgkweDcKPj4gKyNkZWZpbmUgVExCX1BBUklU WV9FUlJfREFUQQkweDgKPj4gKyNkZWZpbmUgVExCX1BBUklUWV9FUlJfVEFHCTB4OQo+PiArI2Rl ZmluZSBCVVNfRVJST1IJCTB4MTIKPj4gKwo+PiArc3RydWN0IGVycF9kcnZkYXRhIHsKPj4gKwlz dHJ1Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8gKmVkZXZfY3RsOwo+PiArCXN0cnVjdCBlcnBfZHJ2 ZGF0YSBfX3BlcmNwdSAqKmVycF9jcHVfZHJ2ZGF0YTsKPj4gKwlzdHJ1Y3Qgbm90aWZpZXJfYmxv Y2sgbmJfcG07Cj4+ICsJaW50IHBwaTsKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZXJw X2RydmRhdGEgKnBhbmljX2hhbmRsZXJfZHJ2ZGF0YTsKPj4gKwo+PiArc3RhdGljIERFRklORV9T UElOTE9DSyhhcm12OF9lZGFjX2xvY2spOwo+PiArCj4+ICtzdGF0aWMgdm9pZCBsMV9sMl9pcnFf ZW5hYmxlKHZvaWQgKmluZm8pCj4+ICt7Cj4+ICsJaW50IGlycSA9ICooaW50ICopaW5mbzsKPj4g Kwo+PiArCWVuYWJsZV9wZXJjcHVfaXJxKGlycSwgSVJRX1RZUEVfTEVWRUxfSElHSCk7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcmVxdWVzdF9lcnBfaXJxKHN0cnVjdCBwbGF0Zm9ybV9kZXZp Y2UgKnBkZXYsIGNvbnN0IGNoYXIgCj4+ICpwcm9wbmFtZSwKPj4gKwkJCWNvbnN0IGNoYXIgKmRl c2MsIGlycV9oYW5kbGVyX3QgaGFuZGxlciwKPj4gKwkJCXZvaWQgKmVkLCBpbnQgcGVyY3B1KQo+ PiArewo+PiArCWludCByYzsKPj4gKwlzdHJ1Y3QgcmVzb3VyY2UgKnI7Cj4+ICsJc3RydWN0IGVy cF9kcnZkYXRhICpkcnYgPSBlZDsKPj4gKwo+PiArCXIgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2Vf YnluYW1lKHBkZXYsIElPUkVTT1VSQ0VfSVJRLCBwcm9wbmFtZSk7Cj4+ICsKPj4gKwlpZiAoIXIp IHsKPj4gKwkJcHJfZXJyKCJBUk12OCBDUFUgRVJQOiBDb3VsZCBub3QgZmluZCA8JXM+IElSUSBw cm9wZXJ0eS4gUHJvY2VlZGluZyAKPj4gYW55d2F5LlxuIiwKPj4gKwkJCXByb3BuYW1lKTsKPiAK PiBXaGF0IGlzICJFUlAiID8KPiAKRXJyb3IgUmVwb3J0aW5nLiBJIG1heSBqdXN0IHJlbmFtZSBp dCB0byBFREFDIG9yIGxpc3QgaXQgb3V0IGluIApEb2N1bWVudGF0aW9uLgo+PiArCQlnb3RvIG91 dDsKPj4gKwl9Cj4+ICsKPj4gKwlpZiAoIXBlcmNwdSkgewo+PiArCQlyYyA9IGRldm1fcmVxdWVz dF90aHJlYWRlZF9pcnEoJnBkZXYtPmRldiwgci0+c3RhcnQsIE5VTEwsCj4+ICsJCQkJCSAgICAg ICBoYW5kbGVyLAo+PiArCQkJCQkgICAgICAgSVJRRl9PTkVTSE9UIHwgSVJRRl9UUklHR0VSX0hJ R0gsCj4+ICsJCQkJCSAgICAgICBkZXNjLAo+PiArCQkJCQkgICAgICAgZWQpOwo+PiArCj4+ICsJ CWlmIChyYykgewo+PiArCQkJcHJfZXJyKCJBUk12OCBDUFUgRVJQOiBGYWlsZWQgdG8gcmVxdWVz dCBJUlEgJWQ6ICVkICglcyAvICVzKS4gCj4+IFByb2NlZWRpbmcgYW55d2F5LlxuIiwKPj4gKwkJ CSAgICAgICAoaW50KSByLT5zdGFydCwgcmMsIHByb3BuYW1lLCBkZXNjKTsKPj4gKwkJCWdvdG8g b3V0Owo+PiArCQl9Cj4+ICsKPj4gKwl9IGVsc2Ugewo+PiArCQlkcnYtPmVycF9jcHVfZHJ2ZGF0 YSA9IGFsbG9jX3BlcmNwdShzdHJ1Y3QgZXJwX2RydmRhdGEgKik7Cj4+ICsJCWlmICghZHJ2LT5l cnBfY3B1X2RydmRhdGEpIHsKPj4gKwkJCXByX2VycigiRmFpbGVkIHRvIGFsbG9jYXRlIHBlcmNw dSBlcnAgZGF0YVxuIik7Cj4+ICsJCQlnb3RvIG91dDsKPj4gKwkJfQo+PiArCj4+ICsJCSpyYXdf Y3B1X3B0cihkcnYtPmVycF9jcHVfZHJ2ZGF0YSkgPSBkcnY7Cj4+ICsJCXJjID0gcmVxdWVzdF9w ZXJjcHVfaXJxKHItPnN0YXJ0LCBoYW5kbGVyLCBkZXNjLAo+PiArCQkJCWRydi0+ZXJwX2NwdV9k cnZkYXRhKTsKPj4gKwo+PiArCQlpZiAocmMpIHsKPj4gKwkJCXByX2VycigiQVJNdjggQ1BVIEVS UDogRmFpbGVkIHRvIHJlcXVlc3QgSVJRICVkOiAlZCAoJXMgLyAlcykuIAo+PiBQcm9jZWVkaW5n IGFueXdheS5cbiIsCj4+ICsJCQkgICAgICAgKGludCkgci0+c3RhcnQsIHJjLCBwcm9wbmFtZSwg ZGVzYyk7Cj4+ICsJCQlnb3RvIG91dF9mcmVlOwo+PiArCQl9Cj4+ICsKPj4gKwkJZHJ2LT5wcGkg PSByLT5zdGFydDsKPj4gKwkJb25fZWFjaF9jcHUobDFfbDJfaXJxX2VuYWJsZSwgJihyLT5zdGFy dCksIDEpOwo+PiArCX0KPj4gKwo+PiArCXJldHVybiAwOwo+PiArCj4+ICtvdXRfZnJlZToKPj4g KwlmcmVlX3BlcmNwdShkcnYtPmVycF9jcHVfZHJ2ZGF0YSk7Cj4+ICsJZHJ2LT5lcnBfY3B1X2Ry dmRhdGEgPSBOVUxMOwo+PiArb3V0Ogo+PiArCXJldHVybiAxOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgdm9pZCBkdW1wX2Vycl9yZWcoaW50IGVycm9yY29kZSwgaW50IGxldmVsLCB1NjQgZXJyeHN0 YXR1cywgCj4+IHU2NCBlcnJ4bWlzYywKPj4gKwlzdHJ1Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8g KmVkZXZfY3RsKQo+PiArewo+PiArCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJF UlJYU1RBVFVTX0VMMTogJWxseFxuIiwgCj4+IGVycnhzdGF0dXMpOwo+PiArCWVkYWNfcHJpbnRr KEtFUk5fQ1JJVCwgRURBQ19DUFUsICJFUlJYTUlTQ19FTDE6ICVsbHhcbiIsIGVycnhtaXNjKTsK Pj4gKwllZGFjX3ByaW50ayhLRVJOX0NSSVQsIEVEQUNfQ1BVLCAiQ2FjaGUgbGV2ZWw6IEwlZFxu IiwgbGV2ZWwrMSk7Cj4+ICsKPj4gKwlzd2l0Y2ggKEVSUlhTVEFUVVNfU0VSUihlcnJ4c3RhdHVz KSkgewo+PiArCWNhc2UgREFUQV9CVUZfRVJSOgo+PiArCQllZGFjX3ByaW50ayhLRVJOX0NSSVQs IEVEQUNfQ1BVLCAiRUNDIEVycm9yIGZyb20gaW50ZXJuYWwgZGF0YSAKPj4gYnVmZmVyXG4iKTsK Pj4gKwkJYnJlYWs7Cj4+ICsKPj4gKwljYXNlIENBQ0hFX0RBVEFfRVJSOgo+PiArCQllZGFjX3By aW50ayhLRVJOX0NSSVQsIEVEQUNfQ1BVLCAiRUNDIEVycm9yIGZyb20gY2FjaGUgZGF0YSAKPj4g UkFNXG4iKTsKPj4gKwkJYnJlYWs7Cj4+ICsKPj4gKwljYXNlIENBQ0hFX1RBR19ESVJUWV9FUlI6 Cj4+ICsJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUsICJFQ0MgRXJyb3IgZnJvbSBj YWNoZSB0YWcgb3IgZGlydHkgCj4+IFJBTVxuIik7Cj4+ICsJCWJyZWFrOwo+PiArCj4+ICsJY2Fz ZSBUTEJfUEFSSVRZX0VSUl9EQVRBOgo+PiArCQllZGFjX3ByaW50ayhLRVJOX0NSSVQsIEVEQUNf Q1BVLCAiUGFyaXR5IGVycm9yIG9uIFRMQiBEQVRBIFJBTVxuIik7Cj4+ICsJCWJyZWFrOwo+PiAr Cj4+ICsJY2FzZSBUTEJfUEFSSVRZX0VSUl9UQUc6Cj4+ICsJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJ VCwgRURBQ19DUFUsICJQYXJpdHkgZXJyb3Igb24gVExCIFRBRyBSQU1cbiIpOwo+PiArCQlicmVh azsKPj4gKwo+PiArCWNhc2UgQlVTX0VSUk9SOgo+PiArCQllZGFjX3ByaW50ayhLRVJOX0NSSVQs IEVEQUNfQ1BVLCAiQnVzIEVycm9yXG4iKTsKPj4gKwkJYnJlYWs7Cj4+ICsJfQo+PiArCj4+ICsJ aWYgKGxldmVsID09IEwzKQo+PiArCQllZGFjX3ByaW50ayhLRVJOX0NSSVQsIEVEQUNfQ1BVLAo+ PiArCQkJIldheTogJWRcbiIsIChpbnQpIEVSUlhNSVNDX1dBWShlcnJ4bWlzYykpOwo+PiArCWVs c2UKPj4gKwkJZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQVSwKPj4gKwkJCSJXYXk6ICVk XG4iLCAoaW50KSBFUlJYTUlTQ19XQVkoZXJyeG1pc2MpID4+IDIpOwo+PiArCj4+ICsJZWRldl9j dGwtPnBhbmljX29uX3VlID0gcGFuaWNfb25fdWU7Cj4+ICsJZXJyb3JzW2Vycm9yY29kZV0uZnVu YyhlZGV2X2N0bCwgc21wX3Byb2Nlc3Nvcl9pZCgpLAo+PiArCQkJCWxldmVsLCBlcnJvcnNbZXJy b3Jjb2RlXS5tc2cpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBhcm12OF9wYXJzZV9sMV9s Ml9jYWNoZV9lcnJvcih1NjQgZXJyeHN0YXR1cywgdTY0IAo+PiBlcnJ4bWlzYywKPj4gKwlzdHJ1 Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8gKmVkZXZfY3RsKQo+PiArewo+PiArCXN3aXRjaCAoRVJS WE1JU0NfTFZMKGVycnhtaXNjKSkgewo+PiArCWNhc2UgTDE6Cj4+ICsJCWlmIChFUlJYU1RBVFVT X1VFKGVycnhzdGF0dXMpKQo+PiArCQkJZHVtcF9lcnJfcmVnKEwxX1VFLCBMMSwgZXJyeHN0YXR1 cywgZXJyeG1pc2MsCj4+ICsJCQkJCWVkZXZfY3RsKTsKPj4gKwkJZWxzZQo+PiArCQkJZHVtcF9l cnJfcmVnKEwxX0NFLCBMMSwgZXJyeHN0YXR1cywgZXJyeG1pc2MsCj4+ICsJCQkJCWVkZXZfY3Rs KTsKPj4gKwkJYnJlYWs7Cj4+ICsJY2FzZSBMMjoKPj4gKwkJaWYgKEVSUlhTVEFUVVNfVUUoZXJy eHN0YXR1cykpCj4+ICsJCQlkdW1wX2Vycl9yZWcoTDJfVUUsIEwyLCBlcnJ4c3RhdHVzLCBlcnJ4 bWlzYywKPj4gKwkJCQkJZWRldl9jdGwpOwo+PiArCQllbHNlCj4+ICsJCQlkdW1wX2Vycl9yZWco TDJfQ0UsIEwyLCBlcnJ4c3RhdHVzLCBlcnJ4bWlzYywKPj4gKwkJCQkJZWRldl9jdGwpOwo+PiAr CQlicmVhazsKPj4gKwlkZWZhdWx0Ogo+PiArCQllZGFjX3ByaW50ayhLRVJOX0NSSVQsIEVEQUNf Q1BVLCAiVW5rbm93biBFUlJYTUlTQ19MVkwgdmFsdWVcbiIpOwo+PiArCX0KPj4gK30KPj4gKwo+ PiArc3RhdGljIGJvb2wgYXJtdjhfY2hlY2tfbDFfbDJfZWNjKHZvaWQgKmluZm8pCj4+ICt7Cj4+ ICsJc3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICplZGV2X2N0bCA9IGluZm87Cj4+ICsJdTY0 IGVycnhzdGF0dXM7Cj4+ICsJdTY0IGVycnhtaXNjOwo+PiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7 Cj4+ICsKPj4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmYXJtdjhfZWRhY19sb2NrLCBmbGFncyk7Cj4+ ICsJd3JpdGVfZXJyc2Vscl9lbDEoMCk7Cj4+ICsJZXJyeHN0YXR1cyA9IHJlYWRfZXJyeHN0YXR1 c19lbDEoKTsKPj4gKwo+PiArCWlmIChFUlJYU1RBVFVTX1ZBTElEKGVycnhzdGF0dXMpKSB7Cj4+ ICsJCWVycnhtaXNjID0gcmVhZF9lcnJ4bWlzY19lbDEoKTsKPj4gKwkJZWRhY19wcmludGsoS0VS Tl9DUklULCBFREFDX0NQVSwKPj4gKwkJIkNQVSVkIGRldGVjdGVkIGEgTDEvTDIgY2FjaGUgZXJy b3JcbiIsCj4+ICsJCXNtcF9wcm9jZXNzb3JfaWQoKSk7Cj4+ICsKPj4gKwkJYXJtdjhfcGFyc2Vf bDFfbDJfY2FjaGVfZXJyb3IoZXJyeHN0YXR1cywgZXJyeG1pc2MsIGVkZXZfY3RsKTsKPj4gKwkJ Y2xlYXJfZXJyeHN0YXR1c192YWxpZChlcnJ4c3RhdHVzKTsKPj4gKwkJc3Bpbl91bmxvY2tfaXJx cmVzdG9yZSgmYXJtdjhfZWRhY19sb2NrLCBmbGFncyk7Cj4+ICsJCXJldHVybiB0cnVlOwo+PiAr CX0KPj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZhcm12OF9lZGFjX2xvY2ssIGZsYWdzKTsK Pj4gKwlyZXR1cm4gZmFsc2U7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBib29sIGFybXY4X2NoZWNr X2wzX3NjdV9lcnJvcihzdHJ1Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8gCj4+ICplZGV2X2N0bCkK Pj4gK3sKPj4gKwl1NjQgZXJyeHN0YXR1cyA9IDA7Cj4+ICsJdTY0IGVycnhtaXNjID0gMDsKPj4g Kwl1bnNpZ25lZCBsb25nIGZsYWdzOwo+PiArCj4+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJmFybXY4 X2VkYWNfbG9jaywgZmxhZ3MpOwo+PiArCXdyaXRlX2VycnNlbHJfZWwxKDEpOwo+PiArCWVycnhz dGF0dXMgPSByZWFkX2VycnhzdGF0dXNfZWwxKCk7Cj4+ICsJZXJyeG1pc2MgPSByZWFkX2Vycnht aXNjX2VsMSgpOwo+PiArCj4+ICsJaWYgKEVSUlhTVEFUVVNfVkFMSUQoZXJyeHN0YXR1cykgJiYK Pj4gKwkJRVJSWE1JU0NfTFZMKGVycnhtaXNjKSA9PSBMMykgewo+PiArCQlpZiAoRVJSWFNUQVRV U19VRShlcnJ4c3RhdHVzKSkgewo+PiArCQkJZWRhY19wcmludGsoS0VSTl9DUklULCBFREFDX0NQ VSwgIkRldGVjdGVkIEwzIHVuY29ycmVjdGFibGUgCj4+IGVycm9yXG4iKTsKPj4gKwkJCWR1bXBf ZXJyX3JlZyhMM19VRSwgTDMsIGVycnhzdGF0dXMsIGVycnhtaXNjLAo+PiArCQkJCWVkZXZfY3Rs KTsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCWVkYWNfcHJpbnRrKEtFUk5fQ1JJVCwgRURBQ19DUFUs ICJEZXRlY3RlZCBMMyBjb3JyZWN0YWJsZSAKPj4gZXJyb3JcbiIpOwo+PiArCQkJZHVtcF9lcnJf cmVnKEwzX0NFLCBMMywgZXJyeHN0YXR1cywgZXJyeG1pc2MsCj4+ICsJCQkJZWRldl9jdGwpOwo+ PiArCQl9Cj4+ICsKPj4gKwkJY2xlYXJfZXJyeHN0YXR1c192YWxpZChlcnJ4c3RhdHVzKTsKPj4g KwkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYXJtdjhfZWRhY19sb2NrLCBmbGFncyk7Cj4+ICsJ CXJldHVybiB0cnVlOwo+PiArCX0KPj4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZhcm12OF9l ZGFjX2xvY2ssIGZsYWdzKTsKPj4gKwlyZXR1cm4gZmFsc2U7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRp YyB2b2lkIGFybXY4X2NoZWNrX2wxX2wyX2VjY19oZWxwZXIodm9pZCAqaW5mbykKPj4gK3sKPj4g Kwlhcm12OF9jaGVja19sMV9sMl9lY2MoaW5mbyk7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgYXJtdjhf cG9sbF9jYWNoZV9lcnJvcnMoc3RydWN0IGVkYWNfZGV2aWNlX2N0bF9pbmZvICplZGV2X2N0bCkK Pj4gK3sKPj4gKwlpbnQgY3B1Owo+PiArCj4+ICsJaWYgKCFlZGV2X2N0bCkKPj4gKwkJZWRldl9j dGwgPSBwYW5pY19oYW5kbGVyX2RydmRhdGEtPmVkZXZfY3RsOwo+PiArCj4+ICsJYXJtdjhfY2hl Y2tfbDNfc2N1X2Vycm9yKGVkZXZfY3RsKTsKPj4gKwlmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1 KSB7Cj4+ICsJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIGFybXY4X2NoZWNrX2wxX2wy X2VjY19oZWxwZXIsCj4+ICsJCQllZGV2X2N0bCwgMCk7Cj4+ICsJfQo+PiArfQo+PiArCj4+ICtz dGF0aWMgaXJxcmV0dXJuX3QgYXJtdjhfbDFfbDJfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkcnZk YXRhKQo+PiArewo+PiArCWlmIChhcm12OF9jaGVja19sMV9sMl9lY2MocGFuaWNfaGFuZGxlcl9k cnZkYXRhLT5lZGV2X2N0bCkpCj4+ICsJCXJldHVybiBJUlFfSEFORExFRDsKPj4gKwlyZXR1cm4g SVJRX05PTkU7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBhcm12OF9sM19zY3Vf aGFuZGxlcihpbnQgaXJxLCB2b2lkICpkcnZkYXRhKQo+PiArewo+PiArCXN0cnVjdCBlcnBfZHJ2 ZGF0YSAqZHJ2ID0gZHJ2ZGF0YTsKPj4gKwlzdHJ1Y3QgZWRhY19kZXZpY2VfY3RsX2luZm8gKmVk ZXZfY3RsID0gZHJ2LT5lZGV2X2N0bDsKPj4gKwo+PiArCWlmIChhcm12OF9jaGVja19sM19zY3Vf ZXJyb3IoZWRldl9jdGwpKQo+PiArCQlyZXR1cm4gSVJRX0hBTkRMRUQ7Cj4+ICsJcmV0dXJuIElS UV9OT05FOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBpbml0aWFsaXplX3JlZ2lzdGVycyh2 b2lkICppbmZvKQo+PiArewo+PiArCXNldF9lcnJ4Y3Rscl9lbDEoKTsKPj4gKwlzZXRfZXJyeG1p c2Nfb3ZlcmZsb3coKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaW5pdF9yZWdzX29uX2Nw dShib29sIGFsbF9jcHVzKQo+PiArewo+PiArCWludCBjcHU7Cj4+ICsKPj4gKwl3cml0ZV9lcnJz ZWxyX2VsMSgwKTsKPj4gKwlpZiAoYWxsX2NwdXMpIHsKPj4gKwkJZm9yX2VhY2hfcG9zc2libGVf Y3B1KGNwdSkKPj4gKwkJCXNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIGluaXRpYWxpemVf cmVnaXN0ZXJzLAo+PiArCQkJCQkJTlVMTCwgMSk7Cj4+ICsJfSBlbHNlIHsKPj4gKwkJaW5pdGlh bGl6ZV9yZWdpc3RlcnMoTlVMTCk7Cj4+ICsJfQo+PiArCj4+ICsJd3JpdGVfZXJyc2Vscl9lbDEo MSk7Cj4+ICsJaW5pdGlhbGl6ZV9yZWdpc3RlcnMoTlVMTCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRp YyBpbnQgYXJtdjhfcG11X2NwdV9wbV9ub3RpZnkoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpzZWxm LAo+PiArCQkJCXVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2b2lkICp2KQo+PiArewo+PiArCXN3aXRj aCAoYWN0aW9uKSB7Cj4+ICsJY2FzZSBDUFVfUE1fRVhJVDoKPj4gKwkJaW5pdF9yZWdzX29uX2Nw dShmYWxzZSk7Cj4+ICsJCWFybXY4X2NoZWNrX2wzX3NjdV9lcnJvcihwYW5pY19oYW5kbGVyX2Ry dmRhdGEtPmVkZXZfY3RsKTsKPj4gKwkJYXJtdjhfY2hlY2tfbDFfbDJfZWNjKHBhbmljX2hhbmRs ZXJfZHJ2ZGF0YS0+ZWRldl9jdGwpOwo+PiArCQlicmVhazsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1 cm4gTk9USUZZX09LOwo+PiArfQo+IAo+IFdoYXQgYWJvdXQgQ1BVIGhvdHBsdWc/Cj4gCkFncmVl ZCB0aGF0IENQVSBob3RwbHVnIHdpbGwgYmUgcmVxdWlyZWQgZm9yIHRoZSBzbWFsbCB3aW5kb3cg YmV0d2VlbiAKaG90cGx1Z2dpbmcgYmFjayBpbiBhbmQgTFBNIGV4aXQuCgo+PiArCj4+ICtzdGF0 aWMgaW50IGFybXY4X2NwdV9lcnBfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikK Pj4gK3sKPj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+PiArCXN0cnVjdCBl cnBfZHJ2ZGF0YSAqZHJ2Owo+PiArCWludCByYyA9IDA7Cj4+ICsJaW50IGZhaWwgPSAwOwo+PiAr Cj4+ICsJaW5pdF9yZWdzX29uX2NwdSh0cnVlKTsKPj4gKwo+PiArCWRydiA9IGRldm1fa3phbGxv YyhkZXYsIHNpemVvZigqZHJ2KSwgR0ZQX0tFUk5FTCk7Cj4+ICsKPj4gKwlpZiAoIWRydikKPj4g KwkJcmV0dXJuIC1FTk9NRU07Cj4+ICsKPj4gKwlkcnYtPmVkZXZfY3RsID0gZWRhY19kZXZpY2Vf YWxsb2NfY3RsX2luZm8oMCwgImNwdSIsCj4+ICsJCQkJCW51bV9wb3NzaWJsZV9jcHVzKCksICJM IiwgMywgMSwgTlVMTCwgMCwKPj4gKwkJCQkJZWRhY19kZXZpY2VfYWxsb2NfaW5kZXgoKSk7Cj4+ ICsKPj4gKwlpZiAoIWRydi0+ZWRldl9jdGwpCj4+ICsJCXJldHVybiAtRU5PTUVNOwo+PiArCj4+ ICsJaWYgKElTX0VOQUJMRUQoQ09ORklHX0VEQUNfQVJNVjhfUE9MTCkpIHsKPj4gKwkJZHJ2LT5l ZGV2X2N0bC0+ZWRhY19jaGVjayA9IGFybXY4X3BvbGxfY2FjaGVfZXJyb3JzOwo+PiArCQlkcnYt PmVkZXZfY3RsLT5wb2xsX21zZWMgPSBwb2xsX21zZWM7Cj4+ICsJfQo+PiArCj4+ICsJZHJ2LT5l ZGV2X2N0bC0+ZGV2ID0gZGV2Owo+PiArCWRydi0+ZWRldl9jdGwtPm1vZF9uYW1lID0gZGV2X25h bWUoZGV2KTsKPj4gKwlkcnYtPmVkZXZfY3RsLT5kZXZfbmFtZSA9IGRldl9uYW1lKGRldik7Cj4+ ICsJZHJ2LT5lZGV2X2N0bC0+Y3RsX25hbWUgPSAiY2FjaGUiOwo+PiArCWRydi0+ZWRldl9jdGwt PnBhbmljX29uX3VlID0gcGFuaWNfb25fdWU7Cj4+ICsJZHJ2LT5uYl9wbS5ub3RpZmllcl9jYWxs ID0gYXJtdjhfcG11X2NwdV9wbV9ub3RpZnk7Cj4+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRl diwgZHJ2KTsKPj4gKwo+PiArCXJjID0gZWRhY19kZXZpY2VfYWRkX2RldmljZShkcnYtPmVkZXZf Y3RsKTsKPj4gKwlpZiAocmMpCj4+ICsJCWdvdG8gb3V0X21lbTsKPj4gKwo+PiArCXBhbmljX2hh bmRsZXJfZHJ2ZGF0YSA9IGRydjsKPj4gKwo+PiArCWlmICghSVNfRU5BQkxFRChDT05GSUdfRURB Q19BUk1WOF9QT0xMKSkgewo+PiArCQlmYWlsICs9IHJlcXVlc3RfZXJwX2lycShwZGV2LCAibDEt bDItaXJxIiwKPj4gKwkJCQkibDFfbDJfaXJxIiwKPj4gKwkJCQlhcm12OF9sMV9sMl9oYW5kbGVy LCBkcnYsIDEpOwo+PiArCj4+ICsJCWZhaWwgKz0gcmVxdWVzdF9lcnBfaXJxKHBkZXYsICJsMy1z Y3UtaXJxIiwKPj4gKwkJCQkibDNfc2N1X2lycSIsCj4+ICsJCQkJYXJtdjhfbDNfc2N1X2hhbmRs ZXIsIGRydiwgMCk7Cj4gCj4gU0NVIGlzbid0IGFuIGFyY2hpdGVjdHVyYWwgY29uY2VwdCwgYW5k IGEgY29tYmluZWQgbDEtbDIgaW50ZXJydXB0Cj4gc291bmRzIHZlcnkgc3BlY2lmaWMgdG8gYSBw YXJ0aWN1bGFyIGltcGxlbWVudGF0aW9uLgo+IApDYW4gZG8gYSByZW5hbWUgdG8gc29tZXRoaW5n IG1vcmUgYWtpbiB0byAicHJpdmF0ZV9jYWNoZV9pcnEiIGFuZCAKInNoYXJlZF9jYWNoZV9pcnEi LgoKPiBNeSB1bmRlcnN0YW5kaW5nIHdhcyB0aGF0IHdpdGggdGhlIFJBUyBleHRlbnNpb25zLCBT RXJyb3Igd291bGQgYmUgdXNlZAo+IHRvIG5vdGlmeSBvbiBSQVMgY29uZGl0aW9ucywgc28gSSdt IGNvbmZ1c2VkIGFzIHRvIHdoeSB3ZSdkIG5lZWQKPiByZWd1bGFyIGludGVycnVwdHMgaGVyZS4K PiAKVGhlcmUgbWF5IGJlIGNhc2VzIHdoZXJlIGludGVycnVwdHMgYXJlIHByZWZlcnJlZC4gVG8g bXkga25vd2xlZGdlIAoodGhvdWdoIEkgbWF5IG1pc3Rha2VuKSwgU0Vycm9ycyB3b3VsZCBub3Qg Y2F0Y2ggY29ycmVjdGFibGUgZXJyb3JzPwoKPj4gKwo+PiArCQlpZiAoZmFpbCA9PSBvZl9pcnFf Y291bnQoZGV2LT5vZl9ub2RlKSkgewo+PiArCQkJcHJfZXJyKCJFUlA6IENvdWxkIG5vdCByZXF1 ZXN0IGFueSBJUlFzLiBHaXZpbmcgdXAuXG4iKTsKPj4gKwkJCXJjID0gLUVOT0RFVjsKPj4gKwkJ CWdvdG8gb3V0X2RldjsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCWNwdV9wbV9yZWdpc3Rlcl9u b3RpZmllcigmKGRydi0+bmJfcG0pKTsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArCj4+ICtvdXRf ZGV2Ogo+PiArCWVkYWNfZGV2aWNlX2RlbF9kZXZpY2UoZGV2KTsKPj4gK291dF9tZW06Cj4+ICsJ ZWRhY19kZXZpY2VfZnJlZV9jdGxfaW5mbyhkcnYtPmVkZXZfY3RsKTsKPj4gKwlyZXR1cm4gcmM7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgYXJtdjhfY3B1X2VycF9yZW1vdmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikKPj4gK3sKPj4gKwlzdHJ1Y3QgZXJwX2RydmRhdGEgKmRydiA9 IGRldl9nZXRfZHJ2ZGF0YSgmcGRldi0+ZGV2KTsKPj4gKwlzdHJ1Y3QgZWRhY19kZXZpY2VfY3Rs X2luZm8gKmVkYWNfY3RsID0gZHJ2LT5lZGV2X2N0bDsKPj4gKwo+PiArCWlmIChkcnYtPmVycF9j cHVfZHJ2ZGF0YSkgewo+PiArCQlmcmVlX3BlcmNwdV9pcnEoZHJ2LT5wcGksIGRydi0+ZXJwX2Nw dV9kcnZkYXRhKTsKPj4gKwkJZnJlZV9wZXJjcHUoZHJ2LT5lcnBfY3B1X2RydmRhdGEpOwo+PiAr CX0KPj4gKwo+PiArCWVkYWNfZGV2aWNlX2RlbF9kZXZpY2UoZWRhY19jdGwtPmRldik7Cj4+ICsJ ZWRhY19kZXZpY2VfZnJlZV9jdGxfaW5mbyhlZGFjX2N0bCk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsK Pj4gK30KPj4gKwo+PiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgYXJtdjhfY3B1 X2VycF9tYXRjaF90YWJsZVtdID0gewo+PiArCXsgLmNvbXBhdGlibGUgPSAiYXJtLGFybXY4LWNw dS1lcnAiIH0sCj4+ICsJeyB9Cj4+ICt9Owo+IAo+IFRoaXMgbmVlZHMgYSBiaW5kaW5nIGRvY3Vt ZW50LCBsYXlpbmcgb3V0IHByZWNpc2VseSB3aGF0IHRoaXMgaXMKPiBpbnRlbmRlZCB0byBkZXNj cmliZS4KPiAKV2lsbCBkby4KPiBUaGFua3MsCj4gTWFyay4KPiAKPiBfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+IGxpbnV4LWFybS1rZXJuZWwgbWFpbGlu ZyBsaXN0Cj4gbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCj4gaHR0cDovL2xp c3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCi0tLQpU byB1bnN1YnNjcmliZSBmcm9tIHRoaXMgbGlzdDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUg bGludXgtZWRhYyIgaW4KdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtl cm5lbC5vcmcKTW9yZSBtYWpvcmRvbW8gaW5mbyBhdCAgaHR0cDovL3ZnZXIua2VybmVsLm9yZy9t YWpvcmRvbW8taW5mby5odG1sCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: kyan@codeaurora.org (Kyle Yan) Date: Mon, 15 Jan 2018 17:00:08 -0800 Subject: [PATCH v1] EDAC, armv8: Add Cache Error Reporting driver for ARMv8 processors In-Reply-To: <20180115144441.d6dlwl7herq24byv@lakrids.cambridge.arm.com> References: <1515804626-21254-1-git-send-email-kyan@codeaurora.org> <20180115144441.d6dlwl7herq24byv@lakrids.cambridge.arm.com> Message-ID: <3d3da849d32b1a674d1bcd560eeba261@codeaurora.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 2018-01-15 06:44, Mark Rutland wrote: > Hi, > > On Fri, Jan 12, 2018 at 04:50:26PM -0800, Kyle Yan wrote: >> Interrupt based EDAC driver for ARMv8 processors that implement >> RAS for error detection of CPU caches and lso allows optional polling >> of error syndrome registers if interrupts are not supported. > > Is this using the architectural RAS extensions, or something specific > to > QC CPUs? It would be good to call this out explicitly. > > If it's the latter, this needs rewording to be clear that this is > specific to QC CPUs, and is not a generic ARMv8 feature. > This is not specific to QC CPUs and looks at the system registers defined by the RAS extensions. > Is there any interaction with SDEI that we need to be aware of? I do not believe so. Instead of being firmware-first, this is more meant to be kernel-first implementation. >> >> Signed-off-by: Kyle Yan >> --- >> drivers/edac/Kconfig | 21 ++ >> drivers/edac/Makefile | 1 + >> drivers/edac/armv8_edac.c | 489 >> ++++++++++++++++++++++++++++++++++++++++++++++ > > I see that there's DT parsing code, but no binding. Please add one, as > per Documentation/devicetree/bindings/submitting-patches.txt. > Will do. > If this is architectural, how is this expected to work on ACPI systems? > The current design of this driver has only been tested/used on mobile devices so I do not yet know how it will work on ACPI systems. >> 3 files changed, 511 insertions(+) >> create mode 100644 drivers/edac/armv8_edac.c >> >> diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig >> index 96afb2a..47a68e3 100644 >> --- a/drivers/edac/Kconfig >> +++ b/drivers/edac/Kconfig >> @@ -457,4 +457,25 @@ config EDAC_XGENE >> Support for error detection and correction on the >> APM X-Gene family of SOCs. >> >> +config EDAC_ARMV8 >> + depends on (ARM || ARM64) >> + tristate "ARMv8 L1/L2/L3/SCU Caches ECC" >> + help >> + Support for error detection and correction on ARMv8 cores >> + supporting RAS features. Reports errors caught by ARMv8 >> + ECC mechanism. >> + For debugging issues having to do with stability and overall >> system >> + health, you should probably say 'Y' here. >> + >> +config EDAC_ARMV8_POLL >> + depends on EDAC_ARMV8 >> + bool "Poll on ARMv8 ECC registers" >> + help >> + This option chooses whether or not you want to poll on the >> Kryo3xx >> + ECC registers. > > Are these registers specific to Kryo3xx (i.e. IMPLEMENTATION DEFINED), > or are they defined by the RAS extensions? > Oops! Typo here. The registers are defined by RAS extensions. >> When this is enabled, the polling rate can be set as >> + a module parameter. By default, it will call the polling function >> + every second. >> + This option should only be used if the associated interrupt lines >> + are not enabled. >> + >> endif # EDAC >> diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile >> index 0fd9ffa..57113ba 100644 >> --- a/drivers/edac/Makefile >> +++ b/drivers/edac/Makefile >> @@ -43,6 +43,7 @@ obj-$(CONFIG_EDAC_IE31200) += ie31200_edac.o >> obj-$(CONFIG_EDAC_X38) += x38_edac.o >> obj-$(CONFIG_EDAC_I82860) += i82860_edac.o >> obj-$(CONFIG_EDAC_R82600) += r82600_edac.o >> +obj-$(CONFIG_EDAC_ARMV8) += armv8_edac.o >> >> amd64_edac_mod-y := amd64_edac.o >> amd64_edac_mod-$(CONFIG_EDAC_DEBUG) += amd64_edac_dbg.o >> diff --git a/drivers/edac/armv8_edac.c b/drivers/edac/armv8_edac.c >> new file mode 100644 >> index 0000000..d986c47 >> --- /dev/null >> +++ b/drivers/edac/armv8_edac.c >> @@ -0,0 +1,489 @@ >> +/* Copyright (c) 2016-2018, The Linux Foundation. All rights >> reserved. >> + * >> + * This program is free software; you can redistribute it and/or >> modify >> + * it under the terms of the GNU General Public License version 2 and >> + * only version 2 as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "edac_mc.h" >> +#include "edac_device.h" >> + >> +static int poll_msec = 1000; >> +module_param(poll_msec, int, 0444); >> + >> +static bool panic_on_ue = 0; >> +module_param_named(panic_on_ue, panic_on_ue, bool, 0664); >> + >> +#define L1 0x0 >> +#define L2 0x1 >> +#define L3 0x2 >> + >> +#define EDAC_CPU "armv8_edac" >> + >> +#define ERRXSTATUS_VALID(a) ((a >> 30) & 0x1) >> +#define ERRXSTATUS_UE(a) ((a >> 29) & 0x1) >> +#define ERRXSTATUS_SERR(a) (a & 0xFF) >> + >> +#define ERRXMISC_LVL(a) ((a >> 1) & 0x7) >> +#define ERRXMISC_WAY(a) ((a >> 28) & 0xF) >> + >> +#define ERRXCTLR_ENABLE 0x10f >> +#define ERRXMISC_OVERFLOW 0x7F7F00000000ULL >> + >> +static inline void set_errxctlr_el1(void) >> +{ >> + asm volatile("msr s3_0_c5_c4_1, %0" : : "r" (ERRXCTLR_ENABLE)); >> +} >> + >> +static inline void set_errxmisc_overflow(void) >> +{ >> + asm volatile("msr s3_0_c5_c5_0, %0" : : "r" (ERRXMISC_OVERFLOW)); >> +} >> + >> +static inline void write_errselr_el1(u64 val) >> +{ >> + asm volatile("msr s3_0_c5_c3_1, %0" : : "r" (val)); >> +} >> + >> +static inline u64 read_errxstatus_el1(void) >> +{ >> + u64 val; >> + >> + asm volatile("mrs %0, s3_0_c5_c4_2" : "=r" (val)); >> + return val; >> +} >> + >> +static inline u64 read_errxmisc_el1(void) >> +{ >> + u64 val; >> + >> + asm volatile("mrs %0, s3_0_c5_c5_0" : "=r" (val)); >> + return val; >> +} >> + >> +static inline void clear_errxstatus_valid(u64 val) >> +{ >> + asm volatile("msr s3_0_c5_c4_2, %0" : : "r" (val)); >> +} > > Please use {read,write}_sysreg(). > > If these registers are defined by ARMv8, please place definitions in > arm64's . > Will do. >> + >> +struct errors_edac { >> + const char * const msg; >> + void (*func)(struct edac_device_ctl_info *edac_dev, >> + int inst_nr, int block_nr, const char *msg); >> +}; >> + >> +static const struct errors_edac errors[] = { >> + { "L1 Correctable Error", edac_device_handle_ce }, >> + { "L1 Uncorrectable Error", edac_device_handle_ue }, >> + { "L2 Correctable Error", edac_device_handle_ce }, >> + { "L2 Uncorrectable Error", edac_device_handle_ue }, >> + { "L3 Correctable Error", edac_device_handle_ce }, >> + { "L3 Uncorrectable Error", edac_device_handle_ue }, >> +}; >> + >> +#define L1_CE 0 >> +#define L1_UE 1 >> +#define L2_CE 2 >> +#define L2_UE 3 >> +#define L3_CE 4 >> +#define L3_UE 5 >> + >> +#define DATA_BUF_ERR 0x2 >> +#define CACHE_DATA_ERR 0x6 >> +#define CACHE_TAG_DIRTY_ERR 0x7 >> +#define TLB_PARITY_ERR_DATA 0x8 >> +#define TLB_PARITY_ERR_TAG 0x9 >> +#define BUS_ERROR 0x12 >> + >> +struct erp_drvdata { >> + struct edac_device_ctl_info *edev_ctl; >> + struct erp_drvdata __percpu **erp_cpu_drvdata; >> + struct notifier_block nb_pm; >> + int ppi; >> +}; >> + >> +static struct erp_drvdata *panic_handler_drvdata; >> + >> +static DEFINE_SPINLOCK(armv8_edac_lock); >> + >> +static void l1_l2_irq_enable(void *info) >> +{ >> + int irq = *(int *)info; >> + >> + enable_percpu_irq(irq, IRQ_TYPE_LEVEL_HIGH); >> +} >> + >> +static int request_erp_irq(struct platform_device *pdev, const char >> *propname, >> + const char *desc, irq_handler_t handler, >> + void *ed, int percpu) >> +{ >> + int rc; >> + struct resource *r; >> + struct erp_drvdata *drv = ed; >> + >> + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, propname); >> + >> + if (!r) { >> + pr_err("ARMv8 CPU ERP: Could not find <%s> IRQ property. Proceeding >> anyway.\n", >> + propname); > > What is "ERP" ? > Error Reporting. I may just rename it to EDAC or list it out in Documentation. >> + goto out; >> + } >> + >> + if (!percpu) { >> + rc = devm_request_threaded_irq(&pdev->dev, r->start, NULL, >> + handler, >> + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, >> + desc, >> + ed); >> + >> + if (rc) { >> + pr_err("ARMv8 CPU ERP: Failed to request IRQ %d: %d (%s / %s). >> Proceeding anyway.\n", >> + (int) r->start, rc, propname, desc); >> + goto out; >> + } >> + >> + } else { >> + drv->erp_cpu_drvdata = alloc_percpu(struct erp_drvdata *); >> + if (!drv->erp_cpu_drvdata) { >> + pr_err("Failed to allocate percpu erp data\n"); >> + goto out; >> + } >> + >> + *raw_cpu_ptr(drv->erp_cpu_drvdata) = drv; >> + rc = request_percpu_irq(r->start, handler, desc, >> + drv->erp_cpu_drvdata); >> + >> + if (rc) { >> + pr_err("ARMv8 CPU ERP: Failed to request IRQ %d: %d (%s / %s). >> Proceeding anyway.\n", >> + (int) r->start, rc, propname, desc); >> + goto out_free; >> + } >> + >> + drv->ppi = r->start; >> + on_each_cpu(l1_l2_irq_enable, &(r->start), 1); >> + } >> + >> + return 0; >> + >> +out_free: >> + free_percpu(drv->erp_cpu_drvdata); >> + drv->erp_cpu_drvdata = NULL; >> +out: >> + return 1; >> +} >> + >> +static void dump_err_reg(int errorcode, int level, u64 errxstatus, >> u64 errxmisc, >> + struct edac_device_ctl_info *edev_ctl) >> +{ >> + edac_printk(KERN_CRIT, EDAC_CPU, "ERRXSTATUS_EL1: %llx\n", >> errxstatus); >> + edac_printk(KERN_CRIT, EDAC_CPU, "ERRXMISC_EL1: %llx\n", errxmisc); >> + edac_printk(KERN_CRIT, EDAC_CPU, "Cache level: L%d\n", level+1); >> + >> + switch (ERRXSTATUS_SERR(errxstatus)) { >> + case DATA_BUF_ERR: >> + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from internal data >> buffer\n"); >> + break; >> + >> + case CACHE_DATA_ERR: >> + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from cache data >> RAM\n"); >> + break; >> + >> + case CACHE_TAG_DIRTY_ERR: >> + edac_printk(KERN_CRIT, EDAC_CPU, "ECC Error from cache tag or dirty >> RAM\n"); >> + break; >> + >> + case TLB_PARITY_ERR_DATA: >> + edac_printk(KERN_CRIT, EDAC_CPU, "Parity error on TLB DATA RAM\n"); >> + break; >> + >> + case TLB_PARITY_ERR_TAG: >> + edac_printk(KERN_CRIT, EDAC_CPU, "Parity error on TLB TAG RAM\n"); >> + break; >> + >> + case BUS_ERROR: >> + edac_printk(KERN_CRIT, EDAC_CPU, "Bus Error\n"); >> + break; >> + } >> + >> + if (level == L3) >> + edac_printk(KERN_CRIT, EDAC_CPU, >> + "Way: %d\n", (int) ERRXMISC_WAY(errxmisc)); >> + else >> + edac_printk(KERN_CRIT, EDAC_CPU, >> + "Way: %d\n", (int) ERRXMISC_WAY(errxmisc) >> 2); >> + >> + edev_ctl->panic_on_ue = panic_on_ue; >> + errors[errorcode].func(edev_ctl, smp_processor_id(), >> + level, errors[errorcode].msg); >> +} >> + >> +static void armv8_parse_l1_l2_cache_error(u64 errxstatus, u64 >> errxmisc, >> + struct edac_device_ctl_info *edev_ctl) >> +{ >> + switch (ERRXMISC_LVL(errxmisc)) { >> + case L1: >> + if (ERRXSTATUS_UE(errxstatus)) >> + dump_err_reg(L1_UE, L1, errxstatus, errxmisc, >> + edev_ctl); >> + else >> + dump_err_reg(L1_CE, L1, errxstatus, errxmisc, >> + edev_ctl); >> + break; >> + case L2: >> + if (ERRXSTATUS_UE(errxstatus)) >> + dump_err_reg(L2_UE, L2, errxstatus, errxmisc, >> + edev_ctl); >> + else >> + dump_err_reg(L2_CE, L2, errxstatus, errxmisc, >> + edev_ctl); >> + break; >> + default: >> + edac_printk(KERN_CRIT, EDAC_CPU, "Unknown ERRXMISC_LVL value\n"); >> + } >> +} >> + >> +static bool armv8_check_l1_l2_ecc(void *info) >> +{ >> + struct edac_device_ctl_info *edev_ctl = info; >> + u64 errxstatus; >> + u64 errxmisc; >> + unsigned long flags; >> + >> + spin_lock_irqsave(&armv8_edac_lock, flags); >> + write_errselr_el1(0); >> + errxstatus = read_errxstatus_el1(); >> + >> + if (ERRXSTATUS_VALID(errxstatus)) { >> + errxmisc = read_errxmisc_el1(); >> + edac_printk(KERN_CRIT, EDAC_CPU, >> + "CPU%d detected a L1/L2 cache error\n", >> + smp_processor_id()); >> + >> + armv8_parse_l1_l2_cache_error(errxstatus, errxmisc, edev_ctl); >> + clear_errxstatus_valid(errxstatus); >> + spin_unlock_irqrestore(&armv8_edac_lock, flags); >> + return true; >> + } >> + spin_unlock_irqrestore(&armv8_edac_lock, flags); >> + return false; >> +} >> + >> +static bool armv8_check_l3_scu_error(struct edac_device_ctl_info >> *edev_ctl) >> +{ >> + u64 errxstatus = 0; >> + u64 errxmisc = 0; >> + unsigned long flags; >> + >> + spin_lock_irqsave(&armv8_edac_lock, flags); >> + write_errselr_el1(1); >> + errxstatus = read_errxstatus_el1(); >> + errxmisc = read_errxmisc_el1(); >> + >> + if (ERRXSTATUS_VALID(errxstatus) && >> + ERRXMISC_LVL(errxmisc) == L3) { >> + if (ERRXSTATUS_UE(errxstatus)) { >> + edac_printk(KERN_CRIT, EDAC_CPU, "Detected L3 uncorrectable >> error\n"); >> + dump_err_reg(L3_UE, L3, errxstatus, errxmisc, >> + edev_ctl); >> + } else { >> + edac_printk(KERN_CRIT, EDAC_CPU, "Detected L3 correctable >> error\n"); >> + dump_err_reg(L3_CE, L3, errxstatus, errxmisc, >> + edev_ctl); >> + } >> + >> + clear_errxstatus_valid(errxstatus); >> + spin_unlock_irqrestore(&armv8_edac_lock, flags); >> + return true; >> + } >> + spin_unlock_irqrestore(&armv8_edac_lock, flags); >> + return false; >> +} >> + >> +static void armv8_check_l1_l2_ecc_helper(void *info) >> +{ >> + armv8_check_l1_l2_ecc(info); >> +} >> + >> +void armv8_poll_cache_errors(struct edac_device_ctl_info *edev_ctl) >> +{ >> + int cpu; >> + >> + if (!edev_ctl) >> + edev_ctl = panic_handler_drvdata->edev_ctl; >> + >> + armv8_check_l3_scu_error(edev_ctl); >> + for_each_possible_cpu(cpu) { >> + smp_call_function_single(cpu, armv8_check_l1_l2_ecc_helper, >> + edev_ctl, 0); >> + } >> +} >> + >> +static irqreturn_t armv8_l1_l2_handler(int irq, void *drvdata) >> +{ >> + if (armv8_check_l1_l2_ecc(panic_handler_drvdata->edev_ctl)) >> + return IRQ_HANDLED; >> + return IRQ_NONE; >> +} >> + >> +static irqreturn_t armv8_l3_scu_handler(int irq, void *drvdata) >> +{ >> + struct erp_drvdata *drv = drvdata; >> + struct edac_device_ctl_info *edev_ctl = drv->edev_ctl; >> + >> + if (armv8_check_l3_scu_error(edev_ctl)) >> + return IRQ_HANDLED; >> + return IRQ_NONE; >> +} >> + >> +static void initialize_registers(void *info) >> +{ >> + set_errxctlr_el1(); >> + set_errxmisc_overflow(); >> +} >> + >> +static void init_regs_on_cpu(bool all_cpus) >> +{ >> + int cpu; >> + >> + write_errselr_el1(0); >> + if (all_cpus) { >> + for_each_possible_cpu(cpu) >> + smp_call_function_single(cpu, initialize_registers, >> + NULL, 1); >> + } else { >> + initialize_registers(NULL); >> + } >> + >> + write_errselr_el1(1); >> + initialize_registers(NULL); >> +} >> + >> +static int armv8_pmu_cpu_pm_notify(struct notifier_block *self, >> + unsigned long action, void *v) >> +{ >> + switch (action) { >> + case CPU_PM_EXIT: >> + init_regs_on_cpu(false); >> + armv8_check_l3_scu_error(panic_handler_drvdata->edev_ctl); >> + armv8_check_l1_l2_ecc(panic_handler_drvdata->edev_ctl); >> + break; >> + } >> + >> + return NOTIFY_OK; >> +} > > What about CPU hotplug? > Agreed that CPU hotplug will be required for the small window between hotplugging back in and LPM exit. >> + >> +static int armv8_cpu_erp_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct erp_drvdata *drv; >> + int rc = 0; >> + int fail = 0; >> + >> + init_regs_on_cpu(true); >> + >> + drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); >> + >> + if (!drv) >> + return -ENOMEM; >> + >> + drv->edev_ctl = edac_device_alloc_ctl_info(0, "cpu", >> + num_possible_cpus(), "L", 3, 1, NULL, 0, >> + edac_device_alloc_index()); >> + >> + if (!drv->edev_ctl) >> + return -ENOMEM; >> + >> + if (IS_ENABLED(CONFIG_EDAC_ARMV8_POLL)) { >> + drv->edev_ctl->edac_check = armv8_poll_cache_errors; >> + drv->edev_ctl->poll_msec = poll_msec; >> + } >> + >> + drv->edev_ctl->dev = dev; >> + drv->edev_ctl->mod_name = dev_name(dev); >> + drv->edev_ctl->dev_name = dev_name(dev); >> + drv->edev_ctl->ctl_name = "cache"; >> + drv->edev_ctl->panic_on_ue = panic_on_ue; >> + drv->nb_pm.notifier_call = armv8_pmu_cpu_pm_notify; >> + platform_set_drvdata(pdev, drv); >> + >> + rc = edac_device_add_device(drv->edev_ctl); >> + if (rc) >> + goto out_mem; >> + >> + panic_handler_drvdata = drv; >> + >> + if (!IS_ENABLED(CONFIG_EDAC_ARMV8_POLL)) { >> + fail += request_erp_irq(pdev, "l1-l2-irq", >> + "l1_l2_irq", >> + armv8_l1_l2_handler, drv, 1); >> + >> + fail += request_erp_irq(pdev, "l3-scu-irq", >> + "l3_scu_irq", >> + armv8_l3_scu_handler, drv, 0); > > SCU isn't an architectural concept, and a combined l1-l2 interrupt > sounds very specific to a particular implementation. > Can do a rename to something more akin to "private_cache_irq" and "shared_cache_irq". > My understanding was that with the RAS extensions, SError would be used > to notify on RAS conditions, so I'm confused as to why we'd need > regular interrupts here. > There may be cases where interrupts are preferred. To my knowledge (though I may mistaken), SErrors would not catch correctable errors? >> + >> + if (fail == of_irq_count(dev->of_node)) { >> + pr_err("ERP: Could not request any IRQs. Giving up.\n"); >> + rc = -ENODEV; >> + goto out_dev; >> + } >> + } >> + >> + cpu_pm_register_notifier(&(drv->nb_pm)); >> + >> + return 0; >> + >> +out_dev: >> + edac_device_del_device(dev); >> +out_mem: >> + edac_device_free_ctl_info(drv->edev_ctl); >> + return rc; >> +} >> + >> +static int armv8_cpu_erp_remove(struct platform_device *pdev) >> +{ >> + struct erp_drvdata *drv = dev_get_drvdata(&pdev->dev); >> + struct edac_device_ctl_info *edac_ctl = drv->edev_ctl; >> + >> + if (drv->erp_cpu_drvdata) { >> + free_percpu_irq(drv->ppi, drv->erp_cpu_drvdata); >> + free_percpu(drv->erp_cpu_drvdata); >> + } >> + >> + edac_device_del_device(edac_ctl->dev); >> + edac_device_free_ctl_info(edac_ctl); >> + >> + return 0; >> +} >> + >> +static const struct of_device_id armv8_cpu_erp_match_table[] = { >> + { .compatible = "arm,armv8-cpu-erp" }, >> + { } >> +}; > > This needs a binding document, laying out precisely what this is > intended to describe. > Will do. > Thanks, > Mark. > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel