LyoKICogUGVyZm9ybWFuY2UgY291bnRlciBjb3JlIGNvZGUKICoKICogIENvcHlyaWdodCAoQykgMjAwOCBUaG9tYXMgR2xlaXhuZXIgPHRnbHhAbGludXRyb25peC5kZT4KICogIENvcHlyaWdodCAoQykgMjAwOC0yMDA5IFJlZCBIYXQsIEluYy4sIEluZ28gTW9sbmFyCiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAwOSBSZWQgSGF0LCBJbmMuLCBQZXRlciBaaWpsc3RyYSA8cHppamxzdHJAcmVkaGF0LmNvbT4KICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqICBGb3IgbGljZW5zaW5nIGRldGFpbHMgc2VlIGtlcm5lbC1iYXNlL0NPUFlJTkcKICovCgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9jcHUuaD4KI2luY2x1ZGUgPGxpbnV4L3NtcC5oPgojaW5jbHVkZSA8bGludXgvZmlsZS5oPgojaW5jbHVkZSA8bGludXgvcG9sbC5oPgojaW5jbHVkZSA8bGludXgvc3lzZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2RjYWNoZS5oPgojaW5jbHVkZSA8bGludXgvcGVyY3B1Lmg+CiNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KI2luY2x1ZGUgPGxpbnV4L3Ztc3RhdC5oPgojaW5jbHVkZSA8bGludXgvaGFyZGlycS5oPgojaW5jbHVkZSA8bGludXgvcmN1bGlzdC5oPgojaW5jbHVkZSA8bGludXgvdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KI2luY2x1ZGUgPGxpbnV4L2Fub25faW5vZGVzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWxfc3RhdC5oPgojaW5jbHVkZSA8bGludXgvcGVyZl9jb3VudGVyLmg+CgojaW5jbHVkZSA8YXNtL2lycV9yZWdzLmg+CgovKgogKiBFYWNoIENQVSBoYXMgYSBsaXN0IG9mIHBlciBDUFUgY291bnRlcnM6CiAqLwpERUZJTkVfUEVSX0NQVShzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCwgcGVyZl9jcHVfY29udGV4dCk7CgppbnQgcGVyZl9tYXhfY291bnRlcnMgX19yZWFkX21vc3RseSA9IDE7CnN0YXRpYyBpbnQgcGVyZl9yZXNlcnZlZF9wZXJjcHUgX19yZWFkX21vc3RseTsKc3RhdGljIGludCBwZXJmX292ZXJjb21taXQgX19yZWFkX21vc3RseSA9IDE7CgpzdGF0aWMgYXRvbWljX3QgbnJfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX21tYXBfY291bnRlcnMgX19yZWFkX21vc3RseTsKc3RhdGljIGF0b21pY190IG5yX2NvbW1fY291bnRlcnMgX19yZWFkX21vc3RseTsKCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX3ByaXYgX19yZWFkX21vc3RseTsgLyogZG8gd2UgbmVlZCB0byBiZSBwcml2aWxlZ2VkICovCmludCBzeXNjdGxfcGVyZl9jb3VudGVyX21sb2NrIF9fcmVhZF9tb3N0bHkgPSA1MTI7IC8qICdmcmVlJyBrYiBwZXIgdXNlciAqLwppbnQgc3lzY3RsX3BlcmZfY291bnRlcl9saW1pdCBfX3JlYWRfbW9zdGx5ID0gMTAwMDAwOyAvKiBtYXggTk1JcyBwZXIgc2Vjb25kICovCgpzdGF0aWMgYXRvbWljNjRfdCBwZXJmX2NvdW50ZXJfaWQ7CgovKgogKiBMb2NrIGZvciAoc3lzYWRtaW4tY29uZmlndXJhYmxlKSBjb3VudGVyIHJlc2VydmF0aW9uczoKICovCnN0YXRpYyBERUZJTkVfU1BJTkxPQ0socGVyZl9yZXNvdXJjZV9sb2NrKTsKCi8qCiAqIEFyY2hpdGVjdHVyZSBwcm92aWRlZCBBUElzIC0gd2VhayBhbGlhc2VzOgogKi8KZXh0ZXJuIF9fd2VhayBjb25zdCBzdHJ1Y3QgcG11ICpod19wZXJmX2NvdW50ZXJfaW5pdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBfX3dlYWsgaHdfcGVyZl9kaXNhYmxlKHZvaWQpCQl7IGJhcnJpZXIoKTsgfQp2b2lkIF9fd2VhayBod19wZXJmX2VuYWJsZSh2b2lkKQkJeyBiYXJyaWVyKCk7IH0KCnZvaWQgX193ZWFrIGh3X3BlcmZfY291bnRlcl9zZXR1cChpbnQgY3B1KQl7IGJhcnJpZXIoKTsgfQoKaW50IF9fd2Vhawpod19wZXJmX2dyb3VwX3NjaGVkX2luKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciwKCSAgICAgICBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJICAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LCBpbnQgY3B1KQp7CglyZXR1cm4gMDsKfQoKdm9pZCBfX3dlYWsgcGVyZl9jb3VudGVyX3ByaW50X2RlYnVnKHZvaWQpCXsgfQoKc3RhdGljIERFRklORV9QRVJfQ1BVKGludCwgZGlzYWJsZV9jb3VudCk7Cgp2b2lkIF9fcGVyZl9kaXNhYmxlKHZvaWQpCnsKCV9fZ2V0X2NwdV92YXIoZGlzYWJsZV9jb3VudCkrKzsKfQoKYm9vbCBfX3BlcmZfZW5hYmxlKHZvaWQpCnsKCXJldHVybiAhLS1fX2dldF9jcHVfdmFyKGRpc2FibGVfY291bnQpOwp9Cgp2b2lkIHBlcmZfZGlzYWJsZSh2b2lkKQp7CglfX3BlcmZfZGlzYWJsZSgpOwoJaHdfcGVyZl9kaXNhYmxlKCk7Cn0KCnZvaWQgcGVyZl9lbmFibGUodm9pZCkKewoJaWYgKF9fcGVyZl9lbmFibGUoKSkKCQlod19wZXJmX2VuYWJsZSgpOwp9CgpzdGF0aWMgdm9pZCBnZXRfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglhdG9taWNfaW5jKCZjdHgtPnJlZmNvdW50KTsKfQoKc3RhdGljIHZvaWQgZnJlZV9jdHgoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCgljdHggPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0LCByY3VfaGVhZCk7CglrZnJlZShjdHgpOwp9CgpzdGF0aWMgdm9pZCBwdXRfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmY3R4LT5yZWZjb3VudCkpIHsKCQlpZiAoY3R4LT5wYXJlbnRfY3R4KQoJCQlwdXRfY3R4KGN0eC0+cGFyZW50X2N0eCk7CgkJaWYgKGN0eC0+dGFzaykKCQkJcHV0X3Rhc2tfc3RydWN0KGN0eC0+dGFzayk7CgkJY2FsbF9yY3UoJmN0eC0+cmN1X2hlYWQsIGZyZWVfY3R4KTsKCX0KfQoKLyoKICogR2V0IHRoZSBwZXJmX2NvdW50ZXJfY29udGV4dCBmb3IgYSB0YXNrIGFuZCBsb2NrIGl0LgogKiBUaGlzIGhhcyB0byBjb3BlIHdpdGggd2l0aCB0aGUgZmFjdCB0aGF0IHVudGlsIGl0IGlzIGxvY2tlZCwKICogdGhlIGNvbnRleHQgY291bGQgZ2V0IG1vdmVkIHRvIGFub3RoZXIgdGFzay4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKgpwZXJmX2xvY2tfdGFza19jb250ZXh0KHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywgdW5zaWduZWQgbG9uZyAqZmxhZ3MpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCXJjdV9yZWFkX2xvY2soKTsKIHJldHJ5OgoJY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfY291bnRlcl9jdHhwKTsKCWlmIChjdHgpIHsKCQkvKgoJCSAqIElmIHRoaXMgY29udGV4dCBpcyBhIGNsb25lIG9mIGFub3RoZXIsIGl0IG1pZ2h0CgkJICogZ2V0IHN3YXBwZWQgZm9yIGFub3RoZXIgdW5kZXJuZWF0aCB1cyBieQoJCSAqIHBlcmZfY291bnRlcl90YXNrX3NjaGVkX291dCwgdGhvdWdoIHRoZQoJCSAqIHJjdV9yZWFkX2xvY2soKSBwcm90ZWN0cyB1cyBmcm9tIGFueSBjb250ZXh0CgkJICogZ2V0dGluZyBmcmVlZC4gIExvY2sgdGhlIGNvbnRleHQgYW5kIGNoZWNrIGlmIGl0CgkJICogZ290IHN3YXBwZWQgYmVmb3JlIHdlIGNvdWxkIGdldCB0aGUgbG9jaywgYW5kIHJldHJ5CgkJICogaWYgc28uICBJZiB3ZSBsb2NrZWQgdGhlIHJpZ2h0IGNvbnRleHQsIHRoZW4gaXQKCQkgKiBjYW4ndCBnZXQgc3dhcHBlZCBvbiB1cyBhbnkgbW9yZS4KCQkgKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCAqZmxhZ3MpOwoJCWlmIChjdHggIT0gcmN1X2RlcmVmZXJlbmNlKHRhc2stPnBlcmZfY291bnRlcl9jdHhwKSkgewoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssICpmbGFncyk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CglyZXR1cm4gY3R4Owp9CgovKgogKiBHZXQgdGhlIGNvbnRleHQgZm9yIGEgdGFzayBhbmQgaW5jcmVtZW50IGl0cyBwaW5fY291bnQgc28gaXQKICogY2FuJ3QgZ2V0IHN3YXBwZWQgdG8gYW5vdGhlciB0YXNrLiAgVGhpcyBhbHNvIGluY3JlbWVudHMgaXRzCiAqIHJlZmVyZW5jZSBjb3VudCBzbyB0aGF0IHRoZSBjb250ZXh0IGNhbid0IGdldCBmcmVlZC4KICovCnN0YXRpYyBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKnBlcmZfcGluX3Rhc2tfY29udGV4dChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2spCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgljdHggPSBwZXJmX2xvY2tfdGFza19jb250ZXh0KHRhc2ssICZmbGFncyk7CglpZiAoY3R4KSB7CgkJKytjdHgtPnBpbl9jb3VudDsKCQlnZXRfY3R4KGN0eCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgl9CglyZXR1cm4gY3R4Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3VucGluX2NvbnRleHQoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJLS1jdHgtPnBpbl9jb3VudDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmN0eC0+bG9jaywgZmxhZ3MpOwoJcHV0X2N0eChjdHgpOwp9CgovKgogKiBBZGQgYSBjb3VudGVyIGZyb20gdGhlIGxpc3RzIGZvciBpdHMgY29udGV4dC4KICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGFuZCBjdHgtPmxvY2sgaGVsZC4KICovCnN0YXRpYyB2b2lkCmxpc3RfYWRkX2NvdW50ZXIoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciA9IGNvdW50ZXItPmdyb3VwX2xlYWRlcjsKCgkvKgoJICogRGVwZW5kaW5nIG9uIHdoZXRoZXIgaXQgaXMgYSBzdGFuZGFsb25lIG9yIHNpYmxpbmcgY291bnRlciwKCSAqIGFkZCBpdCBzdHJhaWdodCB0byB0aGUgY29udGV4dCdzIGNvdW50ZXIgbGlzdCwgb3IgdG8gdGhlIGdyb3VwCgkgKiBsZWFkZXIncyBzaWJsaW5nIGxpc3Q6CgkgKi8KCWlmIChncm91cF9sZWFkZXIgPT0gY291bnRlcikKCQlsaXN0X2FkZF90YWlsKCZjb3VudGVyLT5saXN0X2VudHJ5LCAmY3R4LT5jb3VudGVyX2xpc3QpOwoJZWxzZSB7CgkJbGlzdF9hZGRfdGFpbCgmY291bnRlci0+bGlzdF9lbnRyeSwgJmdyb3VwX2xlYWRlci0+c2libGluZ19saXN0KTsKCQlncm91cF9sZWFkZXItPm5yX3NpYmxpbmdzKys7Cgl9CgoJbGlzdF9hZGRfcmN1KCZjb3VudGVyLT5ldmVudF9lbnRyeSwgJmN0eC0+ZXZlbnRfbGlzdCk7CgljdHgtPm5yX2NvdW50ZXJzKys7Cn0KCi8qCiAqIFJlbW92ZSBhIGNvdW50ZXIgZnJvbSB0aGUgbGlzdHMgZm9yIGl0cyBjb250ZXh0LgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggYW5kIGN0eC0+bG9jayBoZWxkLgogKi8Kc3RhdGljIHZvaWQKbGlzdF9kZWxfY291bnRlcihzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqc2libGluZywgKnRtcDsKCglpZiAobGlzdF9lbXB0eSgmY291bnRlci0+bGlzdF9lbnRyeSkpCgkJcmV0dXJuOwoJY3R4LT5ucl9jb3VudGVycy0tOwoKCWxpc3RfZGVsX2luaXQoJmNvdW50ZXItPmxpc3RfZW50cnkpOwoJbGlzdF9kZWxfcmN1KCZjb3VudGVyLT5ldmVudF9lbnRyeSk7CgoJaWYgKGNvdW50ZXItPmdyb3VwX2xlYWRlciAhPSBjb3VudGVyKQoJCWNvdW50ZXItPmdyb3VwX2xlYWRlci0+bnJfc2libGluZ3MtLTsKCgkvKgoJICogSWYgdGhpcyB3YXMgYSBncm91cCBjb3VudGVyIHdpdGggc2libGluZyBjb3VudGVycyB0aGVuCgkgKiB1cGdyYWRlIHRoZSBzaWJsaW5ncyB0byBzaW5nbGV0b24gY291bnRlcnMgYnkgYWRkaW5nIHRoZW0KCSAqIHRvIHRoZSBjb250ZXh0IGxpc3QgZGlyZWN0bHk6CgkgKi8KCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShzaWJsaW5nLCB0bXAsCgkJCQkgJmNvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkgewoKCQlsaXN0X21vdmVfdGFpbCgmc2libGluZy0+bGlzdF9lbnRyeSwgJmN0eC0+Y291bnRlcl9saXN0KTsKCQlzaWJsaW5nLT5ncm91cF9sZWFkZXIgPSBzaWJsaW5nOwoJfQp9CgpzdGF0aWMgdm9pZApjb3VudGVyX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCSAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwKCQkgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglpZiAoY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQlyZXR1cm47CgoJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkU7Cgljb3VudGVyLT50c3RhbXBfc3RvcHBlZCA9IGN0eC0+dGltZTsKCWNvdW50ZXItPnBtdS0+ZGlzYWJsZShjb3VudGVyKTsKCWNvdW50ZXItPm9uY3B1ID0gLTE7CgoJaWYgKCFpc19zb2Z0d2FyZV9jb3VudGVyKGNvdW50ZXIpKQoJCWNwdWN0eC0+YWN0aXZlX29uY3B1LS07CgljdHgtPm5yX2FjdGl2ZS0tOwoJaWYgKGNvdW50ZXItPmF0dHIuZXhjbHVzaXZlIHx8ICFjcHVjdHgtPmFjdGl2ZV9vbmNwdSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDA7Cn0KCnN0YXRpYyB2b2lkCmdyb3VwX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jb3VudGVyICpncm91cF9jb3VudGVyLAoJCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKGdyb3VwX2NvdW50ZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJcmV0dXJuOwoKCWNvdW50ZXJfc2NoZWRfb3V0KGdyb3VwX2NvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCgkvKgoJICogU2NoZWR1bGUgb3V0IHNpYmxpbmdzIChpZiBhbnkpOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZncm91cF9jb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpCgkJY291bnRlcl9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoKCWlmIChncm91cF9jb3VudGVyLT5hdHRyLmV4Y2x1c2l2ZSkKCQljcHVjdHgtPmV4Y2x1c2l2ZSA9IDA7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIHJlbW92ZSBhIHBlcmZvcm1hbmNlIGNvdW50ZXIKICoKICogV2UgZGlzYWJsZSB0aGUgY291bnRlciBvbiB0aGUgaGFyZHdhcmUgbGV2ZWwgZmlyc3QuIEFmdGVyIHRoYXQgd2UKICogcmVtb3ZlIGl0IGZyb20gdGhlIGNvbnRleHQgbGlzdC4KICovCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX3JlbW92ZV9mcm9tX2NvbnRleHQodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGluZm87CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCgkvKgoJICogSWYgdGhpcyBpcyBhIHRhc2sgY29udGV4dCwgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIGl0IGlzCgkgKiB0aGUgY3VycmVudCB0YXNrIGNvbnRleHQgb2YgdGhpcyBjcHUuIElmIG5vdCBpdCBoYXMgYmVlbgoJICogc2NoZWR1bGVkIG91dCBiZWZvcmUgdGhlIHNtcCBjYWxsIGFycml2ZWQuCgkgKi8KCWlmIChjdHgtPnRhc2sgJiYgY3B1Y3R4LT50YXNrX2N0eCAhPSBjdHgpCgkJcmV0dXJuOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCS8qCgkgKiBQcm90ZWN0IHRoZSBsaXN0IG9wZXJhdGlvbiBhZ2FpbnN0IE5NSSBieSBkaXNhYmxpbmcgdGhlCgkgKiBjb3VudGVycyBvbiBhIGdsb2JhbCBsZXZlbC4KCSAqLwoJcGVyZl9kaXNhYmxlKCk7CgoJY291bnRlcl9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoKCWxpc3RfZGVsX2NvdW50ZXIoY291bnRlciwgY3R4KTsKCglpZiAoIWN0eC0+dGFzaykgewoJCS8qCgkJICogQWxsb3cgbW9yZSBwZXIgdGFzayBjb3VudGVycyB3aXRoIHJlc3BlY3QgdG8gdGhlCgkJICogcmVzZXJ2YXRpb246CgkJICovCgkJY3B1Y3R4LT5tYXhfcGVydGFzayA9CgkJCW1pbihwZXJmX21heF9jb3VudGVycyAtIGN0eC0+bnJfY291bnRlcnMsCgkJCSAgICBwZXJmX21heF9jb3VudGVycyAtIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1KTsKCX0KCglwZXJmX2VuYWJsZSgpOwoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCgovKgogKiBSZW1vdmUgdGhlIGNvdW50ZXIgZnJvbSBhIHRhc2sncyAob3IgYSBDUFUncykgbGlzdCBvZiBjb3VudGVycy4KICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBjdHgtPm11dGV4IGhlbGQuCiAqCiAqIENQVSBjb3VudGVycyBhcmUgcmVtb3ZlZCB3aXRoIGEgc21wIGNhbGwuIEZvciB0YXNrIGNvdW50ZXJzIHdlIG9ubHkKICogY2FsbCB3aGVuIHRoZSB0YXNrIGlzIG9uIGEgQ1BVLgogKgogKiBJZiBjb3VudGVyLT5jdHggaXMgYSBjbG9uZWQgY29udGV4dCwgY2FsbGVycyBtdXN0IG1ha2Ugc3VyZSB0aGF0CiAqIGV2ZXJ5IHRhc2sgc3RydWN0IHRoYXQgY291bnRlci0+Y3R4LT50YXNrIGNvdWxkIHBvc3NpYmx5IHBvaW50IHRvCiAqIHJlbWFpbnMgdmFsaWQuICBUaGlzIGlzIE9LIHdoZW4gY2FsbGVkIGZyb20gcGVyZl9yZWxlYXNlIHNpbmNlCiAqIHRoYXQgb25seSBjYWxscyB1cyBvbiB0aGUgdG9wLWxldmVsIGNvbnRleHQsIHdoaWNoIGNhbid0IGJlIGEgY2xvbmUuCiAqIFdoZW4gY2FsbGVkIGZyb20gcGVyZl9jb3VudGVyX2V4aXRfdGFzaywgaXQncyBPSyBiZWNhdXNlIHRoZQogKiBjb250ZXh0IGhhcyBiZWVuIGRldGFjaGVkIGZyb20gaXRzIHRhc2suCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfcmVtb3ZlX2Zyb21fY29udGV4dChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIFBlciBjcHUgY291bnRlcnMgYXJlIHJlbW92ZWQgdmlhIGFuIHNtcCBjYWxsIGFuZAoJCSAqIHRoZSByZW1vdmFsIGlzIGFsd2F5cyBzdWNlc3NmdWwuCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNvdW50ZXItPmNwdSwKCQkJCQkgX19wZXJmX2NvdW50ZXJfcmVtb3ZlX2Zyb21fY29udGV4dCwKCQkJCQkgY291bnRlciwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2NvdW50ZXJfcmVtb3ZlX2Zyb21fY29udGV4dCwKCQkJCSBjb3VudGVyKTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIElmIHRoZSBjb250ZXh0IGlzIGFjdGl2ZSB3ZSBuZWVkIHRvIHJldHJ5IHRoZSBzbXAgY2FsbC4KCSAqLwoJaWYgKGN0eC0+bnJfYWN0aXZlICYmICFsaXN0X2VtcHR5KCZjb3VudGVyLT5saXN0X2VudHJ5KSkgewoJCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCQlnb3RvIHJldHJ5OwoJfQoKCS8qCgkgKiBUaGUgbG9jayBwcmV2ZW50cyB0aGF0IHRoaXMgY29udGV4dCBpcyBzY2hlZHVsZWQgaW4gc28gd2UKCSAqIGNhbiByZW1vdmUgdGhlIGNvdW50ZXIgc2FmZWx5LCBpZiB0aGUgY2FsbCBhYm92ZSBkaWQgbm90CgkgKiBzdWNjZWVkLgoJICovCglpZiAoIWxpc3RfZW1wdHkoJmNvdW50ZXItPmxpc3RfZW50cnkpKSB7CgkJbGlzdF9kZWxfY291bnRlcihjb3VudGVyLCBjdHgpOwoJfQoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW5saW5lIHU2NCBwZXJmX2Nsb2NrKHZvaWQpCnsKCXJldHVybiBjcHVfY2xvY2soc21wX3Byb2Nlc3Nvcl9pZCgpKTsKfQoKLyoKICogVXBkYXRlIHRoZSByZWNvcmQgb2YgdGhlIGN1cnJlbnQgdGltZSBpbiBhIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfY29udGV4dF90aW1lKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7Cgl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoKCWN0eC0+dGltZSArPSBub3cgLSBjdHgtPnRpbWVzdGFtcDsKCWN0eC0+dGltZXN0YW1wID0gbm93Owp9CgovKgogKiBVcGRhdGUgdGhlIHRvdGFsX3RpbWVfZW5hYmxlZCBhbmQgdG90YWxfdGltZV9ydW5uaW5nIGZpZWxkcyBmb3IgYSBjb3VudGVyLgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2NvdW50ZXJfdGltZXMoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7Cgl1NjQgcnVuX2VuZDsKCglpZiAoY291bnRlci0+c3RhdGUgPCBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJcmV0dXJuOwoKCWNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCA9IGN0eC0+dGltZSAtIGNvdW50ZXItPnRzdGFtcF9lbmFibGVkOwoKCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpCgkJcnVuX2VuZCA9IGNvdW50ZXItPnRzdGFtcF9zdG9wcGVkOwoJZWxzZQoJCXJ1bl9lbmQgPSBjdHgtPnRpbWU7CgoJY291bnRlci0+dG90YWxfdGltZV9ydW5uaW5nID0gcnVuX2VuZCAtIGNvdW50ZXItPnRzdGFtcF9ydW5uaW5nOwp9CgovKgogKiBVcGRhdGUgdG90YWxfdGltZV9lbmFibGVkIGFuZCB0b3RhbF90aW1lX3J1bm5pbmcgZm9yIGFsbCBjb3VudGVycyBpbiBhIGdyb3VwLgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2dyb3VwX3RpbWVzKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlcikKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCgl1cGRhdGVfY291bnRlcl90aW1lcyhsZWFkZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpCgkJdXBkYXRlX2NvdW50ZXJfdGltZXMoY291bnRlcik7Cn0KCi8qCiAqIENyb3NzIENQVSBjYWxsIHRvIGRpc2FibGUgYSBwZXJmb3JtYW5jZSBjb3VudGVyCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl9kaXNhYmxlKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBpbmZvOwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSBwZXItdGFzayBjb3VudGVyLCBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhpcwoJICogY291bnRlcidzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkKCQlyZXR1cm47CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoKCS8qCgkgKiBJZiB0aGUgY291bnRlciBpcyBvbiwgdHVybiBpdCBvZmYuCgkgKiBJZiBpdCBpcyBpbiBlcnJvciBzdGF0ZSwgbGVhdmUgaXQgaW4gZXJyb3Igc3RhdGUuCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA+PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgkJdXBkYXRlX2NvdW50ZXJfdGltZXMoY291bnRlcik7CgkJaWYgKGNvdW50ZXIgPT0gY291bnRlci0+Z3JvdXBfbGVhZGVyKQoJCQlncm91cF9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoJCWVsc2UKCQkJY291bnRlcl9zY2hlZF9vdXQoY291bnRlciwgY3B1Y3R4LCBjdHgpOwoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRjsKCX0KCglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogRGlzYWJsZSBhIGNvdW50ZXIuCiAqCiAqIElmIGNvdW50ZXItPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBjb3VudGVyLT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzaWZlZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZCBvciBwZXJmX2NvdW50ZXJfZm9yX2VhY2ggYmVjYXVzZSB0aGV5CiAqIGhvbGQgdGhlIHRvcC1sZXZlbCBjb3VudGVyJ3MgY2hpbGRfbXV0ZXgsIHNvIGFueSBkZXNjZW5kYW50IHRoYXQKICogZ29lcyB0byBleGl0IHdpbGwgYmxvY2sgaW4gc3luY19jaGlsZF9jb3VudGVyLgogKiBXaGVuIGNhbGxlZCBmcm9tIHBlcmZfcGVuZGluZ19jb3VudGVyIGl0J3MgT0sgYmVjYXVzZSBjb3VudGVyLT5jdHgKICogaXMgdGhlIGN1cnJlbnQgY29udGV4dCBvbiB0aGlzIENQVSBhbmQgcHJlZW1wdGlvbiBpcyBkaXNhYmxlZCwKICogaGVuY2Ugd2UgY2FuJ3QgZ2V0IGludG8gcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfb3V0IGZvciB0aGlzIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGN0eC0+dGFzazsKCglpZiAoIXRhc2spIHsKCQkvKgoJCSAqIERpc2FibGUgdGhlIGNvdW50ZXIgb24gdGhlIGNwdSB0aGF0IGl0J3Mgb24KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY291bnRlci0+Y3B1LCBfX3BlcmZfY291bnRlcl9kaXNhYmxlLAoJCQkJCSBjb3VudGVyLCAxKTsKCQlyZXR1cm47Cgl9CgogcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2NvdW50ZXJfZGlzYWJsZSwgY291bnRlcik7CgoJc3Bpbl9sb2NrX2lycSgmY3R4LT5sb2NrKTsKCS8qCgkgKiBJZiB0aGUgY291bnRlciBpcyBzdGlsbCBhY3RpdmUsIHdlIG5lZWQgdG8gcmV0cnkgdGhlIGNyb3NzLWNhbGwuCgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKSB7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoJCWdvdG8gcmV0cnk7Cgl9CgoJLyoKCSAqIFNpbmNlIHdlIGhhdmUgdGhlIGxvY2sgdGhpcyBjb250ZXh0IGNhbid0IGJlIHNjaGVkdWxlZAoJICogaW4sIHNvIHdlIGNhbiBjaGFuZ2UgdGhlIHN0YXRlIHNhZmVseS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkgewoJCXVwZGF0ZV9jb3VudGVyX3RpbWVzKGNvdW50ZXIpOwoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRjsKCX0KCglzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7Cn0KCnN0YXRpYyBpbnQKY291bnRlcl9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCSBzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LAoJCSBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkgaW50IGNwdSkKewoJaWYgKGNvdW50ZXItPnN0YXRlIDw9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYpCgkJcmV0dXJuIDA7CgoJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFOwoJY291bnRlci0+b25jcHUgPSBjcHU7CS8qIFRPRE86IHB1dCAnY3B1JyBpbnRvIGNwdWN0eC0+Y3B1ICovCgkvKgoJICogVGhlIG5ldyBzdGF0ZSBtdXN0IGJlIHZpc2libGUgYmVmb3JlIHdlIHR1cm4gaXQgb24gaW4gdGhlIGhhcmR3YXJlOgoJICovCglzbXBfd21iKCk7CgoJaWYgKGNvdW50ZXItPnBtdS0+ZW5hYmxlKGNvdW50ZXIpKSB7CgkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkU7CgkJY291bnRlci0+b25jcHUgPSAtMTsKCQlyZXR1cm4gLUVBR0FJTjsKCX0KCgljb3VudGVyLT50c3RhbXBfcnVubmluZyArPSBjdHgtPnRpbWUgLSBjb3VudGVyLT50c3RhbXBfc3RvcHBlZDsKCglpZiAoIWlzX3NvZnR3YXJlX2NvdW50ZXIoY291bnRlcikpCgkJY3B1Y3R4LT5hY3RpdmVfb25jcHUrKzsKCWN0eC0+bnJfYWN0aXZlKys7CgoJaWYgKGNvdW50ZXItPmF0dHIuZXhjbHVzaXZlKQoJCWNwdWN0eC0+ZXhjbHVzaXZlID0gMTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludApncm91cF9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jb3VudGVyICpncm91cF9jb3VudGVyLAoJICAgICAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkgICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkgICAgICAgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgKnBhcnRpYWxfZ3JvdXA7CglpbnQgcmV0OwoKCWlmIChncm91cF9jb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGKQoJCXJldHVybiAwOwoKCXJldCA9IGh3X3BlcmZfZ3JvdXBfc2NoZWRfaW4oZ3JvdXBfY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSk7CglpZiAocmV0KQoJCXJldHVybiByZXQgPCAwID8gcmV0IDogMDsKCglpZiAoY291bnRlcl9zY2hlZF9pbihncm91cF9jb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KSkKCQlyZXR1cm4gLUVBR0FJTjsKCgkvKgoJICogU2NoZWR1bGUgaW4gc2libGluZ3MgYXMgb25lIGdyb3VwIChpZiBhbnkpOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZncm91cF9jb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlpZiAoY291bnRlcl9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KSkgewoJCQlwYXJ0aWFsX2dyb3VwID0gY291bnRlcjsKCQkJZ290byBncm91cF9lcnJvcjsKCQl9Cgl9CgoJcmV0dXJuIDA7Cgpncm91cF9lcnJvcjoKCS8qCgkgKiBHcm91cHMgY2FuIGJlIHNjaGVkdWxlZCBpbiBhcyBvbmUgdW5pdCBvbmx5LCBzbyB1bmRvIGFueQoJICogcGFydGlhbCBncm91cCBiZWZvcmUgcmV0dXJuaW5nOgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZncm91cF9jb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpIHsKCQlpZiAoY291bnRlciA9PSBwYXJ0aWFsX2dyb3VwKQoJCQlicmVhazsKCQljb3VudGVyX3NjaGVkX291dChjb3VudGVyLCBjcHVjdHgsIGN0eCk7Cgl9Cgljb3VudGVyX3NjaGVkX291dChncm91cF9jb3VudGVyLCBjcHVjdHgsIGN0eCk7CgoJcmV0dXJuIC1FQUdBSU47Cn0KCi8qCiAqIFJldHVybiAxIGZvciBhIGdyb3VwIGNvbnNpc3RpbmcgZW50aXJlbHkgb2Ygc29mdHdhcmUgY291bnRlcnMsCiAqIDAgaWYgdGhlIGdyb3VwIGNvbnRhaW5zIGFueSBoYXJkd2FyZSBjb3VudGVycy4KICovCnN0YXRpYyBpbnQgaXNfc29mdHdhcmVfb25seV9ncm91cChzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKCFpc19zb2Z0d2FyZV9jb3VudGVyKGxlYWRlcikpCgkJcmV0dXJuIDA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShjb3VudGVyLCAmbGVhZGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpCgkJaWYgKCFpc19zb2Z0d2FyZV9jb3VudGVyKGNvdW50ZXIpKQoJCQlyZXR1cm4gMDsKCglyZXR1cm4gMTsKfQoKLyoKICogV29yayBvdXQgd2hldGhlciB3ZSBjYW4gcHV0IHRoaXMgY291bnRlciBncm91cCBvbiB0aGUgQ1BVIG5vdy4KICovCnN0YXRpYyBpbnQgZ3JvdXBfY2FuX2dvX29uKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCSAgIHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgsCgkJCSAgIGludCBjYW5fYWRkX2h3KQp7CgkvKgoJICogR3JvdXBzIGNvbnNpc3RpbmcgZW50aXJlbHkgb2Ygc29mdHdhcmUgY291bnRlcnMgY2FuIGFsd2F5cyBnbyBvbi4KCSAqLwoJaWYgKGlzX3NvZnR3YXJlX29ubHlfZ3JvdXAoY291bnRlcikpCgkJcmV0dXJuIDE7CgkvKgoJICogSWYgYW4gZXhjbHVzaXZlIGdyb3VwIGlzIGFscmVhZHkgb24sIG5vIG90aGVyIGhhcmR3YXJlCgkgKiBjb3VudGVycyBjYW4gZ28gb24uCgkgKi8KCWlmIChjcHVjdHgtPmV4Y2x1c2l2ZSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBJZiB0aGlzIGdyb3VwIGlzIGV4Y2x1c2l2ZSBhbmQgdGhlcmUgYXJlIGFscmVhZHkKCSAqIGNvdW50ZXJzIG9uIHRoZSBDUFUsIGl0IGNhbid0IGdvIG9uLgoJICovCglpZiAoY291bnRlci0+YXR0ci5leGNsdXNpdmUgJiYgY3B1Y3R4LT5hY3RpdmVfb25jcHUpCgkJcmV0dXJuIDA7CgkvKgoJICogT3RoZXJ3aXNlLCB0cnkgdG8gYWRkIGl0IGlmIGFsbCBwcmV2aW91cyBncm91cHMgd2VyZSBhYmxlCgkgKiB0byBnbyBvbi4KCSAqLwoJcmV0dXJuIGNhbl9hZGRfaHc7Cn0KCnN0YXRpYyB2b2lkIGFkZF9jb3VudGVyX3RvX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkgICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgpCnsKCWxpc3RfYWRkX2NvdW50ZXIoY291bnRlciwgY3R4KTsKCWNvdW50ZXItPnRzdGFtcF9lbmFibGVkID0gY3R4LT50aW1lOwoJY291bnRlci0+dHN0YW1wX3J1bm5pbmcgPSBjdHgtPnRpbWU7Cgljb3VudGVyLT50c3RhbXBfc3RvcHBlZCA9IGN0eC0+dGltZTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIGEgcGVyZm9ybWFuY2UgY291bnRlcgogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZAogKi8Kc3RhdGljIHZvaWQgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCh2b2lkICppbmZvKQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaW5mbzsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJc3RydWN0IHBlcmZfY291bnRlciAqbGVhZGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoJaW50IGNwdSA9IHNtcF9wcm9jZXNzb3JfaWQoKTsKCWludCBlcnI7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSB0YXNrIGNvbnRleHQsIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciBpdCBpcwoJICogdGhlIGN1cnJlbnQgdGFzayBjb250ZXh0IG9mIHRoaXMgY3B1LiBJZiBub3QgaXQgaGFzIGJlZW4KCSAqIHNjaGVkdWxlZCBvdXQgYmVmb3JlIHRoZSBzbXAgY2FsbCBhcnJpdmVkLgoJICogT3IgcG9zc2libHkgdGhpcyBpcyB0aGUgcmlnaHQgY29udGV4dCBidXQgaXQgaXNuJ3QKCSAqIG9uIHRoaXMgY3B1IGJlY2F1c2UgaXQgaGFkIG5vIGNvdW50ZXJzLgoJICovCglpZiAoY3R4LT50YXNrICYmIGNwdWN0eC0+dGFza19jdHggIT0gY3R4KSB7CgkJaWYgKGNwdWN0eC0+dGFza19jdHggfHwgY3R4LT50YXNrICE9IGN1cnJlbnQpCgkJCXJldHVybjsKCQljcHVjdHgtPnRhc2tfY3R4ID0gY3R4OwoJfQoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWN0eC0+aXNfYWN0aXZlID0gMTsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCgkvKgoJICogUHJvdGVjdCB0aGUgbGlzdCBvcGVyYXRpb24gYWdhaW5zdCBOTUkgYnkgZGlzYWJsaW5nIHRoZQoJICogY291bnRlcnMgb24gYSBnbG9iYWwgbGV2ZWwuIE5PUCBmb3Igbm9uIE5NSSBiYXNlZCBjb3VudGVycy4KCSAqLwoJcGVyZl9kaXNhYmxlKCk7CgoJYWRkX2NvdW50ZXJfdG9fY3R4KGNvdW50ZXIsIGN0eCk7CgoJLyoKCSAqIERvbid0IHB1dCB0aGUgY291bnRlciBvbiBpZiBpdCBpcyBkaXNhYmxlZCBvciBpZgoJICogaXQgaXMgaW4gYSBncm91cCBhbmQgdGhlIGdyb3VwIGlzbid0IG9uLgoJICovCglpZiAoY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFIHx8CgkgICAgKGxlYWRlciAhPSBjb3VudGVyICYmIGxlYWRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkpCgkJZ290byB1bmxvY2s7CgoJLyoKCSAqIEFuIGV4Y2x1c2l2ZSBjb3VudGVyIGNhbid0IGdvIG9uIGlmIHRoZXJlIGFyZSBhbHJlYWR5IGFjdGl2ZQoJICogaGFyZHdhcmUgY291bnRlcnMsIGFuZCBubyBoYXJkd2FyZSBjb3VudGVyIGNhbiBnbyBvbiBpZiB0aGVyZQoJICogaXMgYWxyZWFkeSBhbiBleGNsdXNpdmUgY291bnRlciBvbi4KCSAqLwoJaWYgKCFncm91cF9jYW5fZ29fb24oY291bnRlciwgY3B1Y3R4LCAxKSkKCQllcnIgPSAtRUVYSVNUOwoJZWxzZQoJCWVyciA9IGNvdW50ZXJfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsIGNwdSk7CgoJaWYgKGVycikgewoJCS8qCgkJICogVGhpcyBjb3VudGVyIGNvdWxkbid0IGdvIG9uLiAgSWYgaXQgaXMgaW4gYSBncm91cAoJCSAqIHRoZW4gd2UgaGF2ZSB0byBwdWxsIHRoZSB3aG9sZSBncm91cCBvZmYuCgkJICogSWYgdGhlIGNvdW50ZXIgZ3JvdXAgaXMgcGlubmVkIHRoZW4gcHV0IGl0IGluIGVycm9yIHN0YXRlLgoJCSAqLwoJCWlmIChsZWFkZXIgIT0gY291bnRlcikKCQkJZ3JvdXBfc2NoZWRfb3V0KGxlYWRlciwgY3B1Y3R4LCBjdHgpOwoJCWlmIChsZWFkZXItPmF0dHIucGlubmVkKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhsZWFkZXIpOwoJCQlsZWFkZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0VSUk9SOwoJCX0KCX0KCglpZiAoIWVyciAmJiAhY3R4LT50YXNrICYmIGNwdWN0eC0+bWF4X3BlcnRhc2spCgkJY3B1Y3R4LT5tYXhfcGVydGFzay0tOwoKIHVubG9jazoKCXBlcmZfZW5hYmxlKCk7CgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEF0dGFjaCBhIHBlcmZvcm1hbmNlIGNvdW50ZXIgdG8gYSBjb250ZXh0CiAqCiAqIEZpcnN0IHdlIGFkZCB0aGUgY291bnRlciB0byB0aGUgbGlzdCB3aXRoIHRoZSBoYXJkd2FyZSBlbmFibGUgYml0CiAqIGluIGNvdW50ZXItPmh3X2NvbmZpZyBjbGVhcmVkLgogKgogKiBJZiB0aGUgY291bnRlciBpcyBhdHRhY2hlZCB0byBhIHRhc2sgd2hpY2ggaXMgb24gYSBDUFUgd2UgdXNlIGEgc21wCiAqIGNhbGwgdG8gZW5hYmxlIGl0IGluIHRoZSB0YXNrIGNvbnRleHQuIFRoZSB0YXNrIG1pZ2h0IGhhdmUgYmVlbgogKiBzY2hlZHVsZWQgYXdheSwgYnV0IHdlIGNoZWNrIHRoaXMgaW4gdGhlIHNtcCBjYWxsIGFnYWluLgogKgogKiBNdXN0IGJlIGNhbGxlZCB3aXRoIGN0eC0+bXV0ZXggaGVsZC4KICovCnN0YXRpYyB2b2lkCnBlcmZfaW5zdGFsbF9pbl9jb250ZXh0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQlzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQlpbnQgY3B1KQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBQZXIgY3B1IGNvdW50ZXJzIGFyZSBpbnN0YWxsZWQgdmlhIGFuIHNtcCBjYWxsIGFuZAoJCSAqIHRoZSBpbnN0YWxsIGlzIGFsd2F5cyBzdWNlc3NmdWwuCgkJICovCgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCwKCQkJCQkgY291bnRlciwgMSk7CgkJcmV0dXJuOwoJfQoKcmV0cnk6Cgl0YXNrX29uY3B1X2Z1bmN0aW9uX2NhbGwodGFzaywgX19wZXJmX2luc3RhbGxfaW5fY29udGV4dCwKCQkJCSBjb3VudGVyKTsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJLyoKCSAqIHdlIG5lZWQgdG8gcmV0cnkgdGhlIHNtcCBjYWxsLgoJICovCglpZiAoY3R4LT5pc19hY3RpdmUgJiYgbGlzdF9lbXB0eSgmY291bnRlci0+bGlzdF9lbnRyeSkpIHsKCQlzcGluX3VubG9ja19pcnEoJmN0eC0+bG9jayk7CgkJZ290byByZXRyeTsKCX0KCgkvKgoJICogVGhlIGxvY2sgcHJldmVudHMgdGhhdCB0aGlzIGNvbnRleHQgaXMgc2NoZWR1bGVkIGluIHNvIHdlCgkgKiBjYW4gYWRkIHRoZSBjb3VudGVyIHNhZmVseSwgaWYgaXQgdGhlIGNhbGwgYWJvdmUgZGlkIG5vdAoJICogc3VjY2VlZC4KCSAqLwoJaWYgKGxpc3RfZW1wdHkoJmNvdW50ZXItPmxpc3RfZW50cnkpKQoJCWFkZF9jb3VudGVyX3RvX2N0eChjb3VudGVyLCBjdHgpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgovKgogKiBDcm9zcyBDUFUgY2FsbCB0byBlbmFibGUgYSBwZXJmb3JtYW5jZSBjb3VudGVyCiAqLwpzdGF0aWMgdm9pZCBfX3BlcmZfY291bnRlcl9lbmFibGUodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGluZm87CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IGNvdW50ZXItPmN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmxlYWRlciA9IGNvdW50ZXItPmdyb3VwX2xlYWRlcjsKCWludCBlcnI7CgoJLyoKCSAqIElmIHRoaXMgaXMgYSBwZXItdGFzayBjb3VudGVyLCBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhpcwoJICogY291bnRlcidzIHRhc2sgaXMgdGhlIGN1cnJlbnQgdGFzayBvbiB0aGlzIGNwdS4KCSAqLwoJaWYgKGN0eC0+dGFzayAmJiBjcHVjdHgtPnRhc2tfY3R4ICE9IGN0eCkgewoJCWlmIChjcHVjdHgtPnRhc2tfY3R4IHx8IGN0eC0+dGFzayAhPSBjdXJyZW50KQoJCQlyZXR1cm47CgkJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKCX0KCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7Cgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJaWYgKGNvdW50ZXItPnN0YXRlID49IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQlnb3RvIHVubG9jazsKCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOwoJY291bnRlci0+dHN0YW1wX2VuYWJsZWQgPSBjdHgtPnRpbWUgLSBjb3VudGVyLT50b3RhbF90aW1lX2VuYWJsZWQ7CgoJLyoKCSAqIElmIHRoZSBjb3VudGVyIGlzIGluIGEgZ3JvdXAgYW5kIGlzbid0IHRoZSBncm91cCBsZWFkZXIsCgkgKiB0aGVuIGRvbid0IHB1dCBpdCBvbiB1bmxlc3MgdGhlIGdyb3VwIGlzIG9uLgoJICovCglpZiAobGVhZGVyICE9IGNvdW50ZXIgJiYgbGVhZGVyLT5zdGF0ZSAhPSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKQoJCWdvdG8gdW5sb2NrOwoKCWlmICghZ3JvdXBfY2FuX2dvX29uKGNvdW50ZXIsIGNwdWN0eCwgMSkpIHsKCQllcnIgPSAtRUVYSVNUOwoJfSBlbHNlIHsKCQlwZXJmX2Rpc2FibGUoKTsKCQlpZiAoY291bnRlciA9PSBsZWFkZXIpCgkJCWVyciA9IGdyb3VwX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LAoJCQkJCSAgICAgc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCQllbHNlCgkJCWVyciA9IGNvdW50ZXJfc2NoZWRfaW4oY291bnRlciwgY3B1Y3R4LCBjdHgsCgkJCQkJICAgICAgIHNtcF9wcm9jZXNzb3JfaWQoKSk7CgkJcGVyZl9lbmFibGUoKTsKCX0KCglpZiAoZXJyKSB7CgkJLyoKCQkgKiBJZiB0aGlzIGNvdW50ZXIgY2FuJ3QgZ28gb24gYW5kIGl0J3MgcGFydCBvZiBhCgkJICogZ3JvdXAsIHRoZW4gdGhlIHdob2xlIGdyb3VwIGhhcyB0byBjb21lIG9mZi4KCQkgKi8KCQlpZiAobGVhZGVyICE9IGNvdW50ZXIpCgkJCWdyb3VwX3NjaGVkX291dChsZWFkZXIsIGNwdWN0eCwgY3R4KTsKCQlpZiAobGVhZGVyLT5hdHRyLnBpbm5lZCkgewoJCQl1cGRhdGVfZ3JvdXBfdGltZXMobGVhZGVyKTsKCQkJbGVhZGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUjsKCQl9Cgl9CgogdW5sb2NrOgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIEVuYWJsZSBhIGNvdW50ZXIuCiAqCiAqIElmIGNvdW50ZXItPmN0eCBpcyBhIGNsb25lZCBjb250ZXh0LCBjYWxsZXJzIG11c3QgbWFrZSBzdXJlIHRoYXQKICogZXZlcnkgdGFzayBzdHJ1Y3QgdGhhdCBjb3VudGVyLT5jdHgtPnRhc2sgY291bGQgcG9zc2libHkgcG9pbnQgdG8KICogcmVtYWlucyB2YWxpZC4gIFRoaXMgY29uZGl0aW9uIGlzIHNhdGlzZmllZCB3aGVuIGNhbGxlZCB0aHJvdWdoCiAqIHBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZCBvciBwZXJmX2NvdW50ZXJfZm9yX2VhY2ggYXMgZGVzY3JpYmVkCiAqIGZvciBwZXJmX2NvdW50ZXJfZGlzYWJsZS4KICovCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9lbmFibGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2sgPSBjdHgtPnRhc2s7CgoJaWYgKCF0YXNrKSB7CgkJLyoKCQkgKiBFbmFibGUgdGhlIGNvdW50ZXIgb24gdGhlIGNwdSB0aGF0IGl0J3Mgb24KCQkgKi8KCQlzbXBfY2FsbF9mdW5jdGlvbl9zaW5nbGUoY291bnRlci0+Y3B1LCBfX3BlcmZfY291bnRlcl9lbmFibGUsCgkJCQkJIGNvdW50ZXIsIDEpOwoJCXJldHVybjsKCX0KCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGNvdW50ZXItPnN0YXRlID49IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQlnb3RvIG91dDsKCgkvKgoJICogSWYgdGhlIGNvdW50ZXIgaXMgaW4gZXJyb3Igc3RhdGUsIGNsZWFyIHRoYXQgZmlyc3QuCgkgKiBUaGF0IHdheSwgaWYgd2Ugc2VlIHRoZSBjb3VudGVyIGluIGVycm9yIHN0YXRlIGJlbG93LCB3ZQoJICoga25vdyB0aGF0IGl0IGhhcyBnb25lIGJhY2sgaW50byBlcnJvciBzdGF0ZSwgYXMgZGlzdGluY3QKCSAqIGZyb20gdGhlIHRhc2sgaGF2aW5nIGJlZW4gc2NoZWR1bGVkIGF3YXkgYmVmb3JlIHRoZQoJICogY3Jvc3MtY2FsbCBhcnJpdmVkLgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0VSUk9SKQoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRjsKCiByZXRyeToKCXNwaW5fdW5sb2NrX2lycSgmY3R4LT5sb2NrKTsKCXRhc2tfb25jcHVfZnVuY3Rpb25fY2FsbCh0YXNrLCBfX3BlcmZfY291bnRlcl9lbmFibGUsIGNvdW50ZXIpOwoKCXNwaW5fbG9ja19pcnEoJmN0eC0+bG9jayk7CgoJLyoKCSAqIElmIHRoZSBjb250ZXh0IGlzIGFjdGl2ZSBhbmQgdGhlIGNvdW50ZXIgaXMgc3RpbGwgb2ZmLAoJICogd2UgbmVlZCB0byByZXRyeSB0aGUgY3Jvc3MtY2FsbC4KCSAqLwoJaWYgKGN0eC0+aXNfYWN0aXZlICYmIGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYpCgkJZ290byByZXRyeTsKCgkvKgoJICogU2luY2Ugd2UgaGF2ZSB0aGUgbG9jayB0aGlzIGNvbnRleHQgY2FuJ3QgYmUgc2NoZWR1bGVkCgkgKiBpbiwgc28gd2UgY2FuIGNoYW5nZSB0aGUgc3RhdGUgc2FmZWx5LgoJICovCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRikgewoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFOwoJCWNvdW50ZXItPnRzdGFtcF9lbmFibGVkID0KCQkJY3R4LT50aW1lIC0gY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkOwoJfQogb3V0OgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9yZWZyZXNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIGludCByZWZyZXNoKQp7CgkvKgoJICogbm90IHN1cHBvcnRlZCBvbiBpbmhlcml0ZWQgY291bnRlcnMKCSAqLwoJaWYgKGNvdW50ZXItPmF0dHIuaW5oZXJpdCkKCQlyZXR1cm4gLUVJTlZBTDsKCglhdG9taWNfYWRkKHJlZnJlc2gsICZjb3VudGVyLT5ldmVudF9saW1pdCk7CglwZXJmX2NvdW50ZXJfZW5hYmxlKGNvdW50ZXIpOwoKCXJldHVybiAwOwp9Cgp2b2lkIF9fcGVyZl9jb3VudGVyX3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJICAgICAgc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDA7CglpZiAobGlrZWx5KCFjdHgtPm5yX2NvdW50ZXJzKSkKCQlnb3RvIG91dDsKCXVwZGF0ZV9jb250ZXh0X3RpbWUoY3R4KTsKCglwZXJmX2Rpc2FibGUoKTsKCWlmIChjdHgtPm5yX2FjdGl2ZSkgewoJCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJCWlmIChjb3VudGVyICE9IGNvdW50ZXItPmdyb3VwX2xlYWRlcikKCQkJCWNvdW50ZXJfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCQkJZWxzZQoJCQkJZ3JvdXBfc2NoZWRfb3V0KGNvdW50ZXIsIGNwdWN0eCwgY3R4KTsKCQl9Cgl9CglwZXJmX2VuYWJsZSgpOwogb3V0OgoJc3Bpbl91bmxvY2soJmN0eC0+bG9jayk7Cn0KCi8qCiAqIFRlc3Qgd2hldGhlciB0d28gY29udGV4dHMgYXJlIGVxdWl2YWxlbnQsIGkuZS4gd2hldGhlciB0aGV5CiAqIGhhdmUgYm90aCBiZWVuIGNsb25lZCBmcm9tIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHNhbWUgY29udGV4dAogKiBhbmQgdGhleSBib3RoIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGVuYWJsZWQgY291bnRlcnMuCiAqIElmIHRoZSBudW1iZXIgb2YgZW5hYmxlZCBjb3VudGVycyBpcyB0aGUgc2FtZSwgdGhlbiB0aGUgc2V0CiAqIG9mIGVuYWJsZWQgY291bnRlcnMgc2hvdWxkIGJlIHRoZSBzYW1lLCBiZWNhdXNlIHRoZXNlIGFyZSBib3RoCiAqIGluaGVyaXRlZCBjb250ZXh0cywgdGhlcmVmb3JlIHdlIGNhbid0IGFjY2VzcyBpbmRpdmlkdWFsIGNvdW50ZXJzCiAqIGluIHRoZW0gZGlyZWN0bHkgd2l0aCBhbiBmZDsgd2UgY2FuIG9ubHkgZW5hYmxlL2Rpc2FibGUgYWxsCiAqIGNvdW50ZXJzIHZpYSBwcmN0bCwgb3IgZW5hYmxlL2Rpc2FibGUgYWxsIGNvdW50ZXJzIGluIGEgZmFtaWx5CiAqIHZpYSBpb2N0bCwgd2hpY2ggd2lsbCBoYXZlIHRoZSBzYW1lIGVmZmVjdCBvbiBib3RoIGNvbnRleHRzLgogKi8Kc3RhdGljIGludCBjb250ZXh0X2VxdWl2KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4MSwKCQkJIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4MikKewoJcmV0dXJuIGN0eDEtPnBhcmVudF9jdHggJiYgY3R4MS0+cGFyZW50X2N0eCA9PSBjdHgyLT5wYXJlbnRfY3R4CgkJJiYgY3R4MS0+cGFyZW50X2dlbiA9PSBjdHgyLT5wYXJlbnRfZ2VuCgkJJiYgIWN0eDEtPnBpbl9jb3VudCAmJiAhY3R4Mi0+cGluX2NvdW50Owp9CgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gcmVtb3ZlIHRoZSBjb3VudGVycyBvZiB0aGUgY3VycmVudCB0YXNrLAogKiB3aXRoIGludGVycnVwdHMgZGlzYWJsZWQuCiAqCiAqIFdlIHN0b3AgZWFjaCBjb3VudGVyIGFuZCB1cGRhdGUgdGhlIGNvdW50ZXIgdmFsdWUgaW4gY291bnRlci0+Y291bnQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGRpc2FibGUoKQogKiBzZXRzIHRoZSBkaXNhYmxlZCBiaXQgaW4gdGhlIGNvbnRyb2wgZmllbGQgb2YgY291bnRlciBfYmVmb3JlXwogKiBhY2Nlc3NpbmcgdGhlIGNvdW50ZXIgY29udHJvbCByZWdpc3Rlci4gSWYgYSBOTUkgaGl0cywgdGhlbiBpdCB3aWxsCiAqIG5vdCByZXN0YXJ0IHRoZSBjb3VudGVyLgogKi8Kdm9pZCBwZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLAoJCQkJIHN0cnVjdCB0YXNrX3N0cnVjdCAqbmV4dCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfY291bnRlcl9jdHhwOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpuZXh0X2N0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqcGFyZW50OwoJc3RydWN0IHB0X3JlZ3MgKnJlZ3M7CglpbnQgZG9fc3dpdGNoID0gMTsKCglyZWdzID0gdGFza19wdF9yZWdzKHRhc2spOwoJcGVyZl9zd2NvdW50ZXJfZXZlbnQoUEVSRl9DT1VOVF9DT05URVhUX1NXSVRDSEVTLCAxLCAxLCByZWdzLCAwKTsKCglpZiAobGlrZWx5KCFjdHggfHwgIWNwdWN0eC0+dGFza19jdHgpKQoJCXJldHVybjsKCgl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7CgoJcmN1X3JlYWRfbG9jaygpOwoJcGFyZW50ID0gcmN1X2RlcmVmZXJlbmNlKGN0eC0+cGFyZW50X2N0eCk7CgluZXh0X2N0eCA9IG5leHQtPnBlcmZfY291bnRlcl9jdHhwOwoJaWYgKHBhcmVudCAmJiBuZXh0X2N0eCAmJgoJICAgIHJjdV9kZXJlZmVyZW5jZShuZXh0X2N0eC0+cGFyZW50X2N0eCkgPT0gcGFyZW50KSB7CgkJLyoKCQkgKiBMb29rcyBsaWtlIHRoZSB0d28gY29udGV4dHMgYXJlIGNsb25lcywgc28gd2UgbWlnaHQgYmUKCQkgKiBhYmxlIHRvIG9wdGltaXplIHRoZSBjb250ZXh0IHN3aXRjaC4gIFdlIGxvY2sgYm90aAoJCSAqIGNvbnRleHRzIGFuZCBjaGVjayB0aGF0IHRoZXkgYXJlIGNsb25lcyB1bmRlciB0aGUKCQkgKiBsb2NrIChpbmNsdWRpbmcgcmUtY2hlY2tpbmcgdGhhdCBuZWl0aGVyIGhhcyBiZWVuCgkJICogdW5jbG9uZWQgaW4gdGhlIG1lYW50aW1lKS4gIEl0IGRvZXNuJ3QgbWF0dGVyIHdoaWNoCgkJICogb3JkZXIgd2UgdGFrZSB0aGUgbG9ja3MgYmVjYXVzZSBubyBvdGhlciBjcHUgY291bGQKCQkgKiBiZSB0cnlpbmcgdG8gbG9jayBib3RoIG9mIHRoZXNlIHRhc2tzLgoJCSAqLwoJCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCQlzcGluX2xvY2tfbmVzdGVkKCZuZXh0X2N0eC0+bG9jaywgU0lOR0xFX0RFUFRIX05FU1RJTkcpOwoJCWlmIChjb250ZXh0X2VxdWl2KGN0eCwgbmV4dF9jdHgpKSB7CgkJCS8qCgkJCSAqIFhYWCBkbyB3ZSBuZWVkIGEgbWVtb3J5IGJhcnJpZXIgb2Ygc29ydHMKCQkJICogd3J0IHRvIHJjdV9kZXJlZmVyZW5jZSgpIG9mIHBlcmZfY291bnRlcl9jdHhwCgkJCSAqLwoJCQl0YXNrLT5wZXJmX2NvdW50ZXJfY3R4cCA9IG5leHRfY3R4OwoJCQluZXh0LT5wZXJmX2NvdW50ZXJfY3R4cCA9IGN0eDsKCQkJY3R4LT50YXNrID0gbmV4dDsKCQkJbmV4dF9jdHgtPnRhc2sgPSB0YXNrOwoJCQlkb19zd2l0Y2ggPSAwOwoJCX0KCQlzcGluX3VubG9jaygmbmV4dF9jdHgtPmxvY2spOwoJCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKGRvX3N3aXRjaCkgewoJCV9fcGVyZl9jb3VudGVyX3NjaGVkX291dChjdHgsIGNwdWN0eCk7CgkJY3B1Y3R4LT50YXNrX2N0eCA9IE5VTEw7Cgl9Cn0KCi8qCiAqIENhbGxlZCB3aXRoIElSUXMgZGlzYWJsZWQKICovCnN0YXRpYyB2b2lkIF9fcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfb3V0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJl9fZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CgoJaWYgKCFjcHVjdHgtPnRhc2tfY3R4KQoJCXJldHVybjsKCglpZiAoV0FSTl9PTl9PTkNFKGN0eCAhPSBjcHVjdHgtPnRhc2tfY3R4KSkKCQlyZXR1cm47CgoJX19wZXJmX2NvdW50ZXJfc2NoZWRfb3V0KGN0eCwgY3B1Y3R4KTsKCWNwdWN0eC0+dGFza19jdHggPSBOVUxMOwp9CgovKgogKiBDYWxsZWQgd2l0aCBJUlFzIGRpc2FibGVkCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfY3B1X3NjaGVkX291dChzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4KQp7CglfX3BlcmZfY291bnRlcl9zY2hlZF9vdXQoJmNwdWN0eC0+Y3R4LCBjcHVjdHgpOwp9CgpzdGF0aWMgdm9pZApfX3BlcmZfY291bnRlcl9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCwgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCWludCBjYW5fYWRkX2h3ID0gMTsKCglzcGluX2xvY2soJmN0eC0+bG9jayk7CgljdHgtPmlzX2FjdGl2ZSA9IDE7CglpZiAobGlrZWx5KCFjdHgtPm5yX2NvdW50ZXJzKSkKCQlnb3RvIG91dDsKCgljdHgtPnRpbWVzdGFtcCA9IHBlcmZfY2xvY2soKTsKCglwZXJmX2Rpc2FibGUoKTsKCgkvKgoJICogRmlyc3QgZ28gdGhyb3VnaCB0aGUgbGlzdCBhbmQgcHV0IG9uIGFueSBwaW5uZWQgZ3JvdXBzCgkgKiBpbiBvcmRlciB0byBnaXZlIHRoZW0gdGhlIGJlc3QgY2hhbmNlIG9mIGdvaW5nIG9uLgoJICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWlmIChjb3VudGVyLT5zdGF0ZSA8PSBQRVJGX0NPVU5URVJfU1RBVEVfT0ZGIHx8CgkJICAgICFjb3VudGVyLT5hdHRyLnBpbm5lZCkKCQkJY29udGludWU7CgkJaWYgKGNvdW50ZXItPmNwdSAhPSAtMSAmJiBjb3VudGVyLT5jcHUgIT0gY3B1KQoJCQljb250aW51ZTsKCgkJaWYgKGNvdW50ZXIgIT0gY291bnRlci0+Z3JvdXBfbGVhZGVyKQoJCQljb3VudGVyX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpOwoJCWVsc2UgewoJCQlpZiAoZ3JvdXBfY2FuX2dvX29uKGNvdW50ZXIsIGNwdWN0eCwgMSkpCgkJCQlncm91cF9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KTsKCQl9CgoJCS8qCgkJICogSWYgdGhpcyBwaW5uZWQgZ3JvdXAgaGFzbid0IGJlZW4gc2NoZWR1bGVkLAoJCSAqIHB1dCBpdCBpbiBlcnJvciBzdGF0ZS4KCQkgKi8KCQlpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKSB7CgkJCXVwZGF0ZV9ncm91cF90aW1lcyhjb3VudGVyKTsKCQkJY291bnRlci0+c3RhdGUgPSBQRVJGX0NPVU5URVJfU1RBVEVfRVJST1I7CgkJfQoJfQoKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJLyoKCQkgKiBJZ25vcmUgY291bnRlcnMgaW4gT0ZGIG9yIEVSUk9SIHN0YXRlLCBhbmQKCQkgKiBpZ25vcmUgcGlubmVkIGNvdW50ZXJzIHNpbmNlIHdlIGRpZCB0aGVtIGFscmVhZHkuCgkJICovCgkJaWYgKGNvdW50ZXItPnN0YXRlIDw9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkYgfHwKCQkgICAgY291bnRlci0+YXR0ci5waW5uZWQpCgkJCWNvbnRpbnVlOwoKCQkvKgoJCSAqIExpc3RlbiB0byB0aGUgJ2NwdScgc2NoZWR1bGluZyBmaWx0ZXIgY29uc3RyYWludAoJCSAqIG9mIGNvdW50ZXJzOgoJCSAqLwoJCWlmIChjb3VudGVyLT5jcHUgIT0gLTEgJiYgY291bnRlci0+Y3B1ICE9IGNwdSkKCQkJY29udGludWU7CgoJCWlmIChjb3VudGVyICE9IGNvdW50ZXItPmdyb3VwX2xlYWRlcikgewoJCQlpZiAoY291bnRlcl9zY2hlZF9pbihjb3VudGVyLCBjcHVjdHgsIGN0eCwgY3B1KSkKCQkJCWNhbl9hZGRfaHcgPSAwOwoJCX0gZWxzZSB7CgkJCWlmIChncm91cF9jYW5fZ29fb24oY291bnRlciwgY3B1Y3R4LCBjYW5fYWRkX2h3KSkgewoJCQkJaWYgKGdyb3VwX3NjaGVkX2luKGNvdW50ZXIsIGNwdWN0eCwgY3R4LCBjcHUpKQoJCQkJCWNhbl9hZGRfaHcgPSAwOwoJCQl9CgkJfQoJfQoJcGVyZl9lbmFibGUoKTsKIG91dDoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9CgovKgogKiBDYWxsZWQgZnJvbSBzY2hlZHVsZXIgdG8gYWRkIHRoZSBjb3VudGVycyBvZiB0aGUgY3VycmVudCB0YXNrCiAqIHdpdGggaW50ZXJydXB0cyBkaXNhYmxlZC4KICoKICogV2UgcmVzdG9yZSB0aGUgY291bnRlciB2YWx1ZSBhbmQgdGhlbiBlbmFibGUgaXQuCiAqCiAqIFRoaXMgZG9lcyBub3QgcHJvdGVjdCB1cyBhZ2FpbnN0IE5NSSwgYnV0IGVuYWJsZSgpCiAqIHNldHMgdGhlIGVuYWJsZWQgYml0IGluIHRoZSBjb250cm9sIGZpZWxkIG9mIGNvdW50ZXIgX2JlZm9yZV8KICogYWNjZXNzaW5nIHRoZSBjb3VudGVyIGNvbnRyb2wgcmVnaXN0ZXIuIElmIGEgTk1JIGhpdHMsIHRoZW4gaXQgd2lsbAogKiBrZWVwIHRoZSBjb3VudGVyIHJ1bm5pbmcuCiAqLwp2b2lkIHBlcmZfY291bnRlcl90YXNrX3NjaGVkX2luKHN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzaywgaW50IGNwdSkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZwZXJfY3B1KHBlcmZfY3B1X2NvbnRleHQsIGNwdSk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfY291bnRlcl9jdHhwOwoKCWlmIChsaWtlbHkoIWN0eCkpCgkJcmV0dXJuOwoJaWYgKGNwdWN0eC0+dGFza19jdHggPT0gY3R4KQoJCXJldHVybjsKCV9fcGVyZl9jb3VudGVyX3NjaGVkX2luKGN0eCwgY3B1Y3R4LCBjcHUpOwoJY3B1Y3R4LT50YXNrX2N0eCA9IGN0eDsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2NwdV9zY2hlZF9pbihzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4LCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9ICZjcHVjdHgtPmN0eDsKCglfX3BlcmZfY291bnRlcl9zY2hlZF9pbihjdHgsIGNwdWN0eCwgY3B1KTsKfQoKI2RlZmluZSBNQVhfSU5URVJSVVBUUyAofjBVTEwpCgpzdGF0aWMgdm9pZCBwZXJmX2xvZ190aHJvdHRsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBpbnQgZW5hYmxlKTsKc3RhdGljIHZvaWQgcGVyZl9sb2dfcGVyaW9kKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBwZXJpb2QpOwoKc3RhdGljIHZvaWQgcGVyZl9hZGp1c3RfZnJlcShzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCXU2NCBpbnRlcnJ1cHRzLCBzYW1wbGVfcGVyaW9kOwoJdTY0IGV2ZW50cywgcGVyaW9kOwoJczY0IGRlbHRhOwoKCXNwaW5fbG9jaygmY3R4LT5sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJaWYgKGNvdW50ZXItPnN0YXRlICE9IFBFUkZfQ09VTlRFUl9TVEFURV9BQ1RJVkUpCgkJCWNvbnRpbnVlOwoKCQlpbnRlcnJ1cHRzID0gY291bnRlci0+aHcuaW50ZXJydXB0czsKCQljb3VudGVyLT5ody5pbnRlcnJ1cHRzID0gMDsKCgkJaWYgKGludGVycnVwdHMgPT0gTUFYX0lOVEVSUlVQVFMpIHsKCQkJcGVyZl9sb2dfdGhyb3R0bGUoY291bnRlciwgMSk7CgkJCWNvdW50ZXItPnBtdS0+dW50aHJvdHRsZShjb3VudGVyKTsKCQkJaW50ZXJydXB0cyA9IDIqc3lzY3RsX3BlcmZfY291bnRlcl9saW1pdC9IWjsKCQl9CgoJCWlmICghY291bnRlci0+YXR0ci5mcmVxIHx8ICFjb3VudGVyLT5hdHRyLnNhbXBsZV9mcmVxKQoJCQljb250aW51ZTsKCgkJZXZlbnRzID0gSFogKiBpbnRlcnJ1cHRzICogY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZDsKCQlwZXJpb2QgPSBkaXY2NF91NjQoZXZlbnRzLCBjb3VudGVyLT5hdHRyLnNhbXBsZV9mcmVxKTsKCgkJZGVsdGEgPSAoczY0KSgxICsgcGVyaW9kIC0gY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCk7CgkJZGVsdGEgPj49IDE7CgoJCXNhbXBsZV9wZXJpb2QgPSBjb3VudGVyLT5ody5zYW1wbGVfcGVyaW9kICsgZGVsdGE7CgoJCWlmICghc2FtcGxlX3BlcmlvZCkKCQkJc2FtcGxlX3BlcmlvZCA9IDE7CgoJCXBlcmZfbG9nX3BlcmlvZChjb3VudGVyLCBzYW1wbGVfcGVyaW9kKTsKCgkJY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCA9IHNhbXBsZV9wZXJpb2Q7Cgl9CglzcGluX3VubG9jaygmY3R4LT5sb2NrKTsKfQoKLyoKICogUm91bmQtcm9iaW4gYSBjb250ZXh0J3MgY291bnRlcnM6CiAqLwpzdGF0aWMgdm9pZCByb3RhdGVfY3R4KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWlmICghY3R4LT5ucl9jb3VudGVycykKCQlyZXR1cm47CgoJc3Bpbl9sb2NrKCZjdHgtPmxvY2spOwoJLyoKCSAqIFJvdGF0ZSB0aGUgZmlyc3QgZW50cnkgbGFzdCAod29ya3MganVzdCBmaW5lIGZvciBncm91cCBjb3VudGVycyB0b28pOgoJICovCglwZXJmX2Rpc2FibGUoKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoY291bnRlciwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJbGlzdF9tb3ZlX3RhaWwoJmNvdW50ZXItPmxpc3RfZW50cnksICZjdHgtPmNvdW50ZXJfbGlzdCk7CgkJYnJlYWs7Cgl9CglwZXJmX2VuYWJsZSgpOwoKCXNwaW5fdW5sb2NrKCZjdHgtPmxvY2spOwp9Cgp2b2lkIHBlcmZfY291bnRlcl90YXNrX3RpY2soc3RydWN0IHRhc2tfc3RydWN0ICpjdXJyLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHg7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY291bnRlcnMpKQoJCXJldHVybjsKCgljcHVjdHggPSAmcGVyX2NwdShwZXJmX2NwdV9jb250ZXh0LCBjcHUpOwoJY3R4ID0gY3Vyci0+cGVyZl9jb3VudGVyX2N0eHA7CgoJcGVyZl9hZGp1c3RfZnJlcSgmY3B1Y3R4LT5jdHgpOwoJaWYgKGN0eCkKCQlwZXJmX2FkanVzdF9mcmVxKGN0eCk7CgoJcGVyZl9jb3VudGVyX2NwdV9zY2hlZF9vdXQoY3B1Y3R4KTsKCWlmIChjdHgpCgkJX19wZXJmX2NvdW50ZXJfdGFza19zY2hlZF9vdXQoY3R4KTsKCglyb3RhdGVfY3R4KCZjcHVjdHgtPmN0eCk7CglpZiAoY3R4KQoJCXJvdGF0ZV9jdHgoY3R4KTsKCglwZXJmX2NvdW50ZXJfY3B1X3NjaGVkX2luKGNwdWN0eCwgY3B1KTsKCWlmIChjdHgpCgkJcGVyZl9jb3VudGVyX3Rhc2tfc2NoZWRfaW4oY3VyciwgY3B1KTsKfQoKLyoKICogQ3Jvc3MgQ1BVIGNhbGwgdG8gcmVhZCB0aGUgaGFyZHdhcmUgY291bnRlcgogKi8Kc3RhdGljIHZvaWQgX19yZWFkKHZvaWQgKmluZm8pCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSBpbmZvOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCWlmIChjdHgtPmlzX2FjdGl2ZSkKCQl1cGRhdGVfY29udGV4dF90aW1lKGN0eCk7Cgljb3VudGVyLT5wbXUtPnJlYWQoY291bnRlcik7Cgl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKfQoKc3RhdGljIHU2NCBwZXJmX2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CgkvKgoJICogSWYgY291bnRlciBpcyBlbmFibGVkIGFuZCBjdXJyZW50bHkgYWN0aXZlIG9uIGEgQ1BVLCB1cGRhdGUgdGhlCgkgKiB2YWx1ZSBpbiB0aGUgY291bnRlciBzdHJ1Y3R1cmU6CgkgKi8KCWlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfQUNUSVZFKSB7CgkJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNvdW50ZXItPm9uY3B1LAoJCQkJCSBfX3JlYWQsIGNvdW50ZXIsIDEpOwoJfSBlbHNlIGlmIChjb3VudGVyLT5zdGF0ZSA9PSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkUpIHsKCQl1cGRhdGVfY291bnRlcl90aW1lcyhjb3VudGVyKTsKCX0KCglyZXR1cm4gYXRvbWljNjRfcmVhZCgmY291bnRlci0+Y291bnQpOwp9CgovKgogKiBJbml0aWFsaXplIHRoZSBwZXJmX2NvdW50ZXIgY29udGV4dCBpbiBhIHRhc2tfc3RydWN0OgogKi8Kc3RhdGljIHZvaWQKX19wZXJmX2NvdW50ZXJfaW5pdF9jb250ZXh0KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkgICAgc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CgltZW1zZXQoY3R4LCAwLCBzaXplb2YoKmN0eCkpOwoJc3Bpbl9sb2NrX2luaXQoJmN0eC0+bG9jayk7CgltdXRleF9pbml0KCZjdHgtPm11dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjdHgtPmNvdW50ZXJfbGlzdCk7CglJTklUX0xJU1RfSEVBRCgmY3R4LT5ldmVudF9saXN0KTsKCWF0b21pY19zZXQoJmN0eC0+cmVmY291bnQsIDEpOwoJY3R4LT50YXNrID0gdGFzazsKfQoKc3RhdGljIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqZmluZF9nZXRfY29udGV4dChwaWRfdCBwaWQsIGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqcGFyZW50X2N0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzazsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZXJyOwoKCS8qCgkgKiBJZiBjcHUgaXMgbm90IGEgd2lsZGNhcmQgdGhlbiB0aGlzIGlzIGEgcGVyY3B1IGNvdW50ZXI6CgkgKi8KCWlmIChjcHUgIT0gLTEpIHsKCQkvKiBNdXN0IGJlIHJvb3QgdG8gb3BlcmF0ZSBvbiBhIENQVSBjb3VudGVyOiAqLwoJCWlmIChzeXNjdGxfcGVyZl9jb3VudGVyX3ByaXYgJiYgIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJCXJldHVybiBFUlJfUFRSKC1FQUNDRVMpOwoKCQlpZiAoY3B1IDwgMCB8fCBjcHUgPiBudW1fcG9zc2libGVfY3B1cygpKQoJCQlyZXR1cm4gRVJSX1BUUigtRUlOVkFMKTsKCgkJLyoKCQkgKiBXZSBjb3VsZCBiZSBjbGV2ZXIgYW5kIGFsbG93IHRvIGF0dGFjaCBhIGNvdW50ZXIgdG8gYW4KCQkgKiBvZmZsaW5lIENQVSBhbmQgYWN0aXZhdGUgaXQgd2hlbiB0aGUgQ1BVIGNvbWVzIHVwLCBidXQKCQkgKiB0aGF0J3MgZm9yIGxhdGVyLgoJCSAqLwoJCWlmICghY3B1X2lzc2V0KGNwdSwgY3B1X29ubGluZV9tYXApKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKCgkJY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCQljdHggPSAmY3B1Y3R4LT5jdHg7CgkJZ2V0X2N0eChjdHgpOwoKCQlyZXR1cm4gY3R4OwoJfQoKCXJjdV9yZWFkX2xvY2soKTsKCWlmICghcGlkKQoJCXRhc2sgPSBjdXJyZW50OwoJZWxzZQoJCXRhc2sgPSBmaW5kX3Rhc2tfYnlfdnBpZChwaWQpOwoJaWYgKHRhc2spCgkJZ2V0X3Rhc2tfc3RydWN0KHRhc2spOwoJcmN1X3JlYWRfdW5sb2NrKCk7CgoJaWYgKCF0YXNrKQoJCXJldHVybiBFUlJfUFRSKC1FU1JDSCk7CgoJLyoKCSAqIENhbid0IGF0dGFjaCBjb3VudGVycyB0byBhIGR5aW5nIHRhc2suCgkgKi8KCWVyciA9IC1FU1JDSDsKCWlmICh0YXNrLT5mbGFncyAmIFBGX0VYSVRJTkcpCgkJZ290byBlcnJvdXQ7CgoJLyogUmV1c2UgcHRyYWNlIHBlcm1pc3Npb24gY2hlY2tzIGZvciBub3cuICovCgllcnIgPSAtRUFDQ0VTOwoJaWYgKCFwdHJhY2VfbWF5X2FjY2Vzcyh0YXNrLCBQVFJBQ0VfTU9ERV9SRUFEKSkKCQlnb3RvIGVycm91dDsKCiByZXRyeToKCWN0eCA9IHBlcmZfbG9ja190YXNrX2NvbnRleHQodGFzaywgJmZsYWdzKTsKCWlmIChjdHgpIHsKCQlwYXJlbnRfY3R4ID0gY3R4LT5wYXJlbnRfY3R4OwoJCWlmIChwYXJlbnRfY3R4KSB7CgkJCXB1dF9jdHgocGFyZW50X2N0eCk7CgkJCWN0eC0+cGFyZW50X2N0eCA9IE5VTEw7CQkvKiBubyBsb25nZXIgYSBjbG9uZSAqLwoJCX0KCQkvKgoJCSAqIEdldCBhbiBleHRyYSByZWZlcmVuY2UgYmVmb3JlIGRyb3BwaW5nIHRoZSBsb2NrIHNvIHRoYXQKCQkgKiB0aGlzIGNvbnRleHQgd29uJ3QgZ2V0IGZyZWVkIGlmIHRoZSB0YXNrIGV4aXRzLgoJCSAqLwoJCWdldF9jdHgoY3R4KTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCX0KCglpZiAoIWN0eCkgewoJCWN0eCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCksIEdGUF9LRVJORUwpOwoJCWVyciA9IC1FTk9NRU07CgkJaWYgKCFjdHgpCgkJCWdvdG8gZXJyb3V0OwoJCV9fcGVyZl9jb3VudGVyX2luaXRfY29udGV4dChjdHgsIHRhc2spOwoJCWdldF9jdHgoY3R4KTsKCQlpZiAoY21weGNoZygmdGFzay0+cGVyZl9jb3VudGVyX2N0eHAsIE5VTEwsIGN0eCkpIHsKCQkJLyoKCQkJICogV2UgcmFjZWQgd2l0aCBzb21lIG90aGVyIHRhc2s7IHVzZQoJCQkgKiB0aGUgY29udGV4dCB0aGV5IHNldC4KCQkJICovCgkJCWtmcmVlKGN0eCk7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWdldF90YXNrX3N0cnVjdCh0YXNrKTsKCX0KCglwdXRfdGFza19zdHJ1Y3QodGFzayk7CglyZXR1cm4gY3R4OwoKIGVycm91dDoKCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKCXJldHVybiBFUlJfUFRSKGVycik7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY291bnRlcl9yY3Uoc3RydWN0IHJjdV9oZWFkICpoZWFkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCWNvdW50ZXIgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IHBlcmZfY291bnRlciwgcmN1X2hlYWQpOwoJaWYgKGNvdW50ZXItPm5zKQoJCXB1dF9waWRfbnMoY291bnRlci0+bnMpOwoJa2ZyZWUoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfcGVuZGluZ19zeW5jKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpOwoKc3RhdGljIHZvaWQgZnJlZV9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfcGVuZGluZ19zeW5jKGNvdW50ZXIpOwoKCWF0b21pY19kZWMoJm5yX2NvdW50ZXJzKTsKCWlmIChjb3VudGVyLT5hdHRyLm1tYXApCgkJYXRvbWljX2RlYygmbnJfbW1hcF9jb3VudGVycyk7CglpZiAoY291bnRlci0+YXR0ci5jb21tKQoJCWF0b21pY19kZWMoJm5yX2NvbW1fY291bnRlcnMpOwoKCWlmIChjb3VudGVyLT5kZXN0cm95KQoJCWNvdW50ZXItPmRlc3Ryb3koY291bnRlcik7CgoJcHV0X2N0eChjb3VudGVyLT5jdHgpOwoJY2FsbF9yY3UoJmNvdW50ZXItPnJjdV9oZWFkLCBmcmVlX2NvdW50ZXJfcmN1KTsKfQoKLyoKICogQ2FsbGVkIHdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIHRvIHRoZSBmaWxlIGlzIGdvbmUuCiAqLwpzdGF0aWMgaW50IHBlcmZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoKCWZpbGUtPnByaXZhdGVfZGF0YSA9IE5VTEw7CgoJV0FSTl9PTl9PTkNFKGN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjdHgtPm11dGV4KTsKCXBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNvdW50ZXIpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCgltdXRleF9sb2NrKCZjb3VudGVyLT5vd25lci0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfZGVsX2luaXQoJmNvdW50ZXItPm93bmVyX2VudHJ5KTsKCW11dGV4X3VubG9jaygmY291bnRlci0+b3duZXItPnBlcmZfY291bnRlcl9tdXRleCk7CglwdXRfdGFza19zdHJ1Y3QoY291bnRlci0+b3duZXIpOwoKCWZyZWVfY291bnRlcihjb3VudGVyKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmVhZCB0aGUgcGVyZm9ybWFuY2UgY291bnRlciAtIHNpbXBsZSBub24gYmxvY2tpbmcgdmVyc2lvbiBmb3Igbm93CiAqLwpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWRfaHcoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQp7Cgl1NjQgdmFsdWVzWzNdOwoJaW50IG47CgoJLyoKCSAqIFJldHVybiBlbmQtb2YtZmlsZSBmb3IgYSByZWFkIG9uIGEgY291bnRlciB0aGF0IGlzIGluCgkgKiBlcnJvciBzdGF0ZSAoaS5lLiBiZWNhdXNlIGl0IHdhcyBwaW5uZWQgYnV0IGl0IGNvdWxkbid0IGJlCgkgKiBzY2hlZHVsZWQgb24gdG8gdGhlIENQVSBhdCBzb21lIHBvaW50KS4KCSAqLwoJaWYgKGNvdW50ZXItPnN0YXRlID09IFBFUkZfQ09VTlRFUl9TVEFURV9FUlJPUikKCQlyZXR1cm4gMDsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCXZhbHVlc1swXSA9IHBlcmZfY291bnRlcl9yZWFkKGNvdW50ZXIpOwoJbiA9IDE7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfRU5BQkxFRCkKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfZW5hYmxlZCArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfZW5hYmxlZCk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX1RPVEFMX1RJTUVfUlVOTklORykKCQl2YWx1ZXNbbisrXSA9IGNvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZyArCgkJCWF0b21pYzY0X3JlYWQoJmNvdW50ZXItPmNoaWxkX3RvdGFsX3RpbWVfcnVubmluZyk7CglpZiAoY291bnRlci0+YXR0ci5yZWFkX2Zvcm1hdCAmIFBFUkZfRk9STUFUX0lEKQoJCXZhbHVlc1tuKytdID0gY291bnRlci0+aWQ7CgltdXRleF91bmxvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCglpZiAoY291bnQgPCBuICogc2l6ZW9mKHU2NCkpCgkJcmV0dXJuIC1FSU5WQUw7Cgljb3VudCA9IG4gKiBzaXplb2YodTY0KTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgdmFsdWVzLCBjb3VudCkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgc3NpemVfdApwZXJmX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpwcG9zKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCXJldHVybiBwZXJmX3JlYWRfaHcoY291bnRlciwgYnVmLCBjb3VudCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgcGVyZl9wb2xsKHN0cnVjdCBmaWxlICpmaWxlLCBwb2xsX3RhYmxlICp3YWl0KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgaW50IGV2ZW50cyA9IFBPTExfSFVQOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoY291bnRlci0+ZGF0YSk7CglpZiAoZGF0YSkKCQlldmVudHMgPSBhdG9taWNfeGNoZygmZGF0YS0+cG9sbCwgMCk7CglyY3VfcmVhZF91bmxvY2soKTsKCglwb2xsX3dhaXQoZmlsZSwgJmNvdW50ZXItPndhaXRxLCB3YWl0KTsKCglyZXR1cm4gZXZlbnRzOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfcmVzZXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJKHZvaWQpcGVyZl9jb3VudGVyX3JlYWQoY291bnRlcik7CglhdG9taWM2NF9zZXQoJmNvdW50ZXItPmNvdW50LCAwKTsKCXBlcmZfY291bnRlcl91cGRhdGVfdXNlcnBhZ2UoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9mb3JfZWFjaF9zaWJsaW5nKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkJICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfY291bnRlciAqKSkKewoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSBjb3VudGVyLT5jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpzaWJsaW5nOwoKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7Cgljb3VudGVyID0gY291bnRlci0+Z3JvdXBfbGVhZGVyOwoKCWZ1bmMoY291bnRlcik7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNpYmxpbmcsICZjb3VudGVyLT5zaWJsaW5nX2xpc3QsIGxpc3RfZW50cnkpCgkJZnVuYyhzaWJsaW5nKTsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7Cn0KCi8qCiAqIEhvbGRpbmcgdGhlIHRvcC1sZXZlbCBjb3VudGVyJ3MgY2hpbGRfbXV0ZXggbWVhbnMgdGhhdCBhbnkKICogZGVzY2VuZGFudCBwcm9jZXNzIHRoYXQgaGFzIGluaGVyaXRlZCB0aGlzIGNvdW50ZXIgd2lsbCBibG9jawogKiBpbiBzeW5jX2NoaWxkX2NvdW50ZXIgaWYgaXQgZ29lcyB0byBleGl0LCB0aHVzIHNhdGlzZnlpbmcgdGhlCiAqIHRhc2sgZXhpc3RlbmNlIHJlcXVpcmVtZW50cyBvZiBwZXJmX2NvdW50ZXJfZW5hYmxlL2Rpc2FibGUuCiAqLwpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZm9yX2VhY2hfY2hpbGQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfY291bnRlciAqKSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY2hpbGQ7CgoJV0FSTl9PTl9PTkNFKGNvdW50ZXItPmN0eC0+cGFyZW50X2N0eCk7CgltdXRleF9sb2NrKCZjb3VudGVyLT5jaGlsZF9tdXRleCk7CglmdW5jKGNvdW50ZXIpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmNvdW50ZXItPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJZnVuYyhjaGlsZCk7CgltdXRleF91bmxvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Zvcl9lYWNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgIHZvaWQgKCpmdW5jKShzdHJ1Y3QgcGVyZl9jb3VudGVyICopKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZDsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmNvdW50ZXItPmNoaWxkX211dGV4KTsKCXBlcmZfY291bnRlcl9mb3JfZWFjaF9zaWJsaW5nKGNvdW50ZXIsIGZ1bmMpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjaGlsZCwgJmNvdW50ZXItPmNoaWxkX2xpc3QsIGNoaWxkX2xpc3QpCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX3NpYmxpbmcoY2hpbGQsIGZ1bmMpOwoJbXV0ZXhfdW5sb2NrKCZjb3VudGVyLT5jaGlsZF9tdXRleCk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9jb3VudGVyX3BlcmlvZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCB1NjQgX191c2VyICphcmcpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gY291bnRlci0+Y3R4OwoJdW5zaWduZWQgbG9uZyBzaXplOwoJaW50IHJldCA9IDA7Cgl1NjQgdmFsdWU7CgoJaWYgKCFjb3VudGVyLT5hdHRyLnNhbXBsZV9wZXJpb2QpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc2l6ZSA9IGNvcHlfZnJvbV91c2VyKCZ2YWx1ZSwgYXJnLCBzaXplb2YodmFsdWUpKTsKCWlmIChzaXplICE9IHNpemVvZih2YWx1ZSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKCF2YWx1ZSkKCQlyZXR1cm4gLUVJTlZBTDsKCglzcGluX2xvY2tfaXJxKCZjdHgtPmxvY2spOwoJaWYgKGNvdW50ZXItPmF0dHIuZnJlcSkgewoJCWlmICh2YWx1ZSA+IHN5c2N0bF9wZXJmX2NvdW50ZXJfbGltaXQpIHsKCQkJcmV0ID0gLUVJTlZBTDsKCQkJZ290byB1bmxvY2s7CgkJfQoKCQljb3VudGVyLT5hdHRyLnNhbXBsZV9mcmVxID0gdmFsdWU7Cgl9IGVsc2UgewoJCWNvdW50ZXItPmF0dHIuc2FtcGxlX3BlcmlvZCA9IHZhbHVlOwoJCWNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QgPSB2YWx1ZTsKCgkJcGVyZl9sb2dfcGVyaW9kKGNvdW50ZXIsIHZhbHVlKTsKCX0KdW5sb2NrOgoJc3Bpbl91bmxvY2tfaXJxKCZjdHgtPmxvY2spOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBsb25nIHBlcmZfaW9jdGwoc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdm9pZCAoKmZ1bmMpKHN0cnVjdCBwZXJmX2NvdW50ZXIgKik7Cgl1MzIgZmxhZ3MgPSBhcmc7CgoJc3dpdGNoIChjbWQpIHsKCWNhc2UgUEVSRl9DT1VOVEVSX0lPQ19FTkFCTEU6CgkJZnVuYyA9IHBlcmZfY291bnRlcl9lbmFibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRFUl9JT0NfRElTQUJMRToKCQlmdW5jID0gcGVyZl9jb3VudGVyX2Rpc2FibGU7CgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRFUl9JT0NfUkVTRVQ6CgkJZnVuYyA9IHBlcmZfY291bnRlcl9yZXNldDsKCQlicmVhazsKCgljYXNlIFBFUkZfQ09VTlRFUl9JT0NfUkVGUkVTSDoKCQlyZXR1cm4gcGVyZl9jb3VudGVyX3JlZnJlc2goY291bnRlciwgYXJnKTsKCgljYXNlIFBFUkZfQ09VTlRFUl9JT0NfUEVSSU9EOgoJCXJldHVybiBwZXJmX2NvdW50ZXJfcGVyaW9kKGNvdW50ZXIsICh1NjQgX191c2VyICopYXJnKTsKCglkZWZhdWx0OgoJCXJldHVybiAtRU5PVFRZOwoJfQoKCWlmIChmbGFncyAmIFBFUkZfSU9DX0ZMQUdfR1JPVVApCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoKGNvdW50ZXIsIGZ1bmMpOwoJZWxzZQoJCXBlcmZfY291bnRlcl9mb3JfZWFjaF9jaGlsZChjb3VudGVyLCBmdW5jKTsKCglyZXR1cm4gMDsKfQoKaW50IHBlcmZfY291bnRlcl90YXNrX2VuYWJsZSh2b2lkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfY291bnRlcl9tdXRleCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKGNvdW50ZXIsIHBlcmZfY291bnRlcl9lbmFibGUpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgppbnQgcGVyZl9jb3VudGVyX3Rhc2tfZGlzYWJsZSh2b2lkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoKCW11dGV4X2xvY2soJmN1cnJlbnQtPnBlcmZfY291bnRlcl9tdXRleCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNvdW50ZXIsICZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbGlzdCwgb3duZXJfZW50cnkpCgkJcGVyZl9jb3VudGVyX2Zvcl9lYWNoX2NoaWxkKGNvdW50ZXIsIHBlcmZfY291bnRlcl9kaXNhYmxlKTsKCW11dGV4X3VubG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCglyZXR1cm4gMDsKfQoKLyoKICogQ2FsbGVycyBuZWVkIHRvIGVuc3VyZSB0aGVyZSBjYW4gYmUgbm8gbmVzdGluZyBvZiB0aGlzIGZ1bmN0aW9uLCBvdGhlcndpc2UKICogdGhlIHNlcWxvY2sgbG9naWMgZ29lcyBiYWQuIFdlIGNhbiBub3Qgc2VyaWFsaXplIHRoaXMgYmVjYXVzZSB0aGUgYXJjaAogKiBjb2RlIGNhbGxzIHRoaXMgZnJvbSBOTUkgY29udGV4dC4KICovCnZvaWQgcGVyZl9jb3VudGVyX3VwZGF0ZV91c2VycGFnZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX21tYXBfcGFnZSAqdXNlcnBnOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoY291bnRlci0+ZGF0YSk7CglpZiAoIWRhdGEpCgkJZ290byB1bmxvY2s7CgoJdXNlcnBnID0gZGF0YS0+dXNlcl9wYWdlOwoKCS8qCgkgKiBEaXNhYmxlIHByZWVtcHRpb24gc28gYXMgdG8gbm90IGxldCB0aGUgY29ycmVzcG9uZGluZyB1c2VyLXNwYWNlCgkgKiBzcGluIHRvbyBsb25nIGlmIHdlIGdldCBwcmVlbXB0ZWQuCgkgKi8KCXByZWVtcHRfZGlzYWJsZSgpOwoJKyt1c2VycGctPmxvY2s7CgliYXJyaWVyKCk7Cgl1c2VycGctPmluZGV4ID0gY291bnRlci0+aHcuaWR4OwoJdXNlcnBnLT5vZmZzZXQgPSBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5jb3VudCk7CglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQl1c2VycGctPm9mZnNldCAtPSBhdG9taWM2NF9yZWFkKCZjb3VudGVyLT5ody5wcmV2X2NvdW50KTsKCgliYXJyaWVyKCk7CgkrK3VzZXJwZy0+bG9jazsKCXByZWVtcHRfZW5hYmxlKCk7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwp9CgpzdGF0aWMgaW50IHBlcmZfbW1hcF9mYXVsdChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgc3RydWN0IHZtX2ZhdWx0ICp2bWYpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIgPSB2bWEtPnZtX2ZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YTsKCWludCByZXQgPSBWTV9GQVVMVF9TSUdCVVM7CgoJcmN1X3JlYWRfbG9jaygpOwoJZGF0YSA9IHJjdV9kZXJlZmVyZW5jZShjb3VudGVyLT5kYXRhKTsKCWlmICghZGF0YSkKCQlnb3RvIHVubG9jazsKCglpZiAodm1mLT5wZ29mZiA9PSAwKSB7CgkJdm1mLT5wYWdlID0gdmlydF90b19wYWdlKGRhdGEtPnVzZXJfcGFnZSk7Cgl9IGVsc2UgewoJCWludCBuciA9IHZtZi0+cGdvZmYgLSAxOwoKCQlpZiAoKHVuc2lnbmVkKW5yID4gZGF0YS0+bnJfcGFnZXMpCgkJCWdvdG8gdW5sb2NrOwoKCQl2bWYtPnBhZ2UgPSB2aXJ0X3RvX3BhZ2UoZGF0YS0+ZGF0YV9wYWdlc1tucl0pOwoJfQoJZ2V0X3BhZ2Uodm1mLT5wYWdlKTsKCXJldCA9IDA7CnVubG9jazoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGVyZl9tbWFwX2RhdGFfYWxsb2Moc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgaW50IG5yX3BhZ2VzKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGE7Cgl1bnNpZ25lZCBsb25nIHNpemU7CglpbnQgaTsKCglXQVJOX09OKGF0b21pY19yZWFkKCZjb3VudGVyLT5tbWFwX2NvdW50KSk7CgoJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEpOwoJc2l6ZSArPSBucl9wYWdlcyAqIHNpemVvZih2b2lkICopOwoKCWRhdGEgPSBremFsbG9jKHNpemUsIEdGUF9LRVJORUwpOwoJaWYgKCFkYXRhKQoJCWdvdG8gZmFpbDsKCglkYXRhLT51c2VyX3BhZ2UgPSAodm9pZCAqKWdldF96ZXJvZWRfcGFnZShHRlBfS0VSTkVMKTsKCWlmICghZGF0YS0+dXNlcl9wYWdlKQoJCWdvdG8gZmFpbF91c2VyX3BhZ2U7CgoJZm9yIChpID0gMDsgaSA8IG5yX3BhZ2VzOyBpKyspIHsKCQlkYXRhLT5kYXRhX3BhZ2VzW2ldID0gKHZvaWQgKilnZXRfemVyb2VkX3BhZ2UoR0ZQX0tFUk5FTCk7CgkJaWYgKCFkYXRhLT5kYXRhX3BhZ2VzW2ldKQoJCQlnb3RvIGZhaWxfZGF0YV9wYWdlczsKCX0KCglkYXRhLT5ucl9wYWdlcyA9IG5yX3BhZ2VzOwoJYXRvbWljX3NldCgmZGF0YS0+bG9jaywgLTEpOwoKCXJjdV9hc3NpZ25fcG9pbnRlcihjb3VudGVyLT5kYXRhLCBkYXRhKTsKCglyZXR1cm4gMDsKCmZhaWxfZGF0YV9wYWdlczoKCWZvciAoaS0tOyBpID49IDA7IGktLSkKCQlmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+ZGF0YV9wYWdlc1tpXSk7CgoJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPnVzZXJfcGFnZSk7CgpmYWlsX3VzZXJfcGFnZToKCWtmcmVlKGRhdGEpOwoKZmFpbDoKCXJldHVybiAtRU5PTUVNOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfbW1hcF9kYXRhX2ZyZWUoc3RydWN0IHJjdV9oZWFkICpyY3VfaGVhZCkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJaW50IGk7CgoJZGF0YSA9IGNvbnRhaW5lcl9vZihyY3VfaGVhZCwgc3RydWN0IHBlcmZfbW1hcF9kYXRhLCByY3VfaGVhZCk7CgoJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWRhdGEtPnVzZXJfcGFnZSk7Cglmb3IgKGkgPSAwOyBpIDwgZGF0YS0+bnJfcGFnZXM7IGkrKykKCQlmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZGF0YS0+ZGF0YV9wYWdlc1tpXSk7CglrZnJlZShkYXRhKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9tbWFwX2RhdGFfZnJlZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgcGVyZl9tbWFwX2RhdGEgKmRhdGEgPSBjb3VudGVyLT5kYXRhOwoKCVdBUk5fT04oYXRvbWljX3JlYWQoJmNvdW50ZXItPm1tYXBfY291bnQpKTsKCglyY3VfYXNzaWduX3BvaW50ZXIoY291bnRlci0+ZGF0YSwgTlVMTCk7CgljYWxsX3JjdSgmZGF0YS0+cmN1X2hlYWQsIF9fcGVyZl9tbWFwX2RhdGFfZnJlZSk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9vcGVuKHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gdm1hLT52bV9maWxlLT5wcml2YXRlX2RhdGE7CgoJYXRvbWljX2luYygmY291bnRlci0+bW1hcF9jb3VudCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfbW1hcF9jbG9zZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IHZtYS0+dm1fZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCVdBUk5fT05fT05DRShjb3VudGVyLT5jdHgtPnBhcmVudF9jdHgpOwoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJmNvdW50ZXItPm1tYXBfY291bnQsICZjb3VudGVyLT5tbWFwX211dGV4KSkgewoJCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlciA9IGN1cnJlbnRfdXNlcigpOwoKCQlhdG9taWNfbG9uZ19zdWIoY291bnRlci0+ZGF0YS0+bnJfcGFnZXMgKyAxLCAmdXNlci0+bG9ja2VkX3ZtKTsKCQl2bWEtPnZtX21tLT5sb2NrZWRfdm0gLT0gY291bnRlci0+ZGF0YS0+bnJfbG9ja2VkOwoJCXBlcmZfbW1hcF9kYXRhX2ZyZWUoY291bnRlcik7CgkJbXV0ZXhfdW5sb2NrKCZjb3VudGVyLT5tbWFwX211dGV4KTsKCX0KfQoKc3RhdGljIHN0cnVjdCB2bV9vcGVyYXRpb25zX3N0cnVjdCBwZXJmX21tYXBfdm1vcHMgPSB7Cgkub3BlbiAgPSBwZXJmX21tYXBfb3BlbiwKCS5jbG9zZSA9IHBlcmZfbW1hcF9jbG9zZSwKCS5mYXVsdCA9IHBlcmZfbW1hcF9mYXVsdCwKfTsKCnN0YXRpYyBpbnQgcGVyZl9tbWFwKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXVuc2lnbmVkIGxvbmcgdXNlcl9sb2NrZWQsIHVzZXJfbG9ja19saW1pdDsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlciA9IGN1cnJlbnRfdXNlcigpOwoJdW5zaWduZWQgbG9uZyBsb2NrZWQsIGxvY2tfbGltaXQ7Cgl1bnNpZ25lZCBsb25nIHZtYV9zaXplOwoJdW5zaWduZWQgbG9uZyBucl9wYWdlczsKCWxvbmcgdXNlcl9leHRyYSwgZXh0cmE7CglpbnQgcmV0ID0gMDsKCglpZiAoISh2bWEtPnZtX2ZsYWdzICYgVk1fU0hBUkVEKSB8fCAodm1hLT52bV9mbGFncyAmIFZNX1dSSVRFKSkKCQlyZXR1cm4gLUVJTlZBTDsKCgl2bWFfc2l6ZSA9IHZtYS0+dm1fZW5kIC0gdm1hLT52bV9zdGFydDsKCW5yX3BhZ2VzID0gKHZtYV9zaXplIC8gUEFHRV9TSVpFKSAtIDE7CgoJLyoKCSAqIElmIHdlIGhhdmUgZGF0YSBwYWdlcyBlbnN1cmUgdGhleSdyZSBhIHBvd2VyLW9mLXR3byBudW1iZXIsIHNvIHdlCgkgKiBjYW4gZG8gYml0bWFza3MgaW5zdGVhZCBvZiBtb2R1bG8uCgkgKi8KCWlmIChucl9wYWdlcyAhPSAwICYmICFpc19wb3dlcl9vZl8yKG5yX3BhZ2VzKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAodm1hX3NpemUgIT0gUEFHRV9TSVpFICogKDEgKyBucl9wYWdlcykpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKHZtYS0+dm1fcGdvZmYgIT0gMCkKCQlyZXR1cm4gLUVJTlZBTDsKCglXQVJOX09OX09OQ0UoY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJmNvdW50ZXItPm1tYXBfbXV0ZXgpOwoJaWYgKGF0b21pY19pbmNfbm90X3plcm8oJmNvdW50ZXItPm1tYXBfY291bnQpKSB7CgkJaWYgKG5yX3BhZ2VzICE9IGNvdW50ZXItPmRhdGEtPm5yX3BhZ2VzKQoJCQlyZXQgPSAtRUlOVkFMOwoJCWdvdG8gdW5sb2NrOwoJfQoKCXVzZXJfZXh0cmEgPSBucl9wYWdlcyArIDE7Cgl1c2VyX2xvY2tfbGltaXQgPSBzeXNjdGxfcGVyZl9jb3VudGVyX21sb2NrID4+IChQQUdFX1NISUZUIC0gMTApOwoKCS8qCgkgKiBJbmNyZWFzZSB0aGUgbGltaXQgbGluZWFybHkgd2l0aCBtb3JlIENQVXM6CgkgKi8KCXVzZXJfbG9ja19saW1pdCAqPSBudW1fb25saW5lX2NwdXMoKTsKCgl1c2VyX2xvY2tlZCA9IGF0b21pY19sb25nX3JlYWQoJnVzZXItPmxvY2tlZF92bSkgKyB1c2VyX2V4dHJhOwoKCWV4dHJhID0gMDsKCWlmICh1c2VyX2xvY2tlZCA+IHVzZXJfbG9ja19saW1pdCkKCQlleHRyYSA9IHVzZXJfbG9ja2VkIC0gdXNlcl9sb2NrX2xpbWl0OwoKCWxvY2tfbGltaXQgPSBjdXJyZW50LT5zaWduYWwtPnJsaW1bUkxJTUlUX01FTUxPQ0tdLnJsaW1fY3VyOwoJbG9ja19saW1pdCA+Pj0gUEFHRV9TSElGVDsKCWxvY2tlZCA9IHZtYS0+dm1fbW0tPmxvY2tlZF92bSArIGV4dHJhOwoKCWlmICgobG9ja2VkID4gbG9ja19saW1pdCkgJiYgIWNhcGFibGUoQ0FQX0lQQ19MT0NLKSkgewoJCXJldCA9IC1FUEVSTTsKCQlnb3RvIHVubG9jazsKCX0KCglXQVJOX09OKGNvdW50ZXItPmRhdGEpOwoJcmV0ID0gcGVyZl9tbWFwX2RhdGFfYWxsb2MoY291bnRlciwgbnJfcGFnZXMpOwoJaWYgKHJldCkKCQlnb3RvIHVubG9jazsKCglhdG9taWNfc2V0KCZjb3VudGVyLT5tbWFwX2NvdW50LCAxKTsKCWF0b21pY19sb25nX2FkZCh1c2VyX2V4dHJhLCAmdXNlci0+bG9ja2VkX3ZtKTsKCXZtYS0+dm1fbW0tPmxvY2tlZF92bSArPSBleHRyYTsKCWNvdW50ZXItPmRhdGEtPm5yX2xvY2tlZCA9IGV4dHJhOwp1bmxvY2s6CgltdXRleF91bmxvY2soJmNvdW50ZXItPm1tYXBfbXV0ZXgpOwoKCXZtYS0+dm1fZmxhZ3MgJj0gflZNX01BWVdSSVRFOwoJdm1hLT52bV9mbGFncyB8PSBWTV9SRVNFUlZFRDsKCXZtYS0+dm1fb3BzID0gJnBlcmZfbW1hcF92bW9wczsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHBlcmZfZmFzeW5jKGludCBmZCwgc3RydWN0IGZpbGUgKmZpbHAsIGludCBvbikKewoJc3RydWN0IGlub2RlICppbm9kZSA9IGZpbHAtPmZfcGF0aC5kZW50cnktPmRfaW5vZGU7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gZmlscC0+cHJpdmF0ZV9kYXRhOwoJaW50IHJldHZhbDsKCgltdXRleF9sb2NrKCZpbm9kZS0+aV9tdXRleCk7CglyZXR2YWwgPSBmYXN5bmNfaGVscGVyKGZkLCBmaWxwLCBvbiwgJmNvdW50ZXItPmZhc3luYyk7CgltdXRleF91bmxvY2soJmlub2RlLT5pX211dGV4KTsKCglpZiAocmV0dmFsIDwgMCkKCQlyZXR1cm4gcmV0dmFsOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwZXJmX2ZvcHMgPSB7CgkucmVsZWFzZQkJPSBwZXJmX3JlbGVhc2UsCgkucmVhZAkJCT0gcGVyZl9yZWFkLAoJLnBvbGwJCQk9IHBlcmZfcG9sbCwKCS51bmxvY2tlZF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLmNvbXBhdF9pb2N0bAkJPSBwZXJmX2lvY3RsLAoJLm1tYXAJCQk9IHBlcmZfbW1hcCwKCS5mYXN5bmMJCQk9IHBlcmZfZmFzeW5jLAp9OwoKLyoKICogUGVyZiBjb3VudGVyIHdha2V1cAogKgogKiBJZiB0aGVyZSdzIGRhdGEsIGVuc3VyZSB3ZSBzZXQgdGhlIHBvbGwoKSBzdGF0ZSBhbmQgcHVibGlzaCBldmVyeXRoaW5nCiAqIHRvIHVzZXItc3BhY2UgYmVmb3JlIHdha2luZyBldmVyeWJvZHkgdXAuCiAqLwoKdm9pZCBwZXJmX2NvdW50ZXJfd2FrZXVwKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXdha2VfdXBfYWxsKCZjb3VudGVyLT53YWl0cSk7CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfa2lsbCkgewoJCWtpbGxfZmFzeW5jKCZjb3VudGVyLT5mYXN5bmMsIFNJR0lPLCBjb3VudGVyLT5wZW5kaW5nX2tpbGwpOwoJCWNvdW50ZXItPnBlbmRpbmdfa2lsbCA9IDA7Cgl9Cn0KCi8qCiAqIFBlbmRpbmcgd2FrZXVwcwogKgogKiBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgbmVlZCB0byB3YWtldXAgdXAgZnJvbSBOTUkgKG9yIHJxLT5sb2NrKSBjb250ZXh0LgogKgogKiBUaGUgTk1JIGJpdCBtZWFucyB3ZSBjYW5ub3QgcG9zc2libHkgdGFrZSBsb2Nrcy4gVGhlcmVmb3JlLCBtYWludGFpbiBhCiAqIHNpbmdsZSBsaW5rZWQgbGlzdCBhbmQgdXNlIGNtcHhjaGcoKSB0byBhZGQgZW50cmllcyBsb2NrbGVzcy4KICovCgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfY291bnRlcihzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciA9IGNvbnRhaW5lcl9vZihlbnRyeSwKCQkJc3RydWN0IHBlcmZfY291bnRlciwgcGVuZGluZyk7CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSkgewoJCWNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSA9IDA7CgkJcGVyZl9jb3VudGVyX2Rpc2FibGUoY291bnRlcik7Cgl9CgoJaWYgKGNvdW50ZXItPnBlbmRpbmdfd2FrZXVwKSB7CgkJY291bnRlci0+cGVuZGluZ193YWtldXAgPSAwOwoJCXBlcmZfY291bnRlcl93YWtldXAoY291bnRlcik7Cgl9Cn0KCiNkZWZpbmUgUEVORElOR19UQUlMICgoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKS0xVUwpCgpzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqLCBwZXJmX3BlbmRpbmdfaGVhZCkgPSB7CglQRU5ESU5HX1RBSUwsCn07CgpzdGF0aWMgdm9pZCBwZXJmX3BlbmRpbmdfcXVldWUoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqZW50cnksCgkJCSAgICAgICB2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKSkKewoJc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKmhlYWQ7CgoJaWYgKGNtcHhjaGcoJmVudHJ5LT5uZXh0LCBOVUxMLCBQRU5ESU5HX1RBSUwpICE9IE5VTEwpCgkJcmV0dXJuOwoKCWVudHJ5LT5mdW5jID0gZnVuYzsKCgloZWFkID0gJmdldF9jcHVfdmFyKHBlcmZfcGVuZGluZ19oZWFkKTsKCglkbyB7CgkJZW50cnktPm5leHQgPSAqaGVhZDsKCX0gd2hpbGUgKGNtcHhjaGcoaGVhZCwgZW50cnktPm5leHQsIGVudHJ5KSAhPSBlbnRyeS0+bmV4dCk7CgoJc2V0X3BlcmZfY291bnRlcl9wZW5kaW5nKCk7CgoJcHV0X2NwdV92YXIocGVyZl9wZW5kaW5nX2hlYWQpOwp9CgpzdGF0aWMgaW50IF9fcGVyZl9wZW5kaW5nX3J1bih2b2lkKQp7CglzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICpsaXN0OwoJaW50IG5yID0gMDsKCglsaXN0ID0geGNoZygmX19nZXRfY3B1X3ZhcihwZXJmX3BlbmRpbmdfaGVhZCksIFBFTkRJTkdfVEFJTCk7Cgl3aGlsZSAobGlzdCAhPSBQRU5ESU5HX1RBSUwpIHsKCQl2b2lkICgqZnVuYykoc3RydWN0IHBlcmZfcGVuZGluZ19lbnRyeSAqKTsKCQlzdHJ1Y3QgcGVyZl9wZW5kaW5nX2VudHJ5ICplbnRyeSA9IGxpc3Q7CgoJCWxpc3QgPSBsaXN0LT5uZXh0OwoKCQlmdW5jID0gZW50cnktPmZ1bmM7CgkJZW50cnktPm5leHQgPSBOVUxMOwoJCS8qCgkJICogRW5zdXJlIHdlIG9ic2VydmUgdGhlIHVucXVldWUgYmVmb3JlIHdlIGlzc3VlIHRoZSB3YWtldXAsCgkJICogc28gdGhhdCB3ZSB3b24ndCBiZSB3YWl0aW5nIGZvcmV2ZXIuCgkJICogLS0gc2VlIHBlcmZfbm90X3BlbmRpbmcoKS4KCQkgKi8KCQlzbXBfd21iKCk7CgoJCWZ1bmMoZW50cnkpOwoJCW5yKys7Cgl9CgoJcmV0dXJuIG5yOwp9CgpzdGF0aWMgaW5saW5lIGludCBwZXJmX25vdF9wZW5kaW5nKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCS8qCgkgKiBJZiB3ZSBmbHVzaCBvbiB3aGF0ZXZlciBjcHUgd2UgcnVuLCB0aGVyZSBpcyBhIGNoYW5jZSB3ZSBkb24ndAoJICogbmVlZCB0byB3YWl0LgoJICovCglnZXRfY3B1KCk7CglfX3BlcmZfcGVuZGluZ19ydW4oKTsKCXB1dF9jcHUoKTsKCgkvKgoJICogRW5zdXJlIHdlIHNlZSB0aGUgcHJvcGVyIHF1ZXVlIHN0YXRlIGJlZm9yZSBnb2luZyB0byBzbGVlcAoJICogc28gdGhhdCB3ZSBkbyBub3QgbWlzcyB0aGUgd2FrZXVwLiAtLSBzZWUgcGVyZl9wZW5kaW5nX2hhbmRsZSgpCgkgKi8KCXNtcF9ybWIoKTsKCXJldHVybiBjb3VudGVyLT5wZW5kaW5nLm5leHQgPT0gTlVMTDsKfQoKc3RhdGljIHZvaWQgcGVyZl9wZW5kaW5nX3N5bmMoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJd2FpdF9ldmVudChjb3VudGVyLT53YWl0cSwgcGVyZl9ub3RfcGVuZGluZyhjb3VudGVyKSk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2RvX3BlbmRpbmcodm9pZCkKewoJX19wZXJmX3BlbmRpbmdfcnVuKCk7Cn0KCi8qCiAqIENhbGxjaGFpbiBzdXBwb3J0IC0tIGFyY2ggc3BlY2lmaWMKICovCgpfX3dlYWsgc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpwZXJmX2NhbGxjaGFpbihzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJcmV0dXJuIE5VTEw7Cn0KCi8qCiAqIE91dHB1dAogKi8KCnN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgewoJc3RydWN0IHBlcmZfY291bnRlcgkqY291bnRlcjsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YQkqZGF0YTsKCXVuc2lnbmVkIGxvbmcJCWhlYWQ7Cgl1bnNpZ25lZCBsb25nCQlvZmZzZXQ7CglpbnQJCQlubWk7CglpbnQJCQlvdmVyZmxvdzsKCWludAkJCWxvY2tlZDsKCXVuc2lnbmVkIGxvbmcJCWZsYWdzOwp9OwoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfd2FrZXVwKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJYXRvbWljX3NldCgmaGFuZGxlLT5kYXRhLT5wb2xsLCBQT0xMX0lOKTsKCglpZiAoaGFuZGxlLT5ubWkpIHsKCQloYW5kbGUtPmNvdW50ZXItPnBlbmRpbmdfd2FrZXVwID0gMTsKCQlwZXJmX3BlbmRpbmdfcXVldWUoJmhhbmRsZS0+Y291bnRlci0+cGVuZGluZywKCQkJCSAgIHBlcmZfcGVuZGluZ19jb3VudGVyKTsKCX0gZWxzZQoJCXBlcmZfY291bnRlcl93YWtldXAoaGFuZGxlLT5jb3VudGVyKTsKfQoKLyoKICogQ3VyaW91cyBsb2NraW5nIGNvbnN0cnVjdC4KICoKICogV2UgbmVlZCB0byBlbnN1cmUgYSBsYXRlciBldmVudCBkb2Vzbid0IHB1Ymxpc2ggYSBoZWFkIHdoZW4gYSBmb3JtZXIKICogZXZlbnQgaXNuJ3QgZG9uZSB3cml0aW5nLiBIb3dldmVyIHNpbmNlIHdlIG5lZWQgdG8gZGVhbCB3aXRoIE5NSXMgd2UKICogY2Fubm90IGZ1bGx5IHNlcmlhbGl6ZSB0aGluZ3MuCiAqCiAqIFdoYXQgd2UgZG8gaXMgc2VyaWFsaXplIGJldHdlZW4gQ1BVcyBzbyB3ZSBvbmx5IGhhdmUgdG8gZGVhbCB3aXRoIE5NSQogKiBuZXN0aW5nIG9uIGEgc2luZ2xlIENQVS4KICoKICogV2Ugb25seSBwdWJsaXNoIHRoZSBoZWFkIChhbmQgZ2VuZXJhdGUgYSB3YWtldXApIHdoZW4gdGhlIG91dGVyLW1vc3QKICogZXZlbnQgY29tcGxldGVzLgogKi8Kc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfbG9jayhzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlICpoYW5kbGUpCnsKCXN0cnVjdCBwZXJmX21tYXBfZGF0YSAqZGF0YSA9IGhhbmRsZS0+ZGF0YTsKCWludCBjcHU7CgoJaGFuZGxlLT5sb2NrZWQgPSAwOwoKCWxvY2FsX2lycV9zYXZlKGhhbmRsZS0+ZmxhZ3MpOwoJY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCWlmIChpbl9ubWkoKSAmJiBhdG9taWNfcmVhZCgmZGF0YS0+bG9jaykgPT0gY3B1KQoJCXJldHVybjsKCgl3aGlsZSAoYXRvbWljX2NtcHhjaGcoJmRhdGEtPmxvY2ssIC0xLCBjcHUpICE9IC0xKQoJCWNwdV9yZWxheCgpOwoKCWhhbmRsZS0+bG9ja2VkID0gMTsKfQoKc3RhdGljIHZvaWQgcGVyZl9vdXRwdXRfdW5sb2NrKHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSkKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoJdW5zaWduZWQgbG9uZyBoZWFkOwoJaW50IGNwdTsKCglkYXRhLT5kb25lX2hlYWQgPSBkYXRhLT5oZWFkOwoKCWlmICghaGFuZGxlLT5sb2NrZWQpCgkJZ290byBvdXQ7CgphZ2FpbjoKCS8qCgkgKiBUaGUgeGNoZyBpbXBsaWVzIGEgZnVsbCBiYXJyaWVyIHRoYXQgZW5zdXJlcyBhbGwgd3JpdGVzIGFyZSBkb25lCgkgKiBiZWZvcmUgd2UgcHVibGlzaCB0aGUgbmV3IGhlYWQsIG1hdGNoZWQgYnkgYSBybWIoKSBpbiB1c2Vyc3BhY2Ugd2hlbgoJICogcmVhZGluZyB0aGlzIHBvc2l0aW9uLgoJICovCgl3aGlsZSAoKGhlYWQgPSBhdG9taWNfbG9uZ194Y2hnKCZkYXRhLT5kb25lX2hlYWQsIDApKSkKCQlkYXRhLT51c2VyX3BhZ2UtPmRhdGFfaGVhZCA9IGhlYWQ7CgoJLyoKCSAqIE5NSSBjYW4gaGFwcGVuIGhlcmUsIHdoaWNoIG1lYW5zIHdlIGNhbiBtaXNzIGEgZG9uZV9oZWFkIHVwZGF0ZS4KCSAqLwoKCWNwdSA9IGF0b21pY194Y2hnKCZkYXRhLT5sb2NrLCAtMSk7CglXQVJOX09OX09OQ0UoY3B1ICE9IHNtcF9wcm9jZXNzb3JfaWQoKSk7CgoJLyoKCSAqIFRoZXJlZm9yZSB3ZSBoYXZlIHRvIHZhbGlkYXRlIHdlIGRpZCBub3QgaW5kZWVkIGRvIHNvLgoJICovCglpZiAodW5saWtlbHkoYXRvbWljX2xvbmdfcmVhZCgmZGF0YS0+ZG9uZV9oZWFkKSkpIHsKCQkvKgoJCSAqIFNpbmNlIHdlIGhhZCBpdCBsb2NrZWQsIHdlIGNhbiBsb2NrIGl0IGFnYWluLgoJCSAqLwoJCXdoaWxlIChhdG9taWNfY21weGNoZygmZGF0YS0+bG9jaywgLTEsIGNwdSkgIT0gLTEpCgkJCWNwdV9yZWxheCgpOwoKCQlnb3RvIGFnYWluOwoJfQoKCWlmIChhdG9taWNfeGNoZygmZGF0YS0+d2FrZXVwLCAwKSkKCQlwZXJmX291dHB1dF93YWtldXAoaGFuZGxlKTsKb3V0OgoJbG9jYWxfaXJxX3Jlc3RvcmUoaGFuZGxlLT5mbGFncyk7Cn0KCnN0YXRpYyBpbnQgcGVyZl9vdXRwdXRfYmVnaW4oc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlLAoJCQkgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHVuc2lnbmVkIGludCBzaXplLAoJCQkgICAgIGludCBubWksIGludCBvdmVyZmxvdykKewoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhOwoJdW5zaWduZWQgaW50IG9mZnNldCwgaGVhZDsKCgkvKgoJICogRm9yIGluaGVyaXRlZCBjb3VudGVycyB3ZSBzZW5kIGFsbCB0aGUgb3V0cHV0IHRvd2FyZHMgdGhlIHBhcmVudC4KCSAqLwoJaWYgKGNvdW50ZXItPnBhcmVudCkKCQljb3VudGVyID0gY291bnRlci0+cGFyZW50OwoKCXJjdV9yZWFkX2xvY2soKTsKCWRhdGEgPSByY3VfZGVyZWZlcmVuY2UoY291bnRlci0+ZGF0YSk7CglpZiAoIWRhdGEpCgkJZ290byBvdXQ7CgoJaGFuZGxlLT5kYXRhCSA9IGRhdGE7CgloYW5kbGUtPmNvdW50ZXIJID0gY291bnRlcjsKCWhhbmRsZS0+bm1pCSA9IG5taTsKCWhhbmRsZS0+b3ZlcmZsb3cgPSBvdmVyZmxvdzsKCglpZiAoIWRhdGEtPm5yX3BhZ2VzKQoJCWdvdG8gZmFpbDsKCglwZXJmX291dHB1dF9sb2NrKGhhbmRsZSk7CgoJZG8gewoJCW9mZnNldCA9IGhlYWQgPSBhdG9taWNfbG9uZ19yZWFkKCZkYXRhLT5oZWFkKTsKCQloZWFkICs9IHNpemU7Cgl9IHdoaWxlIChhdG9taWNfbG9uZ19jbXB4Y2hnKCZkYXRhLT5oZWFkLCBvZmZzZXQsIGhlYWQpICE9IG9mZnNldCk7CgoJaGFuZGxlLT5vZmZzZXQJPSBvZmZzZXQ7CgloYW5kbGUtPmhlYWQJPSBoZWFkOwoKCWlmICgob2Zmc2V0ID4+IFBBR0VfU0hJRlQpICE9IChoZWFkID4+IFBBR0VfU0hJRlQpKQoJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgoJcmV0dXJuIDA7CgpmYWlsOgoJcGVyZl9vdXRwdXRfd2FrZXVwKGhhbmRsZSk7Cm91dDoKCXJjdV9yZWFkX3VubG9jaygpOwoKCXJldHVybiAtRU5PU1BDOwp9CgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9jb3B5KHN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgKmhhbmRsZSwKCQkJICAgICBjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXVuc2lnbmVkIGludCBwYWdlc19tYXNrOwoJdW5zaWduZWQgaW50IG9mZnNldDsKCXVuc2lnbmVkIGludCBzaXplOwoJdm9pZCAqKnBhZ2VzOwoKCW9mZnNldAkJPSBoYW5kbGUtPm9mZnNldDsKCXBhZ2VzX21hc2sJPSBoYW5kbGUtPmRhdGEtPm5yX3BhZ2VzIC0gMTsKCXBhZ2VzCQk9IGhhbmRsZS0+ZGF0YS0+ZGF0YV9wYWdlczsKCglkbyB7CgkJdW5zaWduZWQgaW50IHBhZ2Vfb2Zmc2V0OwoJCWludCBucjsKCgkJbnIJICAgID0gKG9mZnNldCA+PiBQQUdFX1NISUZUKSAmIHBhZ2VzX21hc2s7CgkJcGFnZV9vZmZzZXQgPSBvZmZzZXQgJiAoUEFHRV9TSVpFIC0gMSk7CgkJc2l6ZQkgICAgPSBtaW5fdCh1bnNpZ25lZCBpbnQsIFBBR0VfU0laRSAtIHBhZ2Vfb2Zmc2V0LCBsZW4pOwoKCQltZW1jcHkocGFnZXNbbnJdICsgcGFnZV9vZmZzZXQsIGJ1Ziwgc2l6ZSk7CgoJCWxlbgkgICAgLT0gc2l6ZTsKCQlidWYJICAgICs9IHNpemU7CgkJb2Zmc2V0CSAgICArPSBzaXplOwoJfSB3aGlsZSAobGVuKTsKCgloYW5kbGUtPm9mZnNldCA9IG9mZnNldDsKCgkvKgoJICogQ2hlY2sgd2UgZGlkbid0IGNvcHkgcGFzdCBvdXIgcmVzZXJ2YXRpb24gd2luZG93LCB0YWtpbmcgdGhlCgkgKiBwb3NzaWJsZSB1bnNpZ25lZCBpbnQgd3JhcCBpbnRvIGFjY291bnQuCgkgKi8KCVdBUk5fT05fT05DRSgoKGxvbmcpKGhhbmRsZS0+aGVhZCAtIGhhbmRsZS0+b2Zmc2V0KSkgPCAwKTsKfQoKI2RlZmluZSBwZXJmX291dHB1dF9wdXQoaGFuZGxlLCB4KSBcCglwZXJmX291dHB1dF9jb3B5KChoYW5kbGUpLCAmKHgpLCBzaXplb2YoeCkpCgpzdGF0aWMgdm9pZCBwZXJmX291dHB1dF9lbmQoc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSAqaGFuZGxlKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyID0gaGFuZGxlLT5jb3VudGVyOwoJc3RydWN0IHBlcmZfbW1hcF9kYXRhICpkYXRhID0gaGFuZGxlLT5kYXRhOwoKCWludCB3YWtldXBfZXZlbnRzID0gY291bnRlci0+YXR0ci53YWtldXBfZXZlbnRzOwoKCWlmIChoYW5kbGUtPm92ZXJmbG93ICYmIHdha2V1cF9ldmVudHMpIHsKCQlpbnQgZXZlbnRzID0gYXRvbWljX2luY19yZXR1cm4oJmRhdGEtPmV2ZW50cyk7CgkJaWYgKGV2ZW50cyA+PSB3YWtldXBfZXZlbnRzKSB7CgkJCWF0b21pY19zdWIod2FrZXVwX2V2ZW50cywgJmRhdGEtPmV2ZW50cyk7CgkJCWF0b21pY19zZXQoJmRhdGEtPndha2V1cCwgMSk7CgkJfQoJfQoKCXBlcmZfb3V0cHV0X3VubG9jayhoYW5kbGUpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB1MzIgcGVyZl9jb3VudGVyX3BpZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCBzdHJ1Y3QgdGFza19zdHJ1Y3QgKnApCnsKCS8qCgkgKiBvbmx5IHRvcCBsZXZlbCBjb3VudGVycyBoYXZlIHRoZSBwaWQgbmFtZXNwYWNlIHRoZXkgd2VyZSBjcmVhdGVkIGluCgkgKi8KCWlmIChjb3VudGVyLT5wYXJlbnQpCgkJY291bnRlciA9IGNvdW50ZXItPnBhcmVudDsKCglyZXR1cm4gdGFza190Z2lkX25yX25zKHAsIGNvdW50ZXItPm5zKTsKfQoKc3RhdGljIHUzMiBwZXJmX2NvdW50ZXJfdGlkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHN0cnVjdCB0YXNrX3N0cnVjdCAqcCkKewoJLyoKCSAqIG9ubHkgdG9wIGxldmVsIGNvdW50ZXJzIGhhdmUgdGhlIHBpZCBuYW1lc3BhY2UgdGhleSB3ZXJlIGNyZWF0ZWQgaW4KCSAqLwoJaWYgKGNvdW50ZXItPnBhcmVudCkKCQljb3VudGVyID0gY291bnRlci0+cGFyZW50OwoKCXJldHVybiB0YXNrX3BpZF9ucl9ucyhwLCBjb3VudGVyLT5ucyk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCWludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJaW50IHJldDsKCXU2NCBzYW1wbGVfdHlwZSA9IGNvdW50ZXItPmF0dHIuc2FtcGxlX3R5cGU7CglzdHJ1Y3QgcGVyZl9vdXRwdXRfaGFuZGxlIGhhbmRsZTsKCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlciBoZWFkZXI7Cgl1NjQgaXA7CglzdHJ1Y3QgewoJCXUzMiBwaWQsIHRpZDsKCX0gdGlkX2VudHJ5OwoJc3RydWN0IHsKCQl1NjQgaWQ7CgkJdTY0IGNvdW50ZXI7Cgl9IGdyb3VwX2VudHJ5OwoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICpjYWxsY2hhaW4gPSBOVUxMOwoJaW50IGNhbGxjaGFpbl9zaXplID0gMDsKCXU2NCB0aW1lOwoJc3RydWN0IHsKCQl1MzIgY3B1LCByZXNlcnZlZDsKCX0gY3B1X2VudHJ5OwoKCWhlYWRlci50eXBlID0gMDsKCWhlYWRlci5zaXplID0gc2l6ZW9mKGhlYWRlcik7CgoJaGVhZGVyLm1pc2MgPSBQRVJGX0VWRU5UX01JU0NfT1ZFUkZMT1c7CgloZWFkZXIubWlzYyB8PSBwZXJmX21pc2NfZmxhZ3MocmVncyk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSVApIHsKCQlpcCA9IHBlcmZfaW5zdHJ1Y3Rpb25fcG9pbnRlcihyZWdzKTsKCQloZWFkZXIudHlwZSB8PSBQRVJGX1NBTVBMRV9JUDsKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YoaXApOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJRCkgewoJCS8qIG5hbWVzcGFjZSBpc3N1ZXMgKi8KCQl0aWRfZW50cnkucGlkID0gcGVyZl9jb3VudGVyX3BpZChjb3VudGVyLCBjdXJyZW50KTsKCQl0aWRfZW50cnkudGlkID0gcGVyZl9jb3VudGVyX3RpZChjb3VudGVyLCBjdXJyZW50KTsKCgkJaGVhZGVyLnR5cGUgfD0gUEVSRl9TQU1QTEVfVElEOwoJCWhlYWRlci5zaXplICs9IHNpemVvZih0aWRfZW50cnkpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX1RJTUUpIHsKCQkvKgoJCSAqIE1heWJlIGRvIGJldHRlciBvbiB4ODYgYW5kIHByb3ZpZGUgY3B1X2Nsb2NrX25taSgpCgkJICovCgkJdGltZSA9IHNjaGVkX2Nsb2NrKCk7CgoJCWhlYWRlci50eXBlIHw9IFBFUkZfU0FNUExFX1RJTUU7CgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQUREUikgewoJCWhlYWRlci50eXBlIHw9IFBFUkZfU0FNUExFX0FERFI7CgkJaGVhZGVyLnNpemUgKz0gc2l6ZW9mKHU2NCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ09ORklHKSB7CgkJaGVhZGVyLnR5cGUgfD0gUEVSRl9TQU1QTEVfQ09ORklHOwoJCWhlYWRlci5zaXplICs9IHNpemVvZih1NjQpOwoJfQoKCWlmIChzYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0NQVSkgewoJCWhlYWRlci50eXBlIHw9IFBFUkZfU0FNUExFX0NQVTsKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YoY3B1X2VudHJ5KTsKCgkJY3B1X2VudHJ5LmNwdSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7Cgl9CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfR1JPVVApIHsKCQloZWFkZXIudHlwZSB8PSBQRVJGX1NBTVBMRV9HUk9VUDsKCQloZWFkZXIuc2l6ZSArPSBzaXplb2YodTY0KSArCgkJCWNvdW50ZXItPm5yX3NpYmxpbmdzICogc2l6ZW9mKGdyb3VwX2VudHJ5KTsKCX0KCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9DQUxMQ0hBSU4pIHsKCQljYWxsY2hhaW4gPSBwZXJmX2NhbGxjaGFpbihyZWdzKTsKCgkJaWYgKGNhbGxjaGFpbikgewoJCQljYWxsY2hhaW5fc2l6ZSA9ICgxICsgY2FsbGNoYWluLT5ucikgKiBzaXplb2YodTY0KTsKCgkJCWhlYWRlci50eXBlIHw9IFBFUkZfU0FNUExFX0NBTExDSEFJTjsKCQkJaGVhZGVyLnNpemUgKz0gY2FsbGNoYWluX3NpemU7CgkJfQoJfQoKCXJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIGhlYWRlci5zaXplLCBubWksIDEpOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGhlYWRlcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfSVApCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGlwKTsKCglpZiAoc2FtcGxlX3R5cGUgJiBQRVJGX1NBTVBMRV9USUQpCgkJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIHRpZF9lbnRyeSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfVElNRSkKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgdGltZSk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQUREUikKCQlwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgYWRkcik7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ09ORklHKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb3VudGVyLT5hdHRyLmNvbmZpZyk7CgoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfQ1BVKQoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjcHVfZW50cnkpOwoKCS8qCgkgKiBYWFggUEVSRl9TQU1QTEVfR1JPVVAgdnMgaW5oZXJpdGVkIGNvdW50ZXJzIHNlZW1zIGRpZmZpY3VsdC4KCSAqLwoJaWYgKHNhbXBsZV90eXBlICYgUEVSRl9TQU1QTEVfR1JPVVApIHsKCQlzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXIsICpzdWI7CgkJdTY0IG5yID0gY291bnRlci0+bnJfc2libGluZ3M7CgoJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBucik7CgoJCWxlYWRlciA9IGNvdW50ZXItPmdyb3VwX2xlYWRlcjsKCQlsaXN0X2Zvcl9lYWNoX2VudHJ5KHN1YiwgJmxlYWRlci0+c2libGluZ19saXN0LCBsaXN0X2VudHJ5KSB7CgkJCWlmIChzdWIgIT0gY291bnRlcikKCQkJCXN1Yi0+cG11LT5yZWFkKHN1Yik7CgoJCQlncm91cF9lbnRyeS5pZCA9IHN1Yi0+aWQ7CgkJCWdyb3VwX2VudHJ5LmNvdW50ZXIgPSBhdG9taWM2NF9yZWFkKCZzdWItPmNvdW50KTsKCgkJCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBncm91cF9lbnRyeSk7CgkJfQoJfQoKCWlmIChjYWxsY2hhaW4pCgkJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBjYWxsY2hhaW4sIGNhbGxjaGFpbl9zaXplKTsKCglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIGZvcmsgdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9mb3JrX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXBwaWQ7Cgl9IGV2ZW50Owp9OwoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2Zvcmtfb3V0cHV0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICAgIHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBmb3JrX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZTsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzayA9IGZvcmtfZXZlbnQtPnRhc2s7CglpbnQgcmV0ID0gcGVyZl9vdXRwdXRfYmVnaW4oJmhhbmRsZSwgY291bnRlciwgc2l6ZSwgMCwgMCk7CgoJaWYgKHJldCkKCQlyZXR1cm47CgoJZm9ya19ldmVudC0+ZXZlbnQucGlkID0gcGVyZl9jb3VudGVyX3BpZChjb3VudGVyLCB0YXNrKTsKCWZvcmtfZXZlbnQtPmV2ZW50LnBwaWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIHRhc2stPnJlYWxfcGFyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgZm9ya19ldmVudC0+ZXZlbnQpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9mb3JrX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5hdHRyLmNvbW0gfHwgY291bnRlci0+YXR0ci5tbWFwKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfZm9ya19jdHgoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2NvdW50ZXJfZm9ya19tYXRjaChjb3VudGVyKSkKCQkJcGVyZl9jb3VudGVyX2Zvcmtfb3V0cHV0KGNvdW50ZXIsIGZvcmtfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9mb3JrX2V2ZW50KHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQgKmZvcmtfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2NvdW50ZXJfZm9ya19jdHgoJmNwdWN0eC0+Y3R4LCBmb3JrX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl9mb3JrX2N0eChjdHgsIGZvcmtfZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2Zvcmsoc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9mb3JrX2V2ZW50IGZvcmtfZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY29tbV9jb3VudGVycykgJiYKCSAgICAhYXRvbWljX3JlYWQoJm5yX21tYXBfY291bnRlcnMpKQoJCXJldHVybjsKCglmb3JrX2V2ZW50ID0gKHN0cnVjdCBwZXJmX2ZvcmtfZXZlbnQpewoJCS50YXNrCT0gdGFzaywKCQkuZXZlbnQgID0gewoJCQkuaGVhZGVyID0gewoJCQkJLnR5cGUgPSBQRVJGX0VWRU5UX0ZPUkssCgkJCQkuc2l6ZSA9IHNpemVvZihmb3JrX2V2ZW50LmV2ZW50KSwKCQkJfSwKCQl9LAoJfTsKCglwZXJmX2NvdW50ZXJfZm9ya19ldmVudCgmZm9ya19ldmVudCk7Cn0KCi8qCiAqIGNvbW0gdHJhY2tpbmcKICovCgpzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IHsKCXN0cnVjdCB0YXNrX3N0cnVjdAkqdGFzazsKCWNoYXIJCQkqY29tbTsKCWludAkJCWNvbW1fc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCX0gZXZlbnQ7Cn07CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfY29tbV9vdXRwdXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwKCQkJCSAgICAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgc2l6ZSA9IGNvbW1fZXZlbnQtPmV2ZW50LmhlYWRlci5zaXplOwoJaW50IHJldCA9IHBlcmZfb3V0cHV0X2JlZ2luKCZoYW5kbGUsIGNvdW50ZXIsIHNpemUsIDAsIDApOwoKCWlmIChyZXQpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQtPmV2ZW50LnBpZCA9IHBlcmZfY291bnRlcl9waWQoY291bnRlciwgY29tbV9ldmVudC0+dGFzayk7Cgljb21tX2V2ZW50LT5ldmVudC50aWQgPSBwZXJmX2NvdW50ZXJfdGlkKGNvdW50ZXIsIGNvbW1fZXZlbnQtPnRhc2spOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCBjb21tX2V2ZW50LT5ldmVudCk7CglwZXJmX291dHB1dF9jb3B5KCZoYW5kbGUsIGNvbW1fZXZlbnQtPmNvbW0sCgkJCQkgICBjb21tX2V2ZW50LT5jb21tX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9jb21tX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9jb21tX2N0eChzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkJCSAgc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfY291bnRlcl9jb21tX21hdGNoKGNvdW50ZXIpKQoJCQlwZXJmX2NvdW50ZXJfY29tbV9vdXRwdXQoY291bnRlciwgY29tbV9ldmVudCk7Cgl9CglyY3VfcmVhZF91bmxvY2soKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX2NvbW1fZXZlbnQoc3RydWN0IHBlcmZfY29tbV9ldmVudCAqY29tbV9ldmVudCkKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eDsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgaW50IHNpemU7CgljaGFyICpjb21tID0gY29tbV9ldmVudC0+dGFzay0+Y29tbTsKCglzaXplID0gQUxJR04oc3RybGVuKGNvbW0pKzEsIHNpemVvZih1NjQpKTsKCgljb21tX2V2ZW50LT5jb21tID0gY29tbTsKCWNvbW1fZXZlbnQtPmNvbW1fc2l6ZSA9IHNpemU7CgoJY29tbV9ldmVudC0+ZXZlbnQuaGVhZGVyLnNpemUgPSBzaXplb2YoY29tbV9ldmVudC0+ZXZlbnQpICsgc2l6ZTsKCgljcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglwZXJmX2NvdW50ZXJfY29tbV9jdHgoJmNwdWN0eC0+Y3R4LCBjb21tX2V2ZW50KTsKCXB1dF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfY291bnRlcl9jb21tX2N0eChjdHgsIGNvbW1fZXZlbnQpOwoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnZvaWQgcGVyZl9jb3VudGVyX2NvbW0oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb21tX2V2ZW50IGNvbW1fZXZlbnQ7CgoJaWYgKCFhdG9taWNfcmVhZCgmbnJfY29tbV9jb3VudGVycykpCgkJcmV0dXJuOwoKCWNvbW1fZXZlbnQgPSAoc3RydWN0IHBlcmZfY29tbV9ldmVudCl7CgkJLnRhc2sJPSB0YXNrLAoJCS5ldmVudCAgPSB7CgkJCS5oZWFkZXIgPSB7IC50eXBlID0gUEVSRl9FVkVOVF9DT01NLCB9LAoJCX0sCgl9OwoKCXBlcmZfY291bnRlcl9jb21tX2V2ZW50KCZjb21tX2V2ZW50KTsKfQoKLyoKICogbW1hcCB0cmFja2luZwogKi8KCnN0cnVjdCBwZXJmX21tYXBfZXZlbnQgewoJc3RydWN0IHZtX2FyZWFfc3RydWN0CSp2bWE7CgoJY29uc3QgY2hhcgkJKmZpbGVfbmFtZTsKCWludAkJCWZpbGVfc2l6ZTsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgoJCXUzMgkJCQlwaWQ7CgkJdTMyCQkJCXRpZDsKCQl1NjQJCQkJc3RhcnQ7CgkJdTY0CQkJCWxlbjsKCQl1NjQJCQkJcGdvZmY7Cgl9IGV2ZW50Owp9OwoKc3RhdGljIHZvaWQgcGVyZl9jb3VudGVyX21tYXBfb3V0cHV0KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICAgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHNpemUgPSBtbWFwX2V2ZW50LT5ldmVudC5oZWFkZXIuc2l6ZTsKCWludCByZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplLCAwLCAwKTsKCglpZiAocmV0KQoJCXJldHVybjsKCgltbWFwX2V2ZW50LT5ldmVudC5waWQgPSBwZXJmX2NvdW50ZXJfcGlkKGNvdW50ZXIsIGN1cnJlbnQpOwoJbW1hcF9ldmVudC0+ZXZlbnQudGlkID0gcGVyZl9jb3VudGVyX3RpZChjb3VudGVyLCBjdXJyZW50KTsKCglwZXJmX291dHB1dF9wdXQoJmhhbmRsZSwgbW1hcF9ldmVudC0+ZXZlbnQpOwoJcGVyZl9vdXRwdXRfY29weSgmaGFuZGxlLCBtbWFwX2V2ZW50LT5maWxlX25hbWUsCgkJCQkgICBtbWFwX2V2ZW50LT5maWxlX3NpemUpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgpzdGF0aWMgaW50IHBlcmZfY291bnRlcl9tbWFwX21hdGNoKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCQkgICBzdHJ1Y3QgcGVyZl9tbWFwX2V2ZW50ICptbWFwX2V2ZW50KQp7CglpZiAoY291bnRlci0+YXR0ci5tbWFwKQoJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBwZXJmX2NvdW50ZXJfbW1hcF9jdHgoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHgsCgkJCQkgIHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CgoJaWYgKHN5c3RlbV9zdGF0ZSAhPSBTWVNURU1fUlVOTklORyB8fCBsaXN0X2VtcHR5KCZjdHgtPmV2ZW50X2xpc3QpKQoJCXJldHVybjsKCglyY3VfcmVhZF9sb2NrKCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3JjdShjb3VudGVyLCAmY3R4LT5ldmVudF9saXN0LCBldmVudF9lbnRyeSkgewoJCWlmIChwZXJmX2NvdW50ZXJfbW1hcF9tYXRjaChjb3VudGVyLCBtbWFwX2V2ZW50KSkKCQkJcGVyZl9jb3VudGVyX21tYXBfb3V0cHV0KGNvdW50ZXIsIG1tYXBfZXZlbnQpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9tbWFwX2V2ZW50KHN0cnVjdCBwZXJmX21tYXBfZXZlbnQgKm1tYXBfZXZlbnQpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hID0gbW1hcF9ldmVudC0+dm1hOwoJc3RydWN0IGZpbGUgKmZpbGUgPSB2bWEtPnZtX2ZpbGU7Cgl1bnNpZ25lZCBpbnQgc2l6ZTsKCWNoYXIgdG1wWzE2XTsKCWNoYXIgKmJ1ZiA9IE5VTEw7Cgljb25zdCBjaGFyICpuYW1lOwoKCWlmIChmaWxlKSB7CgkJYnVmID0ga3phbGxvYyhQQVRIX01BWCwgR0ZQX0tFUk5FTCk7CgkJaWYgKCFidWYpIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy9lbm9tZW0iLCBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoJCW5hbWUgPSBkX3BhdGgoJmZpbGUtPmZfcGF0aCwgYnVmLCBQQVRIX01BWCk7CgkJaWYgKElTX0VSUihuYW1lKSkgewoJCQluYW1lID0gc3RybmNweSh0bXAsICIvL3Rvb2xvbmciLCBzaXplb2YodG1wKSk7CgkJCWdvdG8gZ290X25hbWU7CgkJfQoJfSBlbHNlIHsKCQluYW1lID0gYXJjaF92bWFfbmFtZShtbWFwX2V2ZW50LT52bWEpOwoJCWlmIChuYW1lKQoJCQlnb3RvIGdvdF9uYW1lOwoKCQlpZiAoIXZtYS0+dm1fbW0pIHsKCQkJbmFtZSA9IHN0cm5jcHkodG1wLCAiW3Zkc29dIiwgc2l6ZW9mKHRtcCkpOwoJCQlnb3RvIGdvdF9uYW1lOwoJCX0KCgkJbmFtZSA9IHN0cm5jcHkodG1wLCAiLy9hbm9uIiwgc2l6ZW9mKHRtcCkpOwoJCWdvdG8gZ290X25hbWU7Cgl9Cgpnb3RfbmFtZToKCXNpemUgPSBBTElHTihzdHJsZW4obmFtZSkrMSwgc2l6ZW9mKHU2NCkpOwoKCW1tYXBfZXZlbnQtPmZpbGVfbmFtZSA9IG5hbWU7CgltbWFwX2V2ZW50LT5maWxlX3NpemUgPSBzaXplOwoKCW1tYXBfZXZlbnQtPmV2ZW50LmhlYWRlci5zaXplID0gc2l6ZW9mKG1tYXBfZXZlbnQtPmV2ZW50KSArIHNpemU7CgoJY3B1Y3R4ID0gJmdldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJcGVyZl9jb3VudGVyX21tYXBfY3R4KCZjcHVjdHgtPmN0eCwgbW1hcF9ldmVudCk7CglwdXRfY3B1X3ZhcihwZXJmX2NwdV9jb250ZXh0KTsKCglyY3VfcmVhZF9sb2NrKCk7CgkvKgoJICogZG9lc24ndCByZWFsbHkgbWF0dGVyIHdoaWNoIG9mIHRoZSBjaGlsZCBjb250ZXh0cyB0aGUKCSAqIGV2ZW50cyBlbmRzIHVwIGluLgoJICovCgljdHggPSByY3VfZGVyZWZlcmVuY2UoY3VycmVudC0+cGVyZl9jb3VudGVyX2N0eHApOwoJaWYgKGN0eCkKCQlwZXJmX2NvdW50ZXJfbW1hcF9jdHgoY3R4LCBtbWFwX2V2ZW50KTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWtmcmVlKGJ1Zik7Cn0KCnZvaWQgX19wZXJmX2NvdW50ZXJfbW1hcChzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHBlcmZfbW1hcF9ldmVudCBtbWFwX2V2ZW50OwoKCWlmICghYXRvbWljX3JlYWQoJm5yX21tYXBfY291bnRlcnMpKQoJCXJldHVybjsKCgltbWFwX2V2ZW50ID0gKHN0cnVjdCBwZXJmX21tYXBfZXZlbnQpewoJCS52bWEJPSB2bWEsCgkJLmV2ZW50ICA9IHsKCQkJLmhlYWRlciA9IHsgLnR5cGUgPSBQRVJGX0VWRU5UX01NQVAsIH0sCgkJCS5zdGFydCAgPSB2bWEtPnZtX3N0YXJ0LAoJCQkubGVuICAgID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0LAoJCQkucGdvZmYgID0gdm1hLT52bV9wZ29mZiwKCQl9LAoJfTsKCglwZXJmX2NvdW50ZXJfbW1hcF9ldmVudCgmbW1hcF9ldmVudCk7Cn0KCi8qCiAqIExvZyBzYW1wbGVfcGVyaW9kIGNoYW5nZXMgc28gdGhhdCBhbmFseXppbmcgdG9vbHMgY2FuIHJlLW5vcm1hbGl6ZSB0aGUKICogZXZlbnQgZmxvdy4KICovCgpzdGF0aWMgdm9pZCBwZXJmX2xvZ19wZXJpb2Qoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgdTY0IHBlcmlvZCkKewoJc3RydWN0IHBlcmZfb3V0cHV0X2hhbmRsZSBoYW5kbGU7CglpbnQgcmV0OwoKCXN0cnVjdCB7CgkJc3RydWN0IHBlcmZfZXZlbnRfaGVhZGVyCWhlYWRlcjsKCQl1NjQJCQkJdGltZTsKCQl1NjQJCQkJcGVyaW9kOwoJfSBmcmVxX2V2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9FVkVOVF9QRVJJT0QsCgkJCS5taXNjID0gMCwKCQkJLnNpemUgPSBzaXplb2YoZnJlcV9ldmVudCksCgkJfSwKCQkudGltZSA9IHNjaGVkX2Nsb2NrKCksCgkJLnBlcmlvZCA9IHBlcmlvZCwKCX07CgoJaWYgKGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QgPT0gcGVyaW9kKQoJCXJldHVybjsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplb2YoZnJlcV9ldmVudCksIDAsIDApOwoJaWYgKHJldCkKCQlyZXR1cm47CgoJcGVyZl9vdXRwdXRfcHV0KCZoYW5kbGUsIGZyZXFfZXZlbnQpOwoJcGVyZl9vdXRwdXRfZW5kKCZoYW5kbGUpOwp9CgovKgogKiBJUlEgdGhyb3R0bGUgbG9nZ2luZwogKi8KCnN0YXRpYyB2b2lkIHBlcmZfbG9nX3Rocm90dGxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIGludCBlbmFibGUpCnsKCXN0cnVjdCBwZXJmX291dHB1dF9oYW5kbGUgaGFuZGxlOwoJaW50IHJldDsKCglzdHJ1Y3QgewoJCXN0cnVjdCBwZXJmX2V2ZW50X2hlYWRlcgloZWFkZXI7CgkJdTY0CQkJCXRpbWU7Cgl9IHRocm90dGxlX2V2ZW50ID0gewoJCS5oZWFkZXIgPSB7CgkJCS50eXBlID0gUEVSRl9FVkVOVF9USFJPVFRMRSArIDEsCgkJCS5taXNjID0gMCwKCQkJLnNpemUgPSBzaXplb2YodGhyb3R0bGVfZXZlbnQpLAoJCX0sCgkJLnRpbWUgPSBzY2hlZF9jbG9jaygpLAoJfTsKCglyZXQgPSBwZXJmX291dHB1dF9iZWdpbigmaGFuZGxlLCBjb3VudGVyLCBzaXplb2YodGhyb3R0bGVfZXZlbnQpLCAxLCAwKTsKCWlmIChyZXQpCgkJcmV0dXJuOwoKCXBlcmZfb3V0cHV0X3B1dCgmaGFuZGxlLCB0aHJvdHRsZV9ldmVudCk7CglwZXJmX291dHB1dF9lbmQoJmhhbmRsZSk7Cn0KCi8qCiAqIEdlbmVyaWMgY291bnRlciBvdmVyZmxvdyBoYW5kbGluZy4KICovCgppbnQgcGVyZl9jb3VudGVyX292ZXJmbG93KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsCgkJCSAgaW50IG5taSwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MsIHU2NCBhZGRyKQp7CglpbnQgZXZlbnRzID0gYXRvbWljX3JlYWQoJmNvdW50ZXItPmV2ZW50X2xpbWl0KTsKCWludCB0aHJvdHRsZSA9IGNvdW50ZXItPnBtdS0+dW50aHJvdHRsZSAhPSBOVUxMOwoJaW50IHJldCA9IDA7CgoJaWYgKCF0aHJvdHRsZSkgewoJCWNvdW50ZXItPmh3LmludGVycnVwdHMrKzsKCX0gZWxzZSB7CgkJaWYgKGNvdW50ZXItPmh3LmludGVycnVwdHMgIT0gTUFYX0lOVEVSUlVQVFMpIHsKCQkJY291bnRlci0+aHcuaW50ZXJydXB0cysrOwoJCQlpZiAoSFoqY291bnRlci0+aHcuaW50ZXJydXB0cyA+ICh1NjQpc3lzY3RsX3BlcmZfY291bnRlcl9saW1pdCkgewoJCQkJY291bnRlci0+aHcuaW50ZXJydXB0cyA9IE1BWF9JTlRFUlJVUFRTOwoJCQkJcGVyZl9sb2dfdGhyb3R0bGUoY291bnRlciwgMCk7CgkJCQlyZXQgPSAxOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyoKCQkJICogS2VlcCByZS1kaXNhYmxpbmcgY291bnRlcnMgZXZlbiB0aG91Z2ggb24gdGhlIHByZXZpb3VzCgkJCSAqIHBhc3Mgd2UgZGlzYWJsZWQgaXQgLSBqdXN0IGluIGNhc2Ugd2UgcmFjZWQgd2l0aCBhCgkJCSAqIHNjaGVkLWluIGFuZCB0aGUgY291bnRlciBnb3QgZW5hYmxlZCBhZ2FpbjoKCQkJICovCgkJCXJldCA9IDE7CgkJfQoJfQoKCS8qCgkgKiBYWFggZXZlbnRfbGltaXQgbWlnaHQgbm90IHF1aXRlIHdvcmsgYXMgZXhwZWN0ZWQgb24gaW5oZXJpdGVkCgkgKiBjb3VudGVycwoJICovCgoJY291bnRlci0+cGVuZGluZ19raWxsID0gUE9MTF9JTjsKCWlmIChldmVudHMgJiYgYXRvbWljX2RlY19hbmRfdGVzdCgmY291bnRlci0+ZXZlbnRfbGltaXQpKSB7CgkJcmV0ID0gMTsKCQljb3VudGVyLT5wZW5kaW5nX2tpbGwgPSBQT0xMX0hVUDsKCQlpZiAobm1pKSB7CgkJCWNvdW50ZXItPnBlbmRpbmdfZGlzYWJsZSA9IDE7CgkJCXBlcmZfcGVuZGluZ19xdWV1ZSgmY291bnRlci0+cGVuZGluZywKCQkJCQkgICBwZXJmX3BlbmRpbmdfY291bnRlcik7CgkJfSBlbHNlCgkJCXBlcmZfY291bnRlcl9kaXNhYmxlKGNvdW50ZXIpOwoJfQoKCXBlcmZfY291bnRlcl9vdXRwdXQoY291bnRlciwgbm1pLCByZWdzLCBhZGRyKTsKCXJldHVybiByZXQ7Cn0KCi8qCiAqIEdlbmVyaWMgc29mdHdhcmUgY291bnRlciBpbmZyYXN0cnVjdHVyZQogKi8KCnN0YXRpYyB2b2lkIHBlcmZfc3djb3VudGVyX3VwZGF0ZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7Cgl1NjQgcHJldiwgbm93OwoJczY0IGRlbHRhOwoKYWdhaW46CglwcmV2ID0gYXRvbWljNjRfcmVhZCgmaHdjLT5wcmV2X2NvdW50KTsKCW5vdyA9IGF0b21pYzY0X3JlYWQoJmh3Yy0+Y291bnQpOwoJaWYgKGF0b21pYzY0X2NtcHhjaGcoJmh3Yy0+cHJldl9jb3VudCwgcHJldiwgbm93KSAhPSBwcmV2KQoJCWdvdG8gYWdhaW47CgoJZGVsdGEgPSBub3cgLSBwcmV2OwoKCWF0b21pYzY0X2FkZChkZWx0YSwgJmNvdW50ZXItPmNvdW50KTsKCWF0b21pYzY0X3N1YihkZWx0YSwgJmh3Yy0+cGVyaW9kX2xlZnQpOwp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9zZXRfcGVyaW9kKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBod19wZXJmX2NvdW50ZXIgKmh3YyA9ICZjb3VudGVyLT5odzsKCXM2NCBsZWZ0ID0gYXRvbWljNjRfcmVhZCgmaHdjLT5wZXJpb2RfbGVmdCk7CglzNjQgcGVyaW9kID0gaHdjLT5zYW1wbGVfcGVyaW9kOwoKCWlmICh1bmxpa2VseShsZWZ0IDw9IC1wZXJpb2QpKSB7CgkJbGVmdCA9IHBlcmlvZDsKCQlhdG9taWM2NF9zZXQoJmh3Yy0+cGVyaW9kX2xlZnQsIGxlZnQpOwoJfQoKCWlmICh1bmxpa2VseShsZWZ0IDw9IDApKSB7CgkJbGVmdCArPSBwZXJpb2Q7CgkJYXRvbWljNjRfYWRkKHBlcmlvZCwgJmh3Yy0+cGVyaW9kX2xlZnQpOwoJfQoKCWF0b21pYzY0X3NldCgmaHdjLT5wcmV2X2NvdW50LCAtbGVmdCk7CglhdG9taWM2NF9zZXQoJmh3Yy0+Y291bnQsIC1sZWZ0KTsKfQoKc3RhdGljIGVudW0gaHJ0aW1lcl9yZXN0YXJ0IHBlcmZfc3djb3VudGVyX2hydGltZXIoc3RydWN0IGhydGltZXIgKmhydGltZXIpCnsKCWVudW0gaHJ0aW1lcl9yZXN0YXJ0IHJldCA9IEhSVElNRVJfUkVTVEFSVDsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CglzdHJ1Y3QgcHRfcmVncyAqcmVnczsKCXU2NCBwZXJpb2Q7CgoJY291bnRlcgk9IGNvbnRhaW5lcl9vZihocnRpbWVyLCBzdHJ1Y3QgcGVyZl9jb3VudGVyLCBody5ocnRpbWVyKTsKCWNvdW50ZXItPnBtdS0+cmVhZChjb3VudGVyKTsKCglyZWdzID0gZ2V0X2lycV9yZWdzKCk7CgkvKgoJICogSW4gY2FzZSB3ZSBleGNsdWRlIGtlcm5lbCBJUHMgb3IgYXJlIHNvbWVob3cgbm90IGluIGludGVycnVwdAoJICogY29udGV4dCwgcHJvdmlkZSB0aGUgbmV4dCBiZXN0IHRoaW5nLCB0aGUgdXNlciBJUC4KCSAqLwoJaWYgKChjb3VudGVyLT5hdHRyLmV4Y2x1ZGVfa2VybmVsIHx8ICFyZWdzKSAmJgoJCQkhY291bnRlci0+YXR0ci5leGNsdWRlX3VzZXIpCgkJcmVncyA9IHRhc2tfcHRfcmVncyhjdXJyZW50KTsKCglpZiAocmVncykgewoJCWlmIChwZXJmX2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgMCwgcmVncywgMCkpCgkJCXJldCA9IEhSVElNRVJfTk9SRVNUQVJUOwoJfQoKCXBlcmlvZCA9IG1heF90KHU2NCwgMTAwMDAsIGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QpOwoJaHJ0aW1lcl9mb3J3YXJkX25vdyhocnRpbWVyLCBuc190b19rdGltZShwZXJpb2QpKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBwZXJmX3N3Y291bnRlcl9vdmVyZmxvdyhzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJICAgIGludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJcGVyZl9zd2NvdW50ZXJfdXBkYXRlKGNvdW50ZXIpOwoJcGVyZl9zd2NvdW50ZXJfc2V0X3BlcmlvZChjb3VudGVyKTsKCWlmIChwZXJmX2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgbm1pLCByZWdzLCBhZGRyKSkKCQkvKiBzb2Z0LWRpc2FibGUgdGhlIGNvdW50ZXIgKi8KCQk7Cgp9CgpzdGF0aWMgaW50IHBlcmZfc3djb3VudGVyX2lzX2NvdW50aW5nKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBjb3VudDsKCglpZiAoY291bnRlci0+c3RhdGUgPT0gUEVSRl9DT1VOVEVSX1NUQVRFX0FDVElWRSkKCQlyZXR1cm4gMTsKCglpZiAoY291bnRlci0+c3RhdGUgIT0gUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybiAwOwoKCS8qCgkgKiBJZiB0aGUgY291bnRlciBpcyBpbmFjdGl2ZSwgaXQgY291bGQgYmUganVzdCBiZWNhdXNlCgkgKiBpdHMgdGFzayBpcyBzY2hlZHVsZWQgb3V0LCBvciBiZWNhdXNlIGl0J3MgaW4gYSBncm91cAoJICogd2hpY2ggY291bGQgbm90IGdvIG9uIHRoZSBQTVUuICBXZSB3YW50IHRvIGNvdW50IGluCgkgKiB0aGUgZmlyc3QgY2FzZSBidXQgbm90IHRoZSBzZWNvbmQuICBJZiB0aGUgY29udGV4dCBpcwoJICogY3VycmVudGx5IGFjdGl2ZSB0aGVuIGFuIGluYWN0aXZlIHNvZnR3YXJlIGNvdW50ZXIgbXVzdAoJICogYmUgdGhlIHNlY29uZCBjYXNlLiAgSWYgaXQncyBub3QgY3VycmVudGx5IGFjdGl2ZSB0aGVuCgkgKiB3ZSBuZWVkIHRvIGtub3cgd2hldGhlciB0aGUgY291bnRlciB3YXMgYWN0aXZlIHdoZW4gdGhlCgkgKiBjb250ZXh0IHdhcyBsYXN0IGFjdGl2ZSwgd2hpY2ggd2UgY2FuIGRldGVybWluZSBieQoJICogY29tcGFyaW5nIGNvdW50ZXItPnRzdGFtcF9zdG9wcGVkIHdpdGggY3R4LT50aW1lLgoJICoKCSAqIFdlIGFyZSB3aXRoaW4gYW4gUkNVIHJlYWQtc2lkZSBjcml0aWNhbCBzZWN0aW9uLAoJICogd2hpY2ggcHJvdGVjdHMgdGhlIGV4aXN0ZW5jZSBvZiAqY3R4LgoJICovCgljdHggPSBjb3VudGVyLT5jdHg7CglzcGluX2xvY2tfaXJxc2F2ZSgmY3R4LT5sb2NrLCBmbGFncyk7Cgljb3VudCA9IDE7CgkvKiBSZS1jaGVjayBzdGF0ZSBub3cgd2UgaGF2ZSB0aGUgbG9jayAqLwoJaWYgKGNvdW50ZXItPnN0YXRlIDwgUEVSRl9DT1VOVEVSX1NUQVRFX0lOQUNUSVZFIHx8CgkgICAgY291bnRlci0+Y3R4LT5pc19hY3RpdmUgfHwKCSAgICBjb3VudGVyLT50c3RhbXBfc3RvcHBlZCA8IGN0eC0+dGltZSkKCQljb3VudCA9IDA7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjdHgtPmxvY2ssIGZsYWdzKTsKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIGludCBwZXJmX3N3Y291bnRlcl9tYXRjaChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLAoJCQkJZW51bSBwZXJmX2V2ZW50X3R5cGVzIHR5cGUsCgkJCQl1MzIgZXZlbnQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cgl1NjQgZXZlbnRfY29uZmlnOwoKCWV2ZW50X2NvbmZpZyA9ICgodTY0KSB0eXBlIDw8IFBFUkZfQ09VTlRFUl9UWVBFX1NISUZUKSB8IGV2ZW50OwoKCWlmICghcGVyZl9zd2NvdW50ZXJfaXNfY291bnRpbmcoY291bnRlcikpCgkJcmV0dXJuIDA7CgoJaWYgKGNvdW50ZXItPmF0dHIuY29uZmlnICE9IGV2ZW50X2NvbmZpZykKCQlyZXR1cm4gMDsKCglpZiAocmVncykgewoJCWlmIChjb3VudGVyLT5hdHRyLmV4Y2x1ZGVfdXNlciAmJiB1c2VyX21vZGUocmVncykpCgkJCXJldHVybiAwOwoKCQlpZiAoY291bnRlci0+YXR0ci5leGNsdWRlX2tlcm5lbCAmJiAhdXNlcl9tb2RlKHJlZ3MpKQoJCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfYWRkKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBuciwKCQkJICAgICAgIGludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJaW50IG5lZyA9IGF0b21pYzY0X2FkZF9uZWdhdGl2ZShuciwgJmNvdW50ZXItPmh3LmNvdW50KTsKCglpZiAoY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCAmJiAhbmVnICYmIHJlZ3MpCgkJcGVyZl9zd2NvdW50ZXJfb3ZlcmZsb3coY291bnRlciwgbm1pLCByZWdzLCBhZGRyKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfY3R4X2V2ZW50KHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4LAoJCQkJICAgICBlbnVtIHBlcmZfZXZlbnRfdHlwZXMgdHlwZSwgdTMyIGV2ZW50LAoJCQkJICAgICB1NjQgbnIsIGludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLAoJCQkJICAgICB1NjQgYWRkcikKewoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcjsKCglpZiAoc3lzdGVtX3N0YXRlICE9IFNZU1RFTV9SVU5OSU5HIHx8IGxpc3RfZW1wdHkoJmN0eC0+ZXZlbnRfbGlzdCkpCgkJcmV0dXJuOwoKCXJjdV9yZWFkX2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnlfcmN1KGNvdW50ZXIsICZjdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKHBlcmZfc3djb3VudGVyX21hdGNoKGNvdW50ZXIsIHR5cGUsIGV2ZW50LCByZWdzKSkKCQkJcGVyZl9zd2NvdW50ZXJfYWRkKGNvdW50ZXIsIG5yLCBubWksIHJlZ3MsIGFkZHIpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCnN0YXRpYyBpbnQgKnBlcmZfc3djb3VudGVyX3JlY3Vyc2lvbl9jb250ZXh0KHN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHgpCnsKCWlmIChpbl9ubWkoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzNdOwoKCWlmIChpbl9pcnEoKSkKCQlyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzJdOwoKCWlmIChpbl9zb2Z0aXJxKCkpCgkJcmV0dXJuICZjcHVjdHgtPnJlY3Vyc2lvblsxXTsKCglyZXR1cm4gJmNwdWN0eC0+cmVjdXJzaW9uWzBdOwp9CgpzdGF0aWMgdm9pZCBfX3BlcmZfc3djb3VudGVyX2V2ZW50KGVudW0gcGVyZl9ldmVudF90eXBlcyB0eXBlLCB1MzIgZXZlbnQsCgkJCQkgICB1NjQgbnIsIGludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLAoJCQkJICAgdTY0IGFkZHIpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHggPSAmZ2V0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7CglpbnQgKnJlY3Vyc2lvbiA9IHBlcmZfc3djb3VudGVyX3JlY3Vyc2lvbl9jb250ZXh0KGNwdWN0eCk7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCglpZiAoKnJlY3Vyc2lvbikKCQlnb3RvIG91dDsKCgkoKnJlY3Vyc2lvbikrKzsKCWJhcnJpZXIoKTsKCglwZXJmX3N3Y291bnRlcl9jdHhfZXZlbnQoJmNwdWN0eC0+Y3R4LCB0eXBlLCBldmVudCwKCQkJCSBuciwgbm1pLCByZWdzLCBhZGRyKTsKCXJjdV9yZWFkX2xvY2soKTsKCS8qCgkgKiBkb2Vzbid0IHJlYWxseSBtYXR0ZXIgd2hpY2ggb2YgdGhlIGNoaWxkIGNvbnRleHRzIHRoZQoJICogZXZlbnRzIGVuZHMgdXAgaW4uCgkgKi8KCWN0eCA9IHJjdV9kZXJlZmVyZW5jZShjdXJyZW50LT5wZXJmX2NvdW50ZXJfY3R4cCk7CglpZiAoY3R4KQoJCXBlcmZfc3djb3VudGVyX2N0eF9ldmVudChjdHgsIHR5cGUsIGV2ZW50LCBuciwgbm1pLCByZWdzLCBhZGRyKTsKCXJjdV9yZWFkX3VubG9jaygpOwoKCWJhcnJpZXIoKTsKCSgqcmVjdXJzaW9uKS0tOwoKb3V0OgoJcHV0X2NwdV92YXIocGVyZl9jcHVfY29udGV4dCk7Cn0KCnZvaWQKcGVyZl9zd2NvdW50ZXJfZXZlbnQodTMyIGV2ZW50LCB1NjQgbnIsIGludCBubWksIHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1NjQgYWRkcikKewoJX19wZXJmX3N3Y291bnRlcl9ldmVudChQRVJGX1RZUEVfU09GVFdBUkUsIGV2ZW50LCBuciwgbm1pLCByZWdzLCBhZGRyKTsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglwZXJmX3N3Y291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyBpbnQgcGVyZl9zd2NvdW50ZXJfZW5hYmxlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCXBlcmZfc3djb3VudGVyX3NldF9wZXJpb2QoY291bnRlcik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcGVyZl9zd2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglwZXJmX3N3Y291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX2dlbmVyaWMgPSB7CgkuZW5hYmxlCQk9IHBlcmZfc3djb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gcGVyZl9zd2NvdW50ZXJfZGlzYWJsZSwKCS5yZWFkCQk9IHBlcmZfc3djb3VudGVyX3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBjb3VudGVyOiBjcHUgd2FsbCB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgY3B1X2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaW50IGNwdSA9IHJhd19zbXBfcHJvY2Vzc29yX2lkKCk7CglzNjQgcHJldjsKCXU2NCBub3c7CgoJbm93ID0gY3B1X2Nsb2NrKGNwdSk7CglwcmV2ID0gYXRvbWljNjRfcmVhZCgmY291bnRlci0+aHcucHJldl9jb3VudCk7CglhdG9taWM2NF9zZXQoJmNvdW50ZXItPmh3LnByZXZfY291bnQsIG5vdyk7CglhdG9taWM2NF9hZGQobm93IC0gcHJldiwgJmNvdW50ZXItPmNvdW50KTsKfQoKc3RhdGljIGludCBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7CglpbnQgY3B1ID0gcmF3X3NtcF9wcm9jZXNzb3JfaWQoKTsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgY3B1X2Nsb2NrKGNwdSkpOwoJaHJ0aW1lcl9pbml0KCZod2MtPmhydGltZXIsIENMT0NLX01PTk9UT05JQywgSFJUSU1FUl9NT0RFX1JFTCk7Cglod2MtPmhydGltZXIuZnVuY3Rpb24gPSBwZXJmX3N3Y291bnRlcl9ocnRpbWVyOwoJaWYgKGh3Yy0+c2FtcGxlX3BlcmlvZCkgewoJCXU2NCBwZXJpb2QgPSBtYXhfdCh1NjQsIDEwMDAwLCBod2MtPnNhbXBsZV9wZXJpb2QpOwoJCV9faHJ0aW1lcl9zdGFydF9yYW5nZV9ucygmaHdjLT5ocnRpbWVyLAoJCQkJbnNfdG9fa3RpbWUocGVyaW9kKSwgMCwKCQkJCUhSVElNRVJfTU9ERV9SRUwsIDApOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2Rpc2FibGUoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaWYgKGNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QpCgkJaHJ0aW1lcl9jYW5jZWwoJmNvdW50ZXItPmh3LmhydGltZXIpOwoJY3B1X2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlcik7Cn0KCnN0YXRpYyB2b2lkIGNwdV9jbG9ja19wZXJmX2NvdW50ZXJfcmVhZChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CgljcHVfY2xvY2tfcGVyZl9jb3VudGVyX3VwZGF0ZShjb3VudGVyKTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwbXUgcGVyZl9vcHNfY3B1X2Nsb2NrID0gewoJLmVuYWJsZQkJPSBjcHVfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gY3B1X2Nsb2NrX3BlcmZfY291bnRlcl9kaXNhYmxlLAoJLnJlYWQJCT0gY3B1X2Nsb2NrX3BlcmZfY291bnRlcl9yZWFkLAp9OwoKLyoKICogU29mdHdhcmUgY291bnRlcjogdGFzayB0aW1lIGNsb2NrCiAqLwoKc3RhdGljIHZvaWQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfdXBkYXRlKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIsIHU2NCBub3cpCnsKCXU2NCBwcmV2OwoJczY0IGRlbHRhOwoKCXByZXYgPSBhdG9taWM2NF94Y2hnKCZjb3VudGVyLT5ody5wcmV2X2NvdW50LCBub3cpOwoJZGVsdGEgPSBub3cgLSBwcmV2OwoJYXRvbWljNjRfYWRkKGRlbHRhLCAmY291bnRlci0+Y291bnQpOwp9CgpzdGF0aWMgaW50IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2MgPSAmY291bnRlci0+aHc7Cgl1NjQgbm93OwoKCW5vdyA9IGNvdW50ZXItPmN0eC0+dGltZTsKCglhdG9taWM2NF9zZXQoJmh3Yy0+cHJldl9jb3VudCwgbm93KTsKCWhydGltZXJfaW5pdCgmaHdjLT5ocnRpbWVyLCBDTE9DS19NT05PVE9OSUMsIEhSVElNRVJfTU9ERV9SRUwpOwoJaHdjLT5ocnRpbWVyLmZ1bmN0aW9uID0gcGVyZl9zd2NvdW50ZXJfaHJ0aW1lcjsKCWlmIChod2MtPnNhbXBsZV9wZXJpb2QpIHsKCQl1NjQgcGVyaW9kID0gbWF4X3QodTY0LCAxMDAwMCwgaHdjLT5zYW1wbGVfcGVyaW9kKTsKCQlfX2hydGltZXJfc3RhcnRfcmFuZ2VfbnMoJmh3Yy0+aHJ0aW1lciwKCQkJCW5zX3RvX2t0aW1lKHBlcmlvZCksIDAsCgkJCQlIUlRJTUVSX01PREVfUkVMLCAwKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZGlzYWJsZShzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglpZiAoY291bnRlci0+aHcuc2FtcGxlX3BlcmlvZCkKCQlocnRpbWVyX2NhbmNlbCgmY291bnRlci0+aHcuaHJ0aW1lcik7Cgl0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlciwgY291bnRlci0+Y3R4LT50aW1lKTsKCn0KCnN0YXRpYyB2b2lkIHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3JlYWQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJdTY0IHRpbWU7CgoJaWYgKCFpbl9ubWkoKSkgewoJCXVwZGF0ZV9jb250ZXh0X3RpbWUoY291bnRlci0+Y3R4KTsKCQl0aW1lID0gY291bnRlci0+Y3R4LT50aW1lOwoJfSBlbHNlIHsKCQl1NjQgbm93ID0gcGVyZl9jbG9jaygpOwoJCXU2NCBkZWx0YSA9IG5vdyAtIGNvdW50ZXItPmN0eC0+dGltZXN0YW1wOwoJCXRpbWUgPSBjb3VudGVyLT5jdHgtPnRpbWUgKyBkZWx0YTsKCX0KCgl0YXNrX2Nsb2NrX3BlcmZfY291bnRlcl91cGRhdGUoY291bnRlciwgdGltZSk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11IHBlcmZfb3BzX3Rhc2tfY2xvY2sgPSB7CgkuZW5hYmxlCQk9IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX2VuYWJsZSwKCS5kaXNhYmxlCT0gdGFza19jbG9ja19wZXJmX2NvdW50ZXJfZGlzYWJsZSwKCS5yZWFkCQk9IHRhc2tfY2xvY2tfcGVyZl9jb3VudGVyX3JlYWQsCn07CgovKgogKiBTb2Z0d2FyZSBjb3VudGVyOiBjcHUgbWlncmF0aW9ucwogKi8Kdm9pZCBwZXJmX2NvdW50ZXJfdGFza19taWdyYXRpb24oc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrLCBpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4OwoKCXBlcmZfc3djb3VudGVyX2N0eF9ldmVudCgmY3B1Y3R4LT5jdHgsIFBFUkZfVFlQRV9TT0ZUV0FSRSwKCQkJCSBQRVJGX0NPVU5UX0NQVV9NSUdSQVRJT05TLAoJCQkJIDEsIDEsIE5VTEwsIDApOwoKCWN0eCA9IHBlcmZfcGluX3Rhc2tfY29udGV4dCh0YXNrKTsKCWlmIChjdHgpIHsKCQlwZXJmX3N3Y291bnRlcl9jdHhfZXZlbnQoY3R4LCBQRVJGX1RZUEVfU09GVFdBUkUsCgkJCQkJIFBFUkZfQ09VTlRfQ1BVX01JR1JBVElPTlMsCgkJCQkJIDEsIDEsIE5VTEwsIDApOwoJCXBlcmZfdW5waW5fY29udGV4dChjdHgpOwoJfQp9CgojaWZkZWYgQ09ORklHX0VWRU5UX1BST0ZJTEUKdm9pZCBwZXJmX3RwY291bnRlcl9ldmVudChpbnQgZXZlbnRfaWQpCnsKCXN0cnVjdCBwdF9yZWdzICpyZWdzID0gZ2V0X2lycV9yZWdzKCk7CgoJaWYgKCFyZWdzKQoJCXJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgoJX19wZXJmX3N3Y291bnRlcl9ldmVudChQRVJGX1RZUEVfVFJBQ0VQT0lOVCwgZXZlbnRfaWQsIDEsIDEsIHJlZ3MsIDApOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHBlcmZfdHBjb3VudGVyX2V2ZW50KTsKCmV4dGVybiBpbnQgZnRyYWNlX3Byb2ZpbGVfZW5hYmxlKGludCk7CmV4dGVybiB2b2lkIGZ0cmFjZV9wcm9maWxlX2Rpc2FibGUoaW50KTsKCnN0YXRpYyB2b2lkIHRwX3BlcmZfY291bnRlcl9kZXN0cm95KHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXIpCnsKCWZ0cmFjZV9wcm9maWxlX2Rpc2FibGUocGVyZl9ldmVudF9pZCgmY291bnRlci0+YXR0cikpOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHBtdSAqdHBfcGVyZl9jb3VudGVyX2luaXQoc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlcikKewoJaW50IGV2ZW50X2lkID0gcGVyZl9ldmVudF9pZCgmY291bnRlci0+YXR0cik7CglpbnQgcmV0OwoKCXJldCA9IGZ0cmFjZV9wcm9maWxlX2VuYWJsZShldmVudF9pZCk7CglpZiAocmV0KQoJCXJldHVybiBOVUxMOwoKCWNvdW50ZXItPmRlc3Ryb3kgPSB0cF9wZXJmX2NvdW50ZXJfZGVzdHJveTsKCWNvdW50ZXItPmh3LnNhbXBsZV9wZXJpb2QgPSBjb3VudGVyLT5hdHRyLnNhbXBsZV9wZXJpb2Q7CgoJcmV0dXJuICZwZXJmX29wc19nZW5lcmljOwp9CiNlbHNlCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11ICp0cF9wZXJmX2NvdW50ZXJfaW5pdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7CglyZXR1cm4gTlVMTDsKfQojZW5kaWYKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgcG11ICpzd19wZXJmX2NvdW50ZXJfaW5pdChzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyKQp7Cgljb25zdCBzdHJ1Y3QgcG11ICpwbXUgPSBOVUxMOwoKCS8qCgkgKiBTb2Z0d2FyZSBjb3VudGVycyAoY3VycmVudGx5KSBjYW4ndCBpbiBnZW5lcmFsIGRpc3Rpbmd1aXNoCgkgKiBiZXR3ZWVuIHVzZXIsIGtlcm5lbCBhbmQgaHlwZXJ2aXNvciBldmVudHMuCgkgKiBIb3dldmVyLCBjb250ZXh0IHN3aXRjaGVzIGFuZCBjcHUgbWlncmF0aW9ucyBhcmUgY29uc2lkZXJlZAoJICogdG8gYmUga2VybmVsIGV2ZW50cywgYW5kIHBhZ2UgZmF1bHRzIGFyZSBuZXZlciBoeXBlcnZpc29yCgkgKiBldmVudHMuCgkgKi8KCXN3aXRjaCAocGVyZl9ldmVudF9pZCgmY291bnRlci0+YXR0cikpIHsKCWNhc2UgUEVSRl9DT1VOVF9DUFVfQ0xPQ0s6CgkJcG11ID0gJnBlcmZfb3BzX2NwdV9jbG9jazsKCgkJYnJlYWs7CgljYXNlIFBFUkZfQ09VTlRfVEFTS19DTE9DSzoKCQkvKgoJCSAqIElmIHRoZSB1c2VyIGluc3RhbnRpYXRlcyB0aGlzIGFzIGEgcGVyLWNwdSBjb3VudGVyLAoJCSAqIHVzZSB0aGUgY3B1X2Nsb2NrIGNvdW50ZXIgaW5zdGVhZC4KCQkgKi8KCQlpZiAoY291bnRlci0+Y3R4LT50YXNrKQoJCQlwbXUgPSAmcGVyZl9vcHNfdGFza19jbG9jazsKCQllbHNlCgkJCXBtdSA9ICZwZXJmX29wc19jcHVfY2xvY2s7CgoJCWJyZWFrOwoJY2FzZSBQRVJGX0NPVU5UX1BBR0VfRkFVTFRTOgoJY2FzZSBQRVJGX0NPVU5UX1BBR0VfRkFVTFRTX01JTjoKCWNhc2UgUEVSRl9DT1VOVF9QQUdFX0ZBVUxUU19NQUo6CgljYXNlIFBFUkZfQ09VTlRfQ09OVEVYVF9TV0lUQ0hFUzoKCWNhc2UgUEVSRl9DT1VOVF9DUFVfTUlHUkFUSU9OUzoKCQlwbXUgPSAmcGVyZl9vcHNfZ2VuZXJpYzsKCQlicmVhazsKCX0KCglyZXR1cm4gcG11Owp9CgovKgogKiBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIGNvdW50ZXIgc3RydWN0dXJlCiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfY291bnRlciAqCnBlcmZfY291bnRlcl9hbGxvYyhzdHJ1Y3QgcGVyZl9jb3VudGVyX2F0dHIgKmF0dHIsCgkJICAgaW50IGNwdSwKCQkgICBzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCwKCQkgICBzdHJ1Y3QgcGVyZl9jb3VudGVyICpncm91cF9sZWFkZXIsCgkJICAgZ2ZwX3QgZ2ZwZmxhZ3MpCnsKCWNvbnN0IHN0cnVjdCBwbXUgKnBtdTsKCXN0cnVjdCBwZXJmX2NvdW50ZXIgKmNvdW50ZXI7CglzdHJ1Y3QgaHdfcGVyZl9jb3VudGVyICpod2M7Cglsb25nIGVycjsKCgljb3VudGVyID0ga3phbGxvYyhzaXplb2YoKmNvdW50ZXIpLCBnZnBmbGFncyk7CglpZiAoIWNvdW50ZXIpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgoJLyoKCSAqIFNpbmdsZSBjb3VudGVycyBhcmUgdGhlaXIgb3duIGdyb3VwIGxlYWRlcnMsIHdpdGggYW4KCSAqIGVtcHR5IHNpYmxpbmcgbGlzdDoKCSAqLwoJaWYgKCFncm91cF9sZWFkZXIpCgkJZ3JvdXBfbGVhZGVyID0gY291bnRlcjsKCgltdXRleF9pbml0KCZjb3VudGVyLT5jaGlsZF9tdXRleCk7CglJTklUX0xJU1RfSEVBRCgmY291bnRlci0+Y2hpbGRfbGlzdCk7CgoJSU5JVF9MSVNUX0hFQUQoJmNvdW50ZXItPmxpc3RfZW50cnkpOwoJSU5JVF9MSVNUX0hFQUQoJmNvdW50ZXItPmV2ZW50X2VudHJ5KTsKCUlOSVRfTElTVF9IRUFEKCZjb3VudGVyLT5zaWJsaW5nX2xpc3QpOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY291bnRlci0+d2FpdHEpOwoKCW11dGV4X2luaXQoJmNvdW50ZXItPm1tYXBfbXV0ZXgpOwoKCWNvdW50ZXItPmNwdQkJPSBjcHU7Cgljb3VudGVyLT5hdHRyCQk9ICphdHRyOwoJY291bnRlci0+Z3JvdXBfbGVhZGVyCT0gZ3JvdXBfbGVhZGVyOwoJY291bnRlci0+cG11CQk9IE5VTEw7Cgljb3VudGVyLT5jdHgJCT0gY3R4OwoJY291bnRlci0+b25jcHUJCT0gLTE7CgoJY291bnRlci0+bnMJCT0gZ2V0X3BpZF9ucyhjdXJyZW50LT5uc3Byb3h5LT5waWRfbnMpOwoJY291bnRlci0+aWQJCT0gYXRvbWljNjRfaW5jX3JldHVybigmcGVyZl9jb3VudGVyX2lkKTsKCgljb3VudGVyLT5zdGF0ZQkJPSBQRVJGX0NPVU5URVJfU1RBVEVfSU5BQ1RJVkU7CgoJaWYgKGF0dHItPmRpc2FibGVkKQoJCWNvdW50ZXItPnN0YXRlID0gUEVSRl9DT1VOVEVSX1NUQVRFX09GRjsKCglwbXUgPSBOVUxMOwoKCWh3YyA9ICZjb3VudGVyLT5odzsKCWlmIChhdHRyLT5mcmVxICYmIGF0dHItPnNhbXBsZV9mcmVxKQoJCWh3Yy0+c2FtcGxlX3BlcmlvZCA9IGRpdjY0X3U2NChUSUNLX05TRUMsIGF0dHItPnNhbXBsZV9mcmVxKTsKCWVsc2UKCQlod2MtPnNhbXBsZV9wZXJpb2QgPSBhdHRyLT5zYW1wbGVfcGVyaW9kOwoKCS8qCgkgKiB3ZSBjdXJyZW50bHkgZG8gbm90IHN1cHBvcnQgUEVSRl9TQU1QTEVfR1JPVVAgb24gaW5oZXJpdGVkIGNvdW50ZXJzCgkgKi8KCWlmIChhdHRyLT5pbmhlcml0ICYmIChhdHRyLT5zYW1wbGVfdHlwZSAmIFBFUkZfU0FNUExFX0dST1VQKSkKCQlnb3RvIGRvbmU7CgoJaWYgKHBlcmZfZXZlbnRfcmF3KGF0dHIpKSB7CgkJcG11ID0gaHdfcGVyZl9jb3VudGVyX2luaXQoY291bnRlcik7CgkJZ290byBkb25lOwoJfQoKCXN3aXRjaCAocGVyZl9ldmVudF90eXBlKGF0dHIpKSB7CgljYXNlIFBFUkZfVFlQRV9IQVJEV0FSRToKCQlwbXUgPSBod19wZXJmX2NvdW50ZXJfaW5pdChjb3VudGVyKTsKCQlicmVhazsKCgljYXNlIFBFUkZfVFlQRV9TT0ZUV0FSRToKCQlwbXUgPSBzd19wZXJmX2NvdW50ZXJfaW5pdChjb3VudGVyKTsKCQlicmVhazsKCgljYXNlIFBFUkZfVFlQRV9UUkFDRVBPSU5UOgoJCXBtdSA9IHRwX3BlcmZfY291bnRlcl9pbml0KGNvdW50ZXIpOwoJCWJyZWFrOwoJfQpkb25lOgoJZXJyID0gMDsKCWlmICghcG11KQoJCWVyciA9IC1FSU5WQUw7CgllbHNlIGlmIChJU19FUlIocG11KSkKCQllcnIgPSBQVFJfRVJSKHBtdSk7CgoJaWYgKGVycikgewoJCWlmIChjb3VudGVyLT5ucykKCQkJcHV0X3BpZF9ucyhjb3VudGVyLT5ucyk7CgkJa2ZyZWUoY291bnRlcik7CgkJcmV0dXJuIEVSUl9QVFIoZXJyKTsKCX0KCgljb3VudGVyLT5wbXUgPSBwbXU7CgoJYXRvbWljX2luYygmbnJfY291bnRlcnMpOwoJaWYgKGNvdW50ZXItPmF0dHIubW1hcCkKCQlhdG9taWNfaW5jKCZucl9tbWFwX2NvdW50ZXJzKTsKCWlmIChjb3VudGVyLT5hdHRyLmNvbW0pCgkJYXRvbWljX2luYygmbnJfY29tbV9jb3VudGVycyk7CgoJcmV0dXJuIGNvdW50ZXI7Cn0KCi8qKgogKiBzeXNfcGVyZl9jb3VudGVyX29wZW4gLSBvcGVuIGEgcGVyZm9ybWFuY2UgY291bnRlciwgYXNzb2NpYXRlIGl0IHRvIGEgdGFzay9jcHUKICoKICogQGF0dHJfdXB0cjoJZXZlbnQgdHlwZSBhdHRyaWJ1dGVzIGZvciBtb25pdG9yaW5nL3NhbXBsaW5nCiAqIEBwaWQ6CQl0YXJnZXQgcGlkCiAqIEBjcHU6CQl0YXJnZXQgY3B1CiAqIEBncm91cF9mZDoJCWdyb3VwIGxlYWRlciBjb3VudGVyIGZkCiAqLwpTWVNDQUxMX0RFRklORTUocGVyZl9jb3VudGVyX29wZW4sCgkJY29uc3Qgc3RydWN0IHBlcmZfY291bnRlcl9hdHRyIF9fdXNlciAqLCBhdHRyX3VwdHIsCgkJcGlkX3QsIHBpZCwgaW50LCBjcHUsIGludCwgZ3JvdXBfZmQsIHVuc2lnbmVkIGxvbmcsIGZsYWdzKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCAqZ3JvdXBfbGVhZGVyOwoJc3RydWN0IHBlcmZfY291bnRlcl9hdHRyIGF0dHI7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eDsKCXN0cnVjdCBmaWxlICpjb3VudGVyX2ZpbGUgPSBOVUxMOwoJc3RydWN0IGZpbGUgKmdyb3VwX2ZpbGUgPSBOVUxMOwoJaW50IGZwdXRfbmVlZGVkID0gMDsKCWludCBmcHV0X25lZWRlZDIgPSAwOwoJaW50IHJldDsKCgkvKiBmb3IgZnV0dXJlIGV4cGFuZGFiaWxpdHkuLi4gKi8KCWlmIChmbGFncykKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoY29weV9mcm9tX3VzZXIoJmF0dHIsIGF0dHJfdXB0ciwgc2l6ZW9mKGF0dHIpKSAhPSAwKQoJCXJldHVybiAtRUZBVUxUOwoKCS8qCgkgKiBHZXQgdGhlIHRhcmdldCBjb250ZXh0ICh0YXNrIG9yIHBlcmNwdSk6CgkgKi8KCWN0eCA9IGZpbmRfZ2V0X2NvbnRleHQocGlkLCBjcHUpOwoJaWYgKElTX0VSUihjdHgpKQoJCXJldHVybiBQVFJfRVJSKGN0eCk7CgoJLyoKCSAqIExvb2sgdXAgdGhlIGdyb3VwIGxlYWRlciAod2Ugd2lsbCBhdHRhY2ggdGhpcyBjb3VudGVyIHRvIGl0KToKCSAqLwoJZ3JvdXBfbGVhZGVyID0gTlVMTDsKCWlmIChncm91cF9mZCAhPSAtMSkgewoJCXJldCA9IC1FSU5WQUw7CgkJZ3JvdXBfZmlsZSA9IGZnZXRfbGlnaHQoZ3JvdXBfZmQsICZmcHV0X25lZWRlZCk7CgkJaWYgKCFncm91cF9maWxlKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCQlpZiAoZ3JvdXBfZmlsZS0+Zl9vcCAhPSAmcGVyZl9mb3BzKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCgkJZ3JvdXBfbGVhZGVyID0gZ3JvdXBfZmlsZS0+cHJpdmF0ZV9kYXRhOwoJCS8qCgkJICogRG8gbm90IGFsbG93IGEgcmVjdXJzaXZlIGhpZXJhcmNoeSAodGhpcyBuZXcgc2libGluZwoJCSAqIGJlY29taW5nIHBhcnQgb2YgYW5vdGhlciBncm91cC1zaWJsaW5nKToKCQkgKi8KCQlpZiAoZ3JvdXBfbGVhZGVyLT5ncm91cF9sZWFkZXIgIT0gZ3JvdXBfbGVhZGVyKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCQkvKgoJCSAqIERvIG5vdCBhbGxvdyB0byBhdHRhY2ggdG8gYSBncm91cCBpbiBhIGRpZmZlcmVudAoJCSAqIHRhc2sgb3IgQ1BVIGNvbnRleHQ6CgkJICovCgkJaWYgKGdyb3VwX2xlYWRlci0+Y3R4ICE9IGN0eCkKCQkJZ290byBlcnJfcHV0X2NvbnRleHQ7CgkJLyoKCQkgKiBPbmx5IGEgZ3JvdXAgbGVhZGVyIGNhbiBiZSBleGNsdXNpdmUgb3IgcGlubmVkCgkJICovCgkJaWYgKGF0dHIuZXhjbHVzaXZlIHx8IGF0dHIucGlubmVkKQoJCQlnb3RvIGVycl9wdXRfY29udGV4dDsKCX0KCgljb3VudGVyID0gcGVyZl9jb3VudGVyX2FsbG9jKCZhdHRyLCBjcHUsIGN0eCwgZ3JvdXBfbGVhZGVyLAoJCQkJICAgICBHRlBfS0VSTkVMKTsKCXJldCA9IFBUUl9FUlIoY291bnRlcik7CglpZiAoSVNfRVJSKGNvdW50ZXIpKQoJCWdvdG8gZXJyX3B1dF9jb250ZXh0OwoKCXJldCA9IGFub25faW5vZGVfZ2V0ZmQoIltwZXJmX2NvdW50ZXJdIiwgJnBlcmZfZm9wcywgY291bnRlciwgMCk7CglpZiAocmV0IDwgMCkKCQlnb3RvIGVycl9mcmVlX3B1dF9jb250ZXh0OwoKCWNvdW50ZXJfZmlsZSA9IGZnZXRfbGlnaHQocmV0LCAmZnB1dF9uZWVkZWQyKTsKCWlmICghY291bnRlcl9maWxlKQoJCWdvdG8gZXJyX2ZyZWVfcHV0X2NvbnRleHQ7CgoJY291bnRlci0+ZmlscCA9IGNvdW50ZXJfZmlsZTsKCVdBUk5fT05fT05DRShjdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CglwZXJmX2luc3RhbGxfaW5fY29udGV4dChjdHgsIGNvdW50ZXIsIGNwdSk7CgkrK2N0eC0+Z2VuZXJhdGlvbjsKCW11dGV4X3VubG9jaygmY3R4LT5tdXRleCk7CgoJY291bnRlci0+b3duZXIgPSBjdXJyZW50OwoJZ2V0X3Rhc2tfc3RydWN0KGN1cnJlbnQpOwoJbXV0ZXhfbG9jaygmY3VycmVudC0+cGVyZl9jb3VudGVyX211dGV4KTsKCWxpc3RfYWRkX3RhaWwoJmNvdW50ZXItPm93bmVyX2VudHJ5LCAmY3VycmVudC0+cGVyZl9jb3VudGVyX2xpc3QpOwoJbXV0ZXhfdW5sb2NrKCZjdXJyZW50LT5wZXJmX2NvdW50ZXJfbXV0ZXgpOwoKCWZwdXRfbGlnaHQoY291bnRlcl9maWxlLCBmcHV0X25lZWRlZDIpOwoKb3V0X2ZwdXQ6CglmcHV0X2xpZ2h0KGdyb3VwX2ZpbGUsIGZwdXRfbmVlZGVkKTsKCglyZXR1cm4gcmV0OwoKZXJyX2ZyZWVfcHV0X2NvbnRleHQ6CglrZnJlZShjb3VudGVyKTsKCmVycl9wdXRfY29udGV4dDoKCXB1dF9jdHgoY3R4KTsKCglnb3RvIG91dF9mcHV0Owp9CgovKgogKiBpbmhlcml0IGEgY291bnRlciBmcm9tIHBhcmVudCB0YXNrIHRvIGNoaWxkIHRhc2s6CiAqLwpzdGF0aWMgc3RydWN0IHBlcmZfY291bnRlciAqCmluaGVyaXRfY291bnRlcihzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlciwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXIgKmdyb3VwX2xlYWRlciwKCSAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jb3VudGVyOwoKCS8qCgkgKiBJbnN0ZWFkIG9mIGNyZWF0aW5nIHJlY3Vyc2l2ZSBoaWVyYXJjaGllcyBvZiBjb3VudGVycywKCSAqIHdlIGxpbmsgaW5oZXJpdGVkIGNvdW50ZXJzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBhcmVudCwKCSAqIHdoaWNoIGhhcyBhIGZpbHAgZm9yIHN1cmUsIHdoaWNoIHdlIHVzZSBhcyB0aGUgcmVmZXJlbmNlCgkgKiBjb3VudDoKCSAqLwoJaWYgKHBhcmVudF9jb3VudGVyLT5wYXJlbnQpCgkJcGFyZW50X2NvdW50ZXIgPSBwYXJlbnRfY291bnRlci0+cGFyZW50OwoKCWNoaWxkX2NvdW50ZXIgPSBwZXJmX2NvdW50ZXJfYWxsb2MoJnBhcmVudF9jb3VudGVyLT5hdHRyLAoJCQkJCSAgIHBhcmVudF9jb3VudGVyLT5jcHUsIGNoaWxkX2N0eCwKCQkJCQkgICBncm91cF9sZWFkZXIsIEdGUF9LRVJORUwpOwoJaWYgKElTX0VSUihjaGlsZF9jb3VudGVyKSkKCQlyZXR1cm4gY2hpbGRfY291bnRlcjsKCWdldF9jdHgoY2hpbGRfY3R4KTsKCgkvKgoJICogTWFrZSB0aGUgY2hpbGQgc3RhdGUgZm9sbG93IHRoZSBzdGF0ZSBvZiB0aGUgcGFyZW50IGNvdW50ZXIsCgkgKiBub3QgaXRzIGF0dHIuZGlzYWJsZWQgYml0LiAgV2UgaG9sZCB0aGUgcGFyZW50J3MgbXV0ZXgsCgkgKiBzbyB3ZSB3b24ndCByYWNlIHdpdGggcGVyZl9jb3VudGVyX3tlbiwgZGlzfWFibGVfZmFtaWx5LgoJICovCglpZiAocGFyZW50X2NvdW50ZXItPnN0YXRlID49IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRSkKCQljaGlsZF9jb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9JTkFDVElWRTsKCWVsc2UKCQljaGlsZF9jb3VudGVyLT5zdGF0ZSA9IFBFUkZfQ09VTlRFUl9TVEFURV9PRkY7CgoJLyoKCSAqIExpbmsgaXQgdXAgaW4gdGhlIGNoaWxkJ3MgY29udGV4dDoKCSAqLwoJYWRkX2NvdW50ZXJfdG9fY3R4KGNoaWxkX2NvdW50ZXIsIGNoaWxkX2N0eCk7CgoJY2hpbGRfY291bnRlci0+cGFyZW50ID0gcGFyZW50X2NvdW50ZXI7CgkvKgoJICogaW5oZXJpdCBpbnRvIGNoaWxkJ3MgY2hpbGQgYXMgd2VsbDoKCSAqLwoJY2hpbGRfY291bnRlci0+YXR0ci5pbmhlcml0ID0gMTsKCgkvKgoJICogR2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBwYXJlbnQgZmlscCAtIHdlIHdpbGwgZnB1dCBpdAoJICogd2hlbiB0aGUgY2hpbGQgY291bnRlciBleGl0cy4gVGhpcyBpcyBzYWZlIHRvIGRvIGJlY2F1c2UKCSAqIHdlIGFyZSBpbiB0aGUgcGFyZW50IGFuZCB3ZSBrbm93IHRoYXQgdGhlIGZpbHAgc3RpbGwKCSAqIGV4aXN0cyBhbmQgaGFzIGEgbm9uemVybyBjb3VudDoKCSAqLwoJYXRvbWljX2xvbmdfaW5jKCZwYXJlbnRfY291bnRlci0+ZmlscC0+Zl9jb3VudCk7CgoJLyoKCSAqIExpbmsgdGhpcyBpbnRvIHRoZSBwYXJlbnQgY291bnRlcidzIGNoaWxkIGxpc3QKCSAqLwoJV0FSTl9PTl9PTkNFKHBhcmVudF9jb3VudGVyLT5jdHgtPnBhcmVudF9jdHgpOwoJbXV0ZXhfbG9jaygmcGFyZW50X2NvdW50ZXItPmNoaWxkX211dGV4KTsKCWxpc3RfYWRkX3RhaWwoJmNoaWxkX2NvdW50ZXItPmNoaWxkX2xpc3QsICZwYXJlbnRfY291bnRlci0+Y2hpbGRfbGlzdCk7CgltdXRleF91bmxvY2soJnBhcmVudF9jb3VudGVyLT5jaGlsZF9tdXRleCk7CgoJcmV0dXJuIGNoaWxkX2NvdW50ZXI7Cn0KCnN0YXRpYyBpbnQgaW5oZXJpdF9ncm91cChzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlciwKCSAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAqcGFyZW50LAoJICAgICAgc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpwYXJlbnRfY3R4LAoJICAgICAgc3RydWN0IHRhc2tfc3RydWN0ICpjaGlsZCwKCSAgICAgIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpsZWFkZXI7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpzdWI7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jdHI7CgoJbGVhZGVyID0gaW5oZXJpdF9jb3VudGVyKHBhcmVudF9jb3VudGVyLCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkgY2hpbGQsIE5VTEwsIGNoaWxkX2N0eCk7CglpZiAoSVNfRVJSKGxlYWRlcikpCgkJcmV0dXJuIFBUUl9FUlIobGVhZGVyKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc3ViLCAmcGFyZW50X2NvdW50ZXItPnNpYmxpbmdfbGlzdCwgbGlzdF9lbnRyeSkgewoJCWNoaWxkX2N0ciA9IGluaGVyaXRfY291bnRlcihzdWIsIHBhcmVudCwgcGFyZW50X2N0eCwKCQkJCQkgICAgY2hpbGQsIGxlYWRlciwgY2hpbGRfY3R4KTsKCQlpZiAoSVNfRVJSKGNoaWxkX2N0cikpCgkJCXJldHVybiBQVFJfRVJSKGNoaWxkX2N0cik7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc3luY19jaGlsZF9jb3VudGVyKHN0cnVjdCBwZXJmX2NvdW50ZXIgKmNoaWxkX2NvdW50ZXIsCgkJCSAgICAgICBzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlcikKewoJdTY0IGNoaWxkX3ZhbDsKCgljaGlsZF92YWwgPSBhdG9taWM2NF9yZWFkKCZjaGlsZF9jb3VudGVyLT5jb3VudCk7CgoJLyoKCSAqIEFkZCBiYWNrIHRoZSBjaGlsZCdzIGNvdW50IHRvIHRoZSBwYXJlbnQncyBjb3VudDoKCSAqLwoJYXRvbWljNjRfYWRkKGNoaWxkX3ZhbCwgJnBhcmVudF9jb3VudGVyLT5jb3VudCk7CglhdG9taWM2NF9hZGQoY2hpbGRfY291bnRlci0+dG90YWxfdGltZV9lbmFibGVkLAoJCSAgICAgJnBhcmVudF9jb3VudGVyLT5jaGlsZF90b3RhbF90aW1lX2VuYWJsZWQpOwoJYXRvbWljNjRfYWRkKGNoaWxkX2NvdW50ZXItPnRvdGFsX3RpbWVfcnVubmluZywKCQkgICAgICZwYXJlbnRfY291bnRlci0+Y2hpbGRfdG90YWxfdGltZV9ydW5uaW5nKTsKCgkvKgoJICogUmVtb3ZlIHRoaXMgY291bnRlciBmcm9tIHRoZSBwYXJlbnQncyBsaXN0CgkgKi8KCVdBUk5fT05fT05DRShwYXJlbnRfY291bnRlci0+Y3R4LT5wYXJlbnRfY3R4KTsKCW11dGV4X2xvY2soJnBhcmVudF9jb3VudGVyLT5jaGlsZF9tdXRleCk7CglsaXN0X2RlbF9pbml0KCZjaGlsZF9jb3VudGVyLT5jaGlsZF9saXN0KTsKCW11dGV4X3VubG9jaygmcGFyZW50X2NvdW50ZXItPmNoaWxkX211dGV4KTsKCgkvKgoJICogUmVsZWFzZSB0aGUgcGFyZW50IGNvdW50ZXIsIGlmIHRoaXMgd2FzIHRoZSBsYXN0CgkgKiByZWZlcmVuY2UgdG8gaXQuCgkgKi8KCWZwdXQocGFyZW50X2NvdW50ZXItPmZpbHApOwp9CgpzdGF0aWMgdm9pZApfX3BlcmZfY291bnRlcl9leGl0X3Rhc2soc3RydWN0IHBlcmZfY291bnRlciAqY2hpbGRfY291bnRlciwKCQkJIHN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY2hpbGRfY3R4KQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpwYXJlbnRfY291bnRlcjsKCgl1cGRhdGVfY291bnRlcl90aW1lcyhjaGlsZF9jb3VudGVyKTsKCXBlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNoaWxkX2NvdW50ZXIpOwoKCXBhcmVudF9jb3VudGVyID0gY2hpbGRfY291bnRlci0+cGFyZW50OwoJLyoKCSAqIEl0IGNhbiBoYXBwZW4gdGhhdCBwYXJlbnQgZXhpdHMgZmlyc3QsIGFuZCBoYXMgY291bnRlcnMKCSAqIHRoYXQgYXJlIHN0aWxsIGFyb3VuZCBkdWUgdG8gdGhlIGNoaWxkIHJlZmVyZW5jZS4gVGhlc2UKCSAqIGNvdW50ZXJzIG5lZWQgdG8gYmUgemFwcGVkIC0gYnV0IG90aGVyd2lzZSBsaW5nZXIuCgkgKi8KCWlmIChwYXJlbnRfY291bnRlcikgewoJCXN5bmNfY2hpbGRfY291bnRlcihjaGlsZF9jb3VudGVyLCBwYXJlbnRfY291bnRlcik7CgkJZnJlZV9jb3VudGVyKGNoaWxkX2NvdW50ZXIpOwoJfQp9CgovKgogKiBXaGVuIGEgY2hpbGQgdGFzayBleGl0cywgZmVlZCBiYWNrIGNvdW50ZXIgdmFsdWVzIHRvIHBhcmVudCBjb3VudGVycy4KICovCnZvaWQgcGVyZl9jb3VudGVyX2V4aXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjaGlsZF9jb3VudGVyLCAqdG1wOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjaGlsZF9jdHg7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmIChsaWtlbHkoIWNoaWxkLT5wZXJmX2NvdW50ZXJfY3R4cCkpCgkJcmV0dXJuOwoKCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKCS8qCgkgKiBXZSBjYW4ndCByZXNjaGVkdWxlIGhlcmUgYmVjYXVzZSBpbnRlcnJ1cHRzIGFyZSBkaXNhYmxlZCwKCSAqIGFuZCBlaXRoZXIgY2hpbGQgaXMgY3VycmVudCBvciBpdCBpcyBhIHRhc2sgdGhhdCBjYW4ndCBiZQoJICogc2NoZWR1bGVkLCBzbyB3ZSBhcmUgbm93IHNhZmUgZnJvbSByZXNjaGVkdWxpbmcgY2hhbmdpbmcKCSAqIG91ciBjb250ZXh0LgoJICovCgljaGlsZF9jdHggPSBjaGlsZC0+cGVyZl9jb3VudGVyX2N0eHA7CglfX3BlcmZfY291bnRlcl90YXNrX3NjaGVkX291dChjaGlsZF9jdHgpOwoKCS8qCgkgKiBUYWtlIHRoZSBjb250ZXh0IGxvY2sgaGVyZSBzbyB0aGF0IGlmIGZpbmRfZ2V0X2NvbnRleHQgaXMKCSAqIHJlYWRpbmcgY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwLCB3ZSB3YWl0IHVudGlsIGl0IGhhcwoJICogaW5jcmVtZW50ZWQgdGhlIGNvbnRleHQncyByZWZjb3VudCBiZWZvcmUgd2UgZG8gcHV0X2N0eCBiZWxvdy4KCSAqLwoJc3Bpbl9sb2NrKCZjaGlsZF9jdHgtPmxvY2spOwoJY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwID0gTlVMTDsKCWlmIChjaGlsZF9jdHgtPnBhcmVudF9jdHgpIHsKCQkvKgoJCSAqIFRoaXMgY29udGV4dCBpcyBhIGNsb25lOyB1bmNsb25lIGl0IHNvIGl0IGNhbid0IGdldAoJCSAqIHN3YXBwZWQgdG8gYW5vdGhlciBwcm9jZXNzIHdoaWxlIHdlJ3JlIHJlbW92aW5nIGFsbAoJCSAqIHRoZSBjb3VudGVycyBmcm9tIGl0LgoJCSAqLwoJCXB1dF9jdHgoY2hpbGRfY3R4LT5wYXJlbnRfY3R4KTsKCQljaGlsZF9jdHgtPnBhcmVudF9jdHggPSBOVUxMOwoJfQoJc3Bpbl91bmxvY2soJmNoaWxkX2N0eC0+bG9jayk7Cglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7CgoJbXV0ZXhfbG9jaygmY2hpbGRfY3R4LT5tdXRleCk7CgphZ2FpbjoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjaGlsZF9jb3VudGVyLCB0bXAsICZjaGlsZF9jdHgtPmNvdW50ZXJfbGlzdCwKCQkJCSBsaXN0X2VudHJ5KQoJCV9fcGVyZl9jb3VudGVyX2V4aXRfdGFzayhjaGlsZF9jb3VudGVyLCBjaGlsZF9jdHgpOwoKCS8qCgkgKiBJZiB0aGUgbGFzdCBjb3VudGVyIHdhcyBhIGdyb3VwIGNvdW50ZXIsIGl0IHdpbGwgaGF2ZSBhcHBlbmRlZCBhbGwKCSAqIGl0cyBzaWJsaW5ncyB0byB0aGUgbGlzdCwgYnV0IHdlIG9idGFpbmVkICd0bXAnIGJlZm9yZSB0aGF0IHdoaWNoCgkgKiB3aWxsIHN0aWxsIHBvaW50IHRvIHRoZSBsaXN0IGhlYWQgdGVybWluYXRpbmcgdGhlIGl0ZXJhdGlvbi4KCSAqLwoJaWYgKCFsaXN0X2VtcHR5KCZjaGlsZF9jdHgtPmNvdW50ZXJfbGlzdCkpCgkJZ290byBhZ2FpbjsKCgltdXRleF91bmxvY2soJmNoaWxkX2N0eC0+bXV0ZXgpOwoKCXB1dF9jdHgoY2hpbGRfY3R4KTsKfQoKLyoKICogZnJlZSBhbiB1bmV4cG9zZWQsIHVudXNlZCBjb250ZXh0IGFzIGNyZWF0ZWQgYnkgaW5oZXJpdGFuY2UgYnkKICogaW5pdF90YXNrIGJlbG93LCB1c2VkIGJ5IGZvcmsoKSBpbiBjYXNlIG9mIGZhaWwuCiAqLwp2b2lkIHBlcmZfY291bnRlcl9mcmVlX3Rhc2soc3RydWN0IHRhc2tfc3RydWN0ICp0YXNrKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmN0eCA9IHRhc2stPnBlcmZfY291bnRlcl9jdHhwOwoJc3RydWN0IHBlcmZfY291bnRlciAqY291bnRlciwgKnRtcDsKCglpZiAoIWN0eCkKCQlyZXR1cm47CgoJbXV0ZXhfbG9jaygmY3R4LT5tdXRleCk7CmFnYWluOgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGNvdW50ZXIsIHRtcCwgJmN0eC0+Y291bnRlcl9saXN0LCBsaXN0X2VudHJ5KSB7CgkJc3RydWN0IHBlcmZfY291bnRlciAqcGFyZW50ID0gY291bnRlci0+cGFyZW50OwoKCQlpZiAoV0FSTl9PTl9PTkNFKCFwYXJlbnQpKQoJCQljb250aW51ZTsKCgkJbXV0ZXhfbG9jaygmcGFyZW50LT5jaGlsZF9tdXRleCk7CgkJbGlzdF9kZWxfaW5pdCgmY291bnRlci0+Y2hpbGRfbGlzdCk7CgkJbXV0ZXhfdW5sb2NrKCZwYXJlbnQtPmNoaWxkX211dGV4KTsKCgkJZnB1dChwYXJlbnQtPmZpbHApOwoKCQlsaXN0X2RlbF9jb3VudGVyKGNvdW50ZXIsIGN0eCk7CgkJZnJlZV9jb3VudGVyKGNvdW50ZXIpOwoJfQoKCWlmICghbGlzdF9lbXB0eSgmY3R4LT5jb3VudGVyX2xpc3QpKQoJCWdvdG8gYWdhaW47CgoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKCglwdXRfY3R4KGN0eCk7Cn0KCi8qCiAqIEluaXRpYWxpemUgdGhlIHBlcmZfY291bnRlciBjb250ZXh0IGluIHRhc2tfc3RydWN0CiAqLwppbnQgcGVyZl9jb3VudGVyX2luaXRfdGFzayhzdHJ1Y3QgdGFza19zdHJ1Y3QgKmNoaWxkKQp7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmNoaWxkX2N0eCwgKnBhcmVudF9jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyX2NvbnRleHQgKmNsb25lZF9jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyOwoJc3RydWN0IHRhc2tfc3RydWN0ICpwYXJlbnQgPSBjdXJyZW50OwoJaW50IGluaGVyaXRlZF9hbGwgPSAxOwoJaW50IHJldCA9IDA7CgoJY2hpbGQtPnBlcmZfY291bnRlcl9jdHhwID0gTlVMTDsKCgltdXRleF9pbml0KCZjaGlsZC0+cGVyZl9jb3VudGVyX211dGV4KTsKCUlOSVRfTElTVF9IRUFEKCZjaGlsZC0+cGVyZl9jb3VudGVyX2xpc3QpOwoKCWlmIChsaWtlbHkoIXBhcmVudC0+cGVyZl9jb3VudGVyX2N0eHApKQoJCXJldHVybiAwOwoKCS8qCgkgKiBUaGlzIGlzIGV4ZWN1dGVkIGZyb20gdGhlIHBhcmVudCB0YXNrIGNvbnRleHQsIHNvIGluaGVyaXQKCSAqIGNvdW50ZXJzIHRoYXQgaGF2ZSBiZWVuIG1hcmtlZCBmb3IgY2xvbmluZy4KCSAqIEZpcnN0IGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIGEgY29udGV4dCBmb3IgdGhlIGNoaWxkLgoJICovCgoJY2hpbGRfY3R4ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNoaWxkX2N0eCkKCQlyZXR1cm4gLUVOT01FTTsKCglfX3BlcmZfY291bnRlcl9pbml0X2NvbnRleHQoY2hpbGRfY3R4LCBjaGlsZCk7CgljaGlsZC0+cGVyZl9jb3VudGVyX2N0eHAgPSBjaGlsZF9jdHg7CglnZXRfdGFza19zdHJ1Y3QoY2hpbGQpOwoKCS8qCgkgKiBJZiB0aGUgcGFyZW50J3MgY29udGV4dCBpcyBhIGNsb25lLCBwaW4gaXQgc28gaXQgd29uJ3QgZ2V0CgkgKiBzd2FwcGVkIHVuZGVyIHVzLgoJICovCglwYXJlbnRfY3R4ID0gcGVyZl9waW5fdGFza19jb250ZXh0KHBhcmVudCk7CgoJLyoKCSAqIE5vIG5lZWQgdG8gY2hlY2sgaWYgcGFyZW50X2N0eCAhPSBOVUxMIGhlcmU7IHNpbmNlIHdlIHNhdwoJICogaXQgbm9uLU5VTEwgZWFybGllciwgdGhlIG9ubHkgcmVhc29uIGZvciBpdCB0byBiZWNvbWUgTlVMTAoJICogaXMgaWYgd2UgZXhpdCwgYW5kIHNpbmNlIHdlJ3JlIGN1cnJlbnRseSBpbiB0aGUgbWlkZGxlIG9mCgkgKiBhIGZvcmsgd2UgY2FuJ3QgYmUgZXhpdGluZyBhdCB0aGUgc2FtZSB0aW1lLgoJICovCgoJLyoKCSAqIExvY2sgdGhlIHBhcmVudCBsaXN0LiBObyBuZWVkIHRvIGxvY2sgdGhlIGNoaWxkIC0gbm90IFBJRAoJICogaGFzaGVkIHlldCBhbmQgbm90IHJ1bm5pbmcsIHNvIG5vYm9keSBjYW4gYWNjZXNzIGl0LgoJICovCgltdXRleF9sb2NrKCZwYXJlbnRfY3R4LT5tdXRleCk7CgoJLyoKCSAqIFdlIGRvbnQgaGF2ZSB0byBkaXNhYmxlIE5NSXMgLSB3ZSBhcmUgb25seSBsb29raW5nIGF0CgkgKiB0aGUgbGlzdCwgbm90IG1hbmlwdWxhdGluZyBpdDoKCSAqLwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9yY3UoY291bnRlciwgJnBhcmVudF9jdHgtPmV2ZW50X2xpc3QsIGV2ZW50X2VudHJ5KSB7CgkJaWYgKGNvdW50ZXIgIT0gY291bnRlci0+Z3JvdXBfbGVhZGVyKQoJCQljb250aW51ZTsKCgkJaWYgKCFjb3VudGVyLT5hdHRyLmluaGVyaXQpIHsKCQkJaW5oZXJpdGVkX2FsbCA9IDA7CgkJCWNvbnRpbnVlOwoJCX0KCgkJcmV0ID0gaW5oZXJpdF9ncm91cChjb3VudGVyLCBwYXJlbnQsIHBhcmVudF9jdHgsCgkJCQkJICAgICBjaGlsZCwgY2hpbGRfY3R4KTsKCQlpZiAocmV0KSB7CgkJCWluaGVyaXRlZF9hbGwgPSAwOwoJCQlicmVhazsKCQl9Cgl9CgoJaWYgKGluaGVyaXRlZF9hbGwpIHsKCQkvKgoJCSAqIE1hcmsgdGhlIGNoaWxkIGNvbnRleHQgYXMgYSBjbG9uZSBvZiB0aGUgcGFyZW50CgkJICogY29udGV4dCwgb3Igb2Ygd2hhdGV2ZXIgdGhlIHBhcmVudCBpcyBhIGNsb25lIG9mLgoJCSAqIE5vdGUgdGhhdCBpZiB0aGUgcGFyZW50IGlzIGEgY2xvbmUsIGl0IGNvdWxkIGdldAoJCSAqIHVuY2xvbmVkIGF0IGFueSBwb2ludCwgYnV0IHRoYXQgZG9lc24ndCBtYXR0ZXIKCQkgKiBiZWNhdXNlIHRoZSBsaXN0IG9mIGNvdW50ZXJzIGFuZCB0aGUgZ2VuZXJhdGlvbgoJCSAqIGNvdW50IGNhbid0IGhhdmUgY2hhbmdlZCBzaW5jZSB3ZSB0b29rIHRoZSBtdXRleC4KCQkgKi8KCQljbG9uZWRfY3R4ID0gcmN1X2RlcmVmZXJlbmNlKHBhcmVudF9jdHgtPnBhcmVudF9jdHgpOwoJCWlmIChjbG9uZWRfY3R4KSB7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2N0eCA9IGNsb25lZF9jdHg7CgkJCWNoaWxkX2N0eC0+cGFyZW50X2dlbiA9IHBhcmVudF9jdHgtPnBhcmVudF9nZW47CgkJfSBlbHNlIHsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfY3R4ID0gcGFyZW50X2N0eDsKCQkJY2hpbGRfY3R4LT5wYXJlbnRfZ2VuID0gcGFyZW50X2N0eC0+Z2VuZXJhdGlvbjsKCQl9CgkJZ2V0X2N0eChjaGlsZF9jdHgtPnBhcmVudF9jdHgpOwoJfQoKCW11dGV4X3VubG9jaygmcGFyZW50X2N0eC0+bXV0ZXgpOwoKCXBlcmZfdW5waW5fY29udGV4dChwYXJlbnRfY3R4KTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCBfX2NwdWluaXQgcGVyZl9jb3VudGVyX2luaXRfY3B1KGludCBjcHUpCnsKCXN0cnVjdCBwZXJmX2NwdV9jb250ZXh0ICpjcHVjdHg7CgoJY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCV9fcGVyZl9jb3VudGVyX2luaXRfY29udGV4dCgmY3B1Y3R4LT5jdHgsIE5VTEwpOwoKCXNwaW5fbG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCWNwdWN0eC0+bWF4X3BlcnRhc2sgPSBwZXJmX21heF9jb3VudGVycyAtIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1OwoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJaHdfcGVyZl9jb3VudGVyX3NldHVwKGNwdSk7Cn0KCiNpZmRlZiBDT05GSUdfSE9UUExVR19DUFUKc3RhdGljIHZvaWQgX19wZXJmX2NvdW50ZXJfZXhpdF9jcHUodm9pZCAqaW5mbykKewoJc3RydWN0IHBlcmZfY3B1X2NvbnRleHQgKmNwdWN0eCA9ICZfX2dldF9jcHVfdmFyKHBlcmZfY3B1X2NvbnRleHQpOwoJc3RydWN0IHBlcmZfY291bnRlcl9jb250ZXh0ICpjdHggPSAmY3B1Y3R4LT5jdHg7CglzdHJ1Y3QgcGVyZl9jb3VudGVyICpjb3VudGVyLCAqdG1wOwoKCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShjb3VudGVyLCB0bXAsICZjdHgtPmNvdW50ZXJfbGlzdCwgbGlzdF9lbnRyeSkKCQlfX3BlcmZfY291bnRlcl9yZW1vdmVfZnJvbV9jb250ZXh0KGNvdW50ZXIpOwp9CnN0YXRpYyB2b2lkIHBlcmZfY291bnRlcl9leGl0X2NwdShpbnQgY3B1KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCXN0cnVjdCBwZXJmX2NvdW50ZXJfY29udGV4dCAqY3R4ID0gJmNwdWN0eC0+Y3R4OwoKCW11dGV4X2xvY2soJmN0eC0+bXV0ZXgpOwoJc21wX2NhbGxfZnVuY3Rpb25fc2luZ2xlKGNwdSwgX19wZXJmX2NvdW50ZXJfZXhpdF9jcHUsIE5VTEwsIDEpOwoJbXV0ZXhfdW5sb2NrKCZjdHgtPm11dGV4KTsKfQojZWxzZQpzdGF0aWMgaW5saW5lIHZvaWQgcGVyZl9jb3VudGVyX2V4aXRfY3B1KGludCBjcHUpIHsgfQojZW5kaWYKCnN0YXRpYyBpbnQgX19jcHVpbml0CnBlcmZfY3B1X25vdGlmeShzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKnNlbGYsIHVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2b2lkICpoY3B1KQp7Cgl1bnNpZ25lZCBpbnQgY3B1ID0gKGxvbmcpaGNwdTsKCglzd2l0Y2ggKGFjdGlvbikgewoKCWNhc2UgQ1BVX1VQX1BSRVBBUkU6CgljYXNlIENQVV9VUF9QUkVQQVJFX0ZST1pFTjoKCQlwZXJmX2NvdW50ZXJfaW5pdF9jcHUoY3B1KTsKCQlicmVhazsKCgljYXNlIENQVV9ET1dOX1BSRVBBUkU6CgljYXNlIENQVV9ET1dOX1BSRVBBUkVfRlJPWkVOOgoJCXBlcmZfY291bnRlcl9leGl0X2NwdShjcHUpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIE5PVElGWV9PSzsKfQoKLyoKICogVGhpcyBoYXMgdG8gaGF2ZSBhIGhpZ2hlciBwcmlvcml0eSB0aGFuIG1pZ3JhdGlvbl9ub3RpZmllciBpbiBzY2hlZC5jLgogKi8Kc3RhdGljIHN0cnVjdCBub3RpZmllcl9ibG9jayBfX2NwdWluaXRkYXRhIHBlcmZfY3B1X25iID0gewoJLm5vdGlmaWVyX2NhbGwJCT0gcGVyZl9jcHVfbm90aWZ5LAoJLnByaW9yaXR5CQk9IDIwLAp9OwoKdm9pZCBfX2luaXQgcGVyZl9jb3VudGVyX2luaXQodm9pZCkKewoJcGVyZl9jcHVfbm90aWZ5KCZwZXJmX2NwdV9uYiwgKHVuc2lnbmVkIGxvbmcpQ1BVX1VQX1BSRVBBUkUsCgkJCSh2b2lkICopKGxvbmcpc21wX3Byb2Nlc3Nvcl9pZCgpKTsKCXJlZ2lzdGVyX2NwdV9ub3RpZmllcigmcGVyZl9jcHVfbmIpOwp9CgpzdGF0aWMgc3NpemVfdCBwZXJmX3Nob3dfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsIGNoYXIgKmJ1ZikKewoJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1KTsKfQoKc3RhdGljIHNzaXplX3QKcGVyZl9zZXRfcmVzZXJ2ZV9wZXJjcHUoc3RydWN0IHN5c2Rldl9jbGFzcyAqY2xhc3MsCgkJCWNvbnN0IGNoYXIgKmJ1ZiwKCQkJc2l6ZV90IGNvdW50KQp7CglzdHJ1Y3QgcGVyZl9jcHVfY29udGV4dCAqY3B1Y3R4OwoJdW5zaWduZWQgbG9uZyB2YWw7CglpbnQgZXJyLCBjcHUsIG1wdDsKCgllcnIgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmdmFsKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCWlmICh2YWwgPiBwZXJmX21heF9jb3VudGVycykKCQlyZXR1cm4gLUVJTlZBTDsKCglzcGluX2xvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CglwZXJmX3Jlc2VydmVkX3BlcmNwdSA9IHZhbDsKCWZvcl9lYWNoX29ubGluZV9jcHUoY3B1KSB7CgkJY3B1Y3R4ID0gJnBlcl9jcHUocGVyZl9jcHVfY29udGV4dCwgY3B1KTsKCQlzcGluX2xvY2tfaXJxKCZjcHVjdHgtPmN0eC5sb2NrKTsKCQltcHQgPSBtaW4ocGVyZl9tYXhfY291bnRlcnMgLSBjcHVjdHgtPmN0eC5ucl9jb3VudGVycywKCQkJICBwZXJmX21heF9jb3VudGVycyAtIHBlcmZfcmVzZXJ2ZWRfcGVyY3B1KTsKCQljcHVjdHgtPm1heF9wZXJ0YXNrID0gbXB0OwoJCXNwaW5fdW5sb2NrX2lycSgmY3B1Y3R4LT5jdHgubG9jayk7Cgl9CglzcGluX3VubG9jaygmcGVyZl9yZXNvdXJjZV9sb2NrKTsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBzc2l6ZV90IHBlcmZfc2hvd19vdmVyY29tbWl0KHN0cnVjdCBzeXNkZXZfY2xhc3MgKmNsYXNzLCBjaGFyICpidWYpCnsKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCBwZXJmX292ZXJjb21taXQpOwp9CgpzdGF0aWMgc3NpemVfdApwZXJmX3NldF9vdmVyY29tbWl0KHN0cnVjdCBzeXNkZXZfY2xhc3MgKmNsYXNzLCBjb25zdCBjaGFyICpidWYsIHNpemVfdCBjb3VudCkKewoJdW5zaWduZWQgbG9uZyB2YWw7CglpbnQgZXJyOwoKCWVyciA9IHN0cmljdF9zdHJ0b3VsKGJ1ZiwgMTAsICZ2YWwpOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoJaWYgKHZhbCA+IDEpCgkJcmV0dXJuIC1FSU5WQUw7CgoJc3Bpbl9sb2NrKCZwZXJmX3Jlc291cmNlX2xvY2spOwoJcGVyZl9vdmVyY29tbWl0ID0gdmFsOwoJc3Bpbl91bmxvY2soJnBlcmZfcmVzb3VyY2VfbG9jayk7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgU1lTREVWX0NMQVNTX0FUVFIoCgkJCQlyZXNlcnZlX3BlcmNwdSwKCQkJCTA2NDQsCgkJCQlwZXJmX3Nob3dfcmVzZXJ2ZV9wZXJjcHUsCgkJCQlwZXJmX3NldF9yZXNlcnZlX3BlcmNwdQoJCQkpOwoKc3RhdGljIFNZU0RFVl9DTEFTU19BVFRSKAoJCQkJb3ZlcmNvbW1pdCwKCQkJCTA2NDQsCgkJCQlwZXJmX3Nob3dfb3ZlcmNvbW1pdCwKCQkJCXBlcmZfc2V0X292ZXJjb21taXQKCQkJKTsKCnN0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpwZXJmY2xhc3NfYXR0cnNbXSA9IHsKCSZhdHRyX3Jlc2VydmVfcGVyY3B1LmF0dHIsCgkmYXR0cl9vdmVyY29tbWl0LmF0dHIsCglOVUxMCn07CgpzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBwZXJmY2xhc3NfYXR0cl9ncm91cCA9IHsKCS5hdHRycwkJCT0gcGVyZmNsYXNzX2F0dHJzLAoJLm5hbWUJCQk9ICJwZXJmX2NvdW50ZXJzIiwKfTsKCnN0YXRpYyBpbnQgX19pbml0IHBlcmZfY291bnRlcl9zeXNmc19pbml0KHZvaWQpCnsKCXJldHVybiBzeXNmc19jcmVhdGVfZ3JvdXAoJmNwdV9zeXNkZXZfY2xhc3Mua3NldC5rb2JqLAoJCQkJICAmcGVyZmNsYXNzX2F0dHJfZ3JvdXApOwp9CmRldmljZV9pbml0Y2FsbChwZXJmX2NvdW50ZXJfc3lzZnNfaW5pdCk7Cg==