LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: [PATCH 3/3] soc: fsl: add RCPM driver
From: Ran Wang @ 2018-09-10  3:31 UTC (permalink / raw)
  To: Leo Li
  Cc: Mark Rutland, dongsheng.wang@hxt-semitech.com,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, lkml,
	Rob Herring, linuxppc-dev,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CADRPPNTGrKBxzpbP05R0T3ovngYgQ4P_kgwgYwB6Aqrs8maXqw@mail.gmail.com>

SGkgTGVvLA0KDQpPbiAyMDE4LzkvNyA0OjUxLCBZYW5nIExpIHdyb3RlOg0KPiANCj4gT24gRnJp
LCBTZXAgNywgMjAxOCBhdCA0OjUxIEFNIFJhbiBXYW5nIDxyYW4ud2FuZ18xQG54cC5jb20+IHdy
b3RlOg0KPiA+DQo+ID4gSGkgTGVvLA0KPiA+DQo+ID4gT24gU2VwdGVtYmVyIDA1LCAyMDE4IGF0
IDExOjIyIFlhbmcgTGkgd3JvdGU6DQo+ID4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0K
PiA+ID4gRnJvbTogTGkgWWFuZyA8bGVveWFuZy5saUBueHAuY29tPg0KPiA+ID4gU2VudDogV2Vk
bmVzZGF5LCBTZXB0ZW1iZXIgMDUsIDIwMTggMTE6MjINCj4gPiA+IFRvOiBkb25nc2hlbmcud2Fu
Z0BoeHQtc2VtaXRlY2guY29tDQo+ID4gPiBDYzogUmFuIFdhbmcgPHJhbi53YW5nXzFAbnhwLmNv
bT47IFJvYiBIZXJyaW5nDQo+IDxyb2JoK2R0QGtlcm5lbC5vcmc+Ow0KPiA+ID4gTWFyayBSdXRs
YW5kIDxtYXJrLnJ1dGxhbmRAYXJtLmNvbT47IG9wZW4gbGlzdDpPUEVOIEZJUk1XQVJFIEFORA0K
PiA+ID4gRkxBVFRFTkVEIERFVklDRSBUUkVFIEJJTkRJTkdTIDxkZXZpY2V0cmVlQHZnZXIua2Vy
bmVsLm9yZz47DQo+ID4gPiBsaW51eHBwYy0gZGV2IDxsaW51eHBwYy1kZXZAbGlzdHMub3psYWJz
Lm9yZz47IGxrbWwNCj4gPiA+IDxsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnPjsgbW9kZXJh
dGVkIGxpc3Q6QVJNL0ZSRUVTQ0FMRSBJTVggLw0KPiA+ID4gTVhDIEFSTSBBUkNISVRFQ1RVUkUg
PGxpbnV4LWFybS0ga2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmc+DQo+ID4gPiBTdWJqZWN0OiBS
ZTogW1BBVENIIDMvM10gc29jOiBmc2w6IGFkZCBSQ1BNIGRyaXZlcg0KPiA+ID4NCj4gPiA+IE9u
IFR1ZSwgU2VwIDQsIDIwMTggYXQgOTo1OCBQTSBXYW5nLCBEb25nc2hlbmcNCj4gPGRvbmdzaGVu
Zy53YW5nQGh4dC0NCj4gPiA+IHNlbWl0ZWNoLmNvbT4gd3JvdGU6DQo+ID4gPiA+DQo+ID4gPiA+
IFBsZWFzZSBjaGFuZ2UgeW91ciBjb21tZW50cyBzdHlsZS4NCj4gPiA+DQo+ID4gPiBBbHRob3Vn
aCB0aGlzIGRvZXNuJ3QgZ2V0IGludG8gdGhlIExpbnV4IGtlcm5lbCBjb2Rpbmcgc3R5bGUNCj4g
PiA+IGRvY3VtZW50YXRpb24geWV0LCBMaW51cyBzZWVtcyBjaGFuZ2VkIGhpcyBtaW5kIHRvIHBy
ZWZlciAvLyB0aGFuIC8qDQo+ID4gPiAqLyBjb21tZW50IHN0eWxlIG5vdy4NCj4gPiA+IGh0dHBz
Oi8vZW1lYTAxLnNhZmVsaW5rcy5wcm90ZWN0aW9uLm91dGxvb2suY29tLz91cmw9aHR0cHMlM0El
MkYlMkZsDQo+ID4gPg0KPiBrbWwgLm9yZyUyRmxrbWwlMkYyMDE3JTJGMTElMkYyNSUyRjEzMyZh
bXA7ZGF0YT0wMiU3QzAxJTdDcmFuLncNCj4gYW5nXw0KPiA+ID4NCj4gMSU0MG54cC5jb20lN0Nj
MGQ4OGU2NjkwMzg0ZTAyYjk1MTA4ZDYxMmRlYzIzNSU3QzY4NmVhMWQzYmMyYjRjDQo+ID4gPg0K
PiA2ZmE5MmNkOTljNWMzMDE2MzUlN0MwJTdDMCU3QzYzNjcxNzE0NTI4NTEyNjIwMCZhbXA7c2Rh
dGE9SklvQ1pwDQo+ID4gPg0KPiBXaFJ5Vzc2RXFnU2ZsZlREQTFmMGdNUUdLYSUyRmNidlNjNUNP
JTJGdyUzRCZhbXA7cmVzZXJ2ZWQ9MA0KPiA+ID4gU28gdGhlDQo+ID4gPiAvLyBzdHlsZSBzaG91
bGQgYmUgYWNjZXB0YWJsZSBmb3Igbm93Lg0KPiA+ID4NCj4gPiA+ID4NCj4gPiA+ID4gT24gMjAx
OC84LzMxIDExOjU2LCBSYW4gV2FuZyB3cm90ZToNCj4gPiA+ID4gPiBUaGUgTlhQJ3MgUW9ySVEg
UHJvY2Vzc29ycyBiYXNlZCBvbiBBUk0gQ29yZSBoYXZlIFJDUE0gbW9kdWxlDQo+ID4gPiA+ID4g
KFJ1biBDb250cm9sIGFuZCBQb3dlciBNYW5hZ2VtZW50KSwgd2hpY2ggcGVyZm9ybXMgYWxsDQo+
ID4gPiA+ID4gZGV2aWNlLWxldmVsIHRhc2tzIGFzc29jaWF0ZWQgd2l0aCBwb3dlciBtYW5hZ2Vt
ZW50IHN1Y2ggYXMNCj4gd2FrZXVwIHNvdXJjZSBjb250cm9sLg0KPiA+ID4gPiA+DQo+ID4gPiA+
ID4gVGhpcyBkcml2ZXIgZGVwZW5kcyBvbiBGU0wgcGxhdGZvcm0gUE0gZHJpdmVyIGZyYW1ld29y
ayB3aGljaA0KPiA+ID4gPiA+IGhlbHAgdG8gaXNvbGF0ZSB1c2VyIGFuZCBQTSBzZXJ2aWNlIHBy
b3ZpZGVyIChzdWNoIGFzIFJDUE0gZHJpdmVyKS4NCj4gPiA+ID4gPg0KPiA+ID4gPiA+IFNpZ25l
ZC1vZmYtYnk6IENoZW5odWkgWmhhbyA8Y2hlbmh1aS56aGFvQG54cC5jb20+DQo+ID4gPiA+ID4g
U2lnbmVkLW9mZi1ieTogWWluZyBaaGFuZyA8eWluZy56aGFuZzIyNDU1QG54cC5jb20+DQo+ID4g
PiA+ID4gU2lnbmVkLW9mZi1ieTogUmFuIFdhbmcgPHJhbi53YW5nXzFAbnhwLmNvbT4NCj4gPiA+
ID4gPiAtLS0NCj4gPiA+ID4gPiAgZHJpdmVycy9zb2MvZnNsL0tjb25maWcgICB8ICAgIDYgKysN
Cj4gPiA+ID4gPiAgZHJpdmVycy9zb2MvZnNsL01ha2VmaWxlICB8ICAgIDEgKw0KPiA+ID4gPiA+
ICBkcml2ZXJzL3NvYy9mc2wvbHMtcmNwbS5jIHwgIDE1Mw0KPiA+ID4gPiA+ICsrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ID4gPiA+ICAzIGZpbGVzIGNo
YW5nZWQsIDE2MCBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKSAgY3JlYXRlIG1vZGUNCj4g
PiA+ID4gPiAxMDA2NDQgZHJpdmVycy9zb2MvZnNsL2xzLXJjcG0uYw0KPiA+ID4gPiA+DQo+ID4g
PiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL2ZzbC9LY29uZmlnIGIvZHJpdmVycy9zb2Mv
ZnNsL0tjb25maWcNCj4gPiA+ID4gPiBpbmRleCA2NTE3NDEyLi44ODIzMzBkIDEwMDY0NA0KPiA+
ID4gPiA+IC0tLSBhL2RyaXZlcnMvc29jL2ZzbC9LY29uZmlnDQo+ID4gPiA+ID4gKysrIGIvZHJp
dmVycy9zb2MvZnNsL0tjb25maWcNCj4gPiA+ID4gPiBAQCAtMzAsMyArMzAsOSBAQCBjb25maWcg
RlNMX1BMQVRfUE0NCj4gPiA+ID4gPiAgICAgICAgIGhhdmUgdG8ga25vdyB0aGUgaW1wbGVtZW50
IGRldGFpbHMgb2Ygd2FrZXVwIGZ1bmN0aW9uIGl0DQo+IHJlcXVpcmUuDQo+ID4gPiA+ID4gICAg
ICAgICBCZXNpZGVzLCBpdCBpcyBhbHNvIGVhc3kgZm9yIHNlcnZpY2Ugc2lkZSB0byB1cGdyYWRl
IGl0cyBsb2dpYyB3aGVuDQo+ID4gPiA+ID4gICAgICAgICBkZXNpZ24gY2hhbmdlZCBhbmQgcmVt
YWluIHVzZXIgc2lkZSB1bmNoYW5nZWQuDQo+ID4gPiA+ID4gKw0KPiA+ID4gPiA+ICtjb25maWcg
TFNfUkNQTQ0KPiA+ID4gPiA+ICsgICAgIGJvb2wgIkZyZWVzY2FsZSBSQ1BNIHN1cHBvcnQiDQo+
ID4gPiA+ID4gKyAgICAgZGVwZW5kcyBvbiAoRlNMX1BMQVRfUE0pDQo+ID4gPiA+ID4gKyAgICAg
aGVscA0KPiA+ID4gPiA+ICsgICAgICAgVGhpcyBmZWF0dXJlIGlzIHRvIGVuYWJsZSBzcGVjaWZp
ZWQgd2FrZXVwIHNvdXJjZSBmb3Igc3lzdGVtDQo+IHNsZWVwLg0KPiA+ID4gPiA+IGRpZmYgLS1n
aXQgYS9kcml2ZXJzL3NvYy9mc2wvTWFrZWZpbGUgYi9kcml2ZXJzL3NvYy9mc2wvTWFrZWZpbGUN
Cj4gPiA+ID4gPiBpbmRleCA4ZjlkYjIzLi40M2ZmNzFhIDEwMDY0NA0KPiA+ID4gPiA+IC0tLSBh
L2RyaXZlcnMvc29jL2ZzbC9NYWtlZmlsZQ0KPiA+ID4gPiA+ICsrKyBiL2RyaXZlcnMvc29jL2Zz
bC9NYWtlZmlsZQ0KPiA+ID4gPiA+IEBAIC03LDMgKzcsNCBAQCBvYmotJChDT05GSUdfUVVJQ0Nf
RU5HSU5FKSAgICAgICAgICAgICs9IHFlLw0KPiA+ID4gPiA+ICBvYmotJChDT05GSUdfQ1BNKSAg
ICAgICAgICAgICAgICAgICAgKz0gcWUvDQo+ID4gPiA+ID4gIG9iai0kKENPTkZJR19GU0xfR1VU
UykgICAgICAgICAgICAgICAgICAgICAgICs9IGd1dHMubw0KPiA+ID4gPiA+ICBvYmotJChDT05G
SUdfRlNMX1BMQVRfUE0pICAgICs9IHBsYXRfcG0ubw0KPiA+ID4gPiA+ICtvYmotJChDT05GSUdf
TFNfUkNQTSkgICAgICAgICAgICAgICAgKz0gbHMtcmNwbS5vDQo+ID4gPg0KPiA+ID4gUHJvYmFi
bHkgdXNlICJfIiBpbnN0ZWFkIG9mICItIiBmb3IgYWxpZ25tZW50Lg0KPiA+DQo+ID4gT0ssIHdp
bGwgdXBkYXRlIGluIG5leHQgdmVyc2lvbg0KPiA+DQo+ID4gPiA+ID4gZGlmZiAtLWdpdCBhL2Ry
aXZlcnMvc29jL2ZzbC9scy1yY3BtLmMNCj4gPiA+ID4gPiBiL2RyaXZlcnMvc29jL2ZzbC9scy1y
Y3BtLmMgbmV3IGZpbGUgbW9kZSAxMDA2NDQgaW5kZXgNCj4gPiA+ID4gPiAwMDAwMDAwLi5iMGZl
Yjg4DQo+ID4gPiA+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ID4gPiA+ICsrKyBiL2RyaXZlcnMvc29j
L2ZzbC9scy1yY3BtLmMNCj4gPiA+ID4gPiBAQCAtMCwwICsxLDE1MyBAQA0KPiA+ID4gPiA+ICsv
LyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCAvLyAvLyBwbGF0X3BtLmMgLSBGcmVl
c2NhbGUNCj4gPiA+ID4gPiArTGF5ZXJzY2FwZSBSQ1BNIGRyaXZlcg0KPiA+ID4NCj4gPiA+IFRo
ZSBmaWxlIG5hbWUgaGVyZSBpcyBub3QgdGhlIHNhbWUgYXMgdGhlIHJlYWwgZmlsZSBuYW1lLg0K
PiA+DQo+ID4gR290IGl0LCB3aWxsIGNvcnJlY3QgaXQuDQo+ID4NCj4gPiA+ID4gPiArLy8NCj4g
PiA+ID4gPiArLy8gQ29weXJpZ2h0IDIwMTggTlhQDQo+ID4gPiA+ID4gKy8vDQo+ID4gPiA+ID4g
Ky8vIEF1dGhvcjogUmFuIFdhbmcgPHJhbi53YW5nXzFAbnhwLmNvbT4sDQo+ID4gPg0KPiA+ID4g
V2hlcmUgZG8geW91IG5lZWQgdGhlIGNvbW1hIGluIHRoZSBlbmQ/DQo+ID4NCj4gPiBNeSBiYWQs
IHdpbGwgcmVtb3ZlIGNvbW1hIGluIG5leHQgdmVyc2lvbi4NCj4gPg0KPiA+ID4gPiA+ICsNCj4g
PiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4NCj4gPiA+ID4gPiArI2luY2x1ZGUgPGxp
bnV4L21vZHVsZS5oPg0KPiA+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNl
Lmg+ICNpbmNsdWRlDQo+ID4gPiA+ID4gKzxsaW51eC9vZl9hZGRyZXNzLmg+ICNpbmNsdWRlIDxs
aW51eC9zbGFiLmg+ICNpbmNsdWRlDQo+ID4gPiA+ID4gKzxzb2MvZnNsL3BsYXRfcG0uaD4NCj4g
PiA+ID4gPiArDQo+ID4gPiA+ID4gKyNkZWZpbmUgTUFYX0NPTVBBVElCTEVfTlVNICAgMTANCj4g
PiA+ID4gPiArDQo+ID4gPiA+ID4gK3N0cnVjdCByY3BtX3Qgew0KPiA+ID4gPiA+ICsgICAgIHN0
cnVjdCBkZXZpY2UgKmRldjsNCj4gPiA+ID4gPiArICAgICB2b2lkIF9faW9tZW0gKmlwcGRleHBj
cl9hZGRyOw0KPiA+ID4gPiA+ICsgICAgIGJvb2wgYmlnX2VuZGlhbjsgICAgICAgIC8qIEJpZy9M
aXR0bGUgZW5kaWFuIG9mIFJDUE0gbW9kdWxlICovDQo+ID4gPiA+ID4gK307DQo+ID4gPiA+ID4g
Kw0KPiA+ID4gPiA+ICsvLyByY3BtX2hhbmRsZSAtIENvbmZpZ3VyZSBSQ1BNIHJlZyBhY2NvcmRp
bmcgdG8gd2FrZSB1cCBzb3VyY2UNCj4gPiA+ID4gPiArcmVxdWVzdCAvLyBAdXNlcl9kZXY6IHBv
aW50ZXIgdG8gdXNlcidzIGRldmljZSBzdHJ1Y3QgLy8gQGZsYWc6DQo+ID4gPiA+ID4gK3RvDQo+
ID4gPiA+ID4gK2VuYWJsZSh0cnVlKSBvciBkaXNhYmxlKGZhbHNlKSB3YWtldXAgc291cmNlIC8v
IEBoYW5kbGVfcHJpdjoNCj4gPiA+ID4gPiArcG9pbnRlciB0byBzdHJ1Y3QgcmNwbV90IGluc3Rh
bmNlIC8vIC8vIFJldHVybiAwIG9uIHN1Y2Nlc3MNCj4gPiA+ID4gPiArb3RoZXIgbmVnYXRpdmUg
ZXJybm8NCj4gPiA+DQo+ID4gPiBBbHRob3VnaCBMaW51cyBwcmVmZXJyZWQgdGhpcyAvLyBjb21t
ZW50IHN0eWxlLiAgSSdtIG5vdCBzdXJlIGlmDQo+ID4gPiB0aGlzIHdpbGwgYmUgaGFuZGxlZCBj
b3JyZWN0bHkgYnkgdGhlIGtlcm5lbC1kb2MgY29tcGlsZXIuDQo+ID4gPg0KPiBodHRwczovL2Vt
ZWEwMS5zYWZlbGlua3MucHJvdGVjdGlvbi5vdXRsb29rLmNvbS8/dXJsPWh0dHBzJTNBJTJGJTJG
dw0KPiA+ID4gdw0KPiA+ID4gdy5rZXJuZWwub3JnJTJGZG9jJTJGaHRtbCUyRnY0LjE4JTJGZG9j
LWd1aWRlJTJGa2VybmVsLQ0KPiA+ID4NCj4gZG9jLmh0bWwmYW1wO2RhdGE9MDIlN0MwMSU3Q3Jh
bi53YW5nXzElNDBueHAuY29tJTdDYzBkODhlNjY5MDM4DQo+ID4gPg0KPiA0ZTAyYjk1MTA4ZDYx
MmRlYzIzNSU3QzY4NmVhMWQzYmMyYjRjNmZhOTJjZDk5YzVjMzAxNjM1JTdDMCU3QzANCj4gPiA+
ICU3QzYzNjcxNzE0NTI4NTEyNjIwMCZhbXA7c2RhdGE9SDdHa1VOT0xWRyUyRkNjWkVTemh0SEJl
SEMNCj4gYk85DQo+ID4gPiAlMkZLNGs5RWRIMzBDeHEyJTJCTSUzRCZhbXA7cmVzZXJ2ZWQ9MA0K
PiA+DQo+ID4gU28sIGRvIHlvdSB0aGluayBJIG5lZWQgdG8gY2hhbmdlIGFsbCBjb21tZW50IHN0
eWxlIGJhY2sgdG8gJy8qIC4uLiAqLycgPw0KPiA+IEFjdHVhbGx5IEkgZmVlbCBhIGxpdHRsZSBi
aXQgY29uZnVzZWQgaGVyZS4NCj4gDQo+IEkgdGhpbmsgTGludXMncyBjb21tZW50IGFib3V0IC8v
IGNvbW1lbnQgc3R5bGUgYXBwbGllcyB0byBub3JtYWwgY29kZQ0KPiBjb21tZW50LiAgQnV0IGtl
cm5lbC1kb2MgY29tbWVudCBpcyBhIHNwZWNpYWwga2luZCBvZiBjb2RlIGNvbW1lbnQgdGhhdA0K
PiBuZWVkcyB0byBtZWV0IGNlcnRhaW4gcmVxdWlyZW1lbnRzLiAgUGVvcGxlIGNhbiB1c2UgdGhl
IHNjcmlwdHMva2VybmVsLWRvYw0KPiB0b29sIHRvIGdlbmVyYXRlIHJlYWRhYmxlIEFQSSBkb2N1
bWVudHMgZnJvbSB0aGUgc291cmNlIGNvZGUuICBJdCBsb29rcyBsaWtlDQo+IHlvdSB3YW50ZWQg
dG8gbWFrZSB0aGUgZnVuY3Rpb24gZGVzY3JpcHRpb24gYWxpZ25lZCB3aXRoIHRoZSBrZXJuZWwt
ZG9jDQo+IGZvcm1hdCwgYnV0IGtlcm5lbC1kb2Mgc3BlY2lmaWNhbGx5IHJlcXVpcmVzIHRvIHVz
ZSB0aGUgLyogKi8gc3R5bGUoYXQgbGVhc3QgZm9yDQo+IG5vdykuDQoNCk9LLCB3aWxsIGNoYW5n
ZSBzdHlsZSBiYWNrIHRvIC8qICovLg0KDQpSZWdhcmRzLA0KUmFuDQoNCj4gUmVnYXJkcywNCj4g
TGVvDQo=

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/pci: Access PCI config space directly w/o pci_dn
From: Sam Bobroff @ 2018-09-10  4:23 UTC (permalink / raw)
  To: Sergey Miroshnichenko; +Cc: linuxppc-dev, linux
In-Reply-To: <20180906115752.29316-2-s.miroshnichenko@yadro.com>

[-- Attachment #1: Type: text/plain, Size: 10238 bytes --]

Hi Sergey,

On Thu, Sep 06, 2018 at 02:57:48PM +0300, Sergey Miroshnichenko wrote:
> The pci_dn structures are retrieved from a DT, but hot-plugged PCIe
> devices don't have them. Don't stop PCIe I/O in absence of pci_dn, so
> it is now possible to discover new devices.
> 
> Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
> ---
>  arch/powerpc/kernel/rtas_pci.c       | 97 +++++++++++++++++++---------
>  arch/powerpc/platforms/powernv/pci.c | 64 ++++++++++++------
>  2 files changed, 109 insertions(+), 52 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
> index c2b148b1634a..0611b46d9b5f 100644
> --- a/arch/powerpc/kernel/rtas_pci.c
> +++ b/arch/powerpc/kernel/rtas_pci.c
> @@ -55,10 +55,26 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
>  	return 0;
>  }
>  
> -int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
> +static int rtas_read_raw_config(unsigned long buid, int busno, unsigned int devfn,
> +				int where, int size, u32 *val)
>  {
>  	int returnval = -1;
> -	unsigned long buid, addr;
> +	unsigned long addr = rtas_config_addr(busno, devfn, where);
> +	int ret;
> +
> +	if (buid) {
> +		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
> +				addr, BUID_HI(buid), BUID_LO(buid), size);
> +	} else {
> +		ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
> +	}
> +	*val = returnval;
> +
> +	return ret;
> +}
> +
> +int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
> +{
>  	int ret;
>  
>  	if (!pdn)
> @@ -71,16 +87,8 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
>  		return PCIBIOS_SET_FAILED;
>  #endif
>  
> -	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
> -	buid = pdn->phb->buid;
> -	if (buid) {
> -		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
> -				addr, BUID_HI(buid), BUID_LO(buid), size);
> -	} else {
> -		ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
> -	}
> -	*val = returnval;
> -
> +	ret = rtas_read_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
> +				   where, size, val);
>  	if (ret)
>  		return PCIBIOS_DEVICE_NOT_FOUND;
>  
> @@ -98,18 +106,44 @@ static int rtas_pci_read_config(struct pci_bus *bus,
>  
>  	pdn = pci_get_pdn_by_devfn(bus, devfn);
>  
> -	/* Validity of pdn is checked in here */
> -	ret = rtas_read_config(pdn, where, size, val);
> -	if (*val == EEH_IO_ERROR_VALUE(size) &&
> -	    eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
> -		return PCIBIOS_DEVICE_NOT_FOUND;
> +	if (pdn && eeh_enabled()) {
> +		/* Validity of pdn is checked in here */
> +		ret = rtas_read_config(pdn, where, size, val);
> +
> +		if (*val == EEH_IO_ERROR_VALUE(size) &&
> +		    eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
> +			ret = PCIBIOS_DEVICE_NOT_FOUND;
> +	} else {
> +		struct pci_controller *phb = pci_bus_to_host(bus);
> +
> +		ret = rtas_read_raw_config(phb->buid, bus->number, devfn,
> +					   where, size, val);
> +	}

In the above block, if pdn is valid but EEH isn't enabled,
rtas_read_raw_config() will be used instead of rtas_read_config(), so
config_access_valid() won't be tested. Is that correct?

>  
>  	return ret;
>  }
>  
> +static int rtas_write_raw_config(unsigned long buid, int busno, unsigned int devfn,
> +				 int where, int size, u32 val)
> +{
> +	unsigned long addr = rtas_config_addr(busno, devfn, where);
> +	int ret;
> +
> +	if (buid) {
> +		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
> +				BUID_HI(buid), BUID_LO(buid), size, (ulong)val);
> +	} else {
> +		ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
> +	}
> +
> +	if (ret)
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +	return PCIBIOS_SUCCESSFUL;
> +}
> +
>  int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
>  {
> -	unsigned long buid, addr;
>  	int ret;
>  
>  	if (!pdn)
> @@ -122,15 +156,8 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
>  		return PCIBIOS_SET_FAILED;
>  #endif
>  
> -	addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
> -	buid = pdn->phb->buid;
> -	if (buid) {
> -		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
> -			BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
> -	} else {
> -		ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
> -	}
> -
> +	ret = rtas_write_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
> +				    where, size, val);
>  	if (ret)
>  		return PCIBIOS_DEVICE_NOT_FOUND;
>  
> @@ -141,12 +168,20 @@ static int rtas_pci_write_config(struct pci_bus *bus,
>  				 unsigned int devfn,
>  				 int where, int size, u32 val)
>  {
> -	struct pci_dn *pdn;
> +	struct pci_dn *pdn = pci_get_pdn_by_devfn(bus, devfn);
> +	int ret;
>  
> -	pdn = pci_get_pdn_by_devfn(bus, devfn);
> +	if (pdn && eeh_enabled()) {
> +		/* Validity of pdn is checked in here. */
> +		ret = rtas_write_config(pdn, where, size, val);
> +	} else {
> +		struct pci_controller *phb = pci_bus_to_host(bus);

Same comment as rtas_pci_read_config() above.

>  
> -	/* Validity of pdn is checked in here. */
> -	return rtas_write_config(pdn, where, size, val);
> +		ret = rtas_write_raw_config(phb->buid, bus->number, devfn,
> +					    where, size, val);
> +	}
> +
> +	return ret;
>  }
>  
>  static struct pci_ops rtas_pci_ops = {
> diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
> index 13aef2323bbc..3f87a2dc6578 100644
> --- a/arch/powerpc/platforms/powernv/pci.c
> +++ b/arch/powerpc/platforms/powernv/pci.c
> @@ -654,30 +654,29 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn)
>  	}
>  }
>  
> -int pnv_pci_cfg_read(struct pci_dn *pdn,
> -		     int where, int size, u32 *val)
> +int pnv_pci_cfg_read_raw(u64 phb_id, int busno, unsigned int devfn,
> +			 int where, int size, u32 *val)
>  {
> -	struct pnv_phb *phb = pdn->phb->private_data;
> -	u32 bdfn = (pdn->busno << 8) | pdn->devfn;
> +	u32 bdfn = (busno << 8) | devfn;
>  	s64 rc;
>  
>  	switch (size) {
>  	case 1: {
>  		u8 v8;
> -		rc = opal_pci_config_read_byte(phb->opal_id, bdfn, where, &v8);
> +		rc = opal_pci_config_read_byte(phb_id, bdfn, where, &v8);
>  		*val = (rc == OPAL_SUCCESS) ? v8 : 0xff;
>  		break;
>  	}
>  	case 2: {
>  		__be16 v16;
> -		rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where,
> -						   &v16);
> +		rc = opal_pci_config_read_half_word(phb_id, bdfn, where,
> +						    &v16);
>  		*val = (rc == OPAL_SUCCESS) ? be16_to_cpu(v16) : 0xffff;
>  		break;
>  	}
>  	case 4: {
>  		__be32 v32;
> -		rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32);
> +		rc = opal_pci_config_read_word(phb_id, bdfn, where, &v32);
>  		*val = (rc == OPAL_SUCCESS) ? be32_to_cpu(v32) : 0xffffffff;
>  		break;
>  	}
> @@ -686,27 +685,28 @@ int pnv_pci_cfg_read(struct pci_dn *pdn,
>  	}
>  
>  	pr_devel("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
> -		 __func__, pdn->busno, pdn->devfn, where, size, *val);
> +		 __func__, busno, devfn, where, size, *val);
> +
>  	return PCIBIOS_SUCCESSFUL;
>  }
>  
> -int pnv_pci_cfg_write(struct pci_dn *pdn,
> -		      int where, int size, u32 val)
> +int pnv_pci_cfg_write_raw(u64 phb_id, int busno, unsigned int devfn,
> +			  int where, int size, u32 val)
>  {
> -	struct pnv_phb *phb = pdn->phb->private_data;
> -	u32 bdfn = (pdn->busno << 8) | pdn->devfn;
> +	u32 bdfn = (busno << 8) | devfn;
>  
>  	pr_devel("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
> -		 __func__, pdn->busno, pdn->devfn, where, size, val);
> +		 __func__, busno, devfn, where, size, val);
> +
>  	switch (size) {
>  	case 1:
> -		opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
> +		opal_pci_config_write_byte(phb_id, bdfn, where, val);
>  		break;
>  	case 2:
> -		opal_pci_config_write_half_word(phb->opal_id, bdfn, where, val);
> +		opal_pci_config_write_half_word(phb_id, bdfn, where, val);
>  		break;
>  	case 4:
> -		opal_pci_config_write_word(phb->opal_id, bdfn, where, val);
> +		opal_pci_config_write_word(phb_id, bdfn, where, val);
>  		break;
>  	default:
>  		return PCIBIOS_FUNC_NOT_SUPPORTED;
> @@ -715,6 +715,24 @@ int pnv_pci_cfg_write(struct pci_dn *pdn,
>  	return PCIBIOS_SUCCESSFUL;
>  }
>  
> +int pnv_pci_cfg_read(struct pci_dn *pdn,
> +		     int where, int size, u32 *val)
> +{
> +	struct pnv_phb *phb = pdn->phb->private_data;
> +
> +	return pnv_pci_cfg_read_raw(phb->opal_id, pdn->busno, pdn->devfn,
> +				    where, size, val);
> +}
> +
> +int pnv_pci_cfg_write(struct pci_dn *pdn,
> +		      int where, int size, u32 val)
> +{
> +	struct pnv_phb *phb = pdn->phb->private_data;
> +
> +	return pnv_pci_cfg_write_raw(phb->opal_id, pdn->busno, pdn->devfn,
> +				     where, size, val);
> +}
> +
>  #if CONFIG_EEH
>  static bool pnv_pci_cfg_check(struct pci_dn *pdn)
>  {
> @@ -750,13 +768,15 @@ static int pnv_pci_read_config(struct pci_bus *bus,
>  			       int where, int size, u32 *val)
>  {
>  	struct pci_dn *pdn;
> -	struct pnv_phb *phb;
> +	struct pci_controller *hose = pci_bus_to_host(bus);
> +	struct pnv_phb *phb = hose->private_data;
>  	int ret;
>  
>  	*val = 0xFFFFFFFF;
>  	pdn = pci_get_pdn_by_devfn(bus, devfn);
>  	if (!pdn)
> -		return PCIBIOS_DEVICE_NOT_FOUND;
> +		return pnv_pci_cfg_read_raw(phb->opal_id, bus->number, devfn,
> +					    where, size, val);
>  
>  	if (!pnv_pci_cfg_check(pdn))
>  		return PCIBIOS_DEVICE_NOT_FOUND;
> @@ -779,12 +799,14 @@ static int pnv_pci_write_config(struct pci_bus *bus,
>  				int where, int size, u32 val)
>  {
>  	struct pci_dn *pdn;
> -	struct pnv_phb *phb;
> +	struct pci_controller *hose = pci_bus_to_host(bus);
> +	struct pnv_phb *phb = hose->private_data;
>  	int ret;
>  
>  	pdn = pci_get_pdn_by_devfn(bus, devfn);
>  	if (!pdn)
> -		return PCIBIOS_DEVICE_NOT_FOUND;
> +		return pnv_pci_cfg_write_raw(phb->opal_id, bus->number, devfn,
> +					     where, size, val);
>  
>  	if (!pnv_pci_cfg_check(pdn))
>  		return PCIBIOS_DEVICE_NOT_FOUND;
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc/powernv: Make possible for user to force a full ipl cec reboot
From: Stewart Smith @ 2018-09-10  4:37 UTC (permalink / raw)
  To: Vaibhav Jain, Benjamin Herrenschmidt, Michael Ellerman
  Cc: Michael Neuling, Nicholas Piggin, Vasant Hegde,
	Oliver O'Halloran, Vaibhav Jain, linuxppc-dev
In-Reply-To: <20180901081745.2165-1-vaibhav@linux.ibm.com>

Vaibhav Jain <vaibhav@linux.ibm.com> writes:
> Ever since fast reboot is enabled by default in opal,
> opal_cec_reboot() will use fast-reset instead of full IPL to perform
> system reboot. This leaves the user with no direct way to force a full
> IPL reboot except changing an nvram setting that persistently disables
> fast-reset for all subsequent reboots.
>
> This patch provides a more direct way for the user to force a one-shot
> full IPL reboot by passing the command line argument 'full' to the
> reboot command. So the user will be able to tweak the reboot behavior
> via:
>
>   $ sudo reboot full	# Force a full ipl reboot skipping fast-reset
>
>   or
>   $ sudo reboot  	# default reboot path (usually fast-reset)
>
> The reboot command passes the un-parsed command argument to the kernel
> via the 'Reboot' syscall which is then passed on to the arch function
> pnv_restart(). The patch updates pnv_restart() to handle this cmd-arg
> and issues opal_cec_reboot2 with OPAL_REBOOT_FULL_IPL to force a full
> IPL reset.

We're about to introduce an MPIPL reboot type (to take a firmware
assisted kdump style thing), and we maybe should have a reboot type to
force attempting a fast-reboot, and this makes me think if we should add
those in now?

>
> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> ---
>  arch/powerpc/include/asm/opal-api.h    | 1 +
>  arch/powerpc/platforms/powernv/setup.c | 8 +++++++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
> index 8365353330b4..870fb7b239ea 100644
> --- a/arch/powerpc/include/asm/opal-api.h
> +++ b/arch/powerpc/include/asm/opal-api.h
> @@ -1050,6 +1050,7 @@ enum OpalSysCooling {
>  enum {
>  	OPAL_REBOOT_NORMAL		= 0,
>  	OPAL_REBOOT_PLATFORM_ERROR	= 1,
> +	OPAL_REBOOT_FULL_IPL		= 2,
>  };
>  
>  /* Argument to OPAL_PCI_TCE_KILL */
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index adddde023622..33d2faeacff8 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -224,7 +224,13 @@ static void  __noreturn pnv_restart(char *cmd)
>  	pnv_prepare_going_down();
>  
>  	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
> -		rc = opal_cec_reboot();
> +
> +		/* See if we need to do a full IPL reboot */
> +		if (cmd && strcmp(cmd, "full") == 0)
> +			rc = opal_cec_reboot2(OPAL_REBOOT_FULL_IPL, NULL);
> +		else
> +			rc = opal_cec_reboot();
> +

If the reboot type isn't supported, what should be the behvaiour? Reboot
the default way or don't reboot at all?

-- 
Stewart Smith
OPAL Architect, IBM.

^ permalink raw reply

* Re: [PATCH v2 2/5] powerpc/pci: Create pci_dn on demand
From: Sam Bobroff @ 2018-09-10  4:47 UTC (permalink / raw)
  To: Sergey Miroshnichenko; +Cc: linuxppc-dev, linux
In-Reply-To: <20180906115752.29316-3-s.miroshnichenko@yadro.com>

[-- Attachment #1: Type: text/plain, Size: 5248 bytes --]

Hi Sergey,

On Thu, Sep 06, 2018 at 02:57:49PM +0300, Sergey Miroshnichenko wrote:
> The pci_dn structures can be created not only from DT, but also
> directly from newly discovered PCIe devices, so allocate them
> dynamically.
> 
> Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
> ---
>  arch/powerpc/kernel/pci_dn.c | 76 ++++++++++++++++++++++++++++--------
>  1 file changed, 59 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
> index ab147a1909c8..48ec16407835 100644
> --- a/arch/powerpc/kernel/pci_dn.c
> +++ b/arch/powerpc/kernel/pci_dn.c
> @@ -33,6 +33,8 @@
>  #include <asm/firmware.h>
>  #include <asm/eeh.h>
>  
> +static struct pci_dn *create_pdn(struct pci_dev *pdev, struct pci_dn *parent);
> +
>  /*
>   * The function is used to find the firmware data of one
>   * specific PCI device, which is attached to the indicated
> @@ -58,6 +60,9 @@ static struct pci_dn *pci_bus_to_pdn(struct pci_bus *bus)
>  		pbus = pbus->parent;
>  	}
>  
> +	if (!pbus->self && !pci_is_root_bus(pbus))
> +		return NULL;
> +
>  	/*
>  	 * Except virtual bus, all PCI buses should
>  	 * have device nodes.
> @@ -65,13 +70,15 @@ static struct pci_dn *pci_bus_to_pdn(struct pci_bus *bus)
>  	dn = pci_bus_to_OF_node(pbus);
>  	pdn = dn ? PCI_DN(dn) : NULL;
>  
> +	if (!pdn && pbus->self)
> +		pdn = pbus->self->dev.archdata.pci_data;
> +
>  	return pdn;
>  }
>  
>  struct pci_dn *pci_get_pdn_by_devfn(struct pci_bus *bus,
>  				    int devfn)
>  {
> -	struct device_node *dn = NULL;
>  	struct pci_dn *parent, *pdn;
>  	struct pci_dev *pdev = NULL;
>  
> @@ -80,17 +87,10 @@ struct pci_dn *pci_get_pdn_by_devfn(struct pci_bus *bus,
>  		if (pdev->devfn == devfn) {
>  			if (pdev->dev.archdata.pci_data)
>  				return pdev->dev.archdata.pci_data;
> -
> -			dn = pci_device_to_OF_node(pdev);
>  			break;
>  		}
>  	}
>  
> -	/* Fast path: fetch from device node */
> -	pdn = dn ? PCI_DN(dn) : NULL;
> -	if (pdn)
> -		return pdn;
> -

Why is it necessary to remove the above fast-path?

>  	/* Slow path: fetch from firmware data hierarchy */
>  	parent = pci_bus_to_pdn(bus);
>  	if (!parent)
> @@ -128,16 +128,9 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
>  	if (!parent)
>  		return NULL;
>  
> -	list_for_each_entry(pdn, &parent->child_list, list) {
> -		if (pdn->busno == pdev->bus->number &&
> -		    pdn->devfn == pdev->devfn)
> -			return pdn;
> -	}

Could you explain why the above block was removed? Is it now impossible
for it to find a pdn?

> -
> -	return NULL;
> +	return create_pdn(pdev, parent);
>  }
>  
> -#ifdef CONFIG_PCI_IOV
>  static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
>  					   int vf_index,
>  					   int busno, int devfn)
> @@ -156,7 +149,9 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
>  	pdn->parent = parent;
>  	pdn->busno = busno;
>  	pdn->devfn = devfn;
> +	#ifdef CONFIG_PCI_IOV
>  	pdn->vf_index = vf_index;
> +	#endif /* CONFIG_PCI_IOV */
>  	pdn->pe_number = IODA_INVALID_PE;
>  	INIT_LIST_HEAD(&pdn->child_list);
>  	INIT_LIST_HEAD(&pdn->list);

I can see that this change allows you to re-use this to set up a pdn in
create_pdn(). Perhaps you should refactor pci_add_device_node_info() to
use it as well, now that it's possible?

> @@ -164,7 +159,54 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
>  
>  	return pdn;
>  }
> -#endif
> +
> +static struct pci_dn *create_pdn(struct pci_dev *pdev, struct pci_dn *parent)
> +{
> +	struct pci_dn *pdn = NULL;
> +
> +	pdn = add_one_dev_pci_data(parent, 0, pdev->bus->number, pdev->devfn);
> +	dev_info(&pdev->dev, "Create a new pdn for devfn %2x\n", pdev->devfn / 8);
> +
> +	if (pdn) {
> +		#ifdef CONFIG_EEH
> +		struct eeh_dev *edev;
> +		#endif /* CONFIG_EEH */
> +		u32 class_code;
> +		u16 device_id;
> +		u16 vendor_id;
> +
> +		#ifdef CONFIG_EEH
> +		edev = eeh_dev_init(pdn);
> +		if (!edev) {
> +			kfree(pdn);
> +			dev_err(&pdev->dev, "%s: Failed to allocate edev\n", __func__);
> +			return NULL;
> +		}
> +		#endif /* CONFIG_EEH */
> +
> +		pdn->busno = pdev->bus->busn_res.start;

It seems strange that pdn->busno is set by the call to
add_one_dev_pci_data() above (to pdev->bus->number) and then overwritten
here with a different value. Should add_one_dev_pci_data() use
pdev->bus->busn_res.start and this line be removed?

> +
> +		pci_bus_read_config_word(pdev->bus, pdev->devfn,
> +					 PCI_VENDOR_ID, &vendor_id);
> +		pdn->vendor_id = vendor_id;
> +
> +		pci_bus_read_config_word(pdev->bus, pdev->devfn,
> +					 PCI_DEVICE_ID, &device_id);
> +		pdn->device_id = device_id;
> +
> +		pci_bus_read_config_dword(pdev->bus, pdev->devfn,
> +					  PCI_CLASS_REVISION, &class_code);
> +		class_code >>= 8;
> +		pdn->class_code = class_code;
> +
> +		pdn->pci_ext_config_space = 0;
> +		pdev->dev.archdata.pci_data = pdn;
> +	} else {
> +		dev_err(&pdev->dev, "%s: Failed to allocate pdn\n", __func__);
> +	}
> +
> +	return pdn;
> +}


>  
>  struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
>  {
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH kernel] KVM: PPC: Remove redundand permission bits removal
From: David Gibson @ 2018-09-10  4:50 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, kvm-ppc, Paul Mackerras
In-Reply-To: <20180906095146.43981-1-aik@ozlabs.ru>

[-- Attachment #1: Type: text/plain, Size: 4982 bytes --]

On Thu, Sep 06, 2018 at 07:51:46PM +1000, Alexey Kardashevskiy wrote:
> The kvmppc_gpa_to_ua() helper itself takes care of the permission
> bits in the TCE and yet every single caller removes them.
> 
> This changes semantics of kvmppc_gpa_to_ua() so it takes TCEs
> (which are GPAs + TCE permission bits) to make the callers simpler.
> 
> This should cause no behavioural change.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>


Hmm.  I like shrinking the code, but it bothers me that a function
called simply kvmppc_gpa_to_ua() knows something about a TCE's
internal format.

I think either the TCE bit masking needs to happen in the callers, or
that function needs a name change.  Maybe kvmppc_tce_to_ua()?

> ---
> 
> This is not related to any bug, just noticed this while doing other things.
> 
> I can also rename kvmppc_gpa_to_ua() if it makes more sense, does not it?
> 
> ---
>  arch/powerpc/kvm/book3s_64_vio.c    | 10 +++-------
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 16 ++++++----------
>  2 files changed, 9 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index 174299d..7207481 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -378,8 +378,7 @@ static long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt,
>  	if (iommu_tce_check_gpa(stt->page_shift, gpa))
>  		return H_TOO_HARD;
>  
> -	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
> -				&ua, NULL))
> +	if (kvmppc_gpa_to_ua(stt->kvm, tce, &ua, NULL))
>  		return H_TOO_HARD;
>  
>  	list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
> @@ -553,8 +552,7 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  
>  	idx = srcu_read_lock(&vcpu->kvm->srcu);
>  
> -	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
> -			tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL)) {
> +	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm, tce, &ua, NULL)) {
>  		ret = H_PARAMETER;
>  		goto unlock_exit;
>  	}
> @@ -647,9 +645,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  		}
>  		tce = be64_to_cpu(tce);
>  
> -		if (kvmppc_gpa_to_ua(vcpu->kvm,
> -				tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
> -				&ua, NULL))
> +		if (kvmppc_gpa_to_ua(vcpu->kvm, tce, &ua, NULL))
>  			return H_PARAMETER;
>  
>  		list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 5f810dc..a03cd93 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -110,8 +110,7 @@ static long kvmppc_rm_tce_validate(struct kvmppc_spapr_tce_table *stt,
>  	if (iommu_tce_check_gpa(stt->page_shift, gpa))
>  		return H_PARAMETER;
>  
> -	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
> -				&ua, NULL))
> +	if (kvmppc_gpa_to_ua(stt->kvm, tce, &ua, NULL))
>  		return H_TOO_HARD;
>  
>  	list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
> @@ -180,10 +179,10 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
>  }
>  EXPORT_SYMBOL_GPL(kvmppc_tce_put);
>  
> -long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
> +long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long tce,
>  		unsigned long *ua, unsigned long **prmap)
>  {
> -	unsigned long gfn = gpa >> PAGE_SHIFT;
> +	unsigned long gfn = tce >> PAGE_SHIFT;
>  	struct kvm_memory_slot *memslot;
>  
>  	memslot = search_memslots(kvm_memslots(kvm), gfn);
> @@ -191,7 +190,7 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
>  		return -EINVAL;
>  
>  	*ua = __gfn_to_hva_memslot(memslot, gfn) |
> -		(gpa & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
> +		(tce & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
>  
>  #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
>  	if (prmap)
> @@ -366,8 +365,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  		return ret;
>  
>  	dir = iommu_tce_direction(tce);
> -	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
> -			tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL))
> +	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm, tce, &ua, NULL))
>  		return H_PARAMETER;
>  
>  	entry = ioba >> stt->page_shift;
> @@ -520,9 +518,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  		unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
>  
>  		ua = 0;
> -		if (kvmppc_gpa_to_ua(vcpu->kvm,
> -				tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
> -				&ua, NULL))
> +		if (kvmppc_gpa_to_ua(vcpu->kvm, tce, &ua, NULL))
>  			return H_PARAMETER;
>  
>  		list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 5/5] PCI/powerpc/eeh: Add pcibios hooks for preparing to rescan
From: Sam Bobroff @ 2018-09-10  5:03 UTC (permalink / raw)
  To: Sergey Miroshnichenko; +Cc: linuxppc-dev, linux
In-Reply-To: <20180906115752.29316-6-s.miroshnichenko@yadro.com>

[-- Attachment #1: Type: text/plain, Size: 5168 bytes --]

Hi Sergey,

On Thu, Sep 06, 2018 at 02:57:52PM +0300, Sergey Miroshnichenko wrote:
> Reading an empty slot returns all ones, which triggers a false
> EEH error event on PowerNV.
> 
> New callbacks pcibios_rescan_prepare/done are introduced to
> pause/resume the EEH during rescan.

If I understand it correctly, this temporarily disables EEH for config space
accesses on the whole PHB while the rescan runs. Is it possible that a
real EEH event could be missed if it occurred during the rescan?

Even if it's not possible, I think it would be good to mention that in a
comment.

> Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
> ---
>  arch/powerpc/include/asm/eeh.h               |  2 ++
>  arch/powerpc/kernel/eeh.c                    | 12 +++++++++++
>  arch/powerpc/platforms/powernv/eeh-powernv.c | 22 ++++++++++++++++++++
>  drivers/pci/probe.c                          | 14 +++++++++++++
>  include/linux/pci.h                          |  2 ++
>  5 files changed, 52 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
> index 219637ea69a1..926c3e31df99 100644
> --- a/arch/powerpc/include/asm/eeh.h
> +++ b/arch/powerpc/include/asm/eeh.h
> @@ -219,6 +219,8 @@ struct eeh_ops {
>  	int (*next_error)(struct eeh_pe **pe);
>  	int (*restore_config)(struct pci_dn *pdn);
>  	int (*notify_resume)(struct pci_dn *pdn);
> +	int (*pause)(struct pci_bus *bus);
> +	int (*resume)(struct pci_bus *bus);

I think these names are a bit too generic, what about naming them
pause_bus()/resume_bus() or even prepare_rescan()/rescan_done()?

>  };
>  
>  extern int eeh_subsystem_flags;
> diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
> index 6ebba3e48b01..9fb5012f389d 100644
> --- a/arch/powerpc/kernel/eeh.c
> +++ b/arch/powerpc/kernel/eeh.c
> @@ -1831,3 +1831,15 @@ static int __init eeh_init_proc(void)
>  	return 0;
>  }
>  __initcall(eeh_init_proc);
> +
> +void pcibios_rescan_prepare(struct pci_bus *bus)
> +{
> +	if (eeh_ops && eeh_ops->pause)
> +		eeh_ops->pause(bus);
> +}
> +
> +void pcibios_rescan_done(struct pci_bus *bus)
> +{
> +	if (eeh_ops && eeh_ops->resume)
> +		eeh_ops->resume(bus);
> +}
> diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
> index 3c1beae29f2d..9724a58afcd2 100644
> --- a/arch/powerpc/platforms/powernv/eeh-powernv.c
> +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
> @@ -59,6 +59,26 @@ void pnv_pcibios_bus_add_device(struct pci_dev *pdev)
>  	eeh_sysfs_add_device(pdev);
>  }
>  
> +static int pnv_eeh_pause(struct pci_bus *bus)
> +{
> +	struct pci_controller *hose = pci_bus_to_host(bus);
> +	struct pnv_phb *phb = hose->private_data;
> +
> +	phb->flags &= ~PNV_PHB_FLAG_EEH;
> +	disable_irq(eeh_event_irq);
> +	return 0;
> +}
> +
> +static int pnv_eeh_resume(struct pci_bus *bus)
> +{
> +	struct pci_controller *hose = pci_bus_to_host(bus);
> +	struct pnv_phb *phb = hose->private_data;
> +
> +	enable_irq(eeh_event_irq);
> +	phb->flags |= PNV_PHB_FLAG_EEH;
> +	return 0;
> +}
> +
>  static int pnv_eeh_init(void)
>  {
>  	struct pci_controller *hose;
> @@ -1710,6 +1730,8 @@ static struct eeh_ops pnv_eeh_ops = {
>  	.write_config           = pnv_eeh_write_config,
>  	.next_error		= pnv_eeh_next_error,
>  	.restore_config		= pnv_eeh_restore_config,
> +	.pause			= pnv_eeh_pause,
> +	.resume			= pnv_eeh_resume,
>  	.notify_resume		= NULL
>  };
>  
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index ac876e32de4b..4a9045364809 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2801,6 +2801,14 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
>  {
>  }
>  
> +void __weak pcibios_rescan_prepare(struct pci_bus *bus)
> +{
> +}
> +
> +void __weak pcibios_rescan_done(struct pci_bus *bus)
> +{
> +}
> +
>  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>  		struct pci_ops *ops, void *sysdata, struct list_head *resources)
>  {
> @@ -3055,9 +3063,15 @@ unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
>  unsigned int pci_rescan_bus(struct pci_bus *bus)
>  {
>  	unsigned int max;
> +	struct pci_bus *root = bus;
> +
> +	while (!pci_is_root_bus(root))
> +		root = root->parent;
>  
> +	pcibios_rescan_prepare(root);
>  	max = pci_scan_child_bus(bus);
>  	pci_assign_unassigned_bus_resources(bus);
> +	pcibios_rescan_done(root);
>  	pci_bus_add_devices(bus);
>  
>  	return max;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 340029b2fb38..42930731c5a7 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1929,6 +1929,8 @@ void pcibios_penalize_isa_irq(int irq, int active);
>  int pcibios_alloc_irq(struct pci_dev *dev);
>  void pcibios_free_irq(struct pci_dev *dev);
>  resource_size_t pcibios_default_alignment(void);
> +void pcibios_rescan_prepare(struct pci_bus *bus);
> +void pcibios_rescan_done(struct pci_bus *bus);
>  
>  #ifdef CONFIG_HIBERNATE_CALLBACKS
>  extern struct dev_pm_ops pcibios_pm_ops;
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH 1/5] powerpc: rename setbits32/clrbits32 to setbits32_be/clrbits32_be
From: Christophe LEROY @ 2018-09-10  5:16 UTC (permalink / raw)
  To: Corentin Labbe, Gilles.Muller, Julia.Lawall, agust,
	alexandre.torgue, alistair, benh, carlo, davem, galak, joabreu,
	khilman, maxime.ripard, michal.lkml, mpe, mporter, nicolas.palix,
	oss, paulus, peppe.cavallaro, tj, vitb, wens
  Cc: netdev, linux-kernel, linux-ide, linux-sunxi, linux-amlogic,
	linuxppc-dev, cocci, linux-arm-kernel
In-Reply-To: <1536349307-20714-2-git-send-email-clabbe@baylibre.com>



Le 07/09/2018 à 21:41, Corentin Labbe a écrit :
> Since setbits32/clrbits32 work on be32, it's better to remove ambiguity on
> the used data type.

Wouldn't it be better to call them setbits_be32() / clrbits_be32() to 
have something looking similar to in_be32() / ou_be32() ?

Christophe

> 
> Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
> ---
>   arch/powerpc/include/asm/fsl_lbc.h               |  2 +-
>   arch/powerpc/include/asm/io.h                    |  5 +-
>   arch/powerpc/platforms/44x/canyonlands.c         |  4 +-
>   arch/powerpc/platforms/4xx/gpio.c                | 28 ++++-----
>   arch/powerpc/platforms/512x/pdm360ng.c           |  6 +-
>   arch/powerpc/platforms/52xx/mpc52xx_common.c     |  6 +-
>   arch/powerpc/platforms/52xx/mpc52xx_gpt.c        | 10 ++--
>   arch/powerpc/platforms/82xx/ep8248e.c            |  2 +-
>   arch/powerpc/platforms/82xx/km82xx.c             |  6 +-
>   arch/powerpc/platforms/82xx/mpc8272_ads.c        | 10 ++--
>   arch/powerpc/platforms/82xx/pq2.c                |  2 +-
>   arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |  4 +-
>   arch/powerpc/platforms/82xx/pq2fads.c            | 10 ++--
>   arch/powerpc/platforms/83xx/km83xx.c             |  6 +-
>   arch/powerpc/platforms/83xx/mpc836x_mds.c        |  2 +-
>   arch/powerpc/platforms/85xx/mpc85xx_mds.c        |  2 +-
>   arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c     |  4 +-
>   arch/powerpc/platforms/85xx/mpc85xx_rdb.c        |  2 +-
>   arch/powerpc/platforms/85xx/p1022_ds.c           |  4 +-
>   arch/powerpc/platforms/85xx/p1022_rdk.c          |  4 +-
>   arch/powerpc/platforms/85xx/t1042rdb_diu.c       |  4 +-
>   arch/powerpc/platforms/85xx/twr_p102x.c          |  2 +-
>   arch/powerpc/platforms/86xx/mpc8610_hpcd.c       |  4 +-
>   arch/powerpc/platforms/8xx/adder875.c            |  2 +-
>   arch/powerpc/platforms/8xx/m8xx_setup.c          |  4 +-
>   arch/powerpc/platforms/8xx/mpc86xads_setup.c     |  4 +-
>   arch/powerpc/platforms/8xx/mpc885ads_setup.c     | 28 ++++-----
>   arch/powerpc/platforms/embedded6xx/flipper-pic.c |  6 +-
>   arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |  8 +--
>   arch/powerpc/platforms/embedded6xx/wii.c         | 10 ++--
>   arch/powerpc/sysdev/cpm1.c                       | 26 ++++-----
>   arch/powerpc/sysdev/cpm2.c                       | 16 ++---
>   arch/powerpc/sysdev/cpm_common.c                 |  4 +-
>   arch/powerpc/sysdev/fsl_85xx_l2ctlr.c            |  8 +--
>   arch/powerpc/sysdev/fsl_lbc.c                    |  2 +-
>   arch/powerpc/sysdev/fsl_pci.c                    |  8 +--
>   arch/powerpc/sysdev/fsl_pmc.c                    |  2 +-
>   arch/powerpc/sysdev/fsl_rcpm.c                   | 74 ++++++++++++------------
>   arch/powerpc/sysdev/fsl_rio.c                    |  4 +-
>   arch/powerpc/sysdev/fsl_rmu.c                    |  8 +--
>   arch/powerpc/sysdev/mpic_timer.c                 | 12 ++--
>   41 files changed, 178 insertions(+), 177 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h
> index c7240a024b96..55d7aa0c27cf 100644
> --- a/arch/powerpc/include/asm/fsl_lbc.h
> +++ b/arch/powerpc/include/asm/fsl_lbc.h
> @@ -276,7 +276,7 @@ static inline void fsl_upm_start_pattern(struct fsl_upm *upm, u8 pat_offset)
>    */
>   static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
>   {
> -	clrbits32(upm->mxmr, MxMR_OP_RP);
> +	clrbits32_be(upm->mxmr, MxMR_OP_RP);
>   
>   	while (in_be32(upm->mxmr) & MxMR_OP_RP)
>   		cpu_relax();
> diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
> index e0331e754568..29ecefd41ecb 100644
> --- a/arch/powerpc/include/asm/io.h
> +++ b/arch/powerpc/include/asm/io.h
> @@ -873,8 +873,8 @@ static inline void * bus_to_virt(unsigned long address)
>   #endif /* CONFIG_PPC32 */
>   
>   /* access ports */
> -#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) |  (_v))
> -#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
> +#define setbits32_be(_addr, _v) out_be32((_addr), in_be32(_addr) |  (_v))
> +#define clrbits32_be(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
>   
>   #define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) |  (_v))
>   #define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))
> @@ -904,6 +904,7 @@ static inline void * bus_to_virt(unsigned long address)
>   #define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
>   
>   #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
> +#define clrsetbits32_be(addr, clear, set) clrsetbits(be32, addr, clear, set)
>   
>   #endif /* __KERNEL__ */
>   
> diff --git a/arch/powerpc/platforms/44x/canyonlands.c b/arch/powerpc/platforms/44x/canyonlands.c
> index 157f4ce46386..7145a730769d 100644
> --- a/arch/powerpc/platforms/44x/canyonlands.c
> +++ b/arch/powerpc/platforms/44x/canyonlands.c
> @@ -113,8 +113,8 @@ static int __init ppc460ex_canyonlands_fixup(void)
>   	 * USB2HStop and gpio19 will be USB2DStop. For more details refer to
>   	 * table 34-7 of PPC460EX user manual.
>   	 */
> -	setbits32((vaddr + GPIO0_OSRH), 0x42000000);
> -	setbits32((vaddr + GPIO0_TSRH), 0x42000000);
> +	setbits32_be((vaddr + GPIO0_OSRH), 0x42000000);
> +	setbits32_be((vaddr + GPIO0_TSRH), 0x42000000);
>   err_gpio:
>   	iounmap(vaddr);
>   err_bcsr:
> diff --git a/arch/powerpc/platforms/4xx/gpio.c b/arch/powerpc/platforms/4xx/gpio.c
> index 2238e369cde4..e84f2d20674e 100644
> --- a/arch/powerpc/platforms/4xx/gpio.c
> +++ b/arch/powerpc/platforms/4xx/gpio.c
> @@ -82,9 +82,9 @@ __ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>   	struct ppc4xx_gpio __iomem *regs = mm_gc->regs;
>   
>   	if (val)
> -		setbits32(&regs->or, GPIO_MASK(gpio));
> +		setbits32_be(&regs->or, GPIO_MASK(gpio));
>   	else
> -		clrbits32(&regs->or, GPIO_MASK(gpio));
> +		clrbits32_be(&regs->or, GPIO_MASK(gpio));
>   }
>   
>   static void
> @@ -112,18 +112,18 @@ static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>   	spin_lock_irqsave(&chip->lock, flags);
>   
>   	/* Disable open-drain function */
> -	clrbits32(&regs->odr, GPIO_MASK(gpio));
> +	clrbits32_be(&regs->odr, GPIO_MASK(gpio));
>   
>   	/* Float the pin */
> -	clrbits32(&regs->tcr, GPIO_MASK(gpio));
> +	clrbits32_be(&regs->tcr, GPIO_MASK(gpio));
>   
>   	/* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */
>   	if (gpio < 16) {
> -		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
> -		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->osrl, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->tsrl, GPIO_MASK2(gpio));
>   	} else {
> -		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
> -		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->osrh, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->tsrh, GPIO_MASK2(gpio));
>   	}
>   
>   	spin_unlock_irqrestore(&chip->lock, flags);
> @@ -145,18 +145,18 @@ ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>   	__ppc4xx_gpio_set(gc, gpio, val);
>   
>   	/* Disable open-drain function */
> -	clrbits32(&regs->odr, GPIO_MASK(gpio));
> +	clrbits32_be(&regs->odr, GPIO_MASK(gpio));
>   
>   	/* Drive the pin */
> -	setbits32(&regs->tcr, GPIO_MASK(gpio));
> +	setbits32_be(&regs->tcr, GPIO_MASK(gpio));
>   
>   	/* Bits 0-15 use TSRL, bits 16-31 use TSRH */
>   	if (gpio < 16) {
> -		clrbits32(&regs->osrl, GPIO_MASK2(gpio));
> -		clrbits32(&regs->tsrl, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->osrl, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->tsrl, GPIO_MASK2(gpio));
>   	} else {
> -		clrbits32(&regs->osrh, GPIO_MASK2(gpio));
> -		clrbits32(&regs->tsrh, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->osrh, GPIO_MASK2(gpio));
> +		clrbits32_be(&regs->tsrh, GPIO_MASK2(gpio));
>   	}
>   
>   	spin_unlock_irqrestore(&chip->lock, flags);
> diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c
> index dc81f05e0bce..283925e49096 100644
> --- a/arch/powerpc/platforms/512x/pdm360ng.c
> +++ b/arch/powerpc/platforms/512x/pdm360ng.c
> @@ -38,7 +38,7 @@ static int pdm360ng_get_pendown_state(void)
>   
>   	reg = in_be32(pdm360ng_gpio_base + 0xc);
>   	if (reg & 0x40)
> -		setbits32(pdm360ng_gpio_base + 0xc, 0x40);
> +		setbits32_be(pdm360ng_gpio_base + 0xc, 0x40);
>   
>   	reg = in_be32(pdm360ng_gpio_base + 0x8);
>   
> @@ -69,8 +69,8 @@ static int __init pdm360ng_penirq_init(void)
>   		return -ENODEV;
>   	}
>   	out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff);
> -	setbits32(pdm360ng_gpio_base + 0x18, 0x2000);
> -	setbits32(pdm360ng_gpio_base + 0x10, 0x40);
> +	setbits32_be(pdm360ng_gpio_base + 0x18, 0x2000);
> +	setbits32_be(pdm360ng_gpio_base + 0x10, 0x40);
>   
>   	return 0;
>   }
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> index 565e3a83dc9e..8a8b3d79798d 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -314,13 +314,13 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number)
>   
>   	/* enable gpio pins for output */
>   	setbits8(&wkup_gpio->wkup_gpioe, reset);
> -	setbits32(&simple_gpio->simple_gpioe, sync | out);
> +	setbits32_be(&simple_gpio->simple_gpioe, sync | out);
>   
>   	setbits8(&wkup_gpio->wkup_ddr, reset);
> -	setbits32(&simple_gpio->simple_ddr, sync | out);
> +	setbits32_be(&simple_gpio->simple_ddr, sync | out);
>   
>   	/* Assert cold reset */
> -	clrbits32(&simple_gpio->simple_dvo, sync | out);
> +	clrbits32_be(&simple_gpio->simple_dvo, sync | out);
>   	clrbits8(&wkup_gpio->wkup_dvo, reset);
>   
>   	/* wait for 1 us */
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> index 17cf249b18ee..88eef86f802c 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
> @@ -142,7 +142,7 @@ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
>   	unsigned long flags;
>   
>   	raw_spin_lock_irqsave(&gpt->lock, flags);
> -	setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
> +	setbits32_be(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
>   	raw_spin_unlock_irqrestore(&gpt->lock, flags);
>   }
>   
> @@ -152,7 +152,7 @@ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
>   	unsigned long flags;
>   
>   	raw_spin_lock_irqsave(&gpt->lock, flags);
> -	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
> +	clrbits32_be(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
>   	raw_spin_unlock_irqrestore(&gpt->lock, flags);
>   }
>   
> @@ -308,7 +308,7 @@ static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>   	dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
>   
>   	raw_spin_lock_irqsave(&gpt->lock, flags);
> -	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
> +	clrbits32_be(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
>   	raw_spin_unlock_irqrestore(&gpt->lock, flags);
>   
>   	return 0;
> @@ -482,7 +482,7 @@ int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
>   		return -EBUSY;
>   	}
>   
> -	clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
> +	clrbits32_be(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
>   	raw_spin_unlock_irqrestore(&gpt->lock, flags);
>   	return 0;
>   }
> @@ -639,7 +639,7 @@ static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
>   	unsigned long flags;
>   
>   	raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
> -	clrbits32(&gpt_wdt->regs->mode,
> +	clrbits32_be(&gpt_wdt->regs->mode,
>   		  MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
>   	gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
>   	raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
> diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
> index 8fec050f2d5b..da4fee98085f 100644
> --- a/arch/powerpc/platforms/82xx/ep8248e.c
> +++ b/arch/powerpc/platforms/82xx/ep8248e.c
> @@ -262,7 +262,7 @@ static void __init ep8248e_setup_arch(void)
>   	/* When this is set, snooping CPM DMA from RAM causes
>   	 * machine checks.  See erratum SIU18.
>   	 */
> -	clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
> +	clrbits32_be(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
>   
>   	ep8248e_bcsr_node =
>   		of_find_compatible_node(NULL, NULL, "fsl,ep8248e-bcsr");
> diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c
> index 28860e40b5db..b5b34f8b1a9b 100644
> --- a/arch/powerpc/platforms/82xx/km82xx.c
> +++ b/arch/powerpc/platforms/82xx/km82xx.c
> @@ -157,9 +157,9 @@ static void __init init_ioports(void)
>   	cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
>   
>   	/* Force USB FULL SPEED bit to '1' */
> -	setbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 10));
> +	setbits32_be(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 10));
>   	/* clear USB_SLAVE */
> -	clrbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 11));
> +	clrbits32_be(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 11));
>   }
>   
>   static void __init km82xx_setup_arch(void)
> @@ -172,7 +172,7 @@ static void __init km82xx_setup_arch(void)
>   	/* When this is set, snooping CPM DMA from RAM causes
>   	 * machine checks.  See erratum SIU18.
>   	 */
> -	clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
> +	clrbits32_be(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
>   
>   	init_ioports();
>   
> diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
> index d23c10a96bde..a9c8cd13a4b5 100644
> --- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
> +++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
> @@ -164,13 +164,13 @@ static void __init mpc8272_ads_setup_arch(void)
>   #define BCSR3_FETHIEN2		0x10000000
>   #define BCSR3_FETH2_RST		0x08000000
>   
> -	clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
> -	setbits32(&bcsr[1], BCSR1_FETH_RST);
> +	clrbits32_be(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
> +	setbits32_be(&bcsr[1], BCSR1_FETH_RST);
>   
> -	clrbits32(&bcsr[3], BCSR3_FETHIEN2);
> -	setbits32(&bcsr[3], BCSR3_FETH2_RST);
> +	clrbits32_be(&bcsr[3], BCSR3_FETHIEN2);
> +	setbits32_be(&bcsr[3], BCSR3_FETH2_RST);
>   
> -	clrbits32(&bcsr[3], BCSR3_USB_nEN);
> +	clrbits32_be(&bcsr[3], BCSR3_USB_nEN);
>   
>   	iounmap(bcsr);
>   
> diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
> index c4f7029fc9ae..43a9a948f064 100644
> --- a/arch/powerpc/platforms/82xx/pq2.c
> +++ b/arch/powerpc/platforms/82xx/pq2.c
> @@ -25,7 +25,7 @@
>   void __noreturn pq2_restart(char *cmd)
>   {
>   	local_irq_disable();
> -	setbits32(&cpm2_immr->im_clkrst.car_rmr, RMR_CSRE);
> +	setbits32_be(&cpm2_immr->im_clkrst.car_rmr, RMR_CSRE);
>   
>   	/* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
>   	mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
> diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> index 8b065bdf7412..b691de4c580a 100644
> --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
> @@ -47,7 +47,7 @@ static void pq2ads_pci_mask_irq(struct irq_data *d)
>   		unsigned long flags;
>   		raw_spin_lock_irqsave(&pci_pic_lock, flags);
>   
> -		setbits32(&priv->regs->mask, 1 << irq);
> +		setbits32_be(&priv->regs->mask, 1 << irq);
>   		mb();
>   
>   		raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
> @@ -63,7 +63,7 @@ static void pq2ads_pci_unmask_irq(struct irq_data *d)
>   		unsigned long flags;
>   
>   		raw_spin_lock_irqsave(&pci_pic_lock, flags);
> -		clrbits32(&priv->regs->mask, 1 << irq);
> +		clrbits32_be(&priv->regs->mask, 1 << irq);
>   		raw_spin_unlock_irqrestore(&pci_pic_lock, flags);
>   	}
>   }
> diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
> index 6c654dc74a4b..05e9c743712f 100644
> --- a/arch/powerpc/platforms/82xx/pq2fads.c
> +++ b/arch/powerpc/platforms/82xx/pq2fads.c
> @@ -140,18 +140,18 @@ static void __init pq2fads_setup_arch(void)
>   
>   	/* Enable the serial and ethernet ports */
>   
> -	clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
> -	setbits32(&bcsr[1], BCSR1_FETH_RST);
> +	clrbits32_be(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
> +	setbits32_be(&bcsr[1], BCSR1_FETH_RST);
>   
> -	clrbits32(&bcsr[3], BCSR3_FETHIEN2);
> -	setbits32(&bcsr[3], BCSR3_FETH2_RST);
> +	clrbits32_be(&bcsr[3], BCSR3_FETHIEN2);
> +	setbits32_be(&bcsr[3], BCSR3_FETH2_RST);
>   
>   	iounmap(bcsr);
>   
>   	init_ioports();
>   
>   	/* Enable external IRQs */
> -	clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000);
> +	clrbits32_be(&cpm2_immr->im_siu_conf.siu_82xx.sc_siumcr, 0x0c000000);
>   
>   	pq2_init_pci();
>   
> diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c
> index d8642a4afc74..d13f11aac111 100644
> --- a/arch/powerpc/platforms/83xx/km83xx.c
> +++ b/arch/powerpc/platforms/83xx/km83xx.c
> @@ -101,19 +101,19 @@ static void quirk_mpc8360e_qe_enet10(void)
>   		 * UCC1: write 0b11 to bits 18:19
>   		 * at address IMMRBAR+0x14A8
>   		 */
> -		setbits32((base + 0xa8), 0x00003000);
> +		setbits32_be((base + 0xa8), 0x00003000);
>   
>   		/*
>   		 * UCC2 option 1: write 0b11 to bits 4:5
>   		 * at address IMMRBAR+0x14A8
>   		 */
> -		setbits32((base + 0xa8), 0x0c000000);
> +		setbits32_be((base + 0xa8), 0x0c000000);
>   
>   		/*
>   		 * UCC2 option 2: write 0b11 to bits 16:17
>   		 * at address IMMRBAR+0x14AC
>   		 */
> -		setbits32((base + 0xac), 0x0000c000);
> +		setbits32_be((base + 0xac), 0x0000c000);
>   	}
>   	iounmap(base);
>   	of_node_put(np_par);
> diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
> index fd44dd03e1f3..56e638fdbbc5 100644
> --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
> +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
> @@ -118,7 +118,7 @@ static void __init mpc836x_mds_setup_arch(void)
>   			 * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
>   			 * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
>   			 */
> -			setbits32(immap, 0x0c003000);
> +			setbits32_be(immap, 0x0c003000);
>   
>   			/*
>   			 * IMMR + 0x14AC[20:27] = 10101010
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> index d7e440e6dba3..06c18149dc5a 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> @@ -262,7 +262,7 @@ static void __init mpc85xx_mds_qe_init(void)
>   			 * and QE12 for QE MII management signals in PMUXCR
>   			 * register.
>   			 */
> -				setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
> +				setbits32_be(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
>   						  MPC85xx_PMUXCR_QE(3) |
>   						  MPC85xx_PMUXCR_QE(9) |
>   						  MPC85xx_PMUXCR_QE(12));
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
> index f05325f0cc03..b1bb81a49a7f 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c
> @@ -60,9 +60,9 @@ static void mpc85xx_freeze_time_base(bool freeze)
>   
>   	mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1;
>   	if (freeze)
> -		setbits32(&guts->devdisr, mask);
> +		setbits32_be(&guts->devdisr, mask);
>   	else
> -		clrbits32(&guts->devdisr, mask);
> +		clrbits32_be(&guts->devdisr, mask);
>   
>   	in_be32(&guts->devdisr);
>   }
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
> index 10069503e39f..13ae0b12dd5a 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
> @@ -115,7 +115,7 @@ static void __init mpc85xx_rdb_setup_arch(void)
>   			* and QE12 for QE MII management singals in PMUXCR
>   			* register.
>   			*/
> -				setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
> +				setbits32_be(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
>   						MPC85xx_PMUXCR_QE(3) |
>   						MPC85xx_PMUXCR_QE(9) |
>   						MPC85xx_PMUXCR_QE(12));
> diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
> index 9fb57f78cdbe..adb7abdd291f 100644
> --- a/arch/powerpc/platforms/85xx/p1022_ds.c
> +++ b/arch/powerpc/platforms/85xx/p1022_ds.c
> @@ -405,11 +405,11 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
>   	pxclk = clamp_t(u32, pxclk, 2, 255);
>   
>   	/* Disable the pixel clock, and set it to non-inverted and no delay */
> -	clrbits32(&guts->clkdvdr,
> +	clrbits32_be(&guts->clkdvdr,
>   		  CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
>   
>   	/* Enable the clock and set the pxclk */
> -	setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
> +	setbits32_be(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
>   
>   	iounmap(guts);
>   }
> diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c
> index 276e00ab3dde..97698230f031 100644
> --- a/arch/powerpc/platforms/85xx/p1022_rdk.c
> +++ b/arch/powerpc/platforms/85xx/p1022_rdk.c
> @@ -75,11 +75,11 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock)
>   	pxclk = clamp_t(u32, pxclk, 2, 255);
>   
>   	/* Disable the pixel clock, and set it to non-inverted and no delay */
> -	clrbits32(&guts->clkdvdr,
> +	clrbits32_be(&guts->clkdvdr,
>   		  CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
>   
>   	/* Enable the clock and set the pxclk */
> -	setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
> +	setbits32_be(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
>   
>   	iounmap(guts);
>   }
> diff --git a/arch/powerpc/platforms/85xx/t1042rdb_diu.c b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
> index dac36ba82fea..c11f95711a8a 100644
> --- a/arch/powerpc/platforms/85xx/t1042rdb_diu.c
> +++ b/arch/powerpc/platforms/85xx/t1042rdb_diu.c
> @@ -114,11 +114,11 @@ static void t1042rdb_set_pixel_clock(unsigned int pixclock)
>   	pxclk = clamp_t(u32, pxclk, 2, 255);
>   
>   	/* Disable the pixel clock, and set it to non-inverted and no delay */
> -	clrbits32(scfg + CCSR_SCFG_PIXCLKCR,
> +	clrbits32_be(scfg + CCSR_SCFG_PIXCLKCR,
>   		  PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK);
>   
>   	/* Enable the clock and set the pxclk */
> -	setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
> +	setbits32_be(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));
>   
>   	iounmap(scfg);
>   }
> diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c
> index 360f6253e9ff..b678ee2665d0 100644
> --- a/arch/powerpc/platforms/85xx/twr_p102x.c
> +++ b/arch/powerpc/platforms/85xx/twr_p102x.c
> @@ -95,7 +95,7 @@ static void __init twr_p1025_setup_arch(void)
>   			 * and QE12 for QE MII management signals in PMUXCR
>   			 * register.
>   			 * Set QE mux bits in PMUXCR */
> -			setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
> +			setbits32_be(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
>   					MPC85xx_PMUXCR_QE(3) |
>   					MPC85xx_PMUXCR_QE(9) |
>   					MPC85xx_PMUXCR_QE(12));
> diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
> index a5d73fabe4d1..78472179b05a 100644
> --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
> +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
> @@ -261,11 +261,11 @@ void mpc8610hpcd_set_pixel_clock(unsigned int pixclock)
>   	pxclk = clamp_t(u32, pxclk, 2, 31);
>   
>   	/* Disable the pixel clock, and set it to non-inverted and no delay */
> -	clrbits32(&guts->clkdvdr,
> +	clrbits32_be(&guts->clkdvdr,
>   		  CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK);
>   
>   	/* Enable the clock and set the pxclk */
> -	setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
> +	setbits32_be(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16));
>   
>   	iounmap(guts);
>   }
> diff --git a/arch/powerpc/platforms/8xx/adder875.c b/arch/powerpc/platforms/8xx/adder875.c
> index bcef9f66191e..d21d0b8fd2a7 100644
> --- a/arch/powerpc/platforms/8xx/adder875.c
> +++ b/arch/powerpc/platforms/8xx/adder875.c
> @@ -77,7 +77,7 @@ static void __init init_ioports(void)
>   	cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
>   
>   	/* Set FEC1 and FEC2 to MII mode */
> -	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
> +	clrbits32_be(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
>   }
>   
>   static void __init adder875_setup(void)
> diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
> index 027c42d8966c..2ed24abd0b40 100644
> --- a/arch/powerpc/platforms/8xx/m8xx_setup.c
> +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
> @@ -103,7 +103,7 @@ void __init mpc8xx_calibrate_decr(void)
>   
>   	/* Force all 8xx processors to use divide by 16 processor clock. */
>   	clk_r2 = immr_map(im_clkrst);
> -	setbits32(&clk_r2->car_sccr, 0x02000000);
> +	setbits32_be(&clk_r2->car_sccr, 0x02000000);
>   	immr_unmap(clk_r2);
>   
>   	/* Processor frequency is MHz.
> @@ -203,7 +203,7 @@ void __noreturn mpc8xx_restart(char *cmd)
>   
>   	local_irq_disable();
>   
> -	setbits32(&clk_r->car_plprcr, 0x00000080);
> +	setbits32_be(&clk_r->car_plprcr, 0x00000080);
>   	/* Clear the ME bit in MSR to cause checkstop on machine check
>   	*/
>   	mtmsr(mfmsr() & ~0x1000);
> diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
> index 8d02f5ff4481..a25e5ab15d65 100644
> --- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
> +++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
> @@ -87,7 +87,7 @@ static void __init init_ioports(void)
>   	cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK2, CPM_CLK_RX);
>   
>   	/* Set FEC1 and FEC2 to MII mode */
> -	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
> +	clrbits32_be(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
>   }
>   
>   static void __init mpc86xads_setup_arch(void)
> @@ -112,7 +112,7 @@ static void __init mpc86xads_setup_arch(void)
>   		return;
>   	}
>   
> -	clrbits32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
> +	clrbits32_be(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
>   	iounmap(bcsr_io);
>   }
>   
> diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> index a0c83c1905c6..8aad0fb9090b 100644
> --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
> @@ -123,7 +123,7 @@ static void __init init_ioports(void)
>   	cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX);
>   
>   	/* Set FEC1 and FEC2 to MII mode */
> -	clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
> +	clrbits32_be(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
>   }
>   
>   static void __init mpc885ads_setup_arch(void)
> @@ -148,33 +148,33 @@ static void __init mpc885ads_setup_arch(void)
>   		return;
>   	}
>   
> -	clrbits32(&bcsr[1], BCSR1_RS232EN_1);
> +	clrbits32_be(&bcsr[1], BCSR1_RS232EN_1);
>   #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
> -	setbits32(&bcsr[1], BCSR1_RS232EN_2);
> +	setbits32_be(&bcsr[1], BCSR1_RS232EN_2);
>   #else
> -	clrbits32(&bcsr[1], BCSR1_RS232EN_2);
> +	clrbits32_be(&bcsr[1], BCSR1_RS232EN_2);
>   #endif
>   
> -	clrbits32(bcsr5, BCSR5_MII1_EN);
> -	setbits32(bcsr5, BCSR5_MII1_RST);
> +	clrbits32_be(bcsr5, BCSR5_MII1_EN);
> +	setbits32_be(bcsr5, BCSR5_MII1_RST);
>   	udelay(1000);
> -	clrbits32(bcsr5, BCSR5_MII1_RST);
> +	clrbits32_be(bcsr5, BCSR5_MII1_RST);
>   
>   #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
> -	clrbits32(bcsr5, BCSR5_MII2_EN);
> -	setbits32(bcsr5, BCSR5_MII2_RST);
> +	clrbits32_be(bcsr5, BCSR5_MII2_EN);
> +	setbits32_be(bcsr5, BCSR5_MII2_RST);
>   	udelay(1000);
> -	clrbits32(bcsr5, BCSR5_MII2_RST);
> +	clrbits32_be(bcsr5, BCSR5_MII2_RST);
>   #else
> -	setbits32(bcsr5, BCSR5_MII2_EN);
> +	setbits32_be(bcsr5, BCSR5_MII2_EN);
>   #endif
>   
>   #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
> -	clrbits32(&bcsr[4], BCSR4_ETH10_RST);
> +	clrbits32_be(&bcsr[4], BCSR4_ETH10_RST);
>   	udelay(1000);
> -	setbits32(&bcsr[4], BCSR4_ETH10_RST);
> +	setbits32_be(&bcsr[4], BCSR4_ETH10_RST);
>   
> -	setbits32(&bcsr[1], BCSR1_ETHEN);
> +	setbits32_be(&bcsr[1], BCSR1_ETHEN);
>   
>   	np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
>   #else
> diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> index db0be007fd06..6df4533aa851 100644
> --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
> @@ -53,7 +53,7 @@ static void flipper_pic_mask_and_ack(struct irq_data *d)
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   	u32 mask = 1 << irq;
>   
> -	clrbits32(io_base + FLIPPER_IMR, mask);
> +	clrbits32_be(io_base + FLIPPER_IMR, mask);
>   	/* this is at least needed for RSW */
>   	out_be32(io_base + FLIPPER_ICR, mask);
>   }
> @@ -72,7 +72,7 @@ static void flipper_pic_mask(struct irq_data *d)
>   	int irq = irqd_to_hwirq(d);
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   
> -	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
> +	clrbits32_be(io_base + FLIPPER_IMR, 1 << irq);
>   }
>   
>   static void flipper_pic_unmask(struct irq_data *d)
> @@ -80,7 +80,7 @@ static void flipper_pic_unmask(struct irq_data *d)
>   	int irq = irqd_to_hwirq(d);
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   
> -	setbits32(io_base + FLIPPER_IMR, 1 << irq);
> +	setbits32_be(io_base + FLIPPER_IMR, 1 << irq);
>   }
>   
>   
> diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> index 8112b39879d6..5487710bed1c 100644
> --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
> @@ -50,7 +50,7 @@ static void hlwd_pic_mask_and_ack(struct irq_data *d)
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   	u32 mask = 1 << irq;
>   
> -	clrbits32(io_base + HW_BROADWAY_IMR, mask);
> +	clrbits32_be(io_base + HW_BROADWAY_IMR, mask);
>   	out_be32(io_base + HW_BROADWAY_ICR, mask);
>   }
>   
> @@ -67,7 +67,7 @@ static void hlwd_pic_mask(struct irq_data *d)
>   	int irq = irqd_to_hwirq(d);
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   
> -	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
> +	clrbits32_be(io_base + HW_BROADWAY_IMR, 1 << irq);
>   }
>   
>   static void hlwd_pic_unmask(struct irq_data *d)
> @@ -75,10 +75,10 @@ static void hlwd_pic_unmask(struct irq_data *d)
>   	int irq = irqd_to_hwirq(d);
>   	void __iomem *io_base = irq_data_get_irq_chip_data(d);
>   
> -	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
> +	setbits32_be(io_base + HW_BROADWAY_IMR, 1 << irq);
>   
>   	/* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */
> -	clrbits32(io_base + HW_STARLET_IMR, 1 << irq);
> +	clrbits32_be(io_base + HW_STARLET_IMR, 1 << irq);
>   }
>   
>   
> diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
> index 403523c061ba..dd511e19147a 100644
> --- a/arch/powerpc/platforms/embedded6xx/wii.c
> +++ b/arch/powerpc/platforms/embedded6xx/wii.c
> @@ -134,7 +134,7 @@ static void __init wii_setup_arch(void)
>   	hw_gpio = wii_ioremap_hw_regs("hw_gpio", HW_GPIO_COMPATIBLE);
>   	if (hw_gpio) {
>   		/* turn off the front blue led and IR light */
> -		clrbits32(hw_gpio + HW_GPIO_OUT(0),
> +		clrbits32_be(hw_gpio + HW_GPIO_OUT(0),
>   			  HW_GPIO_SLOT_LED | HW_GPIO_SENSOR_BAR);
>   	}
>   }
> @@ -145,7 +145,7 @@ static void __noreturn wii_restart(char *cmd)
>   
>   	if (hw_ctrl) {
>   		/* clear the system reset pin to cause a reset */
> -		clrbits32(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
> +		clrbits32_be(hw_ctrl + HW_CTRL_RESETS, HW_CTRL_RESETS_SYS);
>   	}
>   	wii_spin();
>   }
> @@ -159,13 +159,13 @@ static void wii_power_off(void)
>   		 * set the owner of the shutdown pin to ARM, because it is
>   		 * accessed through the registers for the ARM, below
>   		 */
> -		clrbits32(hw_gpio + HW_GPIO_OWNER, HW_GPIO_SHUTDOWN);
> +		clrbits32_be(hw_gpio + HW_GPIO_OWNER, HW_GPIO_SHUTDOWN);
>   
>   		/* make sure that the poweroff GPIO is configured as output */
> -		setbits32(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
> +		setbits32_be(hw_gpio + HW_GPIO_DIR(1), HW_GPIO_SHUTDOWN);
>   
>   		/* drive the poweroff GPIO high */
> -		setbits32(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
> +		setbits32_be(hw_gpio + HW_GPIO_OUT(1), HW_GPIO_SHUTDOWN);
>   	}
>   	wii_spin();
>   }
> diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
> index 4f8dcf124828..9de5f13c51cb 100644
> --- a/arch/powerpc/sysdev/cpm1.c
> +++ b/arch/powerpc/sysdev/cpm1.c
> @@ -60,14 +60,14 @@ static void cpm_mask_irq(struct irq_data *d)
>   {
>   	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
>   
> -	clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
> +	clrbits32_be(&cpic_reg->cpic_cimr, (1 << cpm_vec));
>   }
>   
>   static void cpm_unmask_irq(struct irq_data *d)
>   {
>   	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
>   
> -	setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
> +	setbits32_be(&cpic_reg->cpic_cimr, (1 << cpm_vec));
>   }
>   
>   static void cpm_end_irq(struct irq_data *d)
> @@ -188,7 +188,7 @@ unsigned int cpm_pic_init(void)
>   	if (setup_irq(eirq, &cpm_error_irqaction))
>   		printk(KERN_ERR "Could not allocate CPM error IRQ!");
>   
> -	setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
> +	setbits32_be(&cpic_reg->cpic_cicr, CICR_IEN);
>   
>   end:
>   	of_node_put(np);
> @@ -317,14 +317,14 @@ static void cpm1_set_pin32(int port, int pin, int flags)
>   		      &mpc8xx_immr->im_cpm.cp_pedir;
>   
>   	if (flags & CPM_PIN_OUTPUT)
> -		setbits32(&iop->dir, pin);
> +		setbits32_be(&iop->dir, pin);
>   	else
> -		clrbits32(&iop->dir, pin);
> +		clrbits32_be(&iop->dir, pin);
>   
>   	if (!(flags & CPM_PIN_GPIO))
> -		setbits32(&iop->par, pin);
> +		setbits32_be(&iop->par, pin);
>   	else
> -		clrbits32(&iop->par, pin);
> +		clrbits32_be(&iop->par, pin);
>   
>   	if (port == CPM_PORTB) {
>   		if (flags & CPM_PIN_OPENDRAIN)
> @@ -335,14 +335,14 @@ static void cpm1_set_pin32(int port, int pin, int flags)
>   
>   	if (port == CPM_PORTE) {
>   		if (flags & CPM_PIN_SECONDARY)
> -			setbits32(&iop->sor, pin);
> +			setbits32_be(&iop->sor, pin);
>   		else
> -			clrbits32(&iop->sor, pin);
> +			clrbits32_be(&iop->sor, pin);
>   
>   		if (flags & CPM_PIN_OPENDRAIN)
> -			setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
> +			setbits32_be(&mpc8xx_immr->im_cpm.cp_peodr, pin);
>   		else
> -			clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin);
> +			clrbits32_be(&mpc8xx_immr->im_cpm.cp_peodr, pin);
>   	}
>   }
>   
> @@ -732,7 +732,7 @@ static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>   
>   	spin_lock_irqsave(&cpm1_gc->lock, flags);
>   
> -	setbits32(&iop->dir, pin_mask);
> +	setbits32_be(&iop->dir, pin_mask);
>   	__cpm1_gpio32_set(mm_gc, pin_mask, val);
>   
>   	spin_unlock_irqrestore(&cpm1_gc->lock, flags);
> @@ -750,7 +750,7 @@ static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
>   
>   	spin_lock_irqsave(&cpm1_gc->lock, flags);
>   
> -	clrbits32(&iop->dir, pin_mask);
> +	clrbits32_be(&iop->dir, pin_mask);
>   
>   	spin_unlock_irqrestore(&cpm1_gc->lock, flags);
>   
> diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
> index 07718b9a2c99..445d6e45a6de 100644
> --- a/arch/powerpc/sysdev/cpm2.c
> +++ b/arch/powerpc/sysdev/cpm2.c
> @@ -335,22 +335,22 @@ void cpm2_set_pin(int port, int pin, int flags)
>   	pin = 1 << (31 - pin);
>   
>   	if (flags & CPM_PIN_OUTPUT)
> -		setbits32(&iop[port].dir, pin);
> +		setbits32_be(&iop[port].dir, pin);
>   	else
> -		clrbits32(&iop[port].dir, pin);
> +		clrbits32_be(&iop[port].dir, pin);
>   
>   	if (!(flags & CPM_PIN_GPIO))
> -		setbits32(&iop[port].par, pin);
> +		setbits32_be(&iop[port].par, pin);
>   	else
> -		clrbits32(&iop[port].par, pin);
> +		clrbits32_be(&iop[port].par, pin);
>   
>   	if (flags & CPM_PIN_SECONDARY)
> -		setbits32(&iop[port].sor, pin);
> +		setbits32_be(&iop[port].sor, pin);
>   	else
> -		clrbits32(&iop[port].sor, pin);
> +		clrbits32_be(&iop[port].sor, pin);
>   
>   	if (flags & CPM_PIN_OPENDRAIN)
> -		setbits32(&iop[port].odr, pin);
> +		setbits32_be(&iop[port].odr, pin);
>   	else
> -		clrbits32(&iop[port].odr, pin);
> +		clrbits32_be(&iop[port].odr, pin);
>   }
> diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
> index b74508175b67..d36a95708aaf 100644
> --- a/arch/powerpc/sysdev/cpm_common.c
> +++ b/arch/powerpc/sysdev/cpm_common.c
> @@ -165,7 +165,7 @@ static int cpm2_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>   
>   	spin_lock_irqsave(&cpm2_gc->lock, flags);
>   
> -	setbits32(&iop->dir, pin_mask);
> +	setbits32_be(&iop->dir, pin_mask);
>   	__cpm2_gpio32_set(mm_gc, pin_mask, val);
>   
>   	spin_unlock_irqrestore(&cpm2_gc->lock, flags);
> @@ -183,7 +183,7 @@ static int cpm2_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio)
>   
>   	spin_lock_irqsave(&cpm2_gc->lock, flags);
>   
> -	clrbits32(&iop->dir, pin_mask);
> +	clrbits32_be(&iop->dir, pin_mask);
>   
>   	spin_unlock_irqrestore(&cpm2_gc->lock, flags);
>   
> diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
> index c27058e5df26..2b7e2b4a2543 100644
> --- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
> +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
> @@ -124,23 +124,23 @@ static int mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
>   
>   	switch (ways) {
>   	case LOCK_WAYS_EIGHTH:
> -		setbits32(&l2ctlr->ctl,
> +		setbits32_be(&l2ctlr->ctl,
>   			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH);
>   		break;
>   
>   	case LOCK_WAYS_TWO_EIGHTH:
> -		setbits32(&l2ctlr->ctl,
> +		setbits32_be(&l2ctlr->ctl,
>   			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_QUART);
>   		break;
>   
>   	case LOCK_WAYS_HALF:
> -		setbits32(&l2ctlr->ctl,
> +		setbits32_be(&l2ctlr->ctl,
>   			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF);
>   		break;
>   
>   	case LOCK_WAYS_FULL:
>   	default:
> -		setbits32(&l2ctlr->ctl,
> +		setbits32_be(&l2ctlr->ctl,
>   			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL);
>   		break;
>   	}
> diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
> index 5340a483cf55..994233e41b91 100644
> --- a/arch/powerpc/sysdev/fsl_lbc.c
> +++ b/arch/powerpc/sysdev/fsl_lbc.c
> @@ -192,7 +192,7 @@ static int fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl,
>   	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
>   
>   	/* clear event registers */
> -	setbits32(&lbc->ltesr, LTESR_CLEAR);
> +	setbits32_be(&lbc->ltesr, LTESR_CLEAR);
>   	out_be32(&lbc->lteatr, 0);
>   	out_be32(&lbc->ltear, 0);
>   	out_be32(&lbc->lteccr, LTECCR_CLEAR);
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index 918be816b097..17aa5ee63d34 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -1196,11 +1196,11 @@ static int fsl_pci_pme_probe(struct pci_controller *hose)
>   	pci = hose->private_data;
>   
>   	/* Enable PTOD, ENL23D & EXL23D */
> -	clrbits32(&pci->pex_pme_mes_disr,
> +	clrbits32_be(&pci->pex_pme_mes_disr,
>   		  PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
>   
>   	out_be32(&pci->pex_pme_mes_ier, 0);
> -	setbits32(&pci->pex_pme_mes_ier,
> +	setbits32_be(&pci->pex_pme_mes_ier,
>   		  PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
>   
>   	/* PME Enable */
> @@ -1218,7 +1218,7 @@ static void send_pme_turnoff_message(struct pci_controller *hose)
>   	int i;
>   
>   	/* Send PME_Turn_Off Message Request */
> -	setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
> +	setbits32_be(&pci->pex_pmcr, PEX_PMCR_PTOMR);
>   
>   	/* Wait trun off done */
>   	for (i = 0; i < 150; i++) {
> @@ -1254,7 +1254,7 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose)
>   	int i;
>   
>   	/* Send Exit L2 State Message */
> -	setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
> +	setbits32_be(&pci->pex_pmcr, PEX_PMCR_EXL2S);
>   
>   	/* Wait exit done */
>   	for (i = 0; i < 150; i++) {
> diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c
> index 232225e7f863..bbcf4cb89bb6 100644
> --- a/arch/powerpc/sysdev/fsl_pmc.c
> +++ b/arch/powerpc/sysdev/fsl_pmc.c
> @@ -37,7 +37,7 @@ static int pmc_suspend_enter(suspend_state_t state)
>   {
>   	int ret;
>   
> -	setbits32(&pmc_regs->pmcsr, PMCSR_SLP);
> +	setbits32_be(&pmc_regs->pmcsr, PMCSR_SLP);
>   	/* At this point, the CPU is asleep. */
>   
>   	/* Upon resume, wait for SLP bit to be clear. */
> diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c
> index 9259a94f70e1..bd2a7606bfce 100644
> --- a/arch/powerpc/sysdev/fsl_rcpm.c
> +++ b/arch/powerpc/sysdev/fsl_rcpm.c
> @@ -33,10 +33,10 @@ static void rcpm_v1_irq_mask(int cpu)
>   	int hw_cpu = get_hard_smp_processor_id(cpu);
>   	unsigned int mask = 1 << hw_cpu;
>   
> -	setbits32(&rcpm_v1_regs->cpmimr, mask);
> -	setbits32(&rcpm_v1_regs->cpmcimr, mask);
> -	setbits32(&rcpm_v1_regs->cpmmcmr, mask);
> -	setbits32(&rcpm_v1_regs->cpmnmimr, mask);
> +	setbits32_be(&rcpm_v1_regs->cpmimr, mask);
> +	setbits32_be(&rcpm_v1_regs->cpmcimr, mask);
> +	setbits32_be(&rcpm_v1_regs->cpmmcmr, mask);
> +	setbits32_be(&rcpm_v1_regs->cpmnmimr, mask);
>   }
>   
>   static void rcpm_v2_irq_mask(int cpu)
> @@ -44,10 +44,10 @@ static void rcpm_v2_irq_mask(int cpu)
>   	int hw_cpu = get_hard_smp_processor_id(cpu);
>   	unsigned int mask = 1 << hw_cpu;
>   
> -	setbits32(&rcpm_v2_regs->tpmimr0, mask);
> -	setbits32(&rcpm_v2_regs->tpmcimr0, mask);
> -	setbits32(&rcpm_v2_regs->tpmmcmr0, mask);
> -	setbits32(&rcpm_v2_regs->tpmnmimr0, mask);
> +	setbits32_be(&rcpm_v2_regs->tpmimr0, mask);
> +	setbits32_be(&rcpm_v2_regs->tpmcimr0, mask);
> +	setbits32_be(&rcpm_v2_regs->tpmmcmr0, mask);
> +	setbits32_be(&rcpm_v2_regs->tpmnmimr0, mask);
>   }
>   
>   static void rcpm_v1_irq_unmask(int cpu)
> @@ -55,10 +55,10 @@ static void rcpm_v1_irq_unmask(int cpu)
>   	int hw_cpu = get_hard_smp_processor_id(cpu);
>   	unsigned int mask = 1 << hw_cpu;
>   
> -	clrbits32(&rcpm_v1_regs->cpmimr, mask);
> -	clrbits32(&rcpm_v1_regs->cpmcimr, mask);
> -	clrbits32(&rcpm_v1_regs->cpmmcmr, mask);
> -	clrbits32(&rcpm_v1_regs->cpmnmimr, mask);
> +	clrbits32_be(&rcpm_v1_regs->cpmimr, mask);
> +	clrbits32_be(&rcpm_v1_regs->cpmcimr, mask);
> +	clrbits32_be(&rcpm_v1_regs->cpmmcmr, mask);
> +	clrbits32_be(&rcpm_v1_regs->cpmnmimr, mask);
>   }
>   
>   static void rcpm_v2_irq_unmask(int cpu)
> @@ -66,26 +66,26 @@ static void rcpm_v2_irq_unmask(int cpu)
>   	int hw_cpu = get_hard_smp_processor_id(cpu);
>   	unsigned int mask = 1 << hw_cpu;
>   
> -	clrbits32(&rcpm_v2_regs->tpmimr0, mask);
> -	clrbits32(&rcpm_v2_regs->tpmcimr0, mask);
> -	clrbits32(&rcpm_v2_regs->tpmmcmr0, mask);
> -	clrbits32(&rcpm_v2_regs->tpmnmimr0, mask);
> +	clrbits32_be(&rcpm_v2_regs->tpmimr0, mask);
> +	clrbits32_be(&rcpm_v2_regs->tpmcimr0, mask);
> +	clrbits32_be(&rcpm_v2_regs->tpmmcmr0, mask);
> +	clrbits32_be(&rcpm_v2_regs->tpmnmimr0, mask);
>   }
>   
>   static void rcpm_v1_set_ip_power(bool enable, u32 mask)
>   {
>   	if (enable)
> -		setbits32(&rcpm_v1_regs->ippdexpcr, mask);
> +		setbits32_be(&rcpm_v1_regs->ippdexpcr, mask);
>   	else
> -		clrbits32(&rcpm_v1_regs->ippdexpcr, mask);
> +		clrbits32_be(&rcpm_v1_regs->ippdexpcr, mask);
>   }
>   
>   static void rcpm_v2_set_ip_power(bool enable, u32 mask)
>   {
>   	if (enable)
> -		setbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
> +		setbits32_be(&rcpm_v2_regs->ippdexpcr[0], mask);
>   	else
> -		clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask);
> +		clrbits32_be(&rcpm_v2_regs->ippdexpcr[0], mask);
>   }
>   
>   static void rcpm_v1_cpu_enter_state(int cpu, int state)
> @@ -95,10 +95,10 @@ static void rcpm_v1_cpu_enter_state(int cpu, int state)
>   
>   	switch (state) {
>   	case E500_PM_PH10:
> -		setbits32(&rcpm_v1_regs->cdozcr, mask);
> +		setbits32_be(&rcpm_v1_regs->cdozcr, mask);
>   		break;
>   	case E500_PM_PH15:
> -		setbits32(&rcpm_v1_regs->cnapcr, mask);
> +		setbits32_be(&rcpm_v1_regs->cnapcr, mask);
>   		break;
>   	default:
>   		pr_warn("Unknown cpu PM state (%d)\n", state);
> @@ -114,16 +114,16 @@ static void rcpm_v2_cpu_enter_state(int cpu, int state)
>   	switch (state) {
>   	case E500_PM_PH10:
>   		/* one bit corresponds to one thread for PH10 of 6500 */
> -		setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
> +		setbits32_be(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu);
>   		break;
>   	case E500_PM_PH15:
> -		setbits32(&rcpm_v2_regs->pcph15setr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph15setr, mask);
>   		break;
>   	case E500_PM_PH20:
> -		setbits32(&rcpm_v2_regs->pcph20setr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph20setr, mask);
>   		break;
>   	case E500_PM_PH30:
> -		setbits32(&rcpm_v2_regs->pcph30setr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph30setr, mask);
>   		break;
>   	default:
>   		pr_warn("Unknown cpu PM state (%d)\n", state);
> @@ -172,10 +172,10 @@ static void rcpm_v1_cpu_exit_state(int cpu, int state)
>   
>   	switch (state) {
>   	case E500_PM_PH10:
> -		clrbits32(&rcpm_v1_regs->cdozcr, mask);
> +		clrbits32_be(&rcpm_v1_regs->cdozcr, mask);
>   		break;
>   	case E500_PM_PH15:
> -		clrbits32(&rcpm_v1_regs->cnapcr, mask);
> +		clrbits32_be(&rcpm_v1_regs->cnapcr, mask);
>   		break;
>   	default:
>   		pr_warn("Unknown cpu PM state (%d)\n", state);
> @@ -196,16 +196,16 @@ static void rcpm_v2_cpu_exit_state(int cpu, int state)
>   
>   	switch (state) {
>   	case E500_PM_PH10:
> -		setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
> +		setbits32_be(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu);
>   		break;
>   	case E500_PM_PH15:
> -		setbits32(&rcpm_v2_regs->pcph15clrr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph15clrr, mask);
>   		break;
>   	case E500_PM_PH20:
> -		setbits32(&rcpm_v2_regs->pcph20clrr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph20clrr, mask);
>   		break;
>   	case E500_PM_PH30:
> -		setbits32(&rcpm_v2_regs->pcph30clrr, mask);
> +		setbits32_be(&rcpm_v2_regs->pcph30clrr, mask);
>   		break;
>   	default:
>   		pr_warn("Unknown cpu PM state (%d)\n", state);
> @@ -226,7 +226,7 @@ static int rcpm_v1_plat_enter_state(int state)
>   
>   	switch (state) {
>   	case PLAT_PM_SLEEP:
> -		setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP);
> +		setbits32_be(pmcsr_reg, RCPM_POWMGTCSR_SLP);
>   
>   		/* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */
>   		result = spin_event_timeout(
> @@ -253,9 +253,9 @@ static int rcpm_v2_plat_enter_state(int state)
>   	switch (state) {
>   	case PLAT_PM_LPM20:
>   		/* clear previous LPM20 status */
> -		setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
> +		setbits32_be(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST);
>   		/* enter LPM20 status */
> -		setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
> +		setbits32_be(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ);
>   
>   		/* At this point, the device is in LPM20 status. */
>   
> @@ -291,9 +291,9 @@ static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze)
>   
>   	if (freeze) {
>   		mask = in_be32(tben_reg);
> -		clrbits32(tben_reg, mask);
> +		clrbits32_be(tben_reg, mask);
>   	} else {
> -		setbits32(tben_reg, mask);
> +		setbits32_be(tben_reg, mask);
>   	}
>   
>   	/* read back to push the previous write */
> diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
> index 5011ffea4e4b..278e63cc8afe 100644
> --- a/arch/powerpc/sysdev/fsl_rio.c
> +++ b/arch/powerpc/sysdev/fsl_rio.c
> @@ -668,10 +668,10 @@ int fsl_rio_setup(struct platform_device *dev)
>   			out_be32(priv->regs_win
>   				+ RIO_CCSR + i*0x20, 0);
>   			/* Set 1x lane */
> -			setbits32(priv->regs_win
> +			setbits32_be(priv->regs_win
>   				+ RIO_CCSR + i*0x20, 0x02000000);
>   			/* Enable ports */
> -			setbits32(priv->regs_win
> +			setbits32_be(priv->regs_win
>   				+ RIO_CCSR + i*0x20, 0x00600000);
>   			msleep(100);
>   			if (in_be32((priv->regs_win
> diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c
> index 88b35a3dcdc5..134ba53f0fcb 100644
> --- a/arch/powerpc/sysdev/fsl_rmu.c
> +++ b/arch/powerpc/sysdev/fsl_rmu.c
> @@ -355,7 +355,7 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
>   				dmsg->sid, dmsg->tid,
>   				dmsg->info);
>   		}
> -		setbits32(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI);
> +		setbits32_be(&fsl_dbell->dbell_regs->dmr, DOORBELL_DMR_DI);
>   		out_be32(&fsl_dbell->dbell_regs->dsr, DOORBELL_DSR_DIQI);
>   	}
>   
> @@ -909,10 +909,10 @@ fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
>   	out_be32(&rmu->msg_regs->imr, 0x001b0060);
>   
>   	/* Set number of queue entries */
> -	setbits32(&rmu->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
> +	setbits32_be(&rmu->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
>   
>   	/* Now enable the unit */
> -	setbits32(&rmu->msg_regs->imr, 0x1);
> +	setbits32_be(&rmu->msg_regs->imr, 0x1);
>   
>   out:
>   	return rc;
> @@ -1015,7 +1015,7 @@ void *fsl_get_inb_message(struct rio_mport *mport, int mbox)
>   	rmu->msg_rx_ring.virt_buffer[buf_idx] = NULL;
>   
>   out1:
> -	setbits32(&rmu->msg_regs->imr, RIO_MSG_IMR_MI);
> +	setbits32_be(&rmu->msg_regs->imr, RIO_MSG_IMR_MI);
>   
>   out2:
>   	return buf;
> diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c
> index 87e7c42777a8..70b02ba90220 100644
> --- a/arch/powerpc/sysdev/mpic_timer.c
> +++ b/arch/powerpc/sysdev/mpic_timer.c
> @@ -154,7 +154,7 @@ static int set_cascade_timer(struct timer_group_priv *priv, u64 ticks,
>   
>   	tcr = casc_priv->tcr_value |
>   		(casc_priv->tcr_value << MPIC_TIMER_TCR_ROVR_OFFSET);
> -	setbits32(priv->group_tcr, tcr);
> +	setbits32_be(priv->group_tcr, tcr);
>   
>   	tmp_ticks = div_u64_rem(ticks, MAX_TICKS_CASCADE, &rem_ticks);
>   
> @@ -253,7 +253,7 @@ void mpic_start_timer(struct mpic_timer *handle)
>   	struct timer_group_priv *priv = container_of(handle,
>   			struct timer_group_priv, timer[handle->num]);
>   
> -	clrbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
> +	clrbits32_be(&priv->regs[handle->num].gtbcr, TIMER_STOP);
>   }
>   EXPORT_SYMBOL(mpic_start_timer);
>   
> @@ -269,7 +269,7 @@ void mpic_stop_timer(struct mpic_timer *handle)
>   			struct timer_group_priv, timer[handle->num]);
>   	struct cascade_priv *casc_priv;
>   
> -	setbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
> +	setbits32_be(&priv->regs[handle->num].gtbcr, TIMER_STOP);
>   
>   	casc_priv = priv->timer[handle->num].cascade_handle;
>   	if (casc_priv) {
> @@ -340,7 +340,7 @@ void mpic_free_timer(struct mpic_timer *handle)
>   		u32 tcr;
>   		tcr = casc_priv->tcr_value | (casc_priv->tcr_value <<
>   					MPIC_TIMER_TCR_ROVR_OFFSET);
> -		clrbits32(priv->group_tcr, tcr);
> +		clrbits32_be(priv->group_tcr, tcr);
>   		priv->idle |= casc_priv->cascade_map;
>   		priv->timer[handle->num].cascade_handle = NULL;
>   	} else {
> @@ -508,7 +508,7 @@ static void timer_group_init(struct device_node *np)
>   
>   	/* Init FSL timer hardware */
>   	if (priv->flags & FSL_GLOBAL_TIMER)
> -		setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
> +		setbits32_be(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
>   
>   	list_add_tail(&priv->node, &timer_group_list);
>   
> @@ -531,7 +531,7 @@ static void mpic_timer_resume(void)
>   	list_for_each_entry(priv, &timer_group_list, node) {
>   		/* Init FSL timer hardware */
>   		if (priv->flags & FSL_GLOBAL_TIMER)
> -			setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
> +			setbits32_be(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
>   	}
>   }
>   
> 

^ permalink raw reply

* Re: [PATCH 2/5] include: add setbits32/clrbits32/clrsetbits32/setbits64/clrbits64/clrsetbits64 in linux/setbits.h
From: Christophe LEROY @ 2018-09-10  5:22 UTC (permalink / raw)
  To: Corentin Labbe, Gilles.Muller, Julia.Lawall, agust,
	alexandre.torgue, alistair, benh, carlo, davem, galak, joabreu,
	khilman, maxime.ripard, michal.lkml, mpe, mporter, nicolas.palix,
	oss, paulus, peppe.cavallaro, tj, vitb, wens
  Cc: netdev, linux-kernel, linux-ide, linux-sunxi, linux-amlogic,
	linuxppc-dev, cocci, linux-arm-kernel
In-Reply-To: <1536349307-20714-3-git-send-email-clabbe@baylibre.com>



Le 07/09/2018 à 21:41, Corentin Labbe a écrit :
> This patch adds setbits32/clrbits32/clrsetbits32 and
> setbits64/clrbits64/clrsetbits64 in linux/setbits.h header.

So you changed the name of setbits32() ... to setbits32_be() and now you 
are adding new functions called setbits32() ... which do something 
different ?

What will happen if any file has been forgotten during the conversion, 
or if anybody has outoftree drivers and missed this change ?
They will silently successfully compile without any error or warning, 
and the result will be crap buggy.

And why would it be more legitim to have setbits32() be implicitely LE 
instead of implicitely BE ?

I really think those new functions should be called something like 
setbits_le32() ...

Christophe

> 
> Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
> ---
>   include/linux/setbits.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 55 insertions(+)
>   create mode 100644 include/linux/setbits.h
> 
> diff --git a/include/linux/setbits.h b/include/linux/setbits.h
> new file mode 100644
> index 000000000000..3e1e273551bb
> --- /dev/null
> +++ b/include/linux/setbits.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __LINUX_SETBITS_H
> +#define __LINUX_SETBITS_H
> +
> +#include <linux/io.h>
> +
> +#define __setbits(readfunction, writefunction, addr, set) \
> +	writefunction((readfunction(addr) | (set)), addr)
> +#define __clrbits(readfunction, writefunction, addr, mask) \
> +	writefunction((readfunction(addr) & ~(mask)), addr)
> +#define __clrsetbits(readfunction, writefunction, addr, mask, set) \
> +	writefunction(((readfunction(addr) & ~(mask)) | (set)), addr)
> +#define __setclrbits(readfunction, writefunction, addr, mask, set) \
> +	writefunction(((readfunction(addr) | (seti)) & ~(mask)), addr)
> +
> +#define setbits32(addr, set) __setbits(readl, writel, addr, set)
> +#define setbits32_relaxed(addr, set) __setbits(readl_relaxed, writel_relaxed, \
> +					       addr, set)
> +
> +#define clrbits32(addr, mask) __clrbits(readl, writel, addr, mask)
> +#define clrbits32_relaxed(addr, mask) __clrbits(readl_relaxed, writel_relaxed, \
> +						addr, mask)
> +
> +#define clrsetbits32(addr, mask, set) __clrsetbits(readl, writel, addr, mask, set)
> +#define clrsetbits32_relaxed(addr, mask, set) __clrsetbits(readl_relaxed, \
> +							   writel_relaxed, \
> +							   addr, mask, set)
> +
> +#define setclrbits32(addr, mask, set) __setclrbits(readl, writel, addr, mask, set)
> +#define setclrbits32_relaxed(addr, mask, set) __setclrbits(readl_relaxed, \
> +							   writel_relaxed, \
> +							   addr, mask, set)
> +
> +/* We cannot use CONFIG_64BIT as some x86 drivers use writeq */
> +#if defined(writeq) && defined(readq)
> +#define setbits64(addr, set) __setbits(readq, writeq, addr, set)
> +#define setbits64_relaxed(addr, set) __setbits(readq_relaxed, writeq_relaxed, \
> +					       addr, set)
> +
> +#define clrbits64(addr, mask) __clrbits(readq, writeq, addr, mask)
> +#define clrbits64_relaxed(addr, mask) __clrbits(readq_relaxed, writeq_relaxed, \
> +						addr, mask)
> +
> +#define clrsetbits64(addr, mask, set) __clrsetbits(readq, writeq, addr, mask, set)
> +#define clrsetbits64_relaxed(addr, mask, set) __clrsetbits(readq_relaxed, \
> +							   writeq_relaxed, \
> +							   addr, mask, set)
> +
> +#define setclrbits64(addr, mask, set) __setclrbits(readq, writeq, addr, mask, set)
> +#define setclrbits64_relaxed(addr, mask, set) __setclrbits(readq_relaxed, \
> +							   writeq_relaxed, \
> +							   addr, mask, set)
> +#endif /* writeq/readq */
> +
> +#endif /* __LINUX_SETBITS_H */
> 

^ permalink raw reply

* Re: [PATCH 0/5] introduce setbits32/clrbits32/clrsetbits32/setbits64/clrbits64/clrsetbits64 functions
From: Christophe LEROY @ 2018-09-10  5:24 UTC (permalink / raw)
  To: Corentin Labbe, Gilles.Muller, Julia.Lawall, agust,
	alexandre.torgue, alistair, benh, carlo, davem, galak, joabreu,
	khilman, maxime.ripard, michal.lkml, mpe, mporter, nicolas.palix,
	oss, paulus, peppe.cavallaro, tj, vitb, wens
  Cc: netdev, linux-kernel, linux-ide, linux-sunxi, linux-amlogic,
	linuxppc-dev, cocci, linux-arm-kernel
In-Reply-To: <1536349307-20714-1-git-send-email-clabbe@baylibre.com>



Le 07/09/2018 à 21:41, Corentin Labbe a écrit :
> Hello
> 
> This patchset adds a new set of functions which are open-coded in lot of
> place.
> Basicly the pattern is always the same, "read, modify a bit, write"
> some driver already have thoses pattern them as functions. (like ahci_sunxi.c or dwmac-meson8b)
> 
> The first patch rename some powerpc funtions which already use the same name (xxxbits32)
> but with only bigendian values.

The same name as what ?

> 
> The second patch adds the header.

But the second patch adds functions with the same name as the powerpc 
ones but doing something different. Why consider that setbits32() should 
be LE and not BE ?

Christophe


> The third patch is an ugly try to implement a coccinelle semantic patch to
> find all place where xxxbits function could be used.
> Probably this spatch could be better written and I didnt found an easy way to add the "linux/setbits" header.
> 
> The two last patch are example of convertion of two drivers.
> Thoses patchs give an example of the reduction of code won by using xxxbits32.
> 
> This patchset is tested with the ahci_sunxi and dwmac-sun8i drivers.
> 
> Regards
> 
> Corentin Labbe (5):
>    powerpc: rename setbits32/clrbits32 to setbits32_be/clrbits32_be
>    include: add
>      setbits32/clrbits32/clrsetbits32/setbits64/clrbits64/clrsetbits64 in
>      linux/setbits.h
>    coccinelle: add xxxsetbitsXX converting spatch
>    net: ethernet: stmmac: use xxxsetbits32
>    ata: ahci_sunxi: use xxxsetbits32 functions
> 
>   arch/powerpc/include/asm/fsl_lbc.h                 |   2 +-
>   arch/powerpc/include/asm/io.h                      |   5 +-
>   arch/powerpc/platforms/44x/canyonlands.c           |   4 +-
>   arch/powerpc/platforms/4xx/gpio.c                  |  28 +-
>   arch/powerpc/platforms/512x/pdm360ng.c             |   6 +-
>   arch/powerpc/platforms/52xx/mpc52xx_common.c       |   6 +-
>   arch/powerpc/platforms/52xx/mpc52xx_gpt.c          |  10 +-
>   arch/powerpc/platforms/82xx/ep8248e.c              |   2 +-
>   arch/powerpc/platforms/82xx/km82xx.c               |   6 +-
>   arch/powerpc/platforms/82xx/mpc8272_ads.c          |  10 +-
>   arch/powerpc/platforms/82xx/pq2.c                  |   2 +-
>   arch/powerpc/platforms/82xx/pq2ads-pci-pic.c       |   4 +-
>   arch/powerpc/platforms/82xx/pq2fads.c              |  10 +-
>   arch/powerpc/platforms/83xx/km83xx.c               |   6 +-
>   arch/powerpc/platforms/83xx/mpc836x_mds.c          |   2 +-
>   arch/powerpc/platforms/85xx/mpc85xx_mds.c          |   2 +-
>   arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c       |   4 +-
>   arch/powerpc/platforms/85xx/mpc85xx_rdb.c          |   2 +-
>   arch/powerpc/platforms/85xx/p1022_ds.c             |   4 +-
>   arch/powerpc/platforms/85xx/p1022_rdk.c            |   4 +-
>   arch/powerpc/platforms/85xx/t1042rdb_diu.c         |   4 +-
>   arch/powerpc/platforms/85xx/twr_p102x.c            |   2 +-
>   arch/powerpc/platforms/86xx/mpc8610_hpcd.c         |   4 +-
>   arch/powerpc/platforms/8xx/adder875.c              |   2 +-
>   arch/powerpc/platforms/8xx/m8xx_setup.c            |   4 +-
>   arch/powerpc/platforms/8xx/mpc86xads_setup.c       |   4 +-
>   arch/powerpc/platforms/8xx/mpc885ads_setup.c       |  28 +-
>   arch/powerpc/platforms/embedded6xx/flipper-pic.c   |   6 +-
>   arch/powerpc/platforms/embedded6xx/hlwd-pic.c      |   8 +-
>   arch/powerpc/platforms/embedded6xx/wii.c           |  10 +-
>   arch/powerpc/sysdev/cpm1.c                         |  26 +-
>   arch/powerpc/sysdev/cpm2.c                         |  16 +-
>   arch/powerpc/sysdev/cpm_common.c                   |   4 +-
>   arch/powerpc/sysdev/fsl_85xx_l2ctlr.c              |   8 +-
>   arch/powerpc/sysdev/fsl_lbc.c                      |   2 +-
>   arch/powerpc/sysdev/fsl_pci.c                      |   8 +-
>   arch/powerpc/sysdev/fsl_pmc.c                      |   2 +-
>   arch/powerpc/sysdev/fsl_rcpm.c                     |  74 ++--
>   arch/powerpc/sysdev/fsl_rio.c                      |   4 +-
>   arch/powerpc/sysdev/fsl_rmu.c                      |   8 +-
>   arch/powerpc/sysdev/mpic_timer.c                   |  12 +-
>   drivers/ata/ahci_sunxi.c                           |  51 +--
>   .../net/ethernet/stmicro/stmmac/dwmac-meson8b.c    |  54 +--
>   drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  |  55 +--
>   .../net/ethernet/stmicro/stmmac/dwmac1000_core.c   |  21 +-
>   drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  |  51 +--
>   drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   |  13 +-
>   drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c   |  42 +-
>   drivers/net/ethernet/stmicro/stmmac/dwmac5.c       |  11 +-
>   drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c    |  17 +-
>   .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    |  30 +-
>   drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c |  69 +---
>   .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  |  11 +-
>   drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |   7 +-
>   include/linux/setbits.h                            |  55 +++
>   scripts/coccinelle/misc/setbits.cocci              | 423 +++++++++++++++++++++
>   56 files changed, 776 insertions(+), 489 deletions(-)
>   create mode 100644 include/linux/setbits.h
>   create mode 100644 scripts/coccinelle/misc/setbits.cocci
> 

^ permalink raw reply

* Re: MPC83xx reset status register (RSR, offset 0x910)
From: Christophe LEROY @ 2018-09-10  5:37 UTC (permalink / raw)
  To: Radu Rendec, linuxppc-dev; +Cc: Scott Wood, Michael Ellerman
In-Reply-To: <fc3e7ca0f018afbf6c104c333b381ffbae6a48c3.camel@gmail.com>

Hi,

Le 10/09/2018 à 01:13, Radu Rendec a écrit :
> Hi,
> 
> On Fri, 2018-08-24 at 16:20 +0000, Christophe Leroy wrote:
>>> On 08/03/2018 04:36 PM, Radu Rendec wrote:
>>>
>>> Is there any kernel code that handles the "reset status register" (RSR)
>>> on MPC83xx? I looked at arch/powerpc/platforms/83xx/misc.c, but it seems
>>> to only map the reset register area and it's static. The watchdog driver
>>> (drivers/watchdog/mpc8xxx_wdt.c) doesn't seem to look at it either (for
>>> the bootstatus flags).
>>
>> How do you boot your Linux kernel ?
>>
>> My 832x board boots using U-boot, and U-boot reads the RSR then clears
>> it. So when Linux kernel reads it, it is just 0.
> 
> I'm using U-boot as well, but it's just not configured to read or clear
> the RSR. I'm curious: if U-boot reads/clears the RSR in your case, how
> do you make the initial value available to user space programs running
> under Linux?

I'm surprised. When looking at U-boot code, I don't see any way to 
configure that. It seems just do by default in function cpu_init_f():

https://elixir.bootlin.com/u-boot/v2018.07/source/arch/powerpc/cpu/mpc83xx/cpu_init.c#L217

	/* RSR - Reset Status Register - clear all status (4.6.1.3) */
	gd->arch.reset_status = __raw_readl(&im->reset.rsr);
	__raw_writel(~(RSR_RES), &im->reset.rsr);


Do you know any user space program in Linux that needs this value ?

> 
>>> Basically I need to check the CPU reset reason and I thought I would ask
>>> first, before starting to write any code of my own.
>>
>> Anyway, find below a set of two patches I used for testing. Feel free to
>> use them if you bootloader doesn't clear the register
> 
> Thank you very much for the patches. Is there any chance they can be
> submitted upstream?

I see no problem submitting them upstream, but are they really worth it 
? Adding Michael in copy to get his opinion.

> 
> Of course, just printing the decoded bits is only helpful for testing. I
> was thinking of a way to make the value available to both the kernel
> (as an exported symbol) and user space (e.g. via sysfs). Is there a
> standard or preferred way to do this?
> 
> I tried to look for something similar on other platforms or architectures,
> but couldn't find anything.

I believe furst thing is to identify some app needing such an 
information, then we'll be able to investigate how to handle it.

Christophe

> 
> Thanks,
> Radu Rendec
> 

^ permalink raw reply

* [PATCH] powerpc: Avoid code patching freed init sections
From: Michael Neuling @ 2018-09-10  5:44 UTC (permalink / raw)
  To: mpe; +Cc: linuxppc-dev, Nicholas Piggin, paulus, Haren Myneni, mikey

This stops us from doing code patching in init sections after they've
been freed.

In this chain:
  kvm_guest_init() ->
    kvm_use_magic_page() ->
      fault_in_pages_readable() ->
	 __get_user() ->
	   __get_user_nocheck() ->
	     barrier_nospec();

We have a code patching location at barrier_nospec() and
kvm_guest_init() is an init function. This whole chain gets inlined,
so when we free the init section (hence kvm_guest_init()), this code
goes away and hence should no longer be patched.

We seen this as userspace memory corruption when using a memory
checker while doing partition migration testing on powervm (this
starts the code patching post migration via
/sys/kernel/mobility/migration). In theory, it could also happen when
using /sys/kernel/debug/powerpc/barrier_nospec.

With this patch there is a small change of a race if we code patch
between the init section being freed and setting SYSTEM_RUNNING (in
kernel_init()) but that seems like an impractical time and small
window for any code patching to occur.

cc: stable@vger.kernel.org # 4.13+
Signed-off-by: Michael Neuling <mikey@neuling.org>

---
For stable I've marked this as v4.13+ since that's when we refactored
code-patching.c but it could go back even further than that. In
reality though, I think we can only hit this since the first
spectre/meltdown changes.
---
 arch/powerpc/lib/code-patching.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 850f3b8f4d..a2bc08bfd8 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -23,11 +23,30 @@
 #include <asm/code-patching.h>
 #include <asm/setup.h>
 
+
+static inline bool in_init_section(unsigned int *patch_addr)
+{
+	if (patch_addr < (unsigned int *)__init_begin)
+		return false;
+	if (patch_addr >= (unsigned int *)__init_end)
+		return false;
+	return true;
+}
+
+static inline bool init_freed(void)
+{
+	return (system_state >= SYSTEM_RUNNING);
+}
+
 static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
 			       unsigned int *patch_addr)
 {
 	int err;
 
+	/* Make sure we aren't patching a freed init section */
+	if (in_init_section(patch_addr) && init_freed())
+		return 0;
+
 	__put_user_size(instr, patch_addr, 4, err);
 	if (err)
 		return err;
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH] powerpc/powernv: Make possible for user to force a full ipl cec reboot
From: Vaibhav Jain @ 2018-09-10  6:00 UTC (permalink / raw)
  To: Stewart Smith, Benjamin Herrenschmidt, Michael Ellerman
  Cc: Michael Neuling, Nicholas Piggin, Vasant Hegde,
	Oliver O'Halloran, linuxppc-dev
In-Reply-To: <87worut1c7.fsf@linux.vnet.ibm.com>

Thanks for looking into this patch Stewart

Stewart Smith <stewart@linux.ibm.com> writes:

> We're about to introduce an MPIPL reboot type (to take a firmware
> assisted kdump style thing), and we maybe should have a reboot type to
> force attempting a fast-reboot, and this makes me think if we should add
> those in now?
I will probably let Vasant and others answer that.


> If the reboot type isn't supported, what should be the behvaiour? Reboot
> the default way or don't reboot at all?
Yes, I have addressed that in v3 of this patch at
http://patchwork.ozlabs.org/patch/967248/. In case the reboot type isnt
supported or if there is an error invoking it, the patch will revert
back to calling opal_cec_reboot().

-- 
Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Linux Technology Center, IBM India Pvt. Ltd.

^ permalink raw reply

* Re: [RFC PATCH v1 00/17] ban the use of _PAGE_XXX flags outside platform specific code
From: Aneesh Kumar K.V @ 2018-09-10  6:08 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, npiggin, aneesh.kumar
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1f4d6cc9-5d18-b171-02b0-d715629d594f@c-s.fr>

Christophe Leroy <christophe.leroy@c-s.fr> writes:

> On 09/06/2018 09:58 AM, Aneesh Kumar K.V wrote:
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>> 
>>> Today flags like for instance _PAGE_RW or _PAGE_USER are used through
>>> common parts of code.
>>> Using those directly in common parts of code have proven to lead to
>>> mistakes or misbehaviour, because their use is not always as trivial
>>> as one could think.
>>>
>>> For instance, (flags & _PAGE_USER) == 0 isn't enough to tell
>>> that a page is a kernel page, because some targets are using
>>> _PAGE_PRIVILEDGED and not _PAGE_USER, so the test has to be
>>> (flags & (_PAGE_USER | _PAGE_PRIVILEDGED)) == _PAGE_PRIVILEDGED
>>> This has to (bad) consequences:
>>>
>>>   - All targets must define every bit, even the unsupported ones,
>>>     leading to a lot of useless #define _PAGE_XXX 0
>>>   - If someone forgets to take into account all possible _PAGE_XXX bits
>>>     for the case, we can get unexpected behaviour on some targets.
>>>
>>> This becomes even more complex when we come to using _PAGE_RW.
>>> Testing (flags & _PAGE_RW) is not enough to test whether a page
>>> if writable or not, because:
>>>
>>>   - Some targets have _PAGE_RO instead, which has to be unset to tell
>>>     a page is writable
>>>   - Some targets have _PAGE_R and _PAGE_W, in which case
>>>     _PAGE_RW = _PAGE_R | _PAGE_W
>>>   - Even knowing whether a page is readable is not always trivial because:
>>>     - Some targets requires to check that _PAGE_R is set to ensure page
>>>     is readable
>>>     - Some targets requires to check that _PAGE_NA is not set
>>>     - Some targets requires to check that _PAGE_RO or _PAGE_RW is set
>>>
>>> Etc ....
>>>
>>> In order to work around all those issues and minimise the risks of errors,
>>> this serie aims at removing all use of _PAGE_XXX flags from powerpc code
>>> and always use pte_xxx() and pte_mkxxx() accessors instead. Those accessors
>>> are then defined in target specific parts of the kernel code.
>> 
>> The series is really good. It also helps in code readability. Few things
>> i am not sure there is a way to reduce the overhead
>> 
>> -		access = _PAGE_EXEC;
>> +		access = pte_val(pte_mkexec(__pte(0)));
>> 
>> Considering we have multiple big endian to little endian coversion there
>> for book3s 64.
>
> Thanks for the review.
>
> For the above, I propose the following:
>
> diff --git a/arch/powerpc/mm/hash_utils_64.c 
> b/arch/powerpc/mm/hash_utils_64.c
> index f23a89d8e4ce..904ac9c84ea5 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -1482,7 +1482,7 @@ static bool should_hash_preload(struct mm_struct 
> *mm, unsigned long ea)
>   #endif
>
>   void hash_preload(struct mm_struct *mm, unsigned long ea,
> -		  unsigned long access, unsigned long trap)
> +		  bool is_exec, unsigned long trap)
>   {
>   	int hugepage_shift;
>   	unsigned long vsid;
> @@ -1490,6 +1490,7 @@ void hash_preload(struct mm_struct *mm, unsigned 
> long ea,
>   	pte_t *ptep;
>   	unsigned long flags;
>   	int rc, ssize, update_flags = 0;
> +	unsigned long access = is_exec ? _PAGE_EXEC : 0;


I guess it will be better if we do

unsigned long access = _PAGE_PRESENT | _PAGE_READ

if (is_exec)
   access |= _PAGE_EXEC.

That will also bring it closer to __hash_page. I agree that we should
always find _PAGE_PRESENT and _PAGE_READ set, because we just handled
the page fault.

-aneesh

^ permalink raw reply

* [PATCH] powerpc: fix csum_ipv6_magic() on little endian platforms
From: Christophe Leroy @ 2018-09-10  6:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Jianlin Shi, Xin Long
  Cc: linux-kernel, linuxppc-dev, stable

On little endian platforms, csum_ipv6_magic() keeps len and proto in
CPU byte order. This generates a bad results leading to ICMPv6 packets
from other hosts being dropped by powerpc64le platforms.

In order to fix this, len and proto should be converted to network
byte order ie bigendian byte order. However checksumming 0x12345678
and 0x56341278 provide the exact same result so it is enough to
rotate the sum of len and proto by 1 byte.

PPC32 only support bigendian so the fix is needed for PPC64 only

Fixes: e9c4943a107b ("powerpc: Implement csum_ipv6_magic in assembly")
Reported-by: Jianlin Shi <jishi@redhat.com>
Reported-by: Xin Long <lucien.xin@gmail.com>
Cc: <stable@vger.kernel.org> # 4.18+
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/lib/checksum_64.S | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S
index 886ed94b9c13..2a68c43e13f5 100644
--- a/arch/powerpc/lib/checksum_64.S
+++ b/arch/powerpc/lib/checksum_64.S
@@ -443,6 +443,9 @@ _GLOBAL(csum_ipv6_magic)
 	addc	r0, r8, r9
 	ld	r10, 0(r4)
 	ld	r11, 8(r4)
+#ifndef CONFIG_CPU_BIG_ENDIAN
+	rotldi	r5, r5, 8
+#endif
 	adde	r0, r0, r10
 	add	r5, r5, r7
 	adde	r0, r0, r11
-- 
2.13.3

^ permalink raw reply related

* Re: [RFC 0/4] Virtio uses DMA API for all devices
From: Christoph Hellwig @ 2018-09-10  6:19 UTC (permalink / raw)
  To: Jiandi An
  Cc: Christoph Hellwig, Benjamin Herrenschmidt, Michael S. Tsirkin,
	Will Deacon, Anshuman Khandual, virtualization, linux-kernel,
	linuxppc-dev, aik, robh, joe, elfring, david, jasowang, mpe,
	linuxram, haren, paulus, srikar, robin.murphy,
	jean-philippe.brucker, marc.zyngier, thomas.lendacky,
	brijesh.singh, jiandi.an
In-Reply-To: <f1eeb994-ea13-d0f1-dc55-7c5049e70670@amd.com>

On Thu, Sep 06, 2018 at 07:09:09PM -0500, Jiandi An wrote:
> For virtio device we have to pass in iommu_platform=true flag for
> this to set the VIRTIO_F_IOMMU_PLATFORM flag. But for example
> QEMU has the use of iommu_platform attribute disabled for virtio-gpu
> device.  So would also like to move towards not having to specify
> the VIRTIO_F_IOMMU_PLATFORM flag.

Specifying VIRTIO_F_IOMMU_PLATFORM is the right thing for your 
platform given that you can't directly use physical addresses.
Please fix qemu so that virtio-gpu works with VIRTIO_F_IOMMU_PLATFORM.

Also just as I said for the power folks: you should really work with
the qemu folks that VIRTIO_F_IOMMU_PLATFORM (or whatever we call the
properly documented flag) can be set by default, and no pointless
performance overhead is implied by having a sane and simple
implementation.

^ permalink raw reply

* [PATCH 4.4.y] crypto: vmx - Fix sleep-in-atomic bugs
From: Ondrej Mosnacek @ 2018-09-10  7:42 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, Herbert Xu, linux-crypto, linuxppc-dev,
	Ondrej Mosnacek

commit 0522236d4f9c5ab2e79889cb020d1acbe5da416e upstream.

Conflicts:
  drivers/crypto/vmx/
    aes_cbc.c - adapted enable/disable calls to v4.4 state
    aes_xts.c - did not exist yet in v4.4

This patch fixes sleep-in-atomic bugs in AES-CBC and AES-XTS VMX
implementations. The problem is that the blkcipher_* functions should
not be called in atomic context.

The bugs can be reproduced via the AF_ALG interface by trying to
encrypt/decrypt sufficiently large buffers (at least 64 KiB) using the
VMX implementations of 'cbc(aes)' or 'xts(aes)'. Such operations then
trigger BUG in crypto_yield():

[  891.863680] BUG: sleeping function called from invalid context at include/crypto/algapi.h:424
[  891.864622] in_atomic(): 1, irqs_disabled(): 0, pid: 12347, name: kcapi-enc
[  891.864739] 1 lock held by kcapi-enc/12347:
[  891.864811]  #0: 00000000f5d42c46 (sk_lock-AF_ALG){+.+.}, at: skcipher_recvmsg+0x50/0x530
[  891.865076] CPU: 5 PID: 12347 Comm: kcapi-enc Not tainted 4.19.0-0.rc0.git3.1.fc30.ppc64le #1
[  891.865251] Call Trace:
[  891.865340] [c0000003387578c0] [c000000000d67ea4] dump_stack+0xe8/0x164 (unreliable)
[  891.865511] [c000000338757910] [c000000000172a58] ___might_sleep+0x2f8/0x310
[  891.865679] [c000000338757990] [c0000000006bff74] blkcipher_walk_done+0x374/0x4a0
[  891.865825] [c0000003387579e0] [d000000007e73e70] p8_aes_cbc_encrypt+0x1c8/0x260 [vmx_crypto]
[  891.865993] [c000000338757ad0] [c0000000006c0ee0] skcipher_encrypt_blkcipher+0x60/0x80
[  891.866128] [c000000338757b10] [c0000000006ec504] skcipher_recvmsg+0x424/0x530
[  891.866283] [c000000338757bd0] [c000000000b00654] sock_recvmsg+0x74/0xa0
[  891.866403] [c000000338757c10] [c000000000b00f64] ___sys_recvmsg+0xf4/0x2f0
[  891.866515] [c000000338757d90] [c000000000b02bb8] __sys_recvmsg+0x68/0xe0
[  891.866631] [c000000338757e30] [c00000000000bbe4] system_call+0x5c/0x70

Fixes: 8c755ace357c ("crypto: vmx - Adding CBC routines for VMX module")
Fixes: c07f5d3da643 ("crypto: vmx - Adding support for XTS")
Cc: stable@vger.kernel.org
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/crypto/vmx/aes_cbc.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
index 9506e8693c81..d8ef1147b344 100644
--- a/drivers/crypto/vmx/aes_cbc.c
+++ b/drivers/crypto/vmx/aes_cbc.c
@@ -111,24 +111,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
 		ret = crypto_blkcipher_encrypt(&fallback_desc, dst, src,
 					       nbytes);
 	} else {
-		preempt_disable();
-		pagefault_disable();
-		enable_kernel_altivec();
-		enable_kernel_vsx();
-
 		blkcipher_walk_init(&walk, dst, src, nbytes);
 		ret = blkcipher_walk_virt(desc, &walk);
 		while ((nbytes = walk.nbytes)) {
+			preempt_disable();
+			pagefault_disable();
+			enable_kernel_vsx();
+			enable_kernel_altivec();
 			aes_p8_cbc_encrypt(walk.src.virt.addr,
 					   walk.dst.virt.addr,
 					   nbytes & AES_BLOCK_MASK,
 					   &ctx->enc_key, walk.iv, 1);
+			pagefault_enable();
+			preempt_enable();
+
 			nbytes &= AES_BLOCK_SIZE - 1;
 			ret = blkcipher_walk_done(desc, &walk, nbytes);
 		}
-
-		pagefault_enable();
-		preempt_enable();
 	}
 
 	return ret;
@@ -152,24 +151,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
 		ret = crypto_blkcipher_decrypt(&fallback_desc, dst, src,
 					       nbytes);
 	} else {
-		preempt_disable();
-		pagefault_disable();
-		enable_kernel_altivec();
-		enable_kernel_vsx();
-
 		blkcipher_walk_init(&walk, dst, src, nbytes);
 		ret = blkcipher_walk_virt(desc, &walk);
 		while ((nbytes = walk.nbytes)) {
+			preempt_disable();
+			pagefault_disable();
+			enable_kernel_vsx();
+			enable_kernel_altivec();
 			aes_p8_cbc_encrypt(walk.src.virt.addr,
 					   walk.dst.virt.addr,
 					   nbytes & AES_BLOCK_MASK,
 					   &ctx->dec_key, walk.iv, 0);
+			pagefault_enable();
+			preempt_enable();
+
 			nbytes &= AES_BLOCK_SIZE - 1;
 			ret = blkcipher_walk_done(desc, &walk, nbytes);
 		}
-
-		pagefault_enable();
-		preempt_enable();
 	}
 
 	return ret;
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH 4.4.y] crypto: vmx - Fix sleep-in-atomic bugs
From: Ondrej Mosnacek @ 2018-09-10  7:47 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, Herbert Xu, linux-crypto, linuxppc-dev
In-Reply-To: <20180910074204.10812-1-omosnace@redhat.com>

On Mon, Sep 10, 2018 at 9:42 AM Ondrej Mosnacek <omosnace@redhat.com> wrote:
> commit 0522236d4f9c5ab2e79889cb020d1acbe5da416e upstream.
>
> Conflicts:
>   drivers/crypto/vmx/
>     aes_cbc.c - adapted enable/disable calls to v4.4 state
>     aes_xts.c - did not exist yet in v4.4
>
> This patch fixes sleep-in-atomic bugs in AES-CBC and AES-XTS VMX
> implementations. The problem is that the blkcipher_* functions should
> not be called in atomic context.
>
> The bugs can be reproduced via the AF_ALG interface by trying to
> encrypt/decrypt sufficiently large buffers (at least 64 KiB) using the
> VMX implementations of 'cbc(aes)' or 'xts(aes)'. Such operations then
> trigger BUG in crypto_yield():
>
> [  891.863680] BUG: sleeping function called from invalid context at include/crypto/algapi.h:424
> [  891.864622] in_atomic(): 1, irqs_disabled(): 0, pid: 12347, name: kcapi-enc
> [  891.864739] 1 lock held by kcapi-enc/12347:
> [  891.864811]  #0: 00000000f5d42c46 (sk_lock-AF_ALG){+.+.}, at: skcipher_recvmsg+0x50/0x530
> [  891.865076] CPU: 5 PID: 12347 Comm: kcapi-enc Not tainted 4.19.0-0.rc0.git3.1.fc30.ppc64le #1
> [  891.865251] Call Trace:
> [  891.865340] [c0000003387578c0] [c000000000d67ea4] dump_stack+0xe8/0x164 (unreliable)
> [  891.865511] [c000000338757910] [c000000000172a58] ___might_sleep+0x2f8/0x310
> [  891.865679] [c000000338757990] [c0000000006bff74] blkcipher_walk_done+0x374/0x4a0
> [  891.865825] [c0000003387579e0] [d000000007e73e70] p8_aes_cbc_encrypt+0x1c8/0x260 [vmx_crypto]
> [  891.865993] [c000000338757ad0] [c0000000006c0ee0] skcipher_encrypt_blkcipher+0x60/0x80
> [  891.866128] [c000000338757b10] [c0000000006ec504] skcipher_recvmsg+0x424/0x530
> [  891.866283] [c000000338757bd0] [c000000000b00654] sock_recvmsg+0x74/0xa0
> [  891.866403] [c000000338757c10] [c000000000b00f64] ___sys_recvmsg+0xf4/0x2f0
> [  891.866515] [c000000338757d90] [c000000000b02bb8] __sys_recvmsg+0x68/0xe0
> [  891.866631] [c000000338757e30] [c00000000000bbe4] system_call+0x5c/0x70
>
> Fixes: 8c755ace357c ("crypto: vmx - Adding CBC routines for VMX module")
> Fixes: c07f5d3da643 ("crypto: vmx - Adding support for XTS")
> Cc: stable@vger.kernel.org
> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Whoops, sorry about that last Signed-off-by, I cherry-picked from
another stable commit and forgot to edit it out...

> ---
>  drivers/crypto/vmx/aes_cbc.c | 30 ++++++++++++++----------------
>  1 file changed, 14 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
> index 9506e8693c81..d8ef1147b344 100644
> --- a/drivers/crypto/vmx/aes_cbc.c
> +++ b/drivers/crypto/vmx/aes_cbc.c
> @@ -111,24 +111,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
>                 ret = crypto_blkcipher_encrypt(&fallback_desc, dst, src,
>                                                nbytes);
>         } else {
> -               preempt_disable();
> -               pagefault_disable();
> -               enable_kernel_altivec();
> -               enable_kernel_vsx();
> -
>                 blkcipher_walk_init(&walk, dst, src, nbytes);
>                 ret = blkcipher_walk_virt(desc, &walk);
>                 while ((nbytes = walk.nbytes)) {
> +                       preempt_disable();
> +                       pagefault_disable();
> +                       enable_kernel_vsx();
> +                       enable_kernel_altivec();
>                         aes_p8_cbc_encrypt(walk.src.virt.addr,
>                                            walk.dst.virt.addr,
>                                            nbytes & AES_BLOCK_MASK,
>                                            &ctx->enc_key, walk.iv, 1);
> +                       pagefault_enable();
> +                       preempt_enable();
> +
>                         nbytes &= AES_BLOCK_SIZE - 1;
>                         ret = blkcipher_walk_done(desc, &walk, nbytes);
>                 }
> -
> -               pagefault_enable();
> -               preempt_enable();
>         }
>
>         return ret;
> @@ -152,24 +151,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
>                 ret = crypto_blkcipher_decrypt(&fallback_desc, dst, src,
>                                                nbytes);
>         } else {
> -               preempt_disable();
> -               pagefault_disable();
> -               enable_kernel_altivec();
> -               enable_kernel_vsx();
> -
>                 blkcipher_walk_init(&walk, dst, src, nbytes);
>                 ret = blkcipher_walk_virt(desc, &walk);
>                 while ((nbytes = walk.nbytes)) {
> +                       preempt_disable();
> +                       pagefault_disable();
> +                       enable_kernel_vsx();
> +                       enable_kernel_altivec();
>                         aes_p8_cbc_encrypt(walk.src.virt.addr,
>                                            walk.dst.virt.addr,
>                                            nbytes & AES_BLOCK_MASK,
>                                            &ctx->dec_key, walk.iv, 0);
> +                       pagefault_enable();
> +                       preempt_enable();
> +
>                         nbytes &= AES_BLOCK_SIZE - 1;
>                         ret = blkcipher_walk_done(desc, &walk, nbytes);
>                 }
> -
> -               pagefault_enable();
> -               preempt_enable();
>         }
>
>         return ret;
> --
> 2.17.1
>


-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Associate Software Engineer, Security Technologies
Red Hat, Inc.

^ permalink raw reply

* Re: [PATCH] powerpc: Avoid code patching freed init sections
From: Michal Suchánek @ 2018-09-10  8:10 UTC (permalink / raw)
  To: Michael Neuling; +Cc: mpe, linuxppc-dev, Haren Myneni, Nicholas Piggin
In-Reply-To: <20180910054405.32422-1-mikey@neuling.org>

On Mon, 10 Sep 2018 15:44:05 +1000
Michael Neuling <mikey@neuling.org> wrote:

> This stops us from doing code patching in init sections after they've
> been freed.
> 
> In this chain:
>   kvm_guest_init() ->
>     kvm_use_magic_page() ->
>       fault_in_pages_readable() ->
> 	 __get_user() ->
> 	   __get_user_nocheck() ->
> 	     barrier_nospec();
> 
> We have a code patching location at barrier_nospec() and
> kvm_guest_init() is an init function. This whole chain gets inlined,
> so when we free the init section (hence kvm_guest_init()), this code
> goes away and hence should no longer be patched.
> 
> We seen this as userspace memory corruption when using a memory
> checker while doing partition migration testing on powervm (this
> starts the code patching post migration via
> /sys/kernel/mobility/migration). In theory, it could also happen when
> using /sys/kernel/debug/powerpc/barrier_nospec.
> 
> With this patch there is a small change of a race if we code patch
> between the init section being freed and setting SYSTEM_RUNNING (in
> kernel_init()) but that seems like an impractical time and small
> window for any code patching to occur.
> 
> cc: stable@vger.kernel.org # 4.13+
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> 
> ---
> For stable I've marked this as v4.13+ since that's when we refactored
> code-patching.c but it could go back even further than that. In
> reality though, I think we can only hit this since the first
> spectre/meltdown changes.

Which means it affects all maintained stable trees because the
spectre/meltdown changes are backported.

Thanks

Michal

^ permalink raw reply

* [PATCH kernel v2 3/6] KVM: PPC: Inform the userspace about TCE update failures
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

We return H_TOO_HARD from TCE update handlers when we think that
the next handler (realmode -> virtual mode -> user mode) has a chance to
handle the request; H_HARDWARE/H_CLOSED otherwise.

This changes the handlers to return H_TOO_HARD on every error giving
the userspace an opportunity to handle any request or at least log
them all.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 arch/powerpc/kvm/book3s_64_vio.c    | 8 ++++----
 arch/powerpc/kvm/book3s_64_vio_hv.c | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 3c17977..984cec8 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -401,7 +401,7 @@ static long kvmppc_tce_iommu_do_unmap(struct kvm *kvm,
 	long ret;
 
 	if (WARN_ON_ONCE(iommu_tce_xchg(tbl, entry, &hpa, &dir)))
-		return H_HARDWARE;
+		return H_TOO_HARD;
 
 	if (dir == DMA_NONE)
 		return H_SUCCESS;
@@ -449,15 +449,15 @@ long kvmppc_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl,
 		return H_TOO_HARD;
 
 	if (WARN_ON_ONCE(mm_iommu_ua_to_hpa(mem, ua, tbl->it_page_shift, &hpa)))
-		return H_HARDWARE;
+		return H_TOO_HARD;
 
 	if (mm_iommu_mapped_inc(mem))
-		return H_CLOSED;
+		return H_TOO_HARD;
 
 	ret = iommu_tce_xchg(tbl, entry, &hpa, &dir);
 	if (WARN_ON_ONCE(ret)) {
 		mm_iommu_mapped_dec(mem);
-		return H_HARDWARE;
+		return H_TOO_HARD;
 	}
 
 	if (dir != DMA_NONE)
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index c2848e0b..7388b66 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -300,10 +300,10 @@ static long kvmppc_rm_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl,
 
 	if (WARN_ON_ONCE_RM(mm_iommu_ua_to_hpa_rm(mem, ua, tbl->it_page_shift,
 			&hpa)))
-		return H_HARDWARE;
+		return H_TOO_HARD;
 
 	if (WARN_ON_ONCE_RM(mm_iommu_mapped_inc(mem)))
-		return H_CLOSED;
+		return H_TOO_HARD;
 
 	ret = iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 	if (ret) {
@@ -501,7 +501,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 
 		rmap = (void *) vmalloc_to_phys(rmap);
 		if (WARN_ON_ONCE_RM(!rmap))
-			return H_HARDWARE;
+			return H_TOO_HARD;
 
 		/*
 		 * Synchronize with the MMU notifier callbacks in
-- 
2.11.0

^ permalink raw reply related

* [PATCH kernel v2 0/6] KVM: PPC: TCE improvements
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson

Hi,

Here is my current queue of TCE/KVM patches.

1/6 is a bugfix for https://bugzilla.redhat.com/show_bug.cgi?id=1620360
2/6..5/6 are to help with testing https://bugzilla.redhat.com/show_bug.cgi?id=1613190
6/6 is a small cleanup


This is based on sha1
11da3a7 Linus Torvalds "Linux 4.19-rc3".

Please comment. Thanks.


Alex, I cc: you to keep you informed that
[RFC 1/6] did change drivers/vfio/vfio_iommu_spapr_tce.c but
this one does not.


Alexey Kardashevskiy (6):
  KVM: PPC: Avoid marking DMA-mapped pages dirty in real mode
  KVM: PPC: Validate all tces before updating tables
  KVM: PPC: Inform the userspace about TCE update failures
  KVM: PPC: Validate TCEs against preregistered memory page sizes
  KVM: PPC: Propagate errors to the guest when failed instead of
    ignoring
  KVM: PPC: Remove redundand permission bits removal

 arch/powerpc/include/asm/book3s/64/pgtable.h |   1 -
 arch/powerpc/include/asm/iommu.h             |   2 -
 arch/powerpc/include/asm/kvm_ppc.h           |   4 +-
 arch/powerpc/include/asm/mmu_context.h       |   1 +
 arch/powerpc/kernel/iommu.c                  |  25 ------
 arch/powerpc/kvm/book3s_64_vio.c             |  89 +++++++++++++++------
 arch/powerpc/kvm/book3s_64_vio_hv.c          | 114 +++++++++++++++++----------
 arch/powerpc/mm/init_64.c                    |  49 ------------
 arch/powerpc/mm/mmu_context_iommu.c          |  34 +++++++-
 9 files changed, 170 insertions(+), 149 deletions(-)

-- 
2.11.0

^ permalink raw reply

* [PATCH kernel v2 1/6] KVM: PPC: Avoid marking DMA-mapped pages dirty in real mode
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

At the moment the real mode handler of H_PUT_TCE calls iommu_tce_xchg_rm()
which in turn reads the old TCE and if it was a valid entry - marks
the physical page dirty if it was mapped for writing. Since it is
the real mode, realmode_pfn_to_page() is used instead of pfn_to_page()
to get the page struct. However SetPageDirty() itself reads the compound
page head and returns a virtual address for the head page struct and
setting dirty bit for that kills the system.

This adds additional dirty bit tracking into the MM/IOMMU API for use
in the real mode. Note that this does not change how VFIO and
KVM (in virtual mode) set this bit. The KVM (real mode) changes include:
- use the lowest bit of the cached host phys address to carry
the dirty bit;
- mark pages dirty when they are unpinned which happens when
the preregistered memory is released which always happens in virtual
mode;
- add mm_iommu_ua_mark_dirty_rm() helper to set delayed dirty bit;
- change iommu_tce_xchg_rm() to take the kvm struct for the mm to use
in the new mm_iommu_ua_mark_dirty_rm() helper;
- move iommu_tce_xchg_rm() to book3s_64_vio_hv.c (which is the only
caller anyway) to reduce the real mode KVM and IOMMU knowledge
across different subsystems.

This removes realmode_pfn_to_page() as it is not used anymore.

While we at it, remove some EXPORT_SYMBOL_GPL() as that code is for
the real mode only and modules cannot call it anyway.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2:
* only do delaying dirtying for the real mode
* no change in VFIO IOMMU SPAPR TCE driver is needed anymore
* inverted MM_IOMMU_TABLE_GROUP_PAGE_MASK
---
 arch/powerpc/include/asm/book3s/64/pgtable.h |  1 -
 arch/powerpc/include/asm/iommu.h             |  2 --
 arch/powerpc/include/asm/mmu_context.h       |  1 +
 arch/powerpc/kernel/iommu.c                  | 25 --------------
 arch/powerpc/kvm/book3s_64_vio_hv.c          | 39 +++++++++++++++++-----
 arch/powerpc/mm/init_64.c                    | 49 ----------------------------
 arch/powerpc/mm/mmu_context_iommu.c          | 34 ++++++++++++++++---
 7 files changed, 62 insertions(+), 89 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 13a688f..2fdc865 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1051,7 +1051,6 @@ static inline void vmemmap_remove_mapping(unsigned long start,
 	return hash__vmemmap_remove_mapping(start, page_size);
 }
 #endif
-struct page *realmode_pfn_to_page(unsigned long pfn);
 
 static inline pte_t pmd_pte(pmd_t pmd)
 {
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index ab3a4fb..3d4b88c 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -220,8 +220,6 @@ extern void iommu_del_device(struct device *dev);
 extern int __init tce_iommu_bus_notifier_init(void);
 extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
 		unsigned long *hpa, enum dma_data_direction *direction);
-extern long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
-		unsigned long *hpa, enum dma_data_direction *direction);
 #else
 static inline void iommu_register_group(struct iommu_table_group *table_group,
 					int pci_domain_number,
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index b2f89b6..b694d6a 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -38,6 +38,7 @@ extern long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
 		unsigned long ua, unsigned int pageshift, unsigned long *hpa);
 extern long mm_iommu_ua_to_hpa_rm(struct mm_iommu_table_group_mem_t *mem,
 		unsigned long ua, unsigned int pageshift, unsigned long *hpa);
+extern void mm_iommu_ua_mark_dirty_rm(struct mm_struct *mm, unsigned long ua);
 extern long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem);
 extern void mm_iommu_mapped_dec(struct mm_iommu_table_group_mem_t *mem);
 #endif
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index af7a20d..19b4c62 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1013,31 +1013,6 @@ long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
 }
 EXPORT_SYMBOL_GPL(iommu_tce_xchg);
 
-#ifdef CONFIG_PPC_BOOK3S_64
-long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
-		unsigned long *hpa, enum dma_data_direction *direction)
-{
-	long ret;
-
-	ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
-
-	if (!ret && ((*direction == DMA_FROM_DEVICE) ||
-			(*direction == DMA_BIDIRECTIONAL))) {
-		struct page *pg = realmode_pfn_to_page(*hpa >> PAGE_SHIFT);
-
-		if (likely(pg)) {
-			SetPageDirty(pg);
-		} else {
-			tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
-			ret = -EFAULT;
-		}
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(iommu_tce_xchg_rm);
-#endif
-
 int iommu_take_ownership(struct iommu_table *tbl)
 {
 	unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 506a4d4..6821ead 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -187,12 +187,35 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
 EXPORT_SYMBOL_GPL(kvmppc_gpa_to_ua);
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
-static void kvmppc_rm_clear_tce(struct iommu_table *tbl, unsigned long entry)
+static long iommu_tce_xchg_rm(struct mm_struct *mm, struct iommu_table *tbl,
+		unsigned long entry, unsigned long *hpa,
+		enum dma_data_direction *direction)
+{
+	long ret;
+
+	ret = tbl->it_ops->exchange_rm(tbl, entry, hpa, direction);
+
+	if (!ret && ((*direction == DMA_FROM_DEVICE) ||
+				(*direction == DMA_BIDIRECTIONAL))) {
+		__be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry);
+		/*
+		 * kvmppc_rm_tce_iommu_do_map() updates the UA cache after
+		 * calling this so we still get here a valid UA.
+		 */
+		if (pua && *pua)
+			mm_iommu_ua_mark_dirty_rm(mm, be64_to_cpu(*pua));
+	}
+
+	return ret;
+}
+
+static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl,
+		unsigned long entry)
 {
 	unsigned long hpa = 0;
 	enum dma_data_direction dir = DMA_NONE;
 
-	iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+	iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 }
 
 static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm,
@@ -224,7 +247,7 @@ static long kvmppc_rm_tce_iommu_do_unmap(struct kvm *kvm,
 	unsigned long hpa = 0;
 	long ret;
 
-	if (iommu_tce_xchg_rm(tbl, entry, &hpa, &dir))
+	if (iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir))
 		/*
 		 * real mode xchg can fail if struct page crosses
 		 * a page boundary
@@ -236,7 +259,7 @@ static long kvmppc_rm_tce_iommu_do_unmap(struct kvm *kvm,
 
 	ret = kvmppc_rm_tce_iommu_mapped_dec(kvm, tbl, entry);
 	if (ret)
-		iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+		iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 
 	return ret;
 }
@@ -282,7 +305,7 @@ static long kvmppc_rm_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl,
 	if (WARN_ON_ONCE_RM(mm_iommu_mapped_inc(mem)))
 		return H_CLOSED;
 
-	ret = iommu_tce_xchg_rm(tbl, entry, &hpa, &dir);
+	ret = iommu_tce_xchg_rm(kvm->mm, tbl, entry, &hpa, &dir);
 	if (ret) {
 		mm_iommu_mapped_dec(mem);
 		/*
@@ -371,7 +394,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 			return ret;
 
 		WARN_ON_ONCE_RM(1);
-		kvmppc_rm_clear_tce(stit->tbl, entry);
+		kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
 	}
 
 	kvmppc_tce_put(stt, entry, tce);
@@ -520,7 +543,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 				goto unlock_exit;
 
 			WARN_ON_ONCE_RM(1);
-			kvmppc_rm_clear_tce(stit->tbl, entry);
+			kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
 		}
 
 		kvmppc_tce_put(stt, entry + i, tce);
@@ -571,7 +594,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
 				return ret;
 
 			WARN_ON_ONCE_RM(1);
-			kvmppc_rm_clear_tce(stit->tbl, entry);
+			kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
 		}
 	}
 
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 51ce091..7a9886f 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -308,55 +308,6 @@ void register_page_bootmem_memmap(unsigned long section_nr,
 {
 }
 
-/*
- * We do not have access to the sparsemem vmemmap, so we fallback to
- * walking the list of sparsemem blocks which we already maintain for
- * the sake of crashdump. In the long run, we might want to maintain
- * a tree if performance of that linear walk becomes a problem.
- *
- * realmode_pfn_to_page functions can fail due to:
- * 1) As real sparsemem blocks do not lay in RAM continously (they
- * are in virtual address space which is not available in the real mode),
- * the requested page struct can be split between blocks so get_page/put_page
- * may fail.
- * 2) When huge pages are used, the get_page/put_page API will fail
- * in real mode as the linked addresses in the page struct are virtual
- * too.
- */
-struct page *realmode_pfn_to_page(unsigned long pfn)
-{
-	struct vmemmap_backing *vmem_back;
-	struct page *page;
-	unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
-	unsigned long pg_va = (unsigned long) pfn_to_page(pfn);
-
-	for (vmem_back = vmemmap_list; vmem_back; vmem_back = vmem_back->list) {
-		if (pg_va < vmem_back->virt_addr)
-			continue;
-
-		/* After vmemmap_list entry free is possible, need check all */
-		if ((pg_va + sizeof(struct page)) <=
-				(vmem_back->virt_addr + page_size)) {
-			page = (struct page *) (vmem_back->phys + pg_va -
-				vmem_back->virt_addr);
-			return page;
-		}
-	}
-
-	/* Probably that page struct is split between real pages */
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
-
-#else
-
-struct page *realmode_pfn_to_page(unsigned long pfn)
-{
-	struct page *page = pfn_to_page(pfn);
-	return page;
-}
-EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
-
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 #ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c
index c9ee9e2..56c2234 100644
--- a/arch/powerpc/mm/mmu_context_iommu.c
+++ b/arch/powerpc/mm/mmu_context_iommu.c
@@ -18,11 +18,15 @@
 #include <linux/migrate.h>
 #include <linux/hugetlb.h>
 #include <linux/swap.h>
+#include <linux/sizes.h>
 #include <asm/mmu_context.h>
 #include <asm/pte-walk.h>
 
 static DEFINE_MUTEX(mem_list_mutex);
 
+#define MM_IOMMU_TABLE_GROUP_PAGE_DIRTY	0x1
+#define MM_IOMMU_TABLE_GROUP_PAGE_MASK	~(SZ_4K - 1)
+
 struct mm_iommu_table_group_mem_t {
 	struct list_head next;
 	struct rcu_head rcu;
@@ -263,6 +267,9 @@ static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem)
 		if (!page)
 			continue;
 
+		if (mem->hpas[i] & MM_IOMMU_TABLE_GROUP_PAGE_DIRTY)
+			SetPageDirty(page);
+
 		put_page(page);
 		mem->hpas[i] = 0;
 	}
@@ -360,7 +367,6 @@ struct mm_iommu_table_group_mem_t *mm_iommu_lookup_rm(struct mm_struct *mm,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mm_iommu_lookup_rm);
 
 struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm,
 		unsigned long ua, unsigned long entries)
@@ -390,7 +396,7 @@ long mm_iommu_ua_to_hpa(struct mm_iommu_table_group_mem_t *mem,
 	if (pageshift > mem->pageshift)
 		return -EFAULT;
 
-	*hpa = *va | (ua & ~PAGE_MASK);
+	*hpa = (*va & MM_IOMMU_TABLE_GROUP_PAGE_MASK) | (ua & ~PAGE_MASK);
 
 	return 0;
 }
@@ -413,11 +419,31 @@ long mm_iommu_ua_to_hpa_rm(struct mm_iommu_table_group_mem_t *mem,
 	if (!pa)
 		return -EFAULT;
 
-	*hpa = *pa | (ua & ~PAGE_MASK);
+	*hpa = (*pa & MM_IOMMU_TABLE_GROUP_PAGE_MASK) | (ua & ~PAGE_MASK);
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(mm_iommu_ua_to_hpa_rm);
+
+extern void mm_iommu_ua_mark_dirty_rm(struct mm_struct *mm, unsigned long ua)
+{
+	struct mm_iommu_table_group_mem_t *mem;
+	long entry;
+	void *va;
+	unsigned long *pa;
+
+	mem = mm_iommu_lookup_rm(mm, ua, PAGE_SIZE);
+	if (!mem)
+		return;
+
+	entry = (ua - mem->ua) >> PAGE_SHIFT;
+	va = &mem->hpas[entry];
+
+	pa = (void *) vmalloc_to_phys(va);
+	if (!pa)
+		return;
+
+	*pa |= MM_IOMMU_TABLE_GROUP_PAGE_DIRTY;
+}
 
 long mm_iommu_mapped_inc(struct mm_iommu_table_group_mem_t *mem)
 {
-- 
2.11.0

^ permalink raw reply related

* [PATCH kernel v2 2/6] KVM: PPC: Validate all tces before updating tables
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

The KVM TCE handlers are written in a way so they fail when either
something went horribly wrong or the userspace did some obvious mistake
such as passing a misaligned address.

We are going to enhance the TCE checker to fail on attempts to map bigger
IOMMU page than the underlying pinned memory so let's valitate TCE
beforehand.

This should cause no behavioral change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
Changes:
v2:
* added a comment for the second get_user() from v1 discussion
---
 arch/powerpc/kvm/book3s_64_vio.c    | 18 ++++++++++++++++++
 arch/powerpc/kvm/book3s_64_vio_hv.c |  4 ++++
 2 files changed, 22 insertions(+)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 9a3f264..3c17977 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -599,6 +599,24 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		ret = kvmppc_tce_validate(stt, tce);
 		if (ret != H_SUCCESS)
 			goto unlock_exit;
+	}
+
+	for (i = 0; i < npages; ++i) {
+		/*
+		 * This looks unsafe, because we validate, then regrab
+		 * the TCE from userspace which could have been changed by
+		 * another thread.
+		 *
+		 * But it actually is safe, because the relevant checks will be
+		 * re-executed in the following code.  If userspace tries to
+		 * change this dodgily it will result in a messier failure mode
+		 * but won't threaten the host.
+		 */
+		if (get_user(tce, tces + i)) {
+			ret = H_TOO_HARD;
+			goto unlock_exit;
+		}
+		tce = be64_to_cpu(tce);
 
 		if (kvmppc_gpa_to_ua(vcpu->kvm,
 				tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 6821ead..c2848e0b 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -524,6 +524,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		ret = kvmppc_tce_validate(stt, tce);
 		if (ret != H_SUCCESS)
 			goto unlock_exit;
+	}
+
+	for (i = 0; i < npages; ++i) {
+		unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
 
 		ua = 0;
 		if (kvmppc_gpa_to_ua(vcpu->kvm,
-- 
2.11.0

^ permalink raw reply related

* [PATCH kernel v2 4/6] KVM: PPC: Validate TCEs against preregistered memory page sizes
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

The userspace can request an arbitrary supported page size for a DMA
window and this works fine as long as the mapped memory is backed with
the pages of the same or bigger size; if this is not the case,
mm_iommu_ua_to_hpa{_rm}() fail and tables do not populated with
dangerously incorrect TCEs.

However since it is quite easy to misconfigure the KVM and we do not do
reverts to all changes made to TCE tables if an error happens in a middle,
we better do the acceptable page size validation before we even touch
the tables.

This enhances kvmppc_tce_validate() to check the hardware IOMMU page sizes
against the preregistered memory page sizes.

Since the new check uses real/virtual mode helpers, this renames
kvmppc_tce_validate() to kvmppc_rm_tce_validate() to handle the real mode
case and mirrors it for the virtual mode under the old name. The real
mode handler is not used for the virtual mode as:
1. it uses _lockless() list traversing primitives instead of RCU;
2. realmode's mm_iommu_ua_to_hpa_rm() uses vmalloc_to_phys() which
virtual mode does not have to use and since on POWER9+radix only virtual
mode handlers actually work, we do not want to slow down that path even
a bit.

This removes EXPORT_SYMBOL_GPL(kvmppc_tce_validate) as the validators
are static now.

>From now on the attempts on mapping IOMMU pages bigger than allowed will
result in KVM exit.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
Changes:
v2:
* updated commit log
---
 arch/powerpc/include/asm/kvm_ppc.h  |  2 --
 arch/powerpc/kvm/book3s_64_vio.c    | 35 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/book3s_64_vio_hv.c | 30 +++++++++++++++++++++++-------
 3 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index e991821..2f5d431 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -194,8 +194,6 @@ extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
 		(iommu_tce_check_ioba((stt)->page_shift, (stt)->offset, \
 				(stt)->size, (ioba), (npages)) ?        \
 				H_PARAMETER : H_SUCCESS)
-extern long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *tt,
-		unsigned long tce);
 extern long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
 		unsigned long *ua, unsigned long **prmap);
 extern void kvmppc_tce_put(struct kvmppc_spapr_tce_table *tt,
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 984cec8..01e1994 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -363,6 +363,41 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 	return ret;
 }
 
+static long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt,
+		unsigned long tce)
+{
+	unsigned long gpa = tce & ~(TCE_PCI_READ | TCE_PCI_WRITE);
+	enum dma_data_direction dir = iommu_tce_direction(tce);
+	struct kvmppc_spapr_tce_iommu_table *stit;
+	unsigned long ua = 0;
+
+	/* Allow userspace to poison TCE table */
+	if (dir == DMA_NONE)
+		return H_SUCCESS;
+
+	if (iommu_tce_check_gpa(stt->page_shift, gpa))
+		return H_TOO_HARD;
+
+	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
+				&ua, NULL))
+		return H_TOO_HARD;
+
+	list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
+		unsigned long hpa = 0;
+		struct mm_iommu_table_group_mem_t *mem;
+		long shift = stit->tbl->it_page_shift;
+
+		mem = mm_iommu_lookup(stt->kvm->mm, ua, 1ULL << shift);
+		if (!mem)
+			return H_TOO_HARD;
+
+		if (mm_iommu_ua_to_hpa(mem, ua, shift, &hpa))
+			return H_TOO_HARD;
+	}
+
+	return H_SUCCESS;
+}
+
 static void kvmppc_clear_tce(struct iommu_table *tbl, unsigned long entry)
 {
 	unsigned long hpa = 0;
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 7388b66..977e95a 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -94,14 +94,14 @@ EXPORT_SYMBOL_GPL(kvmppc_find_table);
  * to the table and user space is supposed to process them), we can skip
  * checking other things (such as TCE is a guest RAM address or the page
  * was actually allocated).
- *
- * WARNING: This will be called in real-mode on HV KVM and virtual
- *          mode on PR KVM
  */
-long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt, unsigned long tce)
+static long kvmppc_rm_tce_validate(struct kvmppc_spapr_tce_table *stt,
+		unsigned long tce)
 {
 	unsigned long gpa = tce & ~(TCE_PCI_READ | TCE_PCI_WRITE);
 	enum dma_data_direction dir = iommu_tce_direction(tce);
+	struct kvmppc_spapr_tce_iommu_table *stit;
+	unsigned long ua = 0;
 
 	/* Allow userspace to poison TCE table */
 	if (dir == DMA_NONE)
@@ -110,9 +110,25 @@ long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt, unsigned long tce)
 	if (iommu_tce_check_gpa(stt->page_shift, gpa))
 		return H_PARAMETER;
 
+	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
+				&ua, NULL))
+		return H_TOO_HARD;
+
+	list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
+		unsigned long hpa = 0;
+		struct mm_iommu_table_group_mem_t *mem;
+		long shift = stit->tbl->it_page_shift;
+
+		mem = mm_iommu_lookup_rm(stt->kvm->mm, ua, 1ULL << shift);
+		if (!mem)
+			return H_TOO_HARD;
+
+		if (mm_iommu_ua_to_hpa_rm(mem, ua, shift, &hpa))
+			return H_TOO_HARD;
+	}
+
 	return H_SUCCESS;
 }
-EXPORT_SYMBOL_GPL(kvmppc_tce_validate);
 
 /* Note on the use of page_address() in real mode,
  *
@@ -368,7 +384,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (ret != H_SUCCESS)
 		return ret;
 
-	ret = kvmppc_tce_validate(stt, tce);
+	ret = kvmppc_rm_tce_validate(stt, tce);
 	if (ret != H_SUCCESS)
 		return ret;
 
@@ -521,7 +537,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	for (i = 0; i < npages; ++i) {
 		unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
 
-		ret = kvmppc_tce_validate(stt, tce);
+		ret = kvmppc_rm_tce_validate(stt, tce);
 		if (ret != H_SUCCESS)
 			goto unlock_exit;
 	}
-- 
2.11.0

^ permalink raw reply related

* [PATCH kernel v2 5/6] KVM: PPC: Propagate errors to the guest when failed instead of ignoring
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

At the moment if the PUT_TCE{_INDIRECT} handlers fail to update
the hardware tables, we print a warning once, clear the entry and
continue. This is so as at the time the assumption was that if
a VFIO device is hotplugged into the guest, and the userspace replays
virtual DMA mappings (i.e. TCEs) to the hardware tables and if this fails,
then there is nothing useful we can do about it.

However the assumption is not valid as these handlers are not called for
TCE replay (VFIO ioctl interface is used for that) and these handlers
are for new TCEs.

This returns an error to the guest if there is a request which cannot be
processed. By now the only possible failure must be H_TOO_HARD.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 arch/powerpc/kvm/book3s_64_vio.c    | 20 ++++++--------------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 21 +++++++--------------
 2 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 01e1994..8231b17 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -568,14 +568,10 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 			ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, stit->tbl,
 					entry, ua, dir);
 
-		if (ret == H_SUCCESS)
-			continue;
-
-		if (ret == H_TOO_HARD)
+		if (ret != H_SUCCESS) {
+			kvmppc_clear_tce(stit->tbl, entry);
 			goto unlock_exit;
-
-		WARN_ON_ONCE(1);
-		kvmppc_clear_tce(stit->tbl, entry);
+		}
 	}
 
 	kvmppc_tce_put(stt, entry, tce);
@@ -663,14 +659,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 					stit->tbl, entry + i, ua,
 					iommu_tce_direction(tce));
 
-			if (ret == H_SUCCESS)
-				continue;
-
-			if (ret == H_TOO_HARD)
+			if (ret != H_SUCCESS) {
+				kvmppc_clear_tce(stit->tbl, entry);
 				goto unlock_exit;
-
-			WARN_ON_ONCE(1);
-			kvmppc_clear_tce(stit->tbl, entry);
+			}
 		}
 
 		kvmppc_tce_put(stt, entry + i, tce);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 977e95a..adf3b21 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -403,14 +403,10 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 			ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt,
 					stit->tbl, entry, ua, dir);
 
-		if (ret == H_SUCCESS)
-			continue;
-
-		if (ret == H_TOO_HARD)
+		if (ret != H_SUCCESS) {
+			kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
 			return ret;
-
-		WARN_ON_ONCE_RM(1);
-		kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
+		}
 	}
 
 	kvmppc_tce_put(stt, entry, tce);
@@ -556,14 +552,11 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 					stit->tbl, entry + i, ua,
 					iommu_tce_direction(tce));
 
-			if (ret == H_SUCCESS)
-				continue;
-
-			if (ret == H_TOO_HARD)
+			if (ret != H_SUCCESS) {
+				kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl,
+						entry);
 				goto unlock_exit;
-
-			WARN_ON_ONCE_RM(1);
-			kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
+			}
 		}
 
 		kvmppc_tce_put(stt, entry + i, tce);
-- 
2.11.0

^ permalink raw reply related

* [PATCH kernel v2 6/6] KVM: PPC: Remove redundand permission bits removal
From: Alexey Kardashevskiy @ 2018-09-10  8:29 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, David Gibson, kvm-ppc, Aneesh Kumar K.V,
	Paul Mackerras, Alex Williamson
In-Reply-To: <20180910082912.13255-1-aik@ozlabs.ru>

The kvmppc_gpa_to_ua() helper itself takes care of the permission
bits in the TCE and yet every single caller removes them.

This changes semantics of kvmppc_gpa_to_ua() so it takes TCEs
(which are GPAs + TCE permission bits) to make the callers simpler.

This should cause no behavioural change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2:
* %s/kvmppc_gpa_to_ua/kvmppc_tce_to_ua/g
---
 arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
 arch/powerpc/kvm/book3s_64_vio.c    | 12 ++++--------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 22 +++++++++-------------
 3 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 2f5d431..38d0328 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -194,7 +194,7 @@ extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
 		(iommu_tce_check_ioba((stt)->page_shift, (stt)->offset, \
 				(stt)->size, (ioba), (npages)) ?        \
 				H_PARAMETER : H_SUCCESS)
-extern long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
+extern long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce,
 		unsigned long *ua, unsigned long **prmap);
 extern void kvmppc_tce_put(struct kvmppc_spapr_tce_table *tt,
 		unsigned long idx, unsigned long tce);
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 8231b17..c0c64d1 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -378,8 +378,7 @@ static long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt,
 	if (iommu_tce_check_gpa(stt->page_shift, gpa))
 		return H_TOO_HARD;
 
-	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-				&ua, NULL))
+	if (kvmppc_tce_to_ua(stt->kvm, tce, &ua, NULL))
 		return H_TOO_HARD;
 
 	list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
@@ -552,8 +551,7 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 
 	idx = srcu_read_lock(&vcpu->kvm->srcu);
 
-	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
-			tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL)) {
+	if ((dir != DMA_NONE) && kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) {
 		ret = H_PARAMETER;
 		goto unlock_exit;
 	}
@@ -614,7 +612,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		return ret;
 
 	idx = srcu_read_lock(&vcpu->kvm->srcu);
-	if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, NULL)) {
+	if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, NULL)) {
 		ret = H_TOO_HARD;
 		goto unlock_exit;
 	}
@@ -649,9 +647,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		}
 		tce = be64_to_cpu(tce);
 
-		if (kvmppc_gpa_to_ua(vcpu->kvm,
-				tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-				&ua, NULL))
+		if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
 			return H_PARAMETER;
 
 		list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index adf3b21..389dac1 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -110,8 +110,7 @@ static long kvmppc_rm_tce_validate(struct kvmppc_spapr_tce_table *stt,
 	if (iommu_tce_check_gpa(stt->page_shift, gpa))
 		return H_PARAMETER;
 
-	if (kvmppc_gpa_to_ua(stt->kvm, tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-				&ua, NULL))
+	if (kvmppc_tce_to_ua(stt->kvm, tce, &ua, NULL))
 		return H_TOO_HARD;
 
 	list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
@@ -180,10 +179,10 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
 }
 EXPORT_SYMBOL_GPL(kvmppc_tce_put);
 
-long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
+long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce,
 		unsigned long *ua, unsigned long **prmap)
 {
-	unsigned long gfn = gpa >> PAGE_SHIFT;
+	unsigned long gfn = tce >> PAGE_SHIFT;
 	struct kvm_memory_slot *memslot;
 
 	memslot = search_memslots(kvm_memslots(kvm), gfn);
@@ -191,7 +190,7 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
 		return -EINVAL;
 
 	*ua = __gfn_to_hva_memslot(memslot, gfn) |
-		(gpa & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
+		(tce & ~(PAGE_MASK | TCE_PCI_READ | TCE_PCI_WRITE));
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 	if (prmap)
@@ -200,7 +199,7 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(kvmppc_gpa_to_ua);
+EXPORT_SYMBOL_GPL(kvmppc_tce_to_ua);
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 static long iommu_tce_xchg_rm(struct mm_struct *mm, struct iommu_table *tbl,
@@ -389,8 +388,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 		return ret;
 
 	dir = iommu_tce_direction(tce);
-	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
-			tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL))
+	if ((dir != DMA_NONE) && kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
 		return H_PARAMETER;
 
 	entry = ioba >> stt->page_shift;
@@ -492,7 +490,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		 */
 		struct mm_iommu_table_group_mem_t *mem;
 
-		if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, NULL))
+		if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, NULL))
 			return H_TOO_HARD;
 
 		mem = mm_iommu_lookup_rm(vcpu->kvm->mm, ua, IOMMU_PAGE_SIZE_4K);
@@ -508,7 +506,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		 * We do not require memory to be preregistered in this case
 		 * so lock rmap and do __find_linux_pte_or_hugepte().
 		 */
-		if (kvmppc_gpa_to_ua(vcpu->kvm, tce_list, &ua, &rmap))
+		if (kvmppc_tce_to_ua(vcpu->kvm, tce_list, &ua, &rmap))
 			return H_TOO_HARD;
 
 		rmap = (void *) vmalloc_to_phys(rmap);
@@ -542,9 +540,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 		unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
 
 		ua = 0;
-		if (kvmppc_gpa_to_ua(vcpu->kvm,
-				tce & ~(TCE_PCI_READ | TCE_PCI_WRITE),
-				&ua, NULL))
+		if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
 			return H_PARAMETER;
 
 		list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
-- 
2.11.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox