Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKLyogSVBWUzoJTWFnbGV2IEhhc2hpbmcgc2NoZWR1bGluZyBtb2R1bGUKICoKICogQXV0aG9yczoJSW5qdSBTb25nIDxpbmp1LnNvbmdAbmF2ZXJjb3JwLmNvbT4KICoKICovCgovKiBUaGUgbWggYWxnb3JpdGhtIGlzIHRvIGFzc2lnbqBhIHByZWZlcmVuY2UgbGlzdCBvZiBhbGwgdGhlIGxvb2t1cAogKiB0YWJsZSBwb3NpdGlvbnMgdG8gZWFjaCBkZXN0aW5hdGlvbiBhbmQgcG9wdWxhdGUgdGhlIHRhYmxlIHdpdGgKICogdGhlIG1vc3QtcHJlZmVycmVkIHBvc2l0aW9uIG9mIGRlc3RpbmF0aW9ucy4gVGhlbiBpdCBpcyB0byBzZWxlY3QKICogZGVzdGluYXRpb24gd2l0aCB0aGUgaGFzaCBrZXkgb2Ygc291cmNlIElQIGFkZHJlc3OgdGhyb3VnaCBsb29raW5nCiAqIHVwIGEgdGhlIGxvb2t1cCB0YWJsZS4KICoKICogVGhlIGFsZ29yaXRobSBpcyBkZXRhaWxlZCBpbjoKICogWzMuNCBDb25zaXN0ZW50IEhhc2luZ10KaHR0cHM6Ly93d3cudXNlbml4Lm9yZy9zeXN0ZW0vZmlsZXMvY29uZmVyZW5jZS9uc2RpMTYvbnNkaTE2LXBhcGVyLWVpc2VuYnVkLnBkZgogKgogKi8KCiNkZWZpbmUgS01TR19DT01QT05FTlQgIklQVlMiCiNkZWZpbmUgcHJfZm10KGZtdCkgS01TR19DT01QT05FTlQgIjogIiBmbXQKCiNpbmNsdWRlIDxsaW51eC9pcC5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgoKI2luY2x1ZGUgPG5ldC9pcF92cy5oPgoKI2luY2x1ZGUgPGxpbnV4L3NpcGhhc2guaD4KI2luY2x1ZGUgPGxpbnV4L2JpdG9wcy5oPgojaW5jbHVkZSA8bGludXgvZ2NkLmg+CgojZGVmaW5lIElQX1ZTX1NWQ19GX1NDSEVEX01IX0ZBTExCQUNLCUlQX1ZTX1NWQ19GX1NDSEVEMSAvKiBNSCBmYWxsYmFjayAqLwojZGVmaW5lIElQX1ZTX1NWQ19GX1NDSEVEX01IX1BPUlQJSVBfVlNfU1ZDX0ZfU0NIRUQyIC8qIE1IIHVzZSBwb3J0ICovCgpzdHJ1Y3QgaXBfdnNfbWhfbG9va3VwIHsKCXN0cnVjdCBpcF92c19kZXN0IF9fcmN1CSpkZXN0OwkvKiByZWFsIHNlcnZlciAoY2FjaGUpICovCn07CgpzdHJ1Y3QgaXBfdnNfbWhfZGVzdF9zZXR1cCB7Cgl1bnNpZ25lZCBpbnQJb2Zmc2V0OyAvKiBzdGFydGluZyBvZmZzZXQgKi8KCXVuc2lnbmVkIGludAlza2lwOwkvKiBza2lwICovCgl1bnNpZ25lZCBpbnQJcGVybTsJLyogbmV4dF9vZmZzZXQgKi8KCWludAkJdHVybnM7CS8qIHdlaWdodCAvIGdjZCgpIGFuZCByc2hpZnQgKi8KfTsKCi8qIEF2YWlsYWJsZSBwcmltZSBudW1iZXJzIGZvciBNSCB0YWJsZSAqLwpzdGF0aWMgaW50IHByaW1lc1tdID0gezI1MSwgNTA5LCAxMDIxLCAyMDM5LCA0MDkzLAoJCSAgICAgICA4MTkxLCAxNjM4MSwgMzI3NDksIDY1NTIxLCAxMzEwNzF9OwoKLyogRm9yIElQVlMgTUggZW50cnkgaGFzaCB0YWJsZSAqLwojaWZuZGVmIENPTkZJR19JUF9WU19NSF9UQUJfSU5ERVgKI2RlZmluZSBDT05GSUdfSVBfVlNfTUhfVEFCX0lOREVYCTEyCiNlbmRpZgojZGVmaW5lIElQX1ZTX01IX1RBQl9CSVRTCQkoQ09ORklHX0lQX1ZTX01IX1RBQl9JTkRFWCAvIDIpCiNkZWZpbmUgSVBfVlNfTUhfVEFCX0lOREVYCQkoQ09ORklHX0lQX1ZTX01IX1RBQl9JTkRFWCAtIDgpCiNkZWZpbmUgSVBfVlNfTUhfVEFCX1NJWkUgICAgICAgICAgICAgICBwcmltZXNbSVBfVlNfTUhfVEFCX0lOREVYXQoKc3RydWN0IGlwX3ZzX21oX3N0YXRlIHsKCXN0cnVjdCByY3VfaGVhZAkJCXJjdV9oZWFkOwoJc3RydWN0IGlwX3ZzX21oX2xvb2t1cAkJKmxvb2t1cDsKCXN0cnVjdCBpcF92c19taF9kZXN0X3NldHVwCSpkZXN0X3NldHVwOwoJaHNpcGhhc2hfa2V5X3QJCQloYXNoMSwgaGFzaDI7CglpbnQJCQkJZ2NkOwoJaW50CQkJCXJzaGlmdDsKfTsKCnN0YXRpYyBpbmxpbmUgdm9pZCBnZW5lcmF0ZV9oYXNoX3NlY3JldChoc2lwaGFzaF9rZXlfdCAqaGFzaDEsCgkJCQkJaHNpcGhhc2hfa2V5X3QgKmhhc2gyKQp7CgloYXNoMS0+a2V5WzBdID0gMjY1NDQzNTc2MVVMOwoJaGFzaDEtPmtleVsxXSA9IDI2NTQ0MzU3NjFVTDsKCgloYXNoMi0+a2V5WzBdID0gMjY1NDQ0Njg5MlVMOwoJaGFzaDItPmtleVsxXSA9IDI2NTQ0NDY4OTJVTDsKfQoKLyogSGVscGVyIGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBzZXJ2ZXIgaXMgdW5hdmFpbGFibGUgKi8Kc3RhdGljIGlubGluZSBib29sIGlzX3VuYXZhaWxhYmxlKHN0cnVjdCBpcF92c19kZXN0ICpkZXN0KQp7CglyZXR1cm4gYXRvbWljX3JlYWQoJmRlc3QtPndlaWdodCkgPD0gMCB8fAoJICAgICAgIGRlc3QtPmZsYWdzICYgSVBfVlNfREVTVF9GX09WRVJMT0FEOwp9CgovKiBSZXR1cm5zIGhhc2ggdmFsdWUgZm9yIElQVlMgTUggZW50cnkgKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQKaXBfdnNfbWhfaGFzaGtleShpbnQgYWYsIGNvbnN0IHVuaW9uIG5mX2luZXRfYWRkciAqYWRkciwKCQkgX19iZTE2IHBvcnQsIGhzaXBoYXNoX2tleV90ICprZXksIHVuc2lnbmVkIGludCBvZmZzZXQpCnsKCXVuc2lnbmVkIGludCB2OwoJX19iZTMyIGFkZHJfZm9sZCA9IGFkZHItPmlwOwoKI2lmZGVmIENPTkZJR19JUF9WU19JUFY2CglpZiAoYWYgPT0gQUZfSU5FVDYpCgkJYWRkcl9mb2xkID0gYWRkci0+aXA2WzBdIF4gYWRkci0+aXA2WzFdIF4KCQkJICAgIGFkZHItPmlwNlsyXSBeIGFkZHItPmlwNlszXTsKI2VuZGlmCgl2ID0gKG9mZnNldCArIG50b2hzKHBvcnQpICsgbnRvaGwoYWRkcl9mb2xkKSk7CglyZXR1cm4gaHNpcGhhc2goJnYsIHNpemVvZih2KSwga2V5KTsKfQoKLyogUmVzZXQgYWxsIHRoZSBoYXNoIGJ1Y2tldHMgb2YgdGhlIHNwZWNpZmllZCB0YWJsZS4gKi8Kc3RhdGljIHZvaWQgaXBfdnNfbWhfcmVzZXQoc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzKQp7CglpbnQgaTsKCXN0cnVjdCBpcF92c19taF9sb29rdXAgKmw7CglzdHJ1Y3QgaXBfdnNfZGVzdCAqZGVzdDsKCglsID0gJnMtPmxvb2t1cFswXTsKCWZvciAoaSA9IDA7IGkgPCBJUF9WU19NSF9UQUJfU0laRTsgaSsrKSB7CgkJZGVzdCA9IHJjdV9kZXJlZmVyZW5jZV9wcm90ZWN0ZWQobC0+ZGVzdCwgMSk7CgkJaWYgKGRlc3QpIHsKCQkJaXBfdnNfZGVzdF9wdXQoZGVzdCk7CgkJCVJDVV9JTklUX1BPSU5URVIobC0+ZGVzdCwgTlVMTCk7CgkJfQoJCWwrKzsKCX0KfQoKc3RhdGljIGludCBpcF92c19taF9wZXJtdXRhdGUoc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzLAoJCQkgICAgICBzdHJ1Y3QgaXBfdnNfc2VydmljZSAqc3ZjKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICpwOwoJc3RydWN0IGlwX3ZzX21oX2Rlc3Rfc2V0dXAgKmRzOwoJc3RydWN0IGlwX3ZzX2Rlc3QgKmRlc3Q7CglpbnQgbHc7CgoJLyogSWYgZ2NkIGlzIHNtYWxsZXIgdGhlbiAxLCBudW1iZXIgb2YgZGVzdHMgb3IKCSAqIGFsbCBsYXN0X3dlaWdodCBvZiBkZXN0cyBhcmUgemVyby4gU28sIHNraXAKCSAqIHBlcm11dGF0aW9uIGZvciB0aGUgZGVzdHMuCgkgKi8KCWlmIChzLT5nY2QgPCAxKQoJCXJldHVybiAwOwoKCS8qIFNldCBkZXN0X3NldHVwIGZvciB0aGUgZGVzdHMgcGVybXV0YXRpb24gKi8KCXAgPSAmc3ZjLT5kZXN0aW5hdGlvbnM7CglkcyA9ICZzLT5kZXN0X3NldHVwWzBdOwoJd2hpbGUgKChwID0gcC0+bmV4dCkgIT0gJnN2Yy0+ZGVzdGluYXRpb25zKSB7CgkJZGVzdCA9IGxpc3RfZW50cnkocCwgc3RydWN0IGlwX3ZzX2Rlc3QsIG5fbGlzdCk7CgoJCWRzLT5vZmZzZXQgPSBpcF92c19taF9oYXNoa2V5KHN2Yy0+YWYsICZkZXN0LT5hZGRyLAoJCQkJCSAgICAgIGRlc3QtPnBvcnQsICZzLT5oYXNoMSwgMCkgJQoJCQkJCSAgICAgIElQX1ZTX01IX1RBQl9TSVpFOwoJCWRzLT5za2lwID0gaXBfdnNfbWhfaGFzaGtleShzdmMtPmFmLCAmZGVzdC0+YWRkciwKCQkJCQkgICAgZGVzdC0+cG9ydCwgJnMtPmhhc2gyLCAwKSAlCgkJCQkJICAgIChJUF9WU19NSF9UQUJfU0laRSAtIDEpICsgMTsKCQlkcy0+cGVybSA9IGRzLT5vZmZzZXQ7CgoJCWx3ID0gYXRvbWljX3JlYWQoJmRlc3QtPmxhc3Rfd2VpZ2h0KTsKCQlkcy0+dHVybnMgPSAoKGx3IC8gcy0+Z2NkKSA+PiBzLT5yc2hpZnQpID8gOiAobHcgIT0gMCk7CgkJZHMrKzsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpcF92c19taF9wb3B1bGF0ZShzdHJ1Y3QgaXBfdnNfbWhfc3RhdGUgKnMsCgkJCSAgICAgc3RydWN0IGlwX3ZzX3NlcnZpY2UgKnN2YykKewoJaW50IG4sIGMsIGR0X2NvdW50OwoJdW5zaWduZWQgbG9uZyAqdGFibGU7CglzdHJ1Y3QgbGlzdF9oZWFkICpwOwoJc3RydWN0IGlwX3ZzX21oX2Rlc3Rfc2V0dXAgKmRzOwoJc3RydWN0IGlwX3ZzX2Rlc3QgKmRlc3QsICpuZXdfZGVzdDsKCgkvKiBJZiBnY2QgaXMgc21hbGxlciB0aGVuIDEsIG51bWJlciBvZiBkZXN0cyBvcgoJICogYWxsIGxhc3Rfd2VpZ2h0IG9mIGRlc3RzIGFyZSB6ZXJvLiBTbywgc2tpcAoJICogdGhlIHBvcHVsYXRpb24gZm9yIHRoZSBkZXN0cyBhbmQgcmVzZXQgbG9va3VwIHRhYmxlLgoJICovCglpZiAocy0+Z2NkIDwgMSkgewoJCWlwX3ZzX21oX3Jlc2V0KHMpOwoJCXJldHVybiAwOwoJfQoKCXRhYmxlID0gIGtjYWxsb2MoQklUU19UT19MT05HUyhJUF9WU19NSF9UQUJfU0laRSksCgkJCSBzaXplb2YodW5zaWduZWQgbG9uZyksIEdGUF9LRVJORUwpOwoJaWYgKCF0YWJsZSkKCQlyZXR1cm4gLUVOT01FTTsKCglwID0gJnN2Yy0+ZGVzdGluYXRpb25zOwoJbiA9IDA7CglkdF9jb3VudCA9IDA7Cgl3aGlsZSAobiA8IElQX1ZTX01IX1RBQl9TSVpFKSB7CgkJaWYgKHAgPT0gJnN2Yy0+ZGVzdGluYXRpb25zKQoJCQlwID0gcC0+bmV4dDsKCgkJZHMgPSAmcy0+ZGVzdF9zZXR1cFswXTsKCQl3aGlsZSAocCAhPSAmc3ZjLT5kZXN0aW5hdGlvbnMpIHsKCQkJLyogSWdub3JlIGFkZGVkIHNlcnZlciB3aXRoIHplcm8gd2VpZ2h0ICovCgkJCWlmIChkcy0+dHVybnMgPCAxKSB7CgkJCQlwID0gcC0+bmV4dDsKCQkJCWRzKys7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJYyA9IGRzLT5wZXJtOwoJCQl3aGlsZSAodGVzdF9iaXQoYywgdGFibGUpKSB7CgkJCQkvKiBBZGQgc2tpcCwgbW9kIElQX1ZTX01IX1RBQl9TSVpFICovCgkJCQlkcy0+cGVybSArPSBkcy0+c2tpcDsKCQkJCWlmIChkcy0+cGVybSA+PSBJUF9WU19NSF9UQUJfU0laRSkKCQkJCQlkcy0+cGVybSAtPSBJUF9WU19NSF9UQUJfU0laRTsKCQkJCWMgPSBkcy0+cGVybTsKCQkJfQoKCQkJX19zZXRfYml0KGMsIHRhYmxlKTsKCgkJCWRlc3QgPSByY3VfZGVyZWZlcmVuY2VfcHJvdGVjdGVkKHMtPmxvb2t1cFtjXS5kZXN0LCAxKTsKCQkJbmV3X2Rlc3QgPSBsaXN0X2VudHJ5KHAsIHN0cnVjdCBpcF92c19kZXN0LCBuX2xpc3QpOwoJCQlpZiAoZGVzdCAhPSBuZXdfZGVzdCkgewoJCQkJaWYgKGRlc3QpCgkJCQkJaXBfdnNfZGVzdF9wdXQoZGVzdCk7CgkJCQlpcF92c19kZXN0X2hvbGQobmV3X2Rlc3QpOwoJCQkJUkNVX0lOSVRfUE9JTlRFUihzLT5sb29rdXBbY10uZGVzdCwgbmV3X2Rlc3QpOwoJCQl9CgoJCQlpZiAoKytuID09IElQX1ZTX01IX1RBQl9TSVpFKQoJCQkJZ290byBvdXQ7CgoJCQlpZiAoKytkdF9jb3VudCA+PSBkcy0+dHVybnMpIHsKCQkJCWR0X2NvdW50ID0gMDsKCQkJCXAgPSBwLT5uZXh0OwoJCQkJZHMrKzsKCQkJfQoJCX0KCX0KCm91dDoKCWtmcmVlKHRhYmxlKTsKCXJldHVybiAwOwp9CgovKiBHZXQgaXBfdnNfZGVzdCBhc3NvY2lhdGVkIHdpdGggc3VwcGxpZWQgcGFyYW1ldGVycy4gKi8Kc3RhdGljIGlubGluZSBzdHJ1Y3QgaXBfdnNfZGVzdCAqCmlwX3ZzX21oX2dldChzdHJ1Y3QgaXBfdnNfc2VydmljZSAqc3ZjLCBzdHJ1Y3QgaXBfdnNfbWhfc3RhdGUgKnMsCgkgICAgIGNvbnN0IHVuaW9uIG5mX2luZXRfYWRkciAqYWRkciwgX19iZTE2IHBvcnQpCnsKCXVuc2lnbmVkIGludCBoYXNoID0gaXBfdnNfbWhfaGFzaGtleShzdmMtPmFmLCBhZGRyLCBwb3J0LCAmcy0+aGFzaDEsIDApCgkJCQkJICAgICAlIElQX1ZTX01IX1RBQl9TSVpFOwoJc3RydWN0IGlwX3ZzX2Rlc3QgKmRlc3QgPSByY3VfZGVyZWZlcmVuY2Uocy0+bG9va3VwW2hhc2hdLmRlc3QpOwoKCXJldHVybiAoIWRlc3QgfHwgaXNfdW5hdmFpbGFibGUoZGVzdCkpID8gTlVMTCA6IGRlc3Q7Cn0KCi8qIEFzIGlwX3ZzX21oX2dldCwgYnV0IHdpdGggZmFsbGJhY2sgaWYgc2VsZWN0ZWQgc2VydmVyIGlzIHVuYXZhaWxhYmxlICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGlwX3ZzX2Rlc3QgKgppcF92c19taF9nZXRfZmFsbGJhY2soc3RydWN0IGlwX3ZzX3NlcnZpY2UgKnN2Yywgc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzLAoJCSAgICAgIGNvbnN0IHVuaW9uIG5mX2luZXRfYWRkciAqYWRkciwgX19iZTE2IHBvcnQpCnsKCXVuc2lnbmVkIGludCBvZmZzZXQsIHJvZmZzZXQ7Cgl1bnNpZ25lZCBpbnQgaGFzaCwgaWhhc2g7CglzdHJ1Y3QgaXBfdnNfZGVzdCAqZGVzdDsKCgkvKiBGaXJzdCB0cnkgdGhlIGRlc3QgaXQncyBzdXBwb3NlZCB0byBnbyB0byAqLwoJaWhhc2ggPSBpcF92c19taF9oYXNoa2V5KHN2Yy0+YWYsIGFkZHIsIHBvcnQsCgkJCQkgJnMtPmhhc2gxLCAwKSAlIElQX1ZTX01IX1RBQl9TSVpFOwoJZGVzdCA9IHJjdV9kZXJlZmVyZW5jZShzLT5sb29rdXBbaWhhc2hdLmRlc3QpOwoJaWYgKCFkZXN0KQoJCXJldHVybiBOVUxMOwoJaWYgKCFpc191bmF2YWlsYWJsZShkZXN0KSkKCQlyZXR1cm4gZGVzdDsKCglJUF9WU19EQkdfQlVGKDYsICJNSDogc2VsZWN0ZWQgdW5hdmFpbGFibGUgc2VydmVyICVzOiV1LCByZXNlbGVjdGluZyIsCgkJICAgICAgSVBfVlNfREJHX0FERFIoZGVzdC0+YWYsICZkZXN0LT5hZGRyKSwgbnRvaHMoZGVzdC0+cG9ydCkpOwoKCS8qIElmIHRoZSBvcmlnaW5hbCBkZXN0IGlzIHVuYXZhaWxhYmxlLCBsb29wIGFyb3VuZCB0aGUgdGFibGUKCSAqIHN0YXJ0aW5nIGZyb20gaWhhc2ggdG8gZmluZCBhIG5ldyBkZXN0CgkgKi8KCWZvciAob2Zmc2V0ID0gMDsgb2Zmc2V0IDwgSVBfVlNfTUhfVEFCX1NJWkU7IG9mZnNldCsrKSB7CgkJcm9mZnNldCA9IChvZmZzZXQgKyBpaGFzaCkgJSBJUF9WU19NSF9UQUJfU0laRTsKCQloYXNoID0gaXBfdnNfbWhfaGFzaGtleShzdmMtPmFmLCBhZGRyLCBwb3J0LCAmcy0+aGFzaDEsCgkJCQkJcm9mZnNldCkgJSBJUF9WU19NSF9UQUJfU0laRTsKCQlkZXN0ID0gcmN1X2RlcmVmZXJlbmNlKHMtPmxvb2t1cFtoYXNoXS5kZXN0KTsKCQlpZiAoIWRlc3QpCgkJCWJyZWFrOwoJCWlmICghaXNfdW5hdmFpbGFibGUoZGVzdCkpCgkJCXJldHVybiBkZXN0OwoJCUlQX1ZTX0RCR19CVUYoNiwKCQkJICAgICAgIk1IOiBzZWxlY3RlZCB1bmF2YWlsYWJsZSBzZXJ2ZXIgJXM6JXUgKG9mZnNldCAldSksIHJlc2VsZWN0aW5nIiwKCQkJICAgICAgSVBfVlNfREJHX0FERFIoZGVzdC0+YWYsICZkZXN0LT5hZGRyKSwKCQkJICAgICAgbnRvaHMoZGVzdC0+cG9ydCksIHJvZmZzZXQpOwoJfQoKCXJldHVybiBOVUxMOwp9CgovKiBBc3NpZ24gYWxsIHRoZSBoYXNoIGJ1Y2tldHMgb2YgdGhlIHNwZWNpZmllZCB0YWJsZSB3aXRoIHRoZSBzZXJ2aWNlLiAqLwpzdGF0aWMgaW50IGlwX3ZzX21oX3JlYXNzaWduKHN0cnVjdCBpcF92c19taF9zdGF0ZSAqcywKCQkJICAgICBzdHJ1Y3QgaXBfdnNfc2VydmljZSAqc3ZjKQp7CglpbnQgcmV0OwoKCWlmIChzdmMtPm51bV9kZXN0cyA+IElQX1ZTX01IX1RBQl9TSVpFKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChzdmMtPm51bV9kZXN0cyA+PSAxKSB7CgkJcy0+ZGVzdF9zZXR1cCA9IGtjYWxsb2Moc3ZjLT5udW1fZGVzdHMsCgkJCQkJc2l6ZW9mKHN0cnVjdCBpcF92c19taF9kZXN0X3NldHVwKSwKCQkJCQlHRlBfS0VSTkVMKTsKCQlpZiAoIXMtPmRlc3Rfc2V0dXApCgkJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlwX3ZzX21oX3Blcm11dGF0ZShzLCBzdmMpOwoKCXJldCA9IGlwX3ZzX21oX3BvcHVsYXRlKHMsIHN2Yyk7CglpZiAocmV0IDwgMCkKCQlnb3RvIG91dDsKCglJUF9WU19EQkdfQlVGKDYsICJNSDogcmVhc3NpZ24gbG9va3VwIHRhYmxlIG9mICVzOiV1XG4iLAoJCSAgICAgIElQX1ZTX0RCR19BRERSKHN2Yy0+YWYsICZzdmMtPmFkZHIpLAoJCSAgICAgIG50b2hzKHN2Yy0+cG9ydCkpOwoKb3V0OgoJaWYgKHN2Yy0+bnVtX2Rlc3RzID49IDEpIHsKCQlrZnJlZShzLT5kZXN0X3NldHVwKTsKCQlzLT5kZXN0X3NldHVwID0gTlVMTDsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgaXBfdnNfbWhfZ2NkX3dlaWdodChzdHJ1Y3QgaXBfdnNfc2VydmljZSAqc3ZjKQp7CglzdHJ1Y3QgaXBfdnNfZGVzdCAqZGVzdDsKCWludCB3ZWlnaHQ7CglpbnQgZyA9IDA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShkZXN0LCAmc3ZjLT5kZXN0aW5hdGlvbnMsIG5fbGlzdCkgewoJCXdlaWdodCA9IGF0b21pY19yZWFkKCZkZXN0LT5sYXN0X3dlaWdodCk7CgkJaWYgKHdlaWdodCA+IDApIHsKCQkJaWYgKGcgPiAwKQoJCQkJZyA9IGdjZCh3ZWlnaHQsIGcpOwoJCQllbHNlCgkJCQlnID0gd2VpZ2h0OwoJCX0KCX0KCXJldHVybiBnOwp9CgovKiBUbyBhdm9pZCBhc3NpZ25pbmcgaHVnZSB3ZWlnaHQgZm9yIHRoZSBNSCB0YWJsZSwKICogY2FsY3VsYXRlIHNoaWZ0IHZhbHVlIHdpdGggZ2NkLgogKi8Kc3RhdGljIGludCBpcF92c19taF9zaGlmdF93ZWlnaHQoc3RydWN0IGlwX3ZzX3NlcnZpY2UgKnN2YywgaW50IGdjZCkKewoJc3RydWN0IGlwX3ZzX2Rlc3QgKmRlc3Q7CglpbnQgbmV3X3dlaWdodCwgd2VpZ2h0ID0gMDsKCWludCBtdywgc2hpZnQ7CgoJLyogSWYgZ2NkIGlzIHNtYWxsZXIgdGhlbiAxLCBudW1iZXIgb2YgZGVzdHMgb3IKCSAqIGFsbCBsYXN0X3dlaWdodCBvZiBkZXN0cyBhcmUgemVyby4gU28sIHJldHVybgoJICogc2hpZnQgdmFsdWUgYXMgemVyby4KCSAqLwoJaWYgKGdjZCA8IDEpCgkJcmV0dXJuIDA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShkZXN0LCAmc3ZjLT5kZXN0aW5hdGlvbnMsIG5fbGlzdCkgewoJCW5ld193ZWlnaHQgPSBhdG9taWNfcmVhZCgmZGVzdC0+bGFzdF93ZWlnaHQpOwoJCWlmIChuZXdfd2VpZ2h0ID4gd2VpZ2h0KQoJCQl3ZWlnaHQgPSBuZXdfd2VpZ2h0OwoJfQoKCS8qIEJlY2F1c2UgZ2NkIGlzIGdyZWF0ZXIgdGhhbiB6ZXJvLAoJICogdGhlIG1heGltdW0gd2VpZ2h0IGFuZCBnY2QgYXJlIGFsd2F5cyBncmVhdGVyIHRoYW4gemVybwoJICovCgltdyA9IHdlaWdodCAvIGdjZDsKCgkvKiBzaGlmdCA9IG9jY3VwaWVkIGJpdHMgb2Ygd2VpZ2h0L2djZCAtIE1IIGhpZ2hlc3QgYml0cyAqLwoJc2hpZnQgPSBmbHMobXcpIC0gSVBfVlNfTUhfVEFCX0JJVFM7CglyZXR1cm4gKHNoaWZ0ID49IDApID8gc2hpZnQgOiAwOwp9CgpzdGF0aWMgdm9pZCBpcF92c19taF9zdGF0ZV9mcmVlKHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzOwoKCXMgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IGlwX3ZzX21oX3N0YXRlLCByY3VfaGVhZCk7CglrZnJlZShzLT5sb29rdXApOwoJa2ZyZWUocyk7Cn0KCnN0YXRpYyBpbnQgaXBfdnNfbWhfaW5pdF9zdmMoc3RydWN0IGlwX3ZzX3NlcnZpY2UgKnN2YykKewoJaW50IHJldDsKCXN0cnVjdCBpcF92c19taF9zdGF0ZSAqczsKCgkvKiBBbGxvY2F0ZSB0aGUgTUggdGFibGUgZm9yIHRoaXMgc2VydmljZSAqLwoJcyA9IGt6YWxsb2Moc2l6ZW9mKCpzKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXMpCgkJcmV0dXJuIC1FTk9NRU07CgoJcy0+bG9va3VwID0ga2NhbGxvYyhJUF9WU19NSF9UQUJfU0laRSwgc2l6ZW9mKHN0cnVjdCBpcF92c19taF9sb29rdXApLAoJCQkgICAgR0ZQX0tFUk5FTCk7CglpZiAoIXMtPmxvb2t1cCkgewoJCWtmcmVlKHMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWdlbmVyYXRlX2hhc2hfc2VjcmV0KCZzLT5oYXNoMSwgJnMtPmhhc2gyKTsKCXMtPmdjZCA9IGlwX3ZzX21oX2djZF93ZWlnaHQoc3ZjKTsKCXMtPnJzaGlmdCA9IGlwX3ZzX21oX3NoaWZ0X3dlaWdodChzdmMsIHMtPmdjZCk7CgoJSVBfVlNfREJHKDYsCgkJICAiTUggbG9va3VwIHRhYmxlIChtZW1vcnk9JXpkYnl0ZXMpIGFsbG9jYXRlZCBmb3IgY3VycmVudCBzZXJ2aWNlXG4iLAoJCSAgc2l6ZW9mKHN0cnVjdCBpcF92c19taF9sb29rdXApICogSVBfVlNfTUhfVEFCX1NJWkUpOwoKCS8qIEFzc2lnbiB0aGUgbG9va3VwIHRhYmxlIHdpdGggY3VycmVudCBkZXN0cyAqLwoJcmV0ID0gaXBfdnNfbWhfcmVhc3NpZ24ocywgc3ZjKTsKCWlmIChyZXQgPCAwKSB7CgkJaXBfdnNfbWhfcmVzZXQocyk7CgkJaXBfdnNfbWhfc3RhdGVfZnJlZSgmcy0+cmN1X2hlYWQpOwoJCXJldHVybiByZXQ7Cgl9CgoJLyogTm8gbW9yZSBmYWlsdXJlcywgYXR0YWNoIHN0YXRlICovCglzdmMtPnNjaGVkX2RhdGEgPSBzOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGlwX3ZzX21oX2RvbmVfc3ZjKHN0cnVjdCBpcF92c19zZXJ2aWNlICpzdmMpCnsKCXN0cnVjdCBpcF92c19taF9zdGF0ZSAqcyA9IHN2Yy0+c2NoZWRfZGF0YTsKCgkvKiBHb3QgdG8gY2xlYW4gdXAgbG9va3VwIGVudHJ5IGhlcmUgKi8KCWlwX3ZzX21oX3Jlc2V0KHMpOwoKCWNhbGxfcmN1KCZzLT5yY3VfaGVhZCwgaXBfdnNfbWhfc3RhdGVfZnJlZSk7CglJUF9WU19EQkcoNiwgIk1IIGxvb2t1cCB0YWJsZSAobWVtb3J5PSV6ZGJ5dGVzKSByZWxlYXNlZFxuIiwKCQkgIHNpemVvZihzdHJ1Y3QgaXBfdnNfbWhfbG9va3VwKSAqIElQX1ZTX01IX1RBQl9TSVpFKTsKfQoKc3RhdGljIGludCBpcF92c19taF9kZXN0X2NoYW5nZWQoc3RydWN0IGlwX3ZzX3NlcnZpY2UgKnN2YywKCQkJCSBzdHJ1Y3QgaXBfdnNfZGVzdCAqZGVzdCkKewoJc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzID0gc3ZjLT5zY2hlZF9kYXRhOwoKCXMtPmdjZCA9IGlwX3ZzX21oX2djZF93ZWlnaHQoc3ZjKTsKCXMtPnJzaGlmdCA9IGlwX3ZzX21oX3NoaWZ0X3dlaWdodChzdmMsIHMtPmdjZCk7CgoJLyogQXNzaWduIHRoZSBsb29rdXAgdGFibGUgd2l0aCB0aGUgdXBkYXRlZCBzZXJ2aWNlICovCglyZXR1cm4gaXBfdnNfbWhfcmVhc3NpZ24ocywgc3ZjKTsKfQoKLyogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCBwb3J0IG51bWJlciAqLwpzdGF0aWMgaW5saW5lIF9fYmUxNgppcF92c19taF9nZXRfcG9ydChjb25zdCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCBzdHJ1Y3QgaXBfdnNfaXBoZHIgKmlwaCkKewoJX19iZTE2IF9wb3J0c1syXSwgKnBvcnRzOwoKCS8qIEF0IHRoaXMgcG9pbnQgd2Uga25vdyB0aGF0IHdlIGhhdmUgYSB2YWxpZCBwYWNrZXQgb2Ygc29tZSBraW5kLgoJICogQmVjYXVzZSBJQ01QIHBhY2tldHMgYXJlIG9ubHkgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBmaXJzdCA4CgkgKiBieXRlcywgbGV0J3MganVzdCBncmFiIHRoZSBwb3J0cy4gIEZvcnR1bmF0ZWx5IHRoZXkncmUgaW4gdGhlCgkgKiBzYW1lIHBvc2l0aW9uIGZvciBhbGwgdGhyZWUgb2YgdGhlIHByb3RvY29scyB3ZSBjYXJlIGFib3V0LgoJICovCglzd2l0Y2ggKGlwaC0+cHJvdG9jb2wpIHsKCWNhc2UgSVBQUk9UT19UQ1A6CgljYXNlIElQUFJPVE9fVURQOgoJY2FzZSBJUFBST1RPX1NDVFA6CgkJcG9ydHMgPSBza2JfaGVhZGVyX3BvaW50ZXIoc2tiLCBpcGgtPmxlbiwgc2l6ZW9mKF9wb3J0cyksCgkJCQkJICAgJl9wb3J0cyk7CgkJaWYgKHVubGlrZWx5KCFwb3J0cykpCgkJCXJldHVybiAwOwoKCQlpZiAobGlrZWx5KCFpcF92c19pcGhfaW52ZXJzZShpcGgpKSkKCQkJcmV0dXJuIHBvcnRzWzBdOwoJCWVsc2UKCQkJcmV0dXJuIHBvcnRzWzFdOwoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KfQoKLyogTWFnbGV2IEhhc2hpbmcgc2NoZWR1bGluZyAqLwpzdGF0aWMgc3RydWN0IGlwX3ZzX2Rlc3QgKgppcF92c19taF9zY2hlZHVsZShzdHJ1Y3QgaXBfdnNfc2VydmljZSAqc3ZjLCBjb25zdCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCSAgc3RydWN0IGlwX3ZzX2lwaGRyICppcGgpCnsKCXN0cnVjdCBpcF92c19kZXN0ICpkZXN0OwoJc3RydWN0IGlwX3ZzX21oX3N0YXRlICpzOwoJX19iZTE2IHBvcnQgPSAwOwoJY29uc3QgdW5pb24gbmZfaW5ldF9hZGRyICpoYXNoX2FkZHI7CgoJaGFzaF9hZGRyID0gaXBfdnNfaXBoX2ludmVyc2UoaXBoKSA/ICZpcGgtPmRhZGRyIDogJmlwaC0+c2FkZHI7CgoJSVBfVlNfREJHKDYsICIlcyA6IFNjaGVkdWxpbmcuLi5cbiIsIF9fZnVuY19fKTsKCglpZiAoc3ZjLT5mbGFncyAmIElQX1ZTX1NWQ19GX1NDSEVEX01IX1BPUlQpCgkJcG9ydCA9IGlwX3ZzX21oX2dldF9wb3J0KHNrYiwgaXBoKTsKCglzID0gKHN0cnVjdCBpcF92c19taF9zdGF0ZSAqKXN2Yy0+c2NoZWRfZGF0YTsKCglpZiAoc3ZjLT5mbGFncyAmIElQX1ZTX1NWQ19GX1NDSEVEX01IX0ZBTExCQUNLKQoJCWRlc3QgPSBpcF92c19taF9nZXRfZmFsbGJhY2soc3ZjLCBzLCBoYXNoX2FkZHIsIHBvcnQpOwoJZWxzZQoJCWRlc3QgPSBpcF92c19taF9nZXQoc3ZjLCBzLCBoYXNoX2FkZHIsIHBvcnQpOwoKCWlmICghZGVzdCkgewoJCWlwX3ZzX3NjaGVkdWxlcl9lcnIoc3ZjLCAibm8gZGVzdGluYXRpb24gYXZhaWxhYmxlIik7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJSVBfVlNfREJHX0JVRig2LCAiTUg6IHNvdXJjZSBJUCBhZGRyZXNzICVzOiV1IC0tPiBzZXJ2ZXIgJXM6JXVcbiIsCgkJICAgICAgSVBfVlNfREJHX0FERFIoc3ZjLT5hZiwgaGFzaF9hZGRyKSwKCQkgICAgICBudG9ocyhwb3J0KSwKCQkgICAgICBJUF9WU19EQkdfQUREUihkZXN0LT5hZiwgJmRlc3QtPmFkZHIpLAoJCSAgICAgIG50b2hzKGRlc3QtPnBvcnQpKTsKCglyZXR1cm4gZGVzdDsKfQoKLyogSVBWUyBNSCBTY2hlZHVsZXIgc3RydWN0dXJlICovCnN0YXRpYyBzdHJ1Y3QgaXBfdnNfc2NoZWR1bGVyIGlwX3ZzX21oX3NjaGVkdWxlciA9IHsKCS5uYW1lID0JCQkibWgiLAoJLnJlZmNudCA9CQlBVE9NSUNfSU5JVCgwKSwKCS5tb2R1bGUgPQkJVEhJU19NT0RVTEUsCgkubl9saXN0CSA9CQlMSVNUX0hFQURfSU5JVChpcF92c19taF9zY2hlZHVsZXIubl9saXN0KSwKCS5pbml0X3NlcnZpY2UgPQkJaXBfdnNfbWhfaW5pdF9zdmMsCgkuZG9uZV9zZXJ2aWNlID0JCWlwX3ZzX21oX2RvbmVfc3ZjLAoJLmFkZF9kZXN0ID0JCWlwX3ZzX21oX2Rlc3RfY2hhbmdlZCwKCS5kZWxfZGVzdCA9CQlpcF92c19taF9kZXN0X2NoYW5nZWQsCgkudXBkX2Rlc3QgPQkJaXBfdnNfbWhfZGVzdF9jaGFuZ2VkLAoJLnNjaGVkdWxlID0JCWlwX3ZzX21oX3NjaGVkdWxlLAp9OwoKc3RhdGljIGludCBfX2luaXQgaXBfdnNfbWhfaW5pdCh2b2lkKQp7CglyZXR1cm4gcmVnaXN0ZXJfaXBfdnNfc2NoZWR1bGVyKCZpcF92c19taF9zY2hlZHVsZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaXBfdnNfbWhfY2xlYW51cCh2b2lkKQp7Cgl1bnJlZ2lzdGVyX2lwX3ZzX3NjaGVkdWxlcigmaXBfdnNfbWhfc2NoZWR1bGVyKTsKCXJjdV9iYXJyaWVyKCk7Cn0KCm1vZHVsZV9pbml0KGlwX3ZzX21oX2luaXQpOwptb2R1bGVfZXhpdChpcF92c19taF9jbGVhbnVwKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJNYWdsZXYgaGFzaGluZyBpcHZzIHNjaGVkdWxlciIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIHYyIik7Ck1PRFVMRV9BVVRIT1IoIkluanUgU29uZyA8aW5qdS5zb25nQG5hdmVyY29ycC5jb20+Iik7Cg==