From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: "Williams, Dan J" Subject: Re: [PATCH v2 05/20] x86, mm: introduce vmem_altmap to augment vmemmap_populate() Date: Mon, 19 Oct 2015 22:53:00 +0000 Message-ID: <1445295178.29633.8.camel@intel.com> References: <20151010005522.17221.87557.stgit@dwillia2-desk3.jf.intel.com> <20151010005549.17221.32687.stgit@dwillia2-desk3.jf.intel.com> In-Reply-To: <20151010005549.17221.32687.stgit@dwillia2-desk3.jf.intel.com> Content-Language: en-US Content-Type: text/plain; charset="utf-8" Content-ID: <757C1FBEA87F6D41871264554ABE4B5A@intel.com> Content-Transfer-Encoding: base64 MIME-Version: 1.0 Sender: owner-linux-mm@kvack.org To: "linux-nvdimm@lists.01.org" Cc: "linux-kernel@vger.kernel.org" , "linux-mm@kvack.org" , "dave.hansen@linux.intel.com" , "hch@lst.de" , "akpm@linux-foundation.org" , "hpa@zytor.com" , "mingo@redhat.com" , "ross.zwisler@linux.intel.com" List-ID: T24gRnJpLCAyMDE1LTEwLTA5IGF0IDIwOjU1IC0wNDAwLCBEYW4gV2lsbGlhbXMgd3JvdGU6DQo+ IEluIHN1cHBvcnQgb2YgcHJvdmlkaW5nIHN0cnVjdCBwYWdlIGZvciBsYXJnZSBwZXJzaXN0ZW50 IG1lbW9yeQ0KPiBjYXBhY2l0aWVzLCB1c2Ugc3RydWN0IHZtZW1fYWx0bWFwIHRvIGNoYW5nZSB0 aGUgZGVmYXVsdCBwb2xpY3kgZm9yDQo+IGFsbG9jYXRpbmcgbWVtb3J5IGZvciB0aGUgbWVtbWFw IGFycmF5LiAgVGhlIGRlZmF1bHQgdm1lbW1hcF9wb3B1bGF0ZSgpDQo+IGFsbG9jYXRlcyBwYWdl IHRhYmxlIHN0b3JhZ2UgYXJlYSBmcm9tIHRoZSBwYWdlIGFsbG9jYXRvci4gIEdpdmVuDQo+IHBl cnNpc3RlbnQgbWVtb3J5IGNhcGFjaXRpZXMgcmVsYXRpdmUgdG8gRFJBTSBpdCBtYXkgbm90IGJl IGZlYXNpYmxlIHRvDQo+IHN0b3JlIHRoZSBtZW1tYXAgaW4gJ1N5c3RlbSBNZW1vcnknLiAgSW5z dGVhZCB2bWVtX2FsdG1hcCByZXByZXNlbnRzDQo+IHByZS1hbGxvY2F0ZWQgImRldmljZSBwYWdl cyIgdG8gc2F0aXNmeSB2bWVtbWFwX2FsbG9jX2Jsb2NrX2J1ZigpDQo+IHJlcXVlc3RzLg0KPiAN Cj4gQ2M6IEguIFBldGVyIEFudmluIDxocGFAenl0b3IuY29tPg0KPiBDYzogSW5nbyBNb2xuYXIg PG1pbmdvQHJlZGhhdC5jb20+DQo+IENjOiBEYXZlIEhhbnNlbiA8ZGF2ZS5oYW5zZW5AbGludXgu aW50ZWwuY29tPg0KPiBDYzogQW5kcmV3IE1vcnRvbiA8YWtwbUBsaW51eC1mb3VuZGF0aW9uLm9y Zz4NCj4gU2lnbmVkLW9mZi1ieTogRGFuIFdpbGxpYW1zIDxkYW4uai53aWxsaWFtc0BpbnRlbC5j b20+DQo+IC0tLQ0KDQpUaGUga2J1aWxkIHRlc3Qgcm9ib3QgcmVwb3J0ZWQgYSBjcmFzaCB3aXRo IHRoaXMgcGF0Y2ggd2hlbg0KQ09ORklHX1pPTkVfREVWSUNFPXkgJiYgQ09ORklHX1NQQVJTRU1F TV9WTUVNTUFQPW4uICBUaGUgYWJpbGl0eSB0bw0Kc3BlY2lmeSBhbiBhbHRlcm5hdGUgbG9jYXRp b24gZm9yIHRoZSB2bWVtbWFwIG5lZWRzIHRvIGJlIGdhdGVkIG9uDQpDT05GSUdfU1BBUlNFTUVN X1ZNRU1NQVA9eS4NCg0KSGVyZSdzIGEgcmVmcmVzaGVkIHBhdGNoIHdpdGggaWZkZWYgZ3VhcmRz IGFuZCBhIHdhcm5pbmcgbWVzc2FnZSBpZiB0aGUNCkBhbHRtYXAgYXJnIGlzIHBhc3NlZCB0byBk ZXZtX21lbXJlbWFwX3BhZ2VzKCkgb24gYQ0KQ09ORklHX1NQQVJTRU1FTV9WTUVNTUFQPW4ga2Vy bmVsLg0KDQoNCjg8LS0tLQ0KU3ViamVjdDogeDg2LCBtbTogaW50cm9kdWNlIHZtZW1fYWx0bWFw IHRvIGF1Z21lbnQgdm1lbW1hcF9wb3B1bGF0ZSgpDQoNCkZyb206IERhbiBXaWxsaWFtcyA8ZGFu Lmoud2lsbGlhbXNAaW50ZWwuY29tPg0KDQpJbiBzdXBwb3J0IG9mIHByb3ZpZGluZyBzdHJ1Y3Qg cGFnZSBmb3IgbGFyZ2UgcGVyc2lzdGVudCBtZW1vcnkNCmNhcGFjaXRpZXMsIHVzZSBzdHJ1Y3Qg dm1lbV9hbHRtYXAgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IHBvbGljeSBmb3INCmFsbG9jYXRpbmcg bWVtb3J5IGZvciB0aGUgbWVtbWFwIGFycmF5LiAgVGhlIGRlZmF1bHQgdm1lbW1hcF9wb3B1bGF0 ZSgpDQphbGxvY2F0ZXMgcGFnZSB0YWJsZSBzdG9yYWdlIGFyZWEgZnJvbSB0aGUgcGFnZSBhbGxv Y2F0b3IuICBHaXZlbg0KcGVyc2lzdGVudCBtZW1vcnkgY2FwYWNpdGllcyByZWxhdGl2ZSB0byBE UkFNIGl0IG1heSBub3QgYmUgZmVhc2libGUgdG8NCnN0b3JlIHRoZSBtZW1tYXAgaW4gJ1N5c3Rl bSBNZW1vcnknLiAgSW5zdGVhZCB2bWVtX2FsdG1hcCByZXByZXNlbnRzDQpwcmUtYWxsb2NhdGVk ICJkZXZpY2UgcGFnZXMiIHRvIHNhdGlzZnkgdm1lbW1hcF9hbGxvY19ibG9ja19idWYoKQ0KcmVx dWVzdHMuDQoNCkNjOiBILiBQZXRlciBBbnZpbiA8aHBhQHp5dG9yLmNvbT4NCkNjOiBJbmdvIE1v bG5hciA8bWluZ29AcmVkaGF0LmNvbT4NCkNjOiBEYXZlIEhhbnNlbiA8ZGF2ZS5oYW5zZW5AbGlu dXguaW50ZWwuY29tPg0KQ2M6IEFuZHJldyBNb3J0b24gPGFrcG1AbGludXgtZm91bmRhdGlvbi5v cmc+DQpSZXBvcnRlZC1ieToga2J1aWxkIHRlc3Qgcm9ib3QgPGxrcEBpbnRlbC5jb20+DQpTaWdu ZWQtb2ZmLWJ5OiBEYW4gV2lsbGlhbXMgPGRhbi5qLndpbGxpYW1zQGludGVsLmNvbT4NCi0tLQ0K IGFyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX21tLmggfCAgICAxIA0KIGFyY2gvbTY4ay9pbmNs dWRlL2FzbS9wYWdlX25vLmggfCAgICAxIA0KIGFyY2gvbW4xMDMwMC9pbmNsdWRlL2FzbS9wYWdl LmggfCAgICAxIA0KIGFyY2gveDg2L21tL2luaXRfNjQuYyAgICAgICAgICAgfCAgIDMyICsrKysr KysrKystLS0NCiBkcml2ZXJzL252ZGltbS9wbWVtLmMgICAgICAgICAgIHwgICAgNiArKw0KIGlu Y2x1ZGUvbGludXgvaW8uaCAgICAgICAgICAgICAgfCAgIDE3IC0tLS0tLS0NCiBpbmNsdWRlL2xp bnV4L21lbW9yeV9ob3RwbHVnLmggIHwgICAgMyArDQogaW5jbHVkZS9saW51eC9tbS5oICAgICAg ICAgICAgICB8ICAgOTggKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystDQog a2VybmVsL21lbXJlbWFwLmMgICAgICAgICAgICAgICB8ICAgNzcgKysrKysrKysrKysrKysrKysr KysrKysrKysrLS0tLQ0KIG1tL21lbW9yeV9ob3RwbHVnLmMgICAgICAgICAgICAgfCAgIDY2ICsr KysrKysrKysrKysrKysrKystLS0tLS0tDQogbW0vcGFnZV9hbGxvYy5jICAgICAgICAgICAgICAg ICB8ICAgMTAgKysrKw0KIG1tL3NwYXJzZS12bWVtbWFwLmMgICAgICAgICAgICAgfCAgIDM3ICsr KysrKysrKysrKysrLQ0KIG1tL3NwYXJzZS5jICAgICAgICAgICAgICAgICAgICAgfCAgICA4ICsr LQ0KIDEzIGZpbGVzIGNoYW5nZWQsIDI5NCBpbnNlcnRpb25zKCspLCA2MyBkZWxldGlvbnMoLSkN Cg0KZGlmZiAtLWdpdCBhL2FyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX21tLmggYi9hcmNoL202 OGsvaW5jbHVkZS9hc20vcGFnZV9tbS5oDQppbmRleCA1MDI5ZjczZTYyOTQuLjg4NGYyZjdlNGNh ZiAxMDA2NDQNCi0tLSBhL2FyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX21tLmgNCisrKyBiL2Fy Y2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX21tLmgNCkBAIC0xMjUsNiArMTI1LDcgQEAgc3RhdGlj IGlubGluZSB2b2lkICpfX3ZhKHVuc2lnbmVkIGxvbmcgeCkNCiAgKi8NCiAjZGVmaW5lIHZpcnRf dG9fcGZuKGthZGRyKQkoX19wYShrYWRkcikgPj4gUEFHRV9TSElGVCkNCiAjZGVmaW5lIHBmbl90 b192aXJ0KHBmbikJX192YSgocGZuKSA8PCBQQUdFX1NISUZUKQ0KKyNkZWZpbmUJX19wZm5fdG9f cGh5cyhwZm4pCVBGTl9QSFlTKHBmbikNCiANCiBleHRlcm4gaW50IG02OGtfdmlydF90b19ub2Rl X3NoaWZ0Ow0KIA0KZGlmZiAtLWdpdCBhL2FyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX25vLmgg Yi9hcmNoL202OGsvaW5jbHVkZS9hc20vcGFnZV9uby5oDQppbmRleCBlZjIwOTE2OTU3OWEuLjc4 NDVlY2EwYjM2ZCAxMDA2NDQNCi0tLSBhL2FyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX25vLmgN CisrKyBiL2FyY2gvbTY4ay9pbmNsdWRlL2FzbS9wYWdlX25vLmgNCkBAIC0yNCw2ICsyNCw3IEBA IGV4dGVybiB1bnNpZ25lZCBsb25nIG1lbW9yeV9lbmQ7DQogDQogI2RlZmluZSB2aXJ0X3RvX3Bm bihrYWRkcikJKF9fcGEoa2FkZHIpID4+IFBBR0VfU0hJRlQpDQogI2RlZmluZSBwZm5fdG9fdmly dChwZm4pCV9fdmEoKHBmbikgPDwgUEFHRV9TSElGVCkNCisjZGVmaW5lCV9fcGZuX3RvX3BoeXMo cGZuKQlQRk5fUEhZUyhwZm4pDQogDQogI2RlZmluZSB2aXJ0X3RvX3BhZ2UoYWRkcikJKG1lbV9t YXAgKyAoKCh1bnNpZ25lZCBsb25nKShhZGRyKS1QQUdFX09GRlNFVCkgPj4gUEFHRV9TSElGVCkp DQogI2RlZmluZSBwYWdlX3RvX3ZpcnQocGFnZSkJX192YSgoKCgocGFnZSkgLSBtZW1fbWFwKSA8 PCBQQUdFX1NISUZUKSArIFBBR0VfT0ZGU0VUKSkNCmRpZmYgLS1naXQgYS9hcmNoL21uMTAzMDAv aW5jbHVkZS9hc20vcGFnZS5oIGIvYXJjaC9tbjEwMzAwL2luY2x1ZGUvYXNtL3BhZ2UuaA0KaW5k ZXggODI4OGUxMjQxNjViLi4zODEwYTZmNzQwZmQgMTAwNjQ0DQotLS0gYS9hcmNoL21uMTAzMDAv aW5jbHVkZS9hc20vcGFnZS5oDQorKysgYi9hcmNoL21uMTAzMDAvaW5jbHVkZS9hc20vcGFnZS5o DQpAQCAtMTA3LDYgKzEwNyw3IEBAIHN0YXRpYyBpbmxpbmUgaW50IGdldF9vcmRlcih1bnNpZ25l ZCBsb25nIHNpemUpDQogI2RlZmluZSBwZm5fdG9fa2FkZHIocGZuKQlfX3ZhKChwZm4pIDw8IFBB R0VfU0hJRlQpDQogI2RlZmluZSBwZm5fdG9fcGFnZShwZm4pCShtZW1fbWFwICsgKChwZm4pIC0g X19wZm5fZGlzcCkpDQogI2RlZmluZSBwYWdlX3RvX3BmbihwYWdlKQkoKHVuc2lnbmVkIGxvbmcp KChwYWdlKSAtIG1lbV9tYXApICsgX19wZm5fZGlzcCkNCisjZGVmaW5lIF9fcGZuX3RvX3BoeXMo cGZuKQlQRk5fUEhZUyhwZm4pDQogDQogI2RlZmluZSBwZm5fdmFsaWQocGZuKQkJCQkJXA0KICh7 CQkJCQkJCVwNCmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9tbS9pbml0XzY0LmMgYi9hcmNoL3g4Ni9t bS9pbml0XzY0LmMNCmluZGV4IGU1ZDQyZjFhMmE3MS4uY2FiZjhjZWIwYTZiIDEwMDY0NA0KLS0t IGEvYXJjaC94ODYvbW0vaW5pdF82NC5jDQorKysgYi9hcmNoL3g4Ni9tbS9pbml0XzY0LmMNCkBA IC03MTQsNiArNzE0LDEyIEBAIHN0YXRpYyB2b2lkIF9fbWVtaW5pdCBmcmVlX3BhZ2V0YWJsZShz dHJ1Y3QgcGFnZSAqcGFnZSwgaW50IG9yZGVyKQ0KIHsNCiAJdW5zaWduZWQgbG9uZyBtYWdpYzsN CiAJdW5zaWduZWQgaW50IG5yX3BhZ2VzID0gMSA8PCBvcmRlcjsNCisJc3RydWN0IHZtZW1fYWx0 bWFwICphbHRtYXAgPSB0b192bWVtX2FsdG1hcCgodW5zaWduZWQgbG9uZykgcGFnZSk7DQorDQor CWlmIChhbHRtYXApIHsNCisJCXZtZW1fYWx0bWFwX2ZyZWUoYWx0bWFwLCBucl9wYWdlcyk7DQor CQlyZXR1cm47DQorCX0NCiANCiAJLyogYm9vdG1lbSBwYWdlIGhhcyByZXNlcnZlZCBmbGFnICov DQogCWlmIChQYWdlUmVzZXJ2ZWQocGFnZSkpIHsNCkBAIC0xMDE4LDEzICsxMDI0LDE5IEBAIGlu dCBfX3JlZiBhcmNoX3JlbW92ZV9tZW1vcnkodTY0IHN0YXJ0LCB1NjQgc2l6ZSkNCiB7DQogCXVu c2lnbmVkIGxvbmcgc3RhcnRfcGZuID0gc3RhcnQgPj4gUEFHRV9TSElGVDsNCiAJdW5zaWduZWQg bG9uZyBucl9wYWdlcyA9IHNpemUgPj4gUEFHRV9TSElGVDsNCisJc3RydWN0IHBhZ2UgKnBhZ2Ug PSBwZm5fdG9fcGFnZShzdGFydF9wZm4pOw0KKwlzdHJ1Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcDsN CiAJc3RydWN0IHpvbmUgKnpvbmU7DQogCWludCByZXQ7DQogDQotCXpvbmUgPSBwYWdlX3pvbmUo cGZuX3RvX3BhZ2Uoc3RhcnRfcGZuKSk7DQotCWtlcm5lbF9waHlzaWNhbF9tYXBwaW5nX3JlbW92 ZShzdGFydCwgc3RhcnQgKyBzaXplKTsNCisJLyogV2l0aCBhbHRtYXAgdGhlIGZpcnN0IG1hcHBl ZCBwYWdlIGlzIG9mZnNldCBmcm9tIEBzdGFydCAqLw0KKwlhbHRtYXAgPSB0b192bWVtX2FsdG1h cCgodW5zaWduZWQgbG9uZykgcGFnZSk7DQorCWlmIChhbHRtYXApDQorCQlwYWdlICs9IHZtZW1f YWx0bWFwX29mZnNldChhbHRtYXApOw0KKwl6b25lID0gcGFnZV96b25lKHBhZ2UpOw0KIAlyZXQg PSBfX3JlbW92ZV9wYWdlcyh6b25lLCBzdGFydF9wZm4sIG5yX3BhZ2VzKTsNCiAJV0FSTl9PTl9P TkNFKHJldCk7DQorCWtlcm5lbF9waHlzaWNhbF9tYXBwaW5nX3JlbW92ZShzdGFydCwgc3RhcnQg KyBzaXplKTsNCiANCiAJcmV0dXJuIHJldDsNCiB9DQpAQCAtMTIzNCw3ICsxMjQ2LDcgQEAgc3Rh dGljIHZvaWQgX19tZW1pbml0ZGF0YSAqcF9zdGFydCwgKnBfZW5kOw0KIHN0YXRpYyBpbnQgX19t ZW1pbml0ZGF0YSBub2RlX3N0YXJ0Ow0KIA0KIHN0YXRpYyBpbnQgX19tZW1pbml0IHZtZW1tYXBf cG9wdWxhdGVfaHVnZXBhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsDQotCQkJCQkJdW5zaWduZWQg bG9uZyBlbmQsIGludCBub2RlKQ0KKwkJdW5zaWduZWQgbG9uZyBlbmQsIGludCBub2RlLCBzdHJ1 Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcCkNCiB7DQogCXVuc2lnbmVkIGxvbmcgYWRkcjsNCiAJdW5z aWduZWQgbG9uZyBuZXh0Ow0KQEAgLTEyNTcsNyArMTI2OSw3IEBAIHN0YXRpYyBpbnQgX19tZW1p bml0IHZtZW1tYXBfcG9wdWxhdGVfaHVnZXBhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsDQogCQlp ZiAocG1kX25vbmUoKnBtZCkpIHsNCiAJCQl2b2lkICpwOw0KIA0KLQkJCXAgPSB2bWVtbWFwX2Fs bG9jX2Jsb2NrX2J1ZihQTURfU0laRSwgbm9kZSk7DQorCQkJcCA9IHZtZW1tYXBfYWxsb2NfYmxv Y2tfYnVmKFBNRF9TSVpFLCBub2RlLCBhbHRtYXApOw0KIAkJCWlmIChwKSB7DQogCQkJCXB0ZV90 IGVudHJ5Ow0KIA0KQEAgLTEyNzgsNyArMTI5MCw4IEBAIHN0YXRpYyBpbnQgX19tZW1pbml0IHZt ZW1tYXBfcG9wdWxhdGVfaHVnZXBhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsDQogCQkJCWFkZHJf ZW5kID0gYWRkciArIFBNRF9TSVpFOw0KIAkJCQlwX2VuZCA9IHAgKyBQTURfU0laRTsNCiAJCQkJ Y29udGludWU7DQotCQkJfQ0KKwkJCX0gZWxzZSBpZiAoYWx0bWFwKQ0KKwkJCQlyZXR1cm4gLUVO T01FTTsgLyogbm8gZmFsbGJhY2sgKi8NCiAJCX0gZWxzZSBpZiAocG1kX2xhcmdlKCpwbWQpKSB7 DQogCQkJdm1lbW1hcF92ZXJpZnkoKHB0ZV90ICopcG1kLCBub2RlLCBhZGRyLCBuZXh0KTsNCiAJ CQljb250aW51ZTsNCkBAIC0xMjkyLDExICsxMzA1LDE2IEBAIHN0YXRpYyBpbnQgX19tZW1pbml0 IHZtZW1tYXBfcG9wdWxhdGVfaHVnZXBhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsDQogDQogaW50 IF9fbWVtaW5pdCB2bWVtbWFwX3BvcHVsYXRlKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVk IGxvbmcgZW5kLCBpbnQgbm9kZSkNCiB7DQorCXN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwID0g dG9fdm1lbV9hbHRtYXAoc3RhcnQpOw0KIAlpbnQgZXJyOw0KIA0KIAlpZiAoY3B1X2hhc19wc2Up DQotCQllcnIgPSB2bWVtbWFwX3BvcHVsYXRlX2h1Z2VwYWdlcyhzdGFydCwgZW5kLCBub2RlKTsN Ci0JZWxzZQ0KKwkJZXJyID0gdm1lbW1hcF9wb3B1bGF0ZV9odWdlcGFnZXMoc3RhcnQsIGVuZCwg bm9kZSwgYWx0bWFwKTsNCisJZWxzZSBpZiAoYWx0bWFwKSB7DQorCQlwcl9lcnJfb25jZSgiJXM6 IG5vIGNwdSBzdXBwb3J0IGZvciBhbHRtYXAgYWxsb2NhdGlvbnNcbiIsDQorCQkJCV9fZnVuY19f KTsNCisJCWVyciA9IC1FTk9NRU07DQorCX0gZWxzZQ0KIAkJZXJyID0gdm1lbW1hcF9wb3B1bGF0 ZV9iYXNlcGFnZXMoc3RhcnQsIGVuZCwgbm9kZSk7DQogCWlmICghZXJyKQ0KIAkJc3luY19nbG9i YWxfcGdkcyhzdGFydCwgZW5kIC0gMSwgMCk7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9udmRpbW0v cG1lbS5jIGIvZHJpdmVycy9udmRpbW0vcG1lbS5jDQppbmRleCAzNDlmMDNlN2VkMDYuLjNjNWI4 ZjU4NTQ0MSAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvbnZkaW1tL3BtZW0uYw0KKysrIGIvZHJpdmVy cy9udmRpbW0vcG1lbS5jDQpAQCAtMTUxLDcgKzE1MSw4IEBAIHN0YXRpYyBzdHJ1Y3QgcG1lbV9k ZXZpY2UgKnBtZW1fYWxsb2Moc3RydWN0IGRldmljZSAqZGV2LA0KIAl9DQogDQogCWlmIChwbWVt X3Nob3VsZF9tYXBfcGFnZXMoZGV2KSkNCi0JCXBtZW0tPnZpcnRfYWRkciA9ICh2b2lkIF9fcG1l bSAqKSBkZXZtX21lbXJlbWFwX3BhZ2VzKGRldiwgcmVzKTsNCisJCXBtZW0tPnZpcnRfYWRkciA9 ICh2b2lkIF9fcG1lbSAqKSBkZXZtX21lbXJlbWFwX3BhZ2VzKGRldiwgcmVzLA0KKwkJCQlOVUxM KTsNCiAJZWxzZQ0KIAkJcG1lbS0+dmlydF9hZGRyID0gKHZvaWQgX19wbWVtICopIGRldm1fbWVt cmVtYXAoZGV2LA0KIAkJCQlwbWVtLT5waHlzX2FkZHIsIHBtZW0tPnNpemUsDQpAQCAtMzYyLDcg KzM2Myw4IEBAIHN0YXRpYyBpbnQgbnZkaW1tX25hbWVzcGFjZV9hdHRhY2hfcGZuKHN0cnVjdCBu ZF9uYW1lc3BhY2VfY29tbW9uICpuZG5zKQ0KIAkvKiBlc3RhYmxpc2ggcGZuIHJhbmdlIGZvciBs b29rdXAsIGFuZCBzd2l0Y2ggdG8gZGlyZWN0IG1hcCAqLw0KIAlwbWVtID0gZGV2X2dldF9kcnZk YXRhKGRldik7DQogCWRldm1fbWVtdW5tYXAoZGV2LCAodm9pZCBfX2ZvcmNlICopIHBtZW0tPnZp cnRfYWRkcik7DQotCXBtZW0tPnZpcnRfYWRkciA9ICh2b2lkIF9fcG1lbSAqKSBkZXZtX21lbXJl bWFwX3BhZ2VzKGRldiwgJm5zaW8tPnJlcyk7DQorCXBtZW0tPnZpcnRfYWRkciA9ICh2b2lkIF9f cG1lbSAqKSBkZXZtX21lbXJlbWFwX3BhZ2VzKGRldiwgJm5zaW8tPnJlcywNCisJCQlOVUxMKTsN CiAJaWYgKElTX0VSUihwbWVtLT52aXJ0X2FkZHIpKSB7DQogCQlyYyA9IFBUUl9FUlIocG1lbS0+ dmlydF9hZGRyKTsNCiAJCWdvdG8gZXJyOw0KZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvaW8u aCBiL2luY2x1ZGUvbGludXgvaW8uaA0KaW5kZXggZGU2NGMxZTUzNjEyLi4yZjJmODg1OWFiZDkg MTAwNjQ0DQotLS0gYS9pbmNsdWRlL2xpbnV4L2lvLmgNCisrKyBiL2luY2x1ZGUvbGludXgvaW8u aA0KQEAgLTg3LDIzICs4Nyw2IEBAIHZvaWQgKmRldm1fbWVtcmVtYXAoc3RydWN0IGRldmljZSAq ZGV2LCByZXNvdXJjZV9zaXplX3Qgb2Zmc2V0LA0KIAkJc2l6ZV90IHNpemUsIHVuc2lnbmVkIGxv bmcgZmxhZ3MpOw0KIHZvaWQgZGV2bV9tZW11bm1hcChzdHJ1Y3QgZGV2aWNlICpkZXYsIHZvaWQg KmFkZHIpOw0KIA0KLXZvaWQgKl9fZGV2bV9tZW1yZW1hcF9wYWdlcyhzdHJ1Y3QgZGV2aWNlICpk ZXYsIHN0cnVjdCByZXNvdXJjZSAqcmVzKTsNCi0NCi0jaWZkZWYgQ09ORklHX1pPTkVfREVWSUNF DQotdm9pZCAqZGV2bV9tZW1yZW1hcF9wYWdlcyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBy ZXNvdXJjZSAqcmVzKTsNCi0jZWxzZQ0KLXN0YXRpYyBpbmxpbmUgdm9pZCAqZGV2bV9tZW1yZW1h cF9wYWdlcyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCByZXNvdXJjZSAqcmVzKQ0KLXsNCi0J LyoNCi0JICogRmFpbCBhdHRlbXB0cyB0byBjYWxsIGRldm1fbWVtcmVtYXBfcGFnZXMoKSB3aXRo b3V0DQotCSAqIFpPTkVfREVWSUNFIHN1cHBvcnQgZW5hYmxlZCwgdGhpcyByZXF1aXJlcyBjYWxs ZXJzIHRvIGZhbGwNCi0JICogYmFjayB0byBwbGFpbiBkZXZtX21lbXJlbWFwKCkgYmFzZWQgb24g Y29uZmlnDQotCSAqLw0KLQlXQVJOX09OX09OQ0UoMSk7DQotCXJldHVybiBFUlJfUFRSKC1FTlhJ Tyk7DQotfQ0KLSNlbmRpZg0KLQ0KIC8qDQogICogU29tZSBzeXN0ZW1zIGRvIG5vdCBoYXZlIGxl Z2FjeSBJU0EgZGV2aWNlcy4NCiAgKiAvZGV2L3BvcnQgaXMgbm90IGEgdmFsaWQgaW50ZXJmYWNl IG9uIHRoZXNlIHN5c3RlbXMuDQpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9tZW1vcnlfaG90 cGx1Zy5oIGIvaW5jbHVkZS9saW51eC9tZW1vcnlfaG90cGx1Zy5oDQppbmRleCA4ZjYwZTg5OWIz M2MuLjE3OGUwMDBhNzk4MyAxMDA2NDQNCi0tLSBhL2luY2x1ZGUvbGludXgvbWVtb3J5X2hvdHBs dWcuaA0KKysrIGIvaW5jbHVkZS9saW51eC9tZW1vcnlfaG90cGx1Zy5oDQpAQCAtMjczLDcgKzI3 Myw4IEBAIGV4dGVybiBpbnQgb2ZmbGluZV9wYWdlcyh1bnNpZ25lZCBsb25nIHN0YXJ0X3Bmbiwg dW5zaWduZWQgbG9uZyBucl9wYWdlcyk7DQogZXh0ZXJuIGJvb2wgaXNfbWVtYmxvY2tfb2ZmbGlu ZWQoc3RydWN0IG1lbW9yeV9ibG9jayAqbWVtKTsNCiBleHRlcm4gdm9pZCByZW1vdmVfbWVtb3J5 KGludCBuaWQsIHU2NCBzdGFydCwgdTY0IHNpemUpOw0KIGV4dGVybiBpbnQgc3BhcnNlX2FkZF9v bmVfc2VjdGlvbihzdHJ1Y3Qgem9uZSAqem9uZSwgdW5zaWduZWQgbG9uZyBzdGFydF9wZm4pOw0K LWV4dGVybiB2b2lkIHNwYXJzZV9yZW1vdmVfb25lX3NlY3Rpb24oc3RydWN0IHpvbmUgKnpvbmUs IHN0cnVjdCBtZW1fc2VjdGlvbiAqbXMpOw0KK2V4dGVybiB2b2lkIHNwYXJzZV9yZW1vdmVfb25l X3NlY3Rpb24oc3RydWN0IHpvbmUgKnpvbmUsIHN0cnVjdCBtZW1fc2VjdGlvbiAqbXMsDQorCQl1 bnNpZ25lZCBsb25nIG1hcF9vZmZzZXQpOw0KIGV4dGVybiBzdHJ1Y3QgcGFnZSAqc3BhcnNlX2Rl Y29kZV9tZW1fbWFwKHVuc2lnbmVkIGxvbmcgY29kZWRfbWVtX21hcCwNCiAJCQkJCSAgdW5zaWdu ZWQgbG9uZyBwbnVtKTsNCiANCmRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L21tLmggYi9pbmNs dWRlL2xpbnV4L21tLmgNCmluZGV4IDMwYzNjODc2NDY0OS4uYjhjYmE3ZDhlYTI4IDEwMDY0NA0K LS0tIGEvaW5jbHVkZS9saW51eC9tbS5oDQorKysgYi9pbmNsdWRlL2xpbnV4L21tLmgNCkBAIC03 MTgsMTggKzcxOCwxMDkgQEAgc3RhdGljIGlubGluZSBlbnVtIHpvbmVfdHlwZSBwYWdlX3pvbmVu dW0oY29uc3Qgc3RydWN0IHBhZ2UgKnBhZ2UpDQogfQ0KIA0KIC8qKg0KKyAqIHN0cnVjdCB2bWVt X2FsdG1hcCAtIHByZS1hbGxvY2F0ZWQgc3RvcmFnZSBmb3Igdm1lbW1hcF9wb3B1bGF0ZQ0KKyAq IEBiYXNlX3BmbjogYmFzZSBvZiB0aGUgZW50aXJlIGRldl9wYWdlbWFwIG1hcHBpbmcNCisgKiBA cmVzZXJ2ZTogcGFnZXMgbWFwcGVkLCBidXQgcmVzZXJ2ZWQgZm9yIGRyaXZlciB1c2UgKHJlbGF0 aXZlIHRvIEBiYXNlKQ0KKyAqIEBmcmVlOiBmcmVlIHBhZ2VzIHNldCBhc2lkZSBpbiB0aGUgbWFw cGluZyBmb3IgbWVtbWFwIHN0b3JhZ2UNCisgKiBAYWxpZ246IHBhZ2VzIHJlc2VydmVkIHRvIG1l ZXQgYWxsb2NhdGlvbiBhbGlnbm1lbnRzDQorICogQGFsbG9jOiB0cmFjayBwYWdlcyBjb25zdW1l ZCwgcHJpdmF0ZSB0byB2bWVtbWFwX3BvcHVsYXRlKCkNCisgKi8NCitzdHJ1Y3Qgdm1lbV9hbHRt YXAgew0KKwljb25zdCB1bnNpZ25lZCBsb25nIGJhc2VfcGZuOw0KKwljb25zdCB1bnNpZ25lZCBs b25nIHJlc2VydmU7DQorCXVuc2lnbmVkIGxvbmcgZnJlZTsNCisJdW5zaWduZWQgbG9uZyBhbGln bjsNCisJdW5zaWduZWQgbG9uZyBhbGxvYzsNCit9Ow0KKw0KK3N0YXRpYyBpbmxpbmUgdW5zaWdu ZWQgbG9uZyB2bWVtX2FsdG1hcF9ucl9mcmVlKHN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwKQ0K K3sNCisJdW5zaWduZWQgbG9uZyBhbGxvY2F0ZWQgPSBhbHRtYXAtPmFsbG9jICsgYWx0bWFwLT5h bGlnbjsNCisNCisJaWYgKGFsdG1hcC0+ZnJlZSA+IGFsbG9jYXRlZCkNCisJCXJldHVybiBhbHRt YXAtPmZyZWUgLSBhbGxvY2F0ZWQ7DQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgaW5saW5l IHVuc2lnbmVkIGxvbmcgdm1lbV9hbHRtYXBfb2Zmc2V0KHN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0 bWFwKQ0KK3sNCisJLyogbnVtYmVyIG9mIHBmbnMgZnJvbSBiYXNlIHdoZXJlIHBmbl90b19wYWdl KCkgaXMgdmFsaWQgKi8NCisJcmV0dXJuIGFsdG1hcC0+cmVzZXJ2ZSArIGFsdG1hcC0+ZnJlZTsN Cit9DQorDQorc3RhdGljIGlubGluZSB1bnNpZ25lZCBsb25nIHZtZW1fYWx0bWFwX25leHRfcGZu KHN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwKQ0KK3sNCisJcmV0dXJuIGFsdG1hcC0+YmFzZV9w Zm4gKyBhbHRtYXAtPnJlc2VydmUgKyBhbHRtYXAtPmFsbG9jDQorCQkrIGFsdG1hcC0+YWxpZ247 DQorfQ0KKw0KKy8qKg0KKyAqIHZtZW1fYWx0bWFwX2FsbG9jIC0gYWxsb2NhdGUgcGFnZXMgZnJv bSB0aGUgdm1lbV9hbHRtYXAgcmVzZXJ2YXRpb24NCisgKiBAYWx0bWFwIC0gcmVzZXJ2ZWQgcGFn ZSBwb29sIGZvciB0aGUgYWxsb2NhdGlvbg0KKyAqIEBucl9wZm5zIC0gc2l6ZSAoaW4gcGFnZXMp IG9mIHRoZSBhbGxvY2F0aW9uDQorICoNCisgKiBBbGxvY2F0aW9ucyBhcmUgYWxpZ25lZCB0byB0 aGUgc2l6ZSBvZiB0aGUgcmVxdWVzdA0KKyAqLw0KK3N0YXRpYyBpbmxpbmUgdW5zaWduZWQgbG9u ZyB2bWVtX2FsdG1hcF9hbGxvYyhzdHJ1Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcCwNCisJCXVuc2ln bmVkIGxvbmcgbnJfcGZucykNCit7DQorCXVuc2lnbmVkIGxvbmcgcGZuID0gdm1lbV9hbHRtYXBf bmV4dF9wZm4oYWx0bWFwKTsNCisJdW5zaWduZWQgbG9uZyBucl9hbGlnbjsNCisNCisJbnJfYWxp Z24gPSAxVUwgPDwgZmluZF9maXJzdF9iaXQoJm5yX3BmbnMsIEJJVFNfUEVSX0xPTkcpOw0KKwlu cl9hbGlnbiA9IEFMSUdOKHBmbiwgbnJfYWxpZ24pIC0gcGZuOw0KKw0KKwlpZiAobnJfcGZucyAr IG5yX2FsaWduID4gdm1lbV9hbHRtYXBfbnJfZnJlZShhbHRtYXApKQ0KKwkJcmV0dXJuIFVMT05H X01BWDsNCisJYWx0bWFwLT5hbGxvYyArPSBucl9wZm5zOw0KKwlhbHRtYXAtPmFsaWduICs9IG5y X2FsaWduOw0KKwlyZXR1cm4gcGZuICsgbnJfYWxpZ247DQorfQ0KKw0KK3N0YXRpYyBpbmxpbmUg dm9pZCB2bWVtX2FsdG1hcF9mcmVlKHN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwLA0KKwkJdW5z aWduZWQgbG9uZyBucl9wZm5zKQ0KK3sNCisJYWx0bWFwLT5hbGxvYyAtPSBucl9wZm5zOw0KK30N CisNCisvKioNCiAgKiBzdHJ1Y3QgZGV2X3BhZ2VtYXAgLSBtZXRhZGF0YSBmb3IgWk9ORV9ERVZJ Q0UgbWFwcGluZ3MNCisgKiBAYWx0bWFwOiBwcmUtYWxsb2NhdGVkL3Jlc2VydmVkIG1lbW9yeSBm b3Igdm1lbW1hcCBhbGxvY2F0aW9ucw0KICAqIEBkZXY6IGhvc3QgZGV2aWNlIG9mIHRoZSBtYXBw aW5nIGZvciBkZWJ1Zw0KICAqLw0KIHN0cnVjdCBkZXZfcGFnZW1hcCB7DQotCS8qIFRPRE86IHZt ZW1fYWx0bWFwIGFuZCBwZXJjcHVfcmVmIGNvdW50ICovDQorCXN0cnVjdCB2bWVtX2FsdG1hcCAq YWx0bWFwOw0KKwljb25zdCBzdHJ1Y3QgcmVzb3VyY2UgKnJlczsNCiAJc3RydWN0IGRldmljZSAq ZGV2Ow0KIH07DQogDQogI2lmZGVmIENPTkZJR19aT05FX0RFVklDRQ0KIHN0cnVjdCBkZXZfcGFn ZW1hcCAqX19nZXRfZGV2X3BhZ2VtYXAocmVzb3VyY2Vfc2l6ZV90IHBoeXMpOw0KK3ZvaWQgKmRl dm1fbWVtcmVtYXBfcGFnZXMoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgcmVzb3VyY2UgKnJl cywNCisJCXN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwKTsNCisjZWxzZQ0KK3N0YXRpYyBpbmxp bmUgc3RydWN0IGRldl9wYWdlbWFwICpfX2dldF9kZXZfcGFnZW1hcChyZXNvdXJjZV9zaXplX3Qg cGh5cykNCit7DQorCXJldHVybiBOVUxMOw0KK30NCisNCitzdGF0aWMgaW5saW5lIHZvaWQgKmRl dm1fbWVtcmVtYXBfcGFnZXMoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgcmVzb3VyY2UgKnJl cywNCisJCXN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwKQ0KK3sNCisJLyoNCisJICogRmFpbCBh dHRlbXB0cyB0byBjYWxsIGRldm1fbWVtcmVtYXBfcGFnZXMoKSB3aXRob3V0DQorCSAqIFpPTkVf REVWSUNFIHN1cHBvcnQgZW5hYmxlZCwgdGhpcyByZXF1aXJlcyBjYWxsZXJzIHRvIGZhbGwNCisJ ICogYmFjayB0byBwbGFpbiBkZXZtX21lbXJlbWFwKCkgYmFzZWQgb24gY29uZmlnDQorCSAqLw0K KwlXQVJOX09OX09OQ0UoMSk7DQorCXJldHVybiBFUlJfUFRSKC1FTlhJTyk7DQorfQ0KKyNlbmRp Zg0KKw0KKyNpZmRlZiBDT05GSUdfU1BBUlNFTUVNX1ZNRU1NQVANCitzdHJ1Y3Qgdm1lbV9hbHRt YXAgKnRvX3ZtZW1fYWx0bWFwKHVuc2lnbmVkIGxvbmcgbWVtbWFwX3N0YXJ0KTsNCiAjZWxzZQ0K LXN0YXRpYyBpbmxpbmUgc3RydWN0IGRldl9wYWdlbWFwICpnZXRfZGV2X3BhZ2VtYXAocmVzb3Vy Y2Vfc2l6ZV90IHBoeXMpDQorc3RhdGljIGlubGluZSBzdHJ1Y3Qgdm1lbV9hbHRtYXAgKnRvX3Zt ZW1fYWx0bWFwKHVuc2lnbmVkIGxvbmcgbWVtbWFwX3N0YXJ0KQ0KIHsNCiAJcmV0dXJuIE5VTEw7 DQogfQ0KQEAgLTIyNDUsNyArMjMzNiw4IEBAIHB1ZF90ICp2bWVtbWFwX3B1ZF9wb3B1bGF0ZShw Z2RfdCAqcGdkLCB1bnNpZ25lZCBsb25nIGFkZHIsIGludCBub2RlKTsNCiBwbWRfdCAqdm1lbW1h cF9wbWRfcG9wdWxhdGUocHVkX3QgKnB1ZCwgdW5zaWduZWQgbG9uZyBhZGRyLCBpbnQgbm9kZSk7 DQogcHRlX3QgKnZtZW1tYXBfcHRlX3BvcHVsYXRlKHBtZF90ICpwbWQsIHVuc2lnbmVkIGxvbmcg YWRkciwgaW50IG5vZGUpOw0KIHZvaWQgKnZtZW1tYXBfYWxsb2NfYmxvY2sodW5zaWduZWQgbG9u ZyBzaXplLCBpbnQgbm9kZSk7DQotdm9pZCAqdm1lbW1hcF9hbGxvY19ibG9ja19idWYodW5zaWdu ZWQgbG9uZyBzaXplLCBpbnQgbm9kZSk7DQordm9pZCAqdm1lbW1hcF9hbGxvY19ibG9ja19idWYo dW5zaWduZWQgbG9uZyBzaXplLCBpbnQgbm9kZSwNCisJCXN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0 bWFwKTsNCiB2b2lkIHZtZW1tYXBfdmVyaWZ5KHB0ZV90ICosIGludCwgdW5zaWduZWQgbG9uZywg dW5zaWduZWQgbG9uZyk7DQogaW50IHZtZW1tYXBfcG9wdWxhdGVfYmFzZXBhZ2VzKHVuc2lnbmVk IGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgZW5kLA0KIAkJCSAgICAgICBpbnQgbm9kZSk7DQpk aWZmIC0tZ2l0IGEva2VybmVsL21lbXJlbWFwLmMgYi9rZXJuZWwvbWVtcmVtYXAuYw0KaW5kZXgg NjRiZmQ5ZmE5M2FhLi43OWJiYmVhMmRlNmEgMTAwNjQ0DQotLS0gYS9rZXJuZWwvbWVtcmVtYXAu Yw0KKysrIGIva2VybmVsL21lbXJlbWFwLmMNCkBAIC0xNDYsNiArMTQ2LDcgQEAgc3RydWN0IHBh Z2VfbWFwIHsNCiAJc3RydWN0IHJlc291cmNlIHJlczsNCiAJc3RydWN0IGRldl9wYWdlbWFwIHBn bWFwOw0KIAlzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7DQorCXN0cnVjdCB2bWVtX2FsdG1hcCBhbHRt YXA7DQogfTsNCiANCiBzdGF0aWMgdm9pZCBhZGRfcGFnZV9tYXAoc3RydWN0IHBhZ2VfbWFwICpw YWdlX21hcCkNCkBAIC0xNjIsMTQgKzE2MywxNyBAQCBzdGF0aWMgdm9pZCBkZWxfcGFnZV9tYXAo c3RydWN0IHBhZ2VfbWFwICpwYWdlX21hcCkNCiAJc3Bpbl91bmxvY2soJnJhbmdlX2xvY2spOw0K IH0NCiANCi1zdGF0aWMgdm9pZCBkZXZtX21lbXJlbWFwX3BhZ2VzX3JlbGVhc2Uoc3RydWN0IGRl dmljZSAqZGV2LCB2b2lkICpyZXMpDQorc3RhdGljIHZvaWQgZGV2bV9tZW1yZW1hcF9wYWdlc19y ZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldiwgdm9pZCAqZGF0YSkNCiB7DQotCXN0cnVjdCBwYWdl X21hcCAqcGFnZV9tYXAgPSByZXM7DQotDQotCWRlbF9wYWdlX21hcChwYWdlX21hcCk7DQorCXN0 cnVjdCBwYWdlX21hcCAqcGFnZV9tYXAgPSBkYXRhOw0KKwlzdHJ1Y3QgcmVzb3VyY2UgKnJlcyA9 ICZwYWdlX21hcC0+cmVzOw0KKwlzdHJ1Y3QgZGV2X3BhZ2VtYXAgKnBnbWFwID0gJnBhZ2VfbWFw LT5wZ21hcDsNCiANCiAJLyogcGFnZXMgYXJlIGRlYWQgYW5kIHVudXNlZCwgdW5kbyB0aGUgYXJj aCBtYXBwaW5nICovDQotCWFyY2hfcmVtb3ZlX21lbW9yeShwYWdlX21hcC0+cmVzLnN0YXJ0LCBy ZXNvdXJjZV9zaXplKCZwYWdlX21hcC0+cmVzKSk7DQorCWFyY2hfcmVtb3ZlX21lbW9yeShyZXMt PnN0YXJ0LCByZXNvdXJjZV9zaXplKHJlcykpOw0KKwlkZXZfV0FSTl9PTkNFKGRldiwgcGdtYXAt PmFsdG1hcCAmJiBwZ21hcC0+YWx0bWFwLT5hbGxvYywNCisJCQkiJXM6IGZhaWxlZCB0byBmcmVl IGFsbCByZXNlcnZlZCBwYWdlc1xuIiwgX19mdW5jX18pOw0KKwlkZWxfcGFnZV9tYXAocGFnZV9t YXApOw0KIH0NCiANCiAvKiBhc3N1bWVzIHJjdV9yZWFkX2xvY2soKSBoZWxkIGF0IGVudHJ5ICov DQpAQCAtMTg1LDEwICsxODksMjIgQEAgc3RydWN0IGRldl9wYWdlbWFwICpfX2dldF9kZXZfcGFn ZW1hcChyZXNvdXJjZV9zaXplX3QgcGh5cykNCiAJcmV0dXJuIE5VTEw7DQogfQ0KIA0KLXZvaWQg KmRldm1fbWVtcmVtYXBfcGFnZXMoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgcmVzb3VyY2Ug KnJlcykNCisvKioNCisgKiBkZXZtX21lbXJlbWFwX3BhZ2VzIC0gcmVtYXAgYW5kIHByb3ZpZGUg bWVtbWFwIGJhY2tpbmcgZm9yIHRoZSBnaXZlbiByZXNvdXJjZQ0KKyAqIEBkZXY6IGhvc3Rpbmcg ZGV2aWNlIGZvciBAcmVzDQorICogQHJlczogImhvc3QgbWVtb3J5IiBhZGRyZXNzIHJhbmdlDQor ICogQGFsdG1hcDogb3B0aW9uYWwgZGVzY3JpcHRvciBmb3IgYWxsb2NhdGluZyB0aGUgbWVtbWFw IGZyb20gQHJlcw0KKyAqDQorICogTm90ZSwgdGhlIGV4cGVjdGF0aW9uIGlzIHRoYXQgQHJlcyBp cyBhIGhvc3QgbWVtb3J5IHJhbmdlIHRoYXQgY291bGQNCisgKiBmZWFzaWJseSBiZSB0cmVhdGVk IGFzIGEgIlN5c3RlbSBSQU0iIHJhbmdlLCBpLmUuIG5vdCBhIGRldmljZSBtbWlvDQorICogcmFu Z2UsIGJ1dCB0aGlzIGlzIG5vdCBlbmZvcmNlZC4NCisgKi8NCit2b2lkICpkZXZtX21lbXJlbWFw X3BhZ2VzKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHJlc291cmNlICpyZXMsDQorCQlzdHJ1 Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcCkNCiB7DQogCWludCBpc19yYW0gPSByZWdpb25faW50ZXJz ZWN0cyhyZXMtPnN0YXJ0LCByZXNvdXJjZV9zaXplKHJlcyksDQogCQkJIlN5c3RlbSBSQU0iKTsN CisJc3RydWN0IGRldl9wYWdlbWFwICpwZ21hcDsNCiAJc3RydWN0IHBhZ2VfbWFwICpwYWdlX21h cDsNCiAJaW50IGVycm9yLCBuaWQ7DQogDQpAQCAtMjAxLDE0ICsyMTcsMjUgQEAgdm9pZCAqZGV2 bV9tZW1yZW1hcF9wYWdlcyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCByZXNvdXJjZSAqcmVz KQ0KIAlpZiAoaXNfcmFtID09IFJFR0lPTl9JTlRFUlNFQ1RTKQ0KIAkJcmV0dXJuIF9fdmEocmVz LT5zdGFydCk7DQogDQorCWlmIChhbHRtYXAgJiYgIUlTX0VOQUJMRUQoQ09ORklHX1NQQVJTRU1F TV9WTUVNTUFQKSkgew0KKwkJZGV2X2VycihkZXYsICIlczogc3VwcG9ydCBmb3IgYWx0ZXJuYXRl IHZtZW1tYXAgZGlzYWJsZWRcbiIsDQorCQkJCV9fZnVuY19fKTsNCisJCXJldHVybiBFUlJfUFRS KC1FTlhJTyk7DQorCX0NCisNCiAJcGFnZV9tYXAgPSBkZXZyZXNfYWxsb2Nfbm9kZShkZXZtX21l bXJlbWFwX3BhZ2VzX3JlbGVhc2UsDQogCQkJc2l6ZW9mKCpwYWdlX21hcCksIEdGUF9LRVJORUws IGRldl90b19ub2RlKGRldikpOw0KIAlpZiAoIXBhZ2VfbWFwKQ0KIAkJcmV0dXJuIEVSUl9QVFIo LUVOT01FTSk7DQorCXBnbWFwID0gJnBhZ2VfbWFwLT5wZ21hcDsNCiANCiAJbWVtY3B5KCZwYWdl X21hcC0+cmVzLCByZXMsIHNpemVvZigqcmVzKSk7DQotDQotCXBhZ2VfbWFwLT5wZ21hcC5kZXYg PSBkZXY7DQorCWlmIChhbHRtYXApIHsNCisJCW1lbWNweSgmcGFnZV9tYXAtPmFsdG1hcCwgYWx0 bWFwLCBzaXplb2YoKmFsdG1hcCkpOw0KKwkJcGdtYXAtPmFsdG1hcCA9ICZwYWdlX21hcC0+YWx0 bWFwOw0KKwl9DQorCXBnbWFwLT5kZXYgPSBkZXY7DQorCXBnbWFwLT5yZXMgPSAmcGFnZV9tYXAt PnJlczsNCiAJSU5JVF9MSVNUX0hFQUQoJnBhZ2VfbWFwLT5saXN0KTsNCiAJYWRkX3BhZ2VfbWFw KHBhZ2VfbWFwKTsNCiANCkBAIC0yMjgsMyArMjU1LDM3IEBAIHZvaWQgKmRldm1fbWVtcmVtYXBf cGFnZXMoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgcmVzb3VyY2UgKnJlcykNCiB9DQogRVhQ T1JUX1NZTUJPTChkZXZtX21lbXJlbWFwX3BhZ2VzKTsNCiAjZW5kaWYgLyogQ09ORklHX1pPTkVf REVWSUNFICovDQorDQorI2lmZGVmIENPTkZJR19TUEFSU0VNRU1fVk1FTU1BUA0KKy8qDQorICog VW5jb2RpdGlvbmFsbHkgcmV0cmlldmUgYSBkZXZfcGFnZW1hcCBhc3NvY2lhdGVkIHdpdGggdGhl IGdpdmVuIHBoeXNpY2FsDQorICogYWRkcmVzcywgdGhpcyBpcyBvbmx5IGZvciB1c2UgaW4gdGhl IGFyY2hfe2FkZHxyZW1vdmV9X21lbW9yeSgpIGZvciBzZXR0aW5nDQorICogdXAgYW5kIHRlYXJp bmcgZG93biB0aGUgbWVtbWFwLg0KKyAqLw0KK3N0YXRpYyBzdHJ1Y3QgZGV2X3BhZ2VtYXAgKmxv b2t1cF9kZXZfcGFnZW1hcChyZXNvdXJjZV9zaXplX3QgcGh5cykNCit7DQorCXN0cnVjdCBkZXZf cGFnZW1hcCAqcGdtYXA7DQorDQorCXJjdV9yZWFkX2xvY2soKTsNCisJcGdtYXAgPSBfX2dldF9k ZXZfcGFnZW1hcChwaHlzKTsNCisJcmN1X3JlYWRfdW5sb2NrKCk7DQorCXJldHVybiBwZ21hcDsN Cit9DQorDQorc3RydWN0IHZtZW1fYWx0bWFwICp0b192bWVtX2FsdG1hcCh1bnNpZ25lZCBsb25n IG1lbW1hcF9zdGFydCkNCit7DQorCS8qDQorCSAqICdtZW1tYXBfc3RhcnQnIGlzIHRoZSB2aXJ0 dWFsIGFkZHJlc3MgZm9yIHRoZSBmaXJzdCAic3RydWN0DQorCSAqIHBhZ2UiIGluIHRoaXMgcmFu Z2Ugb2YgdGhlIHZtZW1tYXAgYXJyYXkuICBJbiB0aGUgY2FzZSBvZg0KKwkgKiBDT05GSUdfU1BB UlNFX1ZNRU1NQVAgYSBwYWdlX3RvX3BmbiBjb252ZXJzaW9uIGlzIHNpbXBsZQ0KKwkgKiBwb2lu dGVyIGFyaXRobWV0aWMsIHNvIHdlIGNhbiBwZXJmb3JtIHRoaXMgdG9fdm1lbV9hbHRtYXAoKQ0K KwkgKiBjb252ZXJzaW9uIHdpdGhvdXQgY29uY2VybiBmb3IgdGhlIGluaXRpYWxpemF0aW9uIHN0 YXRlIG9mDQorCSAqIHRoZSBzdHJ1Y3QgcGFnZSBmaWVsZHMuDQorCSAqLw0KKwlzdHJ1Y3QgcGFn ZSAqcGFnZSA9IChzdHJ1Y3QgcGFnZSAqKSBtZW1tYXBfc3RhcnQ7DQorCXN0cnVjdCBkZXZfcGFn ZW1hcCAqcGdtYXA7DQorDQorCXBnbWFwID0gbG9va3VwX2Rldl9wYWdlbWFwKF9fcGZuX3RvX3Bo eXMocGFnZV90b19wZm4ocGFnZSkpKTsNCisJcmV0dXJuIHBnbWFwID8gcGdtYXAtPmFsdG1hcCA6 IE5VTEw7DQorfQ0KKyNlbmRpZiAvKiBDT05GSUdfU1BBUlNFTUVNX1ZNRU1NQVAgKi8NCmRpZmYg LS1naXQgYS9tbS9tZW1vcnlfaG90cGx1Zy5jIGIvbW0vbWVtb3J5X2hvdHBsdWcuYw0KaW5kZXgg YWE5OTJlMmRmNThhLi4zNTIxZGYxNTNkZTMgMTAwNjQ0DQotLS0gYS9tbS9tZW1vcnlfaG90cGx1 Zy5jDQorKysgYi9tbS9tZW1vcnlfaG90cGx1Zy5jDQpAQCAtNTA1LDEwICs1MDUsMjUgQEAgaW50 IF9fcmVmIF9fYWRkX3BhZ2VzKGludCBuaWQsIHN0cnVjdCB6b25lICp6b25lLCB1bnNpZ25lZCBs b25nIHBoeXNfc3RhcnRfcGZuLA0KIAl1bnNpZ25lZCBsb25nIGk7DQogCWludCBlcnIgPSAwOw0K IAlpbnQgc3RhcnRfc2VjLCBlbmRfc2VjOw0KKwlzdHJ1Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcDsN CisNCiAJLyogZHVyaW5nIGluaXRpYWxpemUgbWVtX21hcCwgYWxpZ24gaG90LWFkZGVkIHJhbmdl IHRvIHNlY3Rpb24gKi8NCiAJc3RhcnRfc2VjID0gcGZuX3RvX3NlY3Rpb25fbnIocGh5c19zdGFy dF9wZm4pOw0KIAllbmRfc2VjID0gcGZuX3RvX3NlY3Rpb25fbnIocGh5c19zdGFydF9wZm4gKyBu cl9wYWdlcyAtIDEpOw0KIA0KKwlhbHRtYXAgPSB0b192bWVtX2FsdG1hcCgodW5zaWduZWQgbG9u ZykgcGZuX3RvX3BhZ2UocGh5c19zdGFydF9wZm4pKTsNCisJaWYgKGFsdG1hcCkgew0KKwkJLyoN CisJCSAqIFZhbGlkYXRlIGFsdG1hcCBpcyB3aXRoaW4gYm91bmRzIG9mIHRoZSB0b3RhbCByZXF1 ZXN0DQorCQkgKi8NCisJCWlmIChhbHRtYXAtPmJhc2VfcGZuICE9IHBoeXNfc3RhcnRfcGZuDQor CQkJCXx8IHZtZW1fYWx0bWFwX29mZnNldChhbHRtYXApID4gbnJfcGFnZXMpIHsNCisJCQlwcl93 YXJuX29uY2UoIm1lbW9yeSBhZGQgZmFpbCwgaW52YWxpZCBhbHRtYXBcbiIpOw0KKwkJCXJldHVy biAtRUlOVkFMOw0KKwkJfQ0KKwkJYWx0bWFwLT5hbGxvYyA9IDA7DQorCX0NCisNCiAJZm9yIChp ID0gc3RhcnRfc2VjOyBpIDw9IGVuZF9zZWM7IGkrKykgew0KIAkJZXJyID0gX19hZGRfc2VjdGlv bihuaWQsIHpvbmUsIHNlY3Rpb25fbnJfdG9fcGZuKGkpKTsNCiANCkBAIC03MzAsNyArNzQ1LDgg QEAgc3RhdGljIHZvaWQgX19yZW1vdmVfem9uZShzdHJ1Y3Qgem9uZSAqem9uZSwgdW5zaWduZWQg bG9uZyBzdGFydF9wZm4pDQogCXBnZGF0X3Jlc2l6ZV91bmxvY2soem9uZS0+em9uZV9wZ2RhdCwg JmZsYWdzKTsNCiB9DQogDQotc3RhdGljIGludCBfX3JlbW92ZV9zZWN0aW9uKHN0cnVjdCB6b25l ICp6b25lLCBzdHJ1Y3QgbWVtX3NlY3Rpb24gKm1zKQ0KK3N0YXRpYyBpbnQgX19yZW1vdmVfc2Vj dGlvbihzdHJ1Y3Qgem9uZSAqem9uZSwgc3RydWN0IG1lbV9zZWN0aW9uICptcywNCisJCXVuc2ln bmVkIGxvbmcgbWFwX29mZnNldCkNCiB7DQogCXVuc2lnbmVkIGxvbmcgc3RhcnRfcGZuOw0KIAlp bnQgc2NuX25yOw0KQEAgLTc0Nyw3ICs3NjMsNyBAQCBzdGF0aWMgaW50IF9fcmVtb3ZlX3NlY3Rp b24oc3RydWN0IHpvbmUgKnpvbmUsIHN0cnVjdCBtZW1fc2VjdGlvbiAqbXMpDQogCXN0YXJ0X3Bm biA9IHNlY3Rpb25fbnJfdG9fcGZuKHNjbl9ucik7DQogCV9fcmVtb3ZlX3pvbmUoem9uZSwgc3Rh cnRfcGZuKTsNCiANCi0Jc3BhcnNlX3JlbW92ZV9vbmVfc2VjdGlvbih6b25lLCBtcyk7DQorCXNw YXJzZV9yZW1vdmVfb25lX3NlY3Rpb24oem9uZSwgbXMsIG1hcF9vZmZzZXQpOw0KIAlyZXR1cm4g MDsNCiB9DQogDQpAQCAtNzY2LDkgKzc4MiwzMiBAQCBpbnQgX19yZW1vdmVfcGFnZXMoc3RydWN0 IHpvbmUgKnpvbmUsIHVuc2lnbmVkIGxvbmcgcGh5c19zdGFydF9wZm4sDQogCQkgdW5zaWduZWQg bG9uZyBucl9wYWdlcykNCiB7DQogCXVuc2lnbmVkIGxvbmcgaTsNCi0JaW50IHNlY3Rpb25zX3Rv X3JlbW92ZTsNCi0JcmVzb3VyY2Vfc2l6ZV90IHN0YXJ0LCBzaXplOw0KLQlpbnQgcmV0ID0gMDsN CisJdW5zaWduZWQgbG9uZyBtYXBfb2Zmc2V0ID0gMDsNCisJaW50IHNlY3Rpb25zX3RvX3JlbW92 ZSwgcmV0ID0gMDsNCisNCisJLyogSW4gdGhlIFpPTkVfREVWSUNFIGNhc2UgZGV2aWNlIGRyaXZl ciBvd25zIHRoZSBtZW1vcnkgcmVnaW9uICovDQorCWlmIChpc19kZXZfem9uZSh6b25lKSkgew0K KwkJc3RydWN0IHBhZ2UgKnBhZ2UgPSBwZm5fdG9fcGFnZShwaHlzX3N0YXJ0X3Bmbik7DQorCQlz dHJ1Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcDsNCisNCisJCWFsdG1hcCA9IHRvX3ZtZW1fYWx0bWFw KCh1bnNpZ25lZCBsb25nKSBwYWdlKTsNCisJCWlmIChhbHRtYXApDQorCQkJbWFwX29mZnNldCA9 IHZtZW1fYWx0bWFwX29mZnNldChhbHRtYXApOw0KKwl9IGVsc2Ugew0KKwkJcmVzb3VyY2Vfc2l6 ZV90IHN0YXJ0LCBzaXplOw0KKw0KKwkJc3RhcnQgPSBwaHlzX3N0YXJ0X3BmbiA8PCBQQUdFX1NI SUZUOw0KKwkJc2l6ZSA9IG5yX3BhZ2VzICogUEFHRV9TSVpFOw0KKw0KKwkJcmV0ID0gcmVsZWFz ZV9tZW1fcmVnaW9uX2FkanVzdGFibGUoJmlvbWVtX3Jlc291cmNlLCBzdGFydCwNCisJCQkJCXNp emUpOw0KKwkJaWYgKHJldCkgew0KKwkJCXJlc291cmNlX3NpemVfdCBlbmRyZXMgPSBzdGFydCAr IHNpemUgLSAxOw0KKw0KKwkJCXByX3dhcm4oIlVuYWJsZSB0byByZWxlYXNlIHJlc291cmNlIDwl cGEtJXBhPiAoJWQpXG4iLA0KKwkJCQkJJnN0YXJ0LCAmZW5kcmVzLCByZXQpOw0KKwkJfQ0KKwl9 DQogDQogCS8qDQogCSAqIFdlIGNhbiBvbmx5IHJlbW92ZSBlbnRpcmUgc2VjdGlvbnMNCkBAIC03 NzYsMjMgKzgxNSwxMiBAQCBpbnQgX19yZW1vdmVfcGFnZXMoc3RydWN0IHpvbmUgKnpvbmUsIHVu c2lnbmVkIGxvbmcgcGh5c19zdGFydF9wZm4sDQogCUJVR19PTihwaHlzX3N0YXJ0X3BmbiAmIH5Q QUdFX1NFQ1RJT05fTUFTSyk7DQogCUJVR19PTihucl9wYWdlcyAlIFBBR0VTX1BFUl9TRUNUSU9O KTsNCiANCi0Jc3RhcnQgPSBwaHlzX3N0YXJ0X3BmbiA8PCBQQUdFX1NISUZUOw0KLQlzaXplID0g bnJfcGFnZXMgKiBQQUdFX1NJWkU7DQotDQotCS8qIGluIHRoZSBaT05FX0RFVklDRSBjYXNlIGRl dmljZSBkcml2ZXIgb3ducyB0aGUgbWVtb3J5IHJlZ2lvbiAqLw0KLQlpZiAoIWlzX2Rldl96b25l KHpvbmUpKQ0KLQkJcmV0ID0gcmVsZWFzZV9tZW1fcmVnaW9uX2FkanVzdGFibGUoJmlvbWVtX3Jl c291cmNlLCBzdGFydCwgc2l6ZSk7DQotCWlmIChyZXQpIHsNCi0JCXJlc291cmNlX3NpemVfdCBl bmRyZXMgPSBzdGFydCArIHNpemUgLSAxOw0KLQ0KLQkJcHJfd2FybigiVW5hYmxlIHRvIHJlbGVh c2UgcmVzb3VyY2UgPCVwYS0lcGE+ICglZClcbiIsDQotCQkJCSZzdGFydCwgJmVuZHJlcywgcmV0 KTsNCi0JfQ0KLQ0KIAlzZWN0aW9uc190b19yZW1vdmUgPSBucl9wYWdlcyAvIFBBR0VTX1BFUl9T RUNUSU9OOw0KIAlmb3IgKGkgPSAwOyBpIDwgc2VjdGlvbnNfdG9fcmVtb3ZlOyBpKyspIHsNCiAJ CXVuc2lnbmVkIGxvbmcgcGZuID0gcGh5c19zdGFydF9wZm4gKyBpKlBBR0VTX1BFUl9TRUNUSU9O Ow0KLQkJcmV0ID0gX19yZW1vdmVfc2VjdGlvbih6b25lLCBfX3Bmbl90b19zZWN0aW9uKHBmbikp Ow0KKw0KKwkJcmV0ID0gX19yZW1vdmVfc2VjdGlvbih6b25lLCBfX3Bmbl90b19zZWN0aW9uKHBm biksIG1hcF9vZmZzZXQpOw0KKwkJbWFwX29mZnNldCA9IDA7DQogCQlpZiAocmV0KQ0KIAkJCWJy ZWFrOw0KIAl9DQpkaWZmIC0tZ2l0IGEvbW0vcGFnZV9hbGxvYy5jIGIvbW0vcGFnZV9hbGxvYy5j DQppbmRleCA0OGFhZjdiOWYyNTMuLjlkZmM0MzFkNjI3MSAxMDA2NDQNCi0tLSBhL21tL3BhZ2Vf YWxsb2MuYw0KKysrIGIvbW0vcGFnZV9hbGxvYy5jDQpAQCAtNDYyMCw4ICs0NjIwLDkgQEAgc3Rh dGljIHZvaWQgc2V0dXBfem9uZV9taWdyYXRlX3Jlc2VydmUoc3RydWN0IHpvbmUgKnpvbmUpDQog dm9pZCBfX21lbWluaXQgbWVtbWFwX2luaXRfem9uZSh1bnNpZ25lZCBsb25nIHNpemUsIGludCBu aWQsIHVuc2lnbmVkIGxvbmcgem9uZSwNCiAJCXVuc2lnbmVkIGxvbmcgc3RhcnRfcGZuLCBlbnVt IG1lbW1hcF9jb250ZXh0IGNvbnRleHQpDQogew0KLQlwZ19kYXRhX3QgKnBnZGF0ID0gTk9ERV9E QVRBKG5pZCk7DQorCXN0cnVjdCB2bWVtX2FsdG1hcCAqYWx0bWFwID0gdG9fdm1lbV9hbHRtYXAo X19wZm5fdG9fcGh5cyhzdGFydF9wZm4pKTsNCiAJdW5zaWduZWQgbG9uZyBlbmRfcGZuID0gc3Rh cnRfcGZuICsgc2l6ZTsNCisJcGdfZGF0YV90ICpwZ2RhdCA9IE5PREVfREFUQShuaWQpOw0KIAl1 bnNpZ25lZCBsb25nIHBmbjsNCiAJc3RydWN0IHpvbmUgKno7DQogCXVuc2lnbmVkIGxvbmcgbnJf aW5pdGlhbGlzZWQgPSAwOw0KQEAgLTQ2MjksNiArNDYzMCwxMyBAQCB2b2lkIF9fbWVtaW5pdCBt ZW1tYXBfaW5pdF96b25lKHVuc2lnbmVkIGxvbmcgc2l6ZSwgaW50IG5pZCwgdW5zaWduZWQgbG9u ZyB6b25lLA0KIAlpZiAoaGlnaGVzdF9tZW1tYXBfcGZuIDwgZW5kX3BmbiAtIDEpDQogCQloaWdo ZXN0X21lbW1hcF9wZm4gPSBlbmRfcGZuIC0gMTsNCiANCisJLyoNCisJICogSG9ub3IgcmVzZXJ2 YXRpb24gcmVxdWVzdGVkIGJ5IHRoZSBkcml2ZXIgZm9yIHRoaXMgWk9ORV9ERVZJQ0UNCisJICog bWVtb3J5DQorCSAqLw0KKwlpZiAoYWx0bWFwICYmIHN0YXJ0X3BmbiA9PSBhbHRtYXAtPmJhc2Vf cGZuKQ0KKwkJc3RhcnRfcGZuICs9IGFsdG1hcC0+cmVzZXJ2ZTsNCisNCiAJeiA9ICZwZ2RhdC0+ bm9kZV96b25lc1t6b25lXTsNCiAJZm9yIChwZm4gPSBzdGFydF9wZm47IHBmbiA8IGVuZF9wZm47 IHBmbisrKSB7DQogCQkvKg0KZGlmZiAtLWdpdCBhL21tL3NwYXJzZS12bWVtbWFwLmMgYi9tbS9z cGFyc2Utdm1lbW1hcC5jDQppbmRleCA0Y2JhOWMyNzgzYTEuLjk2YzFkY2E0Y2U2YSAxMDA2NDQN Ci0tLSBhL21tL3NwYXJzZS12bWVtbWFwLmMNCisrKyBiL21tL3NwYXJzZS12bWVtbWFwLmMNCkBA IC03MCw3ICs3MCw3IEBAIHZvaWQgKiBfX21lbWluaXQgdm1lbW1hcF9hbGxvY19ibG9jayh1bnNp Z25lZCBsb25nIHNpemUsIGludCBub2RlKQ0KIH0NCiANCiAvKiBuZWVkIHRvIG1ha2Ugc3VyZSBz aXplIGlzIGFsbCB0aGUgc2FtZSBkdXJpbmcgZWFybHkgc3RhZ2UgKi8NCi12b2lkICogX19tZW1p bml0IHZtZW1tYXBfYWxsb2NfYmxvY2tfYnVmKHVuc2lnbmVkIGxvbmcgc2l6ZSwgaW50IG5vZGUp DQorc3RhdGljIHZvaWQgKiBfX21lbWluaXQgX192bWVtbWFwX2FsbG9jX2Jsb2NrX2J1Zih1bnNp Z25lZCBsb25nIHNpemUsIGludCBub2RlKQ0KIHsNCiAJdm9pZCAqcHRyOw0KIA0KQEAgLTg3LDYg Kzg3LDM5IEBAIHZvaWQgKiBfX21lbWluaXQgdm1lbW1hcF9hbGxvY19ibG9ja19idWYodW5zaWdu ZWQgbG9uZyBzaXplLCBpbnQgbm9kZSkNCiAJcmV0dXJuIHB0cjsNCiB9DQogDQorc3RhdGljIHZv aWQgKiBfX21lbWluaXQgYWx0bWFwX2FsbG9jX2Jsb2NrX2J1Zih1bnNpZ25lZCBsb25nIHNpemUs DQorCQlzdHJ1Y3Qgdm1lbV9hbHRtYXAgKmFsdG1hcCkNCit7DQorCXVuc2lnbmVkIGxvbmcgcGZu LCBucl9wZm5zOw0KKwl2b2lkICpwdHI7DQorDQorCWlmIChzaXplICYgflBBR0VfTUFTSykgew0K KwkJcHJfd2Fybl9vbmNlKCIlczogYWxsb2NhdGlvbnMgbXVzdCBiZSBtdWx0aXBsZSBvZiBQQUdF X1NJWkUgKCVsZClcbiIsDQorCQkJCV9fZnVuY19fLCBzaXplKTsNCisJCXJldHVybiBOVUxMOw0K Kwl9DQorDQorCW5yX3BmbnMgPSBzaXplID4+IFBBR0VfU0hJRlQ7DQorCXBmbiA9IHZtZW1fYWx0 bWFwX2FsbG9jKGFsdG1hcCwgbnJfcGZucyk7DQorCWlmIChwZm4gPCBVTE9OR19NQVgpDQorCQlw dHIgPSBfX3ZhKF9fcGZuX3RvX3BoeXMocGZuKSk7DQorCWVsc2UNCisJCXB0ciA9IE5VTEw7DQor CXByX2RlYnVnKCIlczogcGZuOiAlI2x4IGFsbG9jOiAlbGQgYWxpZ246ICVsZCBucjogJSNseFxu IiwNCisJCQlfX2Z1bmNfXywgcGZuLCBhbHRtYXAtPmFsbG9jLCBhbHRtYXAtPmFsaWduLCBucl9w Zm5zKTsNCisNCisJcmV0dXJuIHB0cjsNCit9DQorDQorLyogbmVlZCB0byBtYWtlIHN1cmUgc2l6 ZSBpcyBhbGwgdGhlIHNhbWUgZHVyaW5nIGVhcmx5IHN0YWdlICovDQordm9pZCAqIF9fbWVtaW5p dCB2bWVtbWFwX2FsbG9jX2Jsb2NrX2J1Zih1bnNpZ25lZCBsb25nIHNpemUsIGludCBub2RlLA0K KwkJc3RydWN0IHZtZW1fYWx0bWFwICphbHRtYXApDQorew0KKwlpZiAoYWx0bWFwKQ0KKwkJcmV0 dXJuIGFsdG1hcF9hbGxvY19ibG9ja19idWYoc2l6ZSwgYWx0bWFwKTsNCisJcmV0dXJuIF9fdm1l bW1hcF9hbGxvY19ibG9ja19idWYoc2l6ZSwgbm9kZSk7DQorfQ0KKw0KIHZvaWQgX19tZW1pbml0 IHZtZW1tYXBfdmVyaWZ5KHB0ZV90ICpwdGUsIGludCBub2RlLA0KIAkJCQl1bnNpZ25lZCBsb25n IHN0YXJ0LCB1bnNpZ25lZCBsb25nIGVuZCkNCiB7DQpAQCAtMTAzLDcgKzEzNiw3IEBAIHB0ZV90 ICogX19tZW1pbml0IHZtZW1tYXBfcHRlX3BvcHVsYXRlKHBtZF90ICpwbWQsIHVuc2lnbmVkIGxv bmcgYWRkciwgaW50IG5vZGUpDQogCXB0ZV90ICpwdGUgPSBwdGVfb2Zmc2V0X2tlcm5lbChwbWQs IGFkZHIpOw0KIAlpZiAocHRlX25vbmUoKnB0ZSkpIHsNCiAJCXB0ZV90IGVudHJ5Ow0KLQkJdm9p ZCAqcCA9IHZtZW1tYXBfYWxsb2NfYmxvY2tfYnVmKFBBR0VfU0laRSwgbm9kZSk7DQorCQl2b2lk ICpwID0gX192bWVtbWFwX2FsbG9jX2Jsb2NrX2J1ZihQQUdFX1NJWkUsIG5vZGUpOw0KIAkJaWYg KCFwKQ0KIAkJCXJldHVybiBOVUxMOw0KIAkJZW50cnkgPSBwZm5fcHRlKF9fcGEocCkgPj4gUEFH RV9TSElGVCwgUEFHRV9LRVJORUwpOw0KZGlmZiAtLWdpdCBhL21tL3NwYXJzZS5jIGIvbW0vc3Bh cnNlLmMNCmluZGV4IGQxYjQ4YjY5MWFjOC4uMzcxN2NlZWQ0MTc3IDEwMDY0NA0KLS0tIGEvbW0v c3BhcnNlLmMNCisrKyBiL21tL3NwYXJzZS5jDQpAQCAtNzQ4LDcgKzc0OCw3IEBAIHN0YXRpYyB2 b2lkIGNsZWFyX2h3cG9pc29uZWRfcGFnZXMoc3RydWN0IHBhZ2UgKm1lbW1hcCwgaW50IG5yX3Bh Z2VzKQ0KIAlpZiAoIW1lbW1hcCkNCiAJCXJldHVybjsNCiANCi0JZm9yIChpID0gMDsgaSA8IFBB R0VTX1BFUl9TRUNUSU9OOyBpKyspIHsNCisJZm9yIChpID0gMDsgaSA8IG5yX3BhZ2VzOyBpKysp IHsNCiAJCWlmIChQYWdlSFdQb2lzb24oJm1lbW1hcFtpXSkpIHsNCiAJCQlhdG9taWNfbG9uZ19z dWIoMSwgJm51bV9wb2lzb25lZF9wYWdlcyk7DQogCQkJQ2xlYXJQYWdlSFdQb2lzb24oJm1lbW1h cFtpXSk7DQpAQCAtNzg4LDcgKzc4OCw4IEBAIHN0YXRpYyB2b2lkIGZyZWVfc2VjdGlvbl91c2Vt YXAoc3RydWN0IHBhZ2UgKm1lbW1hcCwgdW5zaWduZWQgbG9uZyAqdXNlbWFwKQ0KIAkJZnJlZV9t YXBfYm9vdG1lbShtZW1tYXApOw0KIH0NCiANCi12b2lkIHNwYXJzZV9yZW1vdmVfb25lX3NlY3Rp b24oc3RydWN0IHpvbmUgKnpvbmUsIHN0cnVjdCBtZW1fc2VjdGlvbiAqbXMpDQordm9pZCBzcGFy c2VfcmVtb3ZlX29uZV9zZWN0aW9uKHN0cnVjdCB6b25lICp6b25lLCBzdHJ1Y3QgbWVtX3NlY3Rp b24gKm1zLA0KKwkJdW5zaWduZWQgbG9uZyBtYXBfb2Zmc2V0KQ0KIHsNCiAJc3RydWN0IHBhZ2Ug Km1lbW1hcCA9IE5VTEw7DQogCXVuc2lnbmVkIGxvbmcgKnVzZW1hcCA9IE5VTEwsIGZsYWdzOw0K QEAgLTgwNCw3ICs4MDUsOCBAQCB2b2lkIHNwYXJzZV9yZW1vdmVfb25lX3NlY3Rpb24oc3RydWN0 IHpvbmUgKnpvbmUsIHN0cnVjdCBtZW1fc2VjdGlvbiAqbXMpDQogCX0NCiAJcGdkYXRfcmVzaXpl X3VubG9jayhwZ2RhdCwgJmZsYWdzKTsNCiANCi0JY2xlYXJfaHdwb2lzb25lZF9wYWdlcyhtZW1t YXAsIFBBR0VTX1BFUl9TRUNUSU9OKTsNCisJY2xlYXJfaHdwb2lzb25lZF9wYWdlcyhtZW1tYXAg KyBtYXBfb2Zmc2V0LA0KKwkJCVBBR0VTX1BFUl9TRUNUSU9OIC0gbWFwX29mZnNldCk7DQogCWZy ZWVfc2VjdGlvbl91c2VtYXAobWVtbWFwLCB1c2VtYXApOw0KIH0NCiAjZW5kaWYgLyogQ09ORklH X01FTU9SWV9IT1RSRU1PVkUgKi8NCg0K -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751685AbbJSWxH (ORCPT ); Mon, 19 Oct 2015 18:53:07 -0400 Received: from mga11.intel.com ([192.55.52.93]:27149 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750928AbbJSWxF (ORCPT ); Mon, 19 Oct 2015 18:53:05 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,704,1437462000"; d="scan'208";a="584128421" From: "Williams, Dan J" To: "linux-nvdimm@lists.01.org" CC: "linux-kernel@vger.kernel.org" , "linux-mm@kvack.org" , "dave.hansen@linux.intel.com" , "hch@lst.de" , "akpm@linux-foundation.org" , "hpa@zytor.com" , "mingo@redhat.com" , "ross.zwisler@linux.intel.com" Subject: Re: [PATCH v2 05/20] x86, mm: introduce vmem_altmap to augment vmemmap_populate() Thread-Topic: [PATCH v2 05/20] x86, mm: introduce vmem_altmap to augment vmemmap_populate() Thread-Index: AQHRAvc2dT7XzPyuuE2iO4WlXTz7MZ5z8TYA Date: Mon, 19 Oct 2015 22:53:00 +0000 Message-ID: <1445295178.29633.8.camel@intel.com> References: <20151010005522.17221.87557.stgit@dwillia2-desk3.jf.intel.com> <20151010005549.17221.32687.stgit@dwillia2-desk3.jf.intel.com> In-Reply-To: <20151010005549.17221.32687.stgit@dwillia2-desk3.jf.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.138] Content-Type: text/plain; charset="utf-8" Content-ID: <757C1FBEA87F6D41871264554ABE4B5A@intel.com> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by mail.home.local id t9JMrNPt011890 On Fri, 2015-10-09 at 20:55 -0400, Dan Williams wrote: > In support of providing struct page for large persistent memory > capacities, use struct vmem_altmap to change the default policy for > allocating memory for the memmap array. The default vmemmap_populate() > allocates page table storage area from the page allocator. Given > persistent memory capacities relative to DRAM it may not be feasible to > store the memmap in 'System Memory'. Instead vmem_altmap represents > pre-allocated "device pages" to satisfy vmemmap_alloc_block_buf() > requests. > > Cc: H. Peter Anvin > Cc: Ingo Molnar > Cc: Dave Hansen > Cc: Andrew Morton > Signed-off-by: Dan Williams > --- The kbuild test robot reported a crash with this patch when CONFIG_ZONE_DEVICE=y && CONFIG_SPARSEMEM_VMEMMAP=n. The ability to specify an alternate location for the vmemmap needs to be gated on CONFIG_SPARSEMEM_VMEMMAP=y. Here's a refreshed patch with ifdef guards and a warning message if the @altmap arg is passed to devm_memremap_pages() on a CONFIG_SPARSEMEM_VMEMMAP=n kernel. 8<---- Subject: x86, mm: introduce vmem_altmap to augment vmemmap_populate() From: Dan Williams In support of providing struct page for large persistent memory capacities, use struct vmem_altmap to change the default policy for allocating memory for the memmap array. The default vmemmap_populate() allocates page table storage area from the page allocator. Given persistent memory capacities relative to DRAM it may not be feasible to store the memmap in 'System Memory'. Instead vmem_altmap represents pre-allocated "device pages" to satisfy vmemmap_alloc_block_buf() requests. Cc: H. Peter Anvin Cc: Ingo Molnar Cc: Dave Hansen Cc: Andrew Morton Reported-by: kbuild test robot Signed-off-by: Dan Williams --- arch/m68k/include/asm/page_mm.h | 1 arch/m68k/include/asm/page_no.h | 1 arch/mn10300/include/asm/page.h | 1 arch/x86/mm/init_64.c | 32 ++++++++++--- drivers/nvdimm/pmem.c | 6 ++ include/linux/io.h | 17 ------- include/linux/memory_hotplug.h | 3 + include/linux/mm.h | 98 ++++++++++++++++++++++++++++++++++++++- kernel/memremap.c | 77 +++++++++++++++++++++++++++---- mm/memory_hotplug.c | 66 +++++++++++++++++++------- mm/page_alloc.c | 10 ++++ mm/sparse-vmemmap.c | 37 ++++++++++++++- mm/sparse.c | 8 ++- 13 files changed, 294 insertions(+), 63 deletions(-) diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h index 5029f73e6294..884f2f7e4caf 100644 --- a/arch/m68k/include/asm/page_mm.h +++ b/arch/m68k/include/asm/page_mm.h @@ -125,6 +125,7 @@ static inline void *__va(unsigned long x) */ #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +#define __pfn_to_phys(pfn) PFN_PHYS(pfn) extern int m68k_virt_to_node_shift; diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index ef209169579a..7845eca0b36d 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -24,6 +24,7 @@ extern unsigned long memory_end; #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +#define __pfn_to_phys(pfn) PFN_PHYS(pfn) #define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) #define page_to_virt(page) __va(((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)) diff --git a/arch/mn10300/include/asm/page.h b/arch/mn10300/include/asm/page.h index 8288e124165b..3810a6f740fd 100644 --- a/arch/mn10300/include/asm/page.h +++ b/arch/mn10300/include/asm/page.h @@ -107,6 +107,7 @@ static inline int get_order(unsigned long size) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define pfn_to_page(pfn) (mem_map + ((pfn) - __pfn_disp)) #define page_to_pfn(page) ((unsigned long)((page) - mem_map) + __pfn_disp) +#define __pfn_to_phys(pfn) PFN_PHYS(pfn) #define pfn_valid(pfn) \ ({ \ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index e5d42f1a2a71..cabf8ceb0a6b 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -714,6 +714,12 @@ static void __meminit free_pagetable(struct page *page, int order) { unsigned long magic; unsigned int nr_pages = 1 << order; + struct vmem_altmap *altmap = to_vmem_altmap((unsigned long) page); + + if (altmap) { + vmem_altmap_free(altmap, nr_pages); + return; + } /* bootmem page has reserved flag */ if (PageReserved(page)) { @@ -1018,13 +1024,19 @@ int __ref arch_remove_memory(u64 start, u64 size) { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + struct page *page = pfn_to_page(start_pfn); + struct vmem_altmap *altmap; struct zone *zone; int ret; - zone = page_zone(pfn_to_page(start_pfn)); - kernel_physical_mapping_remove(start, start + size); + /* With altmap the first mapped page is offset from @start */ + altmap = to_vmem_altmap((unsigned long) page); + if (altmap) + page += vmem_altmap_offset(altmap); + zone = page_zone(page); ret = __remove_pages(zone, start_pfn, nr_pages); WARN_ON_ONCE(ret); + kernel_physical_mapping_remove(start, start + size); return ret; } @@ -1234,7 +1246,7 @@ static void __meminitdata *p_start, *p_end; static int __meminitdata node_start; static int __meminit vmemmap_populate_hugepages(unsigned long start, - unsigned long end, int node) + unsigned long end, int node, struct vmem_altmap *altmap) { unsigned long addr; unsigned long next; @@ -1257,7 +1269,7 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start, if (pmd_none(*pmd)) { void *p; - p = vmemmap_alloc_block_buf(PMD_SIZE, node); + p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap); if (p) { pte_t entry; @@ -1278,7 +1290,8 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start, addr_end = addr + PMD_SIZE; p_end = p + PMD_SIZE; continue; - } + } else if (altmap) + return -ENOMEM; /* no fallback */ } else if (pmd_large(*pmd)) { vmemmap_verify((pte_t *)pmd, node, addr, next); continue; @@ -1292,11 +1305,16 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start, int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) { + struct vmem_altmap *altmap = to_vmem_altmap(start); int err; if (cpu_has_pse) - err = vmemmap_populate_hugepages(start, end, node); - else + err = vmemmap_populate_hugepages(start, end, node, altmap); + else if (altmap) { + pr_err_once("%s: no cpu support for altmap allocations\n", + __func__); + err = -ENOMEM; + } else err = vmemmap_populate_basepages(start, end, node); if (!err) sync_global_pgds(start, end - 1, 0); diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 349f03e7ed06..3c5b8f585441 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -151,7 +151,8 @@ static struct pmem_device *pmem_alloc(struct device *dev, } if (pmem_should_map_pages(dev)) - pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, res); + pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, res, + NULL); else pmem->virt_addr = (void __pmem *) devm_memremap(dev, pmem->phys_addr, pmem->size, @@ -362,7 +363,8 @@ static int nvdimm_namespace_attach_pfn(struct nd_namespace_common *ndns) /* establish pfn range for lookup, and switch to direct map */ pmem = dev_get_drvdata(dev); devm_memunmap(dev, (void __force *) pmem->virt_addr); - pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, &nsio->res); + pmem->virt_addr = (void __pmem *) devm_memremap_pages(dev, &nsio->res, + NULL); if (IS_ERR(pmem->virt_addr)) { rc = PTR_ERR(pmem->virt_addr); goto err; diff --git a/include/linux/io.h b/include/linux/io.h index de64c1e53612..2f2f8859abd9 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -87,23 +87,6 @@ void *devm_memremap(struct device *dev, resource_size_t offset, size_t size, unsigned long flags); void devm_memunmap(struct device *dev, void *addr); -void *__devm_memremap_pages(struct device *dev, struct resource *res); - -#ifdef CONFIG_ZONE_DEVICE -void *devm_memremap_pages(struct device *dev, struct resource *res); -#else -static inline void *devm_memremap_pages(struct device *dev, struct resource *res) -{ - /* - * Fail attempts to call devm_memremap_pages() without - * ZONE_DEVICE support enabled, this requires callers to fall - * back to plain devm_memremap() based on config - */ - WARN_ON_ONCE(1); - return ERR_PTR(-ENXIO); -} -#endif - /* * Some systems do not have legacy ISA devices. * /dev/port is not a valid interface on these systems. diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 8f60e899b33c..178e000a7983 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -273,7 +273,8 @@ extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); extern bool is_memblock_offlined(struct memory_block *mem); extern void remove_memory(int nid, u64 start, u64 size); extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn); -extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms); +extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, + unsigned long map_offset); extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum); diff --git a/include/linux/mm.h b/include/linux/mm.h index 30c3c8764649..b8cba7d8ea28 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -718,18 +718,109 @@ static inline enum zone_type page_zonenum(const struct page *page) } /** + * struct vmem_altmap - pre-allocated storage for vmemmap_populate + * @base_pfn: base of the entire dev_pagemap mapping + * @reserve: pages mapped, but reserved for driver use (relative to @base) + * @free: free pages set aside in the mapping for memmap storage + * @align: pages reserved to meet allocation alignments + * @alloc: track pages consumed, private to vmemmap_populate() + */ +struct vmem_altmap { + const unsigned long base_pfn; + const unsigned long reserve; + unsigned long free; + unsigned long align; + unsigned long alloc; +}; + +static inline unsigned long vmem_altmap_nr_free(struct vmem_altmap *altmap) +{ + unsigned long allocated = altmap->alloc + altmap->align; + + if (altmap->free > allocated) + return altmap->free - allocated; + return 0; +} + +static inline unsigned long vmem_altmap_offset(struct vmem_altmap *altmap) +{ + /* number of pfns from base where pfn_to_page() is valid */ + return altmap->reserve + altmap->free; +} + +static inline unsigned long vmem_altmap_next_pfn(struct vmem_altmap *altmap) +{ + return altmap->base_pfn + altmap->reserve + altmap->alloc + + altmap->align; +} + +/** + * vmem_altmap_alloc - allocate pages from the vmem_altmap reservation + * @altmap - reserved page pool for the allocation + * @nr_pfns - size (in pages) of the allocation + * + * Allocations are aligned to the size of the request + */ +static inline unsigned long vmem_altmap_alloc(struct vmem_altmap *altmap, + unsigned long nr_pfns) +{ + unsigned long pfn = vmem_altmap_next_pfn(altmap); + unsigned long nr_align; + + nr_align = 1UL << find_first_bit(&nr_pfns, BITS_PER_LONG); + nr_align = ALIGN(pfn, nr_align) - pfn; + + if (nr_pfns + nr_align > vmem_altmap_nr_free(altmap)) + return ULONG_MAX; + altmap->alloc += nr_pfns; + altmap->align += nr_align; + return pfn + nr_align; +} + +static inline void vmem_altmap_free(struct vmem_altmap *altmap, + unsigned long nr_pfns) +{ + altmap->alloc -= nr_pfns; +} + +/** * struct dev_pagemap - metadata for ZONE_DEVICE mappings + * @altmap: pre-allocated/reserved memory for vmemmap allocations * @dev: host device of the mapping for debug */ struct dev_pagemap { - /* TODO: vmem_altmap and percpu_ref count */ + struct vmem_altmap *altmap; + const struct resource *res; struct device *dev; }; #ifdef CONFIG_ZONE_DEVICE struct dev_pagemap *__get_dev_pagemap(resource_size_t phys); +void *devm_memremap_pages(struct device *dev, struct resource *res, + struct vmem_altmap *altmap); +#else +static inline struct dev_pagemap *__get_dev_pagemap(resource_size_t phys) +{ + return NULL; +} + +static inline void *devm_memremap_pages(struct device *dev, struct resource *res, + struct vmem_altmap *altmap) +{ + /* + * Fail attempts to call devm_memremap_pages() without + * ZONE_DEVICE support enabled, this requires callers to fall + * back to plain devm_memremap() based on config + */ + WARN_ON_ONCE(1); + return ERR_PTR(-ENXIO); +} +#endif + +#ifdef CONFIG_SPARSEMEM_VMEMMAP +struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start); #else -static inline struct dev_pagemap *get_dev_pagemap(resource_size_t phys) +static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start) { return NULL; } @@ -2245,7 +2336,8 @@ pud_t *vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node); pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node); pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node); void *vmemmap_alloc_block(unsigned long size, int node); -void *vmemmap_alloc_block_buf(unsigned long size, int node); +void *vmemmap_alloc_block_buf(unsigned long size, int node, + struct vmem_altmap *altmap); void vmemmap_verify(pte_t *, int, unsigned long, unsigned long); int vmemmap_populate_basepages(unsigned long start, unsigned long end, int node); diff --git a/kernel/memremap.c b/kernel/memremap.c index 64bfd9fa93aa..79bbbea2de6a 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c @@ -146,6 +146,7 @@ struct page_map { struct resource res; struct dev_pagemap pgmap; struct list_head list; + struct vmem_altmap altmap; }; static void add_page_map(struct page_map *page_map) @@ -162,14 +163,17 @@ static void del_page_map(struct page_map *page_map) spin_unlock(&range_lock); } -static void devm_memremap_pages_release(struct device *dev, void *res) +static void devm_memremap_pages_release(struct device *dev, void *data) { - struct page_map *page_map = res; - - del_page_map(page_map); + struct page_map *page_map = data; + struct resource *res = &page_map->res; + struct dev_pagemap *pgmap = &page_map->pgmap; /* pages are dead and unused, undo the arch mapping */ - arch_remove_memory(page_map->res.start, resource_size(&page_map->res)); + arch_remove_memory(res->start, resource_size(res)); + dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc, + "%s: failed to free all reserved pages\n", __func__); + del_page_map(page_map); } /* assumes rcu_read_lock() held at entry */ @@ -185,10 +189,22 @@ struct dev_pagemap *__get_dev_pagemap(resource_size_t phys) return NULL; } -void *devm_memremap_pages(struct device *dev, struct resource *res) +/** + * devm_memremap_pages - remap and provide memmap backing for the given resource + * @dev: hosting device for @res + * @res: "host memory" address range + * @altmap: optional descriptor for allocating the memmap from @res + * + * Note, the expectation is that @res is a host memory range that could + * feasibly be treated as a "System RAM" range, i.e. not a device mmio + * range, but this is not enforced. + */ +void *devm_memremap_pages(struct device *dev, struct resource *res, + struct vmem_altmap *altmap) { int is_ram = region_intersects(res->start, resource_size(res), "System RAM"); + struct dev_pagemap *pgmap; struct page_map *page_map; int error, nid; @@ -201,14 +217,25 @@ void *devm_memremap_pages(struct device *dev, struct resource *res) if (is_ram == REGION_INTERSECTS) return __va(res->start); + if (altmap && !IS_ENABLED(CONFIG_SPARSEMEM_VMEMMAP)) { + dev_err(dev, "%s: support for alternate vmemmap disabled\n", + __func__); + return ERR_PTR(-ENXIO); + } + page_map = devres_alloc_node(devm_memremap_pages_release, sizeof(*page_map), GFP_KERNEL, dev_to_node(dev)); if (!page_map) return ERR_PTR(-ENOMEM); + pgmap = &page_map->pgmap; memcpy(&page_map->res, res, sizeof(*res)); - - page_map->pgmap.dev = dev; + if (altmap) { + memcpy(&page_map->altmap, altmap, sizeof(*altmap)); + pgmap->altmap = &page_map->altmap; + } + pgmap->dev = dev; + pgmap->res = &page_map->res; INIT_LIST_HEAD(&page_map->list); add_page_map(page_map); @@ -228,3 +255,37 @@ void *devm_memremap_pages(struct device *dev, struct resource *res) } EXPORT_SYMBOL(devm_memremap_pages); #endif /* CONFIG_ZONE_DEVICE */ + +#ifdef CONFIG_SPARSEMEM_VMEMMAP +/* + * Uncoditionally retrieve a dev_pagemap associated with the given physical + * address, this is only for use in the arch_{add|remove}_memory() for setting + * up and tearing down the memmap. + */ +static struct dev_pagemap *lookup_dev_pagemap(resource_size_t phys) +{ + struct dev_pagemap *pgmap; + + rcu_read_lock(); + pgmap = __get_dev_pagemap(phys); + rcu_read_unlock(); + return pgmap; +} + +struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start) +{ + /* + * 'memmap_start' is the virtual address for the first "struct + * page" in this range of the vmemmap array. In the case of + * CONFIG_SPARSE_VMEMMAP a page_to_pfn conversion is simple + * pointer arithmetic, so we can perform this to_vmem_altmap() + * conversion without concern for the initialization state of + * the struct page fields. + */ + struct page *page = (struct page *) memmap_start; + struct dev_pagemap *pgmap; + + pgmap = lookup_dev_pagemap(__pfn_to_phys(page_to_pfn(page))); + return pgmap ? pgmap->altmap : NULL; +} +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index aa992e2df58a..3521df153de3 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -505,10 +505,25 @@ int __ref __add_pages(int nid, struct zone *zone, unsigned long phys_start_pfn, unsigned long i; int err = 0; int start_sec, end_sec; + struct vmem_altmap *altmap; + /* during initialize mem_map, align hot-added range to section */ start_sec = pfn_to_section_nr(phys_start_pfn); end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1); + altmap = to_vmem_altmap((unsigned long) pfn_to_page(phys_start_pfn)); + if (altmap) { + /* + * Validate altmap is within bounds of the total request + */ + if (altmap->base_pfn != phys_start_pfn + || vmem_altmap_offset(altmap) > nr_pages) { + pr_warn_once("memory add fail, invalid altmap\n"); + return -EINVAL; + } + altmap->alloc = 0; + } + for (i = start_sec; i <= end_sec; i++) { err = __add_section(nid, zone, section_nr_to_pfn(i)); @@ -730,7 +745,8 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn) pgdat_resize_unlock(zone->zone_pgdat, &flags); } -static int __remove_section(struct zone *zone, struct mem_section *ms) +static int __remove_section(struct zone *zone, struct mem_section *ms, + unsigned long map_offset) { unsigned long start_pfn; int scn_nr; @@ -747,7 +763,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms) start_pfn = section_nr_to_pfn(scn_nr); __remove_zone(zone, start_pfn); - sparse_remove_one_section(zone, ms); + sparse_remove_one_section(zone, ms, map_offset); return 0; } @@ -766,9 +782,32 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn, unsigned long nr_pages) { unsigned long i; - int sections_to_remove; - resource_size_t start, size; - int ret = 0; + unsigned long map_offset = 0; + int sections_to_remove, ret = 0; + + /* In the ZONE_DEVICE case device driver owns the memory region */ + if (is_dev_zone(zone)) { + struct page *page = pfn_to_page(phys_start_pfn); + struct vmem_altmap *altmap; + + altmap = to_vmem_altmap((unsigned long) page); + if (altmap) + map_offset = vmem_altmap_offset(altmap); + } else { + resource_size_t start, size; + + start = phys_start_pfn << PAGE_SHIFT; + size = nr_pages * PAGE_SIZE; + + ret = release_mem_region_adjustable(&iomem_resource, start, + size); + if (ret) { + resource_size_t endres = start + size - 1; + + pr_warn("Unable to release resource <%pa-%pa> (%d)\n", + &start, &endres, ret); + } + } /* * We can only remove entire sections @@ -776,23 +815,12 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn, BUG_ON(phys_start_pfn & ~PAGE_SECTION_MASK); BUG_ON(nr_pages % PAGES_PER_SECTION); - start = phys_start_pfn << PAGE_SHIFT; - size = nr_pages * PAGE_SIZE; - - /* in the ZONE_DEVICE case device driver owns the memory region */ - if (!is_dev_zone(zone)) - ret = release_mem_region_adjustable(&iomem_resource, start, size); - if (ret) { - resource_size_t endres = start + size - 1; - - pr_warn("Unable to release resource <%pa-%pa> (%d)\n", - &start, &endres, ret); - } - sections_to_remove = nr_pages / PAGES_PER_SECTION; for (i = 0; i < sections_to_remove; i++) { unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION; - ret = __remove_section(zone, __pfn_to_section(pfn)); + + ret = __remove_section(zone, __pfn_to_section(pfn), map_offset); + map_offset = 0; if (ret) break; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 48aaf7b9f253..9dfc431d6271 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4620,8 +4620,9 @@ static void setup_zone_migrate_reserve(struct zone *zone) void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, unsigned long start_pfn, enum memmap_context context) { - pg_data_t *pgdat = NODE_DATA(nid); + struct vmem_altmap *altmap = to_vmem_altmap(__pfn_to_phys(start_pfn)); unsigned long end_pfn = start_pfn + size; + pg_data_t *pgdat = NODE_DATA(nid); unsigned long pfn; struct zone *z; unsigned long nr_initialised = 0; @@ -4629,6 +4630,13 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, if (highest_memmap_pfn < end_pfn - 1) highest_memmap_pfn = end_pfn - 1; + /* + * Honor reservation requested by the driver for this ZONE_DEVICE + * memory + */ + if (altmap && start_pfn == altmap->base_pfn) + start_pfn += altmap->reserve; + z = &pgdat->node_zones[zone]; for (pfn = start_pfn; pfn < end_pfn; pfn++) { /* diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 4cba9c2783a1..96c1dca4ce6a 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -70,7 +70,7 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node) } /* need to make sure size is all the same during early stage */ -void * __meminit vmemmap_alloc_block_buf(unsigned long size, int node) +static void * __meminit __vmemmap_alloc_block_buf(unsigned long size, int node) { void *ptr; @@ -87,6 +87,39 @@ void * __meminit vmemmap_alloc_block_buf(unsigned long size, int node) return ptr; } +static void * __meminit altmap_alloc_block_buf(unsigned long size, + struct vmem_altmap *altmap) +{ + unsigned long pfn, nr_pfns; + void *ptr; + + if (size & ~PAGE_MASK) { + pr_warn_once("%s: allocations must be multiple of PAGE_SIZE (%ld)\n", + __func__, size); + return NULL; + } + + nr_pfns = size >> PAGE_SHIFT; + pfn = vmem_altmap_alloc(altmap, nr_pfns); + if (pfn < ULONG_MAX) + ptr = __va(__pfn_to_phys(pfn)); + else + ptr = NULL; + pr_debug("%s: pfn: %#lx alloc: %ld align: %ld nr: %#lx\n", + __func__, pfn, altmap->alloc, altmap->align, nr_pfns); + + return ptr; +} + +/* need to make sure size is all the same during early stage */ +void * __meminit vmemmap_alloc_block_buf(unsigned long size, int node, + struct vmem_altmap *altmap) +{ + if (altmap) + return altmap_alloc_block_buf(size, altmap); + return __vmemmap_alloc_block_buf(size, node); +} + void __meminit vmemmap_verify(pte_t *pte, int node, unsigned long start, unsigned long end) { @@ -103,7 +136,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node) pte_t *pte = pte_offset_kernel(pmd, addr); if (pte_none(*pte)) { pte_t entry; - void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node); + void *p = __vmemmap_alloc_block_buf(PAGE_SIZE, node); if (!p) return NULL; entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); diff --git a/mm/sparse.c b/mm/sparse.c index d1b48b691ac8..3717ceed4177 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -748,7 +748,7 @@ static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages) if (!memmap) return; - for (i = 0; i < PAGES_PER_SECTION; i++) { + for (i = 0; i < nr_pages; i++) { if (PageHWPoison(&memmap[i])) { atomic_long_sub(1, &num_poisoned_pages); ClearPageHWPoison(&memmap[i]); @@ -788,7 +788,8 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap) free_map_bootmem(memmap); } -void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) +void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, + unsigned long map_offset) { struct page *memmap = NULL; unsigned long *usemap = NULL, flags; @@ -804,7 +805,8 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms) } pgdat_resize_unlock(pgdat, &flags); - clear_hwpoisoned_pages(memmap, PAGES_PER_SECTION); + clear_hwpoisoned_pages(memmap + map_offset, + PAGES_PER_SECTION - map_offset); free_section_usemap(memmap, usemap); } #endif /* CONFIG_MEMORY_HOTREMOVE */ ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayºʇڙë,j­¢f£¢·hšïêÿ‘êçz_è®(­éšŽŠÝ¢j"ú¶m§ÿÿ¾«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^¶m§ÿÿà ÿ¶ìÿ¢¸?–I¥